Package org.rioproject.impl.container

Source Code of org.rioproject.impl.container.ServiceBeanLoader

/*
* Copyright 2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.rioproject.impl.container;

import com.sun.jini.config.Config;
import com.sun.jini.start.AggregatePolicyProvider;
import com.sun.jini.start.LoaderSplitPolicyProvider;
import net.jini.admin.Administrable;
import net.jini.config.Configuration;
import net.jini.id.ReferentUuid;
import net.jini.id.Uuid;
import net.jini.io.MarshalledInstance;
import net.jini.security.BasicProxyPreparer;
import net.jini.security.ProxyPreparer;
import net.jini.security.policy.DynamicPolicyProvider;
import net.jini.security.policy.PolicyFileProvider;
import org.rioproject.RioVersion;
import org.rioproject.admin.ServiceBeanControl;
import org.rioproject.config.Constants;
import org.rioproject.deploy.ServiceBeanInstantiationException;
import org.rioproject.impl.servicebean.DefaultServiceBeanFactory;
import org.rioproject.impl.servicebean.DefaultServiceBeanManager;
import org.rioproject.impl.servicebean.ServiceBeanActivation;
import org.rioproject.impl.servicebean.ServiceElementUtil;
import org.rioproject.impl.system.ComputeResource;
import org.rioproject.impl.system.capability.PlatformCapabilityLoader;
import org.rioproject.loader.ClassAnnotator;
import org.rioproject.loader.CommonClassLoader;
import org.rioproject.loader.ServiceClassLoader;
import org.rioproject.log.LoggerConfig;
import org.rioproject.opstring.ClassBundle;
import org.rioproject.opstring.ServiceElement;
import org.rioproject.resolver.RemoteRepository;
import org.rioproject.resolver.Resolver;
import org.rioproject.resolver.ResolverException;
import org.rioproject.resolver.ResolverHelper;
import org.rioproject.rmi.ResolvingLoader;
import org.rioproject.servicebean.ServiceBeanContext;
import org.rioproject.servicebean.ServiceBeanContextFactory;
import org.rioproject.servicebean.ServiceBeanFactory;
import org.rioproject.servicebean.ServiceBeanManager;
import org.rioproject.system.capability.PlatformCapability;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.MalformedURLException;
import java.net.URL;
import java.security.Policy;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

/**
* The ServiceBeanLoader will load and create a service.
*
* @author Dennis Reedy
*/
public class ServiceBeanLoader {
    /** Component name for loading configuration artifacts specifically related
     * to service creation */
    private static final String CONFIG_COMPONENT = "service.load";
    /** A Logger */
    private static Logger logger = LoggerFactory.getLogger(ServiceBeanLoader.class.getName());
    private final static AggregatePolicyProvider globalPolicy;
    private final static Policy initialGlobalPolicy;
    static {
        initialGlobalPolicy = Policy.getPolicy();
        globalPolicy = new AggregatePolicyProvider(initialGlobalPolicy);
        Policy.setPolicy(globalPolicy);
    }
    private static final Map<String, AtomicInteger> counterTable =
        Collections.synchronizedMap(new HashMap<String, AtomicInteger>());
    private static final List<ProvisionedResources> provisionedResources =
        Collections.synchronizedList(new ArrayList<ProvisionedResources>());
    private final static ExecutorService service = Executors.newCachedThreadPool();

    /**
     * Clean up resources
     * <br>
     * <li>
     * Remove ServiceClassLoader from global policy to prevent leaking
     * ServiceClassLoader instances
     * <li>Remove any downloaded jars
     * </ul>
     *
     * @param result The ServiceBeanLoaderResult object to unload
     * @param elem The ServiceElement to use as a reference
     */
    public static void unload(final ServiceBeanLoaderResult result, final ServiceElement elem) {
        unload(result.getImpl().getClass().getClassLoader(), elem);
    }

    /**
     * Clean up resources
     * <br>
     * <li>
     * Remove ServiceClassLoader from global policy to prevent leaking
     * ServiceClassLoader instances
     * <li>Remove any downloaded jars
     * </ul>
     *
     * @param loader The ClassLoader to unload
     * @param elem The ServiceElement to use as a reference
     */
    public static void unload(final ClassLoader loader, final ServiceElement elem) {
        if(globalPolicy!=null)
            globalPolicy.setPolicy(loader, null);
        checkAndMaybeCleanProvisionedResources(elem);
        service.submit(new Runnable() {
            public void run() {
                ResolvingLoader.release(loader);
            }
        });
    }

    @Override
    protected void finalize() throws Throwable {
        service.shutdownNow();
        super.finalize();
    }

    /*
     * Check and maybe remove provisioned resources collection
     */
    private static void checkAndMaybeCleanProvisionedResources(final ServiceElement elem) {
        List<ProvisionedResources> toRemove = new ArrayList<ProvisionedResources>();
        ProvisionedResources[] copy = provisionedResources.toArray(new ProvisionedResources[provisionedResources.size()]);
        for(ProvisionedResources pr : copy) {
            if(elem.getComponentBundle()!=null &&
               elem.getComponentBundle().getArtifact()!=null)
            if(pr.getArtifact()!=null &&
               pr.getArtifact().equals(elem.getComponentBundle().getArtifact())) {
                toRemove.add(pr);
            }
        }
        for(ProvisionedResources pr : toRemove) {
            AtomicInteger count = counterTable.get(pr.getArtifact());
            if(count!=null) {
                int using = count.decrementAndGet();
                if(logger.isTraceEnabled()) {
                    logger.trace("Number of [{}] artifacts still active={}", pr.getArtifact(), using);
                }
                if(using==0) {
                    provisionedResources.remove(pr);
                } else {
                    counterTable.put(pr.getArtifact(), count);
                }
            }
        }
    }

    /**
     * The load method is invoked to load and instantiate a ServiceBean.
     *
     * @param sElem The ServiceElement
     * @param serviceID Uuid for the service
     * @param jsbManager The ServiceBeanManager
     * @param container The ServiceBeanContainer
     *
     * @return A ServiceBeanLoaderResult object with attributes to access the instantiated
     * service
     *
     * @throws org.rioproject.deploy.ServiceBeanInstantiationException If errors occur while creating the
     * service bean
     */
    public static ServiceBeanLoaderResult load(final ServiceElement sElem,
                                               final Uuid serviceID,
                                               final ServiceBeanManager jsbManager,
                                               final ServiceBeanContainer container) throws ServiceBeanInstantiationException {
        ServiceBeanFactory.Created created = null;
        MarshalledInstance marshalledProxy = null;
        ServiceBeanContext context;
        CommonClassLoader commonCL = CommonClassLoader.getInstance();
        ComputeResource computeResource = container.getComputeResource();

        /*
         * Provision service jars
         */
        URL[] exports = new URL[0];
        URL[] implJARs = new URL[0];
        if(System.getProperty("StaticCybernode")==null) {
            try {
                Resolver resolver = ResolverHelper.getResolver();
                boolean install = computeResource.getPersistentProvisioning();
                Map<String, ProvisionedResources> serviceResources = provisionService(sElem, resolver, install);
                ProvisionedResources dlPR = serviceResources.get("dl");
                ProvisionedResources implPR = serviceResources.get("impl");
                if(dlPR.getJars().length==0 && dlPR.getArtifact()!=null) {
                    String convertedArtifact = dlPR.getArtifact().replaceAll(":", "/");
                    String[] artifactParts = convertedArtifact.split(" ");
                    List<URL> exportURLList = new ArrayList<URL>();
                    for(String artifactPart : artifactParts) {
                        // TODO: if the repositories is default maven central, still need to add?
                        exportURLList.add(new URL("artifact:"+artifactPart+dlPR.getRepositories()));
                    }
                    exports = exportURLList.toArray(new URL[exportURLList.size()]);
                } else {
                    exports = dlPR.getJars();
                }
                implJARs = implPR.getJars();
            } catch(Exception e) {
                throw new ServiceBeanInstantiationException("Unable to provision JARs for " +
                                                            "service "+ ServiceLogUtil.logName(sElem), e);
            }
        }

        final Thread currentThread = Thread.currentThread();
        ClassLoader currentClassLoader = currentThread.getContextClassLoader();
        Uuid serviceIDToUse = serviceID;
        try {
            ClassBundle jsbBundle = sElem.getComponentBundle();
            List<URL> urlList = new ArrayList<URL>();
            /*
            URL[] implJARs;
            if(jsbBundle!=null && jsbBundle.getCodebase()!=null)
                implJARs = jsbBundle.getJARs();
            else
                implJARs = new URL[0];
            */
            urlList.addAll(Arrays.asList(implJARs));

            /* Get matched PlatformCapability jars to load */
            PlatformCapability[] pCaps = computeResource.getPlatformCapabilities();
            PlatformCapability[] matched = ServiceElementUtil.getMatchedPlatformCapabilities(sElem, pCaps);
            for (PlatformCapability pCap : matched) {
                URL[] urls = PlatformCapabilityLoader.getLoadableClassPath(pCap);
                for(URL url : urls) {
                    if(!urlList.contains(url))
                        urlList.add(url);
                }
            }

            URL[] classpath = urlList.toArray(new URL[urlList.size()]);
            Properties metaData = new Properties();
            metaData.setProperty("opStringName", sElem.getOperationalStringName());
            metaData.setProperty("serviceName", sElem.getName());
            ServiceClassLoader jsbCL = new ServiceClassLoader(ServiceClassLoader.getURIs(classpath),
                                                              new ClassAnnotator(exports),
                                                              commonCL,
                                                              metaData);

            /*
            ServiceClassLoader jsbCL =
                new ServiceClassLoader(classpath, annotator, commonCL);
                */
            currentThread.setContextClassLoader(jsbCL);
            if(logger.isDebugEnabled()) {
                StringBuilder buffer = new StringBuilder();
                if(implJARs.length==0) {
                    buffer.append("<empty>");
                } else {
                    for(int i=0; i<implJARs.length; i++) {
                        if(i>0)
                            buffer.append(", ");
                        buffer.append(implJARs[i].toExternalForm());
                    }
                }
                String className = (jsbBundle==null?"<not defined>": jsbBundle.getClassName());
                if(logger.isDebugEnabled()) {
                    logger.debug("Create ServiceClassLoader for {}, classpath {}, codebase {}",
                                 className, buffer.toString(), jsbCL.getClassAnnotation());
                }
            }

            /* Get the servicePolicyFile from the environment. If the
             * property has not been set use the policy set for the VM */
            String servicePolicyFile = System.getProperty("rio.service.security.policy",
                                                          System.getProperty("java.security.policy"));
            if(logger.isTraceEnabled()) {
                logger.trace("{} Service security policy file {}",
                             ServiceLogUtil.logName(sElem), servicePolicyFile);
            }
            if(servicePolicyFile!=null) {
                if(logger.isTraceEnabled()) {
                    logger.trace("Set {} service security to LoaderSplitPolicyProvider", ServiceLogUtil.logName(sElem));
                }
                DynamicPolicyProvider service_policy = new DynamicPolicyProvider(new PolicyFileProvider(servicePolicyFile));
                LoaderSplitPolicyProvider splitServicePolicy = new LoaderSplitPolicyProvider(jsbCL,
                                                                                             service_policy,
                                                                                             new DynamicPolicyProvider(initialGlobalPolicy));
                globalPolicy.setPolicy(jsbCL, splitServicePolicy);
            }

            /* Reload the shared configuration using the service's classloader */
            //String[] configFiles = container.getSharedConfigurationFiles().toArray(new String[sharedConfigurationFiles.size()]);
            Configuration sharedConfiguration = container.getSharedConfiguration();

            /* Get the ServiceBeanContextFactory */
            ServiceBeanContextFactory serviceBeanContextFactory =
                (ServiceBeanContextFactory)Config.getNonNullEntry(sharedConfiguration,
                                                                  CONFIG_COMPONENT,
                                                                  "serviceBeanContextFactory",
                                                                  ServiceBeanContextFactory.class,
                                                                  new ServiceContextFactory());
            /* Create the ServiceBeanContext */
            context = serviceBeanContextFactory.create(sElem,
                                                       jsbManager,
                                                       computeResource,
                                                       sharedConfiguration);
            /* Add a temporary startup value, used to check when issuing
             * lifecycle notification (RIO-141) */
            Map<String, Object> configParms = context.getServiceBeanConfig().getConfigurationParameters();
            configParms.put(Constants.STARTING, true);
            context.getServiceBeanConfig().setConfigurationParameters(configParms);
           
            /*
             * Initialize any configured Logger instances. If there are any
             * exceptions loading the configurations, log the appropriate
             * message and continue
             */
            LoggerConfig[] loggerConfigs = context.getServiceBeanConfig().getLoggerConfigs();
            if(loggerConfigs != null) {
                for (LoggerConfig loggerConfig : loggerConfigs) {
                    try {
                        loggerConfig.getLogger();
                    } catch (Throwable t) {
                        logger.warn("Loading LoggerConfig", t);
                    }
                }
            }
           
            /* Get the ServiceBeanFactory */
            ServiceBeanFactory serviceBeanFactory =
                (ServiceBeanFactory)Config.getNonNullEntry(context.getConfiguration(),
                                                           CONFIG_COMPONENT,
                                                           "serviceBeanFactory",
                                                           ServiceBeanFactory.class,
                                                           new DefaultServiceBeanFactory());
            if(logger.isTraceEnabled()) {
                logger.trace("service = {}, serviceBeanFactory = {}",
                             ServiceLogUtil.logName(sElem), serviceBeanFactory);
            }
            created = serviceBeanFactory.create(context);
            logger.trace("Created ServiceBeanFactory.Created {}", created);
            Object impl = created.getImpl();
            logger.trace("Obtained implementation {}", impl);
           
            if(context.getServiceElement().getComponentBundle()==null) {
                String compName = impl.getClass().getName();
                if(compName.indexOf(".")>0) {
                    int index = compName.lastIndexOf(".");
                    compName = compName.substring(0, index);
                }
                context.getServiceBeanConfig().addInitParameter(ServiceBeanActivation.BOOT_CONFIG_COMPONENT, compName);
            }

            /* Get the ProxyPreparer */
            if(logger.isTraceEnabled()) {
                logger.trace("Get the ProxyPreparer for {}", ServiceLogUtil.logName(sElem));
            }
           
            ProxyPreparer servicePreparer = (ProxyPreparer)Config.getNonNullEntry(context.getConfiguration(),
                                                                                  CONFIG_COMPONENT,
                                                                                  "servicePreparer",
                                                                                  ProxyPreparer.class,
                                                                                  new BasicProxyPreparer());
            if(logger.isTraceEnabled()) {
                logger.trace("Getting the proxy");
            }
            Object proxy = created.getProxy();
            if(logger.isTraceEnabled()) {
                logger.trace("Obtained the proxy %s", proxy);
            }
            if(proxy != null) {
                proxy = servicePreparer.prepareProxy(proxy);
            }
            if(logger.isTraceEnabled()) {
                logger.trace("Proxy {}, prepared? {}", proxy, (proxy==null?"not prepared, returned proxy was null": "yes"));
            }
            /*
             * Set the MarshalledInstance into the ServiceBeanManager
             */
            if(logger.isTraceEnabled()) {
                logger.trace("Set the MarshalledInstance into the ServiceBeanManager");
            }
            marshalledProxy = new MarshalledInstance(proxy);
            ((DefaultServiceBeanManager)context.getServiceBeanManager()).setMarshalledInstance(marshalledProxy);
            /*
             * The service may have created it's own serviceID
             */
            if(proxy instanceof ReferentUuid) {
                serviceIDToUse = ((ReferentUuid)proxy).getReferentUuid();
                if(logger.isDebugEnabled()) {
                    logger.debug("Service has provided Uuid: {}", serviceIDToUse);
                }
                ((DefaultServiceBeanManager)context.getServiceBeanManager()).setServiceID(serviceIDToUse);
            }
           
            /*
             * If the proxy is Administrable and an instanceof
             * ServiceBeanControl, set the ServiceBeanControl in the
             * DefaultAssociationManagement object
             */
            if(proxy instanceof Administrable) {
                Object adminObject = ((Administrable)proxy).getAdmin();              
                if(adminObject instanceof ServiceBeanControl) {
                    context.getAssociationManagement().setServiceBeanControl((ServiceBeanControl)adminObject);
                }                   
            }
            if(logger.isTraceEnabled()) {
                logger.trace("Proxy =  {}", proxy);
            }
        } catch(Exception e) {
            ServiceBeanInstantiationException sbe;
            if(logger.isTraceEnabled()) {
                logger.trace("Loading ServiceBean", e);
            }
            if(e instanceof ServiceBeanInstantiationException)
                sbe = (ServiceBeanInstantiationException)e;
            else
                sbe = new ServiceBeanInstantiationException(e.getClass().getName()+ ": "+ e.getLocalizedMessage(), e);
            throw sbe;
        } finally {               
            currentThread.setContextClassLoader(currentClassLoader);
        }
        return(new ServiceBeanLoaderResult(context, created.getImpl(), created.getBeanAdapter(), marshalledProxy, serviceIDToUse));
   

    static synchronized Map<String, ProvisionedResources> provisionService(final ServiceElement elem,
                                                                           final Resolver resolver,
                                                                           final boolean supportsInstallation)
        throws MalformedURLException, ServiceBeanInstantiationException {

        Map<String, ProvisionedResources> map = new HashMap<String, ProvisionedResources>();
        URL[] implJARs = null;
        String implArtifact = (elem.getComponentBundle()!=null?
                               elem.getComponentBundle().getArtifact(): null);
        ProvisionedResources implPR = getProvisionedResources(implArtifact);

        if(implPR==null) {
            implPR = new ProvisionedResources(implArtifact);
            if(elem.getComponentBundle()!=null) {
                if(System.getProperty("StaticCybernode")==null) {
                    if(elem.getComponentBundle().getArtifact()!=null && resolver!=null) {
                        if(!supportsInstallation)
                            throw new ServiceBeanInstantiationException("Service ["+elem.getName()+"] " +
                                                                        "cannot be instantiated, the Cybernode " +
                                                                        "does not support persistent provisioning, " +
                                                                        "and the service requires artifact resolution " +
                                                                        "for "+implArtifact);
                        URL[] jars;
                        try {
                            StringBuilder builder = new StringBuilder();
                            for(RemoteRepository repository: elem.getRemoteRepositories()) {
                                if(builder.length()>0){
                                    builder.append(", ");
                                }
                                builder.append(repository.getUrl());
                            }
                            if(logger.isInfoEnabled()) {
                                logger.info("Resolve {} using these repositories [{}]",
                                            elem.getComponentBundle().getArtifact(), builder.toString());
                            }
                            jars = ResolverHelper.resolve(elem.getComponentBundle().getArtifact(),
                                                          resolver,
                                                          elem.getRemoteRepositories());
                        } catch (ResolverException e) {
                            Throwable thrown = e;
                            if(e.getCause()!=null)
                                thrown = e.getCause();
                            throw new ServiceBeanInstantiationException("Could not resolve implementation artifact", thrown);
                        }
                        implJARs = jars;
                    } else {
                        /* RIO-228 */
                        if(System.getProperty("StaticCybernode")!=null)
                            implJARs = new URL[0];
                        else
                            implJARs = elem.getComponentBundle().getJARs();
                    }
                }
            } else {
                implJARs = new URL[0];
            }
            if(implJARs!=null)
                implPR.setJars(implJARs);
        }

        String exportArtifact = null;
        for(ClassBundle cb : elem.getExportBundles()) {
            if(cb.getArtifact()!=null) {
                exportArtifact = cb.getArtifact();
                break;
            }
        }
        ProvisionedResources dlPR = getProvisionedResources(exportArtifact);
        if(dlPR==null) {
            if(implArtifact!=null && exportArtifact==null) {
                exportArtifact = "org.rioproject:rio-api:"+ RioVersion.VERSION;
            }
            dlPR = new ProvisionedResources(exportArtifact);
            dlPR.setJars(elem.getExportURLs());
            for(RemoteRepository repository: elem.getRemoteRepositories()) {
                StringBuilder repositoryString = new StringBuilder();
                repositoryString.append(repository.getUrl());
                if(repository.getId()!=null) {
                    repositoryString.append("@");
                    repositoryString.append(repository.getId());
                }
                dlPR.addRepositoryUrl(repositoryString.toString());
            }
        }

        /*
         * If we are instantiating a service that does not use artifact deployment,
         * then we must check the dlPR jars for requisite jar inclusion
         */
        if(exportArtifact==null && implArtifact==null) {
            String localCodebase = System.getProperty(Constants.CODESERVER);
            if(localCodebase!=null) {
                if(!localCodebase.endsWith("/"))
                    localCodebase = localCodebase+"/";
                String[] requisiteExports = new String[]{"rio-api-"+RioVersion.VERSION+".jar", "jsk-dl-2.2.2.jar"};
                for(String export : requisiteExports) {
                    boolean found = false;
                    for(URL u : dlPR.getJars()) {
                        if(u.toExternalForm().endsWith(export)) {
                            found = true;
                            break;
                        }
                    }
                    if(!found) {
                        /* We check if the impl has an artifact, not the dl. The
                         * dl may not declare an artifact. This accounts for the
                         * case where a service is just implemented as a pojo with
                         * no custom remote methods, and is just exported using Rio
                         * infrastructure support
                         * (through the org.rioproject.service.Service
                         * interface).
                         *
                         * If there is no declared artifact, we sail through since
                         * the ServiceElement would have been constructed with the
                         * default platform export jars as part of it's creation.
                         */
                        if(implPR.getArtifact()!=null) {
                            dlPR.addJar(new URL(localCodebase+export));
                        }
                    }
                }
            }
        }

        if(logger.isDebugEnabled()) {
            StringBuilder sb = new StringBuilder();
            sb.append("Service ").append(ServiceLogUtil.logName(elem)).append(" ");
            if(implArtifact!=null)
                sb.append("impl artifact: [").append(implPR.getArtifact()).append("] ");
            sb.append("impl jars: ");
            sb.append(implPR.getJarsAsString());
            sb.append(", ");
            if(dlPR.getArtifact()!=null)
                sb.append("export artifact: [").append(dlPR.getArtifact()).append("] ");
            sb.append("export jars: ");
            sb.append(dlPR.getJarsAsString());
            logger.debug(sb.toString());
        }

        map.put("impl", implPR);
        map.put("dl", dlPR);
        addProvisionedResources(map);
        registerArtifactCounts(map);
        return map;
    }

    private static ProvisionedResources getProvisionedResources(final String artifact) {
        ProvisionedResources pr = null;
        if(artifact!=null && !artifact.contains("SNAPSHOT")) {
            for(ProvisionedResources alreadyProvisioned : provisionedResources) {
                if(alreadyProvisioned.getArtifact()!=null &&
                   alreadyProvisioned.getArtifact().equals(artifact)) {
                    pr = alreadyProvisioned;
                    break;
                }
            }
        }
        return pr;
    }

    private static void addProvisionedResources(final Map<String, ProvisionedResources> map) {
        for(Map.Entry<String, ProvisionedResources> entry : map.entrySet()) {
            ProvisionedResources pr = entry.getValue();
            if(pr.getArtifact()!=null && !pr.getArtifact().contains("SNAPSHOT")) {
                if(!provisionedResources.contains(pr))
                    provisionedResources.add(pr);
            }
        }
    }

    private static void registerArtifactCounts(final Map<String, ProvisionedResources> map) {
        for(Map.Entry<String, ProvisionedResources> entry : map.entrySet()) {
            ProvisionedResources pr = entry.getValue();
            if(pr.getArtifact()!=null && !pr.getArtifact().contains("SNAPSHOT")) {
                AtomicInteger count = counterTable.get(pr.getArtifact());
                if(count==null)
                    count = new AtomicInteger(1);
                else
                    count.incrementAndGet();
                counterTable.put(pr.getArtifact(), count);
                if(logger.isTraceEnabled()) {
                    logger.trace("Counter for [{}] is now {}", pr.getArtifact(), count.get());
                }
            }
        }
    }
  
    private static class ProvisionedResources {
        Set<URL> jars = new HashSet<URL>();
        String artifact;
        StringBuilder repositories = new StringBuilder();

        private ProvisionedResources(final String artifact) {
            this.artifact = artifact;
        }

        void setJars(final URL[] jars) {
            this.jars.addAll(Arrays.asList(jars));
        }

        void addJar(final URL jar) {
            jars.add(jar);
        }

        URL[] getJars() {
            return jars.toArray(new URL[jars.size()]);
        }

        String getArtifact() {
            return artifact;
        }

        String getJarsAsString() {
            return jars.isEmpty() ? "<>" : jars.toString();
        }

        void addRepositoryUrl(String u) {
            repositories.append(";").append(u);
        }

        String getRepositories() {
            return repositories.toString();
        }

        @Override
        public String toString() {
            final StringBuilder sb = new StringBuilder();
            sb.append("jars=").append(
                jars.isEmpty() ? "<>" : jars.toString());
            sb.append('}');
            return sb.toString();
        }
    }
}
TOP

Related Classes of org.rioproject.impl.container.ServiceBeanLoader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.