You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by ga...@apache.org on 2009/12/15 22:41:50 UTC

svn commit: r891006 - in /geronimo/server/trunk/framework/modules/geronimo-kernel/src: main/java/org/apache/geronimo/kernel/osgi/ test/java/org/apache/geronimo/kernel/osgi/

Author: gawor
Date: Tue Dec 15 21:41:49 2009
New Revision: 891006

URL: http://svn.apache.org/viewvc?rev=891006&view=rev
Log:
Basic api for parsing bundle manifest and getting information about the bundle. Some portions of the code are borrowed from Aries and Felix projects

Added:
    geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/osgi/BundleDescription.java   (with props)
    geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/osgi/HeaderParser.java   (with props)
    geronimo/server/trunk/framework/modules/geronimo-kernel/src/test/java/org/apache/geronimo/kernel/osgi/BundleDescriptionTest.java   (with props)
    geronimo/server/trunk/framework/modules/geronimo-kernel/src/test/java/org/apache/geronimo/kernel/osgi/HeaderParserTest.java   (with props)

Added: geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/osgi/BundleDescription.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/osgi/BundleDescription.java?rev=891006&view=auto
==============================================================================
--- geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/osgi/BundleDescription.java (added)
+++ geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/osgi/BundleDescription.java Tue Dec 15 21:41:49 2009
@@ -0,0 +1,129 @@
+/**
+ * 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.geronimo.kernel.osgi;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.geronimo.kernel.osgi.HeaderParser.HeaderElement;
+import org.osgi.framework.Constants;
+
+/**
+ * @version $Rev$, $Date$
+ */
+public class BundleDescription  {
+
+    private Map headers;
+    
+    public BundleDescription(Map headers) {
+        this.headers = headers;
+    }
+   
+    /**
+     * Returns a list of packages that are listed in <i>Import-Package</i> header.
+     */
+    public List<Package> getImportPackage() {
+        String headerValue = (String) headers.get(Constants.IMPORT_PACKAGE);
+        List<Package> imports = new ArrayList<Package>();
+        List<HeaderElement> elements = HeaderParser.parseHeader(headerValue);
+        for (HeaderElement element : elements) {
+            Package p = new Package(element.getName(), element.getAttributes(), element.getDirectives());
+            imports.add(p);
+        }
+        return imports;
+    }
+    
+    /**
+     * Returns a list of packages that are listed in <i>Export-Package</i> header.
+     */
+    public List<Package> getExportPackage() {
+        String headerValue = (String) headers.get(Constants.EXPORT_PACKAGE);
+        List<Package> imports = new ArrayList<Package>();
+        List<HeaderElement> elements = HeaderParser.parseHeader(headerValue);
+        for (HeaderElement element : elements) {
+            Package p = new Package(element.getName(), element.getAttributes(), element.getDirectives());
+            imports.add(p);
+        }
+        return imports;
+        
+    }
+    
+    /**
+     * Returns a list of packages that are listed in <i>Import-Package</i> header
+     * and are <b>not</b> listed in <i>Export-Package</i> header.
+     */
+    public List<Package> getExternalImports() {
+        List<Package> imports = getImportPackage();
+        List<Package> exports = getExportPackage();
+        List<Package> realImports = new ArrayList<Package>();
+        for (Package p : imports) {
+            if (!isExported(exports, p)) {
+                realImports.add(p);
+            }
+        }
+        return realImports;
+    }
+    
+    private static boolean isExported(List<Package> exports, Package p) {
+        for (Package export : exports) {
+            if (export.getName().equals(p.getName())) {
+                return true;
+            }
+        }
+        return false;
+    }
+    
+    public List<String> getRequireBundle() {
+        String headerValue = (String) headers.get(Constants.REQUIRE_BUNDLE);
+        List<String> required = new ArrayList<String>();
+        List<HeaderElement> elements = HeaderParser.parseHeader(headerValue);
+        for (HeaderElement element : elements) {
+            required.add(element.getName());
+        }
+        return required;
+    }
+    
+    public static class Package {
+    
+        private String name;
+        private Map<String, String> attributes;
+        private Map<String, String> directives;
+        
+        public Package(String name, Map<String, String> attributes, Map<String, String> directives) {
+            this.name = name;
+            this.attributes = attributes;
+            this.directives = directives;
+        }
+        
+        public String getName() {
+            return name;
+        }
+        
+        public Map<String, String> getAttributes() {
+            return attributes;
+        }
+        
+        public Map<String, String> getDirectives() {
+            return directives;
+        }       
+        
+    }
+    
+}

Propchange: geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/osgi/BundleDescription.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/osgi/BundleDescription.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/osgi/BundleDescription.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/osgi/HeaderParser.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/osgi/HeaderParser.java?rev=891006&view=auto
==============================================================================
--- geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/osgi/HeaderParser.java (added)
+++ geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/osgi/HeaderParser.java Tue Dec 15 21:41:49 2009
@@ -0,0 +1,160 @@
+/**
+ * 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.geronimo.kernel.osgi;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Utility class to parse standard OSGi headers.
+ *
+ * @version $Rev$, $Date$
+ */
+public class HeaderParser  {
+
+    /**
+     * Parse a given OSGi header into a list of header elements.
+     *
+     * @param header the OSGi header to parse
+     * @return the list of header elements extracted from this header
+     */
+    public static List<HeaderElement> parseHeader(String header) {
+        List<HeaderElement> elements = new ArrayList<HeaderElement>();
+        if (header == null || header.trim().length() == 0) {
+            return elements;
+        }
+        List<String> clauses = parseDelimitedString(header, ",");
+        for (String clause : clauses) {
+            String[] tokens = clause.split(";");
+            if (tokens.length < 1) {
+                throw new IllegalArgumentException("Invalid header clause: " + clause);
+            }
+            HeaderElement elem = new HeaderElement(tokens[0].trim());
+            elements.add(elem);
+            for (int i = 1; i < tokens.length; i++) {
+                int pos = tokens[i].indexOf('=');
+                if (pos != -1) {
+                    if (pos > 0 && tokens[i].charAt(pos - 1) == ':') {
+                        String name = tokens[i].substring(0, pos - 1).trim();
+                        String value = tokens[i].substring(pos + 1).trim();
+                        elem.addDirective(name, value);
+                    } else {
+                        String name = tokens[i].substring(0, pos).trim();
+                        String value = tokens[i].substring(pos + 1).trim();
+                        elem.addAttribute(name, value);
+                    }
+                } else {
+                    elem = new HeaderElement(tokens[i].trim());
+                    elements.add(elem);
+                }
+            }
+        }
+        return elements;
+    }
+
+    private static List<String> parseDelimitedString(String value, String delim) {   
+        if (value == null) {       
+            value = "";
+        }
+
+        List<String> list = new ArrayList<String>();
+
+        int CHAR = 1;
+        int DELIMITER = 2;
+        int STARTQUOTE = 4;
+        int ENDQUOTE = 8;
+
+        StringBuffer sb = new StringBuffer();
+
+        int expecting = (CHAR | DELIMITER | STARTQUOTE);
+
+        for (int i = 0; i < value.length(); i++) {        
+            char c = value.charAt(i);
+
+            boolean isDelimiter = (delim.indexOf(c) >= 0);
+            boolean isQuote = (c == '"');
+
+            if (isDelimiter && ((expecting & DELIMITER) > 0)) {            
+                list.add(sb.toString().trim());
+                sb.delete(0, sb.length());
+                expecting = (CHAR | DELIMITER | STARTQUOTE);
+            } else if (isQuote && ((expecting & STARTQUOTE) > 0)) {            
+                sb.append(c);
+                expecting = CHAR | ENDQUOTE;
+            } else if (isQuote && ((expecting & ENDQUOTE) > 0)) {           
+                sb.append(c);
+                expecting = (CHAR | STARTQUOTE | DELIMITER);
+            } else if ((expecting & CHAR) > 0) {            
+                sb.append(c);
+            } else {
+                throw new IllegalArgumentException("Invalid delimited string: " + value);
+            }
+        }
+
+        if (sb.length() > 0) {        
+            list.add(sb.toString().trim());
+        }
+
+        return list;
+    }
+    
+    public static class HeaderElement {
+        
+        private String path;
+        private Map<String, String> attributes;
+        private Map<String, String> directives;
+        
+        public HeaderElement(String path) {
+            this.path = path;
+            this.attributes = new HashMap<String, String>();
+            this.directives = new HashMap<String, String>();
+        }
+        
+        public String getName() {
+            return this.path;
+        }
+        
+        public Map<String, String> getAttributes() {
+            return attributes;
+        }
+        
+        public String getAttribute(String name) {
+            return attributes.get(name);
+        }
+        
+        public void addAttribute(String name, String value) {
+            attributes.put(name, value);
+        }
+        
+        public Map<String, String> getDirectives() {
+            return directives;
+        }
+        
+        public String getDirective(String name) {
+            return directives.get(name);
+        }
+        
+        public void addDirective(String name, String value) {
+            directives.put(name, value);
+        }        
+        
+    }
+}

Propchange: geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/osgi/HeaderParser.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/osgi/HeaderParser.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/osgi/HeaderParser.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/server/trunk/framework/modules/geronimo-kernel/src/test/java/org/apache/geronimo/kernel/osgi/BundleDescriptionTest.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/framework/modules/geronimo-kernel/src/test/java/org/apache/geronimo/kernel/osgi/BundleDescriptionTest.java?rev=891006&view=auto
==============================================================================
--- geronimo/server/trunk/framework/modules/geronimo-kernel/src/test/java/org/apache/geronimo/kernel/osgi/BundleDescriptionTest.java (added)
+++ geronimo/server/trunk/framework/modules/geronimo-kernel/src/test/java/org/apache/geronimo/kernel/osgi/BundleDescriptionTest.java Tue Dec 15 21:41:49 2009
@@ -0,0 +1,60 @@
+/*
+ * 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.geronimo.kernel.osgi;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.osgi.framework.Constants;
+
+import junit.framework.TestCase;
+
+public class BundleDescriptionTest extends TestCase {
+    
+    public void testSimple() throws Exception {
+        Map<String, String> headers = new HashMap<String, String>();
+        headers.put(Constants.IMPORT_PACKAGE,
+                    "com.thoughtworks.xstream;version=\"1.3\",com.thoughtworks.xstream.converters,org.apache.geronimo.kernel.proxy");
+        headers.put(Constants.EXPORT_PACKAGE, 
+                    "org.apache.geronimo.kernel.rmi;uses:=\"javax.rmi.ssl,org.apache.geronimo.gbean,org.slf4j\",org.apache.geronimo.kernel.proxy");
+        
+        BundleDescription desc = new BundleDescription(headers);
+        
+        List<BundleDescription.Package> imports = desc.getImportPackage();
+        assertEquals(3, imports.size());
+        assertEquals("com.thoughtworks.xstream", imports.get(0).getName());
+        assertEquals("\"1.3\"", imports.get(0).getAttributes().get("version"));
+        assertEquals("com.thoughtworks.xstream.converters", imports.get(1).getName());
+        assertEquals("org.apache.geronimo.kernel.proxy", imports.get(2).getName());
+                
+        List<BundleDescription.Package> exports = desc.getExportPackage();
+        assertEquals(2, exports.size());
+        assertEquals("org.apache.geronimo.kernel.rmi", exports.get(0).getName());
+        assertEquals("\"javax.rmi.ssl,org.apache.geronimo.gbean,org.slf4j\"", exports.get(0).getDirectives().get("uses"));
+        assertEquals("org.apache.geronimo.kernel.proxy", exports.get(1).getName());
+        
+        List<BundleDescription.Package> externalImports = desc.getExternalImports();
+        assertEquals(2, externalImports.size());
+        assertEquals("com.thoughtworks.xstream", externalImports.get(0).getName());
+        assertEquals("\"1.3\"", externalImports.get(0).getAttributes().get("version"));
+        assertEquals("com.thoughtworks.xstream.converters", externalImports.get(1).getName());        
+    }
+}
+

Propchange: geronimo/server/trunk/framework/modules/geronimo-kernel/src/test/java/org/apache/geronimo/kernel/osgi/BundleDescriptionTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/server/trunk/framework/modules/geronimo-kernel/src/test/java/org/apache/geronimo/kernel/osgi/BundleDescriptionTest.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/server/trunk/framework/modules/geronimo-kernel/src/test/java/org/apache/geronimo/kernel/osgi/BundleDescriptionTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/server/trunk/framework/modules/geronimo-kernel/src/test/java/org/apache/geronimo/kernel/osgi/HeaderParserTest.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/framework/modules/geronimo-kernel/src/test/java/org/apache/geronimo/kernel/osgi/HeaderParserTest.java?rev=891006&view=auto
==============================================================================
--- geronimo/server/trunk/framework/modules/geronimo-kernel/src/test/java/org/apache/geronimo/kernel/osgi/HeaderParserTest.java (added)
+++ geronimo/server/trunk/framework/modules/geronimo-kernel/src/test/java/org/apache/geronimo/kernel/osgi/HeaderParserTest.java Tue Dec 15 21:41:49 2009
@@ -0,0 +1,100 @@
+/*
+ * 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.geronimo.kernel.osgi;
+
+import java.util.List;
+
+import org.apache.geronimo.kernel.osgi.HeaderParser;
+import org.apache.geronimo.kernel.osgi.HeaderParser.HeaderElement;
+
+import junit.framework.TestCase;
+
+public class HeaderParserTest extends TestCase {
+
+    public void testSimple() throws Exception {
+        List<HeaderElement> paths = HeaderParser.parseHeader("/foo.xml, /foo/bar.xml");
+        assertEquals(2, paths.size());
+        assertEquals("/foo.xml", paths.get(0).getName());
+        assertEquals(0, paths.get(0).getAttributes().size());
+        assertEquals(0, paths.get(0).getDirectives().size());
+        assertEquals("/foo/bar.xml", paths.get(1).getName());
+        assertEquals(0, paths.get(1).getAttributes().size());
+        assertEquals(0, paths.get(1).getDirectives().size());
+    }
+    
+    public void testComplex() throws Exception {
+        List<HeaderElement> paths = HeaderParser.parseHeader("OSGI-INF/blueprint/comp1_named.xml;ignored-directive:=true,OSGI-INF/blueprint/comp2_named.xml;some-other-attribute=1");
+        assertEquals(2, paths.size());
+        assertEquals("OSGI-INF/blueprint/comp1_named.xml", paths.get(0).getName());
+        assertEquals(0, paths.get(0).getAttributes().size());
+        assertEquals(1, paths.get(0).getDirectives().size());
+        assertEquals("true", paths.get(0).getDirective("ignored-directive"));
+        assertEquals("OSGI-INF/blueprint/comp2_named.xml", paths.get(1).getName());
+        assertEquals(1, paths.get(1).getAttributes().size());
+        assertEquals("1", paths.get(1).getAttribute("some-other-attribute"));
+        assertEquals(0, paths.get(1).getDirectives().size());
+    }
+
+    public void testPaths() throws Exception {
+        List<HeaderElement> paths = HeaderParser.parseHeader("OSGI-INF/blueprint/comp1_named.xml;ignored-directive:=true,OSGI-INF/blueprint/comp2_named.xml;foo.xml;a=b;1:=2;c:=d;4=5");
+        assertEquals(3, paths.size());
+        assertEquals("OSGI-INF/blueprint/comp1_named.xml", paths.get(0).getName());
+        assertEquals(0, paths.get(0).getAttributes().size());
+        assertEquals(1, paths.get(0).getDirectives().size());
+        assertEquals("true", paths.get(0).getDirective("ignored-directive"));
+        assertEquals("OSGI-INF/blueprint/comp2_named.xml", paths.get(1).getName());
+        assertEquals(0, paths.get(1).getAttributes().size());
+        assertEquals(0, paths.get(1).getDirectives().size());
+        assertEquals("foo.xml", paths.get(2).getName());
+        assertEquals(2, paths.get(2).getAttributes().size());
+        assertEquals("b", paths.get(2).getAttribute("a"));
+        assertEquals("5", paths.get(2).getAttribute("4"));
+        assertEquals(2, paths.get(2).getDirectives().size());
+        assertEquals("d", paths.get(2).getDirective("c"));
+        assertEquals("2", paths.get(2).getDirective("1"));
+    }
+    
+    public void testExportPackages() throws Exception {
+        List<HeaderElement> paths = HeaderParser.parseHeader("org.apache.geronimo.kernel.rmi;uses:=\"javax.rmi.ssl,org.apache.geronimo.gbean,org.slf4j\",org.apache.geronimo.kernel.proxy");
+        assertEquals(2, paths.size());
+        
+        assertEquals("org.apache.geronimo.kernel.rmi", paths.get(0).getName());
+        assertEquals(0, paths.get(0).getAttributes().size());
+        assertEquals(1, paths.get(0).getDirectives().size());
+        assertEquals("\"javax.rmi.ssl,org.apache.geronimo.gbean,org.slf4j\"", paths.get(0).getDirective("uses"));
+        
+        assertEquals("org.apache.geronimo.kernel.proxy", paths.get(1).getName());
+        assertEquals(0, paths.get(1).getAttributes().size());
+        assertEquals(0, paths.get(1).getDirectives().size());
+    }
+    
+    public void testImportPackages() throws Exception {
+        List<HeaderElement> paths = HeaderParser.parseHeader("com.thoughtworks.xstream;version=\"1.3\",com.thoughtworks.xstream.converters");
+        assertEquals(2, paths.size());
+        
+        assertEquals("com.thoughtworks.xstream", paths.get(0).getName());
+        assertEquals(1, paths.get(0).getAttributes().size());
+        assertEquals("\"1.3\"", paths.get(0).getAttribute("version"));
+        assertEquals(0, paths.get(0).getDirectives().size());
+        
+        assertEquals("com.thoughtworks.xstream.converters", paths.get(1).getName());
+        assertEquals(0, paths.get(1).getAttributes().size());
+        assertEquals(0, paths.get(1).getDirectives().size());
+    }
+}

Propchange: geronimo/server/trunk/framework/modules/geronimo-kernel/src/test/java/org/apache/geronimo/kernel/osgi/HeaderParserTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/server/trunk/framework/modules/geronimo-kernel/src/test/java/org/apache/geronimo/kernel/osgi/HeaderParserTest.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/server/trunk/framework/modules/geronimo-kernel/src/test/java/org/apache/geronimo/kernel/osgi/HeaderParserTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain