You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by mr...@apache.org on 2007/07/29 15:45:03 UTC
svn commit: r560720 - in /struts/sandbox/trunk/struts2-osgi-plugin: ./ src/
src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/
src/main/java/org/apache/struts2/ src/main/java/org/apache/struts2/osgi/
src/main/resources/
Author: mrdon
Date: Sun Jul 29 06:45:02 2007
New Revision: 560720
URL: http://svn.apache.org/viewvc?view=rev&rev=560720
Log:
initial import
Added:
struts/sandbox/trunk/struts2-osgi-plugin/
struts/sandbox/trunk/struts2-osgi-plugin/pom.xml
struts/sandbox/trunk/struts2-osgi-plugin/src/
struts/sandbox/trunk/struts2-osgi-plugin/src/main/
struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/
struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/
struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/
struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/struts2/
struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/struts2/osgi/
struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/struts2/osgi/BundleAccessor.java
struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/struts2/osgi/BundlePackageLoader.java
struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/struts2/osgi/BundleResourceLoader.java
struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/struts2/osgi/DefaultBundleAccessor.java
struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/struts2/osgi/DelegatingObjectFactory.java
struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/struts2/osgi/OsgiConfigurationProvider.java
struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/struts2/osgi/PackageLoader.java
struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/struts2/osgi/StrutsActivator.java
struts/sandbox/trunk/struts2-osgi-plugin/src/main/resources/
struts/sandbox/trunk/struts2-osgi-plugin/src/main/resources/struts-plugin.xml
Added: struts/sandbox/trunk/struts2-osgi-plugin/pom.xml
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-osgi-plugin/pom.xml?view=auto&rev=560720
==============================================================================
--- struts/sandbox/trunk/struts2-osgi-plugin/pom.xml (added)
+++ struts/sandbox/trunk/struts2-osgi-plugin/pom.xml Sun Jul 29 06:45:02 2007
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.struts</groupId>
+ <artifactId>struts2-plugins</artifactId>
+ <version>2.0.9</version>
+ </parent>
+ <groupId>org.apache.struts</groupId>
+ <artifactId>struts2-osgi-plugin</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0-SNAPSHOT</version>
+ <name>Struts 2 OSGI Plugin</name>
+
+ <scm>
+ <connection>scm:svn:http://svn.apache.org/repos/asf/struts/sandbox/trunk/struts2-osgi-plugin/</connection>
+ <developerConnection>scm:svn:https://svn.apache.org/repos/asf/struts/sandbox/trunk/struts2-osgi-plugin/</developerConnection>
+ <url>http://svn.apache.org/viewcvs.cgi/struts/sandbox/trunk/struts2-osgi-plugin/</url>
+ </scm>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.main</artifactId>
+ <version>0.9.0-incubator-SNAPSHOT</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.struts</groupId>
+ <artifactId>struts2-core</artifactId>
+ <version>2.0.9</version>
+ </dependency>
+
+ <dependency>
+ <groupId>velocity-tools</groupId>
+ <artifactId>velocity-tools</artifactId>
+ <version>1.1</version>
+ </dependency>
+
+
+ <dependency>
+ <groupId>velocity</groupId>
+ <artifactId>velocity</artifactId>
+ <version>1.4</version>
+ </dependency>
+ <dependency>
+ <groupId>velocity</groupId>
+ <artifactId>velocity-dep</artifactId>
+ <version>1.4</version>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ <version>3.8.1</version>
+ </dependency>
+ </dependencies>
+</project>
Added: struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/struts2/osgi/BundleAccessor.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/struts2/osgi/BundleAccessor.java?view=auto&rev=560720
==============================================================================
--- struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/struts2/osgi/BundleAccessor.java (added)
+++ struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/struts2/osgi/BundleAccessor.java Sun Jul 29 06:45:02 2007
@@ -0,0 +1,17 @@
+package org.apache.struts2.osgi;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Map;
+
+import org.osgi.framework.Bundle;
+
+public interface BundleAccessor {
+
+ void setBundles(Map<String,Bundle> bundles);
+ Class loadClass(String name) throws ClassNotFoundException;
+ InputStream loadResourceAsStream(String name) throws IOException;
+ URL loadResource(String name);
+
+}
Added: struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/struts2/osgi/BundlePackageLoader.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/struts2/osgi/BundlePackageLoader.java?view=auto&rev=560720
==============================================================================
--- struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/struts2/osgi/BundlePackageLoader.java (added)
+++ struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/struts2/osgi/BundlePackageLoader.java Sun Jul 29 06:45:02 2007
@@ -0,0 +1,84 @@
+package org.apache.struts2.osgi;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.osgi.framework.Bundle;
+
+import com.opensymphony.xwork2.ObjectFactory;
+import com.opensymphony.xwork2.config.Configuration;
+import com.opensymphony.xwork2.config.ConfigurationException;
+import com.opensymphony.xwork2.config.entities.PackageConfig;
+import com.opensymphony.xwork2.config.impl.DefaultConfiguration;
+import com.opensymphony.xwork2.config.providers.XmlConfigurationProvider;
+import com.opensymphony.xwork2.util.location.Location;
+
+public class BundlePackageLoader implements PackageLoader {
+
+ public List<PackageConfig> loadPackages(Bundle bundle, ObjectFactory objectFactory, Map<String,PackageConfig> pkgConfigs) throws ConfigurationException {
+ BundleConfigurationProvider prov = new BundleConfigurationProvider("struts.xml", bundle);
+ Configuration config = new DefaultConfiguration("struts.xml");
+ for (PackageConfig pkg : pkgConfigs.values()) {
+ config.addPackageConfig(pkg.getName(), pkg);
+ }
+ prov.setObjectFactory(objectFactory);
+ prov.init(config);
+ prov.loadPackages();
+ return new ArrayList<PackageConfig>(config.getPackageConfigs().values());
+ }
+
+ static class BundleConfigurationProvider extends XmlConfigurationProvider {
+ private Bundle bundle;
+
+ public BundleConfigurationProvider(String filename, Bundle bundle) {
+ super(filename, true);
+ this.bundle = bundle;
+ }
+ public BundleConfigurationProvider(String filename) { super(filename); }
+
+ @Override
+ protected Iterator<URL> getConfigurationUrls(String fileName) throws IOException {
+ Enumeration<URL> e = bundle.getResources("struts.xml");
+ Iterator<URL> iter = new EnumeratorIterator<URL>(e);
+ return iter;
+ }
+ @Override
+ protected boolean verifyAction(String className, String name,
+ Location loc) {
+ try {
+ Class cls = bundle.loadClass(className);
+ return cls != null;
+ } catch (ClassNotFoundException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+
+ }
+
+ 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();
+ }
+
+ public E next() {
+ return e.nextElement();
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+}
Added: struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/struts2/osgi/BundleResourceLoader.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/struts2/osgi/BundleResourceLoader.java?view=auto&rev=560720
==============================================================================
--- struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/struts2/osgi/BundleResourceLoader.java (added)
+++ struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/struts2/osgi/BundleResourceLoader.java Sun Jul 29 06:45:02 2007
@@ -0,0 +1,30 @@
+package org.apache.struts2.osgi;
+
+import java.io.InputStream;
+
+import org.apache.struts2.util.ClassLoaderUtils;
+import org.apache.struts2.views.velocity.StrutsResourceLoader;
+import org.apache.velocity.exception.ResourceNotFoundException;
+import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
+
+import com.opensymphony.xwork2.inject.Inject;
+
+public class BundleResourceLoader extends ClasspathResourceLoader {
+
+ public synchronized InputStream getResourceStream(String name)
+ throws ResourceNotFoundException {
+ if ((name == null) || (name.length() == 0)) {
+ throw new ResourceNotFoundException("No template name provided");
+ }
+
+ if (name.startsWith("/")) {
+ name = name.substring(1);
+ }
+
+ try {
+ return DefaultBundleAccessor.getInstance().loadResourceAsStream(name);
+ } catch (Exception e) {
+ throw new ResourceNotFoundException(e.getMessage());
+ }
+ }
+}
Added: struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/struts2/osgi/DefaultBundleAccessor.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/struts2/osgi/DefaultBundleAccessor.java?view=auto&rev=560720
==============================================================================
--- struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/struts2/osgi/DefaultBundleAccessor.java (added)
+++ struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/struts2/osgi/DefaultBundleAccessor.java Sun Jul 29 06:45:02 2007
@@ -0,0 +1,93 @@
+package org.apache.struts2.osgi;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.osgi.framework.Bundle;
+
+public class DefaultBundleAccessor implements BundleAccessor {
+
+ private static DefaultBundleAccessor self;
+ private static final Log LOG = LogFactory.getLog(DefaultBundleAccessor.class);
+
+ private Map<String, Bundle> bundles = new HashMap<String, Bundle>();
+ private Map<String,String> classToBundle = new HashMap<String,String>();
+
+ public DefaultBundleAccessor() {
+ self = this;
+ }
+
+ // todo: this is crap
+ public static DefaultBundleAccessor getInstance() {
+ return self;
+ }
+
+ public void setBundles(Map<String,Bundle> bundles) {
+ this.bundles = bundles;
+ classToBundle.clear();
+ }
+
+ public Class<?> loadClass(String name) throws ClassNotFoundException {
+ Class cls = null;
+ if (classToBundle.containsKey(name)) {
+ bundles.get(classToBundle.get(name)).loadClass(name);
+ } else {
+ for (Entry<String,Bundle> entry : bundles.entrySet()) {
+ try {
+ cls = entry.getValue().loadClass(name);
+ if (cls != null) {
+ classToBundle.put(name, entry.getKey());
+ }
+ } catch (ClassNotFoundException ex) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("class not found in bundle "+entry.getValue().getSymbolicName(), ex);
+ }
+ }
+ }
+ }
+
+ if (cls == null) {
+ throw new ClassNotFoundException("Unable to find class "+name+" in bundles");
+ }
+ return cls;
+ }
+
+ public List<URL> loadResources(String name) throws IOException {
+ List<URL> resources = new ArrayList<URL>();
+ for (Entry<String,Bundle> entry : bundles.entrySet()) {
+ Enumeration e = entry.getValue().getResources(name);
+ while (e.hasMoreElements()) {
+ resources.add((URL) e.nextElement());
+ }
+ }
+ return resources;
+ }
+
+ public URL loadResource(String name) {
+ URL url = null;
+ for (Entry<String,Bundle> entry : bundles.entrySet()) {
+ url = entry.getValue().getResource(name);
+ if (url != null)
+ break;
+ }
+ return url;
+ }
+
+ public InputStream loadResourceAsStream(String name) throws IOException {
+ URL url = loadResource(name);
+ if (url != null) {
+ return url.openStream();
+ }
+ return null;
+ }
+
+}
Added: struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/struts2/osgi/DelegatingObjectFactory.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/struts2/osgi/DelegatingObjectFactory.java?view=auto&rev=560720
==============================================================================
--- struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/struts2/osgi/DelegatingObjectFactory.java (added)
+++ struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/struts2/osgi/DelegatingObjectFactory.java Sun Jul 29 06:45:02 2007
@@ -0,0 +1,40 @@
+package org.apache.struts2.osgi;
+
+import com.opensymphony.xwork2.ObjectFactory;
+import com.opensymphony.xwork2.inject.Container;
+import com.opensymphony.xwork2.inject.Inject;
+
+public class DelegatingObjectFactory extends ObjectFactory {
+ private ObjectFactory delegateObjectFactory;
+ private BundleAccessor bundleResourceLoader;
+
+ @Inject
+ public DelegatingObjectFactory(@Inject Container container,
+ @Inject("struts.objectFactory.delegate") String delegate) {
+
+ if (delegate == null) {
+ delegate = "struts";
+ }
+ delegateObjectFactory = container.getInstance(ObjectFactory.class, delegate);
+ }
+
+ @Inject
+ public void setBundleResourceLoader(BundleAccessor rl) {
+ this.bundleResourceLoader = rl;
+ }
+
+
+ @Override
+ public Class getClassInstance(String className) throws ClassNotFoundException {
+ try
+ {
+ return delegateObjectFactory.getClassInstance(className);
+ }
+ catch (ClassNotFoundException cnfe)
+ {
+ return bundleResourceLoader.loadClass(className);
+ }
+ }
+
+
+}
Added: struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/struts2/osgi/OsgiConfigurationProvider.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/struts2/osgi/OsgiConfigurationProvider.java?view=auto&rev=560720
==============================================================================
--- struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/struts2/osgi/OsgiConfigurationProvider.java (added)
+++ struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/struts2/osgi/OsgiConfigurationProvider.java Sun Jul 29 06:45:02 2007
@@ -0,0 +1,336 @@
+package org.apache.struts2.osgi;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+
+import javax.servlet.ServletContext;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.felix.framework.Felix;
+import org.apache.felix.framework.cache.BundleCache;
+import org.apache.felix.framework.util.FelixConstants;
+import org.apache.felix.framework.util.StringMap;
+import org.apache.struts2.views.velocity.VelocityManager;
+import org.apache.velocity.app.Velocity;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.BundleListener;
+import org.osgi.framework.Constants;
+import org.osgi.framework.FrameworkEvent;
+import org.osgi.framework.FrameworkListener;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+
+import com.opensymphony.xwork2.ObjectFactory;
+import com.opensymphony.xwork2.config.Configuration;
+import com.opensymphony.xwork2.config.ConfigurationException;
+import com.opensymphony.xwork2.config.ConfigurationProvider;
+import com.opensymphony.xwork2.config.entities.PackageConfig;
+import com.opensymphony.xwork2.inject.ContainerBuilder;
+import com.opensymphony.xwork2.inject.Inject;
+import com.opensymphony.xwork2.util.ResolverUtil.Test;
+import com.opensymphony.xwork2.util.location.LocatableProperties;
+
+public class OsgiConfigurationProvider implements ConfigurationProvider {
+
+ private static final Log log = LogFactory.getLog(OsgiConfigurationProvider.class);
+
+ private Felix felix;
+ private Map<String,Bundle> bundles = Collections.synchronizedMap(new HashMap<String,Bundle>());
+ private Configuration configuration;
+ private BundleContext bundleContext;
+ private ServletContext servletContext;
+ private boolean bundlesChanged = false;
+
+ private ObjectFactory objectFactory;
+
+ @Inject
+ public void setBundleAccessor(BundleAccessor acc) {
+ acc.setBundles(bundles);
+ }
+
+ @Inject
+ public void setServletContext(ServletContext ctx) {
+ this.servletContext = ctx;
+ }
+
+ @Inject
+ public void setObjectFactory(ObjectFactory factory) {
+ this.objectFactory = factory;
+ }
+
+ @Inject
+ public void setVelocityManager(VelocityManager vm) {
+ Properties props = new Properties();
+ props.setProperty("osgi.resource.loader.description","OSGI bundle loader");
+ props.setProperty("osgi.resource.loader.class", BundleResourceLoader.class.getName());
+ props.setProperty(Velocity.RESOURCE_LOADER, "strutsclass,osgi");
+ vm.setVelocityProperties(props);
+ }
+
+ public void destroy() {
+ try {
+ felix.stop();
+ } catch (BundleException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ bundles = null;
+ }
+
+ public void init(Configuration configuration) throws ConfigurationException {
+ loadOsgi();
+ this.configuration = configuration;
+ }
+
+ public synchronized void loadPackages() throws ConfigurationException {
+ ServiceReference[] refs;
+ try {
+ refs = bundleContext.getServiceReferences(PackageLoader.class.getName(), null);
+ } catch (InvalidSyntaxException e) {
+ throw new ConfigurationException(e);
+ }
+ Set bundleNames = new HashSet();
+ if (refs != null) {
+ for (ServiceReference ref : refs) {
+ if (!bundleNames.contains(ref.getBundle().getSymbolicName())) {
+ bundleNames.add(ref.getBundle().getSymbolicName());
+ log.info("Loading packages from bundle "+ref.getBundle().getSymbolicName());
+ PackageLoader loader = (PackageLoader) bundleContext.getService(ref);
+ for (PackageConfig pkg : loader.loadPackages(ref.getBundle(), objectFactory, configuration.getPackageConfigs())) {
+ configuration.addPackageConfig(pkg.getName(), pkg);
+ }
+ }
+ }
+ }
+ bundlesChanged = false;
+ }
+
+ public synchronized boolean needsReload() {
+ return bundlesChanged;
+ }
+
+ public void register(ContainerBuilder builder, LocatableProperties props)
+ throws ConfigurationException {
+ }
+
+ protected void loadOsgi() {
+ Map configMap = new StringMap(false);
+ configMap.put(Constants.FRAMEWORK_SYSTEMPACKAGES,
+ "org.osgi.framework; version=1.4.0," +
+ "org.osgi.service.packageadmin; version=1.2.0," +
+ "org.osgi.service.startlevel; version=1.0.0," +
+ "org.osgi.service.url; version=1.0.0");
+
+ Set<String> bundlePaths = new HashSet<String>(findInPackage("bundles"));
+ log.info("Loading Struts bundles "+bundlePaths);
+
+ StringBuilder sb = new StringBuilder();
+ for (String path : bundlePaths) {
+ sb.append(path).append(" ");
+ }
+
+ configMap.put(FelixConstants.AUTO_START_PROP + ".1",
+ sb.toString());
+ configMap.put(BundleCache.CACHE_PROFILE_DIR_PROP, "/tmp/foo");//System.getProperty("tmp.dir"));
+ configMap.put(BundleCache.CACHE_DIR_PROP, "jim");
+ configMap.put(FelixConstants.EMBEDDED_EXECUTION_PROP, "true");
+ configMap.put(FelixConstants.SERVICE_URLHANDLERS_PROP, "false");
+ configMap.put("org.osgi.framework.bootdelegation", "org.apache.*");
+ configMap.put("osgi.parentClassloader", "app");
+ configMap.put("felix.log.level", "4");
+ configMap.put(FelixConstants.BUNDLE_CLASSPATH, ".");
+
+ try {
+ List list = new ArrayList();
+ list.add(new BundleRegistration());
+ // Now create an instance of the framework.
+ felix = new Felix(configMap, list);
+ felix.start();
+ }
+ catch (Exception ex) {
+ throw new ConfigurationException("Couldn't start Felix (OSGi)", ex);
+ }
+
+ // Wait for all bundles to load
+ while (bundles.size() < bundlePaths.size()) {
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+
+ }
+
+ class BundleRegistration implements BundleActivator, BundleListener {
+
+ public void start(BundleContext context) throws Exception {
+ context.addBundleListener(this);
+ bundleContext = context;
+ }
+
+ public void stop(BundleContext arg0) throws Exception {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void bundleChanged(BundleEvent evt) {
+ if (evt.getType() == evt.INSTALLED) {
+ log.debug("Installed bundle "+evt.getBundle().getSymbolicName());
+ bundles.put(evt.getBundle().getLocation(), evt.getBundle());
+ bundlesChanged = true;
+ }
+
+ // Copy out all view files
+ /*if (evt.getType() == evt.STARTED) {
+ Enumeration e = evt.getBundle().findEntries("/view/", null, true);
+ while (e != null && e.hasMoreElements()) {
+ URL url = (URL) e.nextElement();
+ System.out.println("found view url: "+url);
+ }
+ }
+ */
+ }
+
+ }
+
+ /**
+ * Scans for classes starting at the package provided and descending into subpackages.
+ * Each class is offered up to the Test as it is discovered, and if the Test returns
+ * true the class is retained. Accumulated classes can be fetched by calling
+ * {@link #getClasses()}.
+ *
+ * @param test an instance of {@link Test} that will be used to filter classes
+ * @param packageName the name of the package from which to start scanning for
+ * classes, e.g. {@code net.sourceforge.stripes}
+ */
+ public List<String> findInPackage(String packageName) {
+ packageName = packageName.replace('.', '/');
+ Enumeration<URL> urls;
+ List<String> paths = new ArrayList<String>();
+
+ try {
+ urls = Thread.currentThread().getContextClassLoader().getResources(packageName);
+ }
+ catch (IOException ioe) {
+ log.warn("Could not read package: " + packageName, ioe);
+ return paths;
+ }
+
+ while (urls.hasMoreElements()) {
+ try {
+ String urlPath = urls.nextElement().getFile();
+ urlPath = URLDecoder.decode(urlPath, "UTF-8");
+
+ // If it's a file in a directory, trim the stupid file: spec
+ if ( urlPath.startsWith("file:") ) {
+ urlPath = urlPath.substring(5);
+ }
+
+ // Else it's in a JAR, grab the path to the jar
+ if (urlPath.indexOf('!') > 0) {
+ urlPath = urlPath.substring(0, urlPath.indexOf('!'));
+ }
+
+ //log.info("Scanning for classes in [" + urlPath + "] matching criteria: " + test);
+ File file = new File(urlPath);
+ if ( file.isDirectory() ) {
+ loadImplementationsInDirectory(paths, packageName, file);
+ }
+ else {
+ loadImplementationsInJar(paths, packageName, file);
+ }
+ }
+ catch (IOException ioe) {
+ log.warn("could not read entries", ioe);
+ }
+ }
+ return paths;
+ }
+
+
+ /**
+ * Finds matches in a physical directory on a filesystem. Examines all
+ * files within a directory - if the File object is not a directory, and ends with <i>.class</i>
+ * the file is loaded and tested to see if it is acceptable according to the Test. Operates
+ * recursively to find classes within a folder structure matching the package structure.
+ *
+ * @param test a Test used to filter the classes that are discovered
+ * @param parent the package name up to this directory in the package hierarchy. E.g. if
+ * /classes is in the classpath and we wish to examine files in /classes/org/apache then
+ * the values of <i>parent</i> would be <i>org/apache</i>
+ * @param location a File object representing a directory
+ */
+ private void loadImplementationsInDirectory(List<String> paths, String parent, File location) {
+ File[] files = location.listFiles();
+ StringBuilder builder = null;
+
+ for (File file : files) {
+ builder = new StringBuilder(100);
+ builder.append(parent).append("/").append(file.getName());
+ String packageOrClass = ( parent == null ? file.getName() : builder.toString() );
+
+ if (file.isDirectory()) {
+ loadImplementationsInDirectory(paths, packageOrClass, file);
+ }
+ else if (file.getName().endsWith(".jar")) {
+ try {
+ paths.add(file.toURL().toString());
+ } catch (MalformedURLException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ /**
+ * Finds matching classes within a jar files that contains a folder structure
+ * matching the package structure. If the File is not a JarFile or does not exist a warning
+ * will be logged, but no error will be raised.
+ *
+ * @param test a Test used to filter the classes that are discovered
+ * @param parent the parent package under which classes must be in order to be considered
+ * @param jarfile the jar file to be examined for classes
+ */
+ private void loadImplementationsInJar(List<String> paths, String parent, File jarfile) {
+
+ try {
+ JarEntry entry;
+ JarInputStream jarStream = new JarInputStream(new FileInputStream(jarfile));
+
+ while ( (entry = jarStream.getNextJarEntry() ) != null) {
+ String name = entry.getName();
+ if (!entry.isDirectory() && name.startsWith(parent) && name.endsWith(".jar")) {
+ paths.add(jarfile.toURL()+"!"+entry.getName());
+ }
+ }
+ }
+ catch (IOException ioe) {
+ log.error("Could not search jar file '" + jarfile + "' due to an IOException", ioe);
+ }
+ }
+
+}
Added: struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/struts2/osgi/PackageLoader.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/struts2/osgi/PackageLoader.java?view=auto&rev=560720
==============================================================================
--- struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/struts2/osgi/PackageLoader.java (added)
+++ struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/struts2/osgi/PackageLoader.java Sun Jul 29 06:45:02 2007
@@ -0,0 +1,14 @@
+package org.apache.struts2.osgi;
+
+import java.util.List;
+import java.util.Map;
+
+import org.osgi.framework.Bundle;
+
+import com.opensymphony.xwork2.ObjectFactory;
+import com.opensymphony.xwork2.config.ConfigurationException;
+import com.opensymphony.xwork2.config.entities.PackageConfig;
+
+public interface PackageLoader {
+ List<PackageConfig> loadPackages(Bundle bundle, ObjectFactory objectFactory, Map<String,PackageConfig> map) throws ConfigurationException;
+}
Added: struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/struts2/osgi/StrutsActivator.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/struts2/osgi/StrutsActivator.java?view=auto&rev=560720
==============================================================================
--- struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/struts2/osgi/StrutsActivator.java (added)
+++ struts/sandbox/trunk/struts2-osgi-plugin/src/main/java/org/apache/struts2/osgi/StrutsActivator.java Sun Jul 29 06:45:02 2007
@@ -0,0 +1,19 @@
+package org.apache.struts2.osgi;
+
+import java.util.Properties;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+public class StrutsActivator implements BundleActivator {
+
+ public void start(final BundleContext ctx) throws Exception {
+ ctx.registerService(PackageLoader.class.getName(), new BundlePackageLoader(), new Properties());
+ ctx.getBundle().loadClass("org.apache.struts2.osgi.BundleAccessor");
+ ctx.getBundle().loadClass("org.twdata.osgitest.foo.FooAction");
+ }
+
+ public void stop(BundleContext ctx) throws Exception {
+ }
+
+}
Added: struts/sandbox/trunk/struts2-osgi-plugin/src/main/resources/struts-plugin.xml
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-osgi-plugin/src/main/resources/struts-plugin.xml?view=auto&rev=560720
==============================================================================
--- struts/sandbox/trunk/struts2-osgi-plugin/src/main/resources/struts-plugin.xml (added)
+++ struts/sandbox/trunk/struts2-osgi-plugin/src/main/resources/struts-plugin.xml Sun Jul 29 06:45:02 2007
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!DOCTYPE struts PUBLIC
+ "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
+ "http://struts.apache.org/dtds/struts-2.0.dtd">
+
+<struts>
+ <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" />
+
+ <constant name="struts.objectFactory" value="osgi" />
+ <constant name="struts.objectFactory.delegate" value="struts" />
+
+</struts>