Reformat src code; ensure url caching is controlled by jetty Resource.setDefaultUseCaches
This commit is contained in:
parent
792b101639
commit
911643b783
|
@ -28,98 +28,106 @@ import org.osgi.framework.Bundle;
|
|||
import org.osgi.framework.FrameworkUtil;
|
||||
|
||||
/**
|
||||
* Plug bundles that contains tld files so that jasper will discover them
|
||||
* and set them up in jetty.
|
||||
* Plug bundles that contains tld files so that jasper will discover them and
|
||||
* set them up in jetty.
|
||||
*
|
||||
* For example: -Dorg.eclipse.jetty.osgi.tldbundles=org.springframework.web.servlet,com.opensymphony.module.sitemesh
|
||||
* Otherwise use an attribute to the WebAppDeployer
|
||||
* <New class="org.eclipse.jetty.deploy.providers.WebAppProvider">
|
||||
* ....
|
||||
* <Set name="tldBundles"><Property name="org.eclipse.jetty.osgi.tldsbundles" default="" /></Set>
|
||||
* <New>
|
||||
* For example:
|
||||
* -Dorg.eclipse.jetty.osgi.tldbundles=org.springframework.web.servlet
|
||||
* ,com.opensymphony.module.sitemesh Otherwise use an attribute to the
|
||||
* WebAppDeployer <New
|
||||
* class="org.eclipse.jetty.deploy.providers.WebAppProvider"> .... <Set
|
||||
* name="tldBundles"><Property name="org.eclipse.jetty.osgi.tldsbundles"
|
||||
* default="" /></Set> <New>
|
||||
*/
|
||||
public class PluggableWebAppRegistrationCustomizerImpl implements WebappRegistrationCustomizer
|
||||
{
|
||||
/**
|
||||
* To plug into jasper bundles that contain tld files
|
||||
* please use a list of bundle's symbolic names:
|
||||
* -Djetty.osgi.tldbundles=org.springframework.web.servlet,com.opensymphony.module.sitemesh
|
||||
*/
|
||||
public static final String SYS_PROP_TLD_BUNDLES = "org.eclipse.jetty.osgi.tldbundles";
|
||||
|
||||
/**
|
||||
* Union of the tld bundles defined system wide and the one defines as an attribute of the AppProvider.
|
||||
* @param provider
|
||||
* @return
|
||||
*/
|
||||
private static Collection<String> getTldBundles(OSGiAppProvider provider)
|
||||
{
|
||||
String sysprop = System.getProperty(SYS_PROP_TLD_BUNDLES);
|
||||
String att = (String)provider.getTldBundles();
|
||||
if (sysprop == null && att == null)
|
||||
{
|
||||
return Collections.emptySet();
|
||||
}
|
||||
if (att == null)
|
||||
{
|
||||
att = sysprop;
|
||||
}
|
||||
else if (sysprop != null)
|
||||
{
|
||||
att = att + "," + sysprop;
|
||||
}
|
||||
|
||||
Collection<String> tldbundles = new HashSet<String>();
|
||||
StringTokenizer tokenizer = new StringTokenizer(att, ", \n\r\t", false);
|
||||
while (tokenizer.hasMoreTokens())
|
||||
{
|
||||
tldbundles.add(tokenizer.nextToken());
|
||||
}
|
||||
return tldbundles;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The location of the jars that contain tld files.
|
||||
* Jasper will discover them.
|
||||
*/
|
||||
/**
|
||||
* To plug into jasper bundles that contain tld files please use a list of
|
||||
* bundle's symbolic names:
|
||||
* -Djetty.osgi.tldbundles=org.springframework.web.servlet
|
||||
* ,com.opensymphony.module.sitemesh
|
||||
*/
|
||||
public static final String SYS_PROP_TLD_BUNDLES = "org.eclipse.jetty.osgi.tldbundles";
|
||||
|
||||
/**
|
||||
* Union of the tld bundles defined system wide and the one defines as an
|
||||
* attribute of the AppProvider.
|
||||
*
|
||||
* @param provider
|
||||
* @return
|
||||
*/
|
||||
private static Collection<String> getTldBundles(OSGiAppProvider provider)
|
||||
{
|
||||
String sysprop = System.getProperty(SYS_PROP_TLD_BUNDLES);
|
||||
String att = (String) provider.getTldBundles();
|
||||
if (sysprop == null && att == null) { return Collections.emptySet(); }
|
||||
if (att == null)
|
||||
{
|
||||
att = sysprop;
|
||||
}
|
||||
else if (sysprop != null)
|
||||
{
|
||||
att = att + "," + sysprop;
|
||||
}
|
||||
|
||||
Collection<String> tldbundles = new HashSet<String>();
|
||||
StringTokenizer tokenizer = new StringTokenizer(att, ", \n\r\t", false);
|
||||
while (tokenizer.hasMoreTokens())
|
||||
{
|
||||
tldbundles.add(tokenizer.nextToken());
|
||||
}
|
||||
return tldbundles;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The location of the jars that contain tld files. Jasper will
|
||||
* discover them.
|
||||
*/
|
||||
public URL[] getJarsWithTlds(OSGiAppProvider provider, BundleFileLocatorHelper locatorHelper) throws Exception
|
||||
{
|
||||
List<URL> urls = new ArrayList<URL>();
|
||||
//naive way of finding those bundles.
|
||||
//lots of assumptions: for example we assume a single version of each bundle that would contain tld files.
|
||||
//this is probably good enough as those tlds are loaded system-wide on jetty.
|
||||
//to do better than this we need to do it on a per webapp basis.
|
||||
//probably using custom properties in the ContextHandler service
|
||||
//and mirroring those in the MANIFEST.MF
|
||||
|
||||
Bundle[] bundles = FrameworkUtil.getBundle(PluggableWebAppRegistrationCustomizerImpl.class).getBundleContext().getBundles();
|
||||
Collection<String> tldbundles = getTldBundles(provider);
|
||||
for (Bundle bundle : bundles)
|
||||
{
|
||||
if (tldbundles.contains(bundle.getSymbolicName()))
|
||||
{
|
||||
registerTldBundle(locatorHelper, bundle, urls);
|
||||
}
|
||||
}
|
||||
|
||||
return urls.toArray(new URL[urls.size()]);
|
||||
List<URL> urls = new ArrayList<URL>();
|
||||
// naive way of finding those bundles.
|
||||
// lots of assumptions: for example we assume a single version of each
|
||||
// bundle that would contain tld files.
|
||||
// this is probably good enough as those tlds are loaded system-wide on
|
||||
// jetty.
|
||||
// to do better than this we need to do it on a per webapp basis.
|
||||
// probably using custom properties in the ContextHandler service
|
||||
// and mirroring those in the MANIFEST.MF
|
||||
|
||||
Bundle[] bundles = FrameworkUtil.getBundle(PluggableWebAppRegistrationCustomizerImpl.class).getBundleContext().getBundles();
|
||||
Collection<String> tldbundles = getTldBundles(provider);
|
||||
for (Bundle bundle : bundles)
|
||||
{
|
||||
if (tldbundles.contains(bundle.getSymbolicName()))
|
||||
{
|
||||
registerTldBundle(locatorHelper, bundle, urls);
|
||||
}
|
||||
}
|
||||
|
||||
return urls.toArray(new URL[urls.size()]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Resolves the bundle that contains tld files as a set of URLs that will be
|
||||
* passed to jasper as a URLClassLoader later on.
|
||||
* Usually that would be a single URL per bundle.
|
||||
* But we do some more work if there are jars embedded in the bundle.
|
||||
* passed to jasper as a URLClassLoader later on. Usually that would be a
|
||||
* single URL per bundle. But we do some more work if there are jars
|
||||
* embedded in the bundle.
|
||||
*
|
||||
* 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.
|
||||
* 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.
|
||||
* 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.
|
||||
* 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.
|
||||
*
|
||||
* @param locatorHelper
|
||||
* @param bundle
|
||||
|
@ -152,9 +160,9 @@ public class PluggableWebAppRegistrationCustomizerImpl implements WebappRegistra
|
|||
}
|
||||
else
|
||||
{
|
||||
urls.add(jasperLocation.toURI().toURL());
|
||||
urls.add(jasperLocation.toURI().toURL());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -36,48 +36,52 @@ import org.xml.sax.InputSource;
|
|||
import org.xml.sax.SAXException;
|
||||
|
||||
/**
|
||||
* Fix various shortcomings with the way jasper parses the tld files.
|
||||
* Plugs the JSTL tlds assuming that they are packaged with the bundle that contains the JSTL classes.
|
||||
* Fix various shortcomings with the way jasper parses the tld files. Plugs the
|
||||
* JSTL tlds assuming that they are packaged with the bundle that contains the
|
||||
* JSTL classes.
|
||||
* <p>
|
||||
* Pluggable tlds at the server level are handled by {@link PluggableWebAppRegistrationCustomizerImpl}.
|
||||
* Pluggable tlds at the server level are handled by
|
||||
* {@link PluggableWebAppRegistrationCustomizerImpl}.
|
||||
* </p>
|
||||
*/
|
||||
public class WebappRegistrationCustomizerImpl implements WebappRegistrationCustomizer
|
||||
{
|
||||
|
||||
/**
|
||||
* Default name of a class that belongs to the jstl bundle.
|
||||
* From that class we locate the corresponding bundle and register it
|
||||
* as a bundle that contains tld files.
|
||||
*/
|
||||
private static String DEFAULT_JSTL_BUNDLE_CLASS = "org.apache.taglibs.standard.tag.el.core.WhenTag";
|
||||
//used to be "org.apache.jasper.runtime.JspFactoryImpl" but now
|
||||
//the standard tag library implementation are stored in a separate bundle.
|
||||
|
||||
//DISABLED please use the tld bundle argument for the OSGiAppProvider
|
||||
// /**
|
||||
// * Default name of a class that belongs to the bundle where the Java server Faces tld files are defined.
|
||||
// * This is the sun's reference implementation.
|
||||
// */
|
||||
// private static String DEFAUT_JSF_IMPL_CLASS = "com.sun.faces.config.ConfigureListener";
|
||||
|
||||
/**
|
||||
* Default jsp factory implementation.
|
||||
* Idally jasper is osgified and we can use services.
|
||||
* In the mean time we statically set the jsp factory implementation.
|
||||
* bug #299733
|
||||
*/
|
||||
private static String DEFAULT_JSP_FACTORY_IMPL_CLASS = "org.apache.jasper.runtime.JspFactoryImpl";
|
||||
|
||||
/**
|
||||
* Default name of a class that belongs to the jstl bundle. From that class
|
||||
* we locate the corresponding bundle and register it as a bundle that
|
||||
* contains tld files.
|
||||
*/
|
||||
private static String DEFAULT_JSTL_BUNDLE_CLASS = "org.apache.taglibs.standard.tag.el.core.WhenTag";
|
||||
|
||||
// used to be "org.apache.jasper.runtime.JspFactoryImpl" but now
|
||||
// the standard tag library implementation are stored in a separate bundle.
|
||||
|
||||
// DISABLED please use the tld bundle argument for the OSGiAppProvider
|
||||
// /**
|
||||
// * Default name of a class that belongs to the bundle where the Java
|
||||
// server Faces tld files are defined.
|
||||
// * This is the sun's reference implementation.
|
||||
// */
|
||||
// private static String DEFAUT_JSF_IMPL_CLASS =
|
||||
// "com.sun.faces.config.ConfigureListener";
|
||||
|
||||
/**
|
||||
* Default jsp factory implementation. Idally jasper is osgified and we can
|
||||
* use services. In the mean time we statically set the jsp factory
|
||||
* implementation. bug #299733
|
||||
*/
|
||||
private static String DEFAULT_JSP_FACTORY_IMPL_CLASS = "org.apache.jasper.runtime.JspFactoryImpl";
|
||||
|
||||
public WebappRegistrationCustomizerImpl()
|
||||
{
|
||||
fixupDtdResolution();
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
//sanity check:
|
||||
// sanity check:
|
||||
Class cl = getClass().getClassLoader().loadClass("org.apache.jasper.servlet.JspServlet");
|
||||
//System.err.println("found the jsp servlet: " + cl.getName());
|
||||
// System.err.println("found the jsp servlet: " + cl.getName());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -87,18 +91,18 @@ public class WebappRegistrationCustomizerImpl implements WebappRegistrationCusto
|
|||
}
|
||||
try
|
||||
{
|
||||
//bug #299733
|
||||
// bug #299733
|
||||
JspFactory fact = JspFactory.getDefaultFactory();
|
||||
if (fact == null)
|
||||
{ //bug #299733
|
||||
//JspFactory does a simple Class.getForName("org.apache.jasper.runtime.JspFactoryImpl")
|
||||
//however its bundles does not import the jasper package
|
||||
//so it fails. let's help things out:
|
||||
fact = (JspFactory)JettyBootstrapActivator.class.getClassLoader()
|
||||
.loadClass(DEFAULT_JSP_FACTORY_IMPL_CLASS).newInstance();
|
||||
{ // bug #299733
|
||||
// JspFactory does a simple
|
||||
// Class.getForName("org.apache.jasper.runtime.JspFactoryImpl")
|
||||
// however its bundles does not import the jasper package
|
||||
// so it fails. let's help things out:
|
||||
fact = (JspFactory) JettyBootstrapActivator.class.getClassLoader().loadClass(DEFAULT_JSP_FACTORY_IMPL_CLASS).newInstance();
|
||||
JspFactory.setDefaultFactory(fact);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -106,85 +110,90 @@ public class WebappRegistrationCustomizerImpl implements WebappRegistrationCusto
|
|||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* 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.
|
||||
* 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.
|
||||
* 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 array of URLs
|
||||
* @throws Exception
|
||||
*/
|
||||
public URL[] getJarsWithTlds(OSGiAppProvider provider, BundleFileLocatorHelper locatorHelper) throws Exception
|
||||
{
|
||||
|
||||
HashSet<Class<?>> classesToAddToTheTldBundles = new HashSet<Class<?>>();
|
||||
|
||||
//Look for the jstl bundle
|
||||
//We assume the jstl's tlds are defined there.
|
||||
//We assume that the jstl bundle is imported by this bundle
|
||||
//So we can look for this class using this bundle's classloader:
|
||||
Class<?> jstlClass = WebappRegistrationCustomizerImpl.class.getClassLoader().loadClass(DEFAULT_JSTL_BUNDLE_CLASS);
|
||||
|
||||
classesToAddToTheTldBundles.add(jstlClass);
|
||||
|
||||
HashSet<Class<?>> classesToAddToTheTldBundles = new HashSet<Class<?>>();
|
||||
|
||||
// Look for the jstl bundle
|
||||
// We assume the jstl's tlds are defined there.
|
||||
// We assume that the jstl bundle is imported by this bundle
|
||||
// So we can look for this class using this bundle's classloader:
|
||||
Class<?> jstlClass = WebappRegistrationCustomizerImpl.class.getClassLoader().loadClass(DEFAULT_JSTL_BUNDLE_CLASS);
|
||||
|
||||
classesToAddToTheTldBundles.add(jstlClass);
|
||||
|
||||
ArrayList<URL> urls = new ArrayList<URL>();
|
||||
for (Class<?> cl : classesToAddToTheTldBundles)
|
||||
{
|
||||
Bundle tldBundle = FrameworkUtil.getBundle(cl);
|
||||
File tldBundleLocation = locatorHelper.getBundleInstallLocation(tldBundle);
|
||||
if (tldBundleLocation != null && tldBundleLocation.isDirectory())
|
||||
{
|
||||
// try to find the jar files inside this folder
|
||||
for (File f : tldBundleLocation.listFiles())
|
||||
{
|
||||
if (f.getName().endsWith(".jar") && f.isFile())
|
||||
{
|
||||
urls.add(f.toURI().toURL());
|
||||
}
|
||||
else if (f.isDirectory() && f.getName().equals("lib"))
|
||||
{
|
||||
for (File f2 : tldBundleLocation.listFiles())
|
||||
{
|
||||
if (f2.getName().endsWith(".jar") && f2.isFile())
|
||||
{
|
||||
urls.add(f2.toURI().toURL());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if (tldBundleLocation != null)
|
||||
{
|
||||
urls.add(tldBundleLocation.toURI().toURL());
|
||||
}
|
||||
}
|
||||
return urls.toArray(new URL[urls.size()]);
|
||||
for (Class<?> cl : classesToAddToTheTldBundles)
|
||||
{
|
||||
Bundle tldBundle = FrameworkUtil.getBundle(cl);
|
||||
File tldBundleLocation = locatorHelper.getBundleInstallLocation(tldBundle);
|
||||
if (tldBundleLocation != null && tldBundleLocation.isDirectory())
|
||||
{
|
||||
// try to find the jar files inside this folder
|
||||
for (File f : tldBundleLocation.listFiles())
|
||||
{
|
||||
if (f.getName().endsWith(".jar") && f.isFile())
|
||||
{
|
||||
urls.add(f.toURI().toURL());
|
||||
}
|
||||
else if (f.isDirectory() && f.getName().equals("lib"))
|
||||
{
|
||||
for (File f2 : tldBundleLocation.listFiles())
|
||||
{
|
||||
if (f2.getName().endsWith(".jar") && f2.isFile())
|
||||
{
|
||||
urls.add(f2.toURI().toURL());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if (tldBundleLocation != null)
|
||||
{
|
||||
urls.add(tldBundleLocation.toURI().toURL());
|
||||
}
|
||||
}
|
||||
return urls.toArray(new URL[urls.size()]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Jasper resolves the dtd when it parses a taglib descriptor.
|
||||
* It uses this code to do that: ParserUtils.getClass().getResourceAsStream(resourcePath); where
|
||||
* resourcePath is for example: /javax/servlet/jsp/resources/web-jsptaglibrary_1_2.dtd Unfortunately,
|
||||
* the dtd file is not in the exact same classloader as
|
||||
* ParserUtils class and the dtds are packaged in 2 separate bundles.
|
||||
* OSGi does not look in the dependencies' classloader when a resource is searched.
|
||||
* Jasper resolves the dtd when it parses a taglib descriptor. It uses this
|
||||
* code to do that:
|
||||
* ParserUtils.getClass().getResourceAsStream(resourcePath); where
|
||||
* resourcePath is for example:
|
||||
* /javax/servlet/jsp/resources/web-jsptaglibrary_1_2.dtd Unfortunately, the
|
||||
* dtd file is not in the exact same classloader as ParserUtils class and
|
||||
* the dtds are packaged in 2 separate bundles. OSGi does not look in the
|
||||
* dependencies' classloader when a resource is searched.
|
||||
* <p>
|
||||
* The workaround consists of setting the entity resolver. That is a patch
|
||||
* added to the version of glassfish-jasper-jetty. IT is also present in the latest
|
||||
* version of glassfish jasper. Could not use introspection to set new value
|
||||
* on a static friendly field :(
|
||||
* The workaround consists of setting the entity resolver. That is a patch
|
||||
* added to the version of glassfish-jasper-jetty. IT is also present in the
|
||||
* latest version of glassfish jasper. Could not use introspection to set
|
||||
* new value on a static friendly field :(
|
||||
* </p>
|
||||
*/
|
||||
void fixupDtdResolution()
|
||||
void fixupDtdResolution()
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -199,29 +208,23 @@ public class WebappRegistrationCustomizerImpl implements WebappRegistrationCusto
|
|||
}
|
||||
|
||||
/**
|
||||
* Instead of using the ParserUtil's classloader, we use a class that is indeed next to the resource for sure.
|
||||
* Instead of using the ParserUtil's classloader, we use a class that is
|
||||
* indeed next to the resource for sure.
|
||||
*/
|
||||
static class MyFixedupEntityResolver implements EntityResolver
|
||||
{
|
||||
/**
|
||||
* Same values than in ParserUtils...
|
||||
*/
|
||||
static final String[] CACHED_DTD_PUBLIC_IDS =
|
||||
{ Constants.TAGLIB_DTD_PUBLIC_ID_11, Constants.TAGLIB_DTD_PUBLIC_ID_12,
|
||||
Constants.WEBAPP_DTD_PUBLIC_ID_22, Constants.WEBAPP_DTD_PUBLIC_ID_23, };
|
||||
static final String[] CACHED_DTD_PUBLIC_IDS = { Constants.TAGLIB_DTD_PUBLIC_ID_11, Constants.TAGLIB_DTD_PUBLIC_ID_12,
|
||||
Constants.WEBAPP_DTD_PUBLIC_ID_22, Constants.WEBAPP_DTD_PUBLIC_ID_23, };
|
||||
|
||||
static final String[] CACHED_DTD_RESOURCE_PATHS =
|
||||
{ Constants.TAGLIB_DTD_RESOURCE_PATH_11,
|
||||
Constants.TAGLIB_DTD_RESOURCE_PATH_12,
|
||||
Constants.WEBAPP_DTD_RESOURCE_PATH_22,
|
||||
Constants.WEBAPP_DTD_RESOURCE_PATH_23, };
|
||||
static final String[] CACHED_DTD_RESOURCE_PATHS = { Constants.TAGLIB_DTD_RESOURCE_PATH_11, Constants.TAGLIB_DTD_RESOURCE_PATH_12,
|
||||
Constants.WEBAPP_DTD_RESOURCE_PATH_22, Constants.WEBAPP_DTD_RESOURCE_PATH_23, };
|
||||
|
||||
static final String[] CACHED_SCHEMA_RESOURCE_PATHS = { Constants.TAGLIB_SCHEMA_RESOURCE_PATH_20, Constants.TAGLIB_SCHEMA_RESOURCE_PATH_21,
|
||||
Constants.WEBAPP_SCHEMA_RESOURCE_PATH_24, Constants.WEBAPP_SCHEMA_RESOURCE_PATH_25, };
|
||||
|
||||
static final String[] CACHED_SCHEMA_RESOURCE_PATHS = {
|
||||
Constants.TAGLIB_SCHEMA_RESOURCE_PATH_20,
|
||||
Constants.TAGLIB_SCHEMA_RESOURCE_PATH_21,
|
||||
Constants.WEBAPP_SCHEMA_RESOURCE_PATH_24,
|
||||
Constants.WEBAPP_SCHEMA_RESOURCE_PATH_25,
|
||||
};
|
||||
public InputSource resolveEntity(String publicId, String systemId) throws SAXException
|
||||
{
|
||||
for (int i = 0; i < CACHED_DTD_PUBLIC_IDS.length; i++)
|
||||
|
@ -242,10 +245,7 @@ public class WebappRegistrationCustomizerImpl implements WebappRegistrationCusto
|
|||
input = this.getClass().getResourceAsStream(resourcePath);
|
||||
}
|
||||
}
|
||||
if (input == null)
|
||||
{
|
||||
throw new SAXException(Localizer.getMessage("jsp.error.internal.filenotfound",resourcePath));
|
||||
}
|
||||
if (input == null) { throw new SAXException(Localizer.getMessage("jsp.error.internal.filenotfound", resourcePath)); }
|
||||
InputSource isrc = new InputSource(input);
|
||||
return isrc;
|
||||
}
|
||||
|
@ -254,5 +254,5 @@ public class WebappRegistrationCustomizerImpl implements WebappRegistrationCusto
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -19,15 +19,14 @@ import org.osgi.framework.BundleActivator;
|
|||
import org.osgi.framework.BundleContext;
|
||||
|
||||
/**
|
||||
* Pseudo fragment activator.
|
||||
* Called by the main org.eclipse.jetty.osgi.boot bundle.
|
||||
* Please note: this is not a real BundleActivator. Simply something called back by
|
||||
* the host bundle.
|
||||
* Pseudo fragment activator. Called by the main org.eclipse.jetty.osgi.boot
|
||||
* bundle. Please note: this is not a real BundleActivator. Simply something
|
||||
* called back by the host bundle.
|
||||
* <p>
|
||||
* It must be placed in the org.eclipse.jetty.osgi.boot.jsp package:
|
||||
* this is because org.eclipse.jetty.osgi.boot.jsp is the sympbolic-name
|
||||
* of this fragment. From that name, the PackageadminTracker will call
|
||||
* this class. IN a different package it won't be called.
|
||||
* It must be placed in the org.eclipse.jetty.osgi.boot.jsp package: this is
|
||||
* because org.eclipse.jetty.osgi.boot.jsp is the sympbolic-name of this
|
||||
* fragment. From that name, the PackageadminTracker will call this class. IN a
|
||||
* different package it won't be called.
|
||||
* </p>
|
||||
*/
|
||||
public class FragmentActivator implements BundleActivator
|
||||
|
@ -35,7 +34,8 @@ public class FragmentActivator implements BundleActivator
|
|||
/**
|
||||
*
|
||||
*/
|
||||
public void start(BundleContext context) throws Exception {
|
||||
public void start(BundleContext context) throws Exception
|
||||
{
|
||||
System.setProperty("org.apache.jasper.compiler.disablejsr199", Boolean.TRUE.toString());
|
||||
WebBundleDeployerHelper.JSP_REGISTRATION_HELPERS.add(new WebappRegistrationCustomizerImpl());
|
||||
WebBundleDeployerHelper.JSP_REGISTRATION_HELPERS.add(new PluggableWebAppRegistrationCustomizerImpl());
|
||||
|
@ -44,7 +44,8 @@ public class FragmentActivator implements BundleActivator
|
|||
/**
|
||||
*
|
||||
*/
|
||||
public void stop(BundleContext context) throws Exception {
|
||||
|
||||
public void stop(BundleContext context) throws Exception
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,123 +35,120 @@ import org.osgi.util.tracker.ServiceTracker;
|
|||
* Replacement for {@link TagLibConfiguration} for the OSGi integration.
|
||||
* </p>
|
||||
* <p>
|
||||
* In the case of a WAB, tlds can be located in OSGi bundles that are dependencies
|
||||
* of the WAB.
|
||||
* It is expected that each WAB lists the symbolic-names of the bundles that contain
|
||||
* tld files. The list is defined as the value of the header 'Require-TldBundle'
|
||||
* In the case of a WAB, tlds can be located in OSGi bundles that are
|
||||
* dependencies of the WAB. It is expected that each WAB lists the
|
||||
* symbolic-names of the bundles that contain tld files. The list is defined as
|
||||
* the value of the header 'Require-TldBundle'
|
||||
* </p>
|
||||
* <p>
|
||||
* Discussions about this are logged in https://bugs.eclipse.org/bugs/show_bug.cgi?id=306971
|
||||
* Discussions about this are logged in
|
||||
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=306971
|
||||
* </p>
|
||||
*/
|
||||
public class TagLibOSGiConfiguration extends TagLibConfiguration
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(TagLibOSGiConfiguration.class);
|
||||
|
||||
private ServiceTracker packageAdminServiceTracker = null;
|
||||
|
||||
/**
|
||||
* Override the preConfigure; locates the bundles that contain
|
||||
* tld files according to the value of the manifest header Require-TldBundle.
|
||||
* <p>
|
||||
* Set or add to the property TldProcessor.TLDResources the list of located jars
|
||||
* so that the super class will scan those.
|
||||
* </p>
|
||||
*/
|
||||
private ServiceTracker packageAdminServiceTracker = null;
|
||||
|
||||
/**
|
||||
* Override the preConfigure; locates the bundles that contain tld files
|
||||
* according to the value of the manifest header Require-TldBundle.
|
||||
* <p>
|
||||
* Set or add to the property TldProcessor.TLDResources the list of located
|
||||
* jars so that the super class will scan those.
|
||||
* </p>
|
||||
*/
|
||||
public void preConfigure(WebAppContext context) throws Exception
|
||||
{
|
||||
String requireTldBundle = (String)context.getAttribute(OSGiWebappConstants.REQUIRE_TLD_BUNDLE);
|
||||
if (requireTldBundle != null)
|
||||
{
|
||||
Collection<Resource> resources = getRequireTldBundleAsJettyResources(context, requireTldBundle);
|
||||
if (resources != null && !resources.isEmpty())
|
||||
{
|
||||
Collection<Resource> previouslySet = (Collection<Resource>)
|
||||
context.getAttribute(TagLibConfiguration.TLD_RESOURCES);
|
||||
if (previouslySet != null)
|
||||
{
|
||||
resources.addAll(previouslySet);
|
||||
}
|
||||
context.setAttribute(TagLibConfiguration.TLD_RESOURCES, resources);
|
||||
}
|
||||
}
|
||||
super.preConfigure(context);
|
||||
String requireTldBundle = (String) context.getAttribute(OSGiWebappConstants.REQUIRE_TLD_BUNDLE);
|
||||
if (requireTldBundle != null)
|
||||
{
|
||||
Collection<Resource> resources = getRequireTldBundleAsJettyResources(context, requireTldBundle);
|
||||
if (resources != null && !resources.isEmpty())
|
||||
{
|
||||
Collection<Resource> previouslySet = (Collection<Resource>) context.getAttribute(TagLibConfiguration.TLD_RESOURCES);
|
||||
if (previouslySet != null)
|
||||
{
|
||||
resources.addAll(previouslySet);
|
||||
}
|
||||
context.setAttribute(TagLibConfiguration.TLD_RESOURCES, resources);
|
||||
}
|
||||
}
|
||||
super.preConfigure(context);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param requireTldBundle The comma separated list of bundles' symbolic names
|
||||
* that contain tld for this osgi webapp.
|
||||
* @param requireTldBundle The comma separated list of bundles' symbolic
|
||||
* names that contain tld for this osgi webapp.
|
||||
* @return The collection of jars or folders that match those bundles.
|
||||
*/
|
||||
private Collection<Resource> getRequireTldBundleAsJettyResources(
|
||||
WebAppContext context, String requireTldBundle)
|
||||
private Collection<Resource> getRequireTldBundleAsJettyResources(WebAppContext context, String requireTldBundle)
|
||||
{
|
||||
Bundle bundle = (Bundle)
|
||||
context.getAttribute(OSGiWebappConstants.JETTY_OSGI_BUNDLE);
|
||||
PackageAdmin packAdmin = getBundleAdmin();
|
||||
String[] symbNames = requireTldBundle.split(", ");
|
||||
Collection<Resource> tlds = new LinkedHashSet<Resource>();
|
||||
for (String symbName : symbNames)
|
||||
{
|
||||
Bundle[] bs = packAdmin.getBundles(symbName, null);
|
||||
if (bs == null || bs.length == 0)
|
||||
{
|
||||
throw new IllegalArgumentException("Unable to locate the bundle '"
|
||||
+ symbName + "' specified in the "
|
||||
+ OSGiWebappConstants.REQUIRE_TLD_BUNDLE
|
||||
+ " of the manifest of "
|
||||
+ bundle.getSymbolicName());
|
||||
}
|
||||
//take the first one as it is the most recent version?
|
||||
Enumeration<URL> en = bs[0].findEntries("META-INF", "*.tld", false);
|
||||
boolean atLeastOneTldFound = false;
|
||||
while (en.hasMoreElements())
|
||||
{
|
||||
atLeastOneTldFound = true;
|
||||
URL oriUrl = en.nextElement();
|
||||
URL url = DefaultFileLocatorHelper.getLocalURL(oriUrl);
|
||||
Resource tldResource;
|
||||
try
|
||||
{
|
||||
tldResource = Resource.newResource(url);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new IllegalArgumentException("Unable to locate the "
|
||||
+ "tld resource in '"
|
||||
+ url.toString()
|
||||
+ "' in the bundle '" + bs[0].getSymbolicName()
|
||||
+ "' while registering the "
|
||||
+ OSGiWebappConstants.REQUIRE_TLD_BUNDLE
|
||||
+ " of the manifest of "
|
||||
+ bundle.getSymbolicName(), e);
|
||||
}
|
||||
tlds.add(tldResource);
|
||||
}
|
||||
if (!atLeastOneTldFound)
|
||||
{
|
||||
LOG.warn("No '/META-INF/*.tld' resources were found "
|
||||
+ " in the bundle '" + bs[0].getSymbolicName()
|
||||
+ "' while registering the "
|
||||
+ OSGiWebappConstants.REQUIRE_TLD_BUNDLE
|
||||
+ " of the manifest of "
|
||||
+ bundle.getSymbolicName());
|
||||
}
|
||||
}
|
||||
return tlds;
|
||||
Bundle bundle = (Bundle) context.getAttribute(OSGiWebappConstants.JETTY_OSGI_BUNDLE);
|
||||
PackageAdmin packAdmin = getBundleAdmin();
|
||||
String[] symbNames = requireTldBundle.split(", ");
|
||||
Collection<Resource> tlds = new LinkedHashSet<Resource>();
|
||||
for (String symbName : symbNames)
|
||||
{
|
||||
Bundle[] bs = packAdmin.getBundles(symbName, null);
|
||||
if (bs == null || bs.length == 0)
|
||||
{
|
||||
throw new IllegalArgumentException("Unable to locate the bundle '" + symbName
|
||||
+ "' specified in the "
|
||||
+ OSGiWebappConstants.REQUIRE_TLD_BUNDLE
|
||||
+ " of the manifest of "
|
||||
+ bundle.getSymbolicName());
|
||||
}
|
||||
// take the first one as it is the most recent version?
|
||||
Enumeration<URL> en = bs[0].findEntries("META-INF", "*.tld", false);
|
||||
boolean atLeastOneTldFound = false;
|
||||
while (en.hasMoreElements())
|
||||
{
|
||||
atLeastOneTldFound = true;
|
||||
URL oriUrl = en.nextElement();
|
||||
URL url = DefaultFileLocatorHelper.getLocalURL(oriUrl);
|
||||
Resource tldResource;
|
||||
try
|
||||
{
|
||||
tldResource = Resource.newResource(url);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new IllegalArgumentException("Unable to locate the " + "tld resource in '"
|
||||
+ url.toString()
|
||||
+ "' in the bundle '"
|
||||
+ bs[0].getSymbolicName()
|
||||
+ "' while registering the "
|
||||
+ OSGiWebappConstants.REQUIRE_TLD_BUNDLE
|
||||
+ " of the manifest of "
|
||||
+ bundle.getSymbolicName(), e);
|
||||
}
|
||||
tlds.add(tldResource);
|
||||
}
|
||||
if (!atLeastOneTldFound)
|
||||
{
|
||||
LOG.warn("No '/META-INF/*.tld' resources were found " + " in the bundle '"
|
||||
+ bs[0].getSymbolicName()
|
||||
+ "' while registering the "
|
||||
+ OSGiWebappConstants.REQUIRE_TLD_BUNDLE
|
||||
+ " of the manifest of "
|
||||
+ bundle.getSymbolicName());
|
||||
}
|
||||
}
|
||||
return tlds;
|
||||
}
|
||||
|
||||
private PackageAdmin getBundleAdmin()
|
||||
{
|
||||
if (packageAdminServiceTracker == null)
|
||||
{
|
||||
Bundle bootBundle = ((BundleReference)OSGiWebappConstants.class.getClassLoader()).getBundle();
|
||||
packageAdminServiceTracker = new ServiceTracker(bootBundle.getBundleContext(),
|
||||
PackageAdmin.class.getName(), null);
|
||||
packageAdminServiceTracker.open();
|
||||
}
|
||||
return (PackageAdmin) packageAdminServiceTracker.getService();
|
||||
}
|
||||
|
||||
|
||||
private PackageAdmin getBundleAdmin()
|
||||
{
|
||||
if (packageAdminServiceTracker == null)
|
||||
{
|
||||
Bundle bootBundle = ((BundleReference) OSGiWebappConstants.class.getClassLoader()).getBundle();
|
||||
packageAdminServiceTracker = new ServiceTracker(bootBundle.getBundleContext(), PackageAdmin.class.getName(), null);
|
||||
packageAdminServiceTracker.open();
|
||||
}
|
||||
return (PackageAdmin) packageAdminServiceTracker.getService();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -24,12 +24,13 @@ import java.util.jar.Manifest;
|
|||
import org.eclipse.jetty.osgi.boot.warurl.internal.WarBundleManifestGenerator;
|
||||
import org.eclipse.jetty.osgi.boot.warurl.internal.WarURLConnection;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.osgi.service.url.AbstractURLStreamHandlerService;
|
||||
|
||||
/**
|
||||
* RFC-66: support for the "war" protocol
|
||||
* We are reusing the parsing of the query string from jetty.
|
||||
* If we wanted to not depend on jetty at all we could duplicate that method here
|
||||
* RFC-66: support for the "war" protocol We are reusing the parsing of the
|
||||
* query string from jetty. If we wanted to not depend on jetty at all we could
|
||||
* duplicate that method here
|
||||
*/
|
||||
public class WarUrlStreamHandler extends AbstractURLStreamHandlerService
|
||||
{
|
||||
|
@ -40,11 +41,11 @@ public class WarUrlStreamHandler extends AbstractURLStreamHandlerService
|
|||
@Override
|
||||
public URLConnection openConnection(URL url) throws IOException
|
||||
{
|
||||
//remove the war scheme.
|
||||
// remove the war scheme.
|
||||
URL actual = new URL(url.toString().substring("war:".length()));
|
||||
|
||||
//let's do some basic tests: see if this is a folder or not.
|
||||
//if it is a folder. we will try to support it.
|
||||
|
||||
// let's do some basic tests: see if this is a folder or not.
|
||||
// if it is a folder. we will try to support it.
|
||||
if (actual.getProtocol().equals("file"))
|
||||
{
|
||||
File file = new File(URIUtil.encodePath(actual.getPath()));
|
||||
|
@ -52,34 +53,48 @@ public class WarUrlStreamHandler extends AbstractURLStreamHandlerService
|
|||
{
|
||||
if (file.isDirectory())
|
||||
{
|
||||
//TODO (not mandatory for rfc66 though)
|
||||
// TODO (not mandatory for rfc66 though)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if (actual.toString().startsWith("file:/") && ! actual.to)
|
||||
|
||||
// if (actual.toString().startsWith("file:/") && ! actual.to)
|
||||
URLConnection ori = (URLConnection) actual.openConnection();
|
||||
ori.setDefaultUseCaches(Resource.getDefaultUseCaches());
|
||||
JarURLConnection jarOri = null;
|
||||
try {
|
||||
try
|
||||
{
|
||||
if (ori instanceof JarURLConnection)
|
||||
{
|
||||
jarOri = (JarURLConnection)ori;
|
||||
jarOri = (JarURLConnection) ori;
|
||||
}
|
||||
else
|
||||
{
|
||||
jarOri = (JarURLConnection) new URL("jar:"+actual.toString() + "!/").openConnection();
|
||||
jarOri = (JarURLConnection) new URL("jar:" + actual.toString() + "!/").openConnection();
|
||||
jarOri.setDefaultUseCaches(Resource.getDefaultUseCaches());
|
||||
}
|
||||
Manifest mf = WarBundleManifestGenerator.createBundleManifest(
|
||||
jarOri.getManifest(), url, jarOri.getJarFile());
|
||||
try { jarOri.getJarFile().close(); jarOri = null; } catch (Throwable t) {}
|
||||
return new WarURLConnection(actual,mf);
|
||||
Manifest mf = WarBundleManifestGenerator.createBundleManifest(jarOri.getManifest(), url, jarOri.getJarFile());
|
||||
try
|
||||
{
|
||||
jarOri.getJarFile().close();
|
||||
jarOri = null;
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
}
|
||||
return new WarURLConnection(actual, mf);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (jarOri != null) try { jarOri.getJarFile().close(); } catch (Throwable t) {}
|
||||
if (jarOri != null) try
|
||||
{
|
||||
jarOri.getJarFile().close();
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ import java.util.jar.Manifest;
|
|||
import java.util.zip.ZipEntry;
|
||||
|
||||
import org.eclipse.jetty.util.IO;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
|
||||
/**
|
||||
* Facade for a URLConnection that will read a jar and substitute its
|
||||
|
@ -106,6 +107,7 @@ public class WarURLConnection extends URLConnection
|
|||
{
|
||||
super(url);
|
||||
_conn = url.openConnection();
|
||||
_conn.setDefaultUseCaches(Resource.getDefaultUseCaches());
|
||||
_mf = mf;
|
||||
}
|
||||
@Override
|
||||
|
|
|
@ -66,15 +66,19 @@ public class JettyBootstrapActivator implements BundleActivator
|
|||
}
|
||||
|
||||
private ServiceRegistration _registeredServer;
|
||||
|
||||
private Server _server;
|
||||
|
||||
private JettyContextHandlerServiceTracker _jettyContextHandlerTracker;
|
||||
|
||||
private PackageAdminServiceTracker _packageAdminServiceTracker;
|
||||
|
||||
private BundleTracker _webBundleTracker;
|
||||
|
||||
private BundleContext _bundleContext;
|
||||
|
||||
// private ServiceRegistration _jettyServerFactoryService;
|
||||
|
||||
// private ServiceRegistration _jettyServerFactoryService;
|
||||
private JettyServerServiceTracker _jettyServerServiceTracker;
|
||||
|
||||
|
||||
/**
|
||||
* Setup a new jetty Server, registers it as a service. Setup the Service
|
||||
|
@ -93,30 +97,31 @@ public class JettyBootstrapActivator implements BundleActivator
|
|||
// should activate.
|
||||
_packageAdminServiceTracker = new PackageAdminServiceTracker(context);
|
||||
|
||||
_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:
|
||||
// Properties jettyServerMgdFactoryServiceProps = new Properties();
|
||||
// jettyServerMgdFactoryServiceProps.put("pid",
|
||||
// OSGiWebappConstants.MANAGED_JETTY_SERVER_FACTORY_PID);
|
||||
// _jettyServerFactoryService = context.registerService(
|
||||
// ManagedServiceFactory.class.getName(), new
|
||||
// JettyServersManagedFactory(),
|
||||
// jettyServerMgdFactoryServiceProps);
|
||||
|
||||
//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);
|
||||
|
||||
// the tracker in charge of the actual deployment
|
||||
// and that will configure and start the jetty server.
|
||||
context.addServiceListener(_jettyContextHandlerTracker,"(objectclass=" + ContextHandler.class.getName() + ")");
|
||||
context.addServiceListener(_jettyContextHandlerTracker, "(objectclass=" + ContextHandler.class.getName() + ")");
|
||||
|
||||
//see if we shoult start a default jetty instance right now.
|
||||
// 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,
|
||||
Bundle.ACTIVE | Bundle.STOPPING, new WebBundleTrackerCustomizer());
|
||||
|
||||
// now ready to support the Extender pattern:
|
||||
_webBundleTracker = new BundleTracker(context, Bundle.ACTIVE | Bundle.STOPPING, new WebBundleTrackerCustomizer());
|
||||
_webBundleTracker.open();
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -129,12 +134,12 @@ public class JettyBootstrapActivator implements BundleActivator
|
|||
{
|
||||
try
|
||||
{
|
||||
|
||||
if (_webBundleTracker != null)
|
||||
{
|
||||
_webBundleTracker.close();
|
||||
_webBundleTracker = null;
|
||||
}
|
||||
|
||||
if (_webBundleTracker != null)
|
||||
{
|
||||
_webBundleTracker.close();
|
||||
_webBundleTracker = null;
|
||||
}
|
||||
if (_jettyContextHandlerTracker != null)
|
||||
{
|
||||
_jettyContextHandlerTracker.stop();
|
||||
|
@ -143,7 +148,7 @@ public class JettyBootstrapActivator implements BundleActivator
|
|||
}
|
||||
if (_jettyServerServiceTracker != null)
|
||||
{
|
||||
_jettyServerServiceTracker.stop();
|
||||
_jettyServerServiceTracker.stop();
|
||||
context.removeServiceListener(_jettyServerServiceTracker);
|
||||
_jettyServerServiceTracker = null;
|
||||
}
|
||||
|
@ -165,31 +170,31 @@ public class JettyBootstrapActivator implements BundleActivator
|
|||
}
|
||||
finally
|
||||
{
|
||||
_registeredServer = null;
|
||||
_registeredServer = null;
|
||||
}
|
||||
}
|
||||
// if (_jettyServerFactoryService != null)
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// _jettyServerFactoryService.unregister();
|
||||
// }
|
||||
// catch (IllegalArgumentException ill)
|
||||
// {
|
||||
// // already unregistered.
|
||||
// }
|
||||
// finally
|
||||
// {
|
||||
// _jettyServerFactoryService = null;
|
||||
// }
|
||||
// }
|
||||
// if (_jettyServerFactoryService != null)
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// _jettyServerFactoryService.unregister();
|
||||
// }
|
||||
// catch (IllegalArgumentException ill)
|
||||
// {
|
||||
// // already unregistered.
|
||||
// }
|
||||
// finally
|
||||
// {
|
||||
// _jettyServerFactoryService = null;
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (_server != null)
|
||||
{
|
||||
_server.stop();
|
||||
_server.stop();
|
||||
}
|
||||
INSTANCE = null;
|
||||
}
|
||||
|
@ -200,27 +205,25 @@ public class JettyBootstrapActivator implements BundleActivator
|
|||
* registers it as an OSGi service. The tracker
|
||||
* {@link JettyContextHandlerServiceTracker} will do the actual deployment.
|
||||
*
|
||||
* @param contributor
|
||||
* 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 contributor 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 "/"
|
||||
* @throws Exception
|
||||
*/
|
||||
public static void registerWebapplication(Bundle contributor, String webappFolderPath, String contextPath) throws Exception
|
||||
{
|
||||
checkBundleActivated();
|
||||
WebAppContext contextHandler = new WebAppContext();
|
||||
checkBundleActivated();
|
||||
WebAppContext contextHandler = new WebAppContext();
|
||||
Dictionary dic = new Hashtable();
|
||||
dic.put(OSGiWebappConstants.SERVICE_PROP_WAR,webappFolderPath);
|
||||
dic.put(OSGiWebappConstants.SERVICE_PROP_CONTEXT_PATH,contextPath);
|
||||
String requireTldBundle = (String)contributor.getHeaders().get(OSGiWebappConstants.REQUIRE_TLD_BUNDLE);
|
||||
if (requireTldBundle != null) {
|
||||
dic.put(OSGiWebappConstants.SERVICE_PROP_REQUIRE_TLD_BUNDLE, requireTldBundle);
|
||||
dic.put(OSGiWebappConstants.SERVICE_PROP_WAR, webappFolderPath);
|
||||
dic.put(OSGiWebappConstants.SERVICE_PROP_CONTEXT_PATH, contextPath);
|
||||
String requireTldBundle = (String) contributor.getHeaders().get(OSGiWebappConstants.REQUIRE_TLD_BUNDLE);
|
||||
if (requireTldBundle != null)
|
||||
{
|
||||
dic.put(OSGiWebappConstants.SERVICE_PROP_REQUIRE_TLD_BUNDLE, requireTldBundle);
|
||||
}
|
||||
contributor.getBundleContext().registerService(ContextHandler.class.getName(),contextHandler,dic);
|
||||
contributor.getBundleContext().registerService(ContextHandler.class.getName(), contextHandler, dic);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -228,24 +231,20 @@ public class JettyBootstrapActivator implements BundleActivator
|
|||
* registers it as an OSGi service. The tracker
|
||||
* {@link JettyContextHandlerServiceTracker} will do the actual deployment.
|
||||
*
|
||||
* @param contributor
|
||||
* 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 dic
|
||||
* TODO: parameter description
|
||||
* @param contributor 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 dic TODO: parameter description
|
||||
* @throws Exception
|
||||
*/
|
||||
public static void registerWebapplication(Bundle contributor, String webappFolderPath, String contextPath, Dictionary<String, String> dic) throws Exception
|
||||
{
|
||||
checkBundleActivated();
|
||||
checkBundleActivated();
|
||||
WebAppContext contextHandler = new WebAppContext();
|
||||
dic.put(OSGiWebappConstants.SERVICE_PROP_WAR,webappFolderPath);
|
||||
dic.put(OSGiWebappConstants.SERVICE_PROP_CONTEXT_PATH,contextPath);
|
||||
contributor.getBundleContext().registerService(ContextHandler.class.getName(),contextHandler,dic);
|
||||
dic.put(OSGiWebappConstants.SERVICE_PROP_WAR, webappFolderPath);
|
||||
dic.put(OSGiWebappConstants.SERVICE_PROP_CONTEXT_PATH, contextPath);
|
||||
contributor.getBundleContext().registerService(ContextHandler.class.getName(), contextHandler, dic);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -253,16 +252,14 @@ public class JettyBootstrapActivator implements BundleActivator
|
|||
* registers it as an OSGi service. The tracker
|
||||
* {@link JettyContextHandlerServiceTracker} will do the actual deployment.
|
||||
*
|
||||
* @param contributor
|
||||
* The bundle that registers a new context
|
||||
* @param contextFilePath
|
||||
* The path to the file inside the bundle that defines the
|
||||
* context.
|
||||
* @param contributor The bundle that registers a new context
|
||||
* @param contextFilePath The path to the file inside the bundle that
|
||||
* defines the context.
|
||||
* @throws Exception
|
||||
*/
|
||||
public static void registerContext(Bundle contributor, String contextFilePath) throws Exception
|
||||
{
|
||||
registerContext(contributor,contextFilePath,new Hashtable<String, String>());
|
||||
registerContext(contributor, contextFilePath, new Hashtable<String, String>());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -270,33 +267,30 @@ public class JettyBootstrapActivator implements BundleActivator
|
|||
* registers it as an OSGi service. The tracker
|
||||
* {@link JettyContextHandlerServiceTracker} will do the actual deployment.
|
||||
*
|
||||
* @param contributor
|
||||
* The bundle that registers a new context
|
||||
* @param contextFilePath
|
||||
* The path to the file inside the bundle that defines the
|
||||
* context.
|
||||
* @param dic
|
||||
* TODO: parameter description
|
||||
* @param contributor The bundle that registers a new context
|
||||
* @param contextFilePath The path to the file inside the bundle that
|
||||
* defines the context.
|
||||
* @param dic TODO: parameter description
|
||||
* @throws Exception
|
||||
*/
|
||||
public static void registerContext(Bundle contributor, String contextFilePath, Dictionary<String, String> dic) throws Exception
|
||||
{
|
||||
checkBundleActivated();
|
||||
checkBundleActivated();
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
public static void unregister(String contextPath)
|
||||
{
|
||||
// todo
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Since org.eclipse.jetty.osgi.boot does not have a lazy activation policy
|
||||
* when one fo the static methods to register a webapp is called we should make sure that
|
||||
* the bundle is started.
|
||||
* when one fo the static methods to register a webapp is called we should
|
||||
* make sure that the bundle is started.
|
||||
*/
|
||||
private static void checkBundleActivated()
|
||||
{
|
||||
|
@ -313,7 +307,7 @@ public class JettyBootstrapActivator implements BundleActivator
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return The bundle context for this bundle.
|
||||
*/
|
||||
|
@ -322,6 +316,5 @@ public class JettyBootstrapActivator implements BundleActivator
|
|||
checkBundleActivated();
|
||||
return INSTANCE._bundleContext;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -53,14 +53,15 @@ import org.osgi.framework.ServiceReference;
|
|||
public class JettyContextHandlerServiceTracker implements ServiceListener
|
||||
{
|
||||
|
||||
/** New style: ability to manage multiple jetty instances */
|
||||
private final IManagedJettyServerRegistry _registry;
|
||||
/** New style: ability to manage multiple jetty instances */
|
||||
private final IManagedJettyServerRegistry _registry;
|
||||
|
||||
/** The context-handler to deactivate indexed by context handler */
|
||||
private Map<ServiceReference, ContextHandler> _indexByServiceReference = new HashMap<ServiceReference, ContextHandler>();
|
||||
|
||||
/**
|
||||
* The index is the bundle-symbolic-name/path/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<String, ServiceReference> _indexByContextFile = new HashMap<String, ServiceReference>();
|
||||
|
||||
|
@ -72,7 +73,7 @@ public class JettyContextHandlerServiceTracker implements ServiceListener
|
|||
*/
|
||||
public JettyContextHandlerServiceTracker(IManagedJettyServerRegistry registry) throws Exception
|
||||
{
|
||||
_registry = registry;
|
||||
_registry = registry;
|
||||
}
|
||||
|
||||
public void stop() throws Exception
|
||||
|
@ -85,19 +86,16 @@ public class JettyContextHandlerServiceTracker implements ServiceListener
|
|||
// nothing to stop in the WebappRegistrationHelper
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param contextHome Parent folder where the context files can override the context files
|
||||
* defined in the web bundles: equivalent to the contexts folder in a traditional
|
||||
* jetty installation.
|
||||
* when null, just do nothing.
|
||||
* @param contextHome Parent folder where the context files can override the
|
||||
* context files defined in the web bundles: equivalent to the
|
||||
* contexts folder in a traditional jetty installation. when
|
||||
* null, just do nothing.
|
||||
*/
|
||||
protected void setupContextHomeScanner(File contextHome) throws IOException
|
||||
{
|
||||
if (contextHome == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (contextHome == null) { return; }
|
||||
final String osgiContextHomeFolderCanonicalPath = contextHome.getCanonicalPath();
|
||||
_scanner = new Scanner();
|
||||
_scanner.setRecursive(true);
|
||||
|
@ -132,8 +130,7 @@ public class JettyContextHandlerServiceTracker implements ServiceListener
|
|||
/**
|
||||
* Receives notification that a service has had a lifecycle change.
|
||||
*
|
||||
* @param ev
|
||||
* The <code>ServiceEvent</code> object.
|
||||
* @param ev The <code>ServiceEvent</code> object.
|
||||
*/
|
||||
public void serviceChanged(ServiceEvent ev)
|
||||
{
|
||||
|
@ -148,7 +145,7 @@ public class JettyContextHandlerServiceTracker implements ServiceListener
|
|||
{
|
||||
try
|
||||
{
|
||||
getWebBundleDeployerHelp(sr).unregister(ctxtHandler);
|
||||
getWebBundleDeployerHelp(sr).unregister(ctxtHandler);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -170,30 +167,32 @@ public class JettyContextHandlerServiceTracker implements ServiceListener
|
|||
{
|
||||
Bundle contributor = sr.getBundle();
|
||||
BundleContext context = FrameworkUtil.getBundle(JettyBootstrapActivator.class).getBundleContext();
|
||||
ContextHandler contextHandler = (ContextHandler)context.getService(sr);
|
||||
ContextHandler contextHandler = (ContextHandler) context.getService(sr);
|
||||
if (contextHandler.getServer() != null)
|
||||
{
|
||||
// is configured elsewhere.
|
||||
return;
|
||||
}
|
||||
String contextFilePath = (String)sr.getProperty(OSGiWebappConstants.SERVICE_PROP_CONTEXT_FILE_PATH);
|
||||
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.
|
||||
// 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);
|
||||
WebAppContext webapp = (WebAppContext) contextHandler;
|
||||
String contextPath = (String) sr.getProperty(OSGiWebappConstants.SERVICE_PROP_CONTEXT_PATH);
|
||||
if (contextPath == null)
|
||||
{
|
||||
contextPath = webapp.getContextPath();
|
||||
}
|
||||
String webXmlPath = (String)sr.getProperty(OSGiWebappConstants.SERVICE_PROP_WEB_XML_PATH);
|
||||
String webXmlPath = (String) sr.getProperty(OSGiWebappConstants.SERVICE_PROP_WEB_XML_PATH);
|
||||
if (webXmlPath == null)
|
||||
{
|
||||
webXmlPath = webapp.getDescriptor();
|
||||
}
|
||||
String defaultWebXmlPath = (String)sr.getProperty(OSGiWebappConstants.SERVICE_PROP_DEFAULT_WEB_XML_PATH);
|
||||
String defaultWebXmlPath = (String) sr.getProperty(OSGiWebappConstants.SERVICE_PROP_DEFAULT_WEB_XML_PATH);
|
||||
if (defaultWebXmlPath == null)
|
||||
{
|
||||
String jettyHome = System.getProperty(DefaultJettyAtJettyHomeHelper.SYS_PROP_JETTY_HOME);
|
||||
|
@ -202,7 +201,7 @@ public class JettyContextHandlerServiceTracker implements ServiceListener
|
|||
File etc = new File(jettyHome, "etc");
|
||||
if (etc.exists() && etc.isDirectory())
|
||||
{
|
||||
File webDefault = new File (etc, "webdefault.xml");
|
||||
File webDefault = new File(etc, "webdefault.xml");
|
||||
if (webDefault.exists())
|
||||
defaultWebXmlPath = webDefault.getAbsolutePath();
|
||||
else
|
||||
|
@ -212,27 +211,28 @@ public class JettyContextHandlerServiceTracker implements ServiceListener
|
|||
defaultWebXmlPath = webapp.getDefaultsDescriptor();
|
||||
}
|
||||
}
|
||||
String war = (String)sr.getProperty("war");
|
||||
String war = (String) sr.getProperty("war");
|
||||
try
|
||||
{
|
||||
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),
|
||||
(String)sr.getProperty(OSGiWebappConstants.SERVICE_PROP_REQUIRE_TLD_BUNDLE),
|
||||
webXmlPath,defaultWebXmlPath,webapp);
|
||||
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),
|
||||
(String) sr.getProperty(OSGiWebappConstants.SERVICE_PROP_REQUIRE_TLD_BUNDLE),
|
||||
webXmlPath, defaultWebXmlPath, webapp);
|
||||
if (handler != null)
|
||||
{
|
||||
registerInIndex(handler,sr);
|
||||
registerInIndex(handler, sr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
|
@ -242,34 +242,31 @@ public class JettyContextHandlerServiceTracker implements ServiceListener
|
|||
else
|
||||
{
|
||||
// consider this just an empty skeleton:
|
||||
if (contextFilePath == null)
|
||||
{
|
||||
throw new IllegalArgumentException("the property contextFilePath is required");
|
||||
}
|
||||
if (contextFilePath == null) { throw new IllegalArgumentException("the property contextFilePath is required"); }
|
||||
try
|
||||
{
|
||||
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),
|
||||
(String)sr.getProperty(OSGiWebappConstants.SERVICE_PROP_REQUIRE_TLD_BUNDLE),
|
||||
contextHandler);
|
||||
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),
|
||||
(String) sr.getProperty(OSGiWebappConstants.SERVICE_PROP_REQUIRE_TLD_BUNDLE),
|
||||
contextHandler);
|
||||
if (handler != null)
|
||||
{
|
||||
registerInIndex(handler, sr);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
|
@ -278,17 +275,17 @@ public class JettyContextHandlerServiceTracker implements ServiceListener
|
|||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void registerInIndex(ContextHandler handler, ServiceReference sr)
|
||||
{
|
||||
_indexByServiceReference.put(sr,handler);
|
||||
_indexByServiceReference.put(sr, handler);
|
||||
String key = getSymbolicNameAndContextFileKey(sr);
|
||||
if (key != null)
|
||||
{
|
||||
_indexByContextFile.put(key,sr);
|
||||
_indexByContextFile.put(key, sr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -320,11 +317,8 @@ public class JettyContextHandlerServiceTracker implements ServiceListener
|
|||
*/
|
||||
private String getSymbolicNameAndContextFileKey(ServiceReference sr)
|
||||
{
|
||||
String contextFilePath = (String)sr.getProperty(OSGiWebappConstants.SERVICE_PROP_CONTEXT_FILE_PATH);
|
||||
if (contextFilePath != null)
|
||||
{
|
||||
return sr.getBundle().getSymbolicName() + "/" + contextFilePath;
|
||||
}
|
||||
String contextFilePath = (String) sr.getProperty(OSGiWebappConstants.SERVICE_PROP_CONTEXT_FILE_PATH);
|
||||
if (contextFilePath != null) { return sr.getBundle().getSymbolicName() + "/" + contextFilePath; }
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -336,17 +330,14 @@ public class JettyContextHandlerServiceTracker implements ServiceListener
|
|||
public void reloadJettyContextHandler(String canonicalNameOfFileChanged, String osgiContextHomeFolderCanonicalPath)
|
||||
{
|
||||
String key = getNormalizedRelativePath(canonicalNameOfFileChanged, osgiContextHomeFolderCanonicalPath);
|
||||
if (key == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (key == null) { return; }
|
||||
ServiceReference sr = _indexByContextFile.get(key);
|
||||
if (sr == null)
|
||||
{
|
||||
// nothing to do?
|
||||
return;
|
||||
}
|
||||
serviceChanged(new ServiceEvent(ServiceEvent.MODIFIED,sr));
|
||||
serviceChanged(new ServiceEvent(ServiceEvent.MODIFIED, sr));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -362,36 +353,31 @@ public class JettyContextHandlerServiceTracker implements ServiceListener
|
|||
// warning?
|
||||
return null;
|
||||
}
|
||||
return canFilename.substring(osgiContextHomeFolderCanonicalPath.length()).replace('\\','/');
|
||||
return canFilename.substring(osgiContextHomeFolderCanonicalPath.length()).replace('\\', '/');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return The server on which this webapp is meant to be deployed
|
||||
*/
|
||||
private ServerInstanceWrapper getServerInstanceWrapper(String managedServerName)
|
||||
{
|
||||
if (_registry == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (managedServerName == null)
|
||||
{
|
||||
managedServerName = OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME;
|
||||
}
|
||||
ServerInstanceWrapper wrapper = _registry.getServerInstanceWrapper(managedServerName);
|
||||
//System.err.println("Returning " + managedServerName + " = " + wrapper);
|
||||
return wrapper;
|
||||
if (_registry == null) { return null; }
|
||||
if (managedServerName == null)
|
||||
{
|
||||
managedServerName = OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME;
|
||||
}
|
||||
ServerInstanceWrapper wrapper = _registry.getServerInstanceWrapper(managedServerName);
|
||||
// System.err.println("Returning " + managedServerName + " = " +
|
||||
// wrapper);
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
|
||||
private IWebBundleDeployerHelper getWebBundleDeployerHelp(ServiceReference sr)
|
||||
{
|
||||
if (_registry == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
String managedServerName = (String)sr.getProperty(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME);
|
||||
ServerInstanceWrapper wrapper = getServerInstanceWrapper(managedServerName);
|
||||
return wrapper != null ? wrapper.getWebBundleDeployerHelp() : null;
|
||||
if (_registry == null) { return null; }
|
||||
String managedServerName = (String) sr.getProperty(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME);
|
||||
ServerInstanceWrapper wrapper = getServerInstanceWrapper(managedServerName);
|
||||
return wrapper != null ? wrapper.getWebBundleDeployerHelp() : null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -247,7 +247,7 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe
|
|||
catch (IOException e)
|
||||
{
|
||||
// nevermind. just trying our best
|
||||
e.printStackTrace();
|
||||
__logger.ignore(e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -279,7 +279,7 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe
|
|||
catch (Throwable t)
|
||||
{
|
||||
// humf that will hurt if it does not work.
|
||||
t.printStackTrace();
|
||||
__logger.warn("Unable to set webappcontext", t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,13 +78,14 @@ 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
|
||||
* implementation should set a different implementation.
|
||||
*/
|
||||
public 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
|
||||
|
@ -97,8 +98,9 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
* equinox and apache-felix fragment bundles that are specific to an OSGi
|
||||
* implementation should set a different implementation.
|
||||
* <p>
|
||||
* 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.
|
||||
* 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.
|
||||
* </p>
|
||||
*/
|
||||
public static Collection<WebappRegistrationCustomizer> JSP_REGISTRATION_HELPERS = new ArrayList<WebappRegistrationCustomizer>();
|
||||
|
@ -127,7 +129,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
// setup the custom BundleClassLoaderHelper
|
||||
try
|
||||
{
|
||||
BUNDLE_CLASS_LOADER_HELPER = (BundleClassLoaderHelper)Class.forName(BundleClassLoaderHelper.CLASS_NAME).newInstance();
|
||||
BUNDLE_CLASS_LOADER_HELPER = (BundleClassLoaderHelper) Class.forName(BundleClassLoaderHelper.CLASS_NAME).newInstance();
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
|
@ -137,7 +139,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
// setup the custom FileLocatorHelper
|
||||
try
|
||||
{
|
||||
BUNDLE_FILE_LOCATOR_HELPER = (BundleFileLocatorHelper)Class.forName(BundleFileLocatorHelper.CLASS_NAME).newInstance();
|
||||
BUNDLE_FILE_LOCATOR_HELPER = (BundleFileLocatorHelper) Class.forName(BundleFileLocatorHelper.CLASS_NAME).newInstance();
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
|
@ -150,34 +152,28 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
/**
|
||||
* 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 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 requireTldBundle The list of bundles's symbolic names that contain
|
||||
* tld files that are required by this WAB.
|
||||
* tld files that are required by this WAB.
|
||||
* @param webXmlPath
|
||||
* @param defaultWebXmlPath
|
||||
* TODO: parameter description
|
||||
* @param defaultWebXmlPath TODO: parameter description
|
||||
* @return The contexthandler created and started
|
||||
* @throws Exception
|
||||
*/
|
||||
public WebAppContext registerWebapplication(Bundle bundle,
|
||||
String webappFolderPath, String contextPath, String extraClasspath,
|
||||
String overrideBundleInstallLocation,
|
||||
String requireTldBundle, String webXmlPath,
|
||||
String defaultWebXmlPath, WebAppContext webAppContext) throws Exception
|
||||
public WebAppContext registerWebapplication(Bundle bundle, String webappFolderPath, String contextPath, String extraClasspath,
|
||||
String overrideBundleInstallLocation, String requireTldBundle, String webXmlPath, String defaultWebXmlPath,
|
||||
WebAppContext webAppContext) throws Exception
|
||||
{
|
||||
File bundleInstall = overrideBundleInstallLocation == null?BUNDLE_FILE_LOCATOR_HELPER.getBundleInstallLocation(bundle):new File(
|
||||
overrideBundleInstallLocation);
|
||||
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:"))
|
||||
|
@ -186,7 +182,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
}
|
||||
else if (bundleInstall != null && bundleInstall.isDirectory())
|
||||
{
|
||||
webapp = new File(bundleInstall,webappFolderPath);
|
||||
webapp = new File(bundleInstall, webappFolderPath);
|
||||
}
|
||||
else if (bundleInstall != null)
|
||||
{
|
||||
|
@ -201,37 +197,43 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
{
|
||||
webapp = bundleInstall;
|
||||
}
|
||||
if (baseWebappInstallURL == null && (webapp == null || !webapp.exists()))
|
||||
{
|
||||
throw new IllegalArgumentException("Unable to locate " + webappFolderPath + " inside "
|
||||
+ (bundleInstall != null?bundleInstall.getAbsolutePath():"unlocated bundle '" + bundle.getSymbolicName() + "'"));
|
||||
}
|
||||
if (baseWebappInstallURL == null && (webapp == null || !webapp.exists())) { throw new IllegalArgumentException(
|
||||
"Unable to locate " + webappFolderPath
|
||||
+ " inside "
|
||||
+ (bundleInstall != null ? bundleInstall.getAbsolutePath() : "unlocated bundle '" + bundle.getSymbolicName()
|
||||
+ "'")); }
|
||||
if (baseWebappInstallURL == null && webapp != null)
|
||||
{
|
||||
baseWebappInstallURL = webapp.toURI().toURL();
|
||||
}
|
||||
return registerWebapplication(bundle,webappFolderPath,baseWebappInstallURL,contextPath,
|
||||
extraClasspath,bundleInstall,requireTldBundle,webXmlPath,defaultWebXmlPath,webAppContext);
|
||||
return registerWebapplication(bundle, webappFolderPath, baseWebappInstallURL, contextPath, extraClasspath, bundleInstall, requireTldBundle, 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)
|
||||
|
||||
/*
|
||||
* (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)
|
||||
*/
|
||||
private WebAppContext registerWebapplication(Bundle contributor, String pathInBundleToWebApp,
|
||||
URL baseWebappInstallURL, String contextPath, String extraClasspath, File bundleInstall,
|
||||
String requireTldBundle, String webXmlPath, String defaultWebXmlPath, WebAppContext context)
|
||||
throws Exception
|
||||
private WebAppContext registerWebapplication(Bundle contributor, String pathInBundleToWebApp, URL baseWebappInstallURL, String contextPath,
|
||||
String extraClasspath, File bundleInstall, String requireTldBundle, String webXmlPath,
|
||||
String defaultWebXmlPath, WebAppContext context) throws Exception
|
||||
{
|
||||
|
||||
ClassLoader contextCl = Thread.currentThread().getContextClassLoader();
|
||||
String[] oldServerClasses = 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
|
||||
// configure with access to all jetty classes and also all the
|
||||
// classes
|
||||
// that the contributor gives access to.
|
||||
Thread.currentThread().setContextClassLoader(composite);
|
||||
|
||||
|
@ -248,7 +250,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
}
|
||||
else
|
||||
{
|
||||
webXml = new File(bundleInstall,webXmlPath);
|
||||
webXml = new File(bundleInstall, webXmlPath);
|
||||
}
|
||||
if (webXml.exists())
|
||||
{
|
||||
|
@ -258,7 +260,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
|
||||
if (defaultWebXmlPath == null || defaultWebXmlPath.length() == 0)
|
||||
{
|
||||
//use the one defined by the OSGiAppProvider.
|
||||
// use the one defined by the OSGiAppProvider.
|
||||
defaultWebXmlPath = _wrapper.getOSGiAppProvider().getDefaultsDescriptor();
|
||||
}
|
||||
if (defaultWebXmlPath != null && defaultWebXmlPath.length() != 0)
|
||||
|
@ -270,20 +272,19 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
}
|
||||
else
|
||||
{
|
||||
defaultWebXml = new File(bundleInstall,defaultWebXmlPath);
|
||||
defaultWebXml = new File(bundleInstall, defaultWebXmlPath);
|
||||
}
|
||||
if (defaultWebXml.exists())
|
||||
{
|
||||
context.setDefaultsDescriptor(defaultWebXml.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
//other parameters that might be defines on the OSGiAppProvider:
|
||||
|
||||
// other parameters that might be defines on the OSGiAppProvider:
|
||||
context.setParentLoaderPriority(_wrapper.getOSGiAppProvider().isParentLoaderPriority());
|
||||
|
||||
configureWebappClassLoader(contributor,context,composite, requireTldBundle);
|
||||
configureWebAppContext(context,contributor,requireTldBundle);
|
||||
|
||||
configureWebappClassLoader(contributor, context, composite, requireTldBundle);
|
||||
configureWebAppContext(context, contributor, requireTldBundle);
|
||||
|
||||
// @see
|
||||
// org.eclipse.jetty.webapp.JettyWebXmlConfiguration#configure(WebAppContext)
|
||||
|
@ -292,36 +293,36 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
// through the webapp classloader.
|
||||
oldServerClasses = context.getServerClasses();
|
||||
context.setServerClasses(null);
|
||||
|
||||
_wrapper.getOSGiAppProvider().addContext(contributor,pathInBundleToWebApp,context);
|
||||
|
||||
//support for patch resources. ideally this should be done inside a configurator.
|
||||
List<Resource> patchResources =
|
||||
(List<Resource>)context.getAttribute(WebInfConfiguration.RESOURCE_URLS+".patch");
|
||||
|
||||
_wrapper.getOSGiAppProvider().addContext(contributor, pathInBundleToWebApp, context);
|
||||
|
||||
// support for patch resources. ideally this should be done inside a
|
||||
// configurator.
|
||||
List<Resource> patchResources = (List<Resource>) context.getAttribute(WebInfConfiguration.RESOURCE_URLS + ".patch");
|
||||
if (patchResources != null)
|
||||
{
|
||||
LinkedList<Resource> resourcesPath = new LinkedList<Resource>();
|
||||
//place the patch resources at the beginning of the lookup path.
|
||||
resourcesPath.addAll(patchResources);
|
||||
//then place the ones from the host web bundle.
|
||||
Resource hostResources = context.getBaseResource();
|
||||
if (hostResources instanceof ResourceCollection)
|
||||
{
|
||||
for (Resource re : ((ResourceCollection)hostResources).getResources())
|
||||
{
|
||||
resourcesPath.add(re);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
resourcesPath.add(hostResources);
|
||||
}
|
||||
|
||||
ResourceCollection rc = new ResourceCollection(resourcesPath.toArray(
|
||||
new Resource[resourcesPath.size()]));
|
||||
context.setBaseResource(rc);
|
||||
LinkedList<Resource> resourcesPath = new LinkedList<Resource>();
|
||||
// place the patch resources at the beginning of the lookup
|
||||
// path.
|
||||
resourcesPath.addAll(patchResources);
|
||||
// then place the ones from the host web bundle.
|
||||
Resource hostResources = context.getBaseResource();
|
||||
if (hostResources instanceof ResourceCollection)
|
||||
{
|
||||
for (Resource re : ((ResourceCollection) hostResources).getResources())
|
||||
{
|
||||
resourcesPath.add(re);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
resourcesPath.add(hostResources);
|
||||
}
|
||||
|
||||
ResourceCollection rc = new ResourceCollection(resourcesPath.toArray(new Resource[resourcesPath.size()]));
|
||||
context.setBaseResource(rc);
|
||||
}
|
||||
|
||||
|
||||
return context;
|
||||
}
|
||||
finally
|
||||
|
@ -335,38 +336,41 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.jetty.osgi.boot.internal.webapp.IWebBundleDeployerHelper#unregister(org.eclipse.jetty.server.handler.ContextHandler)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.eclipse.jetty.osgi.boot.internal.webapp.IWebBundleDeployerHelper#
|
||||
* unregister(org.eclipse.jetty.server.handler.ContextHandler)
|
||||
*/
|
||||
public void unregister(ContextHandler contextHandler) throws Exception
|
||||
{
|
||||
_wrapper.getOSGiAppProvider().removeContext(contextHandler);
|
||||
}
|
||||
|
||||
/* (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)
|
||||
/*
|
||||
* (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, String requireTldBundle, ContextHandler handler)
|
||||
throws Exception
|
||||
public ContextHandler registerContext(Bundle contributor, String contextFileRelativePath, String extraClasspath, String overrideBundleInstallLocation,
|
||||
String requireTldBundle, ContextHandler handler) throws Exception
|
||||
{
|
||||
File contextsHome = _wrapper.getOSGiAppProvider().getContextXmlDirAsFile();
|
||||
if (contextsHome != null)
|
||||
{
|
||||
File prodContextFile = new File(contextsHome,contributor.getSymbolicName() + "/" + contextFileRelativePath);
|
||||
if (prodContextFile.exists())
|
||||
{
|
||||
return registerContext(contributor,contextFileRelativePath,prodContextFile,extraClasspath,
|
||||
overrideBundleInstallLocation,requireTldBundle,handler);
|
||||
}
|
||||
File prodContextFile = new File(contextsHome, contributor.getSymbolicName() + "/" + contextFileRelativePath);
|
||||
if (prodContextFile.exists()) { return registerContext(contributor, contextFileRelativePath, prodContextFile, extraClasspath,
|
||||
overrideBundleInstallLocation, requireTldBundle, handler); }
|
||||
}
|
||||
File rootFolder = overrideBundleInstallLocation != null
|
||||
? Resource.newResource(overrideBundleInstallLocation).getFile()
|
||||
: BUNDLE_FILE_LOCATOR_HELPER.getBundleInstallLocation(contributor);
|
||||
File contextFile = rootFolder != null?new File(rootFolder,contextFileRelativePath):null;
|
||||
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,requireTldBundle,handler);
|
||||
return registerContext(contributor, contextFileRelativePath, contextFile, extraClasspath, overrideBundleInstallLocation, requireTldBundle, handler);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -378,15 +382,19 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
{
|
||||
contextFileRelativePath = "/" + contextFileRelativePath;
|
||||
}
|
||||
|
||||
|
||||
URL contextURL = contributor.getEntry(contextFileRelativePath);
|
||||
if (contextURL != null)
|
||||
{
|
||||
Resource r = Resource.newResource(contextURL);
|
||||
return registerContext(contributor,contextFileRelativePath,r.getInputStream(),extraClasspath,overrideBundleInstallLocation,requireTldBundle,handler);
|
||||
Resource r = Resource.newResource(contextURL);
|
||||
return registerContext(contributor, contextFileRelativePath, r.getInputStream(), extraClasspath, overrideBundleInstallLocation,
|
||||
requireTldBundle, handler);
|
||||
}
|
||||
throw new IllegalArgumentException("Could not find the context " + "file " + contextFileRelativePath + " for the bundle "
|
||||
+ contributor.getSymbolicName() + (overrideBundleInstallLocation != null?" using the install location " + overrideBundleInstallLocation:""));
|
||||
throw new IllegalArgumentException("Could not find the context " + "file "
|
||||
+ contextFileRelativePath
|
||||
+ " for the bundle "
|
||||
+ contributor.getSymbolicName()
|
||||
+ (overrideBundleInstallLocation != null ? " using the install location " + overrideBundleInstallLocation : ""));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -400,16 +408,14 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
* @param classInBundle
|
||||
* @throws Exception
|
||||
*/
|
||||
private ContextHandler registerContext(Bundle contributor, String pathInBundle, File contextFile,
|
||||
String extraClasspath, String overrideBundleInstallLocation,
|
||||
String requireTldBundle, ContextHandler handler) throws Exception
|
||||
private ContextHandler registerContext(Bundle contributor, String pathInBundle, File contextFile, String extraClasspath,
|
||||
String overrideBundleInstallLocation, String requireTldBundle, ContextHandler handler) throws Exception
|
||||
{
|
||||
InputStream contextFileInputStream = null;
|
||||
try
|
||||
{
|
||||
contextFileInputStream = new BufferedInputStream(new FileInputStream(contextFile));
|
||||
return registerContext(contributor, pathInBundle, contextFileInputStream,
|
||||
extraClasspath,overrideBundleInstallLocation,requireTldBundle,handler);
|
||||
return registerContext(contributor, pathInBundle, contextFileInputStream, extraClasspath, overrideBundleInstallLocation, requireTldBundle, handler);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -424,11 +430,8 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
* happen.
|
||||
* @throws Exception
|
||||
*/
|
||||
private ContextHandler registerContext(Bundle contributor,
|
||||
String pathInsideBundle, InputStream contextFileInputStream,
|
||||
String extraClasspath, String overrideBundleInstallLocation,
|
||||
String requireTldBundle, ContextHandler handler)
|
||||
throws Exception
|
||||
private ContextHandler registerContext(Bundle contributor, String pathInsideBundle, InputStream contextFileInputStream, String extraClasspath,
|
||||
String overrideBundleInstallLocation, String requireTldBundle, ContextHandler handler) throws Exception
|
||||
{
|
||||
ClassLoader contextCl = Thread.currentThread().getContextClassLoader();
|
||||
String[] oldServerClasses = null;
|
||||
|
@ -442,24 +445,23 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
// classes
|
||||
// that the contributor gives access to.
|
||||
Thread.currentThread().setContextClassLoader(composite);
|
||||
ContextHandler context = createContextHandler(handler, contributor,
|
||||
contextFileInputStream,extraClasspath,
|
||||
overrideBundleInstallLocation,requireTldBundle);
|
||||
if (context == null)
|
||||
{
|
||||
ContextHandler context = createContextHandler(handler, contributor, contextFileInputStream, extraClasspath, overrideBundleInstallLocation,
|
||||
requireTldBundle);
|
||||
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);
|
||||
// the actual registration must happen via the new Deployment API.
|
||||
// _ctxtHandler.addHandler(context);
|
||||
|
||||
configureWebappClassLoader(contributor,context,composite, requireTldBundle);
|
||||
configureWebappClassLoader(contributor, context, composite, requireTldBundle);
|
||||
if (context instanceof WebAppContext)
|
||||
{
|
||||
webAppContext = (WebAppContext)context;
|
||||
webAppContext = (WebAppContext) context;
|
||||
// @see
|
||||
// org.eclipse.jetty.webapp.JettyWebXmlConfiguration#configure(WebAppContext)
|
||||
oldServerClasses = webAppContext.getServerClasses();
|
||||
|
@ -485,53 +487,58 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
* @see {WebAppDeployer#scan} around the comment
|
||||
* <code>// configure it</code>
|
||||
*/
|
||||
protected void configureWebAppContext(ContextHandler wah, Bundle contributor,
|
||||
String requireTldBundle) throws IOException
|
||||
protected void configureWebAppContext(ContextHandler wah, Bundle contributor, String requireTldBundle) throws IOException
|
||||
{
|
||||
// rfc66
|
||||
wah.setAttribute(OSGiWebappConstants.RFC66_OSGI_BUNDLE_CONTEXT,contributor.getBundleContext());
|
||||
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());
|
||||
|
||||
//also pass the bundle directly. sometimes a bundle does not have a bundlecontext.
|
||||
//it is still useful to have access to the Bundle from the servlet context.
|
||||
// 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());
|
||||
|
||||
// also pass the bundle directly. sometimes a bundle does not have a
|
||||
// bundlecontext.
|
||||
// it is still useful to have access to the Bundle from the servlet
|
||||
// context.
|
||||
wah.setAttribute(OSGiWebappConstants.JETTY_OSGI_BUNDLE, contributor);
|
||||
|
||||
//pass the value of the require tld bundle so that the TagLibOSGiConfiguration
|
||||
//can pick it up.
|
||||
|
||||
// pass the value of the require tld bundle so that the
|
||||
// TagLibOSGiConfiguration
|
||||
// can pick it up.
|
||||
wah.setAttribute(OSGiWebappConstants.REQUIRE_TLD_BUNDLE, requireTldBundle);
|
||||
|
||||
|
||||
Bundle[] fragments = PackageAdminServiceTracker.INSTANCE.getFragmentsAndRequiredBundles(contributor);
|
||||
if (fragments != null && fragments.length != 0)
|
||||
{
|
||||
//sorted extra resource base found in the fragments.
|
||||
//the resources are either overriding the resourcebase found in the web-bundle
|
||||
//or appended.
|
||||
//amongst each resource we sort them according to the alphabetical order
|
||||
//of the name of the internal folder and the symbolic name of the fragment.
|
||||
//this is useful to make sure that the lookup path of those
|
||||
//resource base defined by fragments is always the same.
|
||||
//This natural order could be abused to define the order in which the base resources are
|
||||
//looked up.
|
||||
TreeMap<String,Resource> patchResourcesPath = new TreeMap<String,Resource>();
|
||||
TreeMap<String,Resource> appendedResourcesPath = new TreeMap<String,Resource>();
|
||||
for (Bundle frag : fragments) {
|
||||
String fragFolder = (String)frag.getHeaders().get(OSGiWebappConstants.JETTY_WAR_FRAGMENT_FOLDER_PATH);
|
||||
String patchFragFolder = (String)frag.getHeaders().get(OSGiWebappConstants.JETTY_WAR_PATCH_FRAGMENT_FOLDER_PATH);
|
||||
// sorted extra resource base found in the fragments.
|
||||
// the resources are either overriding the resourcebase found in the
|
||||
// web-bundle
|
||||
// or appended.
|
||||
// amongst each resource we sort them according to the alphabetical
|
||||
// order
|
||||
// of the name of the internal folder and the symbolic name of the
|
||||
// fragment.
|
||||
// this is useful to make sure that the lookup path of those
|
||||
// resource base defined by fragments is always the same.
|
||||
// This natural order could be abused to define the order in which
|
||||
// the base resources are
|
||||
// looked up.
|
||||
TreeMap<String, Resource> patchResourcesPath = new TreeMap<String, Resource>();
|
||||
TreeMap<String, Resource> appendedResourcesPath = new TreeMap<String, Resource>();
|
||||
for (Bundle frag : fragments)
|
||||
{
|
||||
String fragFolder = (String) frag.getHeaders().get(OSGiWebappConstants.JETTY_WAR_FRAGMENT_FOLDER_PATH);
|
||||
String patchFragFolder = (String) frag.getHeaders().get(OSGiWebappConstants.JETTY_WAR_PATCH_FRAGMENT_FOLDER_PATH);
|
||||
if (fragFolder != null)
|
||||
{
|
||||
URL fragUrl = frag.getEntry(fragFolder);
|
||||
if (fragUrl == null)
|
||||
{
|
||||
throw new IllegalArgumentException("Unable to locate " + fragFolder + " inside "
|
||||
+ " the fragment '" + frag.getSymbolicName() + "'");
|
||||
}
|
||||
if (fragUrl == null) { throw new IllegalArgumentException("Unable to locate " + fragFolder
|
||||
+ " inside "
|
||||
+ " the fragment '"
|
||||
+ frag.getSymbolicName()
|
||||
+ "'"); }
|
||||
fragUrl = DefaultFileLocatorHelper.getLocalURL(fragUrl);
|
||||
String key = fragFolder.startsWith("/") ? fragFolder.substring(1) : fragFolder;
|
||||
appendedResourcesPath.put(key + ";" + frag.getSymbolicName(), Resource.newResource(fragUrl));
|
||||
|
@ -539,11 +546,11 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
if (patchFragFolder != null)
|
||||
{
|
||||
URL patchFragUrl = frag.getEntry(patchFragFolder);
|
||||
if (patchFragUrl == null)
|
||||
{
|
||||
throw new IllegalArgumentException("Unable to locate " + patchFragUrl + " inside "
|
||||
+ " the fragment '" + frag.getSymbolicName() + "'");
|
||||
}
|
||||
if (patchFragUrl == null) { throw new IllegalArgumentException("Unable to locate " + patchFragUrl
|
||||
+ " inside "
|
||||
+ " the fragment '"
|
||||
+ frag.getSymbolicName()
|
||||
+ "'"); }
|
||||
patchFragUrl = DefaultFileLocatorHelper.getLocalURL(patchFragUrl);
|
||||
String key = patchFragFolder.startsWith("/") ? patchFragFolder.substring(1) : patchFragFolder;
|
||||
patchResourcesPath.put(key + ";" + frag.getSymbolicName(), Resource.newResource(patchFragUrl));
|
||||
|
@ -551,92 +558,92 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
}
|
||||
if (!appendedResourcesPath.isEmpty())
|
||||
{
|
||||
wah.setAttribute(WebInfConfiguration.RESOURCE_URLS, new ArrayList<Resource>(appendedResourcesPath.values()));
|
||||
wah.setAttribute(WebInfConfiguration.RESOURCE_URLS, new ArrayList<Resource>(appendedResourcesPath.values()));
|
||||
}
|
||||
if (!patchResourcesPath.isEmpty())
|
||||
{
|
||||
wah.setAttribute(WebInfConfiguration.RESOURCE_URLS + ".patch", new ArrayList<Resource>(patchResourcesPath.values()));
|
||||
wah.setAttribute(WebInfConfiguration.RESOURCE_URLS + ".patch", new ArrayList<Resource>(patchResourcesPath.values()));
|
||||
}
|
||||
|
||||
|
||||
if (wah instanceof WebAppContext)
|
||||
{
|
||||
//This is the equivalent of what MetaInfConfiguration does. For OSGi bundles without the JarScanner
|
||||
WebAppContext webappCtxt = (WebAppContext)wah;
|
||||
//take care of the web-fragments, meta-inf resources and tld resources:
|
||||
//similar to what MetaInfConfiguration does.
|
||||
List<Resource> frags = (List<Resource>)wah.getAttribute(FragmentConfiguration.FRAGMENT_RESOURCES);
|
||||
List<Resource> resfrags = (List<Resource>)wah.getAttribute(WebInfConfiguration.RESOURCE_URLS);
|
||||
List<Resource> tldfrags = (List<Resource>)wah.getAttribute(TagLibConfiguration.TLD_RESOURCES);
|
||||
for (Bundle frag : fragments)
|
||||
{
|
||||
URL webFrag = frag.getEntry("/META-INF/web-fragment.xml");
|
||||
Enumeration<URL> resEnum = frag.findEntries("/META-INF/resources", "*", true);
|
||||
Enumeration<URL> tldEnum = frag.findEntries("/META-INF", "*.tld", false);
|
||||
if (webFrag != null || (resEnum != null && resEnum.hasMoreElements())
|
||||
|| (tldEnum != null && tldEnum.hasMoreElements()))
|
||||
{
|
||||
try
|
||||
{
|
||||
File fragFile = BUNDLE_FILE_LOCATOR_HELPER.getBundleInstallLocation(frag);
|
||||
//add it to the webinf jars collection:
|
||||
//no need to check that it was not there yet: it was not there yet for sure.
|
||||
Resource fragFileAsResource = Resource.newResource(fragFile.toURI());
|
||||
webappCtxt.getMetaData().addWebInfJar(fragFileAsResource);
|
||||
|
||||
if (webFrag != null)
|
||||
{
|
||||
if (frags == null)
|
||||
{
|
||||
frags = new ArrayList<Resource>();
|
||||
wah.setAttribute(FragmentConfiguration.FRAGMENT_RESOURCES, frags);
|
||||
}
|
||||
frags.add(fragFileAsResource);
|
||||
}
|
||||
if (resEnum != null && resEnum.hasMoreElements())
|
||||
{
|
||||
URL resourcesEntry = frag.getEntry("/META-INF/resources/");
|
||||
if (resourcesEntry == null)
|
||||
{
|
||||
//probably we found some fragments to a bundle.
|
||||
//those are already contributed.
|
||||
//so we skip this.
|
||||
}
|
||||
else
|
||||
{
|
||||
if (resfrags == null)
|
||||
{
|
||||
resfrags = new ArrayList<Resource>();
|
||||
wah.setAttribute(WebInfConfiguration.RESOURCE_URLS, resfrags);
|
||||
}
|
||||
resfrags.add(Resource.newResource(
|
||||
DefaultFileLocatorHelper.getLocalURL(resourcesEntry)));
|
||||
}
|
||||
}
|
||||
if (tldEnum != null && tldEnum.hasMoreElements())
|
||||
{
|
||||
if (tldfrags == null)
|
||||
{
|
||||
tldfrags = new ArrayList<Resource>();
|
||||
wah.setAttribute(TagLibConfiguration.TLD_RESOURCES, tldfrags);
|
||||
}
|
||||
while (tldEnum.hasMoreElements())
|
||||
{
|
||||
URL tldUrl = tldEnum.nextElement();
|
||||
tldfrags.add(Resource.newResource(
|
||||
DefaultFileLocatorHelper.getLocalURL(tldUrl)));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
__logger.warn("Unable to locate the bundle " + frag.getBundleId(),e);
|
||||
}
|
||||
}
|
||||
}
|
||||
// This is the equivalent of what MetaInfConfiguration does. For
|
||||
// OSGi bundles without the JarScanner
|
||||
WebAppContext webappCtxt = (WebAppContext) wah;
|
||||
// take care of the web-fragments, meta-inf resources and tld
|
||||
// resources:
|
||||
// similar to what MetaInfConfiguration does.
|
||||
List<Resource> frags = (List<Resource>) wah.getAttribute(FragmentConfiguration.FRAGMENT_RESOURCES);
|
||||
List<Resource> resfrags = (List<Resource>) wah.getAttribute(WebInfConfiguration.RESOURCE_URLS);
|
||||
List<Resource> tldfrags = (List<Resource>) wah.getAttribute(TagLibConfiguration.TLD_RESOURCES);
|
||||
for (Bundle frag : fragments)
|
||||
{
|
||||
URL webFrag = frag.getEntry("/META-INF/web-fragment.xml");
|
||||
Enumeration<URL> resEnum = frag.findEntries("/META-INF/resources", "*", true);
|
||||
Enumeration<URL> tldEnum = frag.findEntries("/META-INF", "*.tld", false);
|
||||
if (webFrag != null || (resEnum != null && resEnum.hasMoreElements()) || (tldEnum != null && tldEnum.hasMoreElements()))
|
||||
{
|
||||
try
|
||||
{
|
||||
File fragFile = BUNDLE_FILE_LOCATOR_HELPER.getBundleInstallLocation(frag);
|
||||
// add it to the webinf jars collection:
|
||||
// no need to check that it was not there yet: it
|
||||
// was not there yet for sure.
|
||||
Resource fragFileAsResource = Resource.newResource(fragFile.toURI());
|
||||
webappCtxt.getMetaData().addWebInfJar(fragFileAsResource);
|
||||
|
||||
if (webFrag != null)
|
||||
{
|
||||
if (frags == null)
|
||||
{
|
||||
frags = new ArrayList<Resource>();
|
||||
wah.setAttribute(FragmentConfiguration.FRAGMENT_RESOURCES, frags);
|
||||
}
|
||||
frags.add(fragFileAsResource);
|
||||
}
|
||||
if (resEnum != null && resEnum.hasMoreElements())
|
||||
{
|
||||
URL resourcesEntry = frag.getEntry("/META-INF/resources/");
|
||||
if (resourcesEntry == null)
|
||||
{
|
||||
// probably we found some fragments to a
|
||||
// bundle.
|
||||
// those are already contributed.
|
||||
// so we skip this.
|
||||
}
|
||||
else
|
||||
{
|
||||
if (resfrags == null)
|
||||
{
|
||||
resfrags = new ArrayList<Resource>();
|
||||
wah.setAttribute(WebInfConfiguration.RESOURCE_URLS, resfrags);
|
||||
}
|
||||
resfrags.add(Resource.newResource(DefaultFileLocatorHelper.getLocalURL(resourcesEntry)));
|
||||
}
|
||||
}
|
||||
if (tldEnum != null && tldEnum.hasMoreElements())
|
||||
{
|
||||
if (tldfrags == null)
|
||||
{
|
||||
tldfrags = new ArrayList<Resource>();
|
||||
wah.setAttribute(TagLibConfiguration.TLD_RESOURCES, tldfrags);
|
||||
}
|
||||
while (tldEnum.hasMoreElements())
|
||||
{
|
||||
URL tldUrl = tldEnum.nextElement();
|
||||
tldfrags.add(Resource.newResource(DefaultFileLocatorHelper.getLocalURL(tldUrl)));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
__logger.warn("Unable to locate the bundle " + frag.getBundleId(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -644,15 +651,13 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
* @param contextFile
|
||||
* @return
|
||||
*/
|
||||
protected ContextHandler createContextHandler(ContextHandler handlerToConfigure,
|
||||
Bundle bundle, File contextFile, String extraClasspath,
|
||||
String overrideBundleInstallLocation, String requireTldBundle)
|
||||
protected ContextHandler createContextHandler(ContextHandler handlerToConfigure, Bundle bundle, File contextFile, String extraClasspath,
|
||||
String overrideBundleInstallLocation, String requireTldBundle)
|
||||
{
|
||||
try
|
||||
{
|
||||
return createContextHandler(handlerToConfigure,bundle,
|
||||
new BufferedInputStream(new FileInputStream(contextFile)),
|
||||
extraClasspath,overrideBundleInstallLocation,requireTldBundle);
|
||||
return createContextHandler(handlerToConfigure, bundle, new BufferedInputStream(new FileInputStream(contextFile)), extraClasspath,
|
||||
overrideBundleInstallLocation, requireTldBundle);
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
|
@ -667,9 +672,8 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected ContextHandler createContextHandler(ContextHandler handlerToConfigure,
|
||||
Bundle bundle, InputStream contextInputStream, String extraClasspath,
|
||||
String overrideBundleInstallLocation, String requireTldBundle)
|
||||
protected ContextHandler createContextHandler(ContextHandler handlerToConfigure, Bundle bundle, InputStream contextInputStream, String extraClasspath,
|
||||
String overrideBundleInstallLocation, String requireTldBundle)
|
||||
{
|
||||
/*
|
||||
* Do something identical to what the ContextProvider would have done:
|
||||
|
@ -686,30 +690,30 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
{
|
||||
XmlConfiguration xmlConfiguration = new XmlConfiguration(contextInputStream);
|
||||
HashMap properties = new HashMap();
|
||||
properties.put("Server",_wrapper.getServer());
|
||||
|
||||
properties.put("Server", _wrapper.getServer());
|
||||
|
||||
// insert the bundle's location as a property.
|
||||
setThisBundleHomeProperty(bundle,properties,overrideBundleInstallLocation);
|
||||
setThisBundleHomeProperty(bundle, properties, overrideBundleInstallLocation);
|
||||
xmlConfiguration.getProperties().putAll(properties);
|
||||
|
||||
ContextHandler context = null;
|
||||
if (handlerToConfigure == null)
|
||||
{
|
||||
context = (ContextHandler)xmlConfiguration.configure();
|
||||
context = (ContextHandler) xmlConfiguration.configure();
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlConfiguration.configure(handlerToConfigure);
|
||||
context = handlerToConfigure;
|
||||
}
|
||||
|
||||
|
||||
if (context instanceof WebAppContext)
|
||||
{
|
||||
((WebAppContext)context).setExtraClasspath(extraClasspath);
|
||||
((WebAppContext)context).setParentLoaderPriority(_wrapper.getOSGiAppProvider().isParentLoaderPriority());
|
||||
((WebAppContext) context).setExtraClasspath(extraClasspath);
|
||||
((WebAppContext) context).setParentLoaderPriority(_wrapper.getOSGiAppProvider().isParentLoaderPriority());
|
||||
if (_wrapper.getOSGiAppProvider().getDefaultsDescriptor() != null && _wrapper.getOSGiAppProvider().getDefaultsDescriptor().length() != 0)
|
||||
{
|
||||
((WebAppContext)context).setDefaultsDescriptor(_wrapper.getOSGiAppProvider().getDefaultsDescriptor());
|
||||
((WebAppContext) context).setDefaultsDescriptor(_wrapper.getOSGiAppProvider().getDefaultsDescriptor());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -775,13 +779,12 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
{
|
||||
if (context instanceof WebAppContext)
|
||||
{
|
||||
WebAppContext webappCtxt = (WebAppContext)context;
|
||||
WebAppContext webappCtxt = (WebAppContext) context;
|
||||
context.setClassLoader(webappClassLoader);
|
||||
webappClassLoader.setWebappContext(webappCtxt);
|
||||
|
||||
String pathsToRequiredBundles = getPathsToRequiredBundles(context, requireTldBundle);
|
||||
if (pathsToRequiredBundles != null)
|
||||
webappClassLoader.addClassPath(pathsToRequiredBundles);
|
||||
if (pathsToRequiredBundles != null) webappClassLoader.addClassPath(pathsToRequiredBundles);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -797,20 +800,20 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
// 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(
|
||||
_wrapper.getParentClassLoaderForWebapps(),new WebAppContext(),contributor,BUNDLE_CLASS_LOADER_HELPER);
|
||||
/* DEBUG
|
||||
try {
|
||||
Class c = webappClassLoader.loadClass("org.glassfish.jsp.api.ResourceInjector");
|
||||
System.err.println("LOADED org.glassfish.jsp.api.ResourceInjector from "+c.getClassLoader());
|
||||
}
|
||||
catch (Exception e) {e.printStackTrace();}
|
||||
try {
|
||||
Class c = webappClassLoader.loadClass("org.apache.jasper.xmlparser.ParserUtils");
|
||||
System.err.println("LOADED org.apache.jasper.xmlparser.ParserUtils from "+c.getClassLoader());
|
||||
}
|
||||
catch (Exception e) {e.printStackTrace();}
|
||||
*/
|
||||
OSGiWebappClassLoader webappClassLoader = new OSGiWebappClassLoader(_wrapper.getParentClassLoaderForWebapps(), new WebAppContext(), contributor,
|
||||
BUNDLE_CLASS_LOADER_HELPER);
|
||||
/*
|
||||
* DEBUG try { Class c =
|
||||
* webappClassLoader.loadClass("org.glassfish.jsp.api.ResourceInjector"
|
||||
* );
|
||||
* System.err.println("LOADED org.glassfish.jsp.api.ResourceInjector from "
|
||||
* +c.getClassLoader()); } catch (Exception e) {e.printStackTrace();}
|
||||
* try { Class c =
|
||||
* webappClassLoader.loadClass("org.apache.jasper.xmlparser.ParserUtils"
|
||||
* );
|
||||
* System.err.println("LOADED org.apache.jasper.xmlparser.ParserUtils from "
|
||||
* +c.getClassLoader()); } catch (Exception e) {e.printStackTrace();}
|
||||
*/
|
||||
return webappClassLoader;
|
||||
}
|
||||
|
||||
|
@ -823,10 +826,9 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
{
|
||||
try
|
||||
{
|
||||
File location = overrideBundleInstallLocation != null?new File(overrideBundleInstallLocation):BUNDLE_FILE_LOCATOR_HELPER
|
||||
.getBundleInstallLocation(bundle);
|
||||
properties.put("this.bundle.install",location.getCanonicalPath());
|
||||
properties.put("this.bundle.install.url",bundle.getEntry("/").toString());
|
||||
File location = overrideBundleInstallLocation != null ? new File(overrideBundleInstallLocation) : BUNDLE_FILE_LOCATOR_HELPER.getBundleInstallLocation(bundle);
|
||||
properties.put("this.bundle.install", location.getCanonicalPath());
|
||||
properties.put("this.bundle.install.url", bundle.getEntry("/").toString());
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
|
@ -834,36 +836,30 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private String getPathsToRequiredBundles (ContextHandler context, String requireTldBundle) throws Exception
|
||||
private String getPathsToRequiredBundles(ContextHandler context, String requireTldBundle) throws Exception
|
||||
{
|
||||
if (requireTldBundle == null)
|
||||
return null;
|
||||
if (requireTldBundle == null) return null;
|
||||
|
||||
StringBuilder paths = new StringBuilder();
|
||||
Bundle bundle = (Bundle)context.getAttribute(OSGiWebappConstants.JETTY_OSGI_BUNDLE);
|
||||
Bundle bundle = (Bundle) context.getAttribute(OSGiWebappConstants.JETTY_OSGI_BUNDLE);
|
||||
PackageAdmin packAdmin = getBundleAdmin();
|
||||
DefaultFileLocatorHelper fileLocatorHelper = new DefaultFileLocatorHelper();
|
||||
|
||||
|
||||
String[] symbNames = requireTldBundle.split(", ");
|
||||
|
||||
for (String symbName : symbNames)
|
||||
{
|
||||
Bundle[] bs = packAdmin.getBundles(symbName, null);
|
||||
if (bs == null || bs.length == 0)
|
||||
{
|
||||
throw new IllegalArgumentException("Unable to locate the bundle '"
|
||||
+ symbName + "' specified in the "
|
||||
+ OSGiWebappConstants.REQUIRE_TLD_BUNDLE
|
||||
+ " of the manifest of "
|
||||
+ bundle.getSymbolicName());
|
||||
}
|
||||
if (bs == null || bs.length == 0) { throw new IllegalArgumentException("Unable to locate the bundle '" + symbName
|
||||
+ "' specified in the "
|
||||
+ OSGiWebappConstants.REQUIRE_TLD_BUNDLE
|
||||
+ " of the manifest of "
|
||||
+ bundle.getSymbolicName()); }
|
||||
|
||||
|
||||
File f = fileLocatorHelper.getBundleInstallLocation(bs[0]);
|
||||
if (paths.length() > 0)
|
||||
if (paths.length() > 0)
|
||||
paths.append(", ");
|
||||
System.err.println("getPathsToRequiredBundles: bundle path="+bs[0].getLocation()+" uri="+f.toURI());
|
||||
__logger.debug("getPathsToRequiredBundles: bundle path=" + bs[0].getLocation() + " uri=" + f.toURI());
|
||||
paths.append(f.toURI().toURL().toString());
|
||||
}
|
||||
|
||||
|
@ -872,12 +868,11 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
|
||||
private PackageAdmin getBundleAdmin()
|
||||
{
|
||||
Bundle bootBundle = ((BundleReference)OSGiWebappConstants.class.getClassLoader()).getBundle();
|
||||
Bundle bootBundle = ((BundleReference) OSGiWebappConstants.class.getClassLoader()).getBundle();
|
||||
ServiceTracker serviceTracker = new ServiceTracker(bootBundle.getBundleContext(), PackageAdmin.class.getName(), null);
|
||||
serviceTracker.open();
|
||||
|
||||
return (PackageAdmin) serviceTracker.getService();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@ import org.osgi.framework.BundleEvent;
|
|||
import org.osgi.util.tracker.BundleTracker;
|
||||
import org.osgi.util.tracker.BundleTrackerCustomizer;
|
||||
|
||||
|
||||
/**
|
||||
* Support bundles that declare the webapp directly through headers in their
|
||||
* manifest.
|
||||
|
@ -49,133 +48,132 @@ import org.osgi.util.tracker.BundleTrackerCustomizer;
|
|||
*
|
||||
* @author hmalphettes
|
||||
*/
|
||||
public class WebBundleTrackerCustomizer implements BundleTrackerCustomizer {
|
||||
public class WebBundleTrackerCustomizer implements BundleTrackerCustomizer
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(WebBundleTrackerCustomizer.class);
|
||||
|
||||
|
||||
/**
|
||||
* A bundle is being added to the <code>BundleTracker</code>.
|
||||
*
|
||||
* <p>
|
||||
* This method is called before a bundle which matched the search parameters
|
||||
* of the <code>BundleTracker</code> is added to the
|
||||
* <code>BundleTracker</code>. This method should return the object to be
|
||||
* tracked for the specified <code>Bundle</code>. The returned object is
|
||||
* stored in the <code>BundleTracker</code> and is available from the
|
||||
* {@link BundleTracker#getObject(Bundle) getObject} method.
|
||||
*
|
||||
* @param bundle The <code>Bundle</code> being added to the
|
||||
* <code>BundleTracker</code>.
|
||||
* @param event The bundle event which caused this customizer method to be
|
||||
* called or <code>null</code> if there is no bundle event
|
||||
* associated with the call to this method.
|
||||
* @return The object to be tracked for the specified <code>Bundle</code>
|
||||
* object or <code>null</code> if the specified <code>Bundle</code>
|
||||
* object should not be tracked.
|
||||
*/
|
||||
public Object addingBundle(Bundle bundle, BundleEvent event)
|
||||
{
|
||||
if (bundle.getState() == Bundle.ACTIVE)
|
||||
{
|
||||
boolean isWebBundle = register(bundle);
|
||||
return isWebBundle ? bundle : null;
|
||||
}
|
||||
else if (bundle.getState() == Bundle.STOPPING)
|
||||
{
|
||||
unregister(bundle);
|
||||
}
|
||||
else
|
||||
{
|
||||
// we should not be called in that state as
|
||||
// we are registered only for ACTIVE and STOPPING
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* A bundle is being added to the <code>BundleTracker</code>.
|
||||
*
|
||||
* <p>
|
||||
* This method is called before a bundle which matched the search parameters
|
||||
* of the <code>BundleTracker</code> is added to the
|
||||
* <code>BundleTracker</code>. This method should return the object to be
|
||||
* tracked for the specified <code>Bundle</code>. The returned object is
|
||||
* stored in the <code>BundleTracker</code> and is available from the
|
||||
* {@link BundleTracker#getObject(Bundle) getObject} method.
|
||||
*
|
||||
* @param bundle The <code>Bundle</code> being added to the
|
||||
* <code>BundleTracker</code>.
|
||||
* @param event The bundle event which caused this customizer method to be
|
||||
* called or <code>null</code> if there is no bundle event associated
|
||||
* with the call to this method.
|
||||
* @return The object to be tracked for the specified <code>Bundle</code>
|
||||
* object or <code>null</code> if the specified <code>Bundle</code>
|
||||
* object should not be tracked.
|
||||
*/
|
||||
public Object addingBundle(Bundle bundle, BundleEvent event)
|
||||
{
|
||||
if (bundle.getState() == Bundle.ACTIVE)
|
||||
{
|
||||
boolean isWebBundle = register(bundle);
|
||||
return isWebBundle ? bundle : null;
|
||||
}
|
||||
else if (bundle.getState() == Bundle.STOPPING)
|
||||
{
|
||||
unregister(bundle);
|
||||
}
|
||||
else
|
||||
{
|
||||
//we should not be called in that state as
|
||||
//we are registered only for ACTIVE and STOPPING
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* A bundle tracked by the <code>BundleTracker</code> has been modified.
|
||||
*
|
||||
* <p>
|
||||
* This method is called when a bundle being tracked by the
|
||||
* <code>BundleTracker</code> has had its state modified.
|
||||
*
|
||||
* @param bundle The <code>Bundle</code> whose state has been modified.
|
||||
* @param event The bundle event which caused this customizer method to be
|
||||
* called or <code>null</code> if there is no bundle event
|
||||
* associated with the call to this method.
|
||||
* @param object The tracked object for the specified bundle.
|
||||
*/
|
||||
public void modifiedBundle(Bundle bundle, BundleEvent event, Object object)
|
||||
{
|
||||
// nothing the web-bundle was already track. something changed.
|
||||
// we only reload the webapps if the bundle is stopped and restarted.
|
||||
if (bundle.getState() == Bundle.STOPPING || bundle.getState() == Bundle.ACTIVE)
|
||||
{
|
||||
unregister(bundle);
|
||||
}
|
||||
if (bundle.getState() == Bundle.ACTIVE)
|
||||
{
|
||||
register(bundle);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A bundle tracked by the <code>BundleTracker</code> has been modified.
|
||||
*
|
||||
* <p>
|
||||
* This method is called when a bundle being tracked by the
|
||||
* <code>BundleTracker</code> has had its state modified.
|
||||
*
|
||||
* @param bundle The <code>Bundle</code> whose state has been modified.
|
||||
* @param event The bundle event which caused this customizer method to be
|
||||
* called or <code>null</code> if there is no bundle event associated
|
||||
* with the call to this method.
|
||||
* @param object The tracked object for the specified bundle.
|
||||
*/
|
||||
public void modifiedBundle(Bundle bundle, BundleEvent event,
|
||||
Object object)
|
||||
{
|
||||
//nothing the web-bundle was already track. something changed.
|
||||
//we only reload the webapps if the bundle is stopped and restarted.
|
||||
// System.err.println(bundle.getSymbolicName());
|
||||
if (bundle.getState() == Bundle.STOPPING || bundle.getState() == Bundle.ACTIVE)
|
||||
{
|
||||
unregister(bundle);
|
||||
}
|
||||
if (bundle.getState() == Bundle.ACTIVE)
|
||||
{
|
||||
register(bundle);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* A bundle tracked by the <code>BundleTracker</code> has been removed.
|
||||
*
|
||||
* <p>
|
||||
* This method is called after a bundle is no longer being tracked by the
|
||||
* <code>BundleTracker</code>.
|
||||
*
|
||||
* @param bundle The <code>Bundle</code> that has been removed.
|
||||
* @param event The bundle event which caused this customizer method to be
|
||||
* called or <code>null</code> if there is no bundle event
|
||||
* associated with the call to this method.
|
||||
* @param object The tracked object for the specified bundle.
|
||||
*/
|
||||
public void removedBundle(Bundle bundle, BundleEvent event, Object object)
|
||||
{
|
||||
unregister(bundle);
|
||||
}
|
||||
|
||||
/**
|
||||
* A bundle tracked by the <code>BundleTracker</code> has been removed.
|
||||
*
|
||||
* <p>
|
||||
* This method is called after a bundle is no longer being tracked by the
|
||||
* <code>BundleTracker</code>.
|
||||
*
|
||||
* @param bundle The <code>Bundle</code> that has been removed.
|
||||
* @param event The bundle event which caused this customizer method to be
|
||||
* called or <code>null</code> if there is no bundle event associated
|
||||
* with the call to this method.
|
||||
* @param object The tracked object for the specified bundle.
|
||||
*/
|
||||
public void removedBundle(Bundle bundle, BundleEvent event,
|
||||
Object object)
|
||||
{
|
||||
unregister(bundle);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param bundle
|
||||
* @return true if this bundle in indeed a web-bundle.
|
||||
*/
|
||||
/**
|
||||
* @param bundle
|
||||
* @return true if this bundle in indeed a web-bundle.
|
||||
*/
|
||||
private boolean register(Bundle bundle)
|
||||
{
|
||||
Dictionary<?, ?> dic = bundle.getHeaders();
|
||||
String warFolderRelativePath = (String)dic.get(OSGiWebappConstants.JETTY_WAR_FOLDER_PATH);
|
||||
String warFolderRelativePath = (String) dic.get(OSGiWebappConstants.JETTY_WAR_FOLDER_PATH);
|
||||
if (warFolderRelativePath != null)
|
||||
{
|
||||
String contextPath = getWebContextPath(bundle, dic, false);//(String)dic.get(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH);
|
||||
String contextPath = getWebContextPath(bundle, dic, false);// (String)dic.get(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH);
|
||||
if (contextPath == null || !contextPath.startsWith("/"))
|
||||
{
|
||||
LOG.warn("The manifest header '" + OSGiWebappConstants.JETTY_WAR_FOLDER_PATH +
|
||||
": " + warFolderRelativePath + "' in the bundle " + bundle.getSymbolicName() +
|
||||
" is not valid: there is no Web-ContextPath defined in the manifest.");
|
||||
return false;
|
||||
LOG.warn("The manifest header '" + OSGiWebappConstants.JETTY_WAR_FOLDER_PATH
|
||||
+ ": "
|
||||
+ warFolderRelativePath
|
||||
+ "' in the bundle "
|
||||
+ bundle.getSymbolicName()
|
||||
+ " is not valid: there is no Web-ContextPath defined in the manifest.");
|
||||
return false;
|
||||
}
|
||||
// create the corresponding service and publish it in the context of
|
||||
// the contributor bundle.
|
||||
try
|
||||
{
|
||||
JettyBootstrapActivator.registerWebapplication(bundle,warFolderRelativePath,contextPath);
|
||||
JettyBootstrapActivator.registerWebapplication(bundle, warFolderRelativePath, contextPath);
|
||||
return true;
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
LOG.warn("Starting the web-bundle " + bundle.getSymbolicName() + " threw an exception.", e);
|
||||
return true;//maybe it did not work maybe it did. safer to track this bundle.
|
||||
LOG.warn("Starting the web-bundle " + bundle.getSymbolicName() + " threw an exception.", e);
|
||||
return true;// maybe it did not work maybe it did. safer to
|
||||
// track this bundle.
|
||||
}
|
||||
}
|
||||
else if (dic.get(OSGiWebappConstants.JETTY_CONTEXT_FILE_PATH) != null)
|
||||
{
|
||||
String contextFileRelativePath = (String)dic.get(OSGiWebappConstants.JETTY_CONTEXT_FILE_PATH);
|
||||
String contextFileRelativePath = (String) dic.get(OSGiWebappConstants.JETTY_CONTEXT_FILE_PATH);
|
||||
if (contextFileRelativePath == null)
|
||||
{
|
||||
// nothing to register here.
|
||||
|
@ -187,7 +185,7 @@ public class WebBundleTrackerCustomizer implements BundleTrackerCustomizer {
|
|||
{
|
||||
try
|
||||
{
|
||||
JettyBootstrapActivator.registerContext(bundle,path.trim());
|
||||
JettyBootstrapActivator.registerContext(bundle, path.trim());
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
|
@ -203,8 +201,8 @@ public class WebBundleTrackerCustomizer implements BundleTrackerCustomizer {
|
|||
// (draft) of the spec: just a couple of posts on the
|
||||
// world-wide-web.
|
||||
URL rfc66Webxml = bundle.getEntry("/WEB-INF/web.xml");
|
||||
if (rfc66Webxml == null && dic.get(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH) == null)
|
||||
{
|
||||
if (rfc66Webxml == null && dic.get(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH) == null)
|
||||
{
|
||||
return false;// no webapp in here
|
||||
}
|
||||
// this is risky: should we make sure that there is no classes and
|
||||
|
@ -215,42 +213,41 @@ public class WebBundleTrackerCustomizer implements BundleTrackerCustomizer {
|
|||
// pointing to files and folders inside WEB-INF. We should
|
||||
// filter-out
|
||||
// META-INF too
|
||||
String rfc66ContextPath = getWebContextPath(bundle,dic,rfc66Webxml==null);
|
||||
String rfc66ContextPath = getWebContextPath(bundle, dic, rfc66Webxml == null);
|
||||
try
|
||||
{
|
||||
JettyBootstrapActivator.registerWebapplication(bundle,".",rfc66ContextPath);
|
||||
JettyBootstrapActivator.registerWebapplication(bundle, ".", rfc66ContextPath);
|
||||
return true;
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
return true;//maybe it did not work maybe it did. safer to track this bundle.
|
||||
return true;// maybe it did not work maybe it did. safer to
|
||||
// track this bundle.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String getWebContextPath(Bundle bundle, Dictionary<?, ?> dic, boolean webinfWebxmlExists)
|
||||
{
|
||||
String rfc66ContextPath = (String)dic.get(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH);
|
||||
String rfc66ContextPath = (String) dic.get(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH);
|
||||
if (rfc66ContextPath == null)
|
||||
{
|
||||
if (!webinfWebxmlExists) {
|
||||
return null;
|
||||
}
|
||||
if (!webinfWebxmlExists) { return null; }
|
||||
// extract from the last token of the bundle's location:
|
||||
// (really ?
|
||||
// could consider processing the symbolic name as an alternative
|
||||
// the location will often reflect the version.
|
||||
// maybe this is relevant when the file is a war)
|
||||
String location = bundle.getLocation();
|
||||
String toks[] = location.replace('\\','/').split("/");
|
||||
String toks[] = location.replace('\\', '/').split("/");
|
||||
rfc66ContextPath = toks[toks.length - 1];
|
||||
// remove .jar, .war etc:
|
||||
int lastDot = rfc66ContextPath.lastIndexOf('.');
|
||||
if (lastDot != -1)
|
||||
{
|
||||
rfc66ContextPath = rfc66ContextPath.substring(0,lastDot);
|
||||
rfc66ContextPath = rfc66ContextPath.substring(0, lastDot);
|
||||
}
|
||||
}
|
||||
if (!rfc66ContextPath.startsWith("/"))
|
||||
|
@ -259,7 +256,7 @@ public class WebBundleTrackerCustomizer implements BundleTrackerCustomizer {
|
|||
}
|
||||
return rfc66ContextPath;
|
||||
}
|
||||
|
||||
|
||||
private void unregister(Bundle bundle)
|
||||
{
|
||||
// nothing to do: when the bundle is stopped, each one of its service
|
||||
|
@ -268,7 +265,4 @@ public class WebBundleTrackerCustomizer implements BundleTrackerCustomizer {
|
|||
// webapps registered in that bundle.
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import java.util.zip.ZipFile;
|
|||
|
||||
import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelper;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.FileResource;
|
||||
import org.osgi.framework.Bundle;
|
||||
|
||||
|
@ -43,11 +44,13 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper
|
|||
// The url nuxeo and felix return is created directly from the File so it
|
||||
// should work.
|
||||
private static Field BUNDLE_ENTRY_FIELD = null;
|
||||
|
||||
private static Field FILE_FIELD = null;
|
||||
|
||||
private static Field BUNDLE_FILE_FIELD_FOR_DIR_ZIP_BUNDLE_ENTRY = null;// ZipBundleFile
|
||||
// inside
|
||||
// DirZipBundleEntry
|
||||
|
||||
// inside
|
||||
// DirZipBundleEntry
|
||||
|
||||
private static Field ZIP_FILE_FILED_FOR_ZIP_BUNDLE_FILE = null;// ZipFile
|
||||
|
||||
|
@ -56,8 +59,7 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper
|
|||
* spirit of OSGi but quite necessary to support self-contained webapps and
|
||||
* other situations.
|
||||
*
|
||||
* @param bundle
|
||||
* The bundle
|
||||
* @param bundle The bundle
|
||||
* @return Its installation location as a file.
|
||||
* @throws Exception
|
||||
*/
|
||||
|
@ -67,19 +69,23 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper
|
|||
// grab the MANIFEST.MF's url
|
||||
// and then do what it takes.
|
||||
URL url = bundle.getEntry("/META-INF/MANIFEST.MF");
|
||||
// System.err.println(url.toString() + " " + url.toURI() + " " + url.getProtocol());
|
||||
//System.err.println(url.toString() + " " + url.toURI() + " " + url.getProtocol());
|
||||
if (url.getProtocol().equals("file"))
|
||||
{
|
||||
// some osgi frameworks do use the file protocole directly in some
|
||||
// situations. Do use the FileResource to transform the URL into a File: URL#toURI is broken
|
||||
return new FileResource(url).getFile().getParentFile().getParentFile();
|
||||
// situations. Do use the FileResource to transform the URL into a
|
||||
// File: URL#toURI is broken
|
||||
return new FileResource(url).getFile().getParentFile().getParentFile();
|
||||
}
|
||||
else if (url.getProtocol().equals("bundleentry"))
|
||||
{
|
||||
// say hello to equinox who has its own protocol.
|
||||
// we use introspection like there is no tomorrow to get access to
|
||||
// the File
|
||||
|
||||
URLConnection con = url.openConnection();
|
||||
con.setUseCaches(Resource.getDefaultUseCaches()); //work around problems where url connections cache references to jars
|
||||
|
||||
if (BUNDLE_ENTRY_FIELD == null)
|
||||
{
|
||||
BUNDLE_ENTRY_FIELD = con.getClass().getDeclaredField("bundleEntry");
|
||||
|
@ -93,13 +99,16 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper
|
|||
FILE_FIELD = bundleEntry.getClass().getDeclaredField("file");
|
||||
FILE_FIELD.setAccessible(true);
|
||||
}
|
||||
File f = (File)FILE_FIELD.get(bundleEntry);
|
||||
File f = (File) FILE_FIELD.get(bundleEntry);
|
||||
return f.getParentFile().getParentFile();
|
||||
}
|
||||
else if (bundleEntry.getClass().getName().equals("org.eclipse.osgi.baseadaptor.bundlefile.ZipBundleEntry"))
|
||||
{
|
||||
url = bundle.getEntry("/");
|
||||
|
||||
con = url.openConnection();
|
||||
con.setDefaultUseCaches(Resource.getDefaultUseCaches());
|
||||
|
||||
if (BUNDLE_ENTRY_FIELD == null)
|
||||
{// this one will be a DirZipBundleEntry
|
||||
BUNDLE_ENTRY_FIELD = con.getClass().getDeclaredField("bundleEntry");
|
||||
|
@ -117,7 +126,7 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper
|
|||
ZIP_FILE_FILED_FOR_ZIP_BUNDLE_FILE = zipBundleFile.getClass().getDeclaredField("zipFile");
|
||||
ZIP_FILE_FILED_FOR_ZIP_BUNDLE_FILE.setAccessible(true);
|
||||
}
|
||||
ZipFile zipFile = (ZipFile)ZIP_FILE_FILED_FOR_ZIP_BUNDLE_FILE.get(zipBundleFile);
|
||||
ZipFile zipFile = (ZipFile) ZIP_FILE_FILED_FOR_ZIP_BUNDLE_FILE.get(zipBundleFile);
|
||||
return new File(zipFile.getName());
|
||||
}
|
||||
else if (bundleEntry.getClass().getName().equals("org.eclipse.osgi.baseadaptor.bundlefile.DirZipBundleEntry"))
|
||||
|
@ -130,7 +139,7 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper
|
|||
{
|
||||
// observed this on felix-2.0.0
|
||||
String location = bundle.getLocation();
|
||||
// System.err.println("location " + location);
|
||||
// System.err.println("location " + location);
|
||||
if (location.startsWith("file:/"))
|
||||
{
|
||||
URI uri = new URI(URIUtil.encodePath(location));
|
||||
|
@ -138,27 +147,32 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper
|
|||
}
|
||||
else if (location.startsWith("file:"))
|
||||
{
|
||||
//location defined in the BundleArchive m_bundleArchive
|
||||
//it is relative to relative to the BundleArchive's m_archiveRootDir
|
||||
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;
|
||||
// location defined in the BundleArchive m_bundleArchive
|
||||
// it is relative to relative to the BundleArchive's
|
||||
// m_archiveRootDir
|
||||
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:"))
|
||||
{
|
||||
location = URLDecoder.decode(location.substring("reference:".length()), "UTF-8");
|
||||
File file = new File(location.substring("file:".length()));
|
||||
return file;
|
||||
location = URLDecoder.decode(location.substring("reference:".length()), "UTF-8");
|
||||
File file = new File(location.substring("file:".length()));
|
||||
return file;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
@ -179,37 +193,40 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper
|
|||
path = path.substring(1);
|
||||
}
|
||||
File bundleInstall = getBundleInstallLocation(bundle);
|
||||
File webapp = path != null && path.length() != 0?new File(bundleInstall,path):bundleInstall;
|
||||
if (!webapp.exists())
|
||||
{
|
||||
throw new IllegalArgumentException("Unable to locate " + path + " inside " + bundle.getSymbolicName() + " ("
|
||||
+ (bundleInstall != null?bundleInstall.getAbsolutePath():" no_bundle_location ") + ")");
|
||||
File webapp = path != null && path.length() != 0 ? new File(bundleInstall, path) : bundleInstall;
|
||||
if (!webapp.exists())
|
||||
{
|
||||
throw new IllegalArgumentException("Unable to locate " + path
|
||||
+ " inside "
|
||||
+ bundle.getSymbolicName()
|
||||
+ " ("
|
||||
+ (bundleInstall != null ? bundleInstall.getAbsolutePath() : " no_bundle_location ")
|
||||
+ ")");
|
||||
}
|
||||
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<URL> 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<URL> enUrls = bundle.findEntries(path, pattern, false);
|
||||
return enUrls;
|
||||
}
|
||||
* 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<URL> 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<URL> enUrls = bundle.findEntries(path, pattern, false);
|
||||
return enUrls;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the bundle is a jar, returns the jar. If the bundle is a folder, look
|
||||
|
@ -256,76 +273,84 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper
|
|||
return new File[] { jasperLocation };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//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;
|
||||
/**
|
||||
* Only useful for equinox: on felix we get the file:// or jar:// url already.
|
||||
* Other OSGi implementations have not been tested
|
||||
* <p>
|
||||
* Get a URL to the bundle entry that uses a common protocol (i.e. file:
|
||||
* jar: or http: etc.).
|
||||
* </p>
|
||||
* @return a URL to the bundle entry that uses a common protocol
|
||||
*/
|
||||
public static URL getLocalURL(URL url) {
|
||||
if ("bundleresource".equals(url.getProtocol()) || "bundleentry".equals(url.getProtocol())) {
|
||||
try {
|
||||
URLConnection conn = url.openConnection();
|
||||
if (BUNDLE_URL_CONNECTION_getLocalURL == null &&
|
||||
conn.getClass().getName().equals(
|
||||
"org.eclipse.osgi.framework.internal.core.BundleURLConnection")) {
|
||||
BUNDLE_URL_CONNECTION_getLocalURL = conn.getClass().getMethod("getLocalURL", null);
|
||||
BUNDLE_URL_CONNECTION_getLocalURL.setAccessible(true);
|
||||
}
|
||||
if (BUNDLE_URL_CONNECTION_getLocalURL != null) {
|
||||
return (URL)BUNDLE_URL_CONNECTION_getLocalURL.invoke(conn, null);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
System.err.println("Unable to locate the OSGi url: '" + url + "'.");
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
return url;
|
||||
}
|
||||
/**
|
||||
* Only useful for equinox: on felix we get the file:// url already.
|
||||
* Other OSGi implementations have not been tested
|
||||
* <p>
|
||||
* Get a URL to the content of the bundle entry that uses the file: protocol.
|
||||
* The content of the bundle entry may be downloaded or extracted to the local
|
||||
* file system in order to create a file: URL.
|
||||
* @return a URL to the content of the bundle entry that uses the file: protocol
|
||||
* </p>
|
||||
*/
|
||||
public static URL getFileURL(URL url)
|
||||
{
|
||||
if ("bundleresource".equals(url.getProtocol()) || "bundleentry".equals(url.getProtocol()))
|
||||
{
|
||||
try
|
||||
{
|
||||
URLConnection conn = url.openConnection();
|
||||
if (BUNDLE_URL_CONNECTION_getFileURL == null &&
|
||||
conn.getClass().getName().equals(
|
||||
"org.eclipse.osgi.framework.internal.core.BundleURLConnection"))
|
||||
{
|
||||
BUNDLE_URL_CONNECTION_getFileURL = conn.getClass().getMethod("getFileURL", null);
|
||||
BUNDLE_URL_CONNECTION_getFileURL.setAccessible(true);
|
||||
}
|
||||
if (BUNDLE_URL_CONNECTION_getFileURL != null)
|
||||
{
|
||||
return (URL)BUNDLE_URL_CONNECTION_getFileURL.invoke(conn, null);
|
||||
}
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
return url;
|
||||
}
|
||||
// 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;
|
||||
|
||||
/**
|
||||
* Only useful for equinox: on felix we get the file:// or jar:// url
|
||||
* already. Other OSGi implementations have not been tested
|
||||
* <p>
|
||||
* Get a URL to the bundle entry that uses a common protocol (i.e. file:
|
||||
* jar: or http: etc.).
|
||||
* </p>
|
||||
*
|
||||
* @return a URL to the bundle entry that uses a common protocol
|
||||
*/
|
||||
public static URL getLocalURL(URL url)
|
||||
{
|
||||
if ("bundleresource".equals(url.getProtocol()) || "bundleentry".equals(url.getProtocol()))
|
||||
{
|
||||
try
|
||||
{
|
||||
URLConnection conn = url.openConnection();
|
||||
conn.setDefaultUseCaches(Resource.getDefaultUseCaches());
|
||||
if (BUNDLE_URL_CONNECTION_getLocalURL == null && conn.getClass().getName()
|
||||
.equals("org.eclipse.osgi.framework.internal.core.BundleURLConnection"))
|
||||
{
|
||||
BUNDLE_URL_CONNECTION_getLocalURL = conn.getClass().getMethod("getLocalURL", null);
|
||||
BUNDLE_URL_CONNECTION_getLocalURL.setAccessible(true);
|
||||
}
|
||||
if (BUNDLE_URL_CONNECTION_getLocalURL != null) { return (URL) BUNDLE_URL_CONNECTION_getLocalURL.invoke(conn, null); }
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
System.err.println("Unable to locate the OSGi url: '" + url + "'.");
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Only useful for equinox: on felix we get the file:// url already. Other
|
||||
* OSGi implementations have not been tested
|
||||
* <p>
|
||||
* Get a URL to the content of the bundle entry that uses the file:
|
||||
* protocol. The content of the bundle entry may be downloaded or extracted
|
||||
* to the local file system in order to create a file: URL.
|
||||
*
|
||||
* @return a URL to the content of the bundle entry that uses the file:
|
||||
* protocol
|
||||
* </p>
|
||||
*/
|
||||
public static URL getFileURL(URL url)
|
||||
{
|
||||
if ("bundleresource".equals(url.getProtocol()) || "bundleentry".equals(url.getProtocol()))
|
||||
{
|
||||
try
|
||||
{
|
||||
URLConnection conn = url.openConnection();
|
||||
conn.setDefaultUseCaches(Resource.getDefaultUseCaches());
|
||||
if (BUNDLE_URL_CONNECTION_getFileURL == null && conn.getClass().getName()
|
||||
.equals("org.eclipse.osgi.framework.internal.core.BundleURLConnection"))
|
||||
{
|
||||
BUNDLE_URL_CONNECTION_getFileURL = conn.getClass().getMethod("getFileURL", null);
|
||||
BUNDLE_URL_CONNECTION_getFileURL.setAccessible(true);
|
||||
}
|
||||
if (BUNDLE_URL_CONNECTION_getFileURL != null) { return (URL) BUNDLE_URL_CONNECTION_getFileURL.invoke(conn, null); }
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue