You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by no...@apache.org on 2009/11/25 17:47:02 UTC

svn commit: r884191 - in /incubator/aries/trunk/application/application-utils: ./ src/main/java/org/apache/aries/application/ src/main/java/org/apache/aries/application/impl/ src/main/java/org/apache/aries/application/utils/manifest/ src/main/resources...

Author: not
Date: Wed Nov 25 16:47:01 2009
New Revision: 884191

URL: http://svn.apache.org/viewvc?rev=884191&view=rev
Log:
ARIES-52 updates to application parsing

Added:
    incubator/aries/trunk/application/application-utils/src/main/java/org/apache/aries/application/ApplicationMetadataManager.java
    incubator/aries/trunk/application/application-utils/src/main/java/org/apache/aries/application/impl/ApplicationMetadataManagerImpl.java
    incubator/aries/trunk/application/application-utils/src/main/java/org/apache/aries/application/impl/ApplicationMetadataManagerServiceImpl.java
    incubator/aries/trunk/application/application-utils/src/main/resources/
    incubator/aries/trunk/application/application-utils/src/main/resources/OSGI-INF/
    incubator/aries/trunk/application/application-utils/src/main/resources/OSGI-INF/blueprint/
    incubator/aries/trunk/application/application-utils/src/main/resources/OSGI-INF/blueprint/app-manager.xml
Removed:
    incubator/aries/trunk/application/application-utils/src/main/java/org/apache/aries/application/ApplicationMetadataFactory.java
Modified:
    incubator/aries/trunk/application/application-utils/   (props changed)
    incubator/aries/trunk/application/application-utils/pom.xml
    incubator/aries/trunk/application/application-utils/src/main/java/org/apache/aries/application/utils/manifest/ManifestProcessor.java
    incubator/aries/trunk/application/application-utils/src/test/java/org/apache/aries/application/utils/ManifestProcessorTest.java

Propchange: incubator/aries/trunk/application/application-utils/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Wed Nov 25 16:47:01 2009
@@ -0,0 +1,4 @@
+.settings
+target
+.classpath
+.project

Modified: incubator/aries/trunk/application/application-utils/pom.xml
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/application/application-utils/pom.xml?rev=884191&r1=884190&r2=884191&view=diff
==============================================================================
--- incubator/aries/trunk/application/application-utils/pom.xml (original)
+++ incubator/aries/trunk/application/application-utils/pom.xml Wed Nov 25 16:47:01 2009
@@ -45,6 +45,16 @@
   </dependencies>
 
     <build>
+        <resources>
+            <resource>
+                <targetPath>OSGI-INF/blueprint</targetPath>
+                <filtering>false</filtering>
+                <directory>${basedir}/src/main/resources/OSGI-INF/blueprint</directory>
+                <includes>
+                    <include>*.xml</include>
+                </includes>
+            </resource>
+        </resources>
         <plugins>
             <plugin>
                 <groupId>org.apache.felix</groupId>

Added: incubator/aries/trunk/application/application-utils/src/main/java/org/apache/aries/application/ApplicationMetadataManager.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/application/application-utils/src/main/java/org/apache/aries/application/ApplicationMetadataManager.java?rev=884191&view=auto
==============================================================================
--- incubator/aries/trunk/application/application-utils/src/main/java/org/apache/aries/application/ApplicationMetadataManager.java (added)
+++ incubator/aries/trunk/application/application-utils/src/main/java/org/apache/aries/application/ApplicationMetadataManager.java Wed Nov 25 16:47:01 2009
@@ -0,0 +1,74 @@
+/*
+ * 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 WARRANTIESOR 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.aries.application;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.jar.Manifest;
+
+import org.osgi.framework.Version;
+
+/**
+ * This service provides manages application metadata.
+ */
+public interface ApplicationMetadataManager
+{
+  /**
+   * Parse from the input stream the application manifest. This method is more
+   * lenient than the normal manifest parsing routine and does not limit the
+   * manifest to 76 bytes as a line length.
+   * 
+   * @param in the input stream to read the application manifest from.
+   * @return   the parsed application metadata.
+   * 
+   * @throws IOException if an IOException occurs reading from the stream.
+   */
+  public ApplicationMetadata parseApplication(InputStream in) throws IOException;
+  /**
+   * Create the application metadata from the provided Manifest. This is provided
+   * so application metadata can be created from within the JVM. When reading
+   * from a stream the parseApplication method should be used.
+   * 
+   * @param man the manifest to read from
+   * @return    the parsed application metadata.
+   */
+  public ApplicationMetadata createApplication(Manifest man);
+  /**
+   * This method is used to retrived a previously registered application metadata.
+   * 
+   * @param applicationSymbolicName the symbolic name of the application.
+   * @param version                 the version of the application.
+   * 
+   * @return the application metadata, or null if no application has been 
+   *         registered.
+   */
+  public ApplicationMetadata getApplication(String applicationSymbolicName, Version version);
+  /**
+   * This method is used to register an application. The ApplicationMetadata
+   * passed in should be created via the createApplication or parseApplication
+   * methods on this service. A boolean is returned to indicate if the 
+   * registration was successful or not. The most likely reason for a registration
+   * failure is that the application is already registered. When this service is 
+   * released all registered applications will be removed from the service.
+   * 
+   * @param app the application to register.
+   * @return    true if the application was registered, false otherwise.
+   */
+  public boolean registerApplication(ApplicationMetadata app);
+}
\ No newline at end of file

Added: incubator/aries/trunk/application/application-utils/src/main/java/org/apache/aries/application/impl/ApplicationMetadataManagerImpl.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/application/application-utils/src/main/java/org/apache/aries/application/impl/ApplicationMetadataManagerImpl.java?rev=884191&view=auto
==============================================================================
--- incubator/aries/trunk/application/application-utils/src/main/java/org/apache/aries/application/impl/ApplicationMetadataManagerImpl.java (added)
+++ incubator/aries/trunk/application/application-utils/src/main/java/org/apache/aries/application/impl/ApplicationMetadataManagerImpl.java Wed Nov 25 16:47:01 2009
@@ -0,0 +1,83 @@
+/*
+ * 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 WARRANTIESOR 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.aries.application.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.jar.Manifest;
+
+import org.apache.aries.application.ApplicationMetadata;
+import org.apache.aries.application.ApplicationMetadataManager;
+import org.apache.aries.application.utils.manifest.ManifestProcessor;
+import org.osgi.framework.Version;
+
+/**
+ * This class implements the application metadata manager. It is not directly
+ * exposed outside of the bundle, their is a service facade in front of it which
+ * is used by clients.
+ */
+public class ApplicationMetadataManagerImpl implements ApplicationMetadataManager
+{
+  /** The applications managed, keyed based on the app symbolic name and version */
+  public ConcurrentMap<String, ApplicationMetadata> applications = new ConcurrentHashMap<String, ApplicationMetadata>();
+
+  public ApplicationMetadata getApplication(String applicationSymbolicName, Version version)
+  {
+    ApplicationMetadata metadata = applications.get(applicationSymbolicName + "_" + version);
+    return metadata;
+  }
+
+  public ApplicationMetadata parseApplication(InputStream in) throws IOException
+  {
+    Manifest man = ManifestProcessor.parseManifest(in);
+    
+    ApplicationMetadata metadata = new ApplicationMetadataImpl(man);
+    
+    return metadata;
+  }
+  
+  public boolean registerApplication(ApplicationMetadata app)
+  {
+    String key = app.getApplicationSymbolicName() + "_" + app.getApplicationVersion();
+    
+    ApplicationMetadata existingApp = applications.putIfAbsent(key, app);
+    
+    return existingApp == null;
+  }
+  
+  public ApplicationMetadata createApplication(Manifest man)
+  {
+    return new ApplicationMetadataImpl(man);
+  }
+  
+  /**
+   * This method is called by the service facade to remove applications when
+   * the client bundle releases the service. It is not public.
+   * 
+   * @param app the application to remove.
+   */
+  public void removeApplication(ApplicationMetadata app)
+  {
+    String key = app.getApplicationSymbolicName() + "_" + app.getApplicationVersion();
+    applications.remove(key);
+  }
+
+}
\ No newline at end of file

Added: incubator/aries/trunk/application/application-utils/src/main/java/org/apache/aries/application/impl/ApplicationMetadataManagerServiceImpl.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/application/application-utils/src/main/java/org/apache/aries/application/impl/ApplicationMetadataManagerServiceImpl.java?rev=884191&view=auto
==============================================================================
--- incubator/aries/trunk/application/application-utils/src/main/java/org/apache/aries/application/impl/ApplicationMetadataManagerServiceImpl.java (added)
+++ incubator/aries/trunk/application/application-utils/src/main/java/org/apache/aries/application/impl/ApplicationMetadataManagerServiceImpl.java Wed Nov 25 16:47:01 2009
@@ -0,0 +1,89 @@
+/*
+ * 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 WARRANTIESOR 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.aries.application.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.jar.Manifest;
+
+import org.apache.aries.application.ApplicationMetadata;
+import org.apache.aries.application.ApplicationMetadataManager;
+import org.osgi.framework.Version;
+
+/**
+ * This class provides a facade in front of the manager to ensure we correctly
+ * remove registered applications when the requesting bundle releases the service.
+ * There is one instance of this class per requesting bundle.
+ */
+public class ApplicationMetadataManagerServiceImpl implements ApplicationMetadataManager
+{
+  /** The core application metadata manager */
+  private ApplicationMetadataManagerImpl manager;
+  /** A list of all applications registered via this service instance */
+  private List<ApplicationMetadata> appMetaData = new ArrayList<ApplicationMetadata>();
+  
+  /**
+   * Called by blueprint.
+   * 
+   * @param appManager the core app metadata manager.
+   */
+  public void setManager(ApplicationMetadataManagerImpl appManager)
+  {
+    manager = appManager;
+  }
+  
+  public ApplicationMetadata getApplication(String applicationSymbolicName, Version version)
+  {
+    return manager.getApplication(applicationSymbolicName, version);
+  }
+
+  public ApplicationMetadata parseApplication(InputStream in) throws IOException
+  {
+    return manager.parseApplication(in);
+  }
+
+  public ApplicationMetadata createApplication(Manifest man)
+  {
+    return manager.createApplication(man);
+  }
+
+  public boolean registerApplication(ApplicationMetadata app)
+  {
+    if (manager.registerApplication(app)) {
+      appMetaData.add(app);
+      return true;
+    }
+    return false;
+  }
+  
+  /**
+   * This method is called by blueprint when the calling bundle releases the
+   * service. It removes all the registered applications from the core manager.
+   */
+  public void close()
+  {
+    for (ApplicationMetadata app : appMetaData) {
+      manager.removeApplication(app);
+    }
+    
+    appMetaData.clear();
+  }
+}
\ No newline at end of file

Modified: incubator/aries/trunk/application/application-utils/src/main/java/org/apache/aries/application/utils/manifest/ManifestProcessor.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/application/application-utils/src/main/java/org/apache/aries/application/utils/manifest/ManifestProcessor.java?rev=884191&r1=884190&r2=884191&view=diff
==============================================================================
--- incubator/aries/trunk/application/application-utils/src/main/java/org/apache/aries/application/utils/manifest/ManifestProcessor.java (original)
+++ incubator/aries/trunk/application/application-utils/src/main/java/org/apache/aries/application/utils/manifest/ManifestProcessor.java Wed Nov 25 16:47:01 2009
@@ -18,7 +18,10 @@
  */
 package org.apache.aries.application.utils.manifest;
 
-import static org.apache.aries.application.utils.AppConstants.TRACE_GROUP;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -28,6 +31,11 @@
 import java.util.jar.Attributes;
 import java.util.jar.Manifest;
 
+/**
+ * This class contains utilities for parsing manifests. It provides methods to
+ * parse the manifest, read a manifest into a map and to split an manifest
+ * entry that follows the Import-Package syntax.
+ */
 public class ManifestProcessor
 {
   /**
@@ -59,6 +67,62 @@
   }
   
   /**
+   * This method parses the manifest using a custom manifest parsing routine.
+   * This means that we can avoid the 76 byte line length in a manifest providing
+   * a better developer experience.
+   * 
+   * @param in the input stream to read the manifest from.
+   * @return   the parsed manifest
+   * @throws IOException
+   */
+  public static Manifest parseManifest(InputStream in) throws IOException
+  {
+    Manifest man = new Manifest();
+    
+    // I'm assuming that we use UTF-8 here, but the jar spec doesn't say.
+    BufferedReader reader = new BufferedReader(new InputStreamReader(in, "UTF-8"));
+    
+    String line;
+    StringBuilder attribute = null;
+    
+    String namedAttribute = null;
+    
+    while ((line = reader.readLine()) != null) {
+      line = line.trim();
+      // if we get a blank line skip to the next one
+      if (line.length() == 0) continue;
+      if (line.charAt(0) == ' ' && attribute != null) {
+        // we have a continuation line, so add to the builder, ignoring the
+        // first character
+        attribute.append(line.substring(1));
+      } else if (attribute == null) {
+        attribute = new StringBuilder(line);
+      } else if (attribute != null) {
+        // We have fully parsed an attribute
+        int index = attribute.indexOf(":");
+        String attributeName = attribute.substring(0, index).trim();
+        // TODO cope with index + 1 being after the end of attribute
+        String attributeValue = attribute.substring(index + 1).trim();
+        
+        if ("Name".equals(attributeName)) {
+          man.getEntries().put(attributeValue, new Attributes());
+          namedAttribute = attributeValue;
+        } else {
+          if (namedAttribute == null) {
+            man.getMainAttributes().put(new Attributes.Name(attributeName), attributeValue);
+          } else {
+            man.getAttributes(namedAttribute).put(new Attributes.Name(attributeName), attributeValue);
+          }
+        }
+        
+        attribute = new StringBuilder(line);
+      }
+    }
+    
+    return man;
+  }
+  
+  /**
    * 
    * Splits a delimiter separated string, tolerating presence of non separator commas
    * within double quoted segments.
@@ -83,8 +147,8 @@
         String tmp = packages[i++].trim();
         // if there is a odd number of " in a string, we need to append
         while (count(tmp, "\"") % 2 == 1) {
-          // check to see if we need to append the next package[i++]          
-            tmp = tmp + delimiter + packages[i++].trim();          
+          // check to see if we need to append the next package[i++]
+          tmp = tmp + delimiter + packages[i++].trim();
         }
         
         result.add(tmp);

Added: incubator/aries/trunk/application/application-utils/src/main/resources/OSGI-INF/blueprint/app-manager.xml
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/application/application-utils/src/main/resources/OSGI-INF/blueprint/app-manager.xml?rev=884191&view=auto
==============================================================================
--- incubator/aries/trunk/application/application-utils/src/main/resources/OSGI-INF/blueprint/app-manager.xml (added)
+++ incubator/aries/trunk/application/application-utils/src/main/resources/OSGI-INF/blueprint/app-manager.xml Wed Nov 25 16:47:01 2009
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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.
+-->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+  
+  <bean id="core-manager" class="org.apache.aries.application.impl.ApplicationMetadataManagerImpl" scope="singleton" activation="lazy"/>
+  
+  <bean id="manager-service" class="org.apache.aries.application.impl.ApplicationMetadataManagerServiceImpl" scope="prototype" destroy-method="close">
+    <property name="manager" ref="core-manager"/>
+  </bean>
+  
+  <service interface="org.apache.aries.application.ApplicationMetadataManager" ref="manager-service" />
+</blueprint>
\ No newline at end of file

Modified: incubator/aries/trunk/application/application-utils/src/test/java/org/apache/aries/application/utils/ManifestProcessorTest.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/application/application-utils/src/test/java/org/apache/aries/application/utils/ManifestProcessorTest.java?rev=884191&r1=884190&r2=884191&view=diff
==============================================================================
--- incubator/aries/trunk/application/application-utils/src/test/java/org/apache/aries/application/utils/ManifestProcessorTest.java (original)
+++ incubator/aries/trunk/application/application-utils/src/test/java/org/apache/aries/application/utils/ManifestProcessorTest.java Wed Nov 25 16:47:01 2009
@@ -39,9 +39,9 @@
 import org.osgi.framework.Version;
 
 import org.apache.aries.application.ApplicationMetadata;
-import org.apache.aries.application.ApplicationMetadataFactory;
 import org.apache.aries.application.Content;
 import org.apache.aries.application.VersionRange;
+import org.apache.aries.application.impl.ApplicationMetadataManagerImpl;
 import org.apache.aries.application.utils.manifest.ManifestProcessor;
 
 public class ManifestProcessorTest
@@ -157,26 +157,25 @@
   @Test
   public void testManifestMetadata() throws Exception
   {
-	Manifest mf = new Manifest(new FileInputStream(new File(appFolder,"/META-INF/APPLICATION.MF")));
-	ApplicationMetadata am = ApplicationMetadataFactory.getApplicationMetadata(mf);
-	assertNotNull(am);
-	
-	String appName = pairs.get("Application-Name");
-	assertEquals(am.getApplicationName(),appName);
-
-	//"com.travel.reservation.web;version=\"[1.1.0,1.2.0)\",com.travel.reservation.business",
-	List<Content> contents = am.getApplicationContents();
-	for(Content content : contents){
-		if("com.travel.reservation.web".equals(content.getContentName())){
-			VersionRange vr = content.getVersion();
-			assertEquals(vr.getMinimumVersion(),new Version("1.1.0"));
-			assertEquals(vr.getMaximumVersion(),new Version("1.2.0"));
-		}else if("com.travel.reservation.business".equals(content.getContentName())){
-			VersionRange vr = content.getVersion();
-			assertNull(vr);		
-		}else fail("Unexepcted content name " + content.getContentName());
-	}
-  }  
-  
-  
-}
+    ApplicationMetadataManagerImpl manager = new ApplicationMetadataManagerImpl();
+    ApplicationMetadata am = manager.parseApplication(new FileInputStream(new File(appFolder,"/META-INF/APPLICATION.MF")));
+    assertNotNull(am);
+
+    String appName = pairs.get("Application-Name");
+    assertEquals(am.getApplicationName(),appName);
+
+    //"com.travel.reservation.web;version=\"[1.1.0,1.2.0)\",com.travel.reservation.business",
+    List<Content> contents = am.getApplicationContents();
+    for (Content content : contents){
+      if ("com.travel.reservation.web".equals(content.getContentName())){
+        VersionRange vr = content.getVersion();
+        assertEquals(vr.getMinimumVersion(),new Version("1.1.0"));
+        assertEquals(vr.getMaximumVersion(),new Version("1.2.0"));
+      } else if("com.travel.reservation.business".equals(content.getContentName())){
+        VersionRange vr = content.getVersion();
+        assertNull(vr);
+      } else 
+        fail("Unexepcted content name " + content.getContentName());
+    }
+  }
+}
\ No newline at end of file