Package org.apache.servicemix.jbi.framework

Source Code of org.apache.servicemix.jbi.framework.AutoDeploymentService

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.servicemix.jbi.framework;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;

import javax.jbi.JBIException;
import javax.jbi.management.DeploymentException;
import javax.management.JMException;
import javax.management.MBeanAttributeInfo;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.servicemix.jbi.container.EnvironmentContext;
import org.apache.servicemix.jbi.container.JBIContainer;
import org.apache.servicemix.jbi.deployment.Component;
import org.apache.servicemix.jbi.deployment.Descriptor;
import org.apache.servicemix.jbi.deployment.DescriptorFactory;
import org.apache.servicemix.jbi.deployment.ServiceAssembly;
import org.apache.servicemix.jbi.event.DeploymentEvent;
import org.apache.servicemix.jbi.event.DeploymentListener;
import org.apache.servicemix.jbi.management.AttributeInfoHelper;
import org.apache.servicemix.jbi.management.BaseSystemService;
import org.apache.servicemix.jbi.util.FileUtil;
import org.apache.servicemix.jbi.util.XmlPersistenceSupport;

import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap;
import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicBoolean;

/**
* Monitors install and deploy directories to auto install/deploy archives
*
* @version $Revision: 534351 $
*/
public class AutoDeploymentService extends BaseSystemService implements AutoDeploymentServiceMBean {
 
    private static final Log log = LogFactory.getLog(AutoDeploymentService.class);
    private EnvironmentContext environmentContext;
    private DeploymentService deploymentService;
    private InstallationService installationService;
    private boolean monitorInstallationDirectory = true;
    private boolean monitorDeploymentDirectory = true;
    private int monitorInterval = 10;
    private String extensions = ".zip,.jar";
    private AtomicBoolean started = new AtomicBoolean(false);
    private Timer statsTimer;
    private TimerTask timerTask;
    private Map pendingComponents = new ConcurrentHashMap();
    private Map pendingSAs = new ConcurrentHashMap();
    private Map installFileMap = null;
    private Map deployFileMap = null;

    /**
     * @return the extensions
     */
    public String getExtensions() {
        return extensions;
    }

    /**
     * @param extensions the extensions to set
     */
    public void setExtensions(String extensions) {
        this.extensions = extensions;
    }

    /**
     * @return a description of this
     */
    public String getDescription(){
        return "automatically installs and deploys JBI Archives";
    }

    /**
     * @return Returns the monitorInstallationDirectory.
     */
    public boolean isMonitorInstallationDirectory(){
        return monitorInstallationDirectory;
    }

    /**
     * @param monitorInstallationDirectory
     *            The monitorInstallationDirectory to set.
     */
    public void setMonitorInstallationDirectory(boolean monitorInstallationDirectory){
        this.monitorInstallationDirectory=monitorInstallationDirectory;
    }

    /**
     * @return Returns the monitorDeploymentDirectory.
     */
    public boolean isMonitorDeploymentDirectory(){
        return monitorDeploymentDirectory;
    }

    /**
     * @param monitorDeploymentDirectory
     *            The monitorDeploymentDirectory to set.
     */
    public void setMonitorDeploymentDirectory(boolean monitorDeploymentDirectory){
        this.monitorDeploymentDirectory=monitorDeploymentDirectory;
    }

    /**
     * @return Returns the monitorInterval (number in secs)
     */
    public int getMonitorInterval(){
        return monitorInterval;
    }

    /**
     * @param monitorInterval
     *            The monitorInterval to set (in secs)
     */
    public void setMonitorInterval(int monitorInterval){
        this.monitorInterval=monitorInterval;
    }

    public void start() throws javax.jbi.JBIException{
        super.start();
        if(started.compareAndSet(false,true)){
            scheduleDirectoryTimer();
        }
    }

    /**
     * Stop the item. This suspends current messaging activities.
     *
     * @exception javax.jbi.JBIException
     *                if the item fails to stop.
     */
    public void stop() throws javax.jbi.JBIException{
        if(started.compareAndSet(true,false)){
            super.stop();
            if(timerTask!=null){
                timerTask.cancel();
            }
        }
    }

    /**
     * Initialize the Service
     *
     * @param container
     * @throws JBIException
     */
    public void init(JBIContainer container) throws JBIException {
        super.init(container);
        this.environmentContext=container.getEnvironmentContext();
        this.installationService=container.getInstallationService();
        this.deploymentService=container.getDeploymentService();
        //clean-up tmp directory
        if(environmentContext.getTmpDir()!=null){
            FileUtil.deleteFile(environmentContext.getTmpDir());
        }
        initializeFileMaps();
    }
   
    protected Class getServiceMBean() {
        return AutoDeploymentServiceMBean.class;
    }
   
   
    /**
     * load an archive from an external location
     * @param location
     * @param autoStart
     * @throws DeploymentException
     */
    public ArchiveEntry updateExternalArchive(String location,boolean autoStart) throws DeploymentException {
        ArchiveEntry entry = new ArchiveEntry();
        entry.location = location;
        entry.lastModified = new Date();
        updateArchive(location,entry,autoStart);
        return entry;
    }

    /**
     * Update an archive
     *
     * @param location
     * @param autoStart
     * @throws DeploymentException
     */
    public void updateArchive(String location, ArchiveEntry entry, boolean autoStart) throws DeploymentException {
        // Call listeners
        try {
            DeploymentListener[] listeners = (DeploymentListener[]) container.getListeners(DeploymentListener.class);
            DeploymentEvent event = new DeploymentEvent(new File(location), DeploymentEvent.FILE_CHANGED);
            for (int i = 0; i < listeners.length; i++) {
                if (listeners[i].fileChanged(event)) {
                    return;
                }
            }
        } catch (IOException e) {
            throw failure("deploy", "Error when deploying: " + location, e);
        }
        // Standard processing
        File tmpDir = null;
        try {
            tmpDir = AutoDeploymentService.unpackLocation(environmentContext.getTmpDir(), location);
        } catch (Exception e) {
            throw failure("deploy", "Unable to unpack archive: " + location, e);
        }
        // unpackLocation returns null if no jbi descriptor is found
        if (tmpDir == null) {
            throw failure("deploy", "Unable to find jbi descriptor: " + location);
        }
        Descriptor root = null;
        try {
            root = DescriptorFactory.buildDescriptor(tmpDir);
        } catch (Exception e) {
            throw failure("deploy", "Unable to build jbi descriptor: " + location, e);
        }
        if (root == null) {
            throw failure("deploy", "Unable to find jbi descriptor: " + location);
        }
        if (root != null) {
            try{
                container.getBroker().suspend();
                if (root.getComponent() != null) {
                    Component comp = root.getComponent();
                  String componentName = comp.getIdentification().getName();
                  entry.type = "component";
                  entry.name = componentName;
                    try {
                        if (container.getRegistry().getComponent(componentName) != null) {
                          installationService.loadInstaller(componentName);
                            installationService.unloadInstaller(componentName, true);
                        }
                        // See if shared libraries are installed
                        entry.dependencies = getSharedLibraryNames(comp);
                        if (log.isDebugEnabled()) {
                            log.debug("Component dependencies: " + entry.dependencies);
                        }
                        String missings = null;
                        boolean canInstall = true;
                        for (Iterator it = entry.dependencies.iterator(); it.hasNext();) {
                            String libraryName = (String) it.next();
                            if (container.getRegistry().getSharedLibrary(libraryName) == null) {
                                canInstall = false;
                                if (missings != null) {
                                    missings += ", " + libraryName;
                                } else {
                                    missings = libraryName;
                                }
                            }
                        }
                        if (canInstall) {
                            installationService.install(tmpDir, null, root, autoStart);
                            checkPendingSAs();
                        } else {
                            entry.pending = true;
                            log.warn("Shared libraries " + missings + " are not installed yet: the component" + componentName +
                                     " installation is suspended and will be resumed once the listed shared libraries are installed");
                            pendingComponents.put(tmpDir, entry);
                        }
                    } catch (Exception e) {
                        String errStr = "Failed to update Component: " + componentName;
                        log.error(errStr, e);
                        throw new DeploymentException(errStr, e);
                    }
                } else if (root.getSharedLibrary() != null) {
                  String libraryName = root.getSharedLibrary().getIdentification().getName();
                  entry.type = "library";
                  entry.name = libraryName;
                    try {
                        if (container.getRegistry().getSharedLibrary(libraryName) != null) {
                            container.getRegistry().unregisterSharedLibrary(libraryName);
                            environmentContext.removeSharedLibraryDirectory(libraryName);
                        }
                        installationService.doInstallSharedLibrary(tmpDir, root.getSharedLibrary());
                        checkPendingComponents();
                    } catch (Exception e) {
                        String errStr = "Failed to update SharedLibrary: " + libraryName;
                        log.error(errStr, e);
                        throw new DeploymentException(errStr, e);
                    }
                } else if (root.getServiceAssembly() != null) {
                    ServiceAssembly sa = root.getServiceAssembly();
                    String name = sa.getIdentification().getName();
                  entry.type = "assembly";
                  entry.name = name;
                    try {
                        if (deploymentService.isSaDeployed(name)) {
                            deploymentService.shutDown(name);
                            deploymentService.undeploy(name);
                        }
                        // see if components are installed
                        entry.dependencies = getComponentNames(sa);
                        if (log.isDebugEnabled()) {
                            log.debug("SA dependencies: " + entry.dependencies);
                        }
                        String missings = null;
                        boolean canDeploy = true;
                        for (Iterator it = entry.dependencies.iterator(); it.hasNext();) {
                          String componentName = (String) it.next();
                          if (container.getComponent(componentName) == null) {
                            canDeploy = false;
                            if (missings != null) {
                              missings += ", " + componentName;
                            } else {
                              missings = componentName;
                            }
                          }
                        }
                        if (canDeploy) {
                            deploymentService.deployServiceAssembly(tmpDir, sa);
                            if (autoStart){
                                deploymentService.start(name);
                            }
                        } else {
                            // TODO: check that the assembly is not already pending
                          entry.pending = true;
                            log.warn("Components " + missings + " are not installed yet: the service assembly " + name +
                                     " deployment is suspended and will be resumed once the listed components are installed");
                            pendingSAs.put(tmpDir, entry);
                        }
                    } catch (Exception e) {
                        String errStr = "Failed to update Service Assembly: " + name;
                        log.error(errStr, e);
                        throw new DeploymentException(errStr, e);
                    }
                }
            } finally {
                container.getBroker().resume();
            }
        }
    }

    protected DeploymentException failure(String task, String info) {
        return failure(task, info, null, null);
    }
   
    protected DeploymentException failure(String task, String info, Exception e) {
        return failure(task, info, e, null);
    }
   
    protected DeploymentException failure(String task, String info, Exception e, List componentResults) {
        ManagementSupport.Message msg = new ManagementSupport.Message();
        msg.setTask(task);
        msg.setResult("FAILED");
        msg.setType("ERROR");
        msg.setException(e);
        msg.setMessage(info);
        return new DeploymentException(ManagementSupport.createFrameworkMessage(msg, componentResults));
    }

    protected Set getComponentNames(ServiceAssembly sa) {
        Set names = new HashSet();
        if (sa.getServiceUnits() != null && sa.getServiceUnits().length > 0) {
            for (int i = 0; i < sa.getServiceUnits().length; i++) {
                names.add(sa.getServiceUnits()[i].getTarget().getComponentName());
            }
        }
        return names;
    }

    protected Set getSharedLibraryNames(Component comp) {
        Set names = new HashSet();
        if (comp.getSharedLibraries() != null && comp.getSharedLibraries().length > 0) {
            for (int i = 0; i < comp.getSharedLibraries().length; i++) {
                names.add(comp.getSharedLibraries()[i].getName());
            }
        }
        return names;
    }

    /**
     * Remove an archive location
     *
     * @param location
     * @throws DeploymentException
     */
    public void removeArchive(ArchiveEntry entry) throws DeploymentException {
        // Call listeners
        try {
            DeploymentListener[] listeners = (DeploymentListener[]) container.getListeners(DeploymentListener.class);
            DeploymentEvent event = new DeploymentEvent(new File(entry.location), DeploymentEvent.FILE_REMOVED);
            for (int i = 0; i < listeners.length; i++) {
                if (listeners[i].fileRemoved(event)) {
                    return;
                }
            }
        } catch (IOException e) {
            throw failure("deploy", "Error when deploying: " + entry.location, e);
        }
        // Standard processing
        log.info("Attempting to remove archive at: " + entry.location);
        try{
            container.getBroker().suspend();
            if ("component".equals(entry.type)) {
                log.info("Uninstalling component: " + entry.name);
                // Ensure installer is loaded
                installationService.loadInstaller(entry.name);
                // Uninstall and delete component
                installationService.unloadInstaller(entry.name,true);
            }
            if ("library".equals(entry.type)) {
                log.info("Removing shared library: " + entry.name);
                installationService.uninstallSharedLibrary(entry.name);
            }
            if ("assembly".equals(entry.type)) {
                log.info("Undeploying service assembly " + entry.name);
                try{
                    if(deploymentService.isSaDeployed(entry.name)){
                        deploymentService.shutDown(entry.name);
                        deploymentService.undeploy(entry.name);
                    }
                } catch(Exception e) {
                    String errStr = "Failed to update service assembly: "+ entry.name;
                    log.error(errStr,e);
                    throw new DeploymentException(errStr,e);
                }
            }
        } finally {
            container.getBroker().resume();
        }
    }

    /**
     * Called when a component has been installed to see
     * if pending service assemblies have all component
     * installed.
     */
    private void checkPendingSAs() {
      Set deployedSas = new HashSet();
      for (Iterator it = pendingSAs.entrySet().iterator(); it.hasNext();) {
        Map.Entry me = (Map.Entry) it.next();
        ArchiveEntry entry = (ArchiveEntry) me.getValue();
            boolean canDeploy = true;
            for (Iterator it2 = entry.dependencies.iterator(); it2.hasNext();) {
              String componentName = (String) it2.next();
              if (container.getComponent(componentName) == null) {
                canDeploy = false;
                break;
              }
            }
            if (canDeploy) {
                File tmp = (File) me.getKey();
                deployedSas.add(tmp);
                try {
                  Descriptor root = DescriptorFactory.buildDescriptor(tmp);
                  deploymentService.deployServiceAssembly(tmp, root.getServiceAssembly());
                  deploymentService.start(root.getServiceAssembly().getIdentification().getName());
                } catch (Exception e) {
                    String errStr = "Failed to update Service Assembly: " + tmp.getName();
                    log.error(errStr, e);
                }
            }
      }
      if (!deployedSas.isEmpty()) {
        // Remove SA from pending SAs
        for (Iterator it = deployedSas.iterator(); it.hasNext();) {
          ArchiveEntry entry = (ArchiveEntry) pendingSAs.remove(it.next());
          entry.pending = false;
        }
        // Store new state
        persistState(environmentContext.getDeploymentDir(), deployFileMap);
        persistState(environmentContext.getInstallationDir(), installFileMap);
      }
    }
   
    private void checkPendingComponents() {
        Set installedComponents = new HashSet();
        for (Iterator it = pendingComponents.entrySet().iterator(); it.hasNext();) {
            Map.Entry me = (Map.Entry) it.next();
            ArchiveEntry entry = (ArchiveEntry) me.getValue();
            boolean canInstall = true;
            for (Iterator it2 = entry.dependencies.iterator(); it2.hasNext();) {
                String libraryName = (String) it2.next();
                if (container.getRegistry().getSharedLibrary(libraryName) == null) {
                    canInstall = false;
                    break;
                }
            }
            if (canInstall) {
                File tmp = (File) me.getKey();
                installedComponents.add(tmp);
                try {
                    Descriptor root = DescriptorFactory.buildDescriptor(tmp);
                    installationService.install(tmp, null, root, true);
                } catch (Exception e) {
                    String errStr = "Failed to update Component: " + tmp.getName();
                    log.error(errStr, e);
                }
            }
        }
        if (!installedComponents.isEmpty()) {
            // Remove SA from pending SAs
            for (Iterator it = installedComponents.iterator(); it.hasNext();) {
                ArchiveEntry entry = (ArchiveEntry) pendingComponents.remove(it.next());
                entry.pending = false;
            }
            // Store new state
            persistState(environmentContext.getDeploymentDir(), deployFileMap);
            persistState(environmentContext.getInstallationDir(), installFileMap);
            // Check for pending SAs
            checkPendingSAs();
        }
    }

    /**
     * Get an array of MBeanAttributeInfo
     *
     * @return array of AttributeInfos
     * @throws JMException
     */
    public MBeanAttributeInfo[] getAttributeInfos() throws JMException{
        AttributeInfoHelper helper=new AttributeInfoHelper();
        helper.addAttribute(getObjectToManage(),"monitorInstallationDirectory",
                        "Periodically monitor the Installation directory");
        helper.addAttribute(getObjectToManage(),"monitorInterval","Interval (secs) before monitoring");
        return AttributeInfoHelper.join(super.getAttributeInfos(),helper.getAttributeInfos());
    }

    /**
     * Unpack a location into a temp file directory.
     * If the location does not contain a jbi descritor, no unpacking occurs.
     *
     * @param location
     * @return tmp directory (if location contains a jbi descriptor)
     * @throws DeploymentException
     */
    protected static File unpackLocation(File tmpRoot, String location) throws DeploymentException {
        File tmpDir = null;
        try {
            File file = new File(location);
            if (file.isDirectory()) {
                if (log.isDebugEnabled()) {
                    log.debug("Deploying an exploded jar/zip, we will create a temporary jar for it.");
                }
                // If we have a directory then we should move it over
                File newFile = new File(tmpRoot.getAbsolutePath() + "/exploded.jar");
                newFile.delete();
                FileUtil.zipDir(file.getAbsolutePath(), newFile.getAbsolutePath());
                file = newFile;
                if (log.isDebugEnabled()) {
                    log.debug("Deployment will now work from " + file.getAbsolutePath());
                }
            }
            if (!file.exists()) {
                // assume it's a URL
                try{
                    URL url = new URL(location);
                    String fileName = url.getFile();
                    if (fileName == null) {
                        throw new DeploymentException("Location: " + location + " is not an archive");
                    }
                    file = FileUtil.unpackArchive(url,tmpRoot);
                } catch (MalformedURLException e) {
                    throw new DeploymentException(e);
                }
            }
            if (FileUtil.archiveContainsEntry(file, DescriptorFactory.DESCRIPTOR_FILE)) {
                tmpDir = FileUtil.createUniqueDirectory(tmpRoot, file.getName());
                FileUtil.unpackArchive(file, tmpDir);
                if (log.isDebugEnabled()) {
                    log.debug("Unpacked archive " + location + " to " + tmpDir);
                }
            }
        } catch (IOException e) {
            throw new DeploymentException(e);
        }
        return tmpDir;
    }

    private void scheduleDirectoryTimer(){
        if (!container.isEmbedded() && (isMonitorInstallationDirectory() || isMonitorDeploymentDirectory())) {
            if(statsTimer==null){
                statsTimer=new Timer(true);
            }
            if(timerTask!=null){
                timerTask.cancel();
            }
            timerTask=new TimerTask(){
                public void run(){
                    if(isMonitorInstallationDirectory()){
                        monitorDirectory(environmentContext.getInstallationDir(),installFileMap);
                    }
                    if(isMonitorDeploymentDirectory()){
                        monitorDirectory(environmentContext.getDeploymentDir(),deployFileMap);
                    }
                }
            };
            long interval=monitorInterval*1000;
            statsTimer.scheduleAtFixedRate(timerTask,0,interval);
        }
    }


    private void monitorDirectory(final File root, final Map fileMap) {
        /*
        if (log.isTraceEnabled()) {
            if (root != null)
                log.trace("Monitoring directory " + root.getAbsolutePath() + " for new or modified archives");
            else
                log.trace("No directory to monitor for new or modified archives for "
                                + ((fileMap==installFileMap) ? "Installation" : "Deployment") + ".");
        }
        */
        List tmpList=new ArrayList();
        if(root!=null&&root.exists()&&root.isDirectory()){
            File[] files=root.listFiles();
            if(files!=null){
                for(int i=0;i<files.length;i++){
                    final File file=files[i];
                    tmpList.add(file.getName());
                    if (isAllowedExtension(file.getName())) {
                        ArchiveEntry lastEntry = (ArchiveEntry) fileMap.get(file.getName());
                        if(lastEntry == null || file.lastModified() > lastEntry.lastModified.getTime()){
                            try{
                              final ArchiveEntry entry = new ArchiveEntry();
                              entry.location = file.getName();
                              entry.lastModified = new Date(file.lastModified());
                              fileMap.put(file.getName(), entry);
                                log.info("Directory: "+root.getName()+": Archive changed: processing "
                                                +file.getName()+" ...");
                                updateArchive(file.getAbsolutePath(), entry, true);
                                log.info("Directory: "+root.getName()+": Finished installation of archive:  "
                                        +file.getName());
                            }catch(Exception e){
                                log.warn("Directory: "+root.getName()+": Automatic install of "+file
                                                +" failed",e);
                            }finally{
                                persistState(root, fileMap);
                            }
                        }
                    }
                }
            }
            // now remove any locations no longer here
            Map map=new HashMap(fileMap);
            for(Iterator i=map.keySet().iterator();i.hasNext();){
                String location=i.next().toString();
                if(!tmpList.contains(location)){
                    ArchiveEntry entry = (ArchiveEntry) fileMap.remove(location);
                    try{
                        log.info("Location "+location+" no longer exists - removing ...");
                        removeArchive(entry);
                    } catch (DeploymentException e) {
                        log.error("Failed to removeArchive: "+location,e);
                    }
                }
            }
            if (!map.equals(fileMap)){
                persistState(root, fileMap);
            }
        }
    }

    private boolean isAllowedExtension(String file) {
        String[] extensions = this.extensions.split(",");
        for (int i = 0; i < extensions.length; i++) {
            if (file.endsWith(extensions[i])) {
                return true;
            }
        }
        return false;
    }

    private void persistState(File root, Map map) {
        try {
            File file = new File(environmentContext.getJbiRootDir(), root.getName() + ".xml");
            XmlPersistenceSupport.write(file, map);
        } catch (IOException e) {
            log.error("Failed to persist file state to: " + root, e);
        }
    }

    private Map readState(File root) {
        Map result = new HashMap();
        try {
            File file = new File(environmentContext.getJbiRootDir(), root.getName() + ".xml");
            if (file.exists()) {
                result = (Map) XmlPersistenceSupport.read(file);
            } else {
                log.debug("State file doesn't exist: " + file.getPath());
            }
        } catch (Exception e) {
            log.error("Failed to read file state from: " + root, e);
        }
        return result;
    }

    private void initializeFileMaps(){
        if (isMonitorInstallationDirectory() && !container.isEmbedded()) {
            try {
                installFileMap=readState(environmentContext.getInstallationDir());
                removePendingEntries(installFileMap);
            } catch (Exception e) {
                log.error("Failed to read installed state", e);
            }
        }
        if (isMonitorDeploymentDirectory() && !container.isEmbedded()) {
            try {
                deployFileMap=readState(environmentContext.getDeploymentDir());
                removePendingEntries(deployFileMap);
            } catch (Exception e) {
                log.error("Failed to read deployed state", e);
            }
        }
    }
   
    private void removePendingEntries(Map map) {
        Set pendings = new HashSet();
        for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
          Map.Entry e = (Map.Entry) it.next();
          if (((ArchiveEntry) e.getValue()).pending) {
            pendings.add(e.getKey());
          }
        }
        for (Iterator it = pendings.iterator(); it.hasNext();) {
          map.remove(it.next());
        }
    }
   
    public static class ArchiveEntry {
      public String location;
      public Date lastModified;
      public String type;
      public String name;
      public boolean pending;
      public transient Set dependencies;
    }
}
TOP

Related Classes of org.apache.servicemix.jbi.framework.AutoDeploymentService

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.