001: //========================================================================
002: //$Id: JettyDeployer.java 1265 2006-11-21 07:49:27Z ngonzalez $
003: //Copyright 2006 Mort Bay Consulting Pty. Ltd.
004: //------------------------------------------------------------------------
005: //Licensed under LGPL.
006: //See license terms at http://www.gnu.org/licenses/lgpl.html
007: //========================================================================
008:
009: package org.jboss.jetty;
010:
011: import java.net.URL;
012: import java.util.ArrayList;
013: import java.util.Hashtable;
014: import java.util.Iterator;
015: import java.util.List;
016:
017: import javax.management.ObjectName;
018:
019: import org.jboss.deployment.DeploymentException;
020: import org.jboss.deployment.DeploymentInfo;
021: import org.jboss.logging.Logger;
022: import org.jboss.web.AbstractWebDeployer;
023: import org.jboss.web.WebApplication;
024: import org.jboss.web.AbstractWebContainer.WebDescriptorParser;
025: import org.mortbay.j2ee.session.Manager;
026: import org.mortbay.jetty.SessionManager;
027: import org.mortbay.jetty.handler.ContextHandlerCollection;
028: import org.mortbay.util.LazyList;
029:
030: /**
031: * JettyDeployer
032: *
033: * Implementation of the jboss AbstractWebDeployer
034: * for deploying webapps to jetty.
035: */
036: public class JettyDeployer extends AbstractWebDeployer {
037: protected static final Logger _log = Logger
038: .getLogger("org.jboss.jetty");
039:
040: protected Jetty _jetty;
041: protected ContextHandlerCollection _contexts;
042: protected DeploymentInfo _deploymentInfo;
043: protected JettyService.ConfigurationData _configData;
044: protected SessionManager _distributableSessionManagerPrototype;
045: protected boolean _forceDistributable = false;
046:
047: /**
048: * use Hashtable because is is synchronised
049: */
050: Hashtable _deployed = new Hashtable();
051:
052: public JettyDeployer(Jetty jetty, DeploymentInfo di) {
053: _jetty = jetty;
054: _deploymentInfo = di;
055: _contexts = (ContextHandlerCollection) _jetty
056: .getChildHandlerByClass(ContextHandlerCollection.class);
057: }
058:
059: public void init(Object containerConfig) throws Exception {
060: _configData = (JettyService.ConfigurationData) containerConfig;
061: setLenientEjbLink(_configData.getLenientEjbLink());
062: setDefaultSecurityDomain(_configData.getDefaultSecurityDomain());
063: setJava2ClassLoadingCompliance(_configData
064: .getJava2ClassLoadingCompliance());
065: setUnpackWars(_configData.getUnpackWars());
066: }
067:
068: public void performDeploy(WebApplication webApp, String warUrl,
069: WebDescriptorParser parser) throws DeploymentException {
070: log.debug("deploying webapp at " + warUrl);
071: try {
072: String contextPath = webApp.getMetaData().getContextRoot();
073: webApp.setURL(new URL(warUrl));
074:
075: if (_deployed.get(warUrl) != null)
076: throw new DeploymentException(warUrl
077: + " is already deployed");
078:
079: //make a context for the webapp and configure it from the jetty jboss-service.xml defaults
080: //and the jboss-web.xml descriptor
081: JBossWebAppContext app = new JBossWebAppContext(parser,
082: webApp, warUrl);
083: app.setContextPath(contextPath);
084: app
085: .setConfigurationClasses(new String[] {
086: "org.mortbay.jetty.webapp.WebInfConfiguration",
087: "org.jboss.jetty.JBossWebXmlConfiguration",
088: "org.mortbay.jetty.webapp.JettyWebXmlConfiguration",
089: "org.mortbay.jetty.webapp.TagLibConfiguration" });
090: app.setExtractWAR(getUnpackWars());
091: app
092: .setParentLoaderPriority(getJava2ClassLoadingCompliance());
093: Manager manager = (Manager) getDistributableSessionManagerPrototype();
094: if (manager != null) {
095: throw new UnsupportedOperationException(
096: "NOT IMPLEMENTED - please ask");
097: // app.setDistributableSessionManager((Manager) manager.clone());
098: // if (getForceDistributable())
099: // app.setDistributable(true);
100: }
101:
102: // if a different webdefault.xml file has been provided, use it
103: if (_configData.getWebDefaultResource() != null) {
104: try {
105: URL url = getClass().getClassLoader().getResource(
106: _configData.getWebDefaultResource());
107: String fixedUrl = (fixURL(url.toString()));
108: app.setDefaultsDescriptor(fixedUrl);
109: if (_log.isDebugEnabled())
110: _log.debug("webdefault specification is: "
111: + _configData.getWebDefaultResource());
112: } catch (Exception e) {
113: _log.error("Could not find resource: "
114: + _configData.getWebDefaultResource()
115: + " using default", e);
116: }
117: }
118:
119: Iterator hosts = webApp.getMetaData().getVirtualHosts();
120: List hostList = new ArrayList();
121: while (hosts.hasNext())
122: hostList.add((String) hosts.next());
123: app.setVirtualHosts((String[]) LazyList.toArray(hostList,
124: String.class));
125:
126: // Add the webapp to jetty - if jetty is already started, this will
127: //also start the webapp
128: _contexts.addHandler(app);
129:
130: // keep track of deployed contexts for undeployment
131: _deployed.put(warUrl, app);
132:
133: //tell jboss about the jsr77 mbeans we've created
134: //first check that there is an mbean for the webapp itself
135: ObjectName webAppMBean = new ObjectName(
136: _configData.getMBeanDomain()
137: + ":J2EEServer=none,J2EEApplication=none,J2EEWebModule="
138: + app.getUniqueName());
139: if (server.isRegistered(webAppMBean))
140: _deploymentInfo.deployedObject = webAppMBean;
141: else
142: throw new IllegalStateException(
143: "No mbean registered for webapp at "
144: + app.getUniqueName());
145:
146: //now get all the mbeans that represent servlets and set them on the
147: //deployment info so they will be found by the jsr77 management system
148: ObjectName servletQuery = new ObjectName(
149: _configData.getMBeanDomain()
150: + ":J2EEServer=none,J2EEApplication=none,J2EEWebModule="
151: + app.getUniqueName()
152: + ",j2eeType=Servlet,*");
153: Iterator iterator = server.queryNames(servletQuery, null)
154: .iterator();
155: while (iterator.hasNext()) {
156: _deploymentInfo.mbeans
157: .add((ObjectName) iterator.next());
158: }
159:
160: //tell jboss about the classloader the webapp is using
161: webApp.getMetaData().setContextLoader(app.getClassLoader());
162:
163: _log.info("successfully deployed " + warUrl + " to "
164: + contextPath);
165: } catch (Exception e) {
166: _log.error("Undeploying on start due to error", e);
167: performUndeploy(warUrl, webApp);
168: throw new DeploymentException(e);
169: }
170: }
171:
172: /**
173: * Undeploy a webapp
174: * @see org.jboss.web.AbstractWebDeployer#performUndeploy(java.lang.String, org.jboss.web.WebApplication)
175: */
176: public void performUndeploy(String warUrl, WebApplication wa)
177: throws DeploymentException {
178: JBossWebAppContext app = (JBossWebAppContext) _deployed
179: .get(warUrl);
180:
181: if (app == null)
182: _log.warn("app (" + warUrl + ") not currently deployed");
183: else {
184: try {
185: app.stop();
186: _contexts.removeHandler(app);
187: app.destroy();
188: app = null;
189: _log.info("Successfully undeployed " + warUrl);
190: } catch (Exception e) {
191: throw new DeploymentException(e);
192: } finally {
193: _deployed.remove(warUrl);
194: }
195: }
196: }
197:
198: /**
199: * Work around broken JarURLConnection caching...
200: * @param url
201: * @return
202: */
203: static String fixURL(String url) {
204: String fixedUrl = url;
205:
206: // Get the separator of the JAR URL and the file reference
207: int index = url.indexOf('!');
208: if (index >= 0)
209: index = url.lastIndexOf('/', index);
210: else
211: index = url.lastIndexOf('/');
212:
213: // If there is at least one forward slash, add a "/." before the JAR file
214: // change the path just slightly. Otherwise, the url is malformed, but
215: // we will ignore that.
216: if (index >= 0)
217: fixedUrl = url.substring(0, index) + "/."
218: + url.substring(index);
219:
220: return fixedUrl;
221: }
222:
223: public void setDistributableSessionManagerPrototype(
224: SessionManager manager) {
225: throw new UnsupportedOperationException(
226: "NOT SUPPORTED - please ask");
227: // _distributableSessionManagerPrototype = manager;
228: }
229:
230: public SessionManager getDistributableSessionManagerPrototype() {
231: return _distributableSessionManagerPrototype;
232: }
233:
234: public boolean getForceDistributable() {
235: return _forceDistributable;
236: }
237:
238: public void setForceDistributable(boolean distributable) {
239: _forceDistributable = distributable;
240: }
241: }
|