incubator-aries-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From timothyjw...@apache.org
Subject svn commit: r921533 - /incubator/aries/trunk/application/application-utils/src/main/java/org/apache/aries/application/utils/manifest/ManifestHeaderProcessor.java
Date Wed, 10 Mar 2010 19:59:26 GMT
Author: timothyjward
Date: Wed Mar 10 19:59:25 2010
New Revision: 921533

URL: http://svn.apache.org/viewvc?rev=921533&view=rev
Log:
ARIES-239 : Improvements to ManifestHeaderProcessor

Modified:
    incubator/aries/trunk/application/application-utils/src/main/java/org/apache/aries/application/utils/manifest/ManifestHeaderProcessor.java

Modified: incubator/aries/trunk/application/application-utils/src/main/java/org/apache/aries/application/utils/manifest/ManifestHeaderProcessor.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/application/application-utils/src/main/java/org/apache/aries/application/utils/manifest/ManifestHeaderProcessor.java?rev=921533&r1=921532&r2=921533&view=diff
==============================================================================
--- incubator/aries/trunk/application/application-utils/src/main/java/org/apache/aries/application/utils/manifest/ManifestHeaderProcessor.java
(original)
+++ incubator/aries/trunk/application/application-utils/src/main/java/org/apache/aries/application/utils/manifest/ManifestHeaderProcessor.java
Wed Mar 10 19:59:25 2010
@@ -37,6 +37,9 @@ import org.osgi.framework.Constants;
 public class ManifestHeaderProcessor
 {
   public static final String NESTED_FILTER_ATTRIBUTE = "org.apache.aries.application.filter.attribute";
+  private static final Pattern FILTER_ATTR = Pattern.compile("(\\(!)?\\((.*?)([<>]?=)(.*?)\\)\\)?");
+  private static final String LESS_EQ_OP = "<=";
+  private static final String GREATER_EQ_OP = ">=";
 
   /**
    * A simple class to associate two types.
@@ -430,125 +433,197 @@ public class ManifestHeaderProcessor
   }
 
   /**
-   * We may wish to consider moving this method to VersionRange.
+	 * Generate a filter from a set of attributes. This filter will be suitable
+	 * for presentation to OBR This means that, due to the way OBR works, it
+	 * will 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.
+	 * 
+	 * @param attribs
+	 * @return filter string
+	 */
+	public static String generateFilter(Map<String, String> attribs) {
+		StringBuilder filter = new StringBuilder("(&");
+		boolean realAttrib = false;
+		StringBuffer realAttribs = new StringBuffer();
+
+		if (attribs == null) {
+			attribs = new HashMap<String, String>();
+		}
+
+		for (Map.Entry<String, String> attrib : attribs.entrySet()) {
+			String attribName = attrib.getKey();
+
+			if (attribName.endsWith(":")) {
+				// skip all directives. It is used to affect the attribs on the
+				// filter xml.
+			} else if ((Constants.VERSION_ATTRIBUTE.equals(attribName))
+					|| (Constants.BUNDLE_VERSION_ATTRIBUTE.equals(attribName))) {
+				// version and bundle-version attrib requires special
+				// conversion.
+				realAttrib = true;
+
+				VersionRange vr = ManifestHeaderProcessor
+						.parseVersionRange(attrib.getValue());
+
+				filter.append("(" + attribName + ">=" + vr.getMinimumVersion());
+
+				if (vr.getMaximumVersion() != null) {
+					filter.append(")(" + attribName + "<=");
+					filter.append(vr.getMaximumVersion());
+				}
+
+				if (vr.getMaximumVersion() != null && vr.isMinimumExclusive()) {
+					filter.append(")(!(" + attribName + "=");
+					filter.append(vr.getMinimumVersion());
+					filter.append(")");
+				}
+
+				if (vr.getMaximumVersion() != null && vr.isMaximumExclusive()) {
+					filter.append(")(!(" + attribName + "=");
+					filter.append(vr.getMaximumVersion());
+					filter.append(")");
+				}
+				filter.append(")");
+
+			} else if (NESTED_FILTER_ATTRIBUTE.equals(attribName)) {
+				// Filters go in whole, no formatting needed
+				realAttrib = true;
+				filter.append(attrib.getValue());
+
+			} else if (Constants.OBJECTCLASS.equals(attribName)) {
+				realAttrib = true;
+				// objectClass has a "," separated list of interfaces
+				String[] values = attrib.getValue().split(",");
+				for (String s : values)
+					filter.append("(" + Constants.OBJECTCLASS + "=" + s + ")");
+
+			} else {
+				// attribName was not version..
+				realAttrib = true;
+
+				filter.append("(" + attribName + "=" + attrib.getValue() + ")");
+				// store all attributes in order to build up the mandatory
+				// filter and separate them with ", "
+				// skip bundle-symbolic-name in the mandatory directive query
+				if (!!!Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE
+						.equals(attribName)) {
+					realAttribs.append(attribName);
+					realAttribs.append(", ");
+				}
+			}
+		}
+		/*
+		 * The following is how OBR makes mandatory attributes work, we require
+		 * that the set of mandatory attributes on the export is a subset of (or
+		 * equal to) the set of the attributes we supply.
+		 */
+
+		if (realAttribs.length() > 0) {
+			String attribStr = (realAttribs.toString()).trim();
+			// remove the final ,
+			if ((attribStr.length() > 0) && (attribStr.endsWith(","))) {
+				attribStr = attribStr.substring(0, attribStr.length() - 1);
+			}
+			// build the mandatory filter, e.g.(mandatory:&lt;*company, local)
+			filter.append("(" + Constants.MANDATORY_DIRECTIVE + ":" + "<*"
+					+ attribStr + ")");
+		}
+
+		// Prune (& off the front and ) off end
+		String filterString = filter.toString();
+		int openBraces = 0;
+		for (int i = 0; openBraces < 3; i++) {
+			i = filterString.indexOf('(', i);
+			if (i == -1) {
+				break;
+			} else {
+				openBraces++;
+			}
+		}
+		if (openBraces < 3 && filterString.length() > 2) {
+			filter.delete(0, 2);
+		} else {
+			filter.append(")");
+		}
+
+		String result = "";
+		if (realAttrib != false) {
+			result = filter.toString();
+		}
+		return result;
+	}
+
+	/**
+   * Generate a filter from a set of attributes. This filter will be suitable
+   * for presentation to OBR. This means that, due to the way OBR works, it will
+   * 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
-   * @return
+   * @return filter string
    */
-  public static String generateFilter(String type, String name, Map<String, String>
attribs){
+  public static String generateFilter(String type, String name,
+      Map<String, String> attribs) {
     StringBuffer filter = new StringBuffer();
-    StringBuffer realAttribs = new StringBuffer();
     String result;
-    //shortcut for the simple case with no attribs.
-    boolean realAttrib = false;
-    if(attribs.isEmpty())
-      filter.append("("+type+"="+name+")");
-    else{    
-      //process all the attribs passed. 
-      //find out whether there are attributes on the filter
-      
-      filter.append("(&("+type+"="+name+")");      
-      for(Map.Entry<String,String> attrib : attribs.entrySet()){
-        String attribName = attrib.getKey();
-        
-        if(attribName.endsWith(":")){
-          //skip all directives. It is used to affect the attribs on the filter xml.
-        }else if((Constants.VERSION_ATTRIBUTE.equals(attribName)) || (Constants.BUNDLE_VERSION_ATTRIBUTE.equals(attribName))){
-          //version and bundle-version attrib requires special conversion.
-          realAttrib = true;
-          
-          VersionRange vr = ManifestHeaderProcessor.parseVersionRange(attrib.getValue());
+    // shortcut for the simple case with no attribs.
 
-          filter.append("(" + attribName + ">="+vr.getMinimumVersion());
-    
-          if(vr.getMaximumVersion()!=null) {
-            filter.append(")(" + attribName + "<=");
-            filter.append(vr.getMaximumVersion());
-          }
-    
-          if(vr.getMaximumVersion()!=null && vr.isMinimumExclusive()) {
-            filter.append(")(!(" + attribName + "=");
-            filter.append(vr.getMinimumVersion());
-            filter.append(")");
-          }
-    
-          if(vr.getMaximumVersion()!=null && vr.isMaximumExclusive()) {
-            filter.append(")(!(" + attribName + "=");
-            filter.append(vr.getMaximumVersion());
-            filter.append(")");
-          }
-          filter.append(")"); 
-          
-       } else if (NESTED_FILTER_ATTRIBUTE.equals(attribName)) {
-          // Filters go in whole, no formatting needed
-          realAttrib = true;
-          filter.append(attrib.getValue());
-
-       } else if (Constants.OBJECTCLASS.equals(attribName)) {
-          realAttrib = true;
-          // objectClass has a "," separated list of interfaces
-          String[] values = attrib.getValue().split(",");
-          for (String s : values)
-            filter.append("(" + Constants.OBJECTCLASS + "=" + s + ")");
-          
-      }else{
-          //attribName was not version.. 
-          realAttrib = true;
-          
-          filter.append("("+attribName+"="+attrib.getValue()+")");
-          // store all attributes in order to build up the mandatory filter and separate
them with ", "
-          // skip bundle-symbolic-name in the mandatory directive query
-          if (!!!Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE.equals(attribName)) {
-            realAttribs.append(attribName);
-            realAttribs.append(", ");
-          }
-        }     
-      }      
-      // tidy up realAttribs - remove the final ,
-      
-      if (realAttribs.length() > 0) {
-        String attribStr = (realAttribs.toString()).trim();
-        // remove the final ,
-        if ((attribStr.length() > 0) && (attribStr.endsWith(","))) {
-          attribStr = attribStr.substring(0, attribStr.length() - 1);
-        }
-        // build the mandatory filter, e.g.(mandatory:&lt;*company, local)
-        filter.append("(" + Constants.MANDATORY_DIRECTIVE + ":" + "<*"+attribStr + ")");
+    if (attribs == null || attribs.isEmpty())
+      filter.append("(" + type + "=" + name + ")");
+    else {
+      // process all the attribs passed.
+      // find out whether there are attributes on the filter
+
+      filter.append("(&(" + type + "=" + name + ")");
+
+      String filterString = generateFilter(attribs);
+
+      int start = 0;
+      int end = filterString.length();
+      if (filterString.startsWith("(&")) {
+        start = 2;
+        end--;
       }
-      filter.append(")"); 
-    }
 
-    
-    if (!!!(realAttrib)) {
-      result = "("+type+"="+name+")";
-    } else {
-      result = filter.toString();
+      if ("".equals(filterString)) {
+        filter.delete(0, 2);
+      } else {
+        filter.append(filterString, start, end);
+        filter.append(")");
+      }
     }
-    
+
+    result = filter.toString();
+
     return result;
   }
 
-  private static final Pattern FILTER_ATTR = Pattern.compile("(\\(!)?\\((.*?)([<>]?=)(.*?)\\)\\)?");
-  private static final String LESS_EQ_OP = "<=";
-  private static final String GREATER_EQ_OP = ">=";
-  
-  private static Map<String,String> parseFilterList(String filter)
-  {
+  private static Map<String, String> parseFilterList(String filter) {
+
     Map<String, String> result = new HashMap<String, String>();
     Set<String> negatedVersions = new HashSet<String>();
-    
+    Set<String> negatedBundleVersions = new HashSet<String>();
+
     String lowerVersion = null;
     String upperVersion = null;
-    
+    String lowerBundleVersion = null;
+    String upperBundleVersion = null;
+
     Matcher m = FILTER_ATTR.matcher(filter);
     while (m.find()) {
       boolean negation = m.group(1) != null;
       String attr = m.group(2);
       String op = m.group(3);
       String value = m.group(4);
-      
+
       if (Constants.VERSION_ATTRIBUTE.equals(attr)) {
         if (negation) {
           negatedVersions.add(value);
@@ -560,6 +635,20 @@ public class ManifestHeaderProcessor
           else
             throw new IllegalArgumentException();
         }
+      } else if (Constants.BUNDLE_VERSION_ATTRIBUTE.equals(attr)) {
+        // bundle-version is like version, but may be specified at the
+        // same time
+        // therefore we have similar code with separate variables
+        if (negation) {
+          negatedBundleVersions.add(value);
+        } else {
+          if (GREATER_EQ_OP.equals(op))
+            lowerBundleVersion = value;
+          else if (LESS_EQ_OP.equals(op))
+            upperBundleVersion = value;
+          else
+            throw new IllegalArgumentException();
+        }
       } else {
         result.put(attr, value);
       }
@@ -568,17 +657,29 @@ public class ManifestHeaderProcessor
     if (lowerVersion != null) {
       StringBuilder versionAttr = new StringBuilder(lowerVersion);
       if (upperVersion != null) {
-        versionAttr.append(",")
-          .append(upperVersion)
-          .insert(0, negatedVersions.contains(lowerVersion) ? '(' : '[')
-          .append(negatedVersions.contains(upperVersion) ? ')' : ']');
+        versionAttr.append(",").append(upperVersion).insert(0,
+            negatedVersions.contains(lowerVersion) ? '(' : '[').append(
+            negatedVersions.contains(upperVersion) ? ')' : ']');
       }
-      
+
       result.put(Constants.VERSION_ATTRIBUTE, versionAttr.toString());
     }
+    // Do it again for bundle-version
+    if (lowerBundleVersion != null) {
+      StringBuilder versionAttr = new StringBuilder(lowerBundleVersion);
+      if (upperBundleVersion != null) {
+        versionAttr.append(",").append(upperBundleVersion).insert(0,
+            negatedBundleVersions.contains(lowerBundleVersion) ? '(' : '[')
+            .append(
+                negatedBundleVersions.contains(upperBundleVersion) ? ')' : ']');
+      }
+
+      result.put(Constants.BUNDLE_VERSION_ATTRIBUTE, versionAttr.toString());
+    }
+
     return result;
   }
-  
+	  
   public static Map<String,String> parseFilter(String filter) 
   {
     Map<String,String> result;



Mime
View raw message