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