Author: musachy
Date: Fri Apr  3 19:13:06 2009
New Revision: 761766

URL: http://svn.apache.org/viewvc?rev=761766&view=rev
Log:
Refactor plugin. Update to Felix 1.4
Added:
    
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/OsgiHost.java
    
struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/test/java/org/apache/struts2/osgi/FelixOsgiHostTest.java
Removed:
    
struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/test/java/org/apache/struts2/osgi/OsgiConfigurationProviderTest.java
Modified:
    struts/sandbox/trunk/struts2-osgi-plugin/plugin/   (props changed)
    struts/sandbox/trunk/struts2-osgi-plugin/plugin/pom.xml
    
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/OsgiConfigurationProvider.java
    
struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/loaders/StaticContentBundleResourceLoader.java
    
struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/resources/struts-osgi.properties
    
struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/resources/struts-plugin.xml

Propchange: struts/sandbox/trunk/struts2-osgi-plugin/plugin/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Fri Apr  3 19:13:06 2009
@@ -0,0 +1 @@
+target

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=761766&r1=761765&r2=761766&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-osgi-plugin/plugin/pom.xml (original)
+++ struts/sandbox/trunk/struts2-osgi-plugin/plugin/pom.xml Fri Apr  3 19:13:06 
2009
@@ -5,31 +5,49 @@
     <parent>
         <groupId>org.apache.struts</groupId>
         <artifactId>struts2-plugins</artifactId>
-        <version>2.1.2</version>
+        <version>2.0.9</version>
     </parent>
     <groupId>org.apache.struts</groupId>
     <artifactId>struts2-osgi-plugin</artifactId>
     <packaging>jar</packaging>
-    <version>1.0-SNAPSHOT</version>
+    <version>1.0.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>
+        
<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>
 
+    <build>
+        <plugins>
+            <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>
+    </build>
+
     <dependencies>
         <dependency>
             <groupId>org.apache.felix</groupId>
             <artifactId>org.apache.felix.main</artifactId>
-            <version>1.1.0-SNAPSHOT</version>
+            <version>1.4.1</version>
         </dependency>
 
-         <dependency>
+        <dependency>
             <groupId>org.apache.felix</groupId>
             <artifactId>org.apache.felix.fileinstall</artifactId>
-            <version>0.9.0-SNAPSHOT</version>
+            <version>0.9.0</version>
 
             <exclusions>
                 <exclusion>
@@ -42,31 +60,35 @@
         <dependency>
             <groupId>org.apache.struts</groupId>
             <artifactId>struts2-core</artifactId>
-            <version>2.1.3-SNAPSHOT</version>
+            <version>2.1.7-SNAPSHOT</version>
         </dependency>
 
         <dependency>
-            <groupId>org.twdata.pkgscanner</groupId>
-            <artifactId>package-scanner</artifactId>
-            <version>0.5.1</version>
+            <groupId>org.apache.velocity</groupId>
+            <artifactId>velocity</artifactId>
+            <version>1.5</version>
         </dependency>
 
         <dependency>
-            <groupId>velocity-tools</groupId>
+            <groupId>org.apache.velocity</groupId>
             <artifactId>velocity-tools</artifactId>
-            <version>1.1</version>
+            <version>1.3</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>javax.servlet</groupId>
+                    <artifactId>servlet-api</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>struts</groupId>
+                    <artifactId>struts</artifactId>
+                </exclusion>
+            </exclusions>
         </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>
+            <groupId>commons-digester</groupId>
+            <artifactId>commons-digester</artifactId>
+            <version>2.0</version>
         </dependency>
 
         <dependency>
@@ -75,13 +97,5 @@
             <scope>test</scope>
             <version>3.8.1</version>
         </dependency>
-   </dependencies>
-
-    <repositories>
-        <repository>
-            <id>pkgscanner-repository</id>
-            <name>pkgscanner Repository for Maven</name>
-            <url>http://pkgscanner.googlecode.com/svn/repo/</url>
-        </repository>
-    </repositories>
+    </dependencies>
 </project>

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=761766&r1=761765&r2=761766&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
 Fri Apr  3 19:13:06 2009
@@ -53,7 +53,7 @@
         private BundleContext bundleContext;
 
         public BundleConfigurationProvider(String filename, Bundle bundle, 
BundleContext bundleContext) { 
-            super(filename, true);
+            super(filename, false);
             this.bundle = bundle;
             this.bundleContext = bundleContext;
         }
@@ -62,8 +62,7 @@
         @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;
+            return e.hasMoreElements() ? new EnumeratorIterator<URL>(e) : null;
         }
         
         /* 
@@ -76,14 +75,14 @@
                 return bundle.loadClass(className) != null;
             } catch (Exception e) {
                 if (LOG.isDebugEnabled())
-                    LOG.debug("Unable to find class #1 in bundle #2", 
className, bundle.getSymbolicName());
+                    LOG.debug("Unable to find class [#0] in bundle [#1]", 
className, bundle.getSymbolicName());
 
                 //try to find a bean with that id
                 try {
                     return SpringOSGiUtil.isValidBean(bundleContext, 
className);
                 } catch (Exception e1) {
                     if (LOG.isDebugEnabled())
-                        LOG.debug("Unable to find bean #1", className);
+                        LOG.debug("Unable to find bean [#0]", className);
                 }
                 
                 return false;

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=761766&r1=761765&r2=761766&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
 Fri Apr  3 19:13:06 2009
@@ -67,7 +67,7 @@
         Bundle bundle = getCurrentBundle();
         if (bundle != null) {
             cls = bundle.loadClass(className);
-            LOG.debug("Located class #1 in bundle #2", className, 
bundle.getSymbolicName());
+            LOG.debug("Located class [#0] in bundle [#1]", className, 
bundle.getSymbolicName());
         }
 
         if (cls == null) {
@@ -78,7 +78,7 @@
                     cls = bean.getClass();
             } catch (Exception e) {
                 if (LOG.isDebugEnabled())
-                    LOG.debug("Unable to find bean #1", className);
+                    LOG.debug("Unable to find bean [#0]", className);
             }
         }
         

Added: 
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=761766&view=auto
==============================================================================
--- 
struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/FelixOsgiHost.java
 (added)
+++ 
struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/FelixOsgiHost.java
 Fri Apr  3 19:13:06 2009
@@ -0,0 +1,333 @@
+/*
+ * $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 org.apache.felix.framework.Felix;
+import org.apache.felix.framework.util.FelixConstants;
+import org.apache.felix.main.Main;
+import org.apache.felix.main.AutoActivator;
+import org.apache.felix.shell.ShellService;
+import org.apache.commons.lang.xwork.StringUtils;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+import org.osgi.framework.BundleActivator;
+import org.osgi.util.tracker.ServiceTracker;
+
+import java.util.Map;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Properties;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+import java.util.jar.Attributes;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FilenameFilter;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.net.MalformedURLException;
+import java.net.URISyntaxException;
+import java.security.CodeSource;
+import java.security.ProtectionDomain;
+
+import com.opensymphony.xwork2.inject.Inject;
+import com.opensymphony.xwork2.util.logging.Logger;
+import com.opensymphony.xwork2.util.logging.LoggerFactory;
+import com.opensymphony.xwork2.util.finder.ResourceFinder;
+import com.opensymphony.xwork2.util.URLUtil;
+import com.opensymphony.xwork2.config.ConfigurationException;
+
+/**
+ * Apache felix implementation of an OsgiHost
+ * See 
http://felix.apache.org/site/apache-felix-framework-launching-and-embedding.html
+ */
+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])+[\\.-]");
+
+    protected void startFelix() {
+        //load properties from felix embedded file
+        Properties configProps = getProperties("default.properties");
+
+        // Copy framework properties from the system properties.
+        Main.copySystemProperties(configProps);
+        replaceSystemPackages(configProps);
+
+        //struts, xwork and felix exported packages
+        Properties strutsConfigProps = getProperties("struts-osgi.properties");
+        addExportedPackages(strutsConfigProps, configProps);
+
+        //find bundles and adde em to autostart property
+        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");*/
+
+        if (cleanBundleCache) {
+            if (LOG.isDebugEnabled())
+                LOG.debug("Clearing bundle cache");
+            configProps.put(FelixConstants.FRAMEWORK_STORAGE_CLEAN, 
FelixConstants.FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT);
+        }
+
+        //other properties
+        configProps.put(FelixConstants.SERVICE_URLHANDLERS_PROP, "false");
+        configProps.put(FelixConstants.LOG_LEVEL_PROP, "4");
+        configProps.put(FelixConstants.BUNDLE_CLASSPATH, ".");
+
+        try {
+            List<BundleActivator> list = new ArrayList<BundleActivator>();
+            if (extraBundleActivators != null)
+                list.addAll(extraBundleActivators);
+            list.add(new AutoActivator(configProps));
+            configProps.put(FelixConstants.SYSTEMBUNDLE_ACTIVATORS_PROP, list);
+
+            felix = new Felix(configProps);
+            felix.start();
+            if (LOG.isTraceEnabled())
+                LOG.trace("Apache Felix is running");
+        }
+        catch (Exception ex) {
+            throw new ConfigurationException("Couldn't start Felix (OSGi)", 
ex);
+        }
+
+        // Wait for all bundles to load
+        while (bundles.size() < bundlePaths) {
+            try {
+                Thread.sleep(500);
+            } catch (InterruptedException e) {
+                LOG.error("An error occured while waiting for bundle 
activation", e);
+            }
+        }
+    }
+
+    private int addAutoStartBundles(Properties configProps) {
+        List<String> bundleJars = new ArrayList<String>();
+        try {
+            ResourceFinder finder = new ResourceFinder();
+            URL url = finder.find("bundles");
+            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");
+                    }
+                });
+
+                if (bundles != null && bundles.length > 0) {
+                    //add all the bundles to the list
+                    for (File bundle : bundles) {
+                        String externalForm = 
bundle.toURI().toURL().toExternalForm();
+                        if (LOG.isDebugEnabled())
+                            LOG.debug("Adding bundle [#0]", externalForm);
+                        bundleJars.add(externalForm);
+                     }
+
+                } else if (LOG.isDebugEnabled()) {
+                    LOG.debug("No bundles found under the 'bundles' 
directory");
+                }
+            }
+        } catch (Exception e) {
+            if (LOG.isWarnEnabled())
+                LOG.warn("Unable load bundles from the 'bundles' directory", 
e);
+            return 0;
+        }
+
+        // Add shell and File Install bundles activation
+        bundleJars.add(getJarUrl(ShellService.class));
+        //sb.append(getJarUrl(FileInstall.class)).append(" ");
+        bundleJars.add(getJarUrl(ServiceTracker.class));
+
+        //autostart bundles
+        configProps.put(AutoActivator.AUTO_START_PROP + ".1", 
StringUtils.join(bundleJars, " "));
+
+        return bundleJars.size();
+    }
+
+    private String getJarUrl(Class clazz) {
+        ProtectionDomain protectionDomain = clazz.getProtectionDomain();
+        CodeSource codeSource = protectionDomain.getCodeSource();
+        URL loc = codeSource.getLocation();
+        return loc.toString();
+    }
+
+    private void replaceSystemPackages(Properties properties) {
+        //Felix has a way to load the config file and substitution expressions
+        //but the method does not have a way to specify the file (other than 
in an env variable)
+
+        //${jre-${java.specification.version}}
+        String systemPackages = (String) 
properties.get(Constants.FRAMEWORK_SYSTEMPACKAGES);
+        String jreVersion = "jre-" + 
System.getProperty("java.version").substring(0, 3);
+        systemPackages = 
systemPackages.replace("${jre-${java.specification.version}}", (String) 
properties.get(jreVersion));
+        properties.put(Constants.FRAMEWORK_SYSTEMPACKAGES, systemPackages);
+    }
+
+    /*
+        Find subpackages of the packages defined in the property file and 
export them
+     */
+    private void addExportedPackages(Properties strutsConfigProps, Properties 
configProps) {
+        String[] rootPackages = StringUtils.split((String) 
strutsConfigProps.get("scanning.package.includes"), ",");
+        ResourceFinder finder = new ResourceFinder(StringUtils.EMPTY, 
OsgiConfigurationProvider.class.getClassLoader());
+        List<String> exportedPackages = new ArrayList<String>();
+        //build a list of subpackages
+        for (String rootPackage : rootPackages) {
+            try {
+                Map<URL, Set<String>> subpackagesMap = 
finder.findPackagesMap(StringUtils.replace(rootPackage.trim(), ".", "/"));
+                for (Map.Entry<URL, Set<String>> entry : 
subpackagesMap.entrySet()) {
+                    URL url = entry.getKey();
+                    Set<String> packages = entry.getValue();
+                    String version = getVersion(url);
+
+                    if (packages != null) {
+                        for (String subpackage : packages) {
+                            exportedPackages.add(subpackage + "; version=" + 
version);
+                        }
+                    }
+                }
+            } catch (IOException e) {
+                if (LOG.isErrorEnabled())
+                    LOG.error("Unable to find subpackages of [#0]", e, 
rootPackage);
+            }
+        }
+
+        //make a string with the exported packages and add it to the system 
properties
+        if (!exportedPackages.isEmpty()) {
+            String systemPackages = (String) 
configProps.get(Constants.FRAMEWORK_SYSTEMPACKAGES);
+            systemPackages = StringUtils.chomp(systemPackages, ",") + "," + 
StringUtils.join(exportedPackages, ",");
+            configProps.put(Constants.FRAMEWORK_SYSTEMPACKAGES, 
systemPackages);
+        }
+    }
+
+    /**
+     * Gets the version used to export the packages. it tries to get it from 
MANIFEST.MF, or the file name
+     */
+    private String getVersion(URL url) {
+        if ("jar".equals(url.getProtocol())) {
+            try {
+                JarFile jarFile = new JarFile(new 
File(URLUtil.normalizeToFileProtocol(url).toURI()));
+                Manifest manifest = jarFile.getManifest();
+                if (manifest != null) {
+                    String version = 
manifest.getMainAttributes().getValue("Bundle-Version");
+                    if (StringUtils.isNotBlank(version)) {
+                        return getVersionFromString(version);
+                    }
+                } else {
+                    //try to get the version from the file name
+                    return getVersionFromString(jarFile.getName());
+                }
+            } catch (Exception e) {
+                if (LOG.isErrorEnabled())
+                    LOG.error("Unable to extract version from [#0], defaulting 
to '1.0.0'", url.toExternalForm());
+
+            }
+        }
+
+        return "1.0.0";
+    }
+
+    /**
+     * Extracts numbers followed by "." or "-" from the string and joins them 
with "."
+     */
+    static String getVersionFromString(String str) {
+        Matcher matcher = versionPattern.matcher(str);
+        List<String> parts = new ArrayList<String>();
+        while(matcher.find()) {
+            parts.add(matcher.group(1));
+        }
+
+        //default
+        if (parts.size() == 0)
+            return "1.0.0";
+
+        while(parts.size() < 3)
+            parts.add("0");
+
+        return StringUtils.join(parts, ".");
+    }
+
+    private Properties getProperties(String fileName) {
+        ResourceFinder finder = new ResourceFinder("");
+        try {
+            return finder.findProperties(fileName);
+        } catch (IOException e) {
+           if (LOG.isErrorEnabled())
+               LOG.error("Unable to read property file [#]", fileName);
+            return new Properties();
+        }
+    }
+
+    /**
+     * Bundle activators that will be added to the container
+     */
+    public void setExtraBundleActivators(List<? extends BundleActivator> 
extraBundleActivators) {
+        this.extraBundleActivators = extraBundleActivators;
+    }
+
+    public Map<String, Bundle> getBundles() {
+        return bundles;
+    }
+
+    public void destroy() throws Exception {
+        try {
+            felix.stop();
+        } finally {
+            bundles = null;
+        }
+    }
+
+    @Override
+    public void init() throws Exception {
+        startFelix();
+    }
+
+    @Inject("struts.osgi.clearBundleCache")
+    public void setCleanBundleCache(String cleanBundleCache) {
+        this.cleanBundleCache = "true".equalsIgnoreCase(cleanBundleCache);
+    }
+}

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=761766&r1=761765&r2=761766&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
 Fri Apr  3 19:13:06 2009
@@ -1,98 +1,66 @@
 package org.apache.struts2.osgi;
 
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLDecoder;
-import java.security.CodeSource;
-import java.security.ProtectionDomain;
-import java.util.*;
-import java.util.jar.JarEntry;
-import java.util.jar.JarInputStream;
-
-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.felix.main.AutoActivator;
-import org.apache.felix.shell.ShellService;
+import com.opensymphony.xwork2.ObjectFactory;
+import com.opensymphony.xwork2.config.Configuration;
+import com.opensymphony.xwork2.config.ConfigurationException;
+import com.opensymphony.xwork2.config.PackageProvider;
+import com.opensymphony.xwork2.config.entities.PackageConfig;
+import com.opensymphony.xwork2.inject.Inject;
+import com.opensymphony.xwork2.util.logging.Logger;
+import com.opensymphony.xwork2.util.logging.LoggerFactory;
 import org.apache.struts2.osgi.loaders.VelocityBundleResourceLoader;
 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.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
-import org.twdata.pkgscanner.ExportPackage;
-import org.twdata.pkgscanner.PackageScanner;
-import static org.twdata.pkgscanner.PackageScanner.*;
-
-import com.opensymphony.xwork2.ObjectFactory;
-import com.opensymphony.xwork2.config.Configuration;
-import com.opensymphony.xwork2.config.ConfigurationException;
-import com.opensymphony.xwork2.config.PackageProvider;
-import com.opensymphony.xwork2.config.entities.PackageConfig;
-import com.opensymphony.xwork2.inject.Inject;
-import com.opensymphony.xwork2.util.logging.Logger;
-import com.opensymphony.xwork2.util.logging.LoggerFactory;
 
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+/**
+ * Struts package provider that starts the OSGi container and deelgates 
package loading
+ */
 public class OsgiConfigurationProvider implements PackageProvider {
 
-    private static final String FELIX_LOG_LEVEL = "felix.log.level";
-
     private static final Logger LOG = 
LoggerFactory.getLogger(OsgiConfigurationProvider.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 Configuration configuration;
+    private ObjectFactory objectFactory;
+    private OsgiHost osgiHost;
+
     private BundleContext bundleContext;
     private BundleAccessor bundleAccessor;
     private boolean bundlesChanged = false;
 
-    private ObjectFactory objectFactory;
-
-    @Inject
-    public void setBundleAccessor(BundleAccessor acc) {
-        this.bundleAccessor = acc;
-    }
-
-    @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", 
VelocityBundleResourceLoader.class.getName());
-        props.setProperty(Velocity.RESOURCE_LOADER, 
"strutsfile,strutsclass,osgi");
-        vm.setVelocityProperties(props);
-    }
-
     public void destroy() {
         try {
-            felix.stop();
-        } catch (BundleException e) {
-            LOG.error("Failed to stop Felix", e);
+            if (LOG.isTraceEnabled())
+                LOG.trace("Stopping OSGi container");
+            osgiHost.destroy();
+        } catch (Exception e) {
+            LOG.error("Failed to stop OSGi container", e);
         }
-        bundles = null;
     }
 
     public void init(Configuration configuration) throws 
ConfigurationException {
-        loadOsgi();
+        if (LOG.isTraceEnabled())
+            LOG.trace("Starting OSGi container");
+        try {
+            osgiHost.setExtraBundleActivators(Arrays.asList(new 
BundleRegistrationListener()));
+            osgiHost.init();
+        } catch (Exception e) {
+            if (LOG.isErrorEnabled())
+                LOG.error("Failed to start the OSGi container", e);
+            throw new ConfigurationException(e);
+        }
         this.configuration = configuration;
     }
 
@@ -103,22 +71,25 @@
         } catch (InvalidSyntaxException e) {
             throw new ConfigurationException(e);
         }
-        Map<String,String> packageToBundle = new HashMap<String,String>();
+        Map<String, String> packageToBundle = new HashMap<String, String>();
         Set<String> bundleNames = new HashSet<String>();
         if (refs != null) {
             for (ServiceReference ref : refs) {
                 if (!bundleNames.contains(ref.getBundle().getSymbolicName())) {
                     bundleNames.add(ref.getBundle().getSymbolicName());
-                    LOG.info("Loading packages from bundle #1", 
ref.getBundle().getSymbolicName());
+
+                    if (LOG.isDebugEnabled())
+                        LOG.debug("Loading packages from bundle [#0]", 
ref.getBundle().getSymbolicName());
+
                     PackageLoader loader = (PackageLoader) 
bundleContext.getService(ref);
-                    for (PackageConfig pkg : 
loader.loadPackages(ref.getBundle(),  bundleContext, objectFactory, 
configuration.getPackageConfigs())) {
+                    for (PackageConfig pkg : 
loader.loadPackages(ref.getBundle(), bundleContext, objectFactory, 
configuration.getPackageConfigs())) {
                         configuration.addPackageConfig(pkg.getName(), pkg);
                         packageToBundle.put(pkg.getName(), 
ref.getBundle().getSymbolicName());
                     }
                 }
             }
         }
-        bundleAccessor.init(bundles, bundleContext, packageToBundle);
+        bundleAccessor.init(osgiHost.getBundles(), bundleContext, 
packageToBundle);
         bundlesChanged = false;
     }
 
@@ -126,145 +97,34 @@
         return bundlesChanged;
     }
 
-    protected void loadOsgi() {
-        //configuration properties
-        Properties systemProperties = getProperties("default.properties");
-
-        //struts, xwork and felix exported packages
-        Properties packages = getProperties("struts-osgi.properties");
-
-        Map<String, String> configMap = new StringMap(false);
-
-        configMap.put(Constants.FRAMEWORK_SYSTEMPACKAGES, 
packages.getProperty("packages")
-                + "," + getScannedPackages(packages)
-                + getSystemPackages(systemProperties));
-
-
-        // find bundles
-        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(" ");
-        }
-
-        // Add shell and File Install bundles activation
-        sb.append(getJarUrl(ShellService.class)).append(" ");
-        //sb.append(getJarUrl(FileInstall.class)).append(" ");
-        //sb.append(getJarUrl(ServiceTracker.class));
-
-        //autostart bundles
-        configMap.put(AutoActivator.AUTO_START_PROP + ".1", sb.toString());
-
-        // Bundle cache
-        configMap.put(BundleCache.CACHE_PROFILE_DIR_PROP, 
System.getProperty("java.io.tmpdir") + ".felix-cache");
-        configMap.put(BundleCache.CACHE_DIR_PROP, "jim");
-
-        // File Install
-        String bundlesDir = 
Thread.currentThread().getContextClassLoader().getResource("bundles").getPath();
-        configMap.put(OsgiConfigurationProvider.FELIX_FILEINSTALL_POLL, 
"5000");
-        configMap.put(OsgiConfigurationProvider.FELIX_FILEINSTALL_DIR, 
bundlesDir);
-        configMap.put(OsgiConfigurationProvider.FELIX_FILEINSTALL_DEBUG, "1");
-
-        //other properties
-        configMap.put(FelixConstants.EMBEDDED_EXECUTION_PROP, "true");
-        configMap.put(FelixConstants.SERVICE_URLHANDLERS_PROP, "false");
-        configMap.put(OsgiConfigurationProvider.FELIX_LOG_LEVEL, "4");
-        configMap.put(FelixConstants.BUNDLE_CLASSPATH, ".");
-
-        try {
-            List<BundleActivator> list = new ArrayList<BundleActivator>();
-            list.add(new BundleRegistration());
-            list.add(new AutoActivator(configMap));
-            // Now create an instance of the framework.
-            Map configMap2 = new StringMap(configMap, false);
-            felix = new Felix(configMap2, 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) {
-                LOG.error("An error occured while waiting for bundle 
activation", e);
-            }
-        }
-    }
-
-    private String getJarUrl(Class clazz) {
-        ProtectionDomain protectionDomain = clazz.getProtectionDomain();
-        CodeSource codeSource = protectionDomain.getCodeSource();
-        URL loc = codeSource.getLocation();
-        return loc.toString();
-    }
-
-    private String getSystemPackages(Properties properties) {
-        String jreVersion = "jre-" + 
System.getProperty("java.version").substring(0, 3);
-        return properties.getProperty(jreVersion);
+    @Inject
+    public void setObjectFactory(ObjectFactory factory) {
+        this.objectFactory = factory;
     }
 
-    String getScannedPackages(Properties props) {
-        Collection<ExportPackage> exports = new PackageScanner()
-                .select(
-                    jars(
-                         
include(toArray(props.getProperty("scanning.jar.includes"))),
-                         
exclude(toArray(props.getProperty("scanning.jar.excludes")))),
-                    packages(
-                         
include(toArray(props.getProperty("scanning.package.includes"))),
-                         
exclude(toArray(props.getProperty("scanning.package.excludes")))))
-                .scan();
-
-        StringBuilder sb = new StringBuilder();
-        sb.append("Export-Package: ");
-        for (Iterator<ExportPackage> i = exports.iterator(); i.hasNext(); ) {
-            ExportPackage pkg = i.next();
-            sb.append(pkg.getPackageName());
-            if (pkg.getVersion() != null) {
-                sb.append(";version=").append(pkg.getVersion());
-            }
-            if (i.hasNext()) {
-                sb.append(",");
-            }
-        }
-        return sb.toString();
+    @Inject("felix")
+    public void setOsgiHost(OsgiHost osgiHost) {
+        this.osgiHost = osgiHost;
     }
 
-    String[] toArray(String val) {
-        if (val != null) {
-            return val.split("\\s*,\\s*");
-        } else {
-            return new String[]{};
-        }
+    @Inject
+    public void setBundleAccessor(BundleAccessor acc) {
+        this.bundleAccessor = acc;
     }
 
-    private Properties getProperties(String fileName) {
-        URL propertiesURL = 
OsgiConfigurationProvider.class.getClassLoader().getResource(
-            fileName);
-        Properties properties = new Properties();
-        InputStream is = null;
-        try {
-            is = propertiesURL.openConnection().getInputStream();
-            properties.load(is);
-            is.close();
-        } catch (Exception ex2) {
-            // Try to close input stream if we have one.
-            try {
-                if (is != null)
-                    is.close();
-            } catch (IOException ex3) {
-                // Nothing we can do.
-            }
-        }
-        return properties;
+    @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", 
VelocityBundleResourceLoader.class.getName());
+        props.setProperty(Velocity.RESOURCE_LOADER, 
"strutsfile,strutsclass,osgi");
+        vm.setVelocityProperties(props);
     }
 
-    class BundleRegistration implements BundleActivator, BundleListener {
-
+    /**
+     * Listens to bundle events and adds bundles to the bundle list when one 
is activated
+     */
+    class BundleRegistrationListener implements BundleActivator, 
BundleListener {
         public void start(BundleContext context) throws Exception {
             context.addBundleListener(this);
             bundleContext = context;
@@ -275,124 +135,13 @@
 
         public void bundleChanged(BundleEvent evt) {
             if (evt.getType() == BundleEvent.STARTED && 
evt.getBundle().getSymbolicName() != null) {
-                LOG.info("Started bundle #1", 
evt.getBundle().getSymbolicName());
+                if (LOG.isDebugEnabled())
+                    LOG.debug("Started bundle [#0]", 
evt.getBundle().getSymbolicName());
 
-                bundles.put(evt.getBundle().getSymbolicName(), 
evt.getBundle());
+                osgiHost.getBundles().put(evt.getBundle().getSymbolicName(), 
evt.getBundle());
                 bundlesChanged = true;
             }
         }
     }
 
-    /**
-     * 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
-     *
-     * @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 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.toURI().toURL().toString());
-                } catch (MalformedURLException e) {
-                    LOG.error("Invalid file path", e);
-                }
-            }
-        }
-    }
-
-    /**
-     * 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 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.toURI().toURL()+"!"+entry.getName());
-                }
-            }
-        }
-        catch (IOException ioe) {
-            LOG.error("Could not search jar file #1 due to an IOException", 
ioe, jarfile.toString());
-        }
-    }
-
 }

Added: 
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=761766&view=auto
==============================================================================
--- 
struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/OsgiHost.java
 (added)
+++ 
struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/OsgiHost.java
 Fri Apr  3 19:13:06 2009
@@ -0,0 +1,34 @@
+/*
+ * $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 org.osgi.framework.BundleActivator;
+import org.osgi.framework.Bundle;
+
+import java.util.List;
+import java.util.Map;
+
+public interface OsgiHost {
+    void destroy() throws Exception;
+    void init() throws Exception;
+    void setExtraBundleActivators(List<? extends BundleActivator> 
extraBundleActivators);
+    Map<String, Bundle> getBundles();
+}

Modified: 
struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/loaders/StaticContentBundleResourceLoader.java
URL: 
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/loaders/StaticContentBundleResourceLoader.java?rev=761766&r1=761765&r2=761766&view=diff
==============================================================================
--- 
struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/loaders/StaticContentBundleResourceLoader.java
 (original)
+++ 
struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/loaders/StaticContentBundleResourceLoader.java
 Fri Apr  3 19:13:06 2009
@@ -11,7 +11,6 @@
  *
  */
 public class StaticContentBundleResourceLoader extends 
DefaultStaticContentLoader {
-    @Override
     protected InputStream findInputStream(String path) throws IOException {
         return 
DefaultBundleAccessor.getInstance().loadResourceFromAllBundlesAsStream(path);
     }

Modified: 
struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/resources/struts-osgi.properties
URL: 
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/resources/struts-osgi.properties?rev=761766&r1=761765&r2=761766&view=diff
==============================================================================
--- 
struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/resources/struts-osgi.properties
 (original)
+++ 
struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/resources/struts-osgi.properties
 Fri Apr  3 19:13:06 2009
@@ -15,17 +15,10 @@
 # specific language governing permissions and limitations
 # under the License.
 
-packages = 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
+scanning.package.includes = com.opensymphony.xwork2, \
+                            org.apache.struts2, \
+                            ognl, \
+                            freemarker, \
+                            org.apache.velocity, \
+                            javax.servlet
 
-scanning.jar.includes = *.jar
-scanning.jar.excludes =
-scanning.package.includes = com.opensymphony.xwork2*, \
-                            org.apache.struts2*, \
-                            ognl*, \
-                            freemarker*, \
-                            org.apache.velocity*, \
-                            javax.servlet*
-scanning.package.excludes =

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=761766&r1=761765&r2=761766&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
 Fri Apr  3 19:13:06 2009
@@ -8,10 +8,13 @@
     <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.OsgiConfigurationProviderTest" />
+    <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" />
     
     <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" />
     <constant name="struts.staticContentLoader" 
value="org.apache.struts2.osgi.loaders.StaticContentBundleResourceLoader" />
+
+    <constant name="struts.osgi.clearBundleCache" value="true" />
 </struts>

Added: 
struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/test/java/org/apache/struts2/osgi/FelixOsgiHostTest.java
URL: 
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/test/java/org/apache/struts2/osgi/FelixOsgiHostTest.java?rev=761766&view=auto
==============================================================================
--- 
struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/test/java/org/apache/struts2/osgi/FelixOsgiHostTest.java
 (added)
+++ 
struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/test/java/org/apache/struts2/osgi/FelixOsgiHostTest.java
 Fri Apr  3 19:13:06 2009
@@ -0,0 +1,35 @@
+/*
+ * $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 junit.framework.TestCase;
+
+public class FelixOsgiHostTest extends TestCase {
+    public void testGetVersionFromString() {
+        assertEquals("2.1.1", 
FelixOsgiHost.getVersionFromString("2.1.1-SNAPSHOT"));
+        assertEquals("2.1.1", 
FelixOsgiHost.getVersionFromString("2.1.1.SNAPSHOT"));
+        assertEquals("2.1.1", 
FelixOsgiHost.getVersionFromString("something-2.1.1.SNAPSHOT"));
+        assertEquals("2.1.1", 
FelixOsgiHost.getVersionFromString("something-2-1-1.SNAPSHOT"));
+        assertEquals("2.1.0", 
FelixOsgiHost.getVersionFromString("something-2-1.SNAPSHOT"));
+        assertEquals("2.0.0", 
FelixOsgiHost.getVersionFromString("something-2.SNAPSHOT"));
+        assertEquals("1.0.0", FelixOsgiHost.getVersionFromString("something"));
+    }
+}


Reply via email to