Modified manifest parsing and import/export matching to support bundle
versions as attributes.
git-svn-id: https://svn.apache.org/repos/asf/incubator/felix/trunk@425060 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/searchpolicy/R4Attribute.java b/org.apache.felix.framework/src/main/java/org/apache/felix/framework/searchpolicy/R4Attribute.java
index d2c0217..a8658c3 100644
--- a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/searchpolicy/R4Attribute.java
+++ b/org.apache.felix.framework/src/main/java/org/apache/felix/framework/searchpolicy/R4Attribute.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2005 The Apache Software Foundation
+ * Copyright 2006 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,10 +19,10 @@
public class R4Attribute
{
private String m_name = "";
- private String m_value = "";
+ private Object m_value = null;
private boolean m_isMandatory = false;
- public R4Attribute(String name, String value, boolean isMandatory)
+ public R4Attribute(String name, Object value, boolean isMandatory)
{
m_name = name;
m_value = value;
@@ -34,7 +34,7 @@
return m_name;
}
- public String getValue()
+ public Object getValue()
{
return m_value;
}
diff --git a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/searchpolicy/R4Export.java b/org.apache.felix.framework/src/main/java/org/apache/felix/framework/searchpolicy/R4Export.java
index c40a192..b0d8510 100644
--- a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/searchpolicy/R4Export.java
+++ b/org.apache.felix.framework/src/main/java/org/apache/felix/framework/searchpolicy/R4Export.java
@@ -20,6 +20,7 @@
import org.apache.felix.framework.util.Util;
import org.osgi.framework.Constants;
+import org.osgi.framework.Version;
public class R4Export extends R4Package
{
@@ -104,26 +105,26 @@
}
}
- // Convert version, if present.
- String rangeStr = "0.0.0";
+ // Find the version, if present, and convert to Version.
+ // The version attribute value may be a String or a Version,
+ // since the value may be coming from an R4Export that already
+ // converted it to Version.
+ m_version = Version.emptyVersion;
for (int i = 0; i < m_attrs.length; i++)
{
- // Find and parse version attribute, if present.
- if (m_attrs[i].getName().equals(Constants.VERSION_ATTRIBUTE) ||
- m_attrs[i].getName().equals(Constants.PACKAGE_SPECIFICATION_VERSION))
+ if (m_attrs[i].getName().equals(Constants.VERSION_ATTRIBUTE))
{
- // Normalize version attribute name.
+ String versionStr = (m_attrs[i].getValue() instanceof Version)
+ ? ((Version) m_attrs[i].getValue()).toString()
+ : (String) m_attrs[i].getValue();
+ m_version = Version.parseVersion(versionStr);
m_attrs[i] = new R4Attribute(
- Constants.VERSION_ATTRIBUTE, m_attrs[i].getValue(),
+ m_attrs[i].getName(),
+ m_version,
m_attrs[i].isMandatory());
- rangeStr = m_attrs[i].getValue();
break;
}
}
-
- VersionRange range = VersionRange.parse(rangeStr);
- // For now, ignore if we have a version range.
- m_version = range.getLow();
}
public String[] getUses()
diff --git a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/searchpolicy/R4Import.java b/org.apache.felix.framework/src/main/java/org/apache/felix/framework/searchpolicy/R4Import.java
index 6b56936..5293368 100644
--- a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/searchpolicy/R4Import.java
+++ b/org.apache.felix.framework/src/main/java/org/apache/felix/framework/searchpolicy/R4Import.java
@@ -16,7 +16,7 @@
*/
package org.apache.felix.framework.searchpolicy;
-import org.apache.felix.framework.util.FelixConstants;
+import org.osgi.framework.Constants;
import org.osgi.framework.Version;
public class R4Import extends R4Package
@@ -36,30 +36,43 @@
// Find all import directives: resolution.
for (int i = 0; i < m_directives.length; i++)
{
- if (m_directives[i].getName().equals(FelixConstants.RESOLUTION_DIRECTIVE))
+ if (m_directives[i].getName().equals(Constants.RESOLUTION_DIRECTIVE))
{
- m_isOptional = m_directives[i].getValue().equals(FelixConstants.RESOLUTION_OPTIONAL);
+ m_isOptional = m_directives[i].getValue().equals(Constants.RESOLUTION_OPTIONAL);
}
}
- // Find and parse version attribute, if present.
- String rangeStr = "0.0.0";
+ // Convert version and bundle version attributes to VersionRange.
+ // The attribute value may be a String or a Version, since the
+ // value may be coming from an R4Export that already converted
+ // it to Version.
+ m_versionRange = VersionRange.parse(Version.emptyVersion.toString());
+ m_version = m_versionRange.getLow();
for (int i = 0; i < m_attrs.length; i++)
{
- if (m_attrs[i].getName().equals(FelixConstants.VERSION_ATTRIBUTE) ||
- m_attrs[i].getName().equals(FelixConstants.PACKAGE_SPECIFICATION_VERSION))
+ if (m_attrs[i].getName().equals(Constants.VERSION_ATTRIBUTE))
{
- // Normalize version attribute name.
+ String versionStr = (m_attrs[i].getValue() instanceof Version)
+ ? ((Version) m_attrs[i].getValue()).toString()
+ : (String) m_attrs[i].getValue();
+ m_versionRange = VersionRange.parse(versionStr);
+ m_version = m_versionRange.getLow();
m_attrs[i] = new R4Attribute(
- FelixConstants.VERSION_ATTRIBUTE, m_attrs[i].getValue(),
+ m_attrs[i].getName(),
+ m_versionRange,
m_attrs[i].isMandatory());
- rangeStr = m_attrs[i].getValue();
- break;
+ }
+ else if (m_attrs[i].getName().equals(Constants.BUNDLE_VERSION_ATTRIBUTE))
+ {
+ String versionStr = (m_attrs[i].getValue() instanceof Version)
+ ? ((Version) m_attrs[i].getValue()).toString()
+ : (String) m_attrs[i].getValue();
+ m_attrs[i] = new R4Attribute(
+ m_attrs[i].getName(),
+ VersionRange.parse(versionStr),
+ m_attrs[i].isMandatory());
}
}
-
- m_versionRange = VersionRange.parse(rangeStr);
- m_version = m_versionRange.getLow();
}
public Version getVersionHigh()
@@ -108,7 +121,7 @@
// Ignore version attribute, since it is a special case that
// has already been compared using isVersionInRange() before
// the call to this method was made.
- if (impAttr.getName().equals(FelixConstants.VERSION_ATTRIBUTE))
+ if (impAttr.getName().equals(Constants.VERSION_ATTRIBUTE))
{
continue;
}
@@ -124,13 +137,17 @@
// Check if the attribute names are equal.
if (impAttr.getName().equals(expAttr.getName()))
{
- // If the values are not equal, then return false immediately.
- // We should not compare version values here, since they are
- // a special case and have already been compared by a call to
- // isVersionInRange() before getting here; however, it is
- // possible for version to be mandatory, so make sure it is
- // present below.
- if (!impAttr.getValue().equals(expAttr.getValue()))
+ // We only recognize version types. If the value of the
+ // attribute is a version/version range, then we use the
+ // "in range" comparison, otherwise we simply use equals().
+ if (expAttr.getValue() instanceof Version)
+ {
+ if (!((VersionRange) impAttr.getValue()).isInRange((Version) expAttr.getValue()))
+ {
+ return false;
+ }
+ }
+ else if (!impAttr.getValue().equals(expAttr.getValue()))
{
return false;
}
diff --git a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/searchpolicy/R4Package.java b/org.apache.felix.framework/src/main/java/org/apache/felix/framework/searchpolicy/R4Package.java
index 95e51b7..f0d5a8c 100755
--- a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/searchpolicy/R4Package.java
+++ b/org.apache.felix.framework/src/main/java/org/apache/felix/framework/searchpolicy/R4Package.java
@@ -33,8 +33,10 @@
public R4Package(String name, R4Directive[] directives, R4Attribute[] attrs)
{
m_name = name;
- m_directives = (directives == null) ? new R4Directive[0] : directives;
- m_attrs = (attrs == null) ? new R4Attribute[0] : attrs;
+ m_directives = (directives == null)
+ ? new R4Directive[0] : (R4Directive[]) directives.clone();
+ m_attrs = (attrs == null)
+ ? new R4Attribute[0] : (R4Attribute[]) attrs.clone();
}
public String getName()
@@ -191,13 +193,25 @@
if ((v != null) && (sv != null))
{
// Verify they are equal.
- if (!v.getValue().trim().equals(sv.getValue().trim()))
+ if (!((String) v.getValue()).trim().equals(((String) sv.getValue()).trim()))
{
throw new IllegalArgumentException(
"Both version and specificat-version are specified, but they are not equal.");
}
- // Remove spec-version since it isn't needed.
+ }
+
+ // Ensure that only the "version" attribute is used
+ if (sv != null)
+ {
attrsMap.remove(Constants.PACKAGE_SPECIFICATION_VERSION);
+ if (v == null)
+ {
+ attrsMap.put(Constants.VERSION_ATTRIBUTE,
+ new R4Attribute(
+ Constants.VERSION_ATTRIBUTE,
+ sv.getValue(),
+ sv.isMandatory()));
+ }
}
// Create directive array.
diff --git a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/util/ManifestParser.java b/org.apache.felix.framework/src/main/java/org/apache/felix/framework/util/ManifestParser.java
index fe6c56b..39fc343 100644
--- a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/util/ManifestParser.java
+++ b/org.apache.felix.framework/src/main/java/org/apache/felix/framework/util/ManifestParser.java
@@ -47,7 +47,10 @@
}
// Verify bundle version syntax.
- Version.parseVersion(get(Constants.BUNDLE_VERSION));
+ if (get(Constants.BUNDLE_VERSION) != null)
+ {
+ Version.parseVersion(get(Constants.BUNDLE_VERSION));
+ }
// Create map to check for duplicate imports/exports.
Map dupeMap = new HashMap();
@@ -212,7 +215,7 @@
(!m_exports[i].getAttributes()[0].getName().equals(Constants.VERSION_ATTRIBUTE))))
{
throw new BundleException(
- "Export does not conform to R3 syntax: " + m_exports[i]);
+ "R3 export syntax does not support attributes: " + m_exports[i]);
}
}
@@ -235,7 +238,7 @@
(!m_imports[i].getAttributes()[0].getName().equals(Constants.VERSION_ATTRIBUTE))))
{
throw new BundleException(
- "Import does not conform to R3 syntax: " + m_imports[i]);
+ "R3 import syntax does not support attributes: " + m_imports[i]);
}
}
@@ -304,18 +307,17 @@
throw new BundleException("R4 bundle manifests must include bundle symbolic name.");
}
- // Verify that there are no duplicate directives.
+ // Verify that the exports do not specify bundle symbolic name
+ // or bundle version.
for (int i = 0; (m_exports != null) && (i < m_exports.length); i++)
{
String targetVer = get(Constants.BUNDLE_VERSION);
targetVer = (targetVer == null) ? "0.0.0" : targetVer;
- // First verify that the exports do not specify
- // bundle symbolic name or bundle version.
R4Attribute[] attrs = m_exports[i].getAttributes();
for (int attrIdx = 0; attrIdx < attrs.length; attrIdx++)
{
- // Find and parse version attribute, if present.
+ // Find symbolic name and version attribute, if present.
if (attrs[attrIdx].getName().equals(Constants.BUNDLE_VERSION_ATTRIBUTE) ||
attrs[attrIdx].getName().equals(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE))
{
@@ -331,24 +333,7 @@
newAttrs[attrs.length] = new R4Attribute(
Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, symName, false);
newAttrs[attrs.length + 1] = new R4Attribute(
- Constants.BUNDLE_VERSION_ATTRIBUTE, targetVer, false);
- m_exports[i] = new R4Export(
- m_exports[i].getName(), m_exports[i].getDirectives(), newAttrs);
- }
-
- // Need to add symbolic name and bundle version to all R4 exports.
- for (int i = 0; (m_exports != null) && (i < m_exports.length); i++)
- {
- String targetVer = get(Constants.BUNDLE_VERSION);
- targetVer = (targetVer == null) ? "0.0.0" : targetVer;
-
- R4Attribute[] attrs = m_exports[i].getAttributes();
- R4Attribute[] newAttrs = new R4Attribute[attrs.length + 2];
- System.arraycopy(attrs, 0, newAttrs, 0, attrs.length);
- newAttrs[attrs.length] = new R4Attribute(
- Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, symName, false);
- newAttrs[attrs.length + 1] = new R4Attribute(
- Constants.BUNDLE_VERSION_ATTRIBUTE, targetVer, false);
+ Constants.BUNDLE_VERSION_ATTRIBUTE, Version.parseVersion(targetVer), false);
m_exports[i] = new R4Export(
m_exports[i].getName(), m_exports[i].getDirectives(), newAttrs);
}