aries-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dav...@apache.org
Subject svn commit: r1204471 - in /aries/trunk/util/util-r42/src: main/java/org/apache/aries/util/manifest/ManifestHeaderProcessor.java test/java/org/apache/aries/util/manifest/ManifestHeaderProcessorTest.java
Date Mon, 21 Nov 2011 12:35:04 GMT
Author: davidb
Date: Mon Nov 21 12:35:04 2011
New Revision: 1204471

URL: http://svn.apache.org/viewvc?rev=1204471&view=rev
Log:
Enhance ManifestHeaderProcessor to support Provide-Capability and Require-Capability style
headers. The functionality can be found in:
  ManifestHeaderProcessor.parseCapabilityString()
  ManifestHeaderProcessor.parseRequirementString()
Currently the implementation of both is exactly the same under the hood, but I introduced
them as separate methods to make make usage feel more naturally. It will also allow fixes
to them individually in the future if needed.

Modified:
    aries/trunk/util/util-r42/src/main/java/org/apache/aries/util/manifest/ManifestHeaderProcessor.java
    aries/trunk/util/util-r42/src/test/java/org/apache/aries/util/manifest/ManifestHeaderProcessorTest.java

Modified: aries/trunk/util/util-r42/src/main/java/org/apache/aries/util/manifest/ManifestHeaderProcessor.java
URL: http://svn.apache.org/viewvc/aries/trunk/util/util-r42/src/main/java/org/apache/aries/util/manifest/ManifestHeaderProcessor.java?rev=1204471&r1=1204470&r2=1204471&view=diff
==============================================================================
--- aries/trunk/util/util-r42/src/main/java/org/apache/aries/util/manifest/ManifestHeaderProcessor.java
(original)
+++ aries/trunk/util/util-r42/src/main/java/org/apache/aries/util/manifest/ManifestHeaderProcessor.java
Mon Nov 21 12:35:04 2011
@@ -31,6 +31,7 @@ import java.util.regex.Pattern;
 import org.apache.aries.util.ManifestHeaderUtils;
 import org.apache.aries.util.VersionRange;
 import org.osgi.framework.Constants;
+import org.osgi.framework.Version;
 
 
 public class ManifestHeaderProcessor
@@ -41,6 +42,31 @@ public class ManifestHeaderProcessor
   private static final String GREATER_EQ_OP = ">=";
 
   /**
+   * A GenericMetadata is either a Generic Capability or a Generic Requirement
+   */
+  public static class GenericMetadata {
+    private final String namespace;
+    private final Map<String, Object> attributes = new HashMap<String, Object>();
+    private final Map<String, String> directives = new HashMap<String, String>();
+
+    public GenericMetadata(String namespace) {
+      this.namespace = namespace;
+    }
+
+    public String getNamespace() {
+      return namespace;
+    }
+
+    public Map<String, Object> getAttributes() {
+      return attributes;
+    }
+
+    public Map<String, String> getDirectives() {
+      return directives;
+    }
+  }
+
+  /**
    * A simple class to associate two types.
    *
    * @param <N> The type for the 'Name'
@@ -49,7 +75,7 @@ public class ManifestHeaderProcessor
   public static class NameValuePair {
     private String name;
     private Map<String,String> attributes;
-    
+
     public NameValuePair(String name, Map<String,String> value)
     {
       this.name = name;
@@ -63,7 +89,7 @@ public class ManifestHeaderProcessor
     {
       this.name = name;
     }
-    
+
     public Map<String,String> getAttributes()
     {
       return attributes;
@@ -72,7 +98,7 @@ public class ManifestHeaderProcessor
     {
       this.attributes = value;
     }
-    
+
     @Override
     public String toString(){
       return "{"+name.toString()+"::"+attributes.toString()+"}";
@@ -102,9 +128,9 @@ public class ManifestHeaderProcessor
       return true;
     }
   }
-  
+
   /**
-   * Intended to provide a standard way to add Name/Value's to 
+   * Intended to provide a standard way to add Name/Value's to
    * aggregations of Name/Value's.
    *
    * @param <N> Type of 'Name'
@@ -121,17 +147,17 @@ public class ManifestHeaderProcessor
 
   /**
    * Map of Name -> Value.
-   * 
+   *
    * @param <N> Type of 'Name'
    * @param <V> Type of 'Value'
    */
   public static class NameValueMap extends HashMap<String, Map<String,String>>
implements NameValueCollection, Map<String, Map<String,String>>{
 	private static final long serialVersionUID = -6446338858542599141L;
-	
+
 	public void addToCollection(String n, Map<String,String> v){
       this.put(n,v);
     }
-	
+
 	@Override
 	public String toString(){
       StringBuilder sb = new StringBuilder();
@@ -146,19 +172,19 @@ public class ManifestHeaderProcessor
       return sb.toString();
     }
   }
-  
+
   /**
    * List of Name/Value
    *
    * @param <N> Type of 'Name'
    * @param <V> Type of 'Value'
    */
-  public static class NameValueList extends ArrayList<NameValuePair> implements NameValueCollection,
List<NameValuePair> {    
+  public static class NameValueList extends ArrayList<NameValuePair> implements NameValueCollection,
List<NameValuePair> {
 	private static final long serialVersionUID = 1808636823825029983L;
-	
+
 	public void addToCollection(String n, Map<String,String> v){
       this.add(new NameValuePair(n,v));
-    } 
+    }
 	@Override
     public String toString(){
       StringBuffer sb = new StringBuffer();
@@ -167,18 +193,18 @@ public class ManifestHeaderProcessor
       for(NameValuePair nvp : this){
         if(!first)sb.append(",");
         first=false;
-        sb.append(nvp.toString());        
+        sb.append(nvp.toString());
       }
       sb.append("}");
       return sb.toString();
     }
   }
-  
+
   /**
-   * 
+   *
    * Splits a delimiter separated string, tolerating presence of non separator commas
    * within double quoted segments.
-   * 
+   *
    * Eg.
    * com.ibm.ws.eba.helloWorldService;version="[1.0.0, 1.0.0]" &
    * com.ibm.ws.eba.helloWorldService;version="1.0.0"
@@ -191,23 +217,23 @@ public class ManifestHeaderProcessor
   public static List<String> split(String value, String delimiter)
   {
     return ManifestHeaderUtils.split(value, delimiter);
-  }  
-  
- 
+  }
+
+
   /**
    * Internal method to parse headers with the format<p>
-   *   [Name](;[Name])*(;[attribute-name]=[attribute-value])*<br> 
+   *   [Name](;[Name])*(;[attribute-name]=[attribute-value])*<br>
    * Eg.<br>
    *   rumplestiltskin;thing=value;other=something<br>
    *   littleredridinghood
    *   bundle1;bundle2;other=things
    *   bundle1;bundle2
-   *   
+   *
    * @param s data to parse
-   * @return a list of NameValuePair, with the Name being the name component, 
-   *         and the Value being a NameValueMap of key->value mappings.   
+   * @return a list of NameValuePair, with the Name being the name component,
+   *         and the Value being a NameValueMap of key->value mappings.
    */
-  private static List<NameValuePair> genericNameWithNameValuePairProcess(String s){
   
+  private static List<NameValuePair> genericNameWithNameValuePairProcess(String s){
     String name;
     Map<String,String> params = null;
     List<NameValuePair> nameValues = new ArrayList<NameValuePair>();
@@ -217,19 +243,19 @@ public class ManifestHeaderProcessor
       name = s;
       params = new HashMap<String, String>();
       pkgs.add(name);
-    }else{       
+    }else{
       name = s.substring(0,index).trim();
       String tail = s.substring(index+1).trim();
-      
+
       pkgs.add(name); // add the first package
       StringBuilder parameters = new StringBuilder();
-          
-      
+
+
       // take into consideration of multiple packages separated by ';'
       // while they share the same attributes or directives
       List<String> tailParts = split(tail, ";");
       boolean firstParameter =false;
-      
+
       for (String part : tailParts) {
         // if it is not a parameter and no parameter appears in front of it, it must a package
         if (!!!(part.contains("=")))  {
@@ -238,30 +264,30 @@ public class ManifestHeaderProcessor
           if (!!!(firstParameter))
             pkgs.add(part);
         } else {
-          if (!!!(firstParameter)) 
+          if (!!!(firstParameter))
             firstParameter = true;
 
           parameters.append(part + ";");
         }
-      }          
-      
+      }
+
       if (parameters.length() != 0) {
         //remove the final ';' if there is one
         if (parameters.toString().endsWith(";")) {
-         
+
           parameters = parameters.deleteCharAt(parameters.length() -1);
-        }       
-        
+        }
+
         params = genericNameValueProcess(parameters.toString());
       }
-      
+
     }
     for (String pkg : pkgs) {
       nameValues.add(new NameValuePair(pkg,params));
-    }  
-    
+    }
+
     return nameValues;
-   
+
   }
 
   /**
@@ -271,68 +297,68 @@ public class ManifestHeaderProcessor
    *   thing=value;other=something<br>
    * <p>
    * Note. Directives (name:=value) are represented in the map with name suffixed by ':'
-   *   
+   *
    * @param s data to parse
    * @return a NameValueMap, with attribute-name -> attribute-value.
    */
   private static Map<String,String> genericNameValueProcess(String s){
-    Map<String,String> params = new HashMap<String,String>();  
+    Map<String,String> params = new HashMap<String,String>();
     List<String> parameters = split(s, ";");
     for(String parameter : parameters) {
       List<String> parts = split(parameter,"=");
-      // do a check, otherwise we might get NPE   
+      // do a check, otherwise we might get NPE
       if (parts.size() ==2) {
         String second = parts.get(1).trim();
         if (second.startsWith("\"") && second.endsWith("\""))
           second = second.substring(1,second.length()-1);
-        
+
         String first = parts.get(0).trim();
-        
-        // make sure for directives we clear out any space as in "directive  :=value"   
    
+
+        // make sure for directives we clear out any space as in "directive  :=value"
         if (first.endsWith(":")) {
             first = first.substring(0, first.length()-1).trim()+":";
         }
-        
+
         params.put(first, second);
       }
     }
 
     return params;
   }
-  
+
   /**
-   * Processes an import/export style header.. <p> 
+   * Processes an import/export style header.. <p>
    *  pkg1;attrib=value;attrib=value,pkg2;attrib=value,pkg3;attrib=value
-   * 
+   *
    * @param out The collection to add each package name + attrib map to.
    * @param s The data to parse
    */
   private static void genericImportExportProcess(NameValueCollection out, String s){
     List<String> packages = split(s, ",");
-    for(String pkg : packages){   
+    for(String pkg : packages){
       List<NameValuePair> ps = genericNameWithNameValuePairProcess(pkg);
       for (NameValuePair p : ps) {
         out.addToCollection(p.getName(), p.getAttributes());
       }
-    }    
+    }
   }
-  
+
   /**
    * Parse an export style header.<p>
    *   pkg1;attrib=value;attrib=value,pkg2;attrib=value,pkg3;attrib=value2
    * <p>
    * Result is returned as a list, as export does allow duplicate package exports.
-   * 
+   *
    * @param list The data to parse.
-   * @return List of NameValuePairs, where each Name in the list is an exported package,

-   *         with its associated Value being a NameValueMap of any attributes declared. 
+   * @return List of NameValuePairs, where each Name in the list is an exported package,
+   *         with its associated Value being a NameValueMap of any attributes declared.
    */
   public static List<NameValuePair> parseExportString(String s){
     NameValueList retval = new NameValueList();
     genericImportExportProcess(retval, s);
     return retval;
   }
-  
+
   /**
    * Parse an export style header in a list.<p>
    *   pkg1;attrib=value;attrib=value
@@ -340,54 +366,144 @@ public class ManifestHeaderProcessor
    *   pkg3;attrib=value2
    * <p>
    * Result is returned as a list, as export does allow duplicate package exports.
-   * 
+   *
    * @param list The data to parse.
-   * @return List of NameValuePairs, where each Name in the list is an exported package,

-   *         with its associated Value being a NameValueMap of any attributes declared. 
+   * @return List of NameValuePairs, where each Name in the list is an exported package,
+   *         with its associated Value being a NameValueMap of any attributes declared.
    */
   public static List<NameValuePair> parseExportList(List<String> list){
     NameValueList retval = new NameValueList();
-    for(String pkg : list){   
+    for(String pkg : list){
       List<NameValuePair> ps = genericNameWithNameValuePairProcess(pkg);
       for (NameValuePair p : ps) {
         retval.addToCollection(p.getName(), p.getAttributes());
       }
-    } 
+    }
     return retval;
   }
-  
+
   /**
    * Parse an import style header.<p>
    *   pkg1;attrib=value;attrib=value,pkg2;attrib=value,pkg3;attrib=value
    * <p>
    * Result is returned as a set, as import does not allow duplicate package imports.
-   * 
+   *
    * @param s The data to parse.
-   * @return Map of NameValuePairs, where each Key in the Map is an imported package, 
-   *         with its associated Value being a NameValueMap of any attributes declared. 
-   */  
+   * @return Map of NameValuePairs, where each Key in the Map is an imported package,
+   *         with its associated Value being a NameValueMap of any attributes declared.
+   */
   public static Map<String, Map<String, String>> parseImportString(String s){
     NameValueMap retval = new NameValueMap();
     genericImportExportProcess(retval, s);
-    return retval;    
+    return retval;
+  }
+
+  /**
+   * Parse a generic capability header. For example<br/>
+   *   com.acme.myns;mylist:List<String>="nl,be,fr,uk";myver:Version=1.3;long:Long="1234";d:Double="3.14";myattr=xyz,
+   *   com.acme.myns;myattr=abc
+   * @param s The header to be parsed
+   * @return A list of GenericMetadata objects each representing an individual capability.
The values in the attribute map
+   *   are of the specified datatype.
+   */
+  public static List<GenericMetadata> parseCapabilityString(String s) {
+    return parseGenericMetadata(s);
   }
-  
+
+  /**
+   * Parse a generic capability header. For example<br/>
+   *   com.acme.myns;mylist:List<String>="nl,be,fr,uk";myver:Version=1.3;long:Long="1234";d:Double="3.14";myattr=xyz,
+   *   com.acme.myns;myattr=abc
+   * @param s The header to be parsed
+   * @return A list of GenericMetadata objects each representing an individual capability.
The values in the attribute map
+   *   are of the specified datatype.
+   */
+  public static List<GenericMetadata> parseRequirementString(String s) {
+    return parseGenericMetadata(s);
+  }
+
+  private static List<GenericMetadata> parseGenericMetadata(String s) {
+    List<GenericMetadata> capabilities = new ArrayList<GenericMetadata>();
+
+    List<String> entries = split(s, ",");
+    for(String e : entries){
+      List<NameValuePair> nvpList = genericNameWithNameValuePairProcess(e);
+
+      for(NameValuePair nvp : nvpList) {
+        String namespace = nvp.getName();
+        GenericMetadata cap = new GenericMetadata(namespace);
+        capabilities.add(cap);
+
+        Map<String, String> attrMap = nvp.getAttributes();
+        for (Map.Entry<String, String> entry : attrMap.entrySet()) {
+          String k = entry.getKey();
+          String v = entry.getValue();
+          if (k.contains(":")) {
+            if (k.endsWith(":")) {
+              // a directive
+              cap.getDirectives().put(k.substring(0, k.length() - 1), v);
+            } else {
+              // an attribute with its datatype specified
+              parseTypedAttribute(k, v, cap);
+            }
+          } else {
+            // ordinary (String) attribute
+            cap.getAttributes().put(k, v);
+          }
+        }
+      }
+    }
+
+    return capabilities;
+  }
+
+  private static void parseTypedAttribute(String k, String v, GenericMetadata cap) {
+    int idx = k.indexOf(':');
+    String name = k.substring(0, idx);
+    String type = k.substring(idx + 1);
+
+    if (type.startsWith("List<") && type.endsWith(">")) {
+      String subtype = type.substring("List<".length(), type.length() - 1).trim();
+      List<Object> l = new ArrayList<Object>();
+      for (String s : v.split(",")) {
+        l.add(getTypedValue(k, subtype, s));
+      }
+      cap.getAttributes().put(name, l);
+    } else {
+      cap.getAttributes().put(name, getTypedValue(k, type.trim(), v));
+    }
+  }
+
+  private static Object getTypedValue(String k, String type, String v) {
+    if ("String".equals(type)) {
+      return v;
+    } else if ("Long".equals(type)) {
+      return Long.parseLong(v);
+    } else if ("Double".equals(type)) {
+      return Double.parseDouble(v);
+    } else if ("Version".equals(type)) {
+      return Version.parseVersion(v);
+    }
+    throw new IllegalArgumentException(k + "=" + v);
+  }
+
+
   /**
    * Parse a bundle symbolic name.<p>
    *   bundlesymbolicname;attrib=value;attrib=value
    * <p>
-   * 
+   *
    * @param s The data to parse.
-   * @return NameValuePair with Name being the BundleSymbolicName, 
-   *         and Value being any attribs declared for the name. 
-   */   
+   * @return NameValuePair with Name being the BundleSymbolicName,
+   *         and Value being any attribs declared for the name.
+   */
   public static NameValuePair parseBundleSymbolicName(String s){
     return genericNameWithNameValuePairProcess(s).get(0); // should just return the first
one
   }
-  
+
   /**
-   * Parse a version range.. 
-   * 
+   * Parse a version range..
+   *
    * @param s
    * @return VersionRange object.
    * @throws IllegalArgumentException if the String could not be parsed as a VersionRange
@@ -395,10 +511,10 @@ public class ManifestHeaderProcessor
   public static VersionRange parseVersionRange(String s) throws IllegalArgumentException{
     return new VersionRange(s);
   }
-  
+
   /**
-   * Parse a version range and indicate if the version is an exact version 
-   * 
+   * Parse a version range and indicate if the version is an exact version
+   *
    * @param s
    * @param exactVersion
    * @return VersionRange object.
@@ -415,7 +531,7 @@ public class ManifestHeaderProcessor
 	 * Filter strings generated by this method will therefore tend to break the
 	 * standard OSGi Filter class. The OBR stanza can be stripped out later if
 	 * required.
-	 * 
+	 *
 	 * @param attribs
 	 * @return filter string
 	 */
@@ -537,10 +653,10 @@ public class ManifestHeaderProcessor
    * include a stanza of the form, (mandatory:<*mandatoryAttribute) Filter
    * strings generated by this method will therefore tend to break the standard
    * OSGi Filter class. The OBR stanza can be stripped out later if required.
-   * 
+   *
    * We may wish to consider relocating this method since VersionRange has its
    * own top level class.
-   * 
+   *
    * @param type
    * @param name
    * @param attribs
@@ -655,8 +771,8 @@ public class ManifestHeaderProcessor
 
     return result;
   }
-	  
-  public static Map<String,String> parseFilter(String filter) 
+
+  public static Map<String,String> parseFilter(String filter)
   {
     Map<String,String> result;
     if (filter.startsWith("(&")) {
@@ -666,6 +782,5 @@ public class ManifestHeaderProcessor
     }
     return result;
   }
-
 }
 

Modified: aries/trunk/util/util-r42/src/test/java/org/apache/aries/util/manifest/ManifestHeaderProcessorTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/util/util-r42/src/test/java/org/apache/aries/util/manifest/ManifestHeaderProcessorTest.java?rev=1204471&r1=1204470&r2=1204471&view=diff
==============================================================================
--- aries/trunk/util/util-r42/src/test/java/org/apache/aries/util/manifest/ManifestHeaderProcessorTest.java
(original)
+++ aries/trunk/util/util-r42/src/test/java/org/apache/aries/util/manifest/ManifestHeaderProcessorTest.java
Mon Nov 21 12:35:04 2011
@@ -27,15 +27,16 @@ import static org.junit.Assert.assertTru
 import static org.junit.Assert.fail;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
 import org.apache.aries.util.VersionRange;
-import org.apache.aries.util.manifest.ManifestHeaderProcessor;
-import org.apache.aries.util.manifest.ManifestHeaderProcessor.NameValueMap;
+import org.apache.aries.util.manifest.ManifestHeaderProcessor.GenericMetadata;
 import org.apache.aries.util.manifest.ManifestHeaderProcessor.NameValuePair;
 import org.junit.Test;
+import org.osgi.framework.Version;
 
 public class ManifestHeaderProcessorTest
 {
@@ -44,10 +45,10 @@ public class ManifestHeaderProcessorTest
 	HashMap<String, String> attrs = new HashMap<String, String>();
 	attrs.put("some", "value");
     NameValuePair nvp = new NameValuePair("key", attrs);
-    
+
     assertEquals("The name value pair is not set properly.", nvp.getName(), "key");
     assertEquals("The value is not set properly.", nvp.getAttributes().get("some"), "value");
-    
+
 	attrs = new HashMap<String, String>();
 	attrs.put("some", "value");
     NameValuePair anotherNvp = new NameValuePair("key", attrs);
@@ -59,58 +60,58 @@ public class ManifestHeaderProcessorTest
     nvp.setAttributes(attrs);
     assertEquals("The name value pair is not set properly.", nvp.getName(), "newKey");
     assertEquals("The value is not set properly.", nvp.getAttributes().get("some"), "newValue");
-    
+
     Map<String,String> nvm1 = new HashMap<String,String>();
     nvm1.put("a","b");
     nvm1.put("c","d");
-    
+
     Map<String,String> nvm2 = new HashMap<String,String>();
     nvm2.put("c","d");
     nvm2.put("a","b");
     assertEquals("The maps are not equal.", nvm1, nvm2);
     nvm2.put("e","f");
     assertNotSame("The maps are the same.", nvm1, nvm2);
-    
+
     NameValuePair nvp1 = new NameValuePair("one",nvm1);
     NameValuePair nvp2 = new NameValuePair("one",nvm2);
-    
+
     assertNotSame("The pairs are identical ",nvp1,nvp2);
     nvm1.put("e","f");
     assertEquals("The pairs are not equal.", nvp1,nvp2);
-    
+
     List<NameValuePair> bundleInfoList1 = new ArrayList<NameValuePair>();
     bundleInfoList1.add(nvp1);
 
     List<NameValuePair> bundleInfoList2 = new ArrayList<NameValuePair>();
     bundleInfoList2.add(nvp1);
-    
+
     bundleInfoList1.removeAll(bundleInfoList2);
     assertEquals("The List should be empty", bundleInfoList1.isEmpty(), true);
-   
-   
+
+
     assertNotSame("The two objects of NameValuePair is not equal.", nvp, anotherNvp);
   }
 
-  
+
   /**
    * Test the Bundle manifest header entry of
    * Bundle-SymbolicName: com.acme.foo;singleton:=true
    */
   @Test
-  public void testParseBundleSymbolicName() 
+  public void testParseBundleSymbolicName()
   {
     String bundleSymbolicNameEntry = "com.acme.foo;singleton:=true;fragment-attachment:=always";
     NameValuePair nvp = ManifestHeaderProcessor.parseBundleSymbolicName(bundleSymbolicNameEntry);
     assertEquals("The symbolic name is wrong.", nvp.getName(), "com.acme.foo");
     assertEquals("The value is wrong.", "true", nvp.getAttributes().get("singleton:") );
     assertEquals("The directive is wrong.", "always", nvp.getAttributes().get("fragment-attachment:")
);
-  
+
     String bundleSymbolicNameEntry2 = "com.acme.foo";
     NameValuePair nvp2 = ManifestHeaderProcessor.parseBundleSymbolicName(bundleSymbolicNameEntry2);
     assertEquals("The symbolic name is wrong.", nvp2.getName(), "com.acme.foo");
   }
-  
- 
+
+
 
   /**
    * Test the import package and import service
@@ -120,9 +121,9 @@ public class ManifestHeaderProcessorTest
   public void testParseImportString()
   {
     String importPackage = "com.acme.foo,come.acm.e.bar;version=\"[1.23,1.24.5]\";resolution:=mandatory;company=\"ACME\",a.b.c;version=1.2.3;company=com";
-  
+
     Map<String, Map<String, String>> importPackageReturn = ManifestHeaderProcessor.parseImportString(importPackage);
-  
+
     assertTrue("The package is not set.", importPackageReturn.containsKey("com.acme.foo"));
     assertTrue("The package is not set.", importPackageReturn.containsKey("come.acm.e.bar"));
     assertTrue("The package is not set.", importPackageReturn.containsKey("come.acm.e.bar"));
@@ -133,12 +134,12 @@ public class ManifestHeaderProcessorTest
     assertEquals("The directive is not set correctly.", "ACME", importPackageReturn.get("come.acm.e.bar").get("company"));
     assertEquals("The directive is not set correctly.", "1.2.3", importPackageReturn.get("a.b.c").get("version"));
     assertEquals("The directive is not set correctly.", "com", importPackageReturn.get("a.b.c").get("company"));
-    
+
     importPackage="com.acme.foo";
-    
+
     assertTrue("The package is not set.", importPackageReturn.containsKey("com.acme.foo"));
     assertTrue("The package should not contain any attributes.", importPackageReturn.get("com.acme.foo").isEmpty());
-    
+
     importPackage="com.acme.foo;com.acme.bar;version=2";
     Map<String, Map<String, String>> importPackageReturn2 = ManifestHeaderProcessor.parseImportString(importPackage);
     assertTrue("The package is not set.", importPackageReturn2.containsKey("com.acme.foo"));
@@ -146,31 +147,31 @@ public class ManifestHeaderProcessorTest
     assertEquals("The directive is not set correctly.", "2", importPackageReturn2.get("com.acme.foo").get("version"));
     assertEquals("The directive is not set correctly.", "2", importPackageReturn2.get("com.acme.bar").get("version"));
   }
-  
+
   @Test
   public void testParseExportString()
   {
     String exportPackage = "com.acme.foo,com.acme.bar;version=1,com.acme.bar;version=2;uses:=\"a.b.c,d.e.f\";security=false;mandatory:=security";
-  
+
     List<NameValuePair> exportPackageReturn = ManifestHeaderProcessor.parseExportString(exportPackage);
-    
+
     int i =0;
     assertEquals("The number of the packages is wrong.", 3, exportPackageReturn.size());
     for (NameValuePair nvp : exportPackageReturn) {
       if (nvp.getName().equals("com.acme.foo")) {
         i++;
-        
+
         assertTrue("The directive or attribute should not be set.", nvp.getAttributes().isEmpty()
);
       } else if ((nvp.getName().equals("com.acme.bar")) && ("2".equals(nvp.getAttributes().get("version"))))
{
-      
-        
+
+
         i++;
         assertEquals("The directive is wrong.", "a.b.c,d.e.f", nvp.getAttributes().get("uses:"));
         assertEquals("The directive is wrong.", "false", nvp.getAttributes().get("security"));
         assertEquals("The directive is wrong.", "security", nvp.getAttributes().get("mandatory:"));
       } else if ((nvp.getName().equals("com.acme.bar")) && ("1".equals(nvp.getAttributes().get("version"))))
{
         i++;
-        
+
         assertNull("The directive is wrong.", nvp.getAttributes().get("uses:"));
         assertNull("The directive is wrong.", nvp.getAttributes().get("security"));
         assertNull("The directive is wrong.", nvp.getAttributes().get("mandatory:"));
@@ -178,90 +179,90 @@ public class ManifestHeaderProcessorTest
     }
     // make sure all three packages stored
     assertEquals("The names of the packages are wrong.", 3, i);
-    
+
     exportPackage = "com.acme.foo";
-    
+
     exportPackageReturn = ManifestHeaderProcessor.parseExportString(exportPackage);
-    
+
     int k =0;
     assertEquals("The number of the packages is wrong.", 1, exportPackageReturn.size());
     for (NameValuePair nvp : exportPackageReturn) {
       if (nvp.getName().equals("com.acme.foo")) {
         k++;
-        
+
         assertTrue("The directive or attribute should not be set.", nvp.getAttributes().isEmpty()
);
-      } 
+      }
     }
     assertEquals("The names of the packages are wrong.", 1, k);
-    
+
     // test multiple packages separated by ;
-    
+
     exportPackage = "com.acme.foo;com.acme.bar;version=\"2\";resolution:=optional";
-    
+
     exportPackageReturn = ManifestHeaderProcessor.parseExportString(exportPackage);
-    
+
     k =0;
     assertEquals("The number of the packages is wrong.", 2, exportPackageReturn.size());
     for (NameValuePair nvp : exportPackageReturn) {
       if (nvp.getName().equals("com.acme.foo")) {
         k++;
-        
+
         assertEquals("The attribute is wrong.", "2", nvp.getAttributes().get("version") );
         assertEquals("The attribute is wrong.", "optional", nvp.getAttributes().get("resolution:"));
       } else if (nvp.getName().equals("com.acme.bar")) {
         k++;
-        
+
         assertEquals("The attribute is wrong.", "2", nvp.getAttributes().get("version") );
         assertEquals("The attribute is wrong.", "optional", nvp.getAttributes().get("resolution:"));
       }
     }
     assertEquals("The names of the packages are wrong.", 2, k);
-    
+
     exportPackageReturn = ManifestHeaderProcessor.parseExportString("some.export.with.space.in;directive
:= spacey");
     assertEquals(exportPackageReturn.toString(), "spacey", exportPackageReturn.get(0).getAttributes().get("directive:"));
   }
-    
+
     @Test
     public void testExportMandatoryAttributes() {
       String exportPackage = "com.acme.foo,com.acme.bar;version=2;company=dodo;security=false;mandatory:=\"security,company\"";
-      
+
       List<NameValuePair> exportPackageReturn = ManifestHeaderProcessor.parseExportString(exportPackage);
-      
+
       int i =0;
       assertEquals("The number of the packages is wrong.", 2, exportPackageReturn.size());
       for (NameValuePair nvp : exportPackageReturn) {
         if (nvp.getName().equals("com.acme.foo")) {
           i++;
-          
+
           assertTrue("The directive or attribute should not be set.", nvp.getAttributes().isEmpty()
);
         } else if ((nvp.getName().equals("com.acme.bar")) && ("2".equals(nvp.getAttributes().get("version"))))
{
-        
-          
+
+
           i++;
           assertEquals("The directive is wrong.", "dodo", nvp.getAttributes().get("company"));
           assertEquals("The directive is wrong.", "false", nvp.getAttributes().get("security"));
           assertEquals("The directive is wrong.", "security,company", nvp.getAttributes().get("mandatory:"));
-        } 
+        }
       }
       // make sure all three packages stored
       assertEquals("The names of the packages are wrong.", 2, i);
-      
+
     }
-    
+
     private String createExpectedFilter(Map<String, String> values, String ... parts)
     {
       StringBuilder builder = new StringBuilder(parts[0]);
-      
+
       for (Map.Entry<String, String> entry : values.entrySet()) {
         if ("version".equals(entry.getKey())) builder.append(parts[2]);
         else if ("company".equals(entry.getKey())) builder.append(parts[1]);
       }
-      
+
       builder.append(parts[3]);
-      
+
       return builder.toString();
     }
-    
+
     /**
      * Test the filter generated correctly
      * @throws Exception
@@ -275,49 +276,49 @@ public class ManifestHeaderProcessorTest
       String filter = ManifestHeaderProcessor.generateFilter("symbolic-name", "com.ibm.foo",
valueMap);
       String expected = createExpectedFilter(valueMap, "(&(symbolic-name=com.ibm.foo)",
"(company=com)", "(version>=1.2.0)(version<=2.3.0)", "(mandatory:<*company))");
       assertEquals("The filter is wrong.", expected, filter );
-      
-      
+
+
       valueMap.clear();
-      
+
       valueMap.put("version", "(1.2, 2.3]");
       valueMap.put("resulution:", "mandatory");
       valueMap.put("company", "com");
       filter = ManifestHeaderProcessor.generateFilter("symbolic-name", "com.ibm.foo", valueMap);
       expected = createExpectedFilter(valueMap, "(&(symbolic-name=com.ibm.foo)", "(company=com)",
"(version>=1.2.0)(version<=2.3.0)(!(version=1.2.0))", "(mandatory:<*company))");
       assertEquals("The filter is wrong.", expected, filter );
-      
+
       valueMap.clear();
-      
+
       valueMap.put("version", "(1.2, 2.3)");
       valueMap.put("resulution:", "mandatory");
       valueMap.put("company", "com");
       filter = ManifestHeaderProcessor.generateFilter("symbolic-name", "com.ibm.foo", valueMap);
       expected = createExpectedFilter(valueMap, "(&(symbolic-name=com.ibm.foo)", "(company=com)",
"(version>=1.2.0)(version<=2.3.0)(!(version=1.2.0))(!(version=2.3.0))", "(mandatory:<*company))");
       assertEquals("The filter is wrong.", expected, filter );
-      
+
       valueMap.clear();
-      
+
       valueMap.put("version", "1.2");
       valueMap.put("resulution:", "mandatory");
       valueMap.put("company", "com");
       filter = ManifestHeaderProcessor.generateFilter("symbolic-name", "com.ibm.foo", valueMap);
       expected = createExpectedFilter(valueMap, "(&(symbolic-name=com.ibm.foo)", "(company=com)",
"(version>=1.2.0)", "(mandatory:<*company))");
       assertEquals("The filter is wrong.", expected, filter );
-      
+
       valueMap.clear();
-      
+
       valueMap.put("resulution:", "mandatory");
       valueMap.put("company", "com");
       filter = ManifestHeaderProcessor.generateFilter("symbolic-name", "com.ibm.foo", valueMap);
       expected = createExpectedFilter(valueMap, "(&(symbolic-name=com.ibm.foo)", "(company=com)",
"", "(mandatory:<*company))");
       assertEquals("The filter is wrong.", expected, filter );
     }
-    
+
     /**
      * Test the version range created correctly
      * @throws Exception
      */
-    
+
     @Test
     public void testVersionRange() throws Exception {
       String version1 = "[1.2.3, 4.5.6]";
@@ -332,51 +333,51 @@ public class ManifestHeaderProcessorTest
       String version10=null;
       String version11="";
       String version12="\"[1.2.3, 4.5.6]\"";
-      
+
       VersionRange vr = ManifestHeaderProcessor.parseVersionRange(version1);
       assertEquals("The value is wrong", "1.2.3", vr.getMinimumVersion().toString());
       assertFalse("The value is wrong", vr.isMinimumExclusive());
       assertEquals("The value is wrong", "4.5.6", vr.getMaximumVersion().toString());
       assertFalse("The value is wrong", vr.isMaximumExclusive());
-      
+
       vr = ManifestHeaderProcessor.parseVersionRange(version2);
       assertEquals("The value is wrong", "1.0.0", vr.getMinimumVersion().toString());
       assertTrue("The value is wrong", vr.isMinimumExclusive());
       assertEquals("The value is wrong", "2.0.0", vr.getMaximumVersion().toString());
       assertFalse("The value is wrong", vr.isMaximumExclusive());
-      
+
       vr = ManifestHeaderProcessor.parseVersionRange(version3);
-      
+
       assertEquals("The value is wrong", "2.0.0", vr.getMinimumVersion().toString());
       assertFalse("The value is wrong", vr.isMinimumExclusive());
       assertEquals("The value is wrong", "4.0.0", vr.getMaximumVersion().toString());
       assertTrue("The value is wrong", vr.isMaximumExclusive());
-      
+
       vr = ManifestHeaderProcessor.parseVersionRange(version4);
-      
+
       assertEquals("The value is wrong", "1.0.0", vr.getMinimumVersion().toString());
       assertTrue("The value is wrong", vr.isMinimumExclusive());
       assertEquals("The value is wrong", "2.0.0", vr.getMaximumVersion().toString());
       assertTrue("The value is wrong", vr.isMaximumExclusive());
-      
+
       vr = ManifestHeaderProcessor.parseVersionRange(version5);
       assertEquals("The value is wrong", "2.0.0", vr.getMinimumVersion().toString());
       assertFalse("The value is wrong", vr.isMinimumExclusive());
       assertNull("The value is wrong", vr.getMaximumVersion());
       assertFalse("The value is wrong", vr.isMaximumExclusive());
-      
+
       vr = ManifestHeaderProcessor.parseVersionRange(version6);
       assertEquals("The value is wrong", "2.3.0", vr.getMinimumVersion().toString());
       assertFalse("The value is wrong", vr.isMinimumExclusive());
       assertNull("The value is wrong", vr.getMaximumVersion());
       assertFalse("The value is wrong", vr.isMaximumExclusive());
-      
+
       vr = ManifestHeaderProcessor.parseVersionRange(version7);
       assertEquals("The value is wrong", "1.2.3.q", vr.getMinimumVersion().toString());
       assertFalse("The value is wrong", vr.isMinimumExclusive());
       assertEquals("The value is wrong", "2.3.4.p", vr.getMaximumVersion().toString());
       assertTrue("The value is wrong", vr.isMaximumExclusive());
-      
+
       vr = ManifestHeaderProcessor.parseVersionRange(version8);
       assertEquals("The value is wrong", "1.2.2.5", vr.getMinimumVersion().toString());
       assertFalse("The value is wrong", vr.isMinimumExclusive());
@@ -388,7 +389,7 @@ public class ManifestHeaderProcessorTest
       } catch (Exception e){
         exception = true;
       }
-      
+
       assertTrue("The value is wrong", exception);
       boolean exceptionNull = false;
       try {
@@ -403,15 +404,15 @@ public class ManifestHeaderProcessorTest
         assertFalse("The value is wrong", vr.isMinimumExclusive());
         assertNull("The value is wrong", vr.getMaximumVersion());
         assertFalse("The value is wrong", vr.isMaximumExclusive());
-          
-          
+
+
           vr = ManifestHeaderProcessor.parseVersionRange(version12);
           assertEquals("The value is wrong", "1.2.3", vr.getMinimumVersion().toString());
           assertFalse("The value is wrong", vr.isMinimumExclusive());
           assertEquals("The value is wrong", "4.5.6", vr.getMaximumVersion().toString());
-          assertFalse("The value is wrong", vr.isMaximumExclusive());  
+          assertFalse("The value is wrong", vr.isMaximumExclusive());
     }
-    
+
     @Test
     public void testInvalidVersions() throws Exception
     {
@@ -421,7 +422,7 @@ public class ManifestHeaderProcessorTest
       } catch (IllegalArgumentException e) {
         // assertEquals(MessageUtil.getMessage("APPUTILS0009E", "a"), e.getMessage());
       }
-      
+
       try {
         ManifestHeaderProcessor.parseVersionRange("[1.0.0,1.0.1]", true);
         assertTrue("Should have thrown an exception", false);
@@ -437,18 +438,18 @@ public class ManifestHeaderProcessorTest
       List<String> result = ManifestHeaderProcessor.split(export, ",");
       assertEquals("The result is wrong.", export, result.get(0));
       assertEquals("The result is wrong.", 1, result.size());
-      
+
       String aString = "com.acme.foo;weirdAttr=\"one;two;three\";weirdDir:=\"1;2;3\"";
       result = ManifestHeaderProcessor.split(aString, ";");
       assertEquals("The result is wrong.", "com.acme.foo", result.get(0));
       assertEquals("The result is wrong.", "weirdAttr=\"one;two;three\"", result.get(1));
       assertEquals("The result is wrong.", "weirdDir:=\"1;2;3\"", result.get(2));
-      
+
       assertEquals("The result is wrong.", 3, result.size());
-      
-      
-      
-      
+
+
+
+
       String pkg1 = "com.ibm.ws.eba.example.helloIsolation;version=\"1.0.0\" ";
       String pkg2 = "com.ibm.ws.eba.helloWorldService;version=\"[1.0.0,1.0.0]\"";
       String pkg3 = " com.ibm.ws.eba.helloWorldService;version=\"1.0.0\"";
@@ -459,47 +460,47 @@ public class ManifestHeaderProcessorTest
       String appContent3 = pkg1 + ", " + pkg3 + ", " + pkg2;
       String appContent4 = pkg1 + ", " + pkg3 + ", " + pkg4;
       String appContent5 = pkg1 + ", " + pkg3 + ", " + pkg5;
-      
+
       List<String> splitList = ManifestHeaderProcessor.split(appContent1, ",");
       assertEquals(pkg1.trim(), splitList.get(0));
       assertEquals(pkg2.trim(), splitList.get(1));
       assertEquals(pkg3.trim(), splitList.get(2));
-      
+
       splitList = ManifestHeaderProcessor.split(appContent2, ",");
       assertEquals(pkg2.trim(), splitList.get(0));
       assertEquals(pkg1.trim(), splitList.get(1));
       assertEquals(pkg3.trim(), splitList.get(2));
-      
+
       splitList = ManifestHeaderProcessor.split(appContent3, ",");
       assertEquals(pkg1.trim(), splitList.get(0));
       assertEquals(pkg3.trim(), splitList.get(1));
       assertEquals(pkg2.trim(), splitList.get(2));
-      
+
       splitList = ManifestHeaderProcessor.split(appContent4, ",");
       assertEquals(pkg1.trim(), splitList.get(0));
       assertEquals(pkg3.trim(), splitList.get(1));
       assertEquals(pkg4.trim(), splitList.get(2));
-      
+
       splitList = ManifestHeaderProcessor.split(appContent5, ",");
       assertEquals(pkg1.trim(), splitList.get(0));
       assertEquals(pkg3.trim(), splitList.get(1));
-      assertEquals(pkg5.trim(), splitList.get(2));   
+      assertEquals(pkg5.trim(), splitList.get(2));
     }
-    
+
     @Test
     public void testParseFilter()
     {
       Map<String,String> attrs = ManifestHeaderProcessor.parseFilter("(package=com.ibm.test)");
       assertEquals("com.ibm.test", attrs.get("package"));
-      
+
       attrs = ManifestHeaderProcessor.parseFilter("(&(package=com.ibm.test)(attr=value))");
       assertEquals("com.ibm.test", attrs.get("package"));
       assertEquals("value", attrs.get("attr"));
       assertEquals(2, attrs.size());
-      
+
       attrs = ManifestHeaderProcessor.parseFilter("(&(version>=1.0.0))");
       assertEquals("1.0.0", attrs.get("version"));
-      
+
       attrs = ManifestHeaderProcessor.parseFilter("(&(version>=1.0.0)(version<=2.0.0))");
       assertEquals("[1.0.0,2.0.0]", attrs.get("version"));
 
@@ -509,9 +510,9 @@ public class ManifestHeaderProcessorTest
       attrs = ManifestHeaderProcessor.parseFilter("(&(!(version=2.0.0))(!(version=1.0.0))(version>=1.0.0)(version<=2.0.0))");
       assertEquals("(1.0.0,2.0.0)", attrs.get("version"));
     }
-    
+
     @Test
-    public void testExactVersion() throws Exception 
+    public void testExactVersion() throws Exception
     {
       VersionRange vr;
       try {
@@ -520,30 +521,102 @@ public class ManifestHeaderProcessorTest
       } catch (IllegalArgumentException e) {
         // expected
       }
-      
+
       vr = ManifestHeaderProcessor.parseVersionRange("[1.0.0, 1.0.0]", true);
       assertTrue(vr.isExactVersion());
-      
+
       try {
         vr = ManifestHeaderProcessor.parseVersionRange("(1.0.0, 1.0.0]", true);
         fail("should not get here 2");
       } catch (IllegalArgumentException e) {
         // expected
       }
-      
+
       try {
         vr = ManifestHeaderProcessor.parseVersionRange("[1.0.0, 1.0.0)", true);
         fail("should not get here 3");
       } catch (IllegalArgumentException e) {
         // expected
       }
-      
+
       vr = ManifestHeaderProcessor.parseVersionRange("[1.0.0, 2.0.0]");
       assertFalse(vr.isExactVersion());
-      
+
       vr = ManifestHeaderProcessor.parseVersionRange("[1.0.0, 1.0.0]");
       assertTrue(vr.isExactVersion());
-      
-      
+
+
+    }
+
+    @Test
+    public void testCapabilityHeader() throws Exception {
+      String s =
+          "com.acme.dictionary; effective:=resolve; from:String=nl; to=de; version:Version=3.4.0.test;somedir:=test,
" +
+          "com.acme.dictionary; filter:=\"(&(width>=1000)(height>=1000))\", " +
+          "com.acme.ip2location;country:List<String>=\"nl,be,fr,uk\";version:Version=1.3;long:Long="
+ Long.MAX_VALUE + ";d:Double=\"2.2250738585072012e-308\"";
+
+      List<GenericMetadata> capabilities = ManifestHeaderProcessor.parseCapabilityString(s);
+      testCapabilitiesOrRequirements(capabilities);
+    }
+
+    @Test
+    public void testRequirementHeader() throws Exception {
+      String s =
+          "com.acme.dictionary; effective:=resolve; from:String=nl; to=de; version:Version=3.4.0.test;somedir:=test,
" +
+          "com.acme.dictionary; filter:=\"(&(width>=1000)(height>=1000))\", " +
+          "com.acme.ip2location;country:List<String>=\"nl,be,fr,uk\";version:Version=1.3;long:Long="
+ Long.MAX_VALUE + ";d:Double=\"2.2250738585072012e-308\"";
+
+      List<GenericMetadata> capabilities = ManifestHeaderProcessor.parseRequirementString(s);
+      testCapabilitiesOrRequirements(capabilities);
+    }
+
+    private void testCapabilitiesOrRequirements(List<GenericMetadata> metadata) {
+      assertEquals(3, metadata.size());
+
+      boolean found1 = false, found2 = false, found3 = false;
+      for (GenericMetadata cap : metadata) {
+        if ("com.acme.dictionary".equals(cap.getNamespace()) && cap.getDirectives().containsKey("effective"))
{
+          testDictionaryCapability1(cap);
+          found1 = true;
+        } else if ("com.acme.dictionary".equals(cap.getNamespace()) && cap.getDirectives().containsKey("filter"))
{
+          testDictionaryCapability2(cap);
+          found2 = true;
+        } else if ("com.acme.ip2location".equals(cap.getNamespace())) {
+          testIP2LocationCapability(cap);
+          found3 = true;
+        }
+      }
+
+      assertTrue(found1);
+      assertTrue(found2);
+      assertTrue(found3);
+    }
+
+    private void testDictionaryCapability1(GenericMetadata cap) {
+      assertEquals(2, cap.getDirectives().size());
+      assertEquals("resolve", cap.getDirectives().get("effective"));
+      assertEquals("test", cap.getDirectives().get("somedir"));
+
+      assertEquals(3, cap.getAttributes().size());
+      assertEquals("nl", cap.getAttributes().get("from"));
+      assertEquals("de", cap.getAttributes().get("to"));
+      assertEquals(new Version(3, 4, 0, "test"), cap.getAttributes().get("version"));
+    }
+
+    private void testDictionaryCapability2(GenericMetadata cap) {
+      assertEquals(1, cap.getDirectives().size());
+      assertEquals("(&(width>=1000)(height>=1000))", cap.getDirectives().get("filter"));
+
+      assertEquals(0, cap.getAttributes().size());
+    }
+
+    private void testIP2LocationCapability(GenericMetadata cap) {
+      assertEquals(0, cap.getDirectives().size());
+      assertEquals(4, cap.getAttributes().size());
+
+      assertEquals(new Version(1, 3, 0), cap.getAttributes().get("version"));
+      assertEquals(Arrays.asList("nl", "be", "fr", "uk"), cap.getAttributes().get("country"));
+      assertEquals(Long.MAX_VALUE, cap.getAttributes().get("long"));
+      assertEquals(0, new Double("2.2250738585072012e-308").compareTo((Double) cap.getAttributes().get("d")));
     }
 }



Mime
View raw message