[jboss-cvs] system2/src/main/org/jboss/deployers/plugins/scanner ...

Scott Stark scott.stark at jboss.com
Thu Jul 13 22:32:32 EDT 2006


  User: starksm 
  Date: 06/07/13 22:32:32

  Added:       src/main/org/jboss/deployers/plugins/scanner 
                        VFSDeploymentScannerImpl.java
  Log:
  A VFSDeploymentScanner that uses the MainDeployer directly
  
  Revision  Changes    Path
  1.1      date: 2006/07/14 02:32:32;  author: starksm;  state: Exp;system2/src/main/org/jboss/deployers/plugins/scanner/VFSDeploymentScannerImpl.java
  
  Index: VFSDeploymentScannerImpl.java
  ===================================================================
  /*
   * JBoss, Home of Professional Open Source
   * Copyright 2005, JBoss Inc., and individual contributors as indicated
   * by the @authors tag. See the copyright.txt in the distribution for a
   * full listing of individual contributors.
   *
   * This is free software; you can redistribute it and/or modify it
   * under the terms of the GNU Lesser General Public License as
   * published by the Free Software Foundation; either version 2.1 of
   * the License, or (at your option) any later version.
   *
   * This software is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
   * Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
   * License along with this software; if not, write to the Free
   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
   */
  package org.jboss.deployers.plugins.scanner;
  
  import java.io.IOException;
  import java.net.MalformedURLException;
  import java.net.URI;
  import java.net.URISyntaxException;
  import java.net.URL;
  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.LinkedList;
  import java.util.List;
  import java.util.Map;
  import java.util.StringTokenizer;
  
  import org.jboss.deployers.spi.Deployment;
  import org.jboss.deployers.spi.MainDeployer;
  import org.jboss.deployment.IncompleteDeploymentException;
  import org.jboss.deployment.scanner.VFSDeploymentScanner;
  import org.jboss.util.JBossObject;
  import org.jboss.util.StringPropertyReplacer;
  import org.jboss.vfs.VFSFactory;
  import org.jboss.vfs.spi.ReadOnlyVFS;
  import org.jboss.vfs.spi.VirtualFile;
  import org.jboss.vfs.spi.VirtualFileFilter;
  
  
  /**
   * A DeploymentScanner build on top of the VFS and MainDeployer. This is a
   * first pass to flesh out the APIs/concepts.
   * 
   * @author <a href="mailto:dimitris at jboss.org">Dimitris Andreadis</a>
   * @author Scott.Stark at jboss.org
   * @version $Revision$
   */
  public class VFSDeploymentScannerImpl
     extends JBossObject
     implements VFSDeploymentScanner
  {
     // Private Data --------------------------------------------------
     private MainDeployer mainDeployer;
     /** The VFSFactory used to obtain deployment VFS */
     private VFSFactory factory;
  
     private VirtualFileFilter filter;
  
     /** The URIfied ServerHomeURL */
     private URI serverHomeURI;
     
     /** The list of URIs to scan */
     private List<URI> uriList = Collections.synchronizedList(new ArrayList());
     
     /** The list of VirtualFiles to scan */
     private List<VirtualFile> vdfList = Collections.synchronizedList(new ArrayList());
     
     /** Whether to search for files inside directories whose names containing no dots */
     private boolean doRecursiveSearch = true;
     
     /** A set of scanned VirtualFiles which have been deployed */
     private Map<VirtualFile, Deployment> deployedMap = Collections.synchronizedMap(new HashMap());
  
     /** Remember the last exception for reporting */
     private IncompleteDeploymentException lastIncompleteDeploymentException;   
     
     // Constructor ---------------------------------------------------
     
     public VFSDeploymentScannerImpl()
     {
        // empty
     }
     
     // Attributes ----------------------------------------------------
  
     public void setMainDeployer(MainDeployer deployer)
     {
        this.mainDeployer = deployer;
        this.factory = mainDeployer.getVFSFactory();
     }
  
     /**
      * @return Returns the factory.
      */
     public VFSFactory getVFSFactory()
     {
        return this.factory;
     }
  
     public VirtualFileFilter getFilter()
     {
        return filter;
     }
     public void setFilter(VirtualFileFilter filter)
     {
        this.filter = filter;
     }
  
     /**
      * @param factory The factory to set.
      */
     public void setVFSFactory(VFSFactory factory)
     {
        this.factory = factory;
     }
  
     /* (non-Javadoc)
      * @see org.jboss.deployment.scanner.VFSDeploymentScanner#getScanPeriod()
      */
     public long getScanPeriod()
     {
        // TODO Auto-generated method stub
        return 0;
     }
  
     /* (non-Javadoc)
      * @see org.jboss.deployment.scanner.VFSDeploymentScanner#isScanEnabled()
      */
     public boolean isScanEnabled()
     {
        // TODO Auto-generated method stub
        return false;
     }
  
     /* (non-Javadoc)
      * @see org.jboss.deployment.scanner.VFSDeploymentScanner#setScanEnabled(boolean)
      */
     public void setScanEnabled(boolean flag)
     {
        // TODO Auto-generated method stub
        
     }
  
     /* (non-Javadoc)
      * @see org.jboss.deployment.scanner.VFSDeploymentScanner#setScanPeriod(long)
      */
     public void setScanPeriod(long period)
     {
        // TODO Auto-generated method stub
        
     }
  
      /**
      * @throws URISyntaxException
      * @throws IOException
      */
     public void setURIs(final String listspec) throws URISyntaxException, IOException
     {
        if (listspec == null)
        {
           throw new NullPointerException("listspec argument cannot be null");
        }
        List<URI> list = new LinkedList<URI>();
     
        StringTokenizer stok = new StringTokenizer(listspec, ",");
        while (stok.hasMoreTokens())
        {
           String urispec = stok.nextToken().trim();
     
           log.debug("Adding URI from spec: " + urispec);
     
           URI uri = makeURI(urispec);
  
           log.debug("URI: " + uri);
  
           list.add(uri);
        }
        setURIList(list);
     }
  
     /**
      * 
      * @throws IOException
      */
     public void setURIList(final List<URI> list) throws IOException
     {
        if (list == null)
        {
           throw new NullPointerException("list argument cannot be null");
        }
     
        // start out with a fresh list
        uriList.clear();
     
        for(int n = 0; n < list.size(); n ++)
        {
           URI uri = list.get(n);
           if (uri == null)
           {
              throw new IllegalArgumentException("list element["+n+"] is null");
           }
           addURI(uri);
        }
        log.debug("URI list: " + uriList);
     }
     
     /**
      * @jmx:managed-attribute
      */
     public List<URI> getURIList()
     {
        return new ArrayList<URI>(uriList);
     }
  
     /**
      * @jmx:managed-attribute
      */
     public void setRecursiveSearch(boolean recurse)
     {
        doRecursiveSearch = recurse;
     }
     
     /**
      * @jmx:managed-attribute
      */
     public boolean getRecursiveSearch()
     {
        return doRecursiveSearch;
     }
  
     // Operations ----------------------------------------------------
     
     /**
      * @jmx:managed-operation
      */
     public void addURI(final URI uri) throws IOException
     {
        if (uri == null)
        {
           throw new NullPointerException("uri argument cannot be null");
        }
        if( uriList.add(uri) == true )
        {
           log.debug("Added URI: " + uri);
           if (factory != null)
           {
              URL rootURL = uri.toURL();
              ReadOnlyVFS vfs = factory.getVFS(rootURL);
              VirtualFile vf = vfs.resolveFile("");
              vdfList.add(vf);
           }
        }      
     }
  
     /**
      * @jmx:managed-operation
      */
     public void removeURI(final URI uri)
        throws IOException
     {
        if (uri == null)
        {
           throw new NullPointerException("uri argument cannot be null");
        }
        if (factory != null)
        {
           VirtualFile vf = getVFforURI(uri);
           vdfList.remove(vf);
        }
        boolean success = uriList.remove(uri);
        
        if (success)
        {
           log.debug("Removed URI: " + uri);
        }
     }
     
     /**
      * @jmx:managed-operation
      */
     public boolean hasURI(final URI uri)
     {
        if (uri == null)
        {
           throw new NullPointerException("uri argument cannot be null");
        }
        return uriList.contains(uri);
     }
  
     public void start() throws Exception
     {
        // synchronize uriList and vdfList because only at this point
        // setVirtualFileFactory() injection has been performed
        if (factory != null)
        {
           vdfList.clear();
           for (Iterator<URI> i = uriList.iterator(); i.hasNext(); )
           {
              URI uri = i.next();
              VirtualFile vf = this.getVFforURI(uri);
              vdfList.add(vf);
           }
        }
     }
  
     // AbstractDeploymentScanner overrides ---------------------------
     
     public synchronized void scan() throws Exception
     {
        if (vdfList == null)
        {
           throw new IllegalStateException("not initialized");
        }
     
        boolean trace = log.isTraceEnabled();
        lastIncompleteDeploymentException = null;
      
        // Scan for deployments
        if (trace)
        {
           log.trace("Scanning for new deployments");
        }
  
        // VirtualFiles to deploy
        List<VirtualFile> toDeployList = new LinkedList<VirtualFile>();
        synchronized (vdfList)
        {
           for (Iterator i = vdfList.iterator(); i.hasNext();)
           {
              VirtualFile component = (VirtualFile)i.next();
              
              if (component.isFile())
              {
                 // treat this as a deployable unit
                 toDeployList.add(component);
              }
              else if (component.isDirectory())
              {
                 // process (possibly recursively) the dir
                 addDeployments(toDeployList, component);
              }
           }
        }
  
        if (trace)
        {
           log.trace("toDeployList");
           for (Iterator i = toDeployList.iterator(); i.hasNext();)
           {
              log.trace(i.next());
           }
        }
        LinkedList<VirtualFile> toRemoveList = new LinkedList<VirtualFile>();
        LinkedList<VirtualFile> toCheckForUpdateList = new LinkedList<VirtualFile>();
  
        synchronized (deployedMap)
        {
           // remove previously deployed URLs no longer needed
           Iterator<VirtualFile> iter = deployedMap.keySet().iterator();
           while( iter.hasNext() )
           {
              VirtualFile vf = iter.next();
              if (toDeployList.contains(vf))
              {
                 toCheckForUpdateList.add(vf);
              }
              else
              {
                 toRemoveList.add(vf);
              }
           }
        }
  
        // ********
        // Undeploy
        // ********
     
        for (Iterator i = toRemoveList.iterator(); i.hasNext();)
        {
           VirtualFile deployedComponent = (VirtualFile)i.next();
           undeploy(deployedComponent);
        }
  
        // ********
        // Redeploy
        // ********
  
        // compute the DeployedURL list to update
        ArrayList<VirtualFile> toUpdateList = new ArrayList<VirtualFile>(toCheckForUpdateList.size());
        for (Iterator i = toCheckForUpdateList.iterator(); i.hasNext();)
        {
           VirtualFile deployedComponent = (VirtualFile)i.next();
           if (isModified(deployedComponent))
           {
              if (trace)
              {
                 log.trace("Re-deploying " + deployedComponent);
              }
              toUpdateList.add(deployedComponent);
           }
        }
  
        // sort to update list
        //Collections.sort(toUpdateList, sorter);
  
        // Undeploy in order
        for (int i = toUpdateList.size() - 1; i >= 0; i--)
        {
           VirtualFile vf = toUpdateList.get(i);
           undeploy(vf);
        }
  
        // Deploy in order
        for (int i = 0; i < toUpdateList.size(); i++)
        {
           VirtualFile vf = toUpdateList.get(i);
           deploy(vf);
        }
     
        // ******
        // Deploy
        // ******
  
        //Collections.sort(toDeployList, sorter);
        for (Iterator i = toDeployList.iterator(); i.hasNext();)
        {
           VirtualFile vf = (VirtualFile)i.next();
           
           // if component is not deployed already, deploy it
           if (!deployedMap.containsKey(vf))
           {
              deploy(vf);
           }
  
           // component must have been deployed by now, so remove it from list 
           i.remove();
           
           /* Check to see if mainDeployer suffix list has changed, if so, then resort
           if (i.hasNext() && updateSorter())
           {
              Collections.sort(toDeployList, sorter);
              i = toDeployList.iterator();
           }
           */
        }
     
        /* TODO: Validate that there are still incomplete deployments
        if (lastIncompleteDeploymentException != null)
        {
           try
           {
              Object[] args = {};
              String[] sig = {};
              getServer().invoke(getDeployer(), "checkIncompleteDeployments", args, sig);
           }
           catch (Exception e)
           {
              Throwable t = JMXExceptionDecoder.decode(e);
              log.error(t);
           }
        }
        */
     }
        
     // Private -------------------------------------------------------
     
      /**
       * A helper to make a URI from a full/partial urispec
       */
     private URI makeURI(String urispec) throws URISyntaxException
     {
        // First replace URI with appropriate properties
        urispec = StringPropertyReplacer.replaceProperties(urispec);
        return serverHomeURI.resolve(urispec);
     }
     
     /**
      * A helper to find all deployments under a directory component
      * and add them to the supplied list.
      * 
      * We may recurse.
      */
     private void addDeployments(List<VirtualFile> list, VirtualFile root)
        throws IOException
     {
        VirtualFile[] components = root.getChildren();
        
        for (int i = 0; i < components.length; i++)
        {
           VirtualFile vf = components[i];
           
           if (vf.isFile())
           {
              // the first arg in filter.accept is not used!
              if (filter == null || filter.accepts(vf))
              {
                 list.add(vf);
              }            
           }
           else if (vf.isDirectory())
           {
              if (vf.getName().indexOf('.') == -1 && this.doRecursiveSearch)
              {
                 // recurse if not '.' in name and recursive search is enabled
                 addDeployments(list, vf);
              }
              else
              {
                 list.add(vf);
              }
           }
        }
     }
  
     /**
      * A helper to deploy the given vf using the deployer.
      */
     private void deploy(final VirtualFile vf)
     {
        // If the deployer is null simply ignore the request
        log.debug("Deploying: " + vf);
        Deployment deployment = null;
        try
        {
           URL componentUrl = vf.toURL();
           deployment = mainDeployer.parse(componentUrl);
           mainDeployer.deploy(deployment);
        }
        catch (MalformedURLException e)
        {
           log.warn("Cannot convert to URL", e);
           return;
        }
        catch (Exception e)
        {
           log.debug("Failed to deploy: " + vf, e);
        }
  
        String watchPath = getWatchURL(deployment);
        VirtualFile watchComponent = null;
        long deployedLastModified = -1;
        try
        {
           if (watchPath != null)
           {
              watchComponent = vf.findChild(watchPath);
              deployedLastModified = watchComponent.getLastModified();
           }
           else
           {
              deployedLastModified = vf.getLastModified();
           }
        }
        catch (IOException e)
        {
           log.warn(e);
        }
        //vf.setContext(new ComponentContext(watchComponent, deployedLastModified));
     
        if (!deployedMap.containsKey(vf))
        {
           deployedMap.put(vf, deployment);
        }
     }
     
     /**
      * A helper to undeploy the given vf using the deployer.
      */
     private void undeploy(final VirtualFile vf)
     {
        try
        {
           log.debug("Undeploying: " + vf);
           Deployment deployment = deployedMap.remove(vf);
           mainDeployer.undeploy(deployment);
        }
        catch (Exception e)
        {
           log.error("Failed to undeploy: " + vf, e);
        }
     }      
     
     /**
      * Helper to get the watchURL for a deployment, if different.
      * Returns null otherwise
      */
     private String getWatchURL(Deployment deployment)
     {
        String watchPath = (String) deployment.getRootContext().getContextData().get("");
        return watchPath;
     }
  
     /**
      * Helper to find out if a deployed vf has been modified
      * TODO: How should this be implemented
      */
     public boolean isModified(VirtualFile vf)
     {
        // get the context stored with every deployed vf
        ComponentContext cc = null; //(ComponentContext)vf.getContext();
        
        // get modification time at the time of deployment
        long deployedLastModified = cc.deployedLastModified;
        
        // find out the current lastModified time either from
        // the vf or the watched vf, if exists
        long lastModified = (cc.watchComponent != null) ? cc.watchComponent.getLastModified() 
                                                        : vf.getLastModified();
  
         return deployedLastModified != lastModified;
      }
     
     private VirtualFile getVFforURI(URI uri)
        throws IOException
     {
        VirtualFile vf = null;
        if (factory != null)
        {
           URL rootURL = uri.toURL();
           ReadOnlyVFS vfs = factory.getVFS(rootURL);
           vf = vfs.resolveFile("");
        }
        return vf;
     }
  
     /**
      * Simple holder class to let us store extra info
      * on a VirtualFile object
      */
     private static class ComponentContext
     {
        public VirtualFile watchComponent;
        public long deployedLastModified;
        
        public ComponentContext(VirtualFile watchComponent, long deployedLastModified)
        {
           this.watchComponent = watchComponent;
           this.deployedLastModified = deployedLastModified;
        }
     }
  
  }
  
  
  



More information about the jboss-cvs-commits mailing list