Author: musachy Date: Tue Apr 7 18:00:04 2009 New Revision: 762880 URL: http://svn.apache.org/viewvc?rev=762880&view=rev Log: Add Spring OSGi support
Added: struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/SpringOsgiObjectFactory.java Modified: struts/sandbox/trunk/struts2-osgi-plugin/plugin/pom.xml 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/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/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/OsgiHost.java struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/OsgiUtil.java struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/resources/struts-plugin.xml Modified: struts/sandbox/trunk/struts2-osgi-plugin/plugin/pom.xml URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-osgi-plugin/plugin/pom.xml?rev=762880&r1=762879&r2=762880&view=diff ============================================================================== --- struts/sandbox/trunk/struts2-osgi-plugin/plugin/pom.xml (original) +++ struts/sandbox/trunk/struts2-osgi-plugin/plugin/pom.xml Tue Apr 7 18:00:04 2009 @@ -45,19 +45,6 @@ </dependency> <dependency> - <groupId>org.apache.felix</groupId> - <artifactId>org.apache.felix.fileinstall</artifactId> - <version>0.9.0</version> - - <exclusions> - <exclusion> - <groupId>org.apache.felix</groupId> - <artifactId>javax.servlet</artifactId> - </exclusion> - </exclusions> - </dependency> - - <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-core</artifactId> <version>2.1.7-SNAPSHOT</version> 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=762880&r1=762879&r2=762880&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 Tue Apr 7 18:00:04 2009 @@ -15,7 +15,7 @@ String CURRENT_BUNDLE_NAME = "__bundle_name__"; - void init(Map<String, Bundle> bundles, BundleContext bundleContext, Map<String, String> packageToBundle); + void init(Map<String, Bundle> bundles, Map<String, String> packageToBundle); Class loadClass(String name) throws ClassNotFoundException; @@ -31,5 +31,11 @@ ServiceReference getServiceReference(String className); + ServiceReference[] getServiceReferences(String className, String params) throws InvalidSyntaxException; + + public ServiceReference[] getAllServiceReferences(String className); + void addPackageFromBundle(Bundle bundle, String packageName); + + void setBundleContext(BundleContext bundleContext); } 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=762880&r1=762879&r2=762880&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 Tue Apr 7 18:00:04 2009 @@ -68,30 +68,6 @@ Enumeration<URL> e = bundle.getResources("struts.xml"); return e.hasMoreElements() ? new EnumeratorIterator<URL>(e) : null; } - - /* - * Try to find the class (className) on this bundle. If the class it not found, - * try to find an Spring bean with that name. - */ - @Override - protected boolean verifyAction(String className, String name, Location loc) { - try { - return bundle.loadClass(className) != null; - } catch (Exception e) { - if (LOG.isDebugEnabled()) - LOG.debug("Unable to find class [#0] in bundle [#1]", className, bundle.getSymbolicName()); - - //try to find a bean with that id - try { - return OsgiUtil.isValidBean(bundleContext, className); - } catch (Exception e1) { - if (LOG.isDebugEnabled()) - LOG.debug("Unable to find bean [#0]", className); - } - - return false; - } - } } static class EnumeratorIterator<E> implements Iterator<E> { 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=762880&r1=762879&r2=762880&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 Tue Apr 7 18:00:04 2009 @@ -41,16 +41,33 @@ } public Object getService(ServiceReference ref) { - return bundleContext.getService(ref); + return bundleContext != null ? bundleContext.getService(ref) : null; } public ServiceReference getServiceReference(String className) { - return bundleContext.getServiceReference(className); + return bundleContext != null ? bundleContext.getServiceReference(className) : null; } - public void init(Map<String, Bundle> bundles, BundleContext bundleContext, Map<String, String> packageToBundle) { + public ServiceReference[] getAllServiceReferences(String className) { + if (bundleContext != null) { + try { + return bundleContext.getServiceReferences(className, null); + } catch (InvalidSyntaxException e) { + //cannot happen we are passing null as the param + if (LOG.isErrorEnabled()) + LOG.error("Invalid syntaxt for service lookup", e); + } + } + + return null; + } + + public ServiceReference[] getServiceReferences(String className, String params) throws InvalidSyntaxException { + return bundleContext != null ? bundleContext.getServiceReferences(className, params) : null; + } + + public void init(Map<String, Bundle> bundles, Map<String, String> packageToBundle) { this.bundles = Collections.unmodifiableMap(bundles); - this.bundleContext = bundleContext; this.packageToBundle = packageToBundle; this.packagesByBundle = new HashMap<Bundle, Set<String>>(); for (Map.Entry<String, String> entry : packageToBundle.entrySet()) { @@ -93,18 +110,6 @@ } if (cls == null) { - //try to find a bean with that id (hack for spring that searches all bundles) - try { - Object bean = OsgiUtil.getBean(bundleContext, className); - if (bean != null) - cls = bean.getClass(); - } catch (Exception e) { - if (LOG.isDebugEnabled()) - LOG.debug("Unable to find bean [#0]", className); - } - } - - if (cls == null) { throw new ClassNotFoundException("Unable to find class " + className + " in bundles"); } return cls; @@ -199,4 +204,8 @@ } return null; } + + public void setBundleContext(BundleContext bundleContext) { + this.bundleContext = bundleContext; + } } 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=762880&r1=762879&r2=762880&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 Tue Apr 7 18:00:04 2009 @@ -26,18 +26,20 @@ import com.opensymphony.xwork2.util.finder.ResourceFinder; import com.opensymphony.xwork2.util.logging.Logger; import com.opensymphony.xwork2.util.logging.LoggerFactory; +import com.opensymphony.xwork2.ActionContext; import org.apache.commons.lang.xwork.StringUtils; import org.apache.felix.framework.Felix; import org.apache.felix.framework.util.FelixConstants; import org.apache.felix.main.AutoActivator; import org.apache.felix.main.Main; import org.apache.felix.shell.ShellService; +import org.apache.struts2.StrutsStatics; import org.osgi.framework.Bundle; import org.osgi.framework.BundleActivator; import org.osgi.framework.Constants; -import org.osgi.service.log.LogService; import org.osgi.util.tracker.ServiceTracker; +import javax.servlet.ServletContext; import java.io.File; import java.io.FilenameFilter; import java.io.IOException; @@ -63,16 +65,13 @@ public class FelixOsgiHost implements OsgiHost { private static final Logger LOG = LoggerFactory.getLogger(FelixOsgiHost.class); - private static final String FELIX_FILEINSTALL_POLL = "felix.fileinstall.poll"; - private static final String FELIX_FILEINSTALL_DIR = "felix.fileinstall.dir"; - private static final String FELIX_FILEINSTALL_DEBUG = "felix.fileinstall.debug"; - private Felix felix; private Map<String, Bundle> bundles = Collections.synchronizedMap(new HashMap<String, Bundle>()); private List<? extends BundleActivator> extraBundleActivators; private boolean cleanBundleCache; private static Pattern versionPattern = Pattern.compile("([\\d])+[\\.-]"); private String startRunLevel; + private ServletContext servletContext; protected void startFelix() { //load properties from felix embedded file @@ -90,13 +89,10 @@ int bundlePaths = addAutoStartBundles(configProps); // Bundle cache - configProps.setProperty(Constants.FRAMEWORK_STORAGE, System.getProperty("java.io.tmpdir") + ".felix-cache"); - - // File Install - /*String bundlesDir = Thread.currentThread().getContextClassLoader().getResource("bundles").getPath(); - configProps.put(OsgiConfigurationProvider.FELIX_FILEINSTALL_POLL, "5000"); - configProps.put(OsgiConfigurationProvider.FELIX_FILEINSTALL_DIR, bundlesDir); - configProps.put(OsgiConfigurationProvider.FELIX_FILEINSTALL_DEBUG, "1");*/ + 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); if (cleanBundleCache) { if (LOG.isDebugEnabled()) @@ -108,7 +104,7 @@ configProps.put(FelixConstants.SERVICE_URLHANDLERS_PROP, "false"); configProps.put(FelixConstants.LOG_LEVEL_PROP, "4"); configProps.put(FelixConstants.BUNDLE_CLASSPATH, "."); - configProps.put(FelixConstants.FRAMEWORK_BEGINNING_STARTLEVEL, startRunLevel); + configProps.put(FelixConstants.FRAMEWORK_BEGINNING_STARTLEVEL, startRunLevel); try { List<BundleActivator> list = new ArrayList<BundleActivator>(); @@ -134,6 +130,8 @@ LOG.error("An error occured while waiting for bundle activation", e); } } + + addSpringOSGiSupport(); } private int addAutoStartBundles(Properties configProps) { @@ -141,20 +139,34 @@ List<String> bundleJarsLevel1 = new ArrayList<String>(); bundleJarsLevel1.add(getJarUrl(ShellService.class)); bundleJarsLevel1.add(getJarUrl(ServiceTracker.class)); - bundleJarsLevel1.add(getJarUrl(LogService.class)); + + //add third party bundles in level 2 + List<String> bundleJarsLevel2 = new ArrayList<String>(); + bundleJarsLevel2.addAll(getBundlesInDir("bundles/other")); + + //start app bundles in level 3 + List<String> bundleJarsLevel3 = new ArrayList<String>(); + bundleJarsLevel2.addAll(getBundlesInDir("bundles")); + configProps.put(AutoActivator.AUTO_START_PROP + ".1", StringUtils.join(bundleJarsLevel1, " ")); + configProps.put(AutoActivator.AUTO_START_PROP + ".2", StringUtils.join(bundleJarsLevel2, " ")); + configProps.put(AutoActivator.AUTO_START_PROP + ".3", StringUtils.join(bundleJarsLevel3, " ")); - //start app bundles in level2 - List<String> bundleJarsLevel2 = new ArrayList<String>(); + + return bundleJarsLevel1.size() + bundleJarsLevel2.size() + bundleJarsLevel3.size(); + } + + private List<String> getBundlesInDir(String dir) { + List<String> bundleJars = new ArrayList<String>(); try { + ResourceFinder finder = new ResourceFinder(); - URL url = finder.find("bundles"); + URL url = finder.find(dir); if (url != null) { if ("file".equals(url.getProtocol())) { File bundlerDir = new File(url.toURI()); File[] bundles = bundlerDir.listFiles(new FilenameFilter() { - @Override public boolean accept(File file, String name) { return StringUtils.endsWith(name, ".jar"); } @@ -166,26 +178,41 @@ String externalForm = bundle.toURI().toURL().toExternalForm(); if (LOG.isDebugEnabled()) LOG.debug("Adding bundle [#0]", externalForm); - bundleJarsLevel2.add(externalForm); - } + bundleJars.add(externalForm); + } } else if (LOG.isDebugEnabled()) { - LOG.debug("No bundles found under the 'bundles' directory"); + LOG.debug("No bundles found under the [#0] directory", dir); } } else if (LOG.isWarnEnabled()) - LOG.warn("Unable to read 'bundles' directory"); + LOG.warn("Unable to read [#0] directory", dir); } else if (LOG.isWarnEnabled()) - LOG.warn("The 'bundles' directory was not found"); + LOG.warn("The [#0] directory was not found", dir); } catch (Exception e) { if (LOG.isWarnEnabled()) - LOG.warn("Unable load bundles from the 'bundles' directory", e); - return 0; + LOG.warn("Unable load bundles from the [#0] directory", e, dir); } + return bundleJars; + } - //autostart bundles in leve 2 - configProps.put(AutoActivator.AUTO_START_PROP + ".2", StringUtils.join(bundleJarsLevel2, " ")); - - return bundleJarsLevel1.size() + bundleJarsLevel2.size(); + private void addSpringOSGiSupport() { + // see the javadoc for org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext for more details + // OsgiBundleXmlWebApplicationContext expects the the BundleContext to be set in the ServletContext under the attribute + // OsgiBundleXmlWebApplicationContext.BUNDLE_CONTEXT_ATTRIBUTE + try { + Class clazz = Class.forName("org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext"); + String key = (String) clazz.getDeclaredField("BUNDLE_CONTEXT_ATTRIBUTE").get(null); + servletContext.setAttribute(key, felix.getBundleContext()); + } catch (ClassNotFoundException e) { + if (LOG.isDebugEnabled()) { + LOG.debug("Spring OSGi support is not enabled"); + } + } catch (Exception e) { + if (LOG.isErrorEnabled()) { + LOG.error("The API of Spring OSGi has changed and the field [#0] is no longer available. The OSGi plugin needs to be updated", e, + "org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext.BUNDLE_CONTEXT_ATTRIBUTE"); + } + } } private String getJarUrl(Class clazz) { @@ -275,7 +302,7 @@ static String getVersionFromString(String str) { Matcher matcher = versionPattern.matcher(str); List<String> parts = new ArrayList<String>(); - while(matcher.find()) { + while (matcher.find()) { parts.add(matcher.group(1)); } @@ -283,7 +310,7 @@ if (parts.size() == 0) return "1.0.0"; - while(parts.size() < 3) + while (parts.size() < 3) parts.add("0"); return StringUtils.join(parts, "."); @@ -294,8 +321,8 @@ try { return finder.findProperties(fileName); } catch (IOException e) { - if (LOG.isErrorEnabled()) - LOG.error("Unable to read property file [#]", fileName); + if (LOG.isErrorEnabled()) + LOG.error("Unable to read property file [#]", fileName); return new Properties(); } } @@ -308,7 +335,11 @@ } public Map<String, Bundle> getBundles() { - return bundles; + return Collections.unmodifiableMap(bundles); + } + + public void addBundle(Bundle bundle) { + bundles.put(bundle.getSymbolicName(), bundle); } public void destroy() throws Exception { @@ -333,4 +364,9 @@ public void setStartRunLevel(String startRunLevel) { this.startRunLevel = startRunLevel; } + + @Inject + public void setServletContext(ServletContext servletContext) { + this.servletContext = servletContext; + } } 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=762880&r1=762879&r2=762880&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 Tue Apr 7 18:00:04 2009 @@ -78,6 +78,7 @@ } catch (InvalidSyntaxException e) { throw new ConfigurationException(e); } + Map<String, String> packageToBundle = new HashMap<String, String>(); Set<String> bundleNames = new HashSet<String>(); if (refs != null) { @@ -96,7 +97,7 @@ } } } - bundleAccessor.init(osgiHost.getBundles(), bundleContext, packageToBundle); + bundleAccessor.init(osgiHost.getBundles(), packageToBundle); //reload container that will load configuration based on bundles (like convention plugin) reloadExtraProviders(configuration.getContainer()); @@ -185,6 +186,7 @@ public void start(BundleContext context) throws Exception { context.addBundleListener(this); bundleContext = context; + bundleAccessor.setBundleContext(bundleContext); } public void stop(BundleContext ctx) throws Exception { @@ -195,7 +197,7 @@ if (LOG.isDebugEnabled()) LOG.debug("Started bundle [#0]", evt.getBundle().getSymbolicName()); - osgiHost.getBundles().put(evt.getBundle().getSymbolicName(), evt.getBundle()); + osgiHost.addBundle(evt.getBundle()); bundlesChanged = true; } } Modified: struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/OsgiHost.java URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/OsgiHost.java?rev=762880&r1=762879&r2=762880&view=diff ============================================================================== --- struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/OsgiHost.java (original) +++ struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/OsgiHost.java Tue Apr 7 18:00:04 2009 @@ -31,4 +31,5 @@ void init() throws Exception; void setExtraBundleActivators(List<? extends BundleActivator> extraBundleActivators); Map<String, Bundle> getBundles(); + void addBundle(Bundle bundle); } Modified: struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/OsgiUtil.java URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/OsgiUtil.java?rev=762880&r1=762879&r2=762880&view=diff ============================================================================== --- struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/OsgiUtil.java (original) +++ struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/OsgiUtil.java Tue Apr 7 18:00:04 2009 @@ -15,28 +15,6 @@ public class OsgiUtil { private static final Logger LOG = LoggerFactory.getLogger(OsgiUtil.class); - public static boolean isValidBean(BundleContext bundleContext, String beanId) throws InvalidSyntaxException, SecurityException, IllegalArgumentException, NoSuchMethodException, IllegalAccessException, InvocationTargetException { - return getBean(bundleContext, beanId) != null; - } - - public static Object getBean(BundleContext bundleContext, String beanId) throws InvalidSyntaxException, SecurityException, IllegalArgumentException, NoSuchMethodException, IllegalAccessException, InvocationTargetException { - ServiceReference[] references = bundleContext.getAllServiceReferences( - "org.springframework.context.ApplicationContext", null); - if (references != null && references.length > 0) { - Object beanFactory = bundleContext.getService(references[0]); - //this class and the BeanFactory service are loaded by different classloaders - //so we cannot cast to a common interface (is there any other (nice) way of doing this?) - return getBean(beanFactory, beanId); - } - - return null; - } - - private static Object getBean(Object beanFactory, String beanId) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException { - Method getBeanMethod = beanFactory.getClass().getMethod("getBean", String.class); - return getBeanMethod.invoke(beanFactory, beanId); - } - /** * A bundle is a jar, and a bunble URL will be useless to clients, this method translates * a URL to a resource inside a bundle from "bundle:something/path" to "jar:file:bundlelocation!/path" @@ -52,4 +30,36 @@ return bundleUrl; } + + /** + * Calls getBean() on the passed object using refelection. Used on Spring context + * because they are loaded from bundles (in anothe class loader) + */ + public static Object getBean(Object beanFactory, String beanId) { + try { + Method getBeanMethod = beanFactory.getClass().getMethod("getBean", String.class); + return getBeanMethod.invoke(beanFactory, beanId); + } catch (Exception ex) { + if (LOG.isErrorEnabled()) + LOG.error("Unable to call getBean() on object of type [#0], with bean id [#1]", ex, beanFactory.getClass().getName(), beanId); + } + + return null; + } + + /** + * Calls containsBean on the passed object using refelection. Used on Spring context + * because they are loaded from bundles (in anothe class loader) + */ + public static boolean containsBean(Object beanFactory, String beanId) { + try { + Method getBeanMethod = beanFactory.getClass().getMethod("containsBean", String.class); + return (Boolean) getBeanMethod.invoke(beanFactory, beanId); + } catch (Exception ex) { + if (LOG.isErrorEnabled()) + LOG.error("Unable to call containsBean() on object of type [#0], with bean id [#1]", ex, beanFactory.getClass().getName(), beanId); + } + + return false; + } } Added: struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/SpringOsgiObjectFactory.java URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/SpringOsgiObjectFactory.java?rev=762880&view=auto ============================================================================== --- struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/SpringOsgiObjectFactory.java (added) +++ struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/SpringOsgiObjectFactory.java Tue Apr 7 18:00:04 2009 @@ -0,0 +1,76 @@ +/* + * $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; + +import com.opensymphony.xwork2.ObjectFactory; +import com.opensymphony.xwork2.inject.Inject; +import org.osgi.framework.ServiceReference; + +import java.util.Map; + +public class SpringOsgiObjectFactory extends ObjectFactory { + private final static String SPRING_SERVICE_NAME = "org.springframework.context.ApplicationContext"; + + private BundleAccessor bundleAccessor; + + public Object buildBean(String className, Map<String, Object> extraContext, boolean injectInternal) throws Exception { + return containsBean(className) ? getBean(className) : super.buildBean(className, extraContext); + } + + public Object buildBean(Class clazz, Map<String, Object> extraContext) throws Exception { + return clazz.newInstance(); + } + + public Class getClassInstance(String className) throws ClassNotFoundException { + return containsBean(className) ? getBean(className).getClass() : super.getClassInstance(className); + } + + protected Object getBean(String beanName) { + ServiceReference[] refs = bundleAccessor.getAllServiceReferences(SPRING_SERVICE_NAME); + if (refs != null) { + for (ServiceReference ref : refs) { + Object context = bundleAccessor.getService(ref); + if (OsgiUtil.containsBean(context, beanName)) + return OsgiUtil.getBean(context, beanName); + } + } + + return null; + } + + protected boolean containsBean(String beanName) { + ServiceReference[] refs = bundleAccessor.getAllServiceReferences(SPRING_SERVICE_NAME); + if (refs != null) { + for (ServiceReference ref : refs) { + Object context = bundleAccessor.getService(ref); + if (OsgiUtil.containsBean(context, beanName)) + return true; + } + } + + return false; + } + + @Inject + public void setBundleAccessor(BundleAccessor bundleAccessor) { + this.bundleAccessor = bundleAccessor; + } +} 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=762880&r1=762879&r2=762880&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 Tue Apr 7 18:00:04 2009 @@ -1,17 +1,10 @@ <?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" /> - <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" /> + "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN" + "http://struts.apache.org/dtds/struts-2.1.7.dtd"> +<struts order="10"> <constant name="struts.objectFactory" value="osgi" /> <constant name="struts.objectFactory.delegate" value="struts" /> <constant name="struts.freemarker.manager.classname" value="org.apache.struts2.osgi.BundleFreemarkerManager" /> @@ -20,5 +13,13 @@ <constant name="struts.convention.action.includeJars" value="jar:file:.*?/bundles/.*?\.jar(!/)?" /> <constant name="struts.osgi.clearBundleCache" value="true" /> - <constant name="struts.osgi.startRunLevel" value="2" /> + <constant name="struts.osgi.startRunLevel" value="3" /> + + <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" /> </struts>