package org.jboss.deployment.scanner;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
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.Set;
import java.util.StringTokenizer;
import org.jboss.deployment.IncompleteDeploymentException;
import org.jboss.deployment.NetBootFile;
import org.jboss.deployment.NetBootHelper;
import org.jboss.util.NullArgumentException;
public class HttpURLDeploymentScanner
extends URLDeploymentScanner
implements HttpURLDeploymentScannerMBean
{
protected String defaultHttpDirectoryListerUrl = null;
protected String httpDirectoryDownload = null;
protected HttpLister defaultHttpLister = null;
protected HashMap scannedHttpUrls = new HashMap ();
public HttpURLDeploymentScanner () { super (); }
public String getDefaultHttpDirectoryListerUrl ()
{
if (defaultHttpDirectoryListerUrl == null)
defaultHttpDirectoryListerUrl = NetBootHelper.getDefaultListUrl ();
return this.defaultHttpDirectoryListerUrl;
}
public void setDefaultHttpDirectoryListerUrl (String url)
{
this.defaultHttpDirectoryListerUrl = url;
}
public String getDefaultHttpDirectoryDownloadUrl ()
{
if (httpDirectoryDownload == null)
httpDirectoryDownload = NetBootHelper.getDefaultDownloadUrl ();
return this.httpDirectoryDownload;
}
public void setDefaultHttpDirectoryDownloadUrl (String url)
{
this.httpDirectoryDownload = url;
}
public void setURLList(final List list)
{
}
public void setURLs(final String listspec) throws MalformedURLException
{
if (listspec == null)
throw new NullArgumentException("listspec");
boolean debug = log.isDebugEnabled();
List fileList = new LinkedList();
StringTokenizer stok = new StringTokenizer(listspec, ",");
while (stok.hasMoreTokens())
{
String urlspec = stok.nextToken().trim();
if (debug)
{
log.debug("Adding URL from spec: " + urlspec);
}
if (urlspec.startsWith ("file:") || urlspec.startsWith ("http:"))
{
URL url = makeURL(urlspec);
if (debug) log.debug("File URL: " + url);
fileList.add(url);
}
else
{
URL url = makeURL(urlspec);
if (debug) log.debug("HTTP URL: " + url);
addHttpDeployment (urlspec, this.getDefaultHttpDirectoryLister ());
}
}
super.setURLList(fileList);
}
public synchronized void scan() throws Exception
{
super.scan ();
boolean trace = log.isTraceEnabled();
if (trace) log.trace("Scanning for new http deployments");
synchronized (scannedHttpUrls)
{
Iterator listers = this.getAllDeploymentListers().iterator ();
while (listers.hasNext ())
{
HttpLister lister = (HttpLister)listers.next ();
Iterator deployments = this.getHttpDeploymentsForLister (lister).iterator ();
while (deployments.hasNext ())
{
HttpDeploymentFolder deploymentFolder = (HttpDeploymentFolder)deployments.next ();
scanRemoteDirectory (deploymentFolder);
}
}
}
if (trace) log.trace("Scanning existing deployments for removal or modification");
List removed = new LinkedList();
List modified = new LinkedList();
Iterator listers = this.getAllDeploymentListers().iterator ();
while (listers.hasNext ())
{
HttpLister lister = (HttpLister)listers.next ();
Iterator deployments = this.getHttpDeploymentsForLister (lister).iterator ();
while (deployments.hasNext ())
{
HttpDeploymentFolder deploymentFolder = (HttpDeploymentFolder)deployments.next ();
NetBootFile[] remoteFiles = NetBootHelper.listFilesFromDirectory (deploymentFolder.getCompleteListingUrl ());;
Iterator deployedFiles = deploymentFolder.getDeployedFiles ().iterator ();
while (deployedFiles.hasNext ())
{
DeployedRemoteURL deployed = (DeployedRemoteURL)deployedFiles.next ();
NetBootFile alreadyDeployed = findFileWithName (deployed.getFile ().getName (), remoteFiles);
if (alreadyDeployed == null)
{
removed.add (deployed);
}
else if (alreadyDeployed.LastModified () > deployed.getFile ().LastModified ())
{
deployed.updateFile (alreadyDeployed); modified.add (deployed);
}
}
}
}
for (Iterator iter=removed.iterator(); iter.hasNext();)
{
DeployedRemoteURL du = (DeployedRemoteURL)iter.next();
undeploy(du);
}
for (Iterator iter=modified.iterator(); iter.hasNext();)
{
DeployedRemoteURL du = (DeployedRemoteURL)iter.next();
undeploy(du);
deploy(du);
}
if( lastIncompleteDeploymentException != null )
{
try
{
Object[] args = {};
String[] sig = {};
Object o = getServer().invoke(getDeployer(),
"checkIncompleteDeployments", args, sig);
}
catch (Exception e)
{
log.error(e);
}
}
}
protected void scanRemoteDirectory(HttpDeploymentFolder httpFolder) throws Exception
{
boolean trace = log.isTraceEnabled();
if (trace) log.trace("Scanning directory: " + httpFolder.getRelativeFolder ());
NetBootFile[] content = null;
try
{
content = NetBootHelper.listFilesFromDirectory (httpFolder.getCompleteListingUrl ());
}
catch (Exception e)
{
log.trace(e);
return;
}
List list = new LinkedList();
HashMap linkNameToObjects = new HashMap ();
for (int i = 0; i < content.length; i++)
{
if (trace) log.trace("Checking deployment file: " + content[i]);
NetBootFile found = findFileWithName(content[i].getName (), httpFolder.getDeployedFiles());
if (found == null)
{
URL target = httpFolder.getUrlForFile (content[i]);
list.add(target);
linkNameToObjects.put (target, content[i]);
}
}
if (sorter != null)
{
updateSorter();
Collections.sort(list, sorter);
}
Iterator iter = list.iterator();
while (iter.hasNext())
{
URL url = (URL)iter.next();
NetBootFile dep = (NetBootFile)linkNameToObjects.get (url);
deploy( new DeployedRemoteURL(httpFolder, dep) );
iter.remove();
if (sorter != null && iter.hasNext() && updateSorter())
{
Collections.sort(list, sorter);
iter = list.iterator();
}
}
}
protected void undeploy(DeployedRemoteURL deployedUrl)
{
URL url = null;
try
{
url = deployedUrl.getFolder ().getUrlForFile (deployedUrl.getFile ());
if (log.isTraceEnabled()) log.trace("Undeploying: " + url);
deployer.undeploy(url);
deployedUrl.getFolder ().removeDeployedFile (deployedUrl);
}
catch (Exception e)
{
log.error("Failed to undeploy: " + url, e);
}
}
protected void deploy(DeployedRemoteURL deployedUrl)
throws MalformedURLException
{
URL url = deployedUrl.getFolder ().getUrlForFile (deployedUrl.getFile ());
if( url == null ) return;
if (log.isTraceEnabled()) log.trace("Deploying: " + url);
try
{
deployer.deploy(url);
}
catch (IncompleteDeploymentException e)
{
lastIncompleteDeploymentException = e;
}
catch (Exception e)
{
log.error("Failed to deploy: " + url, e);
}
deployedUrl.getFolder ().addDeployedFile (deployedUrl);
}
protected NetBootFile findFileWithName (String name, NetBootFile[] files)
{
for (int i=0; i<files.length; i++)
{
if (files[i].getName ().equals (name))
return files[i];
}
return null;
}
protected NetBootFile findFileWithName (String name, List deployedRemoteURL)
{
NetBootFile[] tmp = new NetBootFile[deployedRemoteURL.size ()];
Iterator iter = deployedRemoteURL.iterator ();
int i=0;
while (iter.hasNext())
{
DeployedRemoteURL url = (DeployedRemoteURL)iter.next ();
tmp[i] = url.getFile ();
i++;
}
return findFileWithName(name, tmp);
}
protected synchronized void addHttpDeployment (String relativeName, HttpLister lister)
{
ArrayList deps = (ArrayList)scannedHttpUrls.get (lister);
if (deps == null)
{
deps = new ArrayList();
scannedHttpUrls.put (lister, deps);
}
deps.add (new HttpDeploymentFolder (relativeName, lister));
}
protected List getHttpDeploymentsForLister (HttpLister lister)
{
ArrayList deps = (ArrayList)scannedHttpUrls.get (lister);
if (deps == null)
{
deps = new ArrayList();
}
return deps;
}
protected Set getAllDeploymentListers ()
{
return this.scannedHttpUrls.keySet ();
}
protected HttpLister getDefaultHttpDirectoryLister ()
{
if (defaultHttpLister == null)
defaultHttpLister = new HttpLister (getDefaultHttpDirectoryDownloadUrl(),
getDefaultHttpDirectoryListerUrl());
return this.defaultHttpLister;
}
protected class HttpLister
{
public String downloadUrl = null;
public String httpListerUrl = null;
public HttpLister (String download, String list)
{
downloadUrl = download;
httpListerUrl = list;
}
public String getDownloadUrl () { return this.downloadUrl; }
public String getHttpListerUrl () { return this.httpListerUrl; }
public int hashCode () { return this.httpListerUrl.hashCode (); }
public boolean equals (Object obj)
{
if (obj instanceof HttpLister)
return ((HttpLister)obj).httpListerUrl.equals (this.httpListerUrl);
else
return false;
}
}
protected class HttpDeploymentFolder
{
public String folder = null;
public HttpLister myLister = null;
public ArrayList deployedFiles = new ArrayList ();
public HttpDeploymentFolder (String folder, HttpLister accessor)
{
this.folder = folder;
this.myLister = accessor;
}
public String getRelativeFolder () { return this.folder; }
public HttpLister getAssociatedLister () { return this.myLister; }
public void addDeployedFile (DeployedRemoteURL file) { deployedFiles.add (file); }
public void removeDeployedFile (DeployedRemoteURL file) { deployedFiles.remove (file); }
public List getDeployedFiles () { return this.deployedFiles; }
public String getCompleteListingUrl ()
throws UnsupportedEncodingException
{
return NetBootHelper.buildListUrlForFolder (this.myLister.getHttpListerUrl (), this.folder);
}
public URL getUrlForFile (NetBootFile file)
throws MalformedURLException
{
return new URL (NetBootHelper.buildDownloadUrlForFile (this.myLister.getDownloadUrl (),
this.folder,
file.getName ()));
}
}
protected class DeployedRemoteURL
{
HttpDeploymentFolder folder = null;
NetBootFile file = null;
public DeployedRemoteURL (HttpDeploymentFolder folder, NetBootFile file)
{
this.folder = folder;
this.file = file;
}
public HttpDeploymentFolder getFolder () { return this.folder; }
public NetBootFile getFile () { return this.file; }
public void updateFile (NetBootFile newer) { this.file = newer; }
}
}