package net.sourceforge.javautil.web.server.deployer;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import net.sourceforge.javautil.common.exception.ThrowableManagerRegistry;
import net.sourceforge.javautil.common.io.IVirtualArtifact;
import net.sourceforge.javautil.common.io.IVirtualDirectory;
import net.sourceforge.javautil.deployer.DeployerEvent.Type;
import net.sourceforge.javautil.deployer.artifact.LinkedDeployment;
import net.sourceforge.javautil.deployer.artifact.IVirtualArtifactDeployer;
import net.sourceforge.javautil.deployer.artifact.VirtualArtifactDeployerException;
import net.sourceforge.javautil.deployer.artifact.IVirtualArtifactDeployerListener;
import net.sourceforge.javautil.deployer.artifact.IVirtualArtifactDeployment;
import net.sourceforge.javautil.deployer.artifact.IVirtualArtifactDeploymentContext;
import net.sourceforge.javautil.deployer.artifact.IVirtualArtifactDeploymentPattern;
import net.sourceforge.javautil.deployer.artifact.impl.VirtualArtifactDeployerBase;
import net.sourceforge.javautil.deployer.artifact.impl.VirtualArtifactDeploymentBase;
import net.sourceforge.javautil.deployer.artifact.impl.VirtualArtifactPatternDeployerAbstract;
import net.sourceforge.javautil.web.server.IWebServer;
import net.sourceforge.javautil.web.server.WebServerApplicationErrorEvent;
import net.sourceforge.javautil.web.server.WebServerApplicationEvent;
import net.sourceforge.javautil.web.server.WebServerErrorEvent;
import net.sourceforge.javautil.web.server.WebServerEvent;
import net.sourceforge.javautil.web.server.IWebServerHost;
import net.sourceforge.javautil.web.server.IWebServerListener;
import net.sourceforge.javautil.web.server.application.IWebApplication;
import net.sourceforge.javautil.web.server.application.impl.WebApplicationStandard;
import net.sourceforge.javautil.web.server.deployer.WebApplicationServerDescriptor.WebApplicationExtensionDescriptor;
import net.sourceforge.javautil.web.server.descriptor.impl.WebXml;
import net.sourceforge.javautil.web.server.impl.WebServerAdapter;
/**
* A deployer that can deploy {@link IWebApplication}'s based on {@link IVirtualArtifact}'s.
*
* @author elponderador
* @author $Author: ponderator $
* @version $Id: WebApplicationDeployer.java 2728 2011-01-31 00:12:30Z ponderator $
*/
public class WebApplicationDeployer extends
VirtualArtifactPatternDeployerAbstract<
IVirtualDirectory,
WebApplicationDeployment<IVirtualDirectory>,
WebApplicationDeployer
> {
protected final IWebServer server;
public WebApplicationDeployer(IWebServer server) {
this.server = server;
this.add(new WebApplicationDeploymentPatternWAR());
}
public WebApplicationDeployment<IVirtualDirectory> deploy(IVirtualArtifactDeploymentContext<IVirtualDirectory, WebApplicationDeployment<IVirtualDirectory>> ctx) {
IVirtualDirectory artifact = ctx.getDeployment();
WebApplicationDeployment<IVirtualDirectory> depl = this.createDeployment(artifact);
ClassLoader original = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(this.deploymentClassLoader);
WebApplicationServerDescriptor wsd = WebApplicationServerDescriptor.get(depl.getDeploymentStructure());
String path = wsd == null ? artifact.getName().split(".war")[0] : wsd.getContextPath();
if (!path.startsWith("/")) path = "/" + path;
WebApplicationStandard application = new WebApplicationStandard(artifact.getName(), path, depl.getDeploymentStructure());
application.setReloadable( !depl.getDeploymentStructure().isReadOnly() );
if (wsd != null) application.addAuxilaryDescriptor(wsd);
application.addAuxilaryDescriptor(artifact);
application.addAuxilaryDescriptor(depl.getDeploymentStructure());
IWebServerHost host = wsd != null && wsd.getHost() != null ? server.getHost(wsd.getHost()) : server.getDefaultHost();
if (host == null) throw new VirtualArtifactDeployerException(this, artifact, "No host could be found for deployment");
if (wsd != null) {
for (WebApplicationExtensionDescriptor waed : wsd.getExtensions()) {
String ecl = waed.getClassName() == null ? server.getExtension(waed.getName()) : waed.getClassName();
if (ecl == null) continue;
application.addExtension(waed.getName(), ecl, waed.getSettings());
}
}
depl.set("host", host);
depl.setApplication(application);
for (IVirtualArtifactDeployment link : ctx.getRelatedDeployments()) { depl.link(link, false); }
if (!host.deploy(application)) {
this.fireEvent(depl, Type.DeploymentFailure);
return null;
}
this.markDeployed(depl);
this.fireEvent(depl, Type.DeploymentSuccess);
return depl;
} catch (Throwable t) {
this.fireEvent(depl, Type.DeploymentFailure, t);
throw ThrowableManagerRegistry.caught(t);
} finally {
Thread.currentThread().setContextClassLoader(original);
}
}
public void undeploy(WebApplicationDeployment<IVirtualDirectory> unit) {
if (unit.getDeployer() != this)
throw new VirtualArtifactDeployerException(this, unit.getDeployed(), "This deployer did not deploy this artifact");
if (!(unit.getDeploymentStructure() instanceof IVirtualDirectory)) {
throw (VirtualArtifactDeployerException) this.fireEvent(unit, Type.Error,
new VirtualArtifactDeployerException(this, unit.getDeployed(), "This unit has not yet been deployed")
).getThrowable();
}
ClassLoader original = Thread.currentThread().getContextClassLoader();
try {
if (!((IWebServerHost)unit.get("host", IWebServerHost.class)).undeploy(unit.getDeployed().getName())) {
this.fireEvent(unit, Type.UndeploymentFailure);
} else {
this.markUndeployed(unit);
this.fireEvent(unit, Type.UndeploymentSuccess);
for (LinkedDeployment deployment : (List<LinkedDeployment>) unit.getLinkedDeployments()) {
unit.unlink(deployment.getLinked());
}
}
} catch (Throwable t) {
this.fireEvent(unit, Type.UndeploymentFailure, t);
throw ThrowableManagerRegistry.caught(t);
} finally {
Thread.currentThread().setContextClassLoader(original);
}
}
}