You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by ma...@apache.org on 2010/02/19 16:51:59 UTC

svn commit: r911851 - in /incubator/aries/trunk/application: application-api/src/main/java/org/apache/aries/application/ application-utils/src/main/java/org/apache/aries/application/impl/ application-utils/src/main/java/org/apache/aries/application/uti...

Author: mahrwald
Date: Fri Feb 19 15:51:58 2010
New Revision: 911851

URL: http://svn.apache.org/viewvc?rev=911851&view=rev
Log:
ARIES-191 Commit supplied patch

Modified:
    incubator/aries/trunk/application/application-api/src/main/java/org/apache/aries/application/VersionRange.java
    incubator/aries/trunk/application/application-utils/src/main/java/org/apache/aries/application/impl/VersionRangeImpl.java
    incubator/aries/trunk/application/application-utils/src/main/java/org/apache/aries/application/utils/manifest/ManifestHeaderProcessor.java
    incubator/aries/trunk/application/application-utils/src/test/java/org/apache/aries/application/impl/VersionRangeTest.java

Modified: incubator/aries/trunk/application/application-api/src/main/java/org/apache/aries/application/VersionRange.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/application/application-api/src/main/java/org/apache/aries/application/VersionRange.java?rev=911851&r1=911850&r2=911851&view=diff
==============================================================================
--- incubator/aries/trunk/application/application-api/src/main/java/org/apache/aries/application/VersionRange.java (original)
+++ incubator/aries/trunk/application/application-api/src/main/java/org/apache/aries/application/VersionRange.java Fri Feb 19 15:51:58 2010
@@ -76,4 +76,13 @@
    * @return        true if the version matches, false otherwise.
    */
   public boolean matches(Version version);
+  
+  /**
+   * Create a new version range that is the intersection of {@code this} and the argument.
+   * In other words, the largest version range that lies within both {@code this} and
+   * the parameter.
+   * @param range a version range to be intersected with {@code this}.
+   * @return a new version range, or {@code null} if no intersection is possible.
+   */
+  public VersionRange intersect(VersionRange range);
 }
\ No newline at end of file

Modified: incubator/aries/trunk/application/application-utils/src/main/java/org/apache/aries/application/impl/VersionRangeImpl.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/application/application-utils/src/main/java/org/apache/aries/application/impl/VersionRangeImpl.java?rev=911851&r1=911850&r2=911851&view=diff
==============================================================================
--- incubator/aries/trunk/application/application-utils/src/main/java/org/apache/aries/application/impl/VersionRangeImpl.java (original)
+++ incubator/aries/trunk/application/application-utils/src/main/java/org/apache/aries/application/impl/VersionRangeImpl.java Fri Feb 19 15:51:58 2010
@@ -21,13 +21,13 @@
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import org.osgi.framework.Version;
-
 import org.apache.aries.application.VersionRange;
 import org.apache.aries.application.utils.internal.MessageUtil;
+import org.osgi.framework.Version;
 
 public final class VersionRangeImpl implements VersionRange
 {
+  /** A string representation of the version. */
   private String version;
   /** The minimum desired version for the bundle */
   private Version minimumVersion;
@@ -39,7 +39,7 @@
   private boolean maximumExclusive;
   /** A regexp to select the version */
   private static final Pattern versionCapture = Pattern.compile("\"?(.*?)\"?$");
-  
+
   /**
    * 
    * @param version   version for the verioninfo
@@ -48,84 +48,135 @@
     this.version = version;
     processVersionAttribute(this.version);
   }
-  
+
   /**
    * 
-   * @param version             version for the verioninfo
+   * @param version             version for the versioninfo
    * @param exactVersion        whether this is an exact version
    */
-  public VersionRangeImpl(String version, boolean exactVersion) {;
+  public VersionRangeImpl(String version, boolean exactVersion) {
     this.version = version;
     if (exactVersion) {
       processExactVersionAttribute(this.version);
     } else {
       processVersionAttribute(this.version);
     }
+    
+    assertInvariants();
   }
-  
-  /* (non-Javadoc)
+
+  /**
+   * Constructor designed for internal use only.
+   * 
+   * @param maximumVersion
+   * @param maximumExclusive
+   * @param minimumVersion
+   * @param minimumExclusive
+   * @throws IllegalArgumentException
+   *           if parameters are not valid.
+   */
+  private VersionRangeImpl(Version maximumVersion, boolean maximumExclusive,
+      Version minimumVersion, boolean minimumExclusive) {
+    this.maximumVersion = maximumVersion;
+    this.maximumExclusive = maximumExclusive;
+    this.minimumVersion = minimumVersion;
+    this.minimumExclusive = minimumExclusive;
+
+    assertInvariants();
+
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
    * @see org.apache.aries.application.impl.VersionRange#toString()
    */
   @Override
   public String toString() {
+    // Some constructors don't take in a string, so construct one if needed
+    if (version == null) {
+      if (maximumVersion == null) {
+        version = minimumVersion.toString();
+      } else {
+        version = (minimumExclusive ? "(" : "[") + minimumVersion + ","
+            + maximumVersion + (maximumExclusive ? ")" : "]");
+      }
+    }
     return this.version;
   }
-  
-  public int hashCode()
-  {
-    return version.hashCode();
+
+  @Override
+  public int hashCode() {
+    int result = 17;
+    result = 31 * result + minimumVersion.hashCode();
+    result = 31 * result + (minimumExclusive ? 1 : 0);
+    result = 31 * result
+        + (maximumVersion != null ? maximumVersion.hashCode() : 0);
+    result = 31 * result + (maximumExclusive ? 1 : 0);
+    return result;
   }
   
-  public boolean equals(Object other)
+  @Override
+  public boolean equals(Object other) 
   {
-    if (other == this) return true;
-    if (other == null) return false;
-    
-    if (other instanceof VersionRangeImpl) {
-      return version.equals(((VersionRangeImpl)other).version);
+    boolean result = false;
+
+    if (this == other) {
+      result = true;
+    } else if (other instanceof VersionRangeImpl) {
+      VersionRangeImpl vr = (VersionRangeImpl) other;
+      result = minimumVersion.equals(vr.minimumVersion)
+          && minimumExclusive == vr.minimumExclusive
+          && (maximumVersion == null ? vr.maximumVersion == null
+              : maximumVersion.equals(vr.maximumVersion))
+          && maximumExclusive == vr.maximumExclusive;
     }
-    
-    return false;
+
+    return result;
   }
-  
-  /* (non-Javadoc)
- * @see org.apache.aries.application.impl.VersionRange#getExactVersion()
- */
+
+
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.aries.application.impl.VersionRange#getExactVersion()
+   */
   public Version getExactVersion() {
     Version v = null;
     if (isExactVersion()) {
       v = getMinimumVersion();
-    } 
+    }
     return v;
   }
-  
+
   /* (non-Javadoc)
- * @see org.apache.aries.application.impl.VersionRange#getMaximumVersion()
- */
+   * @see org.apache.aries.application.impl.VersionRange#getMaximumVersion()
+   */
   public Version getMaximumVersion()
   {
     return maximumVersion;
   }
 
   /* (non-Javadoc)
- * @see org.apache.aries.application.impl.VersionRange#getMinimumVersion()
- */
+   * @see org.apache.aries.application.impl.VersionRange#getMinimumVersion()
+   */
   public Version getMinimumVersion()
   {
     return minimumVersion;
   }
 
   /* (non-Javadoc)
- * @see org.apache.aries.application.impl.VersionRange#isMaximumExclusive()
- */
+   * @see org.apache.aries.application.impl.VersionRange#isMaximumExclusive()
+   */
   public boolean isMaximumExclusive()
   {
     return maximumExclusive;
   }
 
   /* (non-Javadoc)
- * @see org.apache.aries.application.impl.VersionRange#isMaximumUnbounded()
- */
+   * @see org.apache.aries.application.impl.VersionRange#isMaximumUnbounded()
+   */
   public boolean isMaximumUnbounded()
   {
     boolean unbounded = maximumVersion == null;
@@ -133,13 +184,13 @@
   }
 
   /* (non-Javadoc)
- * @see org.apache.aries.application.impl.VersionRange#isMinimumExclusive()
- */
+   * @see org.apache.aries.application.impl.VersionRange#isMinimumExclusive()
+   */
   public boolean isMinimumExclusive()
   {
     return minimumExclusive;
   }
-  
+
   /**
    * this is designed for deployed-version as that is the exact version.
    * @param version
@@ -148,7 +199,7 @@
    */
   private boolean processExactVersionAttribute(String version) throws IllegalArgumentException{
     boolean success = processVersionAttribute(version);
-    
+
     if (maximumVersion == null) {
       maximumVersion = minimumVersion;
     }
@@ -163,32 +214,38 @@
 
     return success;
   }
+
   /**
-   * process the version attribute, 
+   * process the version attribute,
    * @param version  the value to be processed
    * @return
    * @throws IllegalArgumentException
    */
   private boolean processVersionAttribute(String version) throws IllegalArgumentException{
     boolean success = false;
-   
+
+    if (version == null) {
+      throw new IllegalArgumentException(MessageUtil
+          .getMessage("APPUTILS0010E"));
+    }
+
     Matcher matches = versionCapture.matcher(version);
-    
+
     if (matches.matches()) {
       String versions = matches.group(1);
-      
+
       if ((versions.startsWith("[") || versions.startsWith("(")) &&
           (versions.endsWith("]") || versions.endsWith(")"))) {
         if (versions.startsWith("[")) minimumExclusive = false;
         else if (versions.startsWith("(")) minimumExclusive = true;
-        
+
         if (versions.endsWith("]")) maximumExclusive = false;
         else if (versions.endsWith(")")) maximumExclusive = true;
-        
+
         int index = versions.indexOf(',');
         String minVersion = versions.substring(1, index);
         String maxVersion = versions.substring(index + 1, versions.length() - 1);
-        
+
         try {
           minimumVersion = new Version(minVersion.trim());
           maximumVersion = new Version(maxVersion.trim());
@@ -204,15 +261,72 @@
         } catch (NumberFormatException nfe) {
           throw new IllegalArgumentException(MessageUtil.getMessage("APPUTILS0009E", version), nfe);
         }
-      }      
+      }
     } else {
       throw new IllegalArgumentException(MessageUtil.getMessage("APPUTILS0009E", version));
     }
-    
+
     return success;
   }
 
-  public boolean matches(Version version)
+  /**
+   * Assert object invariants. Called by constructors to verify that arguments
+   * were valid.
+   * 
+   * @throws IllegalArgumentException
+   *           if invariants are violated.
+   */
+  private void assertInvariants() {
+    if (minimumVersion == null
+        || !isRangeValid(minimumVersion, minimumExclusive, maximumVersion, maximumExclusive)) {
+      IllegalArgumentException e = new IllegalArgumentException();
+      throw e;
+    }
+  }
+
+  /**
+   * Check if the supplied parameters describe a valid version range.
+   * 
+   * @param min
+   *          the minimum version.
+   * @param minExclusive
+   *          whether the minimum version is exclusive.
+   * @param max
+   *          the maximum version.
+   * @param maxExclusive
+   *          whether the maximum version is exclusive.
+   * @return true is the range is valid; otherwise false.
+   */
+  private boolean isRangeValid(Version min, boolean minExclusive, Version max,
+      boolean maxExclusive) {
+    boolean result;
+
+    // A null maximum version is unbounded so means that minimum is smaller than
+    // maximum.
+    int minMaxCompare = (max == null ? -1 : min.compareTo(max));
+    if (minMaxCompare > 0) {
+      // Minimum larger than maximum is invalid.
+      result = false;
+    } else if (minMaxCompare == 0 && (minExclusive || maxExclusive)) {
+      // If min and max are the same, and either are exclusive, no valid range
+      // exists.
+      result = false;
+    } else {
+      // Range is valid.
+      result = true;
+    }
+
+    return result;
+  }
+
+  /**
+   * This method checks that the provided version matches the desired version.
+   * 
+   * @param version
+   *          the version.
+   * @return true if the version matches, false otherwise.
+   */
+  public boolean matches(Version version) 
   {
     boolean result;
     if (this.getMaximumVersion() == null) {
@@ -220,7 +334,7 @@
     } else {
       int minN = this.isMinimumExclusive() ? 0 : 1;
       int maxN = this.isMaximumExclusive() ? 0 : 1;
-      
+
       result = (this.getMinimumVersion().compareTo(version) < minN) &&
                (version.compareTo(this.getMaximumVersion()) < maxN);
     }
@@ -228,9 +342,68 @@
   }
 
   /* (non-Javadoc)
- * @see org.apache.aries.application.impl.VersionRange#isExactVersion()
- */
+   * @see org.apache.aries.application.impl.VersionRange#isExactVersion()
+   */
   public boolean isExactVersion() {
     return minimumVersion.equals(maximumVersion) && minimumExclusive == maximumExclusive && !!!minimumExclusive;
   }
+
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.aries.application.impl.VersionRange#intersect(VersionRange
+   * range)
+   */
+  public VersionRange intersect(VersionRange r) {
+    // Use the highest minimum version.
+    final Version newMinimumVersion;
+    final boolean newMinimumExclusive;
+    int minCompare = minimumVersion.compareTo(r.getMinimumVersion());
+    if (minCompare > 0) {
+      newMinimumVersion = minimumVersion;
+      newMinimumExclusive = minimumExclusive;
+    } else if (minCompare < 0) {
+      newMinimumVersion = r.getMinimumVersion();
+      newMinimumExclusive = r.isMinimumExclusive();
+    } else {
+      newMinimumVersion = minimumVersion;
+      newMinimumExclusive = (minimumExclusive || r.isMinimumExclusive());
+    }
+
+    // Use the lowest maximum version.
+    final Version newMaximumVersion;
+    final boolean newMaximumExclusive;
+    // null maximum version means unbounded, so the highest possible value.
+    if (maximumVersion == null) {
+      newMaximumVersion = r.getMaximumVersion();
+      newMaximumExclusive = r.isMaximumExclusive();
+    } else if (r.getMaximumVersion() == null) {
+      newMaximumVersion = maximumVersion;
+      newMaximumExclusive = maximumExclusive;
+    } else {
+      int maxCompare = maximumVersion.compareTo(r.getMaximumVersion());
+      if (maxCompare < 0) {
+        newMaximumVersion = maximumVersion;
+        newMaximumExclusive = maximumExclusive;
+      } else if (maxCompare > 0) {
+        newMaximumVersion = r.getMaximumVersion();
+        newMaximumExclusive = r.isMaximumExclusive();
+      } else {
+        newMaximumVersion = maximumVersion;
+        newMaximumExclusive = (maximumExclusive || r.isMaximumExclusive());
+      }
+    }
+
+    VersionRange result;
+    if (isRangeValid(newMinimumVersion, newMinimumExclusive, newMaximumVersion,
+        newMaximumExclusive)) {
+      result = new VersionRangeImpl(newMaximumVersion, newMaximumExclusive,
+          newMinimumVersion, newMinimumExclusive);
+    } else {
+      result = null;
+    }
+    return result;
+  }
+
 }

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=911851&r1=911850&r2=911851&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 Fri Feb 19 15:51:58 2010
@@ -36,6 +36,8 @@
 
 public class ManifestHeaderProcessor
 {
+  public static final String NESTED_FILTER_ATTRIBUTE = "org.apache.aries.application.filter.attribute";
+
   /**
    * A simple class to associate two types.
    *
@@ -66,6 +68,7 @@
     {
       this.value = value;
     }
+    @Override
     public String toString(){
       return "{"+name.toString()+"::"+value.toString()+"}";
     }
@@ -84,7 +87,7 @@
       if (this == obj) return true;
       if (obj == null) return false;
       if (getClass() != obj.getClass()) return false;
-      final NameValuePair other = (NameValuePair) obj;
+      final NameValuePair<?, ?> other = (NameValuePair<?, ?>) obj;
       if (name == null) {
         if (other.name != null) return false;
       } else if (!name.equals(other.name)) return false;
@@ -118,10 +121,12 @@
    * @param <V> Type of 'Value'
    */
   public static class NameValueMap<N,V> extends HashMap<N,V> implements NameValueCollection<N,V>, Map<N,V>{
-    public void addToCollection(N n,V v){
+	    
+   public void addToCollection(N n,V v){
       this.put(n,v);
     }
-    public String toString(){
+   @Override
+   public String toString(){
       StringBuffer sb = new StringBuffer();
       sb.append("{");
       boolean first=true;
@@ -142,9 +147,11 @@
    * @param <V> Type of 'Value'
    */
   public static class NameValueList<N,V> extends ArrayList<NameValuePair<N,V>> implements NameValueCollection<N,V>, List<NameValuePair<N,V>>{    
-    public void addToCollection(N n,V v){
+
+	public void addToCollection(N n,V v){
       this.add(new NameValuePair<N,V>(n,v));
     } 
+	@Override
     public String toString(){
       StringBuffer sb = new StringBuffer();
       sb.append("{");
@@ -337,7 +344,7 @@
    * <p>
    * Result is returned as a list, as export does allow duplicate package exports.
    * 
-   * @param s The data to parse.
+   * @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. 
    */
@@ -423,7 +430,7 @@
   }
 
   /**
-   * This method is temporary here, until VersionRange becomes it's own top level class.
+   * We may wish to consider moving this method to VersionRange.
    * 
    * @param type
    * @param name
@@ -474,7 +481,19 @@
           }
           filter.append(")"); 
           
-        }else{
+       } 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;
           
@@ -486,7 +505,7 @@
             realAttribs.append(", ");
           }
         }     
-      }
+      }      
       // tidy up realAttribs - remove the final ,
       
       if (realAttribs.length() > 0) {

Modified: incubator/aries/trunk/application/application-utils/src/test/java/org/apache/aries/application/impl/VersionRangeTest.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/application/application-utils/src/test/java/org/apache/aries/application/impl/VersionRangeTest.java?rev=911851&r1=911850&r2=911851&view=diff
==============================================================================
--- incubator/aries/trunk/application/application-utils/src/test/java/org/apache/aries/application/impl/VersionRangeTest.java (original)
+++ incubator/aries/trunk/application/application-utils/src/test/java/org/apache/aries/application/impl/VersionRangeTest.java Fri Feb 19 15:51:58 2010
@@ -18,14 +18,9 @@
  */
 package org.apache.aries.application.impl;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.Assert.*;
 
 import org.apache.aries.application.VersionRange;
-import org.apache.aries.application.impl.VersionRangeImpl;
 import org.junit.Test;
 import org.osgi.framework.Version;
 
@@ -184,6 +179,26 @@
     
     vr = new VersionRangeImpl("[1.0.0, 1.0.0]");
     assertTrue(vr.isExactVersion());
+
+    vr = new VersionRangeImpl("1.0.0", true);
+    assertEquals(new Version("1.0.0"), vr.getMinimumVersion());
+    assertTrue(vr.isExactVersion());
+    
+    vr = new VersionRangeImpl("1.0.0", false);
+    assertEquals(new Version("1.0.0"), vr.getMinimumVersion());
+    assertNull(vr.getMaximumVersion());
+    assertFalse(vr.isExactVersion());
+    
+    // don't throw any silly exceptions
+    vr = new VersionRangeImpl("[1.0.0,2.0.0)", false);
+    assertFalse(vr.isExactVersion());
+    
+    vr = new VersionRangeImpl("[1.0.0, 2.0.0]");
+    assertFalse(vr.isExactVersion());
+
+    vr = new VersionRangeImpl("[1.0.0, 1.0.0]");
+    assertTrue(vr.isExactVersion());
+
   }
   
   @Test
@@ -220,4 +235,62 @@
     assertFalse(vr.matches(new Version(1,5,0)));
     assertFalse(vr.matches(new Version(1,9,9)));
   }
+  
+  @Test
+  public void testIntersectVersionRange_Valid1()
+  {
+    VersionRange v1 = new VersionRangeImpl("[1.0.0,3.0.0]");
+    VersionRange v2 = new VersionRangeImpl("[2.0.0,3.0.0)");
+    VersionRange result = v1.intersect(v2);
+    assertNotNull(result);
+    assertEquals("[2.0.0,3.0.0)", result.toString());
+  }
+  
+  @Test
+  public void testIntersectVersionRange_Valid2()
+  {
+    VersionRange v1 = new VersionRangeImpl("[1.0.0,3.0.0)");
+    VersionRange v2 = new VersionRangeImpl("(2.0.0,3.0.0]");
+    VersionRange result = v1.intersect(v2);
+    assertNotNull(result);
+    assertEquals("(2.0.0,3.0.0)", result.toString());
+  }
+
+  @Test
+  public void testIntersectVersionRange_Valid3()
+  {
+    VersionRange v1 = new VersionRangeImpl("[2.0.0,2.0.0]");
+    VersionRange v2 = new VersionRangeImpl("[1.0.0,3.0.0]");
+    VersionRange result = v1.intersect(v2);
+    assertNotNull(result);
+    assertEquals("[2.0.0,2.0.0]", result.toString());
+  }
+  
+  @Test
+  public void testIntersectVersionRange_Invalid1()
+  {
+    VersionRange v1 = new VersionRangeImpl("[1.0.0,2.0.0]");
+    VersionRange v2 = new VersionRangeImpl("(2.0.0,3.0.0]");
+    VersionRange result = v1.intersect(v2);
+    assertNull(result);
+  }
+
+  @Test
+  public void testIntersectVersionRange_Invalid2()
+  {
+    VersionRange v1 = new VersionRangeImpl("[1.0.0,2.0.0)");
+    VersionRange v2 = new VersionRangeImpl("[2.0.0,3.0.0]");
+    VersionRange result = v1.intersect(v2);
+    assertNull(result);
+  }
+
+  @Test
+  public void testIntersectVersionRange_Invalid3()
+  {
+    VersionRange v1 = new VersionRangeImpl("[1.0.0,1.0.0]");
+    VersionRange v2 = new VersionRangeImpl("[2.0.0,2.0.0]");
+    VersionRange result = v1.intersect(v2);
+    assertNull(result);
+  }
+
 }
\ No newline at end of file