You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by mu...@apache.org on 2009/04/13 03:55:03 UTC
svn commit: r764348 - in /struts/sandbox/trunk/struts2-osgi-plugin:
admin-bundle/
admin-bundle/src/main/java/org/apache/struts2/osgi/admin/actions/
plugin/src/main/java/org/apache/struts2/osgi/
plugin/src/main/java/org/apache/struts2/osgi/interceptor/ ...
Author: musachy
Date: Mon Apr 13 01:55:02 2009
New Revision: 764348
URL: http://svn.apache.org/viewvc?rev=764348&view=rev
Log:
Add support for loading/unloading configuration when bundles are started/stopped
Modified:
struts/sandbox/trunk/struts2-osgi-plugin/admin-bundle/pom.xml
struts/sandbox/trunk/struts2-osgi-plugin/admin-bundle/src/main/java/org/apache/struts2/osgi/admin/actions/BundlesAction.java
struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/BundleAccessor.java
struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/BundleFreemarkerManager.java
struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/BundlePackageLoader.java
struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/DefaultBundleAccessor.java
struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/DelegatingObjectFactory.java
struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/FelixOsgiHost.java
struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/OsgiConfigurationProvider.java
struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/PackageLoader.java
struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/interceptor/BundleContextAware.java
struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/interceptor/OsgiInterceptor.java
struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/interceptor/ServiceAware.java
struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/resources/struts-plugin.xml
Modified: struts/sandbox/trunk/struts2-osgi-plugin/admin-bundle/pom.xml
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-osgi-plugin/admin-bundle/pom.xml?rev=764348&r1=764347&r2=764348&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-osgi-plugin/admin-bundle/pom.xml (original)
+++ struts/sandbox/trunk/struts2-osgi-plugin/admin-bundle/pom.xml Mon Apr 13 01:55:02 2009
@@ -14,6 +14,12 @@
<artifactId>struts2-osgi-plugin</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ <version>2.4</version>
+ <scope>provided</scope>
+ </dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
@@ -36,21 +42,26 @@
<configuration>
<instructions>
<manifestLocation>META-INF</manifestLocation>
- <Import-Package>
- *,com.opensymphony.xwork2
- </Import-Package>
- <Export-Package>
- org.apache.struts2.osgi.admin*
- </Export-Package>
- <Bundle-Activator>
- org.apache.struts2.osgi.StrutsActivator
- </Bundle-Activator>
- <Spring-Context>
- *;create-asynchronously:=false
- </Spring-Context>
+ <Struts2-Enabled>true</Struts2-Enabled>
+ <Import-Package>*,com.opensymphony.xwork2</Import-Package>
+ <Export-Package>org.apache.struts2.osgi.admin*</Export-Package>
+ <Spring-Context>*;create-asynchronously:=false</Spring-Context>
</instructions>
</configuration>
</plugin>
+ <plugin>
+ <inherited>true</inherited>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-sources</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
</plugins>
<pluginManagement>
<plugins>
@@ -64,5 +75,4 @@
</plugins>
</pluginManagement>
</build>
-
</project>
Modified: struts/sandbox/trunk/struts2-osgi-plugin/admin-bundle/src/main/java/org/apache/struts2/osgi/admin/actions/BundlesAction.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-osgi-plugin/admin-bundle/src/main/java/org/apache/struts2/osgi/admin/actions/BundlesAction.java?rev=764348&r1=764347&r2=764348&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-osgi-plugin/admin-bundle/src/main/java/org/apache/struts2/osgi/admin/actions/BundlesAction.java (original)
+++ struts/sandbox/trunk/struts2-osgi-plugin/admin-bundle/src/main/java/org/apache/struts2/osgi/admin/actions/BundlesAction.java Mon Apr 13 01:55:02 2009
@@ -21,23 +21,24 @@
package org.apache.struts2.osgi.admin.actions;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-
-import org.apache.struts2.dispatcher.DefaultActionSupport;
+import com.opensymphony.xwork2.ActionSupport;
+import com.opensymphony.xwork2.config.Configuration;
+import com.opensymphony.xwork2.config.entities.PackageConfig;
+import com.opensymphony.xwork2.inject.Inject;
import org.apache.struts2.osgi.BundleAccessor;
-import org.apache.struts2.osgi.DefaultBundleAccessor;
import org.apache.struts2.osgi.OsgiHost;
+import org.apache.struts2.osgi.StrutsOsgiListener;
+import org.apache.struts2.util.ServletContextAware;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleException;
-import com.opensymphony.xwork2.config.Configuration;
-import com.opensymphony.xwork2.config.entities.PackageConfig;
-import com.opensymphony.xwork2.inject.Inject;
+import javax.servlet.ServletContext;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
-public class BundlesAction extends DefaultActionSupport {
+public class BundlesAction extends ActionSupport implements ServletContextAware {
private String id;
@@ -46,7 +47,6 @@
private OsgiHost osgiHost;
public BundlesAction() {
- this.bundleAccessor = DefaultBundleAccessor.getInstance();
}
public String index() {
@@ -61,6 +61,11 @@
Bundle bundle = osgiHost.getBundles().get(id);
try {
bundle.start();
+
+ //start fires the BundleEvent.STARTED, which load the config
+ //we need to wait until the config is loaded from that bundle
+ //there no easy way/elegant way to know if the bundle is being processed
+ Thread.sleep(1000);
} catch (Exception e) {
addActionError(e.toString());
}
@@ -105,8 +110,12 @@
public List<PackageConfig> getPackages() {
List<PackageConfig> pkgs = new ArrayList<PackageConfig>();
Bundle bundle = getBundle();
- for (String name : bundleAccessor.getPackagesByBundle(bundle)) {
- pkgs.add(configuration.getPackageConfig(name));
+ if (bundle.getState() == Bundle.ACTIVE) {
+ for (String name : bundleAccessor.getPackagesByBundle(bundle)) {
+ PackageConfig packageConfig = configuration.getPackageConfig(name);
+ if (packageConfig != null)
+ pkgs.add(packageConfig);
+ }
}
return pkgs;
}
@@ -161,7 +170,11 @@
}
@Inject
- public void setOsgiHost(OsgiHost osgiHost) {
- this.osgiHost = osgiHost;
+ public void setBundleAccessor(BundleAccessor bundleAccessor) {
+ this.bundleAccessor = bundleAccessor;
+ }
+
+ public void setServletContext(ServletContext servletContext) {
+ osgiHost = (OsgiHost) servletContext.getAttribute(StrutsOsgiListener.OSGI_HOST);
}
}
Modified: struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/BundleAccessor.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/BundleAccessor.java?rev=764348&r1=764347&r2=764348&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/BundleAccessor.java (original)
+++ struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/BundleAccessor.java Mon Apr 13 01:55:02 2009
@@ -36,8 +36,6 @@
String CURRENT_BUNDLE_NAME = "__bundle_name__";
- void setPackageToBundle(Map<String, String> packageToBundle);
-
Class loadClass(String name) throws ClassNotFoundException;
InputStream loadResourceAsStream(String name) throws IOException;
Modified: struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/BundleFreemarkerManager.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/BundleFreemarkerManager.java?rev=764348&r1=764347&r2=764348&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/BundleFreemarkerManager.java (original)
+++ struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/BundleFreemarkerManager.java Mon Apr 13 01:55:02 2009
@@ -44,7 +44,7 @@
*/
public class BundleFreemarkerManager extends FreemarkerManager {
private static final Logger LOG = LoggerFactory.getLogger(BundleFreemarkerManager.class);
-
+
@Override
protected TemplateLoader getTemplateLoader(ServletContext servletContext) {
// construct a FileTemplateLoader for the init-param 'TemplatePath'
@@ -59,7 +59,8 @@
try {
templatePathLoader = new FileTemplateLoader(new File(templatePath));
} catch (IOException e) {
- LOG.error("Invalid template path specified: #1",e, e.getMessage());
+ if (LOG.isErrorEnabled())
+ LOG.error("Invalid template path specified: [#0]", e, e.getMessage());
}
}
@@ -73,10 +74,10 @@
new FreeMarkerBundleResourceLoader()
})
: new MultiTemplateLoader(new TemplateLoader[]{
- new WebappTemplateLoader(servletContext),
- new StrutsClassTemplateLoader(),
- new FreeMarkerBundleResourceLoader()
- });
+ new WebappTemplateLoader(servletContext),
+ new StrutsClassTemplateLoader(),
+ new FreeMarkerBundleResourceLoader()
+ });
}
-
+
}
Modified: struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/BundlePackageLoader.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/BundlePackageLoader.java?rev=764348&r1=764347&r2=764348&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/BundlePackageLoader.java (original)
+++ struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/BundlePackageLoader.java Mon Apr 13 01:55:02 2009
@@ -41,48 +41,41 @@
import com.opensymphony.xwork2.util.logging.Logger;
import com.opensymphony.xwork2.util.logging.LoggerFactory;
+/**
+ * Package loader implementation that loads resources from a bundle
+ */
public class BundlePackageLoader implements PackageLoader {
private static final Logger LOG = LoggerFactory.getLogger(BundlePackageLoader.class);
- public List<PackageConfig> loadPackages(Bundle bundle, BundleContext bundleContext, ObjectFactory objectFactory, Map<String,PackageConfig> pkgConfigs) throws ConfigurationException {
+ public List<PackageConfig> loadPackages(Bundle bundle, BundleContext bundleContext, ObjectFactory objectFactory, Map<String, PackageConfig> pkgConfigs) throws ConfigurationException {
Configuration config = new DefaultConfiguration("struts.xml");
- ActionContext ctx = ActionContext.getContext();
- if (ctx == null) {
- ctx = new ActionContext(new HashMap());
- ActionContext.setContext(ctx);
- }
-
- try {
- // Ensure all requested classes and resources will be resolved using the current bundle
- ctx.put(BundleAccessor.CURRENT_BUNDLE_NAME, bundle.getSymbolicName());
-
- BundleConfigurationProvider prov = new BundleConfigurationProvider("struts.xml", bundle, bundleContext);
- for (PackageConfig pkg : pkgConfigs.values()) {
- config.addPackageConfig(pkg.getName(), pkg);
- }
- prov.setObjectFactory(objectFactory);
- prov.init(config);
- prov.loadPackages();
- } finally {
- ctx.put(BundleAccessor.CURRENT_BUNDLE_NAME, null);
- }
+ BundleConfigurationProvider prov = new BundleConfigurationProvider("struts.xml", bundle, bundleContext);
+ for (PackageConfig pkg : pkgConfigs.values()) {
+ config.addPackageConfig(pkg.getName(), pkg);
+ }
+ prov.setObjectFactory(objectFactory);
+ prov.init(config);
+ prov.loadPackages();
List<PackageConfig> list = new ArrayList<PackageConfig>(config.getPackageConfigs().values());
list.removeAll(pkgConfigs.values());
-
+
return list;
}
-
+
static class BundleConfigurationProvider extends XmlConfigurationProvider {
private Bundle bundle;
private BundleContext bundleContext;
- public BundleConfigurationProvider(String filename, Bundle bundle, BundleContext bundleContext) {
+ public BundleConfigurationProvider(String filename, Bundle bundle, BundleContext bundleContext) {
super(filename, false);
this.bundle = bundle;
this.bundleContext = bundleContext;
}
- public BundleConfigurationProvider(String filename) { super(filename); }
+
+ public BundleConfigurationProvider(String filename) {
+ super(filename);
+ }
@Override
protected Iterator<URL> getConfigurationUrls(String fileName) throws IOException {
@@ -90,23 +83,25 @@
return e.hasMoreElements() ? new EnumeratorIterator<URL>(e) : null;
}
}
-
+
static class EnumeratorIterator<E> implements Iterator<E> {
Enumeration<E> e = null;
+
public EnumeratorIterator(Enumeration<E> e) {
this.e = e;
}
+
public boolean hasNext() {
- return e.hasMoreElements();
+ return e.hasMoreElements();
}
public E next() {
- return e.nextElement();
+ return e.nextElement();
}
public void remove() {
- throw new UnsupportedOperationException();
+ throw new UnsupportedOperationException();
}
- }
+ }
}
Modified: struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/DefaultBundleAccessor.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/DefaultBundleAccessor.java?rev=764348&r1=764347&r2=764348&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/DefaultBundleAccessor.java (original)
+++ struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/DefaultBundleAccessor.java Mon Apr 13 01:55:02 2009
@@ -50,8 +50,8 @@
private static final Logger LOG = LoggerFactory.getLogger(DefaultBundleAccessor.class);
private BundleContext bundleContext;
- private Map<String, String> packageToBundle;
- private Map<Bundle, Set<String>> packagesByBundle;
+ private Map<String, String> packageToBundle = new HashMap<String, String>();
+ private Map<Bundle, Set<String>> packagesByBundle = new HashMap<Bundle, Set<String>>();
private OsgiHost osgiHost;
public DefaultBundleAccessor() {
@@ -88,15 +88,6 @@
return bundleContext != null ? bundleContext.getServiceReferences(className, params) : null;
}
- public void setPackageToBundle(Map<String, String> packageToBundle) {
- this.packageToBundle = packageToBundle;
- this.packagesByBundle = new HashMap<Bundle, Set<String>>();
- for (Map.Entry<String, String> entry : packageToBundle.entrySet()) {
- Bundle bundle = osgiHost.getActiveBundles().get(entry.getValue());
- addPackageFromBundle(bundle, entry.getKey());
- }
- }
-
/**
* Add as Bundle -> Package mapping
* @param bundle the bundle where the package was loaded from
@@ -117,7 +108,7 @@
if (bundle != null) {
Class cls = bundle.loadClass(className);
if (LOG.isTraceEnabled())
- LOG.debug("Located class [#0] in bundle [#1]", className, bundle.getSymbolicName());
+ LOG.trace("Located class [#0] in bundle [#1]", className, bundle.getSymbolicName());
return cls;
}
Modified: struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/DelegatingObjectFactory.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/DelegatingObjectFactory.java?rev=764348&r1=764347&r2=764348&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/DelegatingObjectFactory.java (original)
+++ struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/DelegatingObjectFactory.java Mon Apr 13 01:55:02 2009
@@ -61,7 +61,10 @@
try {
return delegateObjectFactory.buildBean(className, extraContext, injectInternal);
} catch (Exception e) {
- return bundleResourceLoader.loadClass(className).newInstance();
+ Object object = bundleResourceLoader.loadClass(className).newInstance();
+ if (injectInternal)
+ injectInternalBeans(object);
+ return object;
}
}
Modified: struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/FelixOsgiHost.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/FelixOsgiHost.java?rev=764348&r1=764347&r2=764348&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/FelixOsgiHost.java (original)
+++ struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/FelixOsgiHost.java Mon Apr 13 01:55:02 2009
@@ -71,11 +71,10 @@
* <p>struts.osgi.logLevel: Defaults to "1". Felix log level. 1 = error, 2 = warning, 3 = information, and 4 = debug </p>
* <p>struts.osgi.runLevel: Defaults to "3". Run level to start the container.</p>
*/
-public class FelixOsgiHost implements OsgiHost, BundleListener {
+public class FelixOsgiHost implements OsgiHost {
private static final Logger LOG = LoggerFactory.getLogger(FelixOsgiHost.class);
private Felix felix;
- private Map<String, Bundle> bundles = Collections.synchronizedMap(new HashMap<String, Bundle>());
private static final Pattern versionPattern = Pattern.compile("([\\d])+[\\.-]");
private ServletContext servletContext;
@@ -98,7 +97,7 @@
String storageDir = System.getProperty("java.io.tmpdir") + ".felix-cache";
configProps.setProperty(Constants.FRAMEWORK_STORAGE, storageDir);
if (LOG.isDebugEnabled())
- LOG.debug("Storing bundle at [#0]", storageDir);
+ LOG.debug("Storing bundles at [#0]", storageDir);
String cleanBundleCache = getServletContextParam("struts.osgi.clearBundleCache", "true");
if ("true".equalsIgnoreCase(cleanBundleCache)) {
@@ -116,17 +115,6 @@
try {
List<BundleActivator> list = new ArrayList<BundleActivator>();
list.add(new AutoActivator(configProps));
-
- //this activator just hooks this class as a BundleListener
- list.add(new BundleActivator() {
- public void start(BundleContext bundleContext) throws Exception {
- bundleContext.addBundleListener(FelixOsgiHost.this);
- }
-
- public void stop(BundleContext bundleContext) throws Exception {
- }
- });
-
configProps.put(FelixConstants.SYSTEMBUNDLE_ACTIVATORS_PROP, list);
felix = new Felix(configProps);
@@ -145,8 +133,9 @@
}
/**
- * Gets a param from the ServletContext, returning the default value if the param is not set
- * @param paramName the name of the param to get from the ServletContext
+ * Gets a param from the ServletContext, returning the default value if the param is not set
+ *
+ * @param paramName the name of the param to get from the ServletContext
* @param defaultValue value to return if the param is not set
* @return
*/
@@ -352,17 +341,22 @@
* Use getActiveBundles() for active bundles
*/
public Map<String, Bundle> getBundles() {
+ Map<String, Bundle> bundles = new HashMap<String, Bundle>();
+ for (Bundle bundle : felix.getBundleContext().getBundles()) {
+ bundles.put(bundle.getSymbolicName(), bundle);
+ }
+
return Collections.unmodifiableMap(bundles);
}
public Map<String, Bundle> getActiveBundles() {
- Map<String, Bundle> activeBundleMap = new HashMap<String, Bundle>();
- for (Map.Entry<String, Bundle> entry : bundles.entrySet()) {
- if (entry.getValue().getState() == Bundle.ACTIVE)
- activeBundleMap.put(entry.getKey(), entry.getValue());
+ Map<String, Bundle> bundles = new HashMap<String, Bundle>();
+ for (Bundle bundle : felix.getBundleContext().getBundles()) {
+ if (bundle.getState() == Bundle.ACTIVE)
+ bundles.put(bundle.getSymbolicName(), bundle);
}
- return activeBundleMap;
+ return Collections.unmodifiableMap(bundles);
}
public BundleContext getBundleContext() {
@@ -370,30 +364,13 @@
}
public void destroy() throws Exception {
- try {
- felix.stop();
- } finally {
- bundles = null;
- }
+ felix.stop();
+ if (LOG.isTraceEnabled())
+ LOG.trace("Apache Felix has stopped");
}
public void init(ServletContext servletContext) {
this.servletContext = servletContext;
startFelix();
}
-
- /**
- * Listen to BundleEvent(s) and build a bundles list
- */
- public void bundleChanged(BundleEvent evt) {
- Bundle bundle = evt.getBundle();
- String bundleName = bundle.getSymbolicName();
- if (bundleName != null) {
- switch (evt.getType()) {
- case BundleEvent.STARTED:
- this.bundles.put(bundleName, bundle);
- break;
- }
- }
- }
}
Modified: struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/OsgiConfigurationProvider.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/OsgiConfigurationProvider.java?rev=764348&r1=764347&r2=764348&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/OsgiConfigurationProvider.java (original)
+++ struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/OsgiConfigurationProvider.java Mon Apr 13 01:55:02 2009
@@ -35,8 +35,11 @@
import org.apache.struts2.osgi.loaders.VelocityBundleResourceLoader;
import org.apache.struts2.views.velocity.VelocityManager;
import org.apache.velocity.app.Velocity;
+import org.apache.commons.lang.xwork.StringUtils;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleListener;
+import org.osgi.framework.BundleEvent;
import javax.servlet.ServletContext;
import java.util.ArrayList;
@@ -50,7 +53,7 @@
/**
* Struts package provider that starts the OSGi container and deelgates package loading
*/
-public class OsgiConfigurationProvider implements PackageProvider {
+public class OsgiConfigurationProvider implements PackageProvider, BundleListener {
private static final String STRUTS_ENABLED = "Struts2-Enabled";
private static final Logger LOG = LoggerFactory.getLogger(OsgiConfigurationProvider.class);
@@ -68,13 +71,14 @@
osgiHost = (OsgiHost) servletContext.getAttribute(StrutsOsgiListener.OSGI_HOST);
bundleContext = osgiHost.getBundleContext();
bundleAccessor.setBundleContext(bundleContext);
- // I can't figure out why BundleAccessor doesn't get the OsgiHost injected
- //for reason it always gets a new instace...weird
bundleAccessor.setOsgiHost(osgiHost);
this.configuration = configuration;
}
public synchronized void loadPackages() throws ConfigurationException {
+ if (LOG.isTraceEnabled())
+ LOG.trace("Loading packages from XML and Convention on startup");
+
//init action contect
ActionContext ctx = ActionContext.getContext();
if (ctx == null) {
@@ -82,7 +86,6 @@
ActionContext.setContext(ctx);
}
- Map<String, String> packageToBundle = new HashMap<String, String>();
Set<String> bundleNames = new HashSet<String>();
//iterate over the bundles and load packages from them
@@ -90,66 +93,74 @@
String bundleName = bundle.getSymbolicName();
if (shouldProcessBundle(bundle) && !bundleNames.contains(bundleName)) {
bundleNames.add(bundleName);
-
- if (LOG.isDebugEnabled())
- LOG.debug("Loading packages from bundle [#0]", bundleName);
-
- PackageLoader loader = new BundlePackageLoader();
- for (PackageConfig pkg : loader.loadPackages(bundle, bundleContext, objectFactory, configuration.getPackageConfigs())) {
- configuration.addPackageConfig(pkg.getName(), pkg);
- packageToBundle.put(pkg.getName(), bundleName);
- }
+ //load XML and COnvention config
+ loadConfigFromBundle(bundle);
}
}
- //add the loaded packages to the BundleAccessor
- bundleAccessor.setPackageToBundle(packageToBundle);
-
- //reload container, that will load configuration based on bundles (like convention plugin)
- reloadExtraProviders(configuration.getContainer());
-
bundlesChanged = false;
+ bundleContext.addBundleListener(this);
}
- protected void reloadExtraProviders(Container container) {
- //these providers will be reloaded for each bundle
- List<PackageProvider> providers = new ArrayList<PackageProvider>();
- PackageProvider conventionPackageProvider = container.getInstance(PackageProvider.class, "convention.packageProvider");
- if (conventionPackageProvider != null)
- providers.add(conventionPackageProvider);
+ /**
+ * Loads XML config as well as Convention config from a bundle
+ * Limitation: Constants and Beans are ignored on XML config
+ */
+ protected void loadConfigFromBundle(Bundle bundle) {
+ String bundleName = bundle.getSymbolicName();
+ if (LOG.isDebugEnabled())
+ LOG.debug("Loading packages from bundle [#0]", bundleName);
- //reload all providers by bundle
+ //init action context
ActionContext ctx = ActionContext.getContext();
- for (Bundle bundle : osgiHost.getBundles().values()) {
- String bundleName = bundle.getSymbolicName();
- if (shouldProcessBundle(bundle)) {
- try {
- //the Convention plugin will use BundleClassLoaderInterface from the ActionContext to find resources
- //and load classes
- ctx.put(ClassLoaderInterface.CLASS_LOADER_INTERFACE, new BundleClassLoaderInterface());
- ctx.put(BundleAccessor.CURRENT_BUNDLE_NAME, bundleName);
-
- for (PackageProvider provider : providers) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Reloading provider [#0] for bundle [#1]", provider.getClass().getName(), bundleName);
- }
-
- //get the existing packages before reloading the provider (se we can figure out what are the new packages)
- Set<String> packagesBeforeLoading = new HashSet(configuration.getPackageConfigNames());
- provider.loadPackages();
- Set<String> packagesAfterLoading = new HashSet(configuration.getPackageConfigNames());
- packagesAfterLoading.removeAll(packagesBeforeLoading);
- if (!packagesAfterLoading.isEmpty()) {
- //add the new packages to the map of bundle -> package
- for (String packageName : packagesAfterLoading)
- bundleAccessor.addPackageFromBundle(bundle, packageName);
- }
- }
- } finally {
- ctx.put(BundleAccessor.CURRENT_BUNDLE_NAME, null);
- ctx.put(ClassLoaderInterface.CLASS_LOADER_INTERFACE, null);
- }
+ if (ctx == null) {
+ ctx = new ActionContext(new HashMap());
+ ActionContext.setContext(ctx);
+ }
+
+ try {
+ //the Convention plugin will use BundleClassLoaderInterface from the ActionContext to find resources
+ //and load classes
+ ctx.put(ClassLoaderInterface.CLASS_LOADER_INTERFACE, new BundleClassLoaderInterface());
+ ctx.put(BundleAccessor.CURRENT_BUNDLE_NAME, bundleName);
+
+ if (LOG.isTraceEnabled())
+ LOG.trace("Loading XML config from bundle [#0]", bundleName);
+
+ //XML config
+ PackageLoader loader = new BundlePackageLoader();
+ for (PackageConfig pkg : loader.loadPackages(bundle, bundleContext, objectFactory, configuration.getPackageConfigs())) {
+ configuration.addPackageConfig(pkg.getName(), pkg);
+ bundleAccessor.addPackageFromBundle(bundle, pkg.getName());
+ }
+
+ //Convention
+ //get the existing packages before reloading the provider (se we can figure out what are the new packages)
+ Set<String> packagesBeforeLoading = new HashSet(configuration.getPackageConfigNames());
+
+ PackageProvider conventionPackageProvider = configuration.getContainer().getInstance(PackageProvider.class, "convention.packageProvider");
+ if (conventionPackageProvider != null) {
+ if (LOG.isTraceEnabled())
+ LOG.trace("Loading Convention config from bundle [#0]", bundleName);
+ conventionPackageProvider.loadPackages();
}
+
+ Set<String> packagesAfterLoading = new HashSet(configuration.getPackageConfigNames());
+ packagesAfterLoading.removeAll(packagesBeforeLoading);
+ if (!packagesAfterLoading.isEmpty()) {
+ //add the new packages to the map of bundle -> package
+ for (String packageName : packagesAfterLoading)
+ bundleAccessor.addPackageFromBundle(bundle, packageName);
+ }
+
+ if (this.configuration.getRuntimeConfiguration() != null) {
+ //if there is a runtime config, it meas that this method was called froma bundle start event
+ //instead of the initial load, in that case, reload the config
+ this.configuration.rebuildRuntimeConfiguration();
+ }
+ } finally {
+ ctx.put(BundleAccessor.CURRENT_BUNDLE_NAME, null);
+ ctx.put(ClassLoaderInterface.CLASS_LOADER_INTERFACE, null);
}
}
@@ -171,11 +182,6 @@
this.objectFactory = factory;
}
- @Inject("felix")
- public void setOsgiHost(OsgiHost osgiHost) {
- this.osgiHost = osgiHost;
- }
-
@Inject
public void setBundleAccessor(BundleAccessor acc) {
this.bundleAccessor = acc;
@@ -197,11 +203,45 @@
public void destroy() {
try {
- if (LOG.isTraceEnabled())
- LOG.trace("Stopping OSGi container");
osgiHost.destroy();
} catch (Exception e) {
- LOG.error("Failed to stop OSGi container", e);
+ if (LOG.isErrorEnabled())
+ LOG.error("Failed to stop OSGi container", e);
+ }
+ }
+
+ /**
+ * Listens to bundle event to load/unload config
+ */
+ public void bundleChanged(BundleEvent bundleEvent) {
+ Bundle bundle = bundleEvent.getBundle();
+ String bundleName = bundle.getSymbolicName();
+ if (bundleName != null && shouldProcessBundle(bundle)) {
+ switch (bundleEvent.getType()) {
+ case BundleEvent.STARTED:
+ if (LOG.isTraceEnabled())
+ LOG.trace("The bundlde [#0] has been activated and will be scanned for struts configuration", bundleName);
+ loadConfigFromBundle(bundle);
+ break;
+ case BundleEvent.STOPPED:
+ onBundleStopped(bundle);
+ break;
+ }
+ }
+ }
+
+ /**
+ * This method is called when a bundle is stopped, so the config that is related to it is removed
+ *
+ * @param bundle the bundle that stopped
+ */
+ protected void onBundleStopped(Bundle bundle) {
+ Set<String> packages = bundleAccessor.getPackagesByBundle(bundle);
+ if (!packages.isEmpty()) {
+ if (LOG.isTraceEnabled())
+ LOG.trace("The bundle [#0] has been stopped. The packages [#1] will be disabled", bundle.getSymbolicName(), StringUtils.join(packages, ","));
+ for (String packageName : packages)
+ configuration.removePackageConfig(packageName);
}
}
}
Modified: struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/PackageLoader.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/PackageLoader.java?rev=764348&r1=764347&r2=764348&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/PackageLoader.java (original)
+++ struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/PackageLoader.java Mon Apr 13 01:55:02 2009
@@ -32,6 +32,9 @@
import com.opensymphony.xwork2.config.PackageProvider;
import com.opensymphony.xwork2.config.entities.PackageConfig;
+/**
+ * Implementations of this interface can load packages from a Bundle
+ */
public interface PackageLoader {
List<PackageConfig> loadPackages(Bundle bundle, BundleContext bundleContext, ObjectFactory objectFactory, Map<String, PackageConfig> map) throws ConfigurationException;
}
Modified: struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/interceptor/BundleContextAware.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/interceptor/BundleContextAware.java?rev=764348&r1=764347&r2=764348&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/interceptor/BundleContextAware.java (original)
+++ struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/interceptor/BundleContextAware.java Mon Apr 13 01:55:02 2009
@@ -1,3 +1,23 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
package org.apache.struts2.osgi.interceptor;
import org.osgi.framework.BundleContext;
Modified: struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/interceptor/OsgiInterceptor.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/interceptor/OsgiInterceptor.java?rev=764348&r1=764347&r2=764348&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/interceptor/OsgiInterceptor.java (original)
+++ struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/interceptor/OsgiInterceptor.java Mon Apr 13 01:55:02 2009
@@ -1,3 +1,23 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
package org.apache.struts2.osgi.interceptor;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
Modified: struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/interceptor/ServiceAware.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/interceptor/ServiceAware.java?rev=764348&r1=764347&r2=764348&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/interceptor/ServiceAware.java (original)
+++ struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/interceptor/ServiceAware.java Mon Apr 13 01:55:02 2009
@@ -1,3 +1,23 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
package org.apache.struts2.osgi.interceptor;
import java.util.List;
Modified: struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/resources/struts-plugin.xml
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/resources/struts-plugin.xml?rev=764348&r1=764347&r2=764348&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/resources/struts-plugin.xml (original)
+++ struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/resources/struts-plugin.xml Mon Apr 13 01:55:02 2009
@@ -14,10 +14,10 @@
<bean type="org.apache.struts2.osgi.BundleAccessor" class="org.apache.struts2.osgi.DefaultBundleAccessor" />
<bean type="org.apache.struts2.osgi.PackageLoader" class="org.apache.struts2.osgi.BundlePackageLoader" />
+
<bean name="osgi" type="com.opensymphony.xwork2.ObjectFactory" class="org.apache.struts2.osgi.DelegatingObjectFactory" />
<bean name="springOsgi" type="com.opensymphony.xwork2.ObjectFactory" class="org.apache.struts2.osgi.SpringOsgiObjectFactory" />
<bean name="osgi" type="com.opensymphony.xwork2.config.PackageProvider" class="org.apache.struts2.osgi.OsgiConfigurationProvider" />
- <bean name="felix" type="org.apache.struts2.osgi.OsgiHost" class="org.apache.struts2.osgi.FelixOsgiHost" />
<bean name="osgi" type="com.opensymphony.xwork2.util.finder.ClassLoaderInterface" class="org.apache.struts2.osgi.BundleClassLoaderInterface" />
<package name="osgi-default" extends="struts-default" abstract="yes">