[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