Reformat and reindent code.
This commit is contained in:
parent
d0f35d10fd
commit
eae1b01122
|
@ -55,27 +55,31 @@ import org.osgi.framework.Constants;
|
|||
* <p>
|
||||
* When the parameter autoInstallOSGiBundles is set to true, OSGi bundles that
|
||||
* are located in the monitored directory are installed and started after the
|
||||
* framework as finished auto-starting all the other bundles.
|
||||
* Warning: only use this for development.
|
||||
* framework as finished auto-starting all the other bundles. Warning: only use
|
||||
* this for development.
|
||||
* </p>
|
||||
*/
|
||||
public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(OSGiAppProvider.class);
|
||||
|
||||
|
||||
private boolean _extractWars = true;
|
||||
|
||||
private boolean _parentLoaderPriority = false;
|
||||
|
||||
private String _defaultsDescriptor;
|
||||
|
||||
private String _tldBundles;
|
||||
|
||||
private String[] _configurationClasses;
|
||||
|
||||
|
||||
private boolean _autoInstallOSGiBundles = true;
|
||||
|
||||
//Keep track of the bundles that were installed and that are waiting for the
|
||||
//framework to complete its initialization.
|
||||
|
||||
// Keep track of the bundles that were installed and that are waiting for
|
||||
// the
|
||||
// framework to complete its initialization.
|
||||
Set<Bundle> _pendingBundlesToStart = null;
|
||||
|
||||
|
||||
/**
|
||||
* When a context file corresponds to a deployed bundle and is changed we
|
||||
* reload the corresponding bundle.
|
||||
|
@ -83,14 +87,11 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
|
|||
private static class Filter implements FilenameFilter
|
||||
{
|
||||
OSGiAppProvider _enclosedInstance;
|
||||
|
||||
|
||||
public boolean accept(File dir, String name)
|
||||
{
|
||||
File file = new File(dir,name);
|
||||
if (fileMightBeAnOSGiBundle(file))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
File file = new File(dir, name);
|
||||
if (fileMightBeAnOSGiBundle(file)) { return true; }
|
||||
if (!file.isDirectory())
|
||||
{
|
||||
String contextName = getDeployedAppName(name);
|
||||
|
@ -105,8 +106,7 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
|
|||
}
|
||||
|
||||
/**
|
||||
* @param contextFileName
|
||||
* for example myContext.xml
|
||||
* @param contextFileName for example myContext.xml
|
||||
* @return The context, for example: myContext; null if this was not a
|
||||
* suitable contextFileName.
|
||||
*/
|
||||
|
@ -115,35 +115,40 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
|
|||
String lowername = contextFileName.toLowerCase();
|
||||
if (lowername.endsWith(".xml"))
|
||||
{
|
||||
String contextName = contextFileName.substring(0,lowername.length() - ".xml".length());
|
||||
String contextName = contextFileName.substring(0, lowername.length() - ".xml".length());
|
||||
return contextName;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reading the display name of a webapp is really not sufficient for indexing the various
|
||||
* deployed ContextHandlers.
|
||||
* Reading the display name of a webapp is really not sufficient for
|
||||
* indexing the various deployed ContextHandlers.
|
||||
*
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
private String getContextHandlerAppName(ContextHandler context) {
|
||||
private String getContextHandlerAppName(ContextHandler context)
|
||||
{
|
||||
String appName = context.getDisplayName();
|
||||
if (appName == null || appName.length() == 0 || getDeployedApps().containsKey(appName)) {
|
||||
if (context instanceof WebAppContext)
|
||||
{
|
||||
appName = ((WebAppContext)context).getContextPath();
|
||||
if (getDeployedApps().containsKey(appName)) {
|
||||
appName = "noDisplayName"+context.getClass().getSimpleName()+context.hashCode();
|
||||
}
|
||||
} else {
|
||||
appName = "noDisplayName"+context.getClass().getSimpleName()+context.hashCode();
|
||||
}
|
||||
if (appName == null || appName.length() == 0 || getDeployedApps().containsKey(appName))
|
||||
{
|
||||
if (context instanceof WebAppContext)
|
||||
{
|
||||
appName = ((WebAppContext) context).getContextPath();
|
||||
if (getDeployedApps().containsKey(appName))
|
||||
{
|
||||
appName = "noDisplayName" + context.getClass().getSimpleName() + context.hashCode();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
appName = "noDisplayName" + context.getClass().getSimpleName() + context.hashCode();
|
||||
}
|
||||
}
|
||||
return appName;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Default OSGiAppProvider consutructed when none are defined in the
|
||||
* jetty.xml configuration.
|
||||
|
@ -151,7 +156,7 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
|
|||
public OSGiAppProvider()
|
||||
{
|
||||
super(new Filter());
|
||||
((Filter)super._filenameFilter)._enclosedInstance = this;
|
||||
((Filter) super._filenameFilter)._enclosedInstance = this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -165,7 +170,7 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
|
|||
this();
|
||||
setMonitoredDirResource(Resource.newResource(contextsDir.toURI()));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the ContextHandler that was created by WebappRegistractionHelper
|
||||
*
|
||||
|
@ -183,13 +188,12 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
|
|||
// that creates the ContextHandler will actually be here.
|
||||
throw new IllegalStateException("The App must be passed the " + "instance of the ContextHandler when it is construsted");
|
||||
}
|
||||
if (_configurationClasses != null && wah instanceof WebAppContext)
|
||||
if (_configurationClasses != null && wah instanceof WebAppContext)
|
||||
{
|
||||
((WebAppContext)wah).setConfigurationClasses(_configurationClasses);
|
||||
((WebAppContext) wah).setConfigurationClasses(_configurationClasses);
|
||||
}
|
||||
|
||||
if (_defaultsDescriptor != null)
|
||||
((WebAppContext)wah).setDefaultsDescriptor(_defaultsDescriptor);
|
||||
|
||||
if (_defaultsDescriptor != null) ((WebAppContext) wah).setDefaultsDescriptor(_defaultsDescriptor);
|
||||
return app.getContextHandler();
|
||||
}
|
||||
|
||||
|
@ -205,18 +209,18 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
|
|||
|
||||
private static String getOriginId(Bundle contributor, String pathInBundle)
|
||||
{
|
||||
return contributor.getSymbolicName() + "-" + contributor.getVersion().toString() +
|
||||
(pathInBundle.startsWith("/") ? pathInBundle : "/" + pathInBundle);
|
||||
return contributor.getSymbolicName() + "-" + contributor.getVersion().toString() + (pathInBundle.startsWith("/") ? pathInBundle : "/" + pathInBundle);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param context
|
||||
* @throws Exception
|
||||
*/
|
||||
public void addContext(Bundle contributor, String pathInBundle, ContextHandler context) throws Exception
|
||||
{
|
||||
addContext(getOriginId(contributor, pathInBundle), context);
|
||||
addContext(getOriginId(contributor, pathInBundle), context);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param context
|
||||
* @throws Exception
|
||||
|
@ -224,19 +228,17 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
|
|||
public void addContext(String originId, ContextHandler context) throws Exception
|
||||
{
|
||||
// TODO apply configuration specific to this provider
|
||||
if (context instanceof WebAppContext)
|
||||
{
|
||||
((WebAppContext)context).setExtractWAR(isExtract());
|
||||
}
|
||||
if (context instanceof WebAppContext)
|
||||
{
|
||||
((WebAppContext) context).setExtractWAR(isExtract());
|
||||
}
|
||||
|
||||
// wrap context as an App
|
||||
App app = new App(getDeploymentManager(),this,originId,context);
|
||||
App app = new App(getDeploymentManager(), this, originId, context);
|
||||
String appName = getContextHandlerAppName(context);
|
||||
getDeployedApps().put(appName,app);
|
||||
getDeployedApps().put(appName, app);
|
||||
getDeploymentManager().addApp(app);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Called by the scanner of the context files directory. If we find the
|
||||
|
@ -254,31 +256,32 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
|
|||
// and reload the corresponding App.
|
||||
// see the 2 pass of the refactoring of the WebAppRegistrationHelper.
|
||||
String name = getDeployedAppName(filename);
|
||||
if (name != null)
|
||||
{
|
||||
return getDeployedApps().get(name);
|
||||
}
|
||||
if (name != null) { return getDeployedApps().get(name); }
|
||||
return null;
|
||||
}
|
||||
|
||||
public void removeContext(ContextHandler context) throws Exception
|
||||
{
|
||||
String appName = getContextHandlerAppName(context);
|
||||
String appName = getContextHandlerAppName(context);
|
||||
App app = getDeployedApps().remove(context.getDisplayName());
|
||||
if (app == null) {
|
||||
//try harder to undeploy this context handler.
|
||||
//see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=330098
|
||||
appName = null;
|
||||
for (Entry<String,App> deployedApp : getDeployedApps().entrySet()) {
|
||||
if (deployedApp.getValue().getContextHandler() == context) {
|
||||
app = deployedApp.getValue();
|
||||
appName = deployedApp.getKey();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (appName != null) {
|
||||
getDeployedApps().remove(appName);
|
||||
}
|
||||
if (app == null)
|
||||
{
|
||||
// try harder to undeploy this context handler.
|
||||
// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=330098
|
||||
appName = null;
|
||||
for (Entry<String, App> deployedApp : getDeployedApps().entrySet())
|
||||
{
|
||||
if (deployedApp.getValue().getContextHandler() == context)
|
||||
{
|
||||
app = deployedApp.getValue();
|
||||
appName = deployedApp.getKey();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (appName != null)
|
||||
{
|
||||
getDeployedApps().remove(appName);
|
||||
}
|
||||
}
|
||||
if (app != null)
|
||||
{
|
||||
|
@ -303,8 +306,7 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
|
|||
/**
|
||||
* Set the parentLoaderPriority.
|
||||
*
|
||||
* @param parentLoaderPriority
|
||||
* the parentLoaderPriority to set
|
||||
* @param parentLoaderPriority the parentLoaderPriority to set
|
||||
*/
|
||||
public void setParentLoaderPriority(boolean parentLoaderPriority)
|
||||
{
|
||||
|
@ -326,8 +328,7 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
|
|||
/**
|
||||
* Set the defaultsDescriptor.
|
||||
*
|
||||
* @param defaultsDescriptor
|
||||
* the defaultsDescriptor to set
|
||||
* @param defaultsDescriptor the defaultsDescriptor to set
|
||||
*/
|
||||
public void setDefaultsDescriptor(String defaultsDescriptor)
|
||||
{
|
||||
|
@ -343,8 +344,7 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
|
|||
try
|
||||
{
|
||||
Resource monitoredDir = getMonitoredDirResource();
|
||||
if (monitoredDir == null)
|
||||
return null;
|
||||
if (monitoredDir == null) return null;
|
||||
return monitoredDir.getFile();
|
||||
}
|
||||
catch (IOException e)
|
||||
|
@ -364,8 +364,7 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
|
|||
try
|
||||
{
|
||||
Resource monitoredDir = getMonitoredDirResource();
|
||||
if (monitoredDir == null)
|
||||
return null;
|
||||
if (monitoredDir == null) return null;
|
||||
return monitoredDir.getFile().toURI().toString();
|
||||
}
|
||||
catch (IOException e)
|
||||
|
@ -382,28 +381,29 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
|
|||
|
||||
public void setExtract(boolean extract)
|
||||
{
|
||||
_extractWars=extract;
|
||||
_extractWars = extract;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true when this app provider locates osgi bundles and features in
|
||||
* its monitored directory and installs them. By default true if there is a folder to monitor.
|
||||
* its monitored directory and installs them. By default true if
|
||||
* there is a folder to monitor.
|
||||
*/
|
||||
public boolean isAutoInstallOSGiBundles()
|
||||
{
|
||||
return _autoInstallOSGiBundles;
|
||||
return _autoInstallOSGiBundles;
|
||||
}
|
||||
|
||||
/**
|
||||
* <autoInstallOSGiBundles>true</autoInstallOSGiBundles>
|
||||
*
|
||||
* @param installingOSGiBundles
|
||||
*/
|
||||
public void setAutoInstallOSGiBundles(boolean installingOSGiBundles)
|
||||
{
|
||||
_autoInstallOSGiBundles=installingOSGiBundles;
|
||||
_autoInstallOSGiBundles = installingOSGiBundles;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Set the directory in which to look for context XML files.
|
||||
|
@ -424,33 +424,33 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
|
|||
{
|
||||
setMonitoredDirName(contextsDir);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param tldBundles Comma separated list of bundles that contain tld jars
|
||||
* that should be setup on the jetty instances created here.
|
||||
* that should be setup on the jetty instances created here.
|
||||
*/
|
||||
public void setTldBundles(String tldBundles)
|
||||
{
|
||||
_tldBundles = tldBundles;
|
||||
_tldBundles = tldBundles;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return The list of bundles that contain tld jars that should be setup
|
||||
* on the jetty instances created here.
|
||||
* @return The list of bundles that contain tld jars that should be setup on
|
||||
* the jetty instances created here.
|
||||
*/
|
||||
public String getTldBundles()
|
||||
{
|
||||
return _tldBundles;
|
||||
return _tldBundles;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param configurations The configuration class names.
|
||||
*/
|
||||
public void setConfigurationClasses(String[] configurations)
|
||||
{
|
||||
_configurationClasses = configurations==null?null:(String[])configurations.clone();
|
||||
}
|
||||
|
||||
_configurationClasses = configurations == null ? null : (String[]) configurations.clone();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
*
|
||||
|
@ -468,41 +468,41 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
|
|||
{
|
||||
if (isAutoInstallOSGiBundles())
|
||||
{
|
||||
if (getMonitoredDirResource() == null)
|
||||
{
|
||||
setAutoInstallOSGiBundles(false);
|
||||
LOG.info("Disable autoInstallOSGiBundles as there is not contexts folder to monitor.");
|
||||
}
|
||||
else
|
||||
{
|
||||
File scandir = null;
|
||||
try
|
||||
{
|
||||
scandir = getMonitoredDirResource().getFile();
|
||||
if (!scandir.exists() || !scandir.isDirectory())
|
||||
{
|
||||
setAutoInstallOSGiBundles(false);
|
||||
LOG.warn("Disable autoInstallOSGiBundles as the contexts folder '" + scandir.getAbsolutePath() + " does not exist.");
|
||||
scandir = null;
|
||||
}
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
setAutoInstallOSGiBundles(false);
|
||||
LOG.warn("Disable autoInstallOSGiBundles as the contexts folder '" + getMonitoredDirResource().getURI() + " does not exist.");
|
||||
scandir = null;
|
||||
}
|
||||
if (scandir != null)
|
||||
{
|
||||
for (File file : scandir.listFiles())
|
||||
{
|
||||
if (fileMightBeAnOSGiBundle(file))
|
||||
{
|
||||
installBundle(file, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (getMonitoredDirResource() == null)
|
||||
{
|
||||
setAutoInstallOSGiBundles(false);
|
||||
LOG.info("Disable autoInstallOSGiBundles as there is not contexts folder to monitor.");
|
||||
}
|
||||
else
|
||||
{
|
||||
File scandir = null;
|
||||
try
|
||||
{
|
||||
scandir = getMonitoredDirResource().getFile();
|
||||
if (!scandir.exists() || !scandir.isDirectory())
|
||||
{
|
||||
setAutoInstallOSGiBundles(false);
|
||||
LOG.warn("Disable autoInstallOSGiBundles as the contexts folder '" + scandir.getAbsolutePath() + " does not exist.");
|
||||
scandir = null;
|
||||
}
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
setAutoInstallOSGiBundles(false);
|
||||
LOG.warn("Disable autoInstallOSGiBundles as the contexts folder '" + getMonitoredDirResource().getURI() + " does not exist.");
|
||||
scandir = null;
|
||||
}
|
||||
if (scandir != null)
|
||||
{
|
||||
for (File file : scandir.listFiles())
|
||||
{
|
||||
if (fileMightBeAnOSGiBundle(file))
|
||||
{
|
||||
installBundle(file, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
super.doStart();
|
||||
if (isAutoInstallOSGiBundles())
|
||||
|
@ -511,10 +511,10 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
|
|||
super.addScannerListener(scanCycleListner);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* When the file is a jar or a folder, we look if it looks like an OSGi bundle.
|
||||
* In that case we install it and start it.
|
||||
* When the file is a jar or a folder, we look if it looks like an OSGi
|
||||
* bundle. In that case we install it and start it.
|
||||
* <p>
|
||||
* Really a simple trick to get going quickly with development.
|
||||
* </p>
|
||||
|
@ -532,7 +532,7 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
|
|||
super.fileAdded(filename);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param file
|
||||
* @return
|
||||
|
@ -541,15 +541,9 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
|
|||
{
|
||||
if (file.isDirectory())
|
||||
{
|
||||
if (new File(file,"META-INF/MANIFEST.MF").exists())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (file.getName().endsWith(".jar"))
|
||||
{
|
||||
return true;
|
||||
if (new File(file, "META-INF/MANIFEST.MF").exists()) { return true; }
|
||||
}
|
||||
else if (file.getName().endsWith(".jar")) { return true; }
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -580,72 +574,72 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
|
|||
super.fileRemoved(filename);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a bundle according to its location.
|
||||
* In the version 1.6 of org.osgi.framework, BundleContext.getBundle(String) is what we want.
|
||||
* However to support older versions of OSGi. We use our own local refrence mechanism.
|
||||
* Returns a bundle according to its location. In the version 1.6 of
|
||||
* org.osgi.framework, BundleContext.getBundle(String) is what we want.
|
||||
* However to support older versions of OSGi. We use our own local refrence
|
||||
* mechanism.
|
||||
*
|
||||
* @param location
|
||||
* @return
|
||||
*/
|
||||
protected Bundle getBundle(BundleContext bc, String location)
|
||||
{
|
||||
//not available in older versions of OSGi:
|
||||
//return bc.getBundle(location);
|
||||
for (Bundle b : bc.getBundles())
|
||||
{
|
||||
if (b.getLocation().equals(location))
|
||||
{
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
// not available in older versions of OSGi:
|
||||
// return bc.getBundle(location);
|
||||
for (Bundle b : bc.getBundles())
|
||||
{
|
||||
if (b.getLocation().equals(location)) { return b; }
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected synchronized Bundle installBundle(File file, boolean start)
|
||||
{
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
BundleContext bc = JettyBootstrapActivator.getBundleContext();
|
||||
String location = file.toURI().toString();
|
||||
Bundle b = getBundle(bc, location);
|
||||
if (b == null)
|
||||
if (b == null)
|
||||
{
|
||||
b = bc.installBundle(location);
|
||||
}
|
||||
if (b == null)
|
||||
{
|
||||
//not sure we will ever be here,
|
||||
//most likely a BundleException was thrown
|
||||
LOG.warn("The file " + location + " is not an OSGi bundle.");
|
||||
return null;
|
||||
// not sure we will ever be here,
|
||||
// most likely a BundleException was thrown
|
||||
LOG.warn("The file " + location + " is not an OSGi bundle.");
|
||||
return null;
|
||||
}
|
||||
if (start && b.getHeaders().get(Constants.FRAGMENT_HOST) == null)
|
||||
{//not a fragment, try to start it. if the framework has finished auto-starting.
|
||||
if (!PackageAdminServiceTracker.INSTANCE.frameworkHasCompletedAutostarts())
|
||||
{
|
||||
if (_pendingBundlesToStart == null)
|
||||
{
|
||||
_pendingBundlesToStart = new HashSet<Bundle>();
|
||||
}
|
||||
_pendingBundlesToStart.add(b);
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
b.start();
|
||||
}
|
||||
{// not a fragment, try to start it. if the framework has finished
|
||||
// auto-starting.
|
||||
if (!PackageAdminServiceTracker.INSTANCE.frameworkHasCompletedAutostarts())
|
||||
{
|
||||
if (_pendingBundlesToStart == null)
|
||||
{
|
||||
_pendingBundlesToStart = new HashSet<Bundle>();
|
||||
}
|
||||
_pendingBundlesToStart.add(b);
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
b.start();
|
||||
}
|
||||
}
|
||||
return b;
|
||||
}
|
||||
catch (BundleException e)
|
||||
{
|
||||
LOG.warn("Unable to " + (start? "start":"install") + " the bundle " + file.getAbsolutePath(), e);
|
||||
LOG.warn("Unable to " + (start ? "start" : "install") + " the bundle " + file.getAbsolutePath(), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
protected void uninstallBundle(File file)
|
||||
{
|
||||
try
|
||||
|
@ -659,7 +653,7 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
|
|||
LOG.warn("Unable to uninstall the bundle " + file.getAbsolutePath(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void updateBundle(File file)
|
||||
{
|
||||
try
|
||||
|
@ -683,53 +677,52 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
|
|||
LOG.warn("Unable to update the bundle " + file.getAbsolutePath(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* At the end of each scan, if there are some bundles to be started,
|
||||
* look if the framework has completed its autostart. In that case start those bundles.
|
||||
* At the end of each scan, if there are some bundles to be started, look if the
|
||||
* framework has completed its autostart. In that case start those bundles.
|
||||
*/
|
||||
class AutoStartWhenFrameworkHasCompleted implements Scanner.ScanCycleListener
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(AutoStartWhenFrameworkHasCompleted.class);
|
||||
|
||||
private final OSGiAppProvider _appProvider;
|
||||
|
||||
AutoStartWhenFrameworkHasCompleted(OSGiAppProvider appProvider)
|
||||
{
|
||||
_appProvider = appProvider;
|
||||
}
|
||||
|
||||
public void scanStarted(int cycle) throws Exception
|
||||
{
|
||||
}
|
||||
|
||||
public void scanEnded(int cycle) throws Exception
|
||||
{
|
||||
if (_appProvider._pendingBundlesToStart != null && PackageAdminServiceTracker.INSTANCE.frameworkHasCompletedAutostarts())
|
||||
{
|
||||
Iterator<Bundle> it = _appProvider._pendingBundlesToStart.iterator();
|
||||
while (it.hasNext())
|
||||
{
|
||||
Bundle b = it.next();
|
||||
if (b.getHeaders().get(Constants.FRAGMENT_HOST) != null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
try
|
||||
{
|
||||
b.start();
|
||||
}
|
||||
catch (BundleException e)
|
||||
{
|
||||
LOG.warn("Unable to start the bundle " + b.getLocation(), e);
|
||||
}
|
||||
private static final Logger LOG = Log.getLogger(AutoStartWhenFrameworkHasCompleted.class);
|
||||
|
||||
}
|
||||
_appProvider._pendingBundlesToStart = null;
|
||||
}
|
||||
}
|
||||
private final OSGiAppProvider _appProvider;
|
||||
|
||||
AutoStartWhenFrameworkHasCompleted(OSGiAppProvider appProvider)
|
||||
{
|
||||
_appProvider = appProvider;
|
||||
}
|
||||
|
||||
public void scanStarted(int cycle) throws Exception
|
||||
{
|
||||
}
|
||||
|
||||
public void scanEnded(int cycle) throws Exception
|
||||
{
|
||||
if (_appProvider._pendingBundlesToStart != null && PackageAdminServiceTracker.INSTANCE.frameworkHasCompletedAutostarts())
|
||||
{
|
||||
Iterator<Bundle> it = _appProvider._pendingBundlesToStart.iterator();
|
||||
while (it.hasNext())
|
||||
{
|
||||
Bundle b = it.next();
|
||||
if (b.getHeaders().get(Constants.FRAGMENT_HOST) != null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
try
|
||||
{
|
||||
b.start();
|
||||
}
|
||||
catch (BundleException e)
|
||||
{
|
||||
LOG.warn("Unable to start the bundle " + b.getLocation(), e);
|
||||
}
|
||||
|
||||
}
|
||||
_appProvider._pendingBundlesToStart = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -32,14 +32,14 @@ import org.osgi.framework.Bundle;
|
|||
import org.osgi.framework.BundleContext;
|
||||
|
||||
/**
|
||||
* Called by the {@link JettyBootstrapActivator} during the starting of the bundle.
|
||||
* If the system property 'jetty.home' is defined and points to a folder,
|
||||
* then setup the corresponding jetty server and starts it.
|
||||
* Called by the {@link JettyBootstrapActivator} during the starting of the
|
||||
* bundle. If the system property 'jetty.home' is defined and points to a
|
||||
* folder, then setup the corresponding jetty server and starts it.
|
||||
*/
|
||||
public class DefaultJettyAtJettyHomeHelper {
|
||||
public class DefaultJettyAtJettyHomeHelper
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(DefaultJettyAtJettyHomeHelper.class);
|
||||
|
||||
|
||||
/**
|
||||
* contains a comma separated list of pathes to the etc/jetty-*.xml files
|
||||
* used to configure jetty. By default the value is 'etc/jetty.xml' when the
|
||||
|
@ -48,44 +48,55 @@ public class DefaultJettyAtJettyHomeHelper {
|
|||
public static final String SYS_PROP_JETTY_ETC_FILES = OSGiServerConstants.MANAGED_JETTY_XML_CONFIG_URLS;
|
||||
|
||||
/**
|
||||
* Usual system property used as the hostname for a typical jetty configuration.
|
||||
* Usual system property used as the hostname for a typical jetty
|
||||
* configuration.
|
||||
*/
|
||||
public static final String SYS_PROP_JETTY_HOME = "jetty.home";
|
||||
|
||||
/**
|
||||
* System property to point to a bundle that embeds a jetty configuration
|
||||
* and that jetty configuration should be the default jetty server.
|
||||
* First we look for jetty.home. If we don't find it then we look for this property.
|
||||
* and that jetty configuration should be the default jetty server. First we
|
||||
* look for jetty.home. If we don't find it then we look for this property.
|
||||
*/
|
||||
public static final String SYS_PROP_JETTY_HOME_BUNDLE = "jetty.home.bundle";
|
||||
|
||||
/**
|
||||
* Usual system property used as the hostname for a typical jetty configuration.
|
||||
* Usual system property used as the hostname for a typical jetty
|
||||
* configuration.
|
||||
*/
|
||||
public static final String SYS_PROP_JETTY_HOST = "jetty.host";
|
||||
|
||||
/**
|
||||
* Usual system property used as the port for http for a typical jetty configuration.
|
||||
* Usual system property used as the port for http for a typical jetty
|
||||
* configuration.
|
||||
*/
|
||||
public static final String SYS_PROP_JETTY_PORT = "jetty.port";
|
||||
|
||||
/**
|
||||
* Usual system property used as the port for https for a typical jetty configuration.
|
||||
* Usual system property used as the port for https for a typical jetty
|
||||
* configuration.
|
||||
*/
|
||||
public static final String SYS_PROP_JETTY_PORT_SSL = "jetty.port.ssl";
|
||||
|
||||
/**
|
||||
* Called by the JettyBootStrapActivator.
|
||||
* If the system property jetty.home is defined and points to a folder,
|
||||
* deploys the corresponding jetty server.
|
||||
* Called by the JettyBootStrapActivator. If the system property jetty.home
|
||||
* is defined and points to a folder, deploys the corresponding jetty
|
||||
* server.
|
||||
* <p>
|
||||
* If the system property jetty.home.bundle is defined and points to a bundle.
|
||||
* Look for the configuration of jetty inside that bundle and deploys the corresponding bundle.
|
||||
* If the system property jetty.home.bundle is defined and points to a
|
||||
* bundle. Look for the configuration of jetty inside that bundle and
|
||||
* deploys the corresponding bundle.
|
||||
* </p>
|
||||
* <p>
|
||||
* In both cases reads the system property 'jetty.etc.config.urls' to locate the configuration
|
||||
* files for the deployed jetty. It is a comma spearate list of URLs or relative paths inside the bundle or folder
|
||||
* to the config files. If underfined it defaults to 'etc/jetty.xml'.
|
||||
* In both cases reads the system property 'jetty.etc.config.urls' to locate
|
||||
* the configuration files for the deployed jetty. It is a comma spearate
|
||||
* list of URLs or relative paths inside the bundle or folder to the config
|
||||
* files. If underfined it defaults to 'etc/jetty.xml'.
|
||||
* </p>
|
||||
* <p>
|
||||
* In both cases the system properties jetty.host, jetty.port and jetty.port.ssl are passed to the configuration files
|
||||
* that might use them as part of their properties.
|
||||
* In both cases the system properties jetty.host, jetty.port and
|
||||
* jetty.port.ssl are passed to the configuration files that might use them
|
||||
* as part of their properties.
|
||||
* </p>
|
||||
*/
|
||||
public static void startJettyAtJettyHome(BundleContext bundleContext) throws Exception
|
||||
|
@ -97,15 +108,14 @@ public class DefaultJettyAtJettyHomeHelper {
|
|||
if (jettyHomeSysProp != null)
|
||||
{
|
||||
jettyHomeSysProp = resolvePropertyValue(jettyHomeSysProp);
|
||||
//bug 329621
|
||||
if (jettyHomeSysProp.startsWith("\"") && jettyHomeSysProp.endsWith("\"")
|
||||
|| (jettyHomeSysProp.startsWith("'") && jettyHomeSysProp.endsWith("'"))) {
|
||||
// bug 329621
|
||||
if (jettyHomeSysProp.startsWith("\"") && jettyHomeSysProp.endsWith("\"") || (jettyHomeSysProp.startsWith("'") && jettyHomeSysProp.endsWith("'")))
|
||||
{
|
||||
jettyHomeSysProp = jettyHomeSysProp.substring(1, jettyHomeSysProp.length() - 1);
|
||||
}
|
||||
if (jettyHomeBundleSysProp != null)
|
||||
{
|
||||
LOG.warn("Both the jetty.home property and the jetty.home.bundle property are defined."
|
||||
+ " jetty.home.bundle is not taken into account.");
|
||||
LOG.warn("Both the jetty.home property and the jetty.home.bundle property are defined." + " jetty.home.bundle is not taken into account.");
|
||||
}
|
||||
jettyHome = new File(jettyHomeSysProp);
|
||||
if (!jettyHome.exists() || !jettyHome.isDirectory())
|
||||
|
@ -147,21 +157,24 @@ public class DefaultJettyAtJettyHomeHelper {
|
|||
|
||||
LOG.info("Configuring the default jetty server with " + configURLs);
|
||||
|
||||
//these properties usually are the ones passed to this type of configuration.
|
||||
setProperty(properties,SYS_PROP_JETTY_HOME,System.getProperty(SYS_PROP_JETTY_HOME));
|
||||
setProperty(properties,SYS_PROP_JETTY_HOST,System.getProperty(SYS_PROP_JETTY_HOST));
|
||||
setProperty(properties,SYS_PROP_JETTY_PORT,System.getProperty(SYS_PROP_JETTY_PORT));
|
||||
setProperty(properties,SYS_PROP_JETTY_PORT_SSL,System.getProperty(SYS_PROP_JETTY_PORT_SSL));
|
||||
// these properties usually are the ones passed to this type of
|
||||
// configuration.
|
||||
setProperty(properties, SYS_PROP_JETTY_HOME, System.getProperty(SYS_PROP_JETTY_HOME));
|
||||
setProperty(properties, SYS_PROP_JETTY_HOST, System.getProperty(SYS_PROP_JETTY_HOST));
|
||||
setProperty(properties, SYS_PROP_JETTY_PORT, System.getProperty(SYS_PROP_JETTY_PORT));
|
||||
setProperty(properties, SYS_PROP_JETTY_PORT_SSL, System.getProperty(SYS_PROP_JETTY_PORT_SSL));
|
||||
|
||||
bundleContext.registerService(Server.class.getName(), server, properties);
|
||||
// hookNestedConnectorToBridgeServlet(server);
|
||||
// hookNestedConnectorToBridgeServlet(server);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Minimum setup for the location of the configuration files given a jettyhome folder.
|
||||
* Reads the system property jetty.etc.config.urls and look for the corresponding jetty
|
||||
* configuration files that will be used to setup the jetty server.
|
||||
* Minimum setup for the location of the configuration files given a
|
||||
* jettyhome folder. Reads the system property jetty.etc.config.urls and
|
||||
* look for the corresponding jetty configuration files that will be used to
|
||||
* setup the jetty server.
|
||||
*
|
||||
* @param jettyhome
|
||||
* @return
|
||||
*/
|
||||
|
@ -191,17 +204,18 @@ public class DefaultJettyAtJettyHomeHelper {
|
|||
}
|
||||
|
||||
/**
|
||||
* Minimum setup for the location of the configuration files given a configuration
|
||||
* embedded inside a bundle.
|
||||
* Reads the system property jetty.etc.config.urls and look for the corresponding jetty
|
||||
* configuration files that will be used to setup the jetty server.
|
||||
* Minimum setup for the location of the configuration files given a
|
||||
* configuration embedded inside a bundle. Reads the system property
|
||||
* jetty.etc.config.urls and look for the corresponding jetty configuration
|
||||
* files that will be used to setup the jetty server.
|
||||
*
|
||||
* @param jettyhome
|
||||
* @return
|
||||
*/
|
||||
private static String getJettyConfigurationURLs(Bundle configurationBundle)
|
||||
{
|
||||
String jettyetc = System.getProperty(SYS_PROP_JETTY_ETC_FILES,"etc/jetty.xml");
|
||||
StringTokenizer tokenizer = new StringTokenizer(jettyetc,";,", false);
|
||||
String jettyetc = System.getProperty(SYS_PROP_JETTY_ETC_FILES, "etc/jetty.xml");
|
||||
StringTokenizer tokenizer = new StringTokenizer(jettyetc, ";,", false);
|
||||
StringBuilder res = new StringBuilder();
|
||||
|
||||
while (tokenizer.hasMoreTokens())
|
||||
|
@ -213,18 +227,18 @@ public class DefaultJettyAtJettyHomeHelper {
|
|||
}
|
||||
else
|
||||
{
|
||||
Enumeration<URL> enUrls = BundleFileLocatorHelper.DEFAULT
|
||||
.findEntries(configurationBundle, etcFile);
|
||||
Enumeration<URL> enUrls = BundleFileLocatorHelper.DEFAULT.findEntries(configurationBundle, etcFile);
|
||||
|
||||
//default for org.eclipse.osgi.boot where we look inside jettyhome for the default embedded configuration.
|
||||
//default inside jettyhome. this way fragments to the bundle can define their own configuration.
|
||||
// default for org.eclipse.osgi.boot where we look inside
|
||||
// jettyhome for the default embedded configuration.
|
||||
// default inside jettyhome. this way fragments to the bundle
|
||||
// can define their own configuration.
|
||||
if ((enUrls == null || !enUrls.hasMoreElements()) && etcFile.endsWith("etc/jetty.xml"))
|
||||
{
|
||||
enUrls = BundleFileLocatorHelper.DEFAULT
|
||||
.findEntries(configurationBundle, "/jettyhome/etc/jetty-osgi-default.xml");
|
||||
System.err.println("Configuring jetty with the default embedded configuration:" +
|
||||
"bundle: " + configurationBundle.getSymbolicName() +
|
||||
" config: /jettyhome/etc/jetty-osgi-default.xml");
|
||||
enUrls = BundleFileLocatorHelper.DEFAULT.findEntries(configurationBundle, "/jettyhome/etc/jetty-osgi-default.xml");
|
||||
System.err.println("Configuring jetty with the default embedded configuration:" + "bundle: "
|
||||
+ configurationBundle.getSymbolicName()
|
||||
+ " config: /jettyhome/etc/jetty-osgi-default.xml");
|
||||
}
|
||||
if (enUrls == null || !enUrls.hasMoreElements())
|
||||
{
|
||||
|
@ -261,30 +275,27 @@ public class DefaultJettyAtJettyHomeHelper {
|
|||
|
||||
/**
|
||||
* recursively substitute the ${sysprop} by their actual system property.
|
||||
* ${sysprop,defaultvalue} will use 'defaultvalue' as the value if no sysprop is defined.
|
||||
* Not the most efficient code but we are shooting for simplicity and speed of development here.
|
||||
* ${sysprop,defaultvalue} will use 'defaultvalue' as the value if no
|
||||
* sysprop is defined. Not the most efficient code but we are shooting for
|
||||
* simplicity and speed of development here.
|
||||
*
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public static String resolvePropertyValue(String value)
|
||||
{
|
||||
{
|
||||
int ind = value.indexOf("${");
|
||||
if (ind == -1) {
|
||||
return value;
|
||||
}
|
||||
if (ind == -1) { return value; }
|
||||
int ind2 = value.indexOf('}', ind);
|
||||
if (ind2 == -1) {
|
||||
return value;
|
||||
}
|
||||
String sysprop = value.substring(ind+2, ind2);
|
||||
if (ind2 == -1) { return value; }
|
||||
String sysprop = value.substring(ind + 2, ind2);
|
||||
String defaultValue = null;
|
||||
int comma = sysprop.indexOf(',');
|
||||
if (comma != -1 && comma+1 != sysprop.length())
|
||||
if (comma != -1 && comma + 1 != sysprop.length())
|
||||
{
|
||||
defaultValue = sysprop.substring(comma+1);
|
||||
defaultValue = sysprop.substring(comma + 1);
|
||||
defaultValue = resolvePropertyValue(defaultValue);
|
||||
sysprop = sysprop.substring(0,comma);
|
||||
sysprop = sysprop.substring(0, comma);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -293,7 +304,7 @@ public class DefaultJettyAtJettyHomeHelper {
|
|||
|
||||
String v = System.getProperty(sysprop);
|
||||
|
||||
String reminder = value.length() > ind2 + 1 ? value.substring(ind2+1) : "";
|
||||
String reminder = value.length() > ind2 + 1 ? value.substring(ind2 + 1) : "";
|
||||
reminder = resolvePropertyValue(reminder);
|
||||
if (v != null)
|
||||
{
|
||||
|
|
|
@ -17,12 +17,14 @@ package org.eclipse.jetty.osgi.boot.internal.serverfactory;
|
|||
/**
|
||||
* Keeps track of the running jetty servers. They are named.
|
||||
*/
|
||||
public interface IManagedJettyServerRegistry {
|
||||
public interface IManagedJettyServerRegistry
|
||||
{
|
||||
|
||||
/**
|
||||
* @param managedServerName The server name
|
||||
* @return the corresponding jetty server wrapped with its deployment properties.
|
||||
* @return the corresponding jetty server wrapped with its deployment
|
||||
* properties.
|
||||
*/
|
||||
public ServerInstanceWrapper getServerInstanceWrapper(String managedServerName);
|
||||
|
||||
public ServerInstanceWrapper getServerInstanceWrapper(String managedServerName);
|
||||
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ import org.osgi.framework.ServiceReference;
|
|||
public class JettyServerServiceTracker implements ServiceListener, IManagedJettyServerRegistry
|
||||
{
|
||||
private static Logger LOG = Log.getLogger(JettyServerServiceTracker.class.getName());
|
||||
|
||||
|
||||
/**
|
||||
* Servers indexed by PIDs. PIDs are generated by the ConfigurationAdmin
|
||||
* service.
|
||||
|
@ -86,15 +86,16 @@ public class JettyServerServiceTracker implements ServiceListener, IManagedJetty
|
|||
LOG.warn(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ev.getType() == ServiceEvent.UNREGISTERING)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// modified, meaning: we reload it. now that we stopped it;
|
||||
// we can register it.
|
||||
|
||||
if (ev.getType() == ServiceEvent.UNREGISTERING)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// modified, meaning: we reload it. now that we stopped it;
|
||||
// we can register it.
|
||||
}
|
||||
}
|
||||
case ServiceEvent.REGISTERED:
|
||||
{
|
||||
|
@ -113,7 +114,7 @@ public class JettyServerServiceTracker implements ServiceListener, IManagedJetty
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOG.warn(e);
|
||||
LOG.warn(e);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -32,8 +32,8 @@ import org.osgi.service.cm.ConfigurationException;
|
|||
import org.osgi.service.cm.ManagedServiceFactory;
|
||||
|
||||
/**
|
||||
* Manages the deployment of jetty server instances.
|
||||
* Not sure this is bringing much compared to the JettyServerServiceTracker.
|
||||
* Manages the deployment of jetty server instances. Not sure this is bringing
|
||||
* much compared to the JettyServerServiceTracker.
|
||||
*
|
||||
* @author hmalphettes
|
||||
*/
|
||||
|
@ -45,6 +45,7 @@ public class JettyServersManagedFactory implements ManagedServiceFactory, IManag
|
|||
* is the corresponding java.io.File
|
||||
*/
|
||||
public static final String JETTY_HOME = "jettyhome";
|
||||
|
||||
/** key to configure the server according to a jetty.xml file */
|
||||
public static final String JETTY_CONFIG_XML = "jettyxml";
|
||||
|
||||
|
@ -58,6 +59,7 @@ public class JettyServersManagedFactory implements ManagedServiceFactory, IManag
|
|||
* default property in jetty.xml that is used as the value of the http port.
|
||||
*/
|
||||
public static final String JETTY_HTTP_PORT = "jetty.http.port";
|
||||
|
||||
/**
|
||||
* default property in jetty.xml that is used as the value of the https
|
||||
* port.
|
||||
|
@ -65,13 +67,16 @@ public class JettyServersManagedFactory implements ManagedServiceFactory, IManag
|
|||
public static final String JETTY_HTTPS_PORT = "jetty.http.port";
|
||||
|
||||
/**
|
||||
* Servers indexed by PIDs. PIDs are generated by the ConfigurationAdmin service.
|
||||
* Servers indexed by PIDs. PIDs are generated by the ConfigurationAdmin
|
||||
* service.
|
||||
*/
|
||||
private Map<String, ServerInstanceWrapper> _serversIndexedByPID = new HashMap<String, ServerInstanceWrapper>();
|
||||
|
||||
/**
|
||||
* PID -> {@link OSGiWebappConstants#MANAGED_JETTY_SERVER_NAME}
|
||||
*/
|
||||
private Map<String, String> _serversNameIndexedByPID = new HashMap<String, String>();
|
||||
|
||||
/**
|
||||
* {@link OSGiWebappConstants#MANAGED_JETTY_SERVER_NAME} -> PID
|
||||
*/
|
||||
|
@ -89,24 +94,20 @@ public class JettyServersManagedFactory implements ManagedServiceFactory, IManag
|
|||
|
||||
public void updated(String pid, Dictionary properties) throws ConfigurationException
|
||||
{
|
||||
ServerInstanceWrapper serverInstanceWrapper = getServerByPID(pid);
|
||||
ServerInstanceWrapper serverInstanceWrapper = getServerByPID(pid);
|
||||
deleted(pid);
|
||||
// do we need to collect the currently deployed http services and
|
||||
// webapps
|
||||
// to be able to re-deploy them later?
|
||||
// probably not. simply restart and see the various service trackers
|
||||
// do everything that is needed.
|
||||
String name = (String)properties.get(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME);
|
||||
if (name == null)
|
||||
{
|
||||
throw new ConfigurationException(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME,
|
||||
"The name of the server is mandatory");
|
||||
}
|
||||
String name = (String) properties.get(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME);
|
||||
if (name == null) { throw new ConfigurationException(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, "The name of the server is mandatory"); }
|
||||
serverInstanceWrapper = new ServerInstanceWrapper(name);
|
||||
_serversIndexedByPID.put(pid, serverInstanceWrapper);
|
||||
_serversNameIndexedByPID.put(pid, name);
|
||||
_serversPIDIndexedByName.put(name, pid);
|
||||
try
|
||||
try
|
||||
{
|
||||
serverInstanceWrapper.start(new Server(), properties);
|
||||
}
|
||||
|
@ -118,21 +119,21 @@ public class JettyServersManagedFactory implements ManagedServiceFactory, IManag
|
|||
|
||||
public synchronized void deleted(String pid)
|
||||
{
|
||||
ServerInstanceWrapper server = (ServerInstanceWrapper)_serversIndexedByPID.remove(pid);
|
||||
ServerInstanceWrapper server = (ServerInstanceWrapper) _serversIndexedByPID.remove(pid);
|
||||
String name = _serversNameIndexedByPID.remove(pid);
|
||||
if (name != null)
|
||||
{
|
||||
_serversPIDIndexedByName.remove(name);
|
||||
_serversPIDIndexedByName.remove(name);
|
||||
}
|
||||
else
|
||||
{
|
||||
//something incorrect going on.
|
||||
// something incorrect going on.
|
||||
}
|
||||
if (server != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
server.stop();
|
||||
server.stop();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -143,21 +144,24 @@ public class JettyServersManagedFactory implements ManagedServiceFactory, IManag
|
|||
|
||||
public synchronized ServerInstanceWrapper getServerByPID(String pid)
|
||||
{
|
||||
return _serversIndexedByPID.get(pid);
|
||||
return _serversIndexedByPID.get(pid);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param managedServerName The server name
|
||||
* @return the corresponding jetty server wrapped with its deployment properties.
|
||||
* @return the corresponding jetty server wrapped with its deployment
|
||||
* properties.
|
||||
*/
|
||||
public ServerInstanceWrapper getServerInstanceWrapper(String managedServerName)
|
||||
public ServerInstanceWrapper getServerInstanceWrapper(String managedServerName)
|
||||
{
|
||||
String pid = _serversPIDIndexedByName.get(managedServerName);
|
||||
return pid != null ? _serversIndexedByPID.get(pid) : null;
|
||||
String pid = _serversPIDIndexedByName.get(managedServerName);
|
||||
return pid != null ? _serversIndexedByPID.get(pid) : null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper method to create and configure a new Jetty Server via the ManagedServiceFactory
|
||||
* Helper method to create and configure a new Jetty Server via the
|
||||
* ManagedServiceFactory
|
||||
*
|
||||
* @param contributor
|
||||
* @param serverName
|
||||
* @param urlsToJettyXml
|
||||
|
@ -165,50 +169,47 @@ public class JettyServersManagedFactory implements ManagedServiceFactory, IManag
|
|||
*/
|
||||
public static void createNewServer(Bundle contributor, String serverName, String urlsToJettyXml) throws Exception
|
||||
{
|
||||
ServiceReference configurationAdminReference =
|
||||
contributor.getBundleContext().getServiceReference( ConfigurationAdmin.class.getName() );
|
||||
ServiceReference configurationAdminReference = contributor.getBundleContext().getServiceReference(ConfigurationAdmin.class.getName());
|
||||
|
||||
ConfigurationAdmin confAdmin = (ConfigurationAdmin) contributor.getBundleContext()
|
||||
.getService( configurationAdminReference );
|
||||
ConfigurationAdmin confAdmin = (ConfigurationAdmin) contributor.getBundleContext().getService(configurationAdminReference);
|
||||
|
||||
Configuration configuration = confAdmin.createFactoryConfiguration(
|
||||
OSGiServerConstants.MANAGED_JETTY_SERVER_FACTORY_PID, contributor.getLocation() );
|
||||
Configuration configuration = confAdmin.createFactoryConfiguration(OSGiServerConstants.MANAGED_JETTY_SERVER_FACTORY_PID, contributor.getLocation());
|
||||
Dictionary properties = new Hashtable();
|
||||
properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, serverName);
|
||||
|
||||
|
||||
StringBuilder actualBundleUrls = new StringBuilder();
|
||||
StringTokenizer tokenizer = new StringTokenizer(urlsToJettyXml, ",", false);
|
||||
while (tokenizer.hasMoreTokens())
|
||||
{
|
||||
if (actualBundleUrls.length() != 0)
|
||||
{
|
||||
actualBundleUrls.append(",");
|
||||
}
|
||||
String token = tokenizer.nextToken();
|
||||
if (token.indexOf(':') != -1)
|
||||
{
|
||||
//a complete url. no change needed:
|
||||
actualBundleUrls.append(token);
|
||||
}
|
||||
else if (token.startsWith("/"))
|
||||
{
|
||||
//url relative to the contributor bundle:
|
||||
URL url = contributor.getEntry(token);
|
||||
if (url == null)
|
||||
{
|
||||
actualBundleUrls.append(token);
|
||||
}
|
||||
else
|
||||
{
|
||||
actualBundleUrls.append(url.toString());
|
||||
}
|
||||
}
|
||||
|
||||
if (actualBundleUrls.length() != 0)
|
||||
{
|
||||
actualBundleUrls.append(",");
|
||||
}
|
||||
String token = tokenizer.nextToken();
|
||||
if (token.indexOf(':') != -1)
|
||||
{
|
||||
// a complete url. no change needed:
|
||||
actualBundleUrls.append(token);
|
||||
}
|
||||
else if (token.startsWith("/"))
|
||||
{
|
||||
// url relative to the contributor bundle:
|
||||
URL url = contributor.getEntry(token);
|
||||
if (url == null)
|
||||
{
|
||||
actualBundleUrls.append(token);
|
||||
}
|
||||
else
|
||||
{
|
||||
actualBundleUrls.append(url.toString());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
properties.put(OSGiServerConstants.MANAGED_JETTY_XML_CONFIG_URLS, actualBundleUrls.toString());
|
||||
configuration.update(properties);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -185,8 +185,7 @@ public class ServerInstanceWrapper
|
|||
{
|
||||
Thread.currentThread().setContextClassLoader(contextCl);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void stop()
|
||||
|
|
|
@ -20,70 +20,65 @@ import org.eclipse.jetty.webapp.WebAppContext;
|
|||
import org.osgi.framework.Bundle;
|
||||
|
||||
/**
|
||||
* Internal interface for the class that deploys a webapp on a server.
|
||||
* Used as we migrate from the single instance of the jety server to multiple jetty servers.
|
||||
* Internal interface for the class that deploys a webapp on a server. Used as
|
||||
* we migrate from the single instance of the jety server to multiple jetty
|
||||
* servers.
|
||||
*/
|
||||
public interface IWebBundleDeployerHelper {
|
||||
public interface IWebBundleDeployerHelper
|
||||
{
|
||||
|
||||
/** when this property is present, the type of context handler registered is not
|
||||
* known in advance. */
|
||||
/**
|
||||
* when this property is present, the type of context handler registered is
|
||||
* not known in advance.
|
||||
*/
|
||||
public static final String INTERNAL_SERVICE_PROP_UNKNOWN_CONTEXT_HANDLER_TYPE = "unknownContextHandlerType";
|
||||
|
||||
|
||||
/**
|
||||
* Deploy a new web application on the jetty server.
|
||||
*
|
||||
* @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.
|
||||
* @param webXmlPath
|
||||
* @param defaultWebXmlPath
|
||||
* TODO: parameter description
|
||||
* @return The contexthandler created and started
|
||||
* @throws Exception
|
||||
*/
|
||||
public abstract WebAppContext registerWebapplication(Bundle bundle,
|
||||
String webappFolderPath, String contextPath, String extraClasspath,
|
||||
String overrideBundleInstallLocation,
|
||||
String requireTldBundle, String webXmlPath,
|
||||
String defaultWebXmlPath, WebAppContext webAppContext) throws Exception;
|
||||
/**
|
||||
* Deploy a new web application on the jetty server.
|
||||
*
|
||||
* @param bundle The bundle
|
||||
* @param webappFolderPath The path to the root of the webapp. Must be a
|
||||
* path relative to bundle; either an absolute path.
|
||||
* @param contextPath The context path. Must start with "/"
|
||||
* @param extraClasspath
|
||||
* @param overrideBundleInstallLocation
|
||||
* @param requireTldBundle The list of bundles's symbolic names that contain
|
||||
* tld files that are required by this WAB.
|
||||
* @param webXmlPath
|
||||
* @param defaultWebXmlPath TODO: parameter description
|
||||
* @return The contexthandler created and started
|
||||
* @throws Exception
|
||||
*/
|
||||
public abstract WebAppContext registerWebapplication(Bundle bundle, String webappFolderPath, String contextPath, String extraClasspath,
|
||||
String overrideBundleInstallLocation, String requireTldBundle, String webXmlPath,
|
||||
String defaultWebXmlPath, WebAppContext webAppContext) throws Exception;
|
||||
|
||||
/**
|
||||
* Stop a ContextHandler and remove it from the collection.
|
||||
*
|
||||
* @see ContextDeployer#undeploy
|
||||
* @param contextHandler
|
||||
* @throws Exception
|
||||
*/
|
||||
public abstract void unregister(ContextHandler contextHandler)
|
||||
throws Exception;
|
||||
/**
|
||||
* Stop a ContextHandler and remove it from the collection.
|
||||
*
|
||||
* @see ContextDeployer#undeploy
|
||||
* @param contextHandler
|
||||
* @throws Exception
|
||||
*/
|
||||
public abstract void unregister(ContextHandler contextHandler) throws Exception;
|
||||
|
||||
/**
|
||||
* This type of registration relies on jetty's complete context xml file.
|
||||
* Context encompasses jndi and all other things. This makes the definition
|
||||
* of the webapp a lot more self-contained.
|
||||
*
|
||||
* @param contributor
|
||||
* @param contextFileRelativePath
|
||||
* @param extraClasspath
|
||||
* @param overrideBundleInstallLocation
|
||||
* @param requireTldBundle The list of bundles'symbolic name that contain tld files for this webapp.
|
||||
* @param handler the context handler passed in the server
|
||||
* reference that will be configured, deployed and started.
|
||||
* @return The contexthandler created and started
|
||||
* @throws Exception
|
||||
*/
|
||||
public abstract ContextHandler registerContext(Bundle contributor,
|
||||
String contextFileRelativePath, String extraClasspath,
|
||||
String overrideBundleInstallLocation, String requireTldBundle,
|
||||
ContextHandler handler) throws Exception;
|
||||
/**
|
||||
* This type of registration relies on jetty's complete context xml file.
|
||||
* Context encompasses jndi and all other things. This makes the definition
|
||||
* of the webapp a lot more self-contained.
|
||||
*
|
||||
* @param contributor
|
||||
* @param contextFileRelativePath
|
||||
* @param extraClasspath
|
||||
* @param overrideBundleInstallLocation
|
||||
* @param requireTldBundle The list of bundles'symbolic name that contain
|
||||
* tld files for this webapp.
|
||||
* @param handler the context handler passed in the server reference that
|
||||
* will be configured, deployed and started.
|
||||
* @return The contexthandler created and started
|
||||
* @throws Exception
|
||||
*/
|
||||
public abstract ContextHandler registerContext(Bundle contributor, String contextFileRelativePath, String extraClasspath,
|
||||
String overrideBundleInstallLocation, String requireTldBundle, ContextHandler handler) throws Exception;
|
||||
|
||||
}
|
|
@ -55,7 +55,7 @@ import org.osgi.framework.ServiceReference;
|
|||
public class JettyContextHandlerServiceTracker implements ServiceListener
|
||||
{
|
||||
private static Logger __logger = Log.getLogger(WebBundleDeployerHelper.class.getName());
|
||||
|
||||
|
||||
/** New style: ability to manage multiple jetty instances */
|
||||
private final IManagedJettyServerRegistry _registry;
|
||||
|
||||
|
|
|
@ -92,22 +92,18 @@ public class LibExtClassLoaderHelper
|
|||
* is the JettyBootStrapper (an osgi classloader.
|
||||
* @throws MalformedURLException
|
||||
*/
|
||||
public static ClassLoader createLibEtcClassLoader(File jettyHome, Server server,
|
||||
ClassLoader parentClassLoader) throws MalformedURLException
|
||||
public static ClassLoader createLibEtcClassLoader(File jettyHome, Server server, ClassLoader parentClassLoader) throws MalformedURLException
|
||||
{
|
||||
if (jettyHome == null)
|
||||
{
|
||||
return parentClassLoader;
|
||||
}
|
||||
if (jettyHome == null) { return parentClassLoader; }
|
||||
ArrayList<URL> urls = new ArrayList<URL>();
|
||||
File jettyResources = new File(jettyHome,"resources");
|
||||
File jettyResources = new File(jettyHome, "resources");
|
||||
if (jettyResources.exists())
|
||||
{
|
||||
// make sure it contains something else than README:
|
||||
Map<String, File> jettyResFiles = new HashMap<String, File>();
|
||||
for (File f : jettyResources.listFiles())
|
||||
{
|
||||
jettyResFiles.put(f.getName(),f);
|
||||
jettyResFiles.put(f.getName(), f);
|
||||
if (f.getName().toLowerCase().startsWith("readme"))
|
||||
{
|
||||
continue;
|
||||
|
@ -120,9 +116,9 @@ public class LibExtClassLoaderHelper
|
|||
}
|
||||
}
|
||||
}
|
||||
processFilesInResourcesFolder(jettyHome,jettyResFiles);
|
||||
processFilesInResourcesFolder(jettyHome, jettyResFiles);
|
||||
}
|
||||
File libExt = new File(jettyHome,"lib/ext");
|
||||
File libExt = new File(jettyHome, "lib/ext");
|
||||
if (libExt.exists())
|
||||
{
|
||||
for (File f : libExt.listFiles())
|
||||
|
@ -140,55 +136,50 @@ public class LibExtClassLoaderHelper
|
|||
}
|
||||
}
|
||||
|
||||
return new URLClassLoader(urls.toArray(new URL[urls.size()]),parentClassLoader);
|
||||
return new URLClassLoader(urls.toArray(new URL[urls.size()]), parentClassLoader);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param server
|
||||
* @return a url classloader with the jars of resources, lib/ext and the
|
||||
* jars passed in the other argument. The parent classloader usually
|
||||
* is the JettyBootStrapper (an osgi classloader).
|
||||
* If there was no extra jars to insert, then just return the parentClassLoader.
|
||||
* is the JettyBootStrapper (an osgi classloader). If there was no
|
||||
* extra jars to insert, then just return the parentClassLoader.
|
||||
* @throws MalformedURLException
|
||||
*/
|
||||
public static ClassLoader createLibExtClassLoader(List<File> jarsContainerOrJars,
|
||||
List<URL> otherJarsOrFolder, Server server,
|
||||
ClassLoader parentClassLoader) throws MalformedURLException
|
||||
public static ClassLoader createLibExtClassLoader(List<File> jarsContainerOrJars, List<URL> otherJarsOrFolder, Server server, ClassLoader parentClassLoader) throws MalformedURLException
|
||||
{
|
||||
if (jarsContainerOrJars == null && otherJarsOrFolder == null)
|
||||
{
|
||||
return parentClassLoader;
|
||||
}
|
||||
List<URL> urls = new ArrayList<URL>();
|
||||
if (otherJarsOrFolder != null)
|
||||
{
|
||||
urls.addAll(otherJarsOrFolder);
|
||||
}
|
||||
if (jarsContainerOrJars != null)
|
||||
{
|
||||
for (File libExt : jarsContainerOrJars)
|
||||
{
|
||||
if (libExt.isDirectory())
|
||||
{
|
||||
for (File f : libExt.listFiles())
|
||||
{
|
||||
if (f.getName().endsWith(".jar"))
|
||||
{
|
||||
// cheap to tolerate folders so let's do it.
|
||||
URL url = f.toURI().toURL();
|
||||
if (f.isFile())
|
||||
{// is this necessary anyways?
|
||||
url = new URL("jar:" + url.toString() + "!/");
|
||||
}
|
||||
urls.add(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return new URLClassLoader(urls.toArray(new URL[urls.size()]),parentClassLoader);
|
||||
if (jarsContainerOrJars == null && otherJarsOrFolder == null) { return parentClassLoader; }
|
||||
List<URL> urls = new ArrayList<URL>();
|
||||
if (otherJarsOrFolder != null)
|
||||
{
|
||||
urls.addAll(otherJarsOrFolder);
|
||||
}
|
||||
if (jarsContainerOrJars != null)
|
||||
{
|
||||
for (File libExt : jarsContainerOrJars)
|
||||
{
|
||||
if (libExt.isDirectory())
|
||||
{
|
||||
for (File f : libExt.listFiles())
|
||||
{
|
||||
if (f.getName().endsWith(".jar"))
|
||||
{
|
||||
// cheap to tolerate folders so let's do it.
|
||||
URL url = f.toURI().toURL();
|
||||
if (f.isFile())
|
||||
{// is this necessary anyways?
|
||||
url = new URL("jar:" + url.toString() + "!/");
|
||||
}
|
||||
urls.add(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return new URLClassLoader(urls.toArray(new URL[urls.size()]), parentClassLoader);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* When we find files typically used for central logging configuration we do
|
||||
* what it takes in this method to do what the user expects. Without
|
||||
|
@ -207,7 +198,7 @@ public class LibExtClassLoaderHelper
|
|||
{
|
||||
for (IFilesInJettyHomeResourcesProcessor processor : registeredFilesInJettyHomeResourcesProcessors)
|
||||
{
|
||||
processor.processFilesInResourcesFolder(jettyHome,childrenFiles);
|
||||
processor.processFilesInResourcesFolder(jettyHome, childrenFiles);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -55,12 +55,12 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe
|
|||
|
||||
public static void addClassThatIdentifiesAJarThatMustBeRejected(Class<?> zclass)
|
||||
{
|
||||
JAR_WITH_SUCH_CLASS_MUST_BE_EXCLUDED.add(zclass.getName().replace('.','/') + ".class");
|
||||
JAR_WITH_SUCH_CLASS_MUST_BE_EXCLUDED.add(zclass.getName().replace('.', '/') + ".class");
|
||||
}
|
||||
|
||||
public static void addClassThatIdentifiesAJarThatMustBeRejected(String zclassName)
|
||||
{
|
||||
JAR_WITH_SUCH_CLASS_MUST_BE_EXCLUDED.add(zclassName.replace('.','/') + ".class");
|
||||
JAR_WITH_SUCH_CLASS_MUST_BE_EXCLUDED.add(zclassName.replace('.', '/') + ".class");
|
||||
}
|
||||
|
||||
static
|
||||
|
@ -69,34 +69,37 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe
|
|||
}
|
||||
|
||||
private ClassLoader _osgiBundleClassLoader;
|
||||
|
||||
private Bundle _contributor;
|
||||
|
||||
private boolean _lookInOsgiFirst = true;
|
||||
|
||||
private Set<String> _libsAlreadyInManifest = new HashSet<String>();
|
||||
|
||||
/**
|
||||
* @param parent The parent classloader. In this case
|
||||
* @param parent The parent classloader. In this case
|
||||
* @param context The WebAppContext
|
||||
* @param contributor The bundle that defines this web-application.
|
||||
* @throws IOException
|
||||
*/
|
||||
public OSGiWebappClassLoader(ClassLoader parent, WebAppContext context, Bundle contributor,
|
||||
BundleClassLoaderHelper bundleClassLoaderHelper) throws IOException
|
||||
public OSGiWebappClassLoader(ClassLoader parent, WebAppContext context, Bundle contributor, BundleClassLoaderHelper bundleClassLoaderHelper)
|
||||
throws IOException
|
||||
{
|
||||
super(parent,context);
|
||||
super(parent, context);
|
||||
_contributor = contributor;
|
||||
_osgiBundleClassLoader = bundleClassLoaderHelper.getBundleClassLoader(contributor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>Bundle</code> that defined this web-application.
|
||||
*
|
||||
* @return The <code>Bundle</code> object associated with this
|
||||
* <code>BundleReference</code>.
|
||||
*/
|
||||
public Bundle getBundle()
|
||||
{
|
||||
return _contributor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>Bundle</code> that defined this web-application.
|
||||
*
|
||||
* @return The <code>Bundle</code> object associated with this
|
||||
* <code>BundleReference</code>.
|
||||
*/
|
||||
public Bundle getBundle()
|
||||
{
|
||||
return _contributor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the manifest. If the manifest is already configured to loads a few
|
||||
|
@ -123,7 +126,7 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe
|
|||
return Collections.enumeration(toList(urls, osgiUrls));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public URL getResource(String name)
|
||||
{
|
||||
|
@ -132,37 +135,37 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe
|
|||
URL url = _osgiBundleClassLoader.getResource(name);
|
||||
return url != null ? url : super.getResource(name);
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
URL url = super.getResource(name);
|
||||
return url != null ? url : _osgiBundleClassLoader.getResource(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private List<URL> toList(Enumeration<URL> e, Enumeration<URL> e2)
|
||||
{
|
||||
List<URL> list = new ArrayList<URL>();
|
||||
while (e!=null && e.hasMoreElements())
|
||||
while (e != null && e.hasMoreElements())
|
||||
list.add(e.nextElement());
|
||||
while (e2!=null && e2.hasMoreElements())
|
||||
while (e2 != null && e2.hasMoreElements())
|
||||
list.add(e2.nextElement());
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
*
|
||||
*/
|
||||
protected Class<?> findClass(String name) throws ClassNotFoundException
|
||||
{
|
||||
try
|
||||
{
|
||||
return _lookInOsgiFirst?_osgiBundleClassLoader.loadClass(name):super.findClass(name);
|
||||
return _lookInOsgiFirst ? _osgiBundleClassLoader.loadClass(name) : super.findClass(name);
|
||||
}
|
||||
catch (ClassNotFoundException cne)
|
||||
{
|
||||
try
|
||||
{
|
||||
return _lookInOsgiFirst?super.findClass(name):_osgiBundleClassLoader.loadClass(name);
|
||||
return _lookInOsgiFirst ? super.findClass(name) : _osgiBundleClassLoader.loadClass(name);
|
||||
}
|
||||
catch (ClassNotFoundException cne2)
|
||||
{
|
||||
|
@ -179,7 +182,7 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe
|
|||
public void addClassPath(String classPath) throws IOException
|
||||
{
|
||||
|
||||
StringTokenizer tokenizer = new StringTokenizer(classPath,",;");
|
||||
StringTokenizer tokenizer = new StringTokenizer(classPath, ",;");
|
||||
while (tokenizer.hasMoreTokens())
|
||||
{
|
||||
String path = tokenizer.nextToken();
|
||||
|
@ -187,7 +190,7 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe
|
|||
|
||||
// Resolve file path if possible
|
||||
File file = resource.getFile();
|
||||
if (file != null && isAcceptableLibrary(file,JAR_WITH_SUCH_CLASS_MUST_BE_EXCLUDED))
|
||||
if (file != null && isAcceptableLibrary(file, JAR_WITH_SUCH_CLASS_MUST_BE_EXCLUDED))
|
||||
{
|
||||
super.addClassPath(path);
|
||||
}
|
||||
|
@ -211,10 +214,7 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe
|
|||
{
|
||||
for (String criteria : pathToClassFiles)
|
||||
{
|
||||
if (new File(file,criteria).exists())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (new File(file, criteria).exists()) { return false; }
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -225,22 +225,18 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe
|
|||
jar = new JarFile(file);
|
||||
for (String criteria : pathToClassFiles)
|
||||
{
|
||||
if (jar.getEntry(criteria) != null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (jar.getEntry(criteria) != null) { return false; }
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (jar != null)
|
||||
try
|
||||
{
|
||||
jar.close();
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
}
|
||||
if (jar != null) try
|
||||
{
|
||||
jar.close();
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -270,7 +266,7 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe
|
|||
_contextField = WebAppClassLoader.class.getDeclaredField("_context");
|
||||
_contextField.setAccessible(true);
|
||||
}
|
||||
_contextField.set(this,webappContext);
|
||||
_contextField.set(this, webappContext);
|
||||
if (webappContext.getExtraClasspath() != null)
|
||||
{
|
||||
addClassPath(webappContext.getExtraClasspath());
|
||||
|
|
|
@ -168,7 +168,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
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 webapp = null;
|
||||
|
@ -199,16 +199,16 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
}
|
||||
if (baseWebappInstallURL == null && (webapp == null || !webapp.exists())) { throw new IllegalArgumentException(
|
||||
"Unable to locate " + webappFolderPath
|
||||
+ " inside "
|
||||
+ (bundleInstall != null ? bundleInstall.getAbsolutePath() : "unlocated bundle '" + bundle.getSymbolicName()
|
||||
+ "'")); }
|
||||
+ " 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);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
|
@ -222,18 +222,18 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
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
|
||||
{
|
||||
|
||||
|
||||
//apply any META-INF/context.xml file that is found to configure the webapp first
|
||||
applyMetaInfContextXml (contributor, context);
|
||||
|
||||
|
||||
// apply any META-INF/context.xml file that is found to configure
|
||||
// the webapp first
|
||||
applyMetaInfContextXml(contributor, context);
|
||||
|
||||
// make sure we provide access to all the jetty bundles by going
|
||||
// through this bundle.
|
||||
OSGiWebappClassLoader composite = createWebappClassLoader(contributor);
|
||||
|
@ -241,10 +241,10 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
// classes
|
||||
// that the contributor gives access to.
|
||||
Thread.currentThread().setContextClassLoader(composite);
|
||||
|
||||
//converts bundleentry: protocol
|
||||
|
||||
// converts bundleentry: protocol
|
||||
baseWebappInstallURL = DefaultFileLocatorHelper.getLocalURL(baseWebappInstallURL);
|
||||
|
||||
|
||||
context.setWar(baseWebappInstallURL.toString());
|
||||
context.setContextPath(contextPath);
|
||||
context.setExtraClasspath(extraClasspath);
|
||||
|
@ -342,7 +342,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
Thread.currentThread().setContextClassLoader(contextCl);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
|
@ -366,7 +366,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
*/
|
||||
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)
|
||||
{
|
||||
|
@ -404,7 +404,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
+ contributor.getSymbolicName()
|
||||
+ (overrideBundleInstallLocation != null ? " using the install location " + overrideBundleInstallLocation : ""));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This type of registration relies on jetty's complete context xml file.
|
||||
|
@ -418,7 +418,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
*/
|
||||
private ContextHandler registerContext(Bundle contributor, String pathInBundle, File contextFile, String extraClasspath,
|
||||
String overrideBundleInstallLocation, String requireTldBundle, ContextHandler handler) throws Exception
|
||||
{
|
||||
{
|
||||
InputStream contextFileInputStream = null;
|
||||
try
|
||||
{
|
||||
|
@ -429,7 +429,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
{
|
||||
IO.close(contextFileInputStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param contributor
|
||||
|
@ -440,7 +440,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
*/
|
||||
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;
|
||||
WebAppContext webAppContext = null;
|
||||
|
@ -455,9 +455,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
Thread.currentThread().setContextClassLoader(composite);
|
||||
ContextHandler context = createContextHandler(handler, contributor, contextFileInputStream, extraClasspath, overrideBundleInstallLocation,
|
||||
requireTldBundle);
|
||||
if (context == null)
|
||||
{
|
||||
return null;// did not happen
|
||||
if (context == null) { return null;// did not happen
|
||||
}
|
||||
|
||||
// ok now register this webapp. we checked when we started jetty
|
||||
|
@ -487,7 +485,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
Thread.currentThread().setContextClassLoader(contextCl);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the properties of WebAppDeployer as defined in jetty.xml.
|
||||
|
@ -810,28 +808,23 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
return webappClassLoader;
|
||||
}
|
||||
|
||||
|
||||
protected void applyMetaInfContextXml (Bundle bundle, ContextHandler contextHandler)
|
||||
throws Exception
|
||||
protected void applyMetaInfContextXml(Bundle bundle, ContextHandler contextHandler) throws Exception
|
||||
{
|
||||
if (bundle == null)
|
||||
return;
|
||||
if (contextHandler == null)
|
||||
return;
|
||||
if (bundle == null) return;
|
||||
if (contextHandler == null) return;
|
||||
|
||||
ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
||||
__logger.info("Context classloader = "+cl);
|
||||
__logger.info("Context classloader = " + cl);
|
||||
try
|
||||
{
|
||||
Thread.currentThread().setContextClassLoader(_wrapper.getParentClassLoaderForWebapps());
|
||||
|
||||
//find if there is a META-INF/context.xml file
|
||||
// find if there is a META-INF/context.xml file
|
||||
URL contextXmlUrl = bundle.getEntry("/META-INF/jetty-webapp-context.xml");
|
||||
if (contextXmlUrl == null)
|
||||
return;
|
||||
if (contextXmlUrl == null) return;
|
||||
|
||||
//Apply it just as the standard jetty ContextProvider would do
|
||||
__logger.info("Applying "+contextXmlUrl+" to "+contextHandler);
|
||||
// Apply it just as the standard jetty ContextProvider would do
|
||||
__logger.info("Applying " + contextXmlUrl + " to " + contextHandler);
|
||||
|
||||
XmlConfiguration xmlConfiguration = new XmlConfiguration(contextXmlUrl);
|
||||
HashMap properties = new HashMap();
|
||||
|
@ -844,9 +837,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
Thread.currentThread().setContextClassLoader(cl);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set the property "this.bundle.install" to point to the location
|
||||
* of the bundle. Useful when <SystemProperty name="this.bundle.home"/> is
|
||||
|
@ -883,11 +874,10 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
+ "' specified in the "
|
||||
+ OSGiWebappConstants.REQUIRE_TLD_BUNDLE
|
||||
+ " of the manifest of "
|
||||
+ (bundle==null?"unknown":bundle.getSymbolicName())); }
|
||||
+ (bundle == null ? "unknown" : bundle.getSymbolicName())); }
|
||||
|
||||
File f = fileLocatorHelper.getBundleInstallLocation(bs[0]);
|
||||
if (paths.length() > 0)
|
||||
paths.append(", ");
|
||||
if (paths.length() > 0) paths.append(", ");
|
||||
__logger.debug("getPathsToRequiredBundles: bundle path=" + bs[0].getLocation() + " uri=" + f.toURI());
|
||||
paths.append(f.toURI().toURL().toString());
|
||||
}
|
||||
|
|
|
@ -167,7 +167,8 @@ public class WebBundleTrackerCustomizer implements BundleTrackerCustomizer
|
|||
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.
|
||||
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)
|
||||
|
@ -199,9 +200,10 @@ 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)
|
||||
{
|
||||
return false;// no webapp in here
|
||||
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
|
||||
// jars directly available
|
||||
|
@ -220,7 +222,8 @@ public class WebBundleTrackerCustomizer implements BundleTrackerCustomizer
|
|||
catch (Throwable e)
|
||||
{
|
||||
LOG.warn(e);
|
||||
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.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,6 @@ public interface BundleFileLocatorHelper
|
|||
/** The default instance supports felix and equinox */
|
||||
public static BundleFileLocatorHelper DEFAULT = new DefaultFileLocatorHelper();
|
||||
|
||||
|
||||
/**
|
||||
* Works with equinox, felix, nuxeo and probably more. Not exactly in the
|
||||
* spirit of OSGi but quite necessary to support self-contained webapps and
|
||||
|
@ -43,8 +42,7 @@ public interface BundleFileLocatorHelper
|
|||
* Currently only works with bundles that are not jar.
|
||||
* </p>
|
||||
*
|
||||
* @param bundle
|
||||
* The bundle
|
||||
* @param bundle The bundle
|
||||
* @return Its installation location as a file.
|
||||
* @throws Exception
|
||||
*/
|
||||
|
@ -75,16 +73,15 @@ public interface BundleFileLocatorHelper
|
|||
* embedded inside it.
|
||||
*/
|
||||
public File[] locateJarsInsideBundle(Bundle bundle) throws Exception;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Helper method equivalent to Bundle#getEntry(String entryPath) except that
|
||||
* it searches for entries in the fragments by using the findEntries method.
|
||||
*
|
||||
* @param bundle
|
||||
* @param entryPath
|
||||
* @return null or all the entries found for that path.
|
||||
*/
|
||||
public Enumeration<URL> findEntries(Bundle bundle, String entryPath);
|
||||
* Helper method equivalent to Bundle#getEntry(String entryPath) except that
|
||||
* it searches for entries in the fragments by using the findEntries method.
|
||||
*
|
||||
* @param bundle
|
||||
* @param entryPath
|
||||
* @return null or all the entries found for that path.
|
||||
*/
|
||||
public Enumeration<URL> findEntries(Bundle bundle, String entryPath);
|
||||
|
||||
}
|
||||
|
|
|
@ -29,7 +29,9 @@ public class DefaultBundleClassLoaderHelper implements BundleClassLoaderHelper
|
|||
{
|
||||
|
||||
private static boolean identifiedOsgiImpl = false;
|
||||
|
||||
private static boolean isEquinox = false;
|
||||
|
||||
private static boolean isFelix = false;
|
||||
|
||||
private static void init(Bundle bundle)
|
||||
|
@ -66,10 +68,10 @@ public class DefaultBundleClassLoaderHelper implements BundleClassLoaderHelper
|
|||
*/
|
||||
public ClassLoader getBundleClassLoader(Bundle bundle)
|
||||
{
|
||||
String bundleActivator = (String)bundle.getHeaders().get("Bundle-Activator");
|
||||
String bundleActivator = (String) bundle.getHeaders().get("Bundle-Activator");
|
||||
if (bundleActivator == null)
|
||||
{
|
||||
bundleActivator = (String)bundle.getHeaders().get("Jetty-ClassInBundle");
|
||||
bundleActivator = (String) bundle.getHeaders().get("Jetty-ClassInBundle");
|
||||
}
|
||||
if (bundleActivator != null)
|
||||
{
|
||||
|
@ -93,14 +95,12 @@ public class DefaultBundleClassLoaderHelper implements BundleClassLoaderHelper
|
|||
{
|
||||
return internalGetEquinoxBundleClassLoader(bundle);
|
||||
}
|
||||
else if (isFelix)
|
||||
{
|
||||
return internalGetFelixBundleClassLoader(bundle);
|
||||
}
|
||||
else if (isFelix) { return internalGetFelixBundleClassLoader(bundle); }
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Method Equinox_BundleHost_getBundleLoader_method;
|
||||
|
||||
private static Method Equinox_BundleLoader_createClassLoader_method;
|
||||
|
||||
private static ClassLoader internalGetEquinoxBundleClassLoader(Bundle bundle)
|
||||
|
@ -111,17 +111,18 @@ public class DefaultBundleClassLoaderHelper implements BundleClassLoaderHelper
|
|||
if (Equinox_BundleHost_getBundleLoader_method == null)
|
||||
{
|
||||
Equinox_BundleHost_getBundleLoader_method = bundle.getClass().getClassLoader().loadClass("org.eclipse.osgi.framework.internal.core.BundleHost")
|
||||
.getDeclaredMethod("getBundleLoader",new Class[] {});
|
||||
.getDeclaredMethod("getBundleLoader", new Class[] {});
|
||||
Equinox_BundleHost_getBundleLoader_method.setAccessible(true);
|
||||
}
|
||||
Object bundleLoader = Equinox_BundleHost_getBundleLoader_method.invoke(bundle,new Object[] {});
|
||||
Object bundleLoader = Equinox_BundleHost_getBundleLoader_method.invoke(bundle, new Object[] {});
|
||||
if (Equinox_BundleLoader_createClassLoader_method == null && bundleLoader != null)
|
||||
{
|
||||
Equinox_BundleLoader_createClassLoader_method = bundleLoader.getClass().getClassLoader().loadClass(
|
||||
"org.eclipse.osgi.internal.loader.BundleLoader").getDeclaredMethod("createClassLoader",new Class[] {});
|
||||
Equinox_BundleLoader_createClassLoader_method = bundleLoader.getClass().getClassLoader()
|
||||
.loadClass("org.eclipse.osgi.internal.loader.BundleLoader")
|
||||
.getDeclaredMethod("createClassLoader", new Class[] {});
|
||||
Equinox_BundleLoader_createClassLoader_method.setAccessible(true);
|
||||
}
|
||||
return (ClassLoader)Equinox_BundleLoader_createClassLoader_method.invoke(bundleLoader,new Object[] {});
|
||||
return (ClassLoader) Equinox_BundleLoader_createClassLoader_method.invoke(bundleLoader, new Object[] {});
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
|
@ -131,6 +132,7 @@ public class DefaultBundleClassLoaderHelper implements BundleClassLoaderHelper
|
|||
}
|
||||
|
||||
private static Field Felix_BundleImpl_m_modules_field;
|
||||
|
||||
private static Field Felix_ModuleImpl_m_classLoader_field;
|
||||
|
||||
private static ClassLoader internalGetFelixBundleClassLoader(Bundle bundle)
|
||||
|
@ -142,8 +144,8 @@ public class DefaultBundleClassLoaderHelper implements BundleClassLoaderHelper
|
|||
// and return the private field m_classLoader of ModuleImpl
|
||||
if (Felix_BundleImpl_m_modules_field == null)
|
||||
{
|
||||
Felix_BundleImpl_m_modules_field = bundle.getClass().getClassLoader().loadClass("org.apache.felix.framework.BundleImpl").getDeclaredField(
|
||||
"m_modules");
|
||||
Felix_BundleImpl_m_modules_field = bundle.getClass().getClassLoader().loadClass("org.apache.felix.framework.BundleImpl")
|
||||
.getDeclaredField("m_modules");
|
||||
Felix_BundleImpl_m_modules_field.setAccessible(true);
|
||||
}
|
||||
|
||||
|
@ -151,26 +153,26 @@ public class DefaultBundleClassLoaderHelper implements BundleClassLoaderHelper
|
|||
Object currentModuleImpl;
|
||||
try
|
||||
{
|
||||
Object[] moduleArray = (Object[])Felix_BundleImpl_m_modules_field.get(bundle);
|
||||
Object[] moduleArray = (Object[]) Felix_BundleImpl_m_modules_field.get(bundle);
|
||||
currentModuleImpl = moduleArray[moduleArray.length - 1];
|
||||
}
|
||||
catch (Throwable t2)
|
||||
{
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Object> moduleArray = (List<Object>)Felix_BundleImpl_m_modules_field.get(bundle);
|
||||
List<Object> moduleArray = (List<Object>) Felix_BundleImpl_m_modules_field.get(bundle);
|
||||
currentModuleImpl = moduleArray.get(moduleArray.size() - 1);
|
||||
}
|
||||
|
||||
|
||||
if (Felix_ModuleImpl_m_classLoader_field == null && currentModuleImpl != null)
|
||||
{
|
||||
Felix_ModuleImpl_m_classLoader_field = bundle.getClass().getClassLoader().loadClass("org.apache.felix.framework.ModuleImpl").getDeclaredField(
|
||||
"m_classLoader");
|
||||
Felix_ModuleImpl_m_classLoader_field = bundle.getClass().getClassLoader().loadClass("org.apache.felix.framework.ModuleImpl")
|
||||
.getDeclaredField("m_classLoader");
|
||||
Felix_ModuleImpl_m_classLoader_field.setAccessible(true);
|
||||
}
|
||||
// first make sure that the classloader is ready:
|
||||
// the m_classLoader field must be initialized by the
|
||||
// ModuleImpl.getClassLoader() private method.
|
||||
ClassLoader cl = (ClassLoader)Felix_ModuleImpl_m_classLoader_field.get(currentModuleImpl);
|
||||
ClassLoader cl = (ClassLoader) Felix_ModuleImpl_m_classLoader_field.get(currentModuleImpl);
|
||||
if (cl == null)
|
||||
{
|
||||
// looks like it was not ready:
|
||||
|
@ -178,7 +180,7 @@ public class DefaultBundleClassLoaderHelper implements BundleClassLoaderHelper
|
|||
// ModuleImpl.getClassLoader() private method.
|
||||
// this call will do that.
|
||||
bundle.loadClass("java.lang.Object");
|
||||
cl = (ClassLoader)Felix_ModuleImpl_m_classLoader_field.get(currentModuleImpl);
|
||||
cl = (ClassLoader) Felix_ModuleImpl_m_classLoader_field.get(currentModuleImpl);
|
||||
// System.err.println("Got the bundle class loader of felix_: "
|
||||
// + cl);
|
||||
return cl;
|
||||
|
|
|
@ -69,7 +69,7 @@ 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");
|
||||
|
||||
|
||||
if (url.getProtocol().equals("file"))
|
||||
{
|
||||
// some osgi frameworks do use the file protocole directly in some
|
||||
|
@ -84,7 +84,12 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper
|
|||
// the File
|
||||
|
||||
URLConnection con = url.openConnection();
|
||||
con.setUseCaches(Resource.getDefaultUseCaches()); //work around problems where url connections cache references to jars
|
||||
con.setUseCaches(Resource.getDefaultUseCaches()); // work around
|
||||
// problems where
|
||||
// url connections
|
||||
// cache
|
||||
// references to
|
||||
// jars
|
||||
|
||||
if (BUNDLE_ENTRY_FIELD == null)
|
||||
{
|
||||
|
@ -105,10 +110,10 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper
|
|||
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");
|
||||
|
@ -151,20 +156,18 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper
|
|||
// 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()));
|
||||
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;
|
||||
}
|
||||
|
@ -194,15 +197,12 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper
|
|||
}
|
||||
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 ")
|
||||
+ ")");
|
||||
}
|
||||
if (!webapp.exists()) { throw new IllegalArgumentException("Unable to locate " + path
|
||||
+ " inside "
|
||||
+ bundle.getSymbolicName()
|
||||
+ " ("
|
||||
+ (bundleInstall != null ? bundleInstall.getAbsolutePath() : " no_bundle_location ")
|
||||
+ ")"); }
|
||||
return webapp;
|
||||
}
|
||||
|
||||
|
@ -301,7 +301,7 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper
|
|||
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"))
|
||||
.equals("org.eclipse.osgi.framework.internal.core.BundleURLConnection"))
|
||||
{
|
||||
BUNDLE_URL_CONNECTION_getLocalURL = conn.getClass().getMethod("getLocalURL", null);
|
||||
BUNDLE_URL_CONNECTION_getLocalURL.setAccessible(true);
|
||||
|
@ -338,7 +338,7 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper
|
|||
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"))
|
||||
.equals("org.eclipse.osgi.framework.internal.core.BundleURLConnection"))
|
||||
{
|
||||
BUNDLE_URL_CONNECTION_getFileURL = conn.getClass().getMethod("getFileURL", null);
|
||||
BUNDLE_URL_CONNECTION_getFileURL.setAccessible(true);
|
||||
|
|
|
@ -37,10 +37,15 @@ public class PackageAdminServiceTracker implements ServiceListener
|
|||
private BundleContext _context;
|
||||
|
||||
private List<BundleActivator> _activatedFragments = new ArrayList<BundleActivator>();
|
||||
|
||||
private boolean _fragmentsWereActivated = false;
|
||||
//Use the deprecated StartLevel to stay compatible with older versions of OSGi.
|
||||
|
||||
// Use the deprecated StartLevel to stay compatible with older versions of
|
||||
// OSGi.
|
||||
private StartLevel _startLevel;
|
||||
|
||||
private int _maxStartLevel = 6;
|
||||
|
||||
public static PackageAdminServiceTracker INSTANCE = null;
|
||||
|
||||
public PackageAdminServiceTracker(BundleContext context)
|
||||
|
@ -51,7 +56,7 @@ public class PackageAdminServiceTracker implements ServiceListener
|
|||
{
|
||||
try
|
||||
{
|
||||
_context.addServiceListener(this,"(objectclass=" + PackageAdmin.class.getName() + ")");
|
||||
_context.addServiceListener(this, "(objectclass=" + PackageAdmin.class.getName() + ")");
|
||||
}
|
||||
catch (InvalidSyntaxException e)
|
||||
{
|
||||
|
@ -67,22 +72,21 @@ public class PackageAdminServiceTracker implements ServiceListener
|
|||
{
|
||||
ServiceReference sr = _context.getServiceReference(PackageAdmin.class.getName());
|
||||
_fragmentsWereActivated = sr != null;
|
||||
if (sr != null)
|
||||
invokeFragmentActivators(sr);
|
||||
|
||||
if (sr != null) invokeFragmentActivators(sr);
|
||||
|
||||
sr = _context.getServiceReference(StartLevel.class.getName());
|
||||
if (sr != null)
|
||||
{
|
||||
_startLevel = (StartLevel)_context.getService(sr);
|
||||
try
|
||||
{
|
||||
_maxStartLevel = Integer.parseInt(System.getProperty("osgi.startLevel","6"));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
//nevermind default on the usual.
|
||||
_maxStartLevel = 6;
|
||||
}
|
||||
_startLevel = (StartLevel) _context.getService(sr);
|
||||
try
|
||||
{
|
||||
_maxStartLevel = Integer.parseInt(System.getProperty("osgi.startLevel", "6"));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// nevermind default on the usual.
|
||||
_maxStartLevel = 6;
|
||||
}
|
||||
}
|
||||
return _fragmentsWereActivated;
|
||||
}
|
||||
|
@ -93,8 +97,7 @@ public class PackageAdminServiceTracker implements ServiceListener
|
|||
* the symbolic name of the fragment and the name of the class must be
|
||||
* 'FragmentActivator'.
|
||||
*
|
||||
* @param event
|
||||
* The <code>ServiceEvent</code> object.
|
||||
* @param event The <code>ServiceEvent</code> object.
|
||||
*/
|
||||
public void serviceChanged(ServiceEvent event)
|
||||
{
|
||||
|
@ -103,11 +106,12 @@ public class PackageAdminServiceTracker implements ServiceListener
|
|||
invokeFragmentActivators(event.getServiceReference());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper to access the PackageAdmin and return the fragments hosted by a bundle.
|
||||
* when we drop the support for the older versions of OSGi, we will stop using the PackageAdmin
|
||||
* service.
|
||||
* Helper to access the PackageAdmin and return the fragments hosted by a
|
||||
* bundle. when we drop the support for the older versions of OSGi, we will
|
||||
* stop using the PackageAdmin service.
|
||||
*
|
||||
* @param bundle
|
||||
* @return
|
||||
*/
|
||||
|
@ -115,17 +119,18 @@ public class PackageAdminServiceTracker implements ServiceListener
|
|||
{
|
||||
ServiceReference sr = _context.getServiceReference(PackageAdmin.class.getName());
|
||||
if (sr == null)
|
||||
{//we should never be here really.
|
||||
{// we should never be here really.
|
||||
return null;
|
||||
}
|
||||
PackageAdmin admin = (PackageAdmin)_context.getService(sr);
|
||||
PackageAdmin admin = (PackageAdmin) _context.getService(sr);
|
||||
return admin.getFragments(bundle);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the fragments and the required-bundles of a bundle.
|
||||
* Recursively collect the required-bundles and fragment when the directive visibility:=reexport
|
||||
* is added to a required-bundle.
|
||||
* Returns the fragments and the required-bundles of a bundle. Recursively
|
||||
* collect the required-bundles and fragment when the directive
|
||||
* visibility:=reexport is added to a required-bundle.
|
||||
*
|
||||
* @param bundle
|
||||
* @param webFragOrAnnotationOrResources
|
||||
* @return
|
||||
|
@ -134,124 +139,122 @@ public class PackageAdminServiceTracker implements ServiceListener
|
|||
{
|
||||
ServiceReference sr = _context.getServiceReference(PackageAdmin.class.getName());
|
||||
if (sr == null)
|
||||
{//we should never be here really.
|
||||
{// we should never be here really.
|
||||
return null;
|
||||
}
|
||||
PackageAdmin admin = (PackageAdmin)_context.getService(sr);
|
||||
LinkedHashMap<String,Bundle> deps = new LinkedHashMap<String,Bundle>();
|
||||
collectFragmentsAndRequiredBundles(bundle, admin, deps, false);
|
||||
return deps.values().toArray(new Bundle[deps.size()]);
|
||||
PackageAdmin admin = (PackageAdmin) _context.getService(sr);
|
||||
LinkedHashMap<String, Bundle> deps = new LinkedHashMap<String, Bundle>();
|
||||
collectFragmentsAndRequiredBundles(bundle, admin, deps, false);
|
||||
return deps.values().toArray(new Bundle[deps.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the fragments and the required-bundles. Collects them transitively when the directive 'visibility:=reexport'
|
||||
* is added to a required-bundle.
|
||||
* Returns the fragments and the required-bundles. Collects them
|
||||
* transitively when the directive 'visibility:=reexport' is added to a
|
||||
* required-bundle.
|
||||
*
|
||||
* @param bundle
|
||||
* @param webFragOrAnnotationOrResources
|
||||
* @return
|
||||
*/
|
||||
protected void collectFragmentsAndRequiredBundles(Bundle bundle, PackageAdmin admin, Map<String,Bundle> deps, boolean onlyReexport)
|
||||
protected void collectFragmentsAndRequiredBundles(Bundle bundle, PackageAdmin admin, Map<String, Bundle> deps, boolean onlyReexport)
|
||||
{
|
||||
Bundle[] fragments = admin.getFragments(bundle);
|
||||
if (fragments != null)
|
||||
{
|
||||
//Also add the bundles required by the fragments.
|
||||
//this way we can inject onto an existing web-bundle a set of bundles that extend it
|
||||
for (Bundle f : fragments)
|
||||
{
|
||||
if (!deps.keySet().contains(f.getSymbolicName()))
|
||||
{
|
||||
deps.put(f.getSymbolicName(), f);
|
||||
collectRequiredBundles(f, admin, deps, onlyReexport);
|
||||
}
|
||||
}
|
||||
// Also add the bundles required by the fragments.
|
||||
// this way we can inject onto an existing web-bundle a set of
|
||||
// bundles that extend it
|
||||
for (Bundle f : fragments)
|
||||
{
|
||||
if (!deps.keySet().contains(f.getSymbolicName()))
|
||||
{
|
||||
deps.put(f.getSymbolicName(), f);
|
||||
collectRequiredBundles(f, admin, deps, onlyReexport);
|
||||
}
|
||||
}
|
||||
}
|
||||
collectRequiredBundles(bundle, admin, deps, onlyReexport);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A simplistic but good enough parser for the Require-Bundle header.
|
||||
* Parses the version range attribute and the visibility directive.
|
||||
* A simplistic but good enough parser for the Require-Bundle header. Parses
|
||||
* the version range attribute and the visibility directive.
|
||||
*
|
||||
* @param onlyReexport true to collect resources and web-fragments transitively if and only if the directive visibility is reexport.
|
||||
* @param onlyReexport true to collect resources and web-fragments
|
||||
* transitively if and only if the directive visibility is
|
||||
* reexport.
|
||||
* @param bundle
|
||||
* @return The map of required bundles associated to the value of the jetty-web attribute.
|
||||
* @return The map of required bundles associated to the value of the
|
||||
* jetty-web attribute.
|
||||
*/
|
||||
protected void collectRequiredBundles(Bundle bundle, PackageAdmin admin, Map<String,Bundle> deps, boolean onlyReexport)
|
||||
protected void collectRequiredBundles(Bundle bundle, PackageAdmin admin, Map<String, Bundle> deps, boolean onlyReexport)
|
||||
{
|
||||
String requiredBundleHeader = (String)bundle.getHeaders().get("Require-Bundle");
|
||||
if (requiredBundleHeader == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
StringTokenizer tokenizer = new ManifestTokenizer(requiredBundleHeader);
|
||||
while (tokenizer.hasMoreTokens())
|
||||
{
|
||||
String tok = tokenizer.nextToken().trim();
|
||||
StringTokenizer tokenizer2 = new StringTokenizer(tok, ";");
|
||||
String symbolicName = tokenizer2.nextToken().trim();
|
||||
if (deps.keySet().contains(symbolicName))
|
||||
{
|
||||
//was already added. 2 dependencies pointing at the same bundle.
|
||||
continue;
|
||||
}
|
||||
String versionRange = null;
|
||||
boolean reexport = false;
|
||||
while (tokenizer2.hasMoreTokens())
|
||||
{
|
||||
String next = tokenizer2.nextToken().trim();
|
||||
if (next.startsWith("bundle-version="))
|
||||
{
|
||||
if (next.startsWith("bundle-version=\"") || next.startsWith("bundle-version='"))
|
||||
{
|
||||
versionRange = next.substring("bundle-version=\"".length(), next.length()-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
versionRange = next.substring("bundle-version=".length());
|
||||
}
|
||||
}
|
||||
else if (next.equals("visibility:=reexport"))
|
||||
{
|
||||
reexport = true;
|
||||
}
|
||||
}
|
||||
if (!reexport && onlyReexport)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Bundle[] reqBundles = admin.getBundles(symbolicName, versionRange);
|
||||
if (reqBundles != null && reqBundles.length != 0)
|
||||
{
|
||||
Bundle reqBundle = null;
|
||||
for (Bundle b : reqBundles)
|
||||
{
|
||||
if (b.getState() == Bundle.ACTIVE || b.getState() == Bundle.STARTING)
|
||||
{
|
||||
reqBundle = b;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (reqBundle == null)
|
||||
{
|
||||
//strange? in OSGi with Require-Bundle,
|
||||
//the dependent bundle is supposed to be active already
|
||||
reqBundle = reqBundles[0];
|
||||
}
|
||||
deps.put(reqBundle.getSymbolicName(),reqBundle);
|
||||
collectFragmentsAndRequiredBundles(reqBundle, admin, deps, true);
|
||||
}
|
||||
}
|
||||
String requiredBundleHeader = (String) bundle.getHeaders().get("Require-Bundle");
|
||||
if (requiredBundleHeader == null) { return; }
|
||||
StringTokenizer tokenizer = new ManifestTokenizer(requiredBundleHeader);
|
||||
while (tokenizer.hasMoreTokens())
|
||||
{
|
||||
String tok = tokenizer.nextToken().trim();
|
||||
StringTokenizer tokenizer2 = new StringTokenizer(tok, ";");
|
||||
String symbolicName = tokenizer2.nextToken().trim();
|
||||
if (deps.keySet().contains(symbolicName))
|
||||
{
|
||||
// was already added. 2 dependencies pointing at the same
|
||||
// bundle.
|
||||
continue;
|
||||
}
|
||||
String versionRange = null;
|
||||
boolean reexport = false;
|
||||
while (tokenizer2.hasMoreTokens())
|
||||
{
|
||||
String next = tokenizer2.nextToken().trim();
|
||||
if (next.startsWith("bundle-version="))
|
||||
{
|
||||
if (next.startsWith("bundle-version=\"") || next.startsWith("bundle-version='"))
|
||||
{
|
||||
versionRange = next.substring("bundle-version=\"".length(), next.length() - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
versionRange = next.substring("bundle-version=".length());
|
||||
}
|
||||
}
|
||||
else if (next.equals("visibility:=reexport"))
|
||||
{
|
||||
reexport = true;
|
||||
}
|
||||
}
|
||||
if (!reexport && onlyReexport) { return; }
|
||||
Bundle[] reqBundles = admin.getBundles(symbolicName, versionRange);
|
||||
if (reqBundles != null && reqBundles.length != 0)
|
||||
{
|
||||
Bundle reqBundle = null;
|
||||
for (Bundle b : reqBundles)
|
||||
{
|
||||
if (b.getState() == Bundle.ACTIVE || b.getState() == Bundle.STARTING)
|
||||
{
|
||||
reqBundle = b;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (reqBundle == null)
|
||||
{
|
||||
// strange? in OSGi with Require-Bundle,
|
||||
// the dependent bundle is supposed to be active already
|
||||
reqBundle = reqBundles[0];
|
||||
}
|
||||
deps.put(reqBundle.getSymbolicName(), reqBundle);
|
||||
collectFragmentsAndRequiredBundles(reqBundle, admin, deps, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void invokeFragmentActivators(ServiceReference sr)
|
||||
{
|
||||
PackageAdmin admin = (PackageAdmin)_context.getService(sr);
|
||||
PackageAdmin admin = (PackageAdmin) _context.getService(sr);
|
||||
Bundle[] fragments = admin.getFragments(_context.getBundle());
|
||||
if (fragments == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (fragments == null) { return; }
|
||||
for (Bundle frag : fragments)
|
||||
{
|
||||
// find a convention to look for a class inside the fragment.
|
||||
|
@ -261,7 +264,7 @@ public class PackageAdminServiceTracker implements ServiceListener
|
|||
Class<?> c = Class.forName(fragmentActivator);
|
||||
if (c != null)
|
||||
{
|
||||
BundleActivator bActivator = (BundleActivator)c.newInstance();
|
||||
BundleActivator bActivator = (BundleActivator) c.newInstance();
|
||||
bActivator.start(_context);
|
||||
_activatedFragments.add(bActivator);
|
||||
}
|
||||
|
@ -304,61 +307,67 @@ public class PackageAdminServiceTracker implements ServiceListener
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return true if the framework has completed all the start levels.
|
||||
*/
|
||||
public boolean frameworkHasCompletedAutostarts()
|
||||
{
|
||||
return _startLevel == null ? true : _startLevel.getStartLevel() >= _maxStartLevel;
|
||||
return _startLevel == null ? true : _startLevel.getStartLevel() >= _maxStartLevel;
|
||||
}
|
||||
|
||||
private static class ManifestTokenizer extends StringTokenizer {
|
||||
private static class ManifestTokenizer extends StringTokenizer
|
||||
{
|
||||
|
||||
public ManifestTokenizer(String header) {
|
||||
public ManifestTokenizer(String header)
|
||||
{
|
||||
super(header, ",");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String nextToken() {
|
||||
public String nextToken()
|
||||
{
|
||||
String token = super.nextToken();
|
||||
|
||||
while (hasOpenQuote(token) && hasMoreTokens()) {
|
||||
while (hasOpenQuote(token) && hasMoreTokens())
|
||||
{
|
||||
token += "," + super.nextToken();
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
private boolean hasOpenQuote(String token) {
|
||||
private boolean hasOpenQuote(String token)
|
||||
{
|
||||
int i = -1;
|
||||
do {
|
||||
int quote = getQuote(token, i+1);
|
||||
if (quote < 0) {
|
||||
return false;
|
||||
}
|
||||
do
|
||||
{
|
||||
int quote = getQuote(token, i + 1);
|
||||
if (quote < 0) { return false; }
|
||||
|
||||
i = token.indexOf(quote, i+1);
|
||||
i = token.indexOf(quote, i+1);
|
||||
} while (i >= 0);
|
||||
i = token.indexOf(quote, i + 1);
|
||||
i = token.indexOf(quote, i + 1);
|
||||
}
|
||||
while (i >= 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
private int getQuote(String token, int offset) {
|
||||
private int getQuote(String token, int offset)
|
||||
{
|
||||
int i = token.indexOf('"', offset);
|
||||
int j = token.indexOf('\'', offset);
|
||||
if (i < 0) {
|
||||
if (j < 0) {
|
||||
if (i < 0)
|
||||
{
|
||||
if (j < 0)
|
||||
{
|
||||
return -1;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
return '\'';
|
||||
}
|
||||
}
|
||||
if (j < 0) {
|
||||
return '"';
|
||||
}
|
||||
if (i < j) {
|
||||
return '"';
|
||||
}
|
||||
if (j < 0) { return '"'; }
|
||||
if (i < j) { return '"'; }
|
||||
return '\'';
|
||||
}
|
||||
|
||||
|
|
|
@ -22,236 +22,240 @@ import org.eclipse.jetty.util.component.LifeCycle;
|
|||
import org.osgi.framework.FrameworkUtil;
|
||||
|
||||
/**
|
||||
* Listens to the start and stop of the NestedConnector to register and unregister the NestedConnector
|
||||
* with the BridgeServlet.
|
||||
* Listens to the start and stop of the NestedConnector to register and
|
||||
* unregister the NestedConnector with the BridgeServlet.
|
||||
* <p>
|
||||
* All interactions with the BridgeServlet are done via introspection to avoid depending on it directly.
|
||||
* The BridgeServlet lives in the bootstrap-webapp; not inside equinox.
|
||||
* All interactions with the BridgeServlet are done via introspection to avoid
|
||||
* depending on it directly. The BridgeServlet lives in the bootstrap-webapp;
|
||||
* not inside equinox.
|
||||
* </p>
|
||||
*/
|
||||
public class NestedConnectorListener extends AbstractLifeCycleListener
|
||||
{
|
||||
|
||||
/** Name of the BridgeServlet class. By default org.eclipse.equinox.servletbridge.BridgeServlet */
|
||||
private String bridgeServletClassName = "org.eclipse.equinox.servletbridge.BridgeServlet";
|
||||
|
||||
/** Name of the static method on the BridgeServlet class to register the
|
||||
* servlet delegate. By default 'registerServletDelegate' */
|
||||
private String registerServletDelegateMethodName = "registerServletDelegate";
|
||||
|
||||
/** Name of the static method on the BridgeServlet class to register the
|
||||
* servlet delegate. By default 'unregisterServletDelegate' */
|
||||
private String unregisterServletDelegateMethodName = "unregisterServletDelegate";
|
||||
|
||||
/** servlet that wraps this NestedConnector and uses the NestedConnector to service the requests. */
|
||||
private NestedConnectorServletDelegate _servletDelegate;
|
||||
|
||||
/**
|
||||
* The NestedConnector listened to.
|
||||
*/
|
||||
private NestedConnector nestedConnector;
|
||||
|
||||
/**
|
||||
* @param bridgeServletClassName Name of the class that is the BridgeServlet.
|
||||
* By default org.eclipse.equinox.servletbridge.BridgeServlet
|
||||
*/
|
||||
public void setBridgeServletClassName(String bridgeServletClassName)
|
||||
{
|
||||
this.bridgeServletClassName = bridgeServletClassName;
|
||||
}
|
||||
|
||||
public String getBridgeServletClassName()
|
||||
{
|
||||
return this.bridgeServletClassName;
|
||||
}
|
||||
public String getRegisterServletDelegateMethodName()
|
||||
{
|
||||
return this.registerServletDelegateMethodName;
|
||||
}
|
||||
public String getUnregisterServletDelegateMethodName()
|
||||
{
|
||||
return this.unregisterServletDelegateMethodName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param registerServletDelegateMethodName Name of the static method on the BridgeServlet class
|
||||
* to register the servlet delegate.
|
||||
*/
|
||||
public void setRegisterServletDelegateMethodName(String registerServletDelegateMethodName)
|
||||
{
|
||||
this.registerServletDelegateMethodName = registerServletDelegateMethodName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param unregisterServletDelegateMethodName Name of the static method on the BridgeServlet class
|
||||
* to unregister the servlet delegate.
|
||||
*/
|
||||
public void setUnregisterServletDelegateMethodName(String unregisterServletDelegateMethodName)
|
||||
{
|
||||
this.unregisterServletDelegateMethodName = unregisterServletDelegateMethodName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param nestedConnector The NestedConnector that we are listening to here.
|
||||
*/
|
||||
public void setNestedConnector(NestedConnector nestedConnector)
|
||||
{
|
||||
this.nestedConnector = nestedConnector;
|
||||
}
|
||||
/**
|
||||
* @return The NestedConnector that we are listening to here.
|
||||
*/
|
||||
public NestedConnector getNestedConnector()
|
||||
{
|
||||
return this.nestedConnector;
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Name of the BridgeServlet class. By default
|
||||
* org.eclipse.equinox.servletbridge.BridgeServlet
|
||||
*/
|
||||
private String bridgeServletClassName = "org.eclipse.equinox.servletbridge.BridgeServlet";
|
||||
|
||||
/**
|
||||
* Name of the static method on the BridgeServlet class to register the
|
||||
* servlet delegate. By default 'registerServletDelegate'
|
||||
*/
|
||||
private String registerServletDelegateMethodName = "registerServletDelegate";
|
||||
|
||||
/**
|
||||
* Name of the static method on the BridgeServlet class to register the
|
||||
* servlet delegate. By default 'unregisterServletDelegate'
|
||||
*/
|
||||
private String unregisterServletDelegateMethodName = "unregisterServletDelegate";
|
||||
|
||||
/**
|
||||
* servlet that wraps this NestedConnector and uses the NestedConnector to
|
||||
* service the requests.
|
||||
*/
|
||||
private NestedConnectorServletDelegate _servletDelegate;
|
||||
|
||||
/**
|
||||
* The NestedConnector listened to.
|
||||
*/
|
||||
private NestedConnector nestedConnector;
|
||||
|
||||
/**
|
||||
* @param bridgeServletClassName Name of the class that is the
|
||||
* BridgeServlet. By default
|
||||
* org.eclipse.equinox.servletbridge.BridgeServlet
|
||||
*/
|
||||
public void setBridgeServletClassName(String bridgeServletClassName)
|
||||
{
|
||||
this.bridgeServletClassName = bridgeServletClassName;
|
||||
}
|
||||
|
||||
public String getBridgeServletClassName()
|
||||
{
|
||||
return this.bridgeServletClassName;
|
||||
}
|
||||
|
||||
public String getRegisterServletDelegateMethodName()
|
||||
{
|
||||
return this.registerServletDelegateMethodName;
|
||||
}
|
||||
|
||||
public String getUnregisterServletDelegateMethodName()
|
||||
{
|
||||
return this.unregisterServletDelegateMethodName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param registerServletDelegateMethodName Name of the static method on the
|
||||
* BridgeServlet class to register the servlet delegate.
|
||||
*/
|
||||
public void setRegisterServletDelegateMethodName(String registerServletDelegateMethodName)
|
||||
{
|
||||
this.registerServletDelegateMethodName = registerServletDelegateMethodName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param unregisterServletDelegateMethodName Name of the static method on
|
||||
* the BridgeServlet class to unregister the servlet delegate.
|
||||
*/
|
||||
public void setUnregisterServletDelegateMethodName(String unregisterServletDelegateMethodName)
|
||||
{
|
||||
this.unregisterServletDelegateMethodName = unregisterServletDelegateMethodName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param nestedConnector The NestedConnector that we are listening to here.
|
||||
*/
|
||||
public void setNestedConnector(NestedConnector nestedConnector)
|
||||
{
|
||||
this.nestedConnector = nestedConnector;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The NestedConnector that we are listening to here.
|
||||
*/
|
||||
public NestedConnector getNestedConnector()
|
||||
{
|
||||
return this.nestedConnector;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lifeCycleStarted(LifeCycle event)
|
||||
{
|
||||
try
|
||||
{
|
||||
registerWithBridgeServlet();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (e instanceof RuntimeException)
|
||||
{
|
||||
throw (RuntimeException)e;
|
||||
}
|
||||
throw new RuntimeException("Unable to register the servlet delegate into the BridgeServlet.", e);
|
||||
}
|
||||
try
|
||||
{
|
||||
registerWithBridgeServlet();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (e instanceof RuntimeException) { throw (RuntimeException) e; }
|
||||
throw new RuntimeException("Unable to register the servlet delegate into the BridgeServlet.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@Override
|
||||
public void lifeCycleStopping(LifeCycle event)
|
||||
{
|
||||
try
|
||||
{
|
||||
unregisterWithBridgeServlet();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (e instanceof RuntimeException)
|
||||
{
|
||||
throw (RuntimeException)e;
|
||||
}
|
||||
throw new RuntimeException("Unable to unregister the servlet delegate into the BridgeServlet.", e);
|
||||
}
|
||||
try
|
||||
{
|
||||
unregisterWithBridgeServlet();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (e instanceof RuntimeException) { throw (RuntimeException) e; }
|
||||
throw new RuntimeException("Unable to unregister the servlet delegate into the BridgeServlet.", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook into the BridgeServlet
|
||||
*/
|
||||
protected void registerWithBridgeServlet() throws Exception
|
||||
{
|
||||
_servletDelegate = new NestedConnectorServletDelegate(getNestedConnector());
|
||||
try
|
||||
{
|
||||
invokeStaticMethod(getBridgeServletClassName(), getRegisterServletDelegateMethodName(),
|
||||
new Class[] {HttpServlet.class}, _servletDelegate);
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
_servletDelegate.destroy();
|
||||
_servletDelegate = null;
|
||||
if (t instanceof Exception)
|
||||
{
|
||||
throw (Exception)t;
|
||||
}
|
||||
throw new RuntimeException("Unable to register the servlet delegate into the BridgeServlet.", t);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unhook into the BridgeServlet
|
||||
*/
|
||||
protected void unregisterWithBridgeServlet() throws Exception
|
||||
{
|
||||
if (_servletDelegate != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
invokeStaticMethod(getBridgeServletClassName(), getUnregisterServletDelegateMethodName(),
|
||||
new Class[] {HttpServlet.class}, _servletDelegate);
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
if (t instanceof Exception)
|
||||
{
|
||||
throw (Exception)t;
|
||||
}
|
||||
throw new RuntimeException("Unable to unregister the servlet delegate from the BridgeServlet.", t);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_servletDelegate.destroy();
|
||||
_servletDelegate = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Hook into the BridgeServlet
|
||||
*/
|
||||
protected void registerWithBridgeServlet() throws Exception
|
||||
{
|
||||
_servletDelegate = new NestedConnectorServletDelegate(getNestedConnector());
|
||||
try
|
||||
{
|
||||
invokeStaticMethod(getBridgeServletClassName(), getRegisterServletDelegateMethodName(), new Class[] { HttpServlet.class }, _servletDelegate);
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
_servletDelegate.destroy();
|
||||
_servletDelegate = null;
|
||||
if (t instanceof Exception) { throw (Exception) t; }
|
||||
throw new RuntimeException("Unable to register the servlet delegate into the BridgeServlet.", t);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param clName
|
||||
* @param methName
|
||||
* @param argType
|
||||
* @throws Exception
|
||||
*/
|
||||
private static void invokeStaticMethod(String clName, String methName, Class[] argType, Object...args)
|
||||
throws Exception
|
||||
{
|
||||
Method m = getMethod(clName, methName, argType);
|
||||
m.invoke(null, args);
|
||||
}
|
||||
/**
|
||||
* Unhook into the BridgeServlet
|
||||
*/
|
||||
protected void unregisterWithBridgeServlet() throws Exception
|
||||
{
|
||||
if (_servletDelegate != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
invokeStaticMethod(getBridgeServletClassName(), getUnregisterServletDelegateMethodName(), new Class[] { HttpServlet.class }, _servletDelegate);
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
if (t instanceof Exception) { throw (Exception) t; }
|
||||
throw new RuntimeException("Unable to unregister the servlet delegate from the BridgeServlet.", t);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_servletDelegate.destroy();
|
||||
_servletDelegate = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param clName Class that belongs to the parent classloader of the OSGi framework.
|
||||
* @param methName Name of the method to find.
|
||||
* @param argType Argument types of the method to find.
|
||||
* @throws Exception
|
||||
*/
|
||||
private static Method getMethod(String clName, String methName, Class... argType)
|
||||
throws Exception
|
||||
{
|
||||
Class bridgeServletClass = FrameworkUtil.class.getClassLoader()
|
||||
.loadClass(clName);
|
||||
return getMethod(bridgeServletClass, methName, argType);
|
||||
}
|
||||
private static Method getMethod(Class cl, String methName, Class... argType)
|
||||
throws Exception
|
||||
{
|
||||
Method meth = null;
|
||||
try
|
||||
{
|
||||
meth = cl.getMethod(methName, argType);
|
||||
return meth;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
for (Method m : cl.getMethods())
|
||||
{
|
||||
if (m.getName().equals(methName) && m.getParameterTypes().length == argType.length)
|
||||
{
|
||||
int i = 0;
|
||||
for (Class p : m.getParameterTypes())
|
||||
{
|
||||
Class ap = argType[i];
|
||||
if (p.getName().equals(ap.getName())
|
||||
&& !p.equals(ap))
|
||||
{
|
||||
throw new IllegalStateException("The method \"" + m.toGenericString() +
|
||||
"\" was found. but the parameter class " + p.getName() + " is not the same " +
|
||||
" inside OSGi classloader (" + ap.getClassLoader() + ") and inside the " +
|
||||
cl.getName() + " classloader (" + p.getClassLoader() + ")." +
|
||||
" Are the ExtensionBundles correctly defined?");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param clName
|
||||
* @param methName
|
||||
* @param argType
|
||||
* @throws Exception
|
||||
*/
|
||||
private static void invokeStaticMethod(String clName, String methName, Class[] argType, Object... args) throws Exception
|
||||
{
|
||||
Method m = getMethod(clName, methName, argType);
|
||||
m.invoke(null, args);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param clName Class that belongs to the parent classloader of the OSGi
|
||||
* framework.
|
||||
* @param methName Name of the method to find.
|
||||
* @param argType Argument types of the method to find.
|
||||
* @throws Exception
|
||||
*/
|
||||
private static Method getMethod(String clName, String methName, Class... argType) throws Exception
|
||||
{
|
||||
Class bridgeServletClass = FrameworkUtil.class.getClassLoader().loadClass(clName);
|
||||
return getMethod(bridgeServletClass, methName, argType);
|
||||
}
|
||||
|
||||
private static Method getMethod(Class cl, String methName, Class... argType) throws Exception
|
||||
{
|
||||
Method meth = null;
|
||||
try
|
||||
{
|
||||
meth = cl.getMethod(methName, argType);
|
||||
return meth;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
for (Method m : cl.getMethods())
|
||||
{
|
||||
if (m.getName().equals(methName) && m.getParameterTypes().length == argType.length)
|
||||
{
|
||||
int i = 0;
|
||||
for (Class p : m.getParameterTypes())
|
||||
{
|
||||
Class ap = argType[i];
|
||||
if (p.getName().equals(ap.getName()) && !p.equals(ap)) { throw new IllegalStateException(
|
||||
"The method \"" + m.toGenericString()
|
||||
+ "\" was found. but the parameter class "
|
||||
+ p.getName()
|
||||
+ " is not the same "
|
||||
+ " inside OSGi classloader ("
|
||||
+ ap.getClassLoader()
|
||||
+ ") and inside the "
|
||||
+ cl.getName()
|
||||
+ " classloader ("
|
||||
+ p.getClassLoader()
|
||||
+ ")."
|
||||
+ " Are the ExtensionBundles correctly defined?");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,20 +27,19 @@ import org.eclipse.jetty.nested.NestedConnector;
|
|||
*/
|
||||
public class NestedConnectorServletDelegate extends HttpServlet
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final NestedConnector _nestedConnector;
|
||||
|
||||
public NestedConnectorServletDelegate(NestedConnector nestedConnector)
|
||||
{
|
||||
_nestedConnector = nestedConnector;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void service(ServletRequest req, ServletResponse res)
|
||||
throws ServletException, IOException
|
||||
{
|
||||
_nestedConnector.service(req, res);
|
||||
}
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final NestedConnector _nestedConnector;
|
||||
|
||||
public NestedConnectorServletDelegate(NestedConnector nestedConnector)
|
||||
{
|
||||
_nestedConnector = nestedConnector;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException
|
||||
{
|
||||
_nestedConnector.service(req, res);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue