diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/JettyBootstrapActivator.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/JettyBootstrapActivator.java index f09425b14f9..a7484296bf9 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/JettyBootstrapActivator.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/JettyBootstrapActivator.java @@ -20,6 +20,7 @@ import java.util.Properties; import org.eclipse.jetty.osgi.boot.internal.serverfactory.DefaultJettyAtJettyHomeHelper; import org.eclipse.jetty.osgi.boot.internal.serverfactory.JettyServerServiceTracker; +import org.eclipse.jetty.osgi.boot.internal.webapp.IWebBundleDeployerHelper; import org.eclipse.jetty.osgi.boot.internal.webapp.JettyContextHandlerServiceTracker; import org.eclipse.jetty.osgi.boot.internal.webapp.WebBundleTrackerCustomizer; import org.eclipse.jetty.osgi.boot.utils.internal.PackageAdminServiceTracker; @@ -56,9 +57,6 @@ import org.osgi.util.tracker.BundleTracker; public class JettyBootstrapActivator implements BundleActivator { - /** development only: when set to true enable the jetty server service tracker */ - private static boolean _enableMultipleJettyServers = true; - private static JettyBootstrapActivator INSTANCE = null; public static JettyBootstrapActivator getInstance() @@ -92,36 +90,24 @@ public class JettyBootstrapActivator implements BundleActivator // should activate. _packageAdminServiceTracker = new PackageAdminServiceTracker(context); - - if (_enableMultipleJettyServers) - {//new style... - _jettyServerServiceTracker = new JettyServerServiceTracker(); - context.addServiceListener(_jettyServerServiceTracker,"(objectclass=" + Server.class.getName() + ")"); + _jettyServerServiceTracker = new JettyServerServiceTracker(); + context.addServiceListener(_jettyServerServiceTracker,"(objectclass=" + Server.class.getName() + ")"); - //Register the Jetty Server Factory as a ManagedServiceFactory: + //Register the Jetty Server Factory as a ManagedServiceFactory: // Properties jettyServerMgdFactoryServiceProps = new Properties(); // jettyServerMgdFactoryServiceProps.put("pid", OSGiWebappConstants.MANAGED_JETTY_SERVER_FACTORY_PID); // _jettyServerFactoryService = context.registerService( // ManagedServiceFactory.class.getName(), new JettyServersManagedFactory(), // jettyServerMgdFactoryServiceProps); - - _jettyContextHandlerTracker = new JettyContextHandlerServiceTracker(_jettyServerServiceTracker); - } - else - {//old style... - _server = new Server(); - // expose the server as a service. - _registeredServer = context.registerService(_server.getClass().getName(),_server,new Properties()); - _jettyContextHandlerTracker = new JettyContextHandlerServiceTracker(context,_server); - } + + _jettyContextHandlerTracker = new JettyContextHandlerServiceTracker(_jettyServerServiceTracker); + // the tracker in charge of the actual deployment // and that will configure and start the jetty server. context.addServiceListener(_jettyContextHandlerTracker,"(objectclass=" + ContextHandler.class.getName() + ")"); - if (_enableMultipleJettyServers) - { - DefaultJettyAtJettyHomeHelper.startJettyAtJettyHome(context); - } + //see if we shoult start a default jetty instance right now. + DefaultJettyAtJettyHomeHelper.startJettyAtJettyHome(context); // now ready to support the Extender pattern: _webBundleTracker = new BundleTracker(context, @@ -288,6 +274,7 @@ public class JettyBootstrapActivator implements BundleActivator { ContextHandler contextHandler = new ContextHandler(); dic.put(OSGiWebappConstants.SERVICE_PROP_CONTEXT_FILE_PATH,contextFilePath); + dic.put(IWebBundleDeployerHelper.INTERNAL_SERVICE_PROP_UNKNOWN_CONTEXT_HANDLER_TYPE,Boolean.TRUE.toString()); contributor.getBundleContext().registerService(ContextHandler.class.getName(),contextHandler,dic); } diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiAppProvider.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiAppProvider.java index ffd4bb8d190..bf3bbcdf38f 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiAppProvider.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiAppProvider.java @@ -289,6 +289,17 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider return null; } } + + public boolean isExtract() + { + return _extractWars; + } + + public void setExtract(boolean extract) + { + _extractWars=extract; + } + /* ------------------------------------------------------------ */ /** diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/DefaultJettyAtJettyHomeHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/DefaultJettyAtJettyHomeHelper.java index 62ea0f666b5..3d747a93dcb 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/DefaultJettyAtJettyHomeHelper.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/DefaultJettyAtJettyHomeHelper.java @@ -18,11 +18,13 @@ import java.io.File; import java.net.MalformedURLException; import java.net.URL; import java.util.Enumeration; +import java.util.Map.Entry; import java.util.Properties; import java.util.StringTokenizer; import org.eclipse.jetty.osgi.boot.JettyBootstrapActivator; import org.eclipse.jetty.osgi.boot.OSGiServerConstants; +import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelper; import org.eclipse.jetty.server.Server; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; @@ -135,11 +137,10 @@ public class DefaultJettyAtJettyHomeHelper { properties.put(OSGiServerConstants.MANAGED_JETTY_XML_CONFIG_URLS, configURLs); //these properties usually are the ones passed to this type of configuration. - //TODO remove the hardcoded defaults once we use 7.1.5 setProperty(properties,SYS_PROP_JETTY_HOME,System.getProperty(SYS_PROP_JETTY_HOME)); setProperty(properties,SYS_PROP_JETTY_HOST,System.getProperty(SYS_PROP_JETTY_HOST)); - setProperty(properties,SYS_PROP_JETTY_PORT,System.getProperty(SYS_PROP_JETTY_PORT, "8080")); - setProperty(properties,SYS_PROP_JETTY_PORT_SSL,System.getProperty(SYS_PROP_JETTY_PORT_SSL, "8443")); + setProperty(properties,SYS_PROP_JETTY_PORT,System.getProperty(SYS_PROP_JETTY_PORT)); + setProperty(properties,SYS_PROP_JETTY_PORT_SSL,System.getProperty(SYS_PROP_JETTY_PORT_SSL)); bundleContext.registerService(Server.class.getName(), server, properties); } @@ -201,26 +202,18 @@ public class DefaultJettyAtJettyHomeHelper { } else { - int last = etcFile.lastIndexOf('/'); - String path = last != -1 && last < etcFile.length() -2 - ? etcFile.substring(0, last) : "/"; - if (!path.startsWith("/")) - { - path = "/" + path; - } - String pattern = last != -1 && last < etcFile.length() -2 - ? etcFile.substring(last+1) : etcFile; - Enumeration enUrls = configurationBundle.findEntries(path, pattern, false); + Enumeration enUrls = BundleFileLocatorHelper.DEFAULT + .findEntries(configurationBundle, etcFile); //default for org.eclipse.osgi.boot where we look inside jettyhome for the default embedded configuration. //default inside jettyhome. this way fragments to the bundle can define their own configuration. - if ((enUrls == null || !enUrls.hasMoreElements()) && pattern.equals("jetty.xml")) + if ((enUrls == null || !enUrls.hasMoreElements()) && etcFile.endsWith("etc/jetty.xml")) { - path = "/jettyhome" + path; - pattern = "jetty-osgi-default.xml"; - enUrls = configurationBundle.findEntries(path, pattern, false); + enUrls = BundleFileLocatorHelper.DEFAULT + .findEntries(configurationBundle, "/jettyhome/etc/jetty-osgi-default.xml"); System.err.println("Configuring jetty with the default embedded configuration:" + - "bundle: " + configurationBundle.getSymbolicName() + " config: /jettyhome/etc/jetty-osgi-default.xml"); + "bundle: " + configurationBundle.getSymbolicName() + + " config: /jettyhome/etc/jetty-osgi-default.xml"); } if (enUrls != null) { @@ -250,4 +243,5 @@ public class DefaultJettyAtJettyHomeHelper { properties.put(key, value); } } + } diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/ServerInstanceWrapper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/ServerInstanceWrapper.java index 69026defeca..7e4afc5b295 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/ServerInstanceWrapper.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/ServerInstanceWrapper.java @@ -33,7 +33,6 @@ import org.eclipse.jetty.osgi.boot.OSGiServerConstants; import org.eclipse.jetty.osgi.boot.internal.jsp.TldLocatableURLClassloader; import org.eclipse.jetty.osgi.boot.internal.webapp.LibExtClassLoaderHelper; import org.eclipse.jetty.osgi.boot.internal.webapp.WebBundleDeployerHelper; -import org.eclipse.jetty.osgi.boot.internal.webapp.WebappRegistrationHelper; import org.eclipse.jetty.osgi.boot.utils.WebappRegistrationCustomizer; import org.eclipse.jetty.osgi.boot.utils.internal.DefaultFileLocatorHelper; import org.eclipse.jetty.server.Server; @@ -224,9 +223,10 @@ public class ServerInstanceWrapper { private URL[] getJarsWithTlds() throws Exception { ArrayList res = new ArrayList(); + WebBundleDeployerHelper.staticInit();//that is not looking great. for (WebappRegistrationCustomizer regCustomizer : WebBundleDeployerHelper.JSP_REGISTRATION_HELPERS) { - URL[] urls = regCustomizer.getJarsWithTlds(_provider, WebBundleDeployerHelper.BUNDLE_FILE_LOCATOR_HELPER); + URL[] urls = regCustomizer.getJarsWithTlds(_provider, WebBundleDeployerHelper.BUNDLE_FILE_LOCATOR_HELPER); for (URL url : urls) { if (!res.contains(url)) @@ -274,8 +274,7 @@ public class ServerInstanceWrapper { } catch (SAXParseException saxparse) { - Log.getLogger(WebappRegistrationHelper.class.getName()) - .warn("Unable to configure the jetty/etc file " + jettyConfiguration,saxparse); + __logger.warn("Unable to configure the jetty/etc file " + jettyConfiguration,saxparse); throw saxparse; } finally diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/IWebBundleDeployerHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/IWebBundleDeployerHelper.java index 575b689be9d..8805561480a 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/IWebBundleDeployerHelper.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/IWebBundleDeployerHelper.java @@ -14,11 +14,9 @@ // ======================================================================== package org.eclipse.jetty.osgi.boot.internal.webapp; -import java.io.File; - import org.eclipse.jetty.deploy.ContextDeployer; -import org.eclipse.jetty.deploy.WebAppDeployer; import org.eclipse.jetty.server.handler.ContextHandler; +import org.eclipse.jetty.webapp.WebAppContext; import org.osgi.framework.Bundle; /** @@ -27,6 +25,11 @@ import org.osgi.framework.Bundle; */ public interface IWebBundleDeployerHelper { + /** when this property is present, the type of context handler registered is not + * known in advance. */ + public static final String INTERNAL_SERVICE_PROP_UNKNOWN_CONTEXT_HANDLER_TYPE = "unknownContextHandlerType"; + + /** * Deploy a new web application on the jetty server. * @@ -45,29 +48,10 @@ public interface IWebBundleDeployerHelper { * @return The contexthandler created and started * @throws Exception */ - public abstract ContextHandler registerWebapplication(Bundle bundle, + public abstract WebAppContext registerWebapplication(Bundle bundle, String webappFolderPath, String contextPath, String extraClasspath, String overrideBundleInstallLocation, String webXmlPath, - String defaultWebXmlPath) throws Exception; - - /** - * TODO: refactor this into the createContext method of OSGiAppProvider. - * @see WebAppDeployer#scan() - - * @param contributor - * @param webapp - * @param contextPath - * @param extraClasspath - * @param bundleInstall - * @param webXmlPath - * @param defaultWebXmlPath - * @return The contexthandler created and started - * @throws Exception - */ - public abstract ContextHandler registerWebapplication(Bundle contributor, - String pathInBundleToWebApp, File webapp, String contextPath, - String extraClasspath, File bundleInstall, String webXmlPath, - String defaultWebXmlPath) throws Exception; + String defaultWebXmlPath, WebAppContext webAppContext) throws Exception; /** * Stop a ContextHandler and remove it from the collection. @@ -88,11 +72,13 @@ public interface IWebBundleDeployerHelper { * @param contextFileRelativePath * @param extraClasspath * @param overrideBundleInstallLocation + * @param handler the context handler passed in the server + * reference that will be configured, deployed and started. * @return The contexthandler created and started * @throws Exception */ public abstract ContextHandler registerContext(Bundle contributor, String contextFileRelativePath, String extraClasspath, - String overrideBundleInstallLocation) throws Exception; + String overrideBundleInstallLocation, ContextHandler handler) throws Exception; } \ No newline at end of file diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/JettyContextHandlerServiceTracker.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/JettyContextHandlerServiceTracker.java index 5e063130a2d..efb908239ac 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/JettyContextHandlerServiceTracker.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/JettyContextHandlerServiceTracker.java @@ -22,7 +22,6 @@ import org.eclipse.jetty.osgi.boot.OSGiServerConstants; import org.eclipse.jetty.osgi.boot.OSGiWebappConstants; import org.eclipse.jetty.osgi.boot.internal.serverfactory.IManagedJettyServerRegistry; import org.eclipse.jetty.osgi.boot.internal.serverfactory.ServerInstanceWrapper; -import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.util.Scanner; import org.eclipse.jetty.webapp.WebAppContext; @@ -55,15 +54,12 @@ public class JettyContextHandlerServiceTracker implements ServiceListener /** New style: ability to manage multiple jetty instances */ private final IManagedJettyServerRegistry _registry; - /** Old style: ability to manage multiple jetty instances */ - private final WebappRegistrationHelper _helper; /** The context-handler to deactivate indexed by context handler */ private Map _indexByServiceReference = new HashMap(); /** - * The index is the bundle-symbolic-name/paht/to/context/file when there is - * such thing + * The index is the bundle-symbolic-name/path/to/context/file when there is such thing */ private Map _indexByContextFile = new HashMap(); @@ -71,24 +67,11 @@ public class JettyContextHandlerServiceTracker implements ServiceListener private Scanner _scanner; /** - * @param context - * @param server - */ - public JettyContextHandlerServiceTracker(BundleContext context, Server server) throws Exception - { - _registry = null; - _helper = new WebappRegistrationHelper(server); - _helper.setup(context,new HashMap()); - setupContextHomeScanner(_helper.getOSGiContextsHome()); - } - /** - * @param context - * @param server + * @param registry */ public JettyContextHandlerServiceTracker(IManagedJettyServerRegistry registry) throws Exception { _registry = registry; - _helper = null; } public void stop() @@ -192,7 +175,11 @@ public class JettyContextHandlerServiceTracker implements ServiceListener // is configured elsewhere. return; } - if (contextHandler instanceof WebAppContext) + String contextFilePath = (String)sr.getProperty(OSGiWebappConstants.SERVICE_PROP_CONTEXT_FILE_PATH); + if (contextHandler instanceof WebAppContext && contextFilePath == null) + //it could be a web-application that will in fact be configured via a context file. + //that case is identified by the fact that the contextFilePath is not null + //in that case we must use the register context methods. { WebAppContext webapp = (WebAppContext)contextHandler; String contextPath = (String)sr.getProperty(OSGiWebappConstants.SERVICE_PROP_CONTEXT_PATH); @@ -213,14 +200,23 @@ public class JettyContextHandlerServiceTracker implements ServiceListener String war = (String)sr.getProperty("war"); try { - ContextHandler handler = getWebBundleDeployerHelp(sr) + IWebBundleDeployerHelper deployerHelper = getWebBundleDeployerHelp(sr); + if (deployerHelper == null) + { + + } + else + { + WebAppContext handler = deployerHelper .registerWebapplication(contributor,war,contextPath,(String)sr .getProperty(OSGiWebappConstants.SERVICE_PROP_EXTRA_CLASSPATH),(String)sr - .getProperty(OSGiWebappConstants.SERVICE_PROP_BUNDLE_INSTALL_LOCATION_OVERRIDE),webXmlPath,defaultWebXmlPath); - if (handler != null) - { - registerInIndex(handler,sr); - } + .getProperty(OSGiWebappConstants.SERVICE_PROP_BUNDLE_INSTALL_LOCATION_OVERRIDE), + webXmlPath,defaultWebXmlPath,webapp); + if (handler != null) + { + registerInIndex(handler,sr); + } + } } catch (Throwable e) { @@ -230,20 +226,33 @@ public class JettyContextHandlerServiceTracker implements ServiceListener else { // consider this just an empty skeleton: - String contextFilePath = (String)sr.getProperty(OSGiWebappConstants.SERVICE_PROP_CONTEXT_FILE_PATH); if (contextFilePath == null) { throw new IllegalArgumentException("the property contextFilePath is required"); } try { - ContextHandler handler = getWebBundleDeployerHelp(sr).registerContext(contributor,contextFilePath,(String)sr - .getProperty(OSGiWebappConstants.SERVICE_PROP_EXTRA_CLASSPATH),(String)sr - .getProperty(OSGiWebappConstants.SERVICE_PROP_BUNDLE_INSTALL_LOCATION_OVERRIDE)); - if (handler != null) - { - registerInIndex(handler,sr); - } + IWebBundleDeployerHelper deployerHelper = getWebBundleDeployerHelp(sr); + if (deployerHelper == null) + { + //more warnings? + } + else + { + if (Boolean.TRUE.toString().equals(sr.getProperty( + IWebBundleDeployerHelper.INTERNAL_SERVICE_PROP_UNKNOWN_CONTEXT_HANDLER_TYPE))) + { + contextHandler = null; + } + ContextHandler handler = deployerHelper.registerContext(contributor,contextFilePath, + (String)sr.getProperty(OSGiWebappConstants.SERVICE_PROP_EXTRA_CLASSPATH), + (String)sr.getProperty(OSGiWebappConstants.SERVICE_PROP_BUNDLE_INSTALL_LOCATION_OVERRIDE), + contextHandler); + if (handler != null) + { + registerInIndex(handler,sr); + } + } } catch (Throwable e) { @@ -353,6 +362,7 @@ public class JettyContextHandlerServiceTracker implements ServiceListener managedServerName = OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME; } ServerInstanceWrapper wrapper = _registry.getServerInstanceWrapper(managedServerName); + System.err.println("Returning " + managedServerName + " = " + wrapper); return wrapper; } @@ -360,12 +370,11 @@ public class JettyContextHandlerServiceTracker implements ServiceListener { if (_registry == null) { - return _helper; + return null; } String managedServerName = (String)sr.getProperty(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME); ServerInstanceWrapper wrapper = getServerInstanceWrapper(managedServerName); - return wrapper != null ? wrapper.getWebBundleDeployerHelp() : _helper; + return wrapper != null ? wrapper.getWebBundleDeployerHelp() : null; } - } diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleDeployerHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleDeployerHelper.java index c2367d96c8c..590e4bd6d57 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleDeployerHelper.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleDeployerHelper.java @@ -23,9 +23,8 @@ import java.io.InputStream; import java.net.URL; import java.util.ArrayList; import java.util.Collection; +import java.util.Enumeration; import java.util.HashMap; -import java.util.jar.JarFile; -import java.util.zip.ZipEntry; import org.eclipse.jetty.deploy.ContextDeployer; import org.eclipse.jetty.osgi.boot.OSGiWebappConstants; @@ -36,6 +35,7 @@ import org.eclipse.jetty.osgi.boot.utils.WebappRegistrationCustomizer; import org.eclipse.jetty.osgi.boot.utils.internal.DefaultBundleClassLoaderHelper; import org.eclipse.jetty.osgi.boot.utils.internal.DefaultFileLocatorHelper; import org.eclipse.jetty.server.handler.ContextHandler; +import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; @@ -67,7 +67,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper private static Logger __logger = Log.getLogger(WebBundleDeployerHelper.class.getName()); private static boolean INITIALIZED = false; - + /** * By default set to: {@link DefaultBundleClassLoaderHelper}. It supports * equinox and apache-felix fragment bundles that are specific to an OSGi @@ -103,12 +103,12 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper public WebBundleDeployerHelper(ServerInstanceWrapper wrapper) { + staticInit(); _wrapper = wrapper; - staticInit(); } // Inject the customizing classes that might be defined in fragment bundles. - private static synchronized void staticInit() + public static synchronized void staticInit() { if (!INITIALIZED) { @@ -139,45 +139,60 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper /* (non-Javadoc) * @see org.eclipse.jetty.osgi.boot.internal.webapp.IWebBundleDeployerHelper#registerWebapplication(org.osgi.framework.Bundle, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String) */ - public ContextHandler registerWebapplication(Bundle bundle, String webappFolderPath, String contextPath, String extraClasspath, - String overrideBundleInstallLocation, String webXmlPath, String defaultWebXmlPath) throws Exception + public WebAppContext registerWebapplication(Bundle bundle, String webappFolderPath, String contextPath, String extraClasspath, + String overrideBundleInstallLocation, String webXmlPath, String defaultWebXmlPath, WebAppContext webAppContext) throws Exception { File bundleInstall = overrideBundleInstallLocation == null?BUNDLE_FILE_LOCATOR_HELPER.getBundleInstallLocation(bundle):new File( overrideBundleInstallLocation); File webapp = null; + URL baseWebappInstallURL = null; if (webappFolderPath != null && webappFolderPath.length() != 0 && !webappFolderPath.equals(".")) { - if (webappFolderPath.startsWith("/") || webappFolderPath.startsWith("file:/")) + if (webappFolderPath.startsWith("/") || webappFolderPath.startsWith("file:")) { webapp = new File(webappFolderPath); } - else + else if (bundleInstall != null && bundleInstall.isDirectory()) { webapp = new File(bundleInstall,webappFolderPath); } + else if (bundleInstall != null) + { + Enumeration urls = BUNDLE_FILE_LOCATOR_HELPER.findEntries(bundle, webappFolderPath); + if (urls != null && urls.hasMoreElements()) + { + baseWebappInstallURL = urls.nextElement(); + } + } } else { webapp = bundleInstall; } - if (!webapp.exists()) + if (baseWebappInstallURL == null && (webapp == null || !webapp.exists())) { throw new IllegalArgumentException("Unable to locate " + webappFolderPath + " inside " + (bundleInstall != null?bundleInstall.getAbsolutePath():"unlocated bundle '" + bundle.getSymbolicName() + "'")); } - return registerWebapplication(bundle,webappFolderPath,webapp,contextPath,extraClasspath,bundleInstall,webXmlPath,defaultWebXmlPath); + if (baseWebappInstallURL == null && webapp != null) + { + baseWebappInstallURL = webapp.toURI().toURL(); + } + return registerWebapplication(bundle,webappFolderPath,baseWebappInstallURL,contextPath, + extraClasspath,bundleInstall,webXmlPath,defaultWebXmlPath,webAppContext); } - + /* (non-Javadoc) * @see org.eclipse.jetty.osgi.boot.internal.webapp.IWebBundleDeployerHelper#registerWebapplication(org.osgi.framework.Bundle, java.lang.String, java.io.File, java.lang.String, java.lang.String, java.io.File, java.lang.String, java.lang.String) */ - public ContextHandler registerWebapplication(Bundle contributor, String pathInBundleToWebApp, File webapp, String contextPath, String extraClasspath, File bundleInstall, - String webXmlPath, String defaultWebXmlPath) throws Exception + private WebAppContext registerWebapplication(Bundle contributor, String pathInBundleToWebApp, + URL baseWebappInstallURL, String contextPath, String extraClasspath, File bundleInstall, + String webXmlPath, String defaultWebXmlPath, WebAppContext context) throws Exception { ClassLoader contextCl = Thread.currentThread().getContextClassLoader(); String[] oldServerClasses = null; - WebAppContext context = null; + try { // make sure we provide access to all the jetty bundles by going @@ -187,7 +202,8 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper // that the contributor gives access to. Thread.currentThread().setContextClassLoader(composite); - context = new WebAppContext(webapp.getAbsolutePath(),contextPath); + context.setWar(baseWebappInstallURL.toString()); + context.setContextPath(contextPath); context.setExtraClasspath(extraClasspath); if (webXmlPath != null && webXmlPath.length() != 0) @@ -242,7 +258,9 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper // through the webapp classloader. oldServerClasses = context.getServerClasses(); context.setServerClasses(null); + _wrapper.getOSGiAppProvider().addContext(contributor,pathInBundleToWebApp,context); + return context; } finally @@ -267,7 +285,8 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper /* (non-Javadoc) * @see org.eclipse.jetty.osgi.boot.internal.webapp.IWebBundleDeployerHelper#registerContext(org.osgi.framework.Bundle, java.lang.String, java.lang.String, java.lang.String) */ - public ContextHandler registerContext(Bundle contributor, String contextFileRelativePath, String extraClasspath, String overrideBundleInstallLocation) + public ContextHandler registerContext(Bundle contributor, String contextFileRelativePath, String extraClasspath, + String overrideBundleInstallLocation, ContextHandler handler) throws Exception { File contextsHome = _wrapper.getOSGiAppProvider().getContextXmlDirAsFile(); @@ -276,15 +295,17 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper File prodContextFile = new File(contextsHome,contributor.getSymbolicName() + "/" + contextFileRelativePath); if (prodContextFile.exists()) { - return registerContext(contributor,contextFileRelativePath,prodContextFile,extraClasspath,overrideBundleInstallLocation); + return registerContext(contributor,contextFileRelativePath,prodContextFile,extraClasspath, + overrideBundleInstallLocation,handler); } } - - File contextFile = overrideBundleInstallLocation != null?new File(overrideBundleInstallLocation,contextFileRelativePath):new File( - BUNDLE_FILE_LOCATOR_HELPER.getBundleInstallLocation(contributor),contextFileRelativePath); - if (contextFile.exists()) + File rootFolder = overrideBundleInstallLocation != null + ? Resource.newResource(overrideBundleInstallLocation).getFile() + : BUNDLE_FILE_LOCATOR_HELPER.getBundleInstallLocation(contributor); + File contextFile = rootFolder != null?new File(rootFolder,contextFileRelativePath):null; + if (contextFile != null && contextFile.exists()) { - return registerContext(contributor,contextFileRelativePath,contextFile,extraClasspath,overrideBundleInstallLocation); + return registerContext(contributor,contextFileRelativePath,contextFile,extraClasspath,overrideBundleInstallLocation,handler); } else { @@ -297,39 +318,10 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper contextFileRelativePath = "/" + contextFileRelativePath; } - File overrideBundleInstallLocationF = overrideBundleInstallLocation != null ? Resource.newResource(overrideBundleInstallLocation).getFile() : null; - if (overrideBundleInstallLocationF == null) + URL contextURL = contributor.getEntry(contextFileRelativePath); + if (contextURL != null) { - URL contextURL = contributor.getEntry(contextFileRelativePath); - if (contextURL != null) - { - return registerContext(contributor,contextFileRelativePath,contextURL.openStream(),extraClasspath,overrideBundleInstallLocation); - } - } - else - { - JarFile zipFile = null; - try - { - zipFile = new JarFile(overrideBundleInstallLocation); - ZipEntry entry = zipFile.getEntry(contextFileRelativePath.substring(1)); - return registerContext(contributor,contextFileRelativePath,zipFile.getInputStream(entry),extraClasspath,overrideBundleInstallLocation); - } - catch (Throwable t) - { - - } - finally - { - if (zipFile != null) - try - { - zipFile.close(); - } - catch (IOException ioe) - { - } - } + return registerContext(contributor,contextFileRelativePath,contextURL.openStream(),extraClasspath,overrideBundleInstallLocation,handler); } throw new IllegalArgumentException("Could not find the context " + "file " + contextFileRelativePath + " for the bundle " + contributor.getSymbolicName() + (overrideBundleInstallLocation != null?" using the install location " + overrideBundleInstallLocation:"")); @@ -346,24 +338,18 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper * @param classInBundle * @throws Exception */ - private ContextHandler registerContext(Bundle contributor, String pathInBundle, File contextFile, String extraClasspath, String overrideBundleInstallLocation) throws Exception + private ContextHandler registerContext(Bundle contributor, String pathInBundle, File contextFile, + String extraClasspath, String overrideBundleInstallLocation, ContextHandler handler) throws Exception { InputStream contextFileInputStream = null; try { contextFileInputStream = new BufferedInputStream(new FileInputStream(contextFile)); - return registerContext(contributor, pathInBundle, contextFileInputStream,extraClasspath,overrideBundleInstallLocation); + return registerContext(contributor, pathInBundle, contextFileInputStream,extraClasspath,overrideBundleInstallLocation, handler); } finally { - if (contextFileInputStream != null) - try - { - contextFileInputStream.close(); - } - catch (IOException ioe) - { - } + IO.close(contextFileInputStream); } } @@ -374,7 +360,8 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper * happen. * @throws Exception */ - private ContextHandler registerContext(Bundle contributor, String pathInsideBundle, InputStream contextFileInputStream, String extraClasspath, String overrideBundleInstallLocation) + private ContextHandler registerContext(Bundle contributor, String pathInsideBundle, InputStream contextFileInputStream, + String extraClasspath, String overrideBundleInstallLocation, ContextHandler handler) throws Exception { ClassLoader contextCl = Thread.currentThread().getContextClassLoader(); @@ -389,7 +376,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper // classes // that the contributor gives access to. Thread.currentThread().setContextClassLoader(composite); - ContextHandler context = createContextHandler(contributor,contextFileInputStream,extraClasspath,overrideBundleInstallLocation); + ContextHandler context = createContextHandler(handler, contributor,contextFileInputStream,extraClasspath,overrideBundleInstallLocation); if (context == null) { return null;// did not happen @@ -449,11 +436,12 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper * @param contextFile * @return */ - protected ContextHandler createContextHandler(Bundle bundle, File contextFile, String extraClasspath, String overrideBundleInstallLocation) + protected ContextHandler createContextHandler(ContextHandler handlerToConfigure, + Bundle bundle, File contextFile, String extraClasspath, String overrideBundleInstallLocation) { try { - return createContextHandler(bundle,new BufferedInputStream(new FileInputStream(contextFile)),extraClasspath,overrideBundleInstallLocation); + return createContextHandler(handlerToConfigure,bundle,new BufferedInputStream(new FileInputStream(contextFile)),extraClasspath,overrideBundleInstallLocation); } catch (FileNotFoundException e) { @@ -468,7 +456,8 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper * @return */ @SuppressWarnings("unchecked") - protected ContextHandler createContextHandler(Bundle bundle, InputStream contextInputStream, String extraClasspath, String overrideBundleInstallLocation) + protected ContextHandler createContextHandler(ContextHandler handlerToConfigure, + Bundle bundle, InputStream contextInputStream, String extraClasspath, String overrideBundleInstallLocation) { /* * Do something identical to what the ContextProvider would have done: @@ -491,7 +480,17 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper setThisBundleHomeProperty(bundle,properties,overrideBundleInstallLocation); xmlConfiguration.setProperties(properties); - ContextHandler context = (ContextHandler)xmlConfiguration.configure(); + ContextHandler context = null; + if (handlerToConfigure == null) + { + context = (ContextHandler)xmlConfiguration.configure(); + } + else + { + xmlConfiguration.configure(handlerToConfigure); + context = handlerToConfigure; + } + if (context instanceof WebAppContext) { ((WebAppContext)context).setExtraClasspath(extraClasspath); @@ -534,14 +533,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper } finally { - if (contextInputStream != null) - try - { - contextInputStream.close(); - } - catch (IOException ioe) - { - } + IO.close(contextInputStream); } return null; } diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebappRegistrationHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebappRegistrationHelper.java deleted file mode 100644 index 03bd2f8c69c..00000000000 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebappRegistrationHelper.java +++ /dev/null @@ -1,1095 +0,0 @@ -// ======================================================================== -// Copyright (c) 2009 Intalio, Inc. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// You may elect to redistribute this code under either of these licenses. -// Contributors: -// Hugues Malphettes - initial API and implementation -// ======================================================================== -package org.eclipse.jetty.osgi.boot.internal.webapp; - -import java.io.BufferedInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.StringTokenizer; -import java.util.jar.JarFile; -import java.util.zip.ZipEntry; - -import org.eclipse.jetty.deploy.AppProvider; -import org.eclipse.jetty.deploy.ContextDeployer; -import org.eclipse.jetty.deploy.DeploymentManager; -import org.eclipse.jetty.deploy.WebAppDeployer; -import org.eclipse.jetty.osgi.boot.JettyBootstrapActivator; -import org.eclipse.jetty.osgi.boot.OSGiAppProvider; -import org.eclipse.jetty.osgi.boot.OSGiWebappConstants; -import org.eclipse.jetty.osgi.boot.internal.jsp.TldLocatableURLClassloader; -import org.eclipse.jetty.osgi.boot.internal.serverfactory.DefaultJettyAtJettyHomeHelper; -import org.eclipse.jetty.osgi.boot.internal.serverfactory.ServerInstanceWrapper; -import org.eclipse.jetty.osgi.boot.utils.BundleClassLoaderHelper; -import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelper; -import org.eclipse.jetty.osgi.boot.utils.WebappRegistrationCustomizer; -import org.eclipse.jetty.osgi.boot.utils.internal.DefaultBundleClassLoaderHelper; -import org.eclipse.jetty.osgi.boot.utils.internal.DefaultFileLocatorHelper; -import org.eclipse.jetty.server.Handler; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.handler.ContextHandler; -import org.eclipse.jetty.server.handler.ContextHandlerCollection; -import org.eclipse.jetty.server.handler.DefaultHandler; -import org.eclipse.jetty.server.handler.HandlerCollection; -import org.eclipse.jetty.server.handler.RequestLogHandler; -import org.eclipse.jetty.server.nio.SelectChannelConnector; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.util.resource.Resource; -import org.eclipse.jetty.webapp.WebAppContext; -import org.eclipse.jetty.xml.XmlConfiguration; -import org.osgi.framework.Bundle; -import org.osgi.framework.BundleContext; -import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; - -/** - * Bridges the jetty deployers with the OSGi lifecycle where applications are - * managed inside OSGi-bundles. - *

- * This class should be called as a consequence of the activation of a new - * service that is a ContextHandler.
- * This way the new webapps are exposed as OSGi services. - *

- *

- * Helper methods to register a bundle that is a web-application or a context. - *

- * Limitations: - *
    - *
  • support for jarred webapps is somewhat limited.
  • - *
- * @deprecated This works for a single instance of jetty and is both starting the jetty server and deploying the web-bundles. - * @see ServerInstanceWrapper - * @see WebBundleDeployerHelper - */ -public class WebappRegistrationHelper implements IWebBundleDeployerHelper -{ - - private static Logger __logger = Log.getLogger(WebappRegistrationHelper.class.getName()); - - private static boolean INITIALIZED = false; - - /** - * By default set to: {@link DefaultBundleClassLoaderHelper}. It supports - * equinox and apache-felix fragment bundles that are specific to an OSGi - * implementation should set a different implementation. - */ - private static BundleClassLoaderHelper BUNDLE_CLASS_LOADER_HELPER = null; - /** - * By default set to: {@link DefaultBundleClassLoaderHelper}. It supports - * equinox and apache-felix fragment bundles that are specific to an OSGi - * implementation should set a different implementation. - */ - private static BundleFileLocatorHelper BUNDLE_FILE_LOCATOR_HELPER = null; - - /** - * By default set to: {@link DefaultBundleClassLoaderHelper}. It supports - * equinox and apache-felix fragment bundles that are specific to an OSGi - * implementation should set a different implementation. - *

- * Several of those objects can be added here: For example we could have an optional fragment that setups - * a specific implementation of JSF for the whole of jetty-osgi. - *

- */ - public static Collection JSP_REGISTRATION_HELPERS = new ArrayList(); - - private Server _server; - private ContextHandlerCollection _ctxtHandler; - - /** - * this class loader loads the jars inside {$jetty.home}/lib/ext it is meant - * as a migration path and for jars that are not OSGi ready. also gives - * access to the jsp jars. - */ - // private URLClassLoader _libExtClassLoader; - - /** - * This is the class loader that should be the parent classloader of any - * webapp classloader. It is in fact the _libExtClassLoader with a trick to - * let the TldScanner find the jars where the tld files are. - */ - private ClassLoader _commonParentClassLoaderForWebapps; - - private DeploymentManager _deploymentManager; - - private OSGiAppProvider _provider; - - public WebappRegistrationHelper(Server server) - { - _server = server; - staticInit(); - } - - // Inject the customizing classes that might be defined in fragment bundles. - private static synchronized void staticInit() - { - if (!INITIALIZED) - { - INITIALIZED = true; - // setup the custom BundleClassLoaderHelper - try - { - BUNDLE_CLASS_LOADER_HELPER = (BundleClassLoaderHelper)Class.forName(BundleClassLoaderHelper.CLASS_NAME).newInstance(); - } - catch (Throwable t) - { - // System.err.println("support for equinox and felix"); - BUNDLE_CLASS_LOADER_HELPER = new DefaultBundleClassLoaderHelper(); - } - // setup the custom FileLocatorHelper - try - { - BUNDLE_FILE_LOCATOR_HELPER = (BundleFileLocatorHelper)Class.forName(BundleFileLocatorHelper.CLASS_NAME).newInstance(); - } - catch (Throwable t) - { - // System.err.println("no jsp/jasper support"); - BUNDLE_FILE_LOCATOR_HELPER = new DefaultFileLocatorHelper(); - } - } - } - - /** - * Removes quotes around system property values before we try to make them - * into file pathes. - */ - public static String stripQuotesIfPresent(String filePath) - { - if (filePath == null) - return null; - - if ((filePath.startsWith("\"") || filePath.startsWith("'")) && (filePath.endsWith("\"") || filePath.endsWith("'"))) - return filePath.substring(1,filePath.length() - 1); - return filePath; - } - - /** - * Look for the home directory of jetty as defined by the system property - * 'jetty.home'. If undefined, look at the current bundle and uses its own - * jettyhome folder for this feature. - *

- * Special case: inside eclipse-SDK:
- * If the bundle is jarred, see if we are inside eclipse-PDE itself. In that - * case, look for the installation directory of eclipse-PDE, try to create a - * jettyhome folder there and install the sample jettyhome folder at that - * location. This makes the installation in eclipse-SDK easier.
- * This is a bit redundant with the work done by the jetty configuration - * launcher. - *

- * - * @param context - * @throws Exception - */ - public void setup(BundleContext context, Map configProperties) throws Exception - { - Enumeration enUrls = context.getBundle().findEntries("/etc", "jetty.xml", false); - if (enUrls != null && enUrls.hasMoreElements()) - { - URL url = (URL) enUrls.nextElement(); - if (url != null) - { - //bug 317231: there is a fragment that defines the jetty configuration file. - //let's use that as the jetty home. - url = DefaultFileLocatorHelper.getLocalURL(url); - if (url.getProtocol().equals("file")) - { - //ok good. - File jettyxml = new File(url.toURI()); - File jettyhome = jettyxml.getParentFile().getParentFile(); - System.setProperty("jetty.home", jettyhome.getAbsolutePath()); - } - } - } - File _installLocation = BUNDLE_FILE_LOCATOR_HELPER.getBundleInstallLocation(context.getBundle()); - // debug: - // new File("~/proj/eclipse-install/eclipse-3.5.1-SDK-jetty7/" + - // "dropins/jetty7/plugins/org.eclipse.jetty.osgi.boot_0.0.1.001-SNAPSHOT.jar"); - boolean bootBundleCanBeJarred = true; - String jettyHome = stripQuotesIfPresent(System.getProperty("jetty.home")); - - if (jettyHome == null || jettyHome.length() == 0) - { - if (_installLocation != null) - { - if (jettyHome == null && _installLocation != null && _installLocation.isDirectory()) - { - jettyHome = _installLocation.getAbsolutePath() + "/jettyhome"; - bootBundleCanBeJarred = false; - } - } - } - if (jettyHome == null || (!bootBundleCanBeJarred && !_installLocation.isDirectory())) - { -// String install = _installLocation != null?_installLocation.getCanonicalPath():" unresolved_install_location"; -// throw new IllegalArgumentException("The system property -Djetty.home" + " must be set to a directory or the bundle " -// + context.getBundle().getSymbolicName() + " installed here " + install + " must be unjarred."); - } - else - { - // in case we stripped the quotes. - System.setProperty("jetty.home",jettyHome); - } - String jettyLogs = stripQuotesIfPresent(System.getProperty("jetty.logs")); - if (jettyLogs == null || jettyLogs.length() == 0) - { - System.setProperty("jetty.logs",jettyHome + "/logs"); - } - - if (jettyHome != null) - { - try - { - System.err.println("JETTY_HOME set to " + new File(jettyHome).getCanonicalPath()); - } - catch (Throwable t) - { - System.err.println("JETTY_HOME _set to " + new File(jettyHome).getAbsolutePath()); - } - } - else - { -// System.err.println("JETTY_HOME is not set"); - } - ClassLoader contextCl = Thread.currentThread().getContextClassLoader(); - try - { - - // passing this bundle's classloader as the context classlaoder - // makes sure there is access to all the jetty's bundles - File jettyHomeF = jettyHome != null ? new File(jettyHome) : null; - ClassLoader libExtClassLoader = null; - try - { - libExtClassLoader = LibExtClassLoaderHelper.createLibEtcClassLoader(jettyHomeF,_server, - JettyBootstrapActivator.class.getClassLoader()); - } - catch (MalformedURLException e) - { - e.printStackTrace(); - } - - Thread.currentThread().setContextClassLoader(libExtClassLoader); - - String jettyetc = System.getProperty(DefaultJettyAtJettyHomeHelper.SYS_PROP_JETTY_ETC_FILES,"etc/jetty.xml"); - StringTokenizer tokenizer = new StringTokenizer(jettyetc,";,"); - - Map id_map = new HashMap(); - id_map.put("Server",_server); - Map properties = new HashMap(); - if (jettyHome != null) - { - properties.put("jetty.home",jettyHome); - } - properties.put("jetty.host",System.getProperty("jetty.host")); - properties.put("jetty.port",System.getProperty("jetty.port", "8080")); - properties.put("jetty.port.ssl",System.getProperty("jetty.port.ssl", "8443")); - - while (tokenizer.hasMoreTokens()) - { - String etcFile = tokenizer.nextToken().trim(); - File conffile = null; - enUrls = null; - if (etcFile.indexOf(":") != -1) - { - conffile = Resource.newResource(etcFile).getFile(); - } - else if (etcFile.startsWith("/")) - { - conffile = new File(etcFile); - } - else if (jettyHomeF != null) - { - conffile = new File(jettyHomeF, etcFile); - } - else - { - int last = etcFile.lastIndexOf('/'); - String path = last != -1 && last < etcFile.length() -2 - ? etcFile.substring(0, last) : "/"; - if (!path.startsWith("/")) - { - path = "/" + path; - } - String pattern = last != -1 && last < etcFile.length() -2 - ? etcFile.substring(last+1) : etcFile; - enUrls = context.getBundle().findEntries(path, pattern, false); - if (pattern.equals("jetty.xml") && (enUrls == null || !enUrls.hasMoreElements())) - { - path = "/jettyhome" + path; - pattern = "jetty-osgi-default.xml"; - enUrls = context.getBundle().findEntries(path, pattern, false); - System.err.println("Configuring jetty with the default embedded configuration:" + - "bundle org.eclipse.jetty.boot.osgi /jettyhome/etc/jetty-osgi-default.xml"); - } - } - if (conffile != null && !conffile.exists()) - { - __logger.warn("Unable to resolve the xml configuration file for jetty " + etcFile); - - if ("etc/jetty.xml".equals(etcFile)) - { - // Missing jetty.xml file, so create a minimal Jetty configuration - __logger.info("Configuring default server on 8080"); - SelectChannelConnector connector = new SelectChannelConnector(); - connector.setPort(8080); - _server.addConnector(connector); - - HandlerCollection handlers = new HandlerCollection(); - ContextHandlerCollection contexts = new ContextHandlerCollection(); - RequestLogHandler requestLogHandler = new RequestLogHandler(); - handlers.setHandlers(new Handler[] { contexts, new DefaultHandler(), requestLogHandler }); - - _server.setHandler(handlers); - } - } - else - { - InputStream is = null; - try - { - // Execute a Jetty configuration file - XmlConfiguration config = null; - if (conffile != null && conffile.exists()) - { - is = new FileInputStream(conffile); - config =new XmlConfiguration(is); - } - else if (enUrls != null && enUrls.hasMoreElements()) - { - URL url = (URL) enUrls.nextElement(); - if (url != null) - { - //bug 317231: there is a fragment that defines the jetty configuration file. - //let's use that as the jetty home. - is = url.openStream(); - config = new XmlConfiguration(is); - } - else - { - System.err.println("Could not locate " + etcFile + - " inside " + context.getBundle().getSymbolicName()); - continue; - } - } - else - { - //it did not work. - continue; - } - - config.setIdMap(id_map); - config.setProperties(properties); - config.configure(); - id_map=config.getIdMap(); - } - catch (SAXParseException saxparse) - { - Log.getLogger(WebappRegistrationHelper.class.getName()).warn("Unable to configure the jetty/etc file " + etcFile,saxparse); - throw saxparse; - } - finally - { - if (is != null) try { is.close(); } catch (IOException ioe) {} - } - } - } - - init(); - - //now that we have an app provider we can call the registration customizer. - try - { - URL[] jarsWithTlds = getJarsWithTlds(); - _commonParentClassLoaderForWebapps = jarsWithTlds == null?libExtClassLoader:new TldLocatableURLClassloader(libExtClassLoader,jarsWithTlds); - } - catch (MalformedURLException e) - { - e.printStackTrace(); - } - _server.start(); - } - catch (Throwable t) - { - t.printStackTrace(); - } - finally - { - Thread.currentThread().setContextClassLoader(contextCl); - } - - } - - /** - * Must be called after the server is configured. - * - * Locate the actual instance of the ContextDeployer and WebAppDeployer that - * was created when configuring the server through jetty.xml. If there is no - * such thing it won't be possible to deploy webapps from a context and we - * throw IllegalStateExceptions. - */ - private void init() - { - if (_ctxtHandler != null) - { - return; - } - // Get the context handler - _ctxtHandler = (ContextHandlerCollection)_server.getChildHandlerByClass(ContextHandlerCollection.class); - - // get a deployerManager - List deployers = _server.getBeans(DeploymentManager.class); - if (deployers != null && !deployers.isEmpty()) - { - _deploymentManager = deployers.get(0); - - for (AppProvider provider : _deploymentManager.getAppProviders()) - { - if (provider instanceof OSGiAppProvider) - { - _provider=(OSGiAppProvider)provider; - break; - } - } - if (_provider == null) - { - //create it on the fly with reasonable default values. - try - { - _provider = new OSGiAppProvider(); - if (System.getProperty("jetty.home") != null) - { - _provider.setMonitoredDir( - Resource.newResource(getDefaultOSGiContextsHome( - new File(System.getProperty("jetty.home"))).toURI())); - } - - } catch (IOException e) { - e.printStackTrace(); - } - _deploymentManager.addAppProvider(_provider); - } - } - - if (_ctxtHandler == null || _provider==null) - throw new IllegalStateException("ERROR: No ContextHandlerCollection or OSGiAppProvider configured"); - - - } - - /** - * Deploy a new web application on the jetty server. - * - * @param bundle - * The bundle - * @param webappFolderPath - * The path to the root of the webapp. Must be a path relative to - * bundle; either an absolute path. - * @param contextPath - * The context path. Must start with "/" - * @param extraClasspath - * @param overrideBundleInstallLocation - * @param webXmlPath - * @param defaultWebXmlPath - * TODO: parameter description - * @return The contexthandler created and started - * @throws Exception - */ - public ContextHandler registerWebapplication(Bundle bundle, String webappFolderPath, String contextPath, String extraClasspath, - String overrideBundleInstallLocation, String webXmlPath, String defaultWebXmlPath) throws Exception - { - File bundleInstall = overrideBundleInstallLocation == null?BUNDLE_FILE_LOCATOR_HELPER.getBundleInstallLocation(bundle):new File( - overrideBundleInstallLocation); - File webapp = null; - if (webappFolderPath != null && webappFolderPath.length() != 0 && !webappFolderPath.equals(".")) - { - if (webappFolderPath.startsWith("/") || webappFolderPath.startsWith("file:/")) - { - webapp = new File(webappFolderPath); - } - else - { - webapp = new File(bundleInstall,webappFolderPath); - } - } - else - { - webapp = bundleInstall; - } - if (!webapp.exists()) - { - throw new IllegalArgumentException("Unable to locate " + webappFolderPath + " inside " - + (bundleInstall != null?bundleInstall.getAbsolutePath():"unlocated bundle '" + bundle.getSymbolicName() + "'")); - } - return registerWebapplication(bundle,webappFolderPath,webapp,contextPath,extraClasspath,bundleInstall,webXmlPath,defaultWebXmlPath); - } - - /** - * TODO: refactor this into the createContext method of OSGiAppProvider. - * @see WebAppDeployer#scan() - - * @param contributor - * @param webapp - * @param contextPath - * @param extraClasspath - * @param bundleInstall - * @param webXmlPath - * @param defaultWebXmlPath - * @return The contexthandler created and started - * @throws Exception - */ - public ContextHandler registerWebapplication(Bundle contributor, String pathInBundleToWebApp, File webapp, String contextPath, String extraClasspath, File bundleInstall, - String webXmlPath, String defaultWebXmlPath) throws Exception - { - - ClassLoader contextCl = Thread.currentThread().getContextClassLoader(); - String[] oldServerClasses = null; - WebAppContext context = null; - try - { - // make sure we provide access to all the jetty bundles by going - // through this bundle. - OSGiWebappClassLoader composite = createWebappClassLoader(contributor); - // configure with access to all jetty classes and also all the classes - // that the contributor gives access to. - Thread.currentThread().setContextClassLoader(composite); - - context = new WebAppContext(webapp.getAbsolutePath(),contextPath); - context.setExtraClasspath(extraClasspath); - - if (webXmlPath != null && webXmlPath.length() != 0) - { - File webXml = null; - if (webXmlPath.startsWith("/") || webXmlPath.startsWith("file:/")) - { - webXml = new File(webXmlPath); - } - else - { - webXml = new File(bundleInstall,webXmlPath); - } - if (webXml.exists()) - { - context.setDescriptor(webXml.getAbsolutePath()); - } - } - - if (defaultWebXmlPath == null || defaultWebXmlPath.length() == 0) - { - //use the one defined by the OSGiAppProvider. - defaultWebXmlPath = _provider.getDefaultsDescriptor(); - } - if (defaultWebXmlPath != null && defaultWebXmlPath.length() != 0) - { - File defaultWebXml = null; - if (defaultWebXmlPath.startsWith("/") || defaultWebXmlPath.startsWith("file:/")) - { - defaultWebXml = new File(webXmlPath); - } - else - { - defaultWebXml = new File(bundleInstall,defaultWebXmlPath); - } - if (defaultWebXml.exists()) - { - context.setDefaultsDescriptor(defaultWebXml.getAbsolutePath()); - } - } - - //other parameters that might be defines on the OSGiAppProvider: - context.setParentLoaderPriority(_provider.isParentLoaderPriority()); - - configureWebAppContext(context,contributor); - configureWebappClassLoader(contributor,context,composite); - - // @see - // org.eclipse.jetty.webapp.JettyWebXmlConfiguration#configure(WebAppContext) - // during initialization of the webapp all the jetty packages are - // visible - // through the webapp classloader. - oldServerClasses = context.getServerClasses(); - context.setServerClasses(null); - _provider.addContext(contributor,pathInBundleToWebApp,context); - return context; - } - finally - { - if (context != null && oldServerClasses != null) - { - context.setServerClasses(oldServerClasses); - } - Thread.currentThread().setContextClassLoader(contextCl); - } - - } - - /** - * Stop a ContextHandler and remove it from the collection. - * - * @see ContextDeployer#undeploy - * @param contextHandler - * @throws Exception - */ - public void unregister(ContextHandler contextHandler) throws Exception - { -// contextHandler.stop(); -// _ctxtHandler.removeHandler(contextHandler); - _provider.removeContext(contextHandler); - } - - /** - * @return The default folder in which the context files of the osgi bundles - * are located and watched. Or null when the system property - * "jetty.osgi.contexts.home" is not defined. - * If the configuration file defines the OSGiAppProvider's context. - * This will not be taken into account. - */ - File getDefaultOSGiContextsHome(File jettyHome) - { - String jettyContextsHome = System.getProperty("jetty.osgi.contexts.home"); - if (jettyContextsHome != null) - { - File contextsHome = new File(jettyContextsHome); - if (!contextsHome.exists() || !contextsHome.isDirectory()) - { - throw new IllegalArgumentException("the ${jetty.osgi.contexts.home} '" + jettyContextsHome + " must exist and be a folder"); - } - return contextsHome; - } - return new File(jettyHome, "/contexts"); - } - - File getOSGiContextsHome() - { - return _provider != null ? _provider.getContextXmlDirAsFile() : null; - } - - /** - * This type of registration relies on jetty's complete context xml file. - * Context encompasses jndi and all other things. This makes the definition - * of the webapp a lot more self-contained. - * - * @param contributor - * @param contextFileRelativePath - * @param extraClasspath - * @param overrideBundleInstallLocation - * @return The contexthandler created and started - * @throws Exception - */ - public ContextHandler registerContext(Bundle contributor, String contextFileRelativePath, String extraClasspath, String overrideBundleInstallLocation) - throws Exception - { - File contextsHome = _provider.getContextXmlDirAsFile(); - if (contextsHome != null) - { - File prodContextFile = new File(contextsHome,contributor.getSymbolicName() + "/" + contextFileRelativePath); - if (prodContextFile.exists()) - { - return registerContext(contributor,contextFileRelativePath,prodContextFile,extraClasspath,overrideBundleInstallLocation); - } - } - - File contextFile = overrideBundleInstallLocation != null?new File(overrideBundleInstallLocation,contextFileRelativePath):new File( - BUNDLE_FILE_LOCATOR_HELPER.getBundleInstallLocation(contributor),contextFileRelativePath); - if (contextFile.exists()) - { - return registerContext(contributor,contextFileRelativePath,contextFile,extraClasspath,overrideBundleInstallLocation); - } - else - { - if (contextFileRelativePath.startsWith("./")) - { - contextFileRelativePath = contextFileRelativePath.substring(1); - } - if (!contextFileRelativePath.startsWith("/")) - { - contextFileRelativePath = "/" + contextFileRelativePath; - } - - File overrideBundleInstallLocationF = overrideBundleInstallLocation != null ? Resource.newResource(overrideBundleInstallLocation).getFile() : null; - if (overrideBundleInstallLocationF == null) - { - URL contextURL = contributor.getEntry(contextFileRelativePath); - if (contextURL != null) - { - return registerContext(contributor,contextFileRelativePath,contextURL.openStream(),extraClasspath,overrideBundleInstallLocation); - } - } - else - { - JarFile zipFile = null; - try - { - zipFile = new JarFile(overrideBundleInstallLocation); - ZipEntry entry = zipFile.getEntry(contextFileRelativePath.substring(1)); - return registerContext(contributor,contextFileRelativePath,zipFile.getInputStream(entry),extraClasspath,overrideBundleInstallLocation); - } - catch (Throwable t) - { - - } - finally - { - if (zipFile != null) - try - { - zipFile.close(); - } - catch (IOException ioe) - { - } - } - } - throw new IllegalArgumentException("Could not find the context " + "file " + contextFileRelativePath + " for the bundle " - + contributor.getSymbolicName() + (overrideBundleInstallLocation != null?" using the install location " + overrideBundleInstallLocation:"")); - } - } - - /** - * This type of registration relies on jetty's complete context xml file. - * Context encompasses jndi and all other things. This makes the definition - * of the webapp a lot more self-contained. - * - * @param webapp - * @param contextPath - * @param classInBundle - * @throws Exception - */ - private ContextHandler registerContext(Bundle contributor, String pathInBundle, File contextFile, String extraClasspath, String overrideBundleInstallLocation) throws Exception - { - InputStream contextFileInputStream = null; - try - { - contextFileInputStream = new BufferedInputStream(new FileInputStream(contextFile)); - return registerContext(contributor, pathInBundle, contextFileInputStream,extraClasspath,overrideBundleInstallLocation); - } - finally - { - if (contextFileInputStream != null) - try - { - contextFileInputStream.close(); - } - catch (IOException ioe) - { - } - } - } - - /** - * @param contributor - * @param contextFileInputStream - * @return The ContextHandler created and registered or null if it did not - * happen. - * @throws Exception - */ - private ContextHandler registerContext(Bundle contributor, String pathInsideBundle, InputStream contextFileInputStream, String extraClasspath, String overrideBundleInstallLocation) - throws Exception - { - ClassLoader contextCl = Thread.currentThread().getContextClassLoader(); - String[] oldServerClasses = null; - WebAppContext webAppContext = null; - try - { - // make sure we provide access to all the jetty bundles by going - // through this bundle. - OSGiWebappClassLoader composite = createWebappClassLoader(contributor); - // configure with access to all jetty classes and also all the - // classes - // that the contributor gives access to. - Thread.currentThread().setContextClassLoader(composite); - ContextHandler context = createContextHandler(contributor,contextFileInputStream,extraClasspath,overrideBundleInstallLocation); - if (context == null) - { - return null;// did not happen - } - - // ok now register this webapp. we checked when we started jetty - // that there - // was at least one such handler for webapps. - //the actual registration must happen via the new Deployment API. -// _ctxtHandler.addHandler(context); - - configureWebappClassLoader(contributor,context,composite); - if (context instanceof WebAppContext) - { - webAppContext = (WebAppContext)context; - // @see - // org.eclipse.jetty.webapp.JettyWebXmlConfiguration#configure(WebAppContext) - oldServerClasses = webAppContext.getServerClasses(); - webAppContext.setServerClasses(null); - } - _provider.addContext(contributor, pathInsideBundle, context); - return context; - } - finally - { - if (webAppContext != null) - { - webAppContext.setServerClasses(oldServerClasses); - } - Thread.currentThread().setContextClassLoader(contextCl); - } - - } - - /** - * TODO: right now only the jetty-jsp bundle is scanned for common taglibs. - * Should support a way to plug more bundles that contain taglibs. - * - * The jasper TldScanner expects a URLClassloader to parse a jar for the - * /META-INF/*.tld it may contain. We place the bundles that we know contain - * such tag-libraries. Please note that it will work if and only if the - * bundle is a jar (!) Currently we just hardcode the bundle that contains - * the jstl implemenation. - * - * A workaround when the tld cannot be parsed with this method is to copy - * and paste it inside the WEB-INF of the webapplication where it is used. - * - * Support only 2 types of packaging for the bundle: - the bundle is a jar - * (recommended for runtime.) - the bundle is a folder and contain jars in - * the root and/or in the lib folder (nice for PDE developement situations) - * Unsupported: the bundle is a jar that embeds more jars. - * - * @return - * @throws Exception - */ - private URL[] getJarsWithTlds() throws Exception - { - ArrayList res = new ArrayList(); - for (WebappRegistrationCustomizer regCustomizer : JSP_REGISTRATION_HELPERS) - { - URL[] urls = regCustomizer.getJarsWithTlds(_provider, BUNDLE_FILE_LOCATOR_HELPER); - for (URL url : urls) - { - if (!res.contains(url)) - res.add(url); - } - } - if (!res.isEmpty()) - return res.toArray(new URL[res.size()]); - else - return null; - } - - /** - * Applies the properties of WebAppDeployer as defined in jetty.xml. - * - * @see {WebAppDeployer#scan} around the comment - * // configure it - */ - protected void configureWebAppContext(WebAppContext wah, Bundle contributor) - { - // rfc66 - wah.setAttribute(OSGiWebappConstants.RFC66_OSGI_BUNDLE_CONTEXT,contributor.getBundleContext()); - - //spring-dm-1.2.1 looks for the BundleContext as a different attribute. - //not a spec... but if we want to support - //org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext - //then we need to do this to: - wah.setAttribute("org.springframework.osgi.web." + BundleContext.class.getName(), - contributor.getBundleContext()); - - } - - /** - * @See {@link ContextDeployer#scan} - * @param contextFile - * @return - */ - protected ContextHandler createContextHandler(Bundle bundle, File contextFile, String extraClasspath, String overrideBundleInstallLocation) - { - try - { - return createContextHandler(bundle,new BufferedInputStream(new FileInputStream(contextFile)),extraClasspath,overrideBundleInstallLocation); - } - catch (FileNotFoundException e) - { - e.printStackTrace(); - } - return null; - } - - /** - * @See {@link ContextDeployer#scan} - * @param contextFile - * @return - */ - @SuppressWarnings("unchecked") - protected ContextHandler createContextHandler(Bundle bundle, InputStream contextInputStream, String extraClasspath, String overrideBundleInstallLocation) - { - /* - * Do something identical to what the ContextProvider would have done: - * XmlConfiguration xmlConfiguration=new - * XmlConfiguration(resource.getURL()); HashMap properties = new - * HashMap(); properties.put("Server", _contexts.getServer()); if - * (_configMgr!=null) properties.putAll(_configMgr.getProperties()); - * - * xmlConfiguration.setProperties(properties); ContextHandler - * context=(ContextHandler)xmlConfiguration.configure(); - * context.setAttributes(new AttributesMap(_contextAttributes)); - */ - try - { - XmlConfiguration xmlConfiguration = new XmlConfiguration(contextInputStream); - HashMap properties = new HashMap(); - properties.put("Server",_server); - - // insert the bundle's location as a property. - setThisBundleHomeProperty(bundle,properties,overrideBundleInstallLocation); - xmlConfiguration.setProperties(properties); - - ContextHandler context = (ContextHandler)xmlConfiguration.configure(); - if (context instanceof WebAppContext) - { - ((WebAppContext)context).setExtraClasspath(extraClasspath); - ((WebAppContext)context).setParentLoaderPriority(_provider.isParentLoaderPriority()); - if (_provider.getDefaultsDescriptor() != null && _provider.getDefaultsDescriptor().length() != 0) - { - ((WebAppContext)context).setDefaultsDescriptor(_provider.getDefaultsDescriptor()); - } - } - - // rfc-66: - context.setAttribute(OSGiWebappConstants.RFC66_OSGI_BUNDLE_CONTEXT,bundle.getBundleContext()); - - //spring-dm-1.2.1 looks for the BundleContext as a different attribute. - //not a spec... but if we want to support - //org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext - //then we need to do this to: - context.setAttribute("org.springframework.osgi.web." + BundleContext.class.getName(), - bundle.getBundleContext()); - return context; - } - catch (FileNotFoundException e) - { - return null; - } - catch (SAXException e) - { - // TODO Auto-generated catch block - e.printStackTrace(); - } - catch (IOException e) - { - // TODO Auto-generated catch block - e.printStackTrace(); - } - catch (Throwable e) - { - // TODO Auto-generated catch block - e.printStackTrace(); - } - finally - { - if (contextInputStream != null) - try - { - contextInputStream.close(); - } - catch (IOException ioe) - { - } - } - return null; - } - - /** - * Configure a classloader onto the context. If the context is a - * WebAppContext, build a WebAppClassLoader that has access to all the jetty - * classes thanks to the classloader of the JettyBootStrapper bundle and - * also has access to the classloader of the bundle that defines this - * context. - *

- * If the context is not a WebAppContext, same but with a simpler - * URLClassLoader. Note that the URLClassLoader is pretty much fake: it - * delegate all actual classloading to the parent classloaders. - *

- *

- * The URL[] returned by the URLClassLoader create contained specifically - * the jars that some j2ee tools expect and look into. For example the jars - * that contain tld files for jasper's jstl support. - *

- *

- * Also as the jars in the lib folder and the classes in the classes folder - * might already be in the OSGi classloader we filter them out of the - * WebAppClassLoader - *

- * - * @param context - * @param contributor - * @param webapp - * @param contextPath - * @param classInBundle - * @throws Exception - */ - protected void configureWebappClassLoader(Bundle contributor, ContextHandler context, OSGiWebappClassLoader webappClassLoader) throws Exception - { - if (context instanceof WebAppContext) - { - WebAppContext webappCtxt = (WebAppContext)context; - context.setClassLoader(webappClassLoader); - webappClassLoader.setWebappContext(webappCtxt); - } - else - { - context.setClassLoader(webappClassLoader); - } - } - - /** - * No matter what the type of webapp, we create a WebappClassLoader. - */ - protected OSGiWebappClassLoader createWebappClassLoader(Bundle contributor) throws Exception - { - // we use a temporary WebAppContext object. - // if this is a real webapp we will set it on it a bit later: once we - // know. - OSGiWebappClassLoader webappClassLoader = new OSGiWebappClassLoader( - _commonParentClassLoaderForWebapps,new WebAppContext(),contributor,BUNDLE_CLASS_LOADER_HELPER); - return webappClassLoader; - } - - /** - * Set the property "this.bundle.install" to point to the location - * of the bundle. Useful when is - * used. - */ - private void setThisBundleHomeProperty(Bundle bundle, HashMap properties, String overrideBundleInstallLocation) - { - try - { - File location = overrideBundleInstallLocation != null?new File(overrideBundleInstallLocation):BUNDLE_FILE_LOCATOR_HELPER - .getBundleInstallLocation(bundle); - properties.put("this.bundle.install",location.getCanonicalPath()); - } - catch (Throwable t) - { - System.err.println("Unable to set 'this.bundle.install' " + " for the bundle " + bundle.getSymbolicName()); - t.printStackTrace(); - } - } - - -} diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleFileLocatorHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleFileLocatorHelper.java index d0a75c5b2cb..820a627e1f2 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleFileLocatorHelper.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleFileLocatorHelper.java @@ -13,6 +13,8 @@ package org.eclipse.jetty.osgi.boot.utils; import java.io.File; +import java.net.URL; +import java.util.Enumeration; import org.eclipse.jetty.osgi.boot.utils.internal.DefaultFileLocatorHelper; import org.osgi.framework.Bundle; @@ -73,5 +75,16 @@ public interface BundleFileLocatorHelper * embedded inside it. */ public File[] locateJarsInsideBundle(Bundle bundle) throws Exception; + + + /** + * Helper method equivalent to Bundle#getEntry(String entryPath) except that + * it searches for entries in the fragments by using the findEntries method. + * + * @param bundle + * @param entryPath + * @return null or all the entries found for that path. + */ + public Enumeration findEntries(Bundle bundle, String entryPath); } diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultFileLocatorHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultFileLocatorHelper.java index fce3b1a68c7..ec8f997d697 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultFileLocatorHelper.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultFileLocatorHelper.java @@ -20,6 +20,7 @@ import java.net.URL; import java.net.URLConnection; import java.net.URLDecoder; import java.util.ArrayList; +import java.util.Enumeration; import java.util.zip.ZipFile; import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelper; @@ -141,13 +142,19 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper { //location defined in the BundleArchive m_bundleArchive //it is relative to relative to the BundleArchive's m_archiveRootDir - Object bundleArchive = getFelixBundleArchive(bundle); - File archiveRoot = getFelixBundleArchiveRootDir(bundleArchive); - String currentLocation = getFelixBundleArchiveCurrentLocation(bundleArchive); -// System.err.println("Got the archive root " + archiveRoot.getAbsolutePath() -// + " current location " + currentLocation); - return new File(archiveRoot, currentLocation != null - ? currentLocation : location.substring("file:".length())); + File res = new File(location.substring("file:".length())); + if (!res.exists()) + { + return null; +// Object bundleArchive = getFelixBundleArchive(bundle); +// File archiveRoot = getFelixBundleArchiveRootDir(bundleArchive); +// String currentLocation = getFelixBundleArchiveCurrentLocation(bundleArchive); +// System.err.println("Got the archive root " + archiveRoot.getAbsolutePath() +// + " current location " + currentLocation + " is directory ?"); +// res = new File(archiveRoot, currentLocation != null +// ? currentLocation : location.substring("file:".length())); + } + return res; } else if (location.startsWith("reference:file:")) { @@ -182,6 +189,29 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper } return webapp; } + + /** + * Helper method equivalent to Bundle#getEntry(String entryPath) except that + * it searches for entries in the fragments by using the Bundle#findEntries method. + * + * @param bundle + * @param entryPath + * @return null or all the entries found for that path. + */ + public Enumeration findEntries(Bundle bundle, String entryPath) + { + int last = entryPath.lastIndexOf('/'); + String path = last != -1 && last < entryPath.length() -2 + ? entryPath.substring(0, last) : "/"; + if (!path.startsWith("/")) + { + path = "/" + path; + } + String pattern = last != -1 && last < entryPath.length() -2 + ? entryPath.substring(last+1) : entryPath; + Enumeration enUrls = bundle.findEntries(path, pattern, false); + return enUrls; + } /** * If the bundle is a jar, returns the jar. If the bundle is a folder, look @@ -231,6 +261,7 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper //introspection on equinox to invoke the getLocalURL method on BundleURLConnection + //equivalent to using the FileLocator without depending on an equinox class. private static Method BUNDLE_URL_CONNECTION_getLocalURL = null; private static Method BUNDLE_URL_CONNECTION_getFileURL = null; /** @@ -297,62 +328,5 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper } return url; } - - - //introspection on felix - private static Field m_bundleArchive_FIELD = null; - private static Field m_archiveRootDir_FIELD = null; - private static Field m_currentLocation_FIELD = null; - private static Object getFelixBundleArchive(Bundle bundle) - { - try - { - if (m_bundleArchive_FIELD == null) - { - m_bundleArchive_FIELD = bundle.getClass().getDeclaredField("m_archive"); - m_bundleArchive_FIELD.setAccessible(true); - } - return m_bundleArchive_FIELD.get(bundle); - } - catch (Throwable t) - { - t.printStackTrace(); - } - return null; - } - private static File getFelixBundleArchiveRootDir(Object bundleArchive) - { - try - { - if (m_archiveRootDir_FIELD == null) - { - m_archiveRootDir_FIELD = bundleArchive.getClass().getDeclaredField("m_archiveRootDir"); - m_archiveRootDir_FIELD.setAccessible(true); - } - return (File)m_archiveRootDir_FIELD.get(bundleArchive); - } - catch (Throwable t) - { - t.printStackTrace(); - } - return null; - } - private static String getFelixBundleArchiveCurrentLocation(Object bundleArchive) - { - try - { - if (m_currentLocation_FIELD == null) - { - m_currentLocation_FIELD = bundleArchive.getClass().getDeclaredField("m_currentLocation"); - m_currentLocation_FIELD.setAccessible(true); - } - return (String)m_currentLocation_FIELD.get(bundleArchive); - } - catch (Throwable t) - { - t.printStackTrace(); - } - return null; - } }