You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by ri...@apache.org on 2010/03/03 15:58:22 UTC
svn commit: r918498 [2/3] - in
/felix/trunk/framework/src/main/java/org/apache/felix:
framework/capabilityset/ framework/util/manifestparser/ moduleloader/
Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java?rev=918498&r1=918497&r2=918498&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java Wed Mar 3 14:58:21 2010
@@ -19,13 +19,17 @@
package org.apache.felix.framework.util.manifestparser;
import java.util.*;
+import java.util.ArrayList;
+import java.util.Map.Entry;
import org.apache.felix.framework.Logger;
+import org.apache.felix.framework.capabilityset.Capability;
+import org.apache.felix.framework.capabilityset.Attribute;
+import org.apache.felix.framework.capabilityset.Directive;
+import org.apache.felix.framework.resolver.Module;
+import org.apache.felix.framework.capabilityset.Requirement;
import org.apache.felix.framework.util.FelixConstants;
import org.apache.felix.framework.util.VersionRange;
-import org.apache.felix.moduleloader.ICapability;
-import org.apache.felix.moduleloader.IModule;
-import org.apache.felix.moduleloader.IRequirement;
import org.osgi.framework.*;
public class ManifestParser
@@ -33,19 +37,19 @@
private final Logger m_logger;
private final Map m_configMap;
private final Map m_headerMap;
- private volatile int m_activationPolicy = IModule.EAGER_ACTIVATION;
+ private volatile int m_activationPolicy = Module.EAGER_ACTIVATION;
private volatile String m_activationIncludeDir;
private volatile String m_activationExcludeDir;
private volatile boolean m_isExtension = false;
private volatile String m_bundleSymbolicName;
private volatile Version m_bundleVersion;
- private volatile ICapability[] m_capabilities;
- private volatile IRequirement[] m_requirements;
- private volatile IRequirement[] m_dynamicRequirements;
- private volatile R4LibraryClause[] m_libraryHeaders;
+ private volatile List<Capability> m_capabilities;
+ private volatile List<Requirement> m_requirements;
+ private volatile List<Requirement> m_dynamicRequirements;
+ private volatile List<R4LibraryClause> m_libraryClauses;
private volatile boolean m_libraryHeadersOptional = false;
- public ManifestParser(Logger logger, Map configMap, IModule owner, Map headerMap)
+ public ManifestParser(Logger logger, Map configMap, Module owner, Map headerMap)
throws BundleException
{
m_logger = logger;
@@ -61,8 +65,7 @@
}
// Create lists to hold capabilities and requirements.
- List capList = new ArrayList();
- List reqList = new ArrayList();
+ List<Capability> capList = new ArrayList();
//
// Parse bundle version.
@@ -90,11 +93,11 @@
// Parse bundle symbolic name.
//
- ICapability moduleCap = parseBundleSymbolicName(owner, m_headerMap);
+ Capability moduleCap = parseBundleSymbolicName(owner, m_headerMap);
if (moduleCap != null)
{
m_bundleSymbolicName = (String)
- moduleCap.getProperties().get(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE);
+ moduleCap.getAttribute(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE).getValue();
// Add a module capability and a host capability to all
// non-fragment bundles. A host capability is the same
@@ -105,159 +108,565 @@
if (headerMap.get(Constants.FRAGMENT_HOST) == null)
{
capList.add(moduleCap);
- capList.add(new Capability(
- owner, ICapability.HOST_NAMESPACE, null,
- ((Capability) moduleCap).getAttributes()));
+ capList.add(new CapabilityImpl(
+ owner, Capability.HOST_NAMESPACE, new ArrayList<Directive>(0),
+ ((CapabilityImpl) moduleCap).getAttributes()));
}
}
+ // Verify that bundle symbolic name is specified.
+ if (getManifestVersion().equals("2") && (m_bundleSymbolicName == null))
+ {
+ throw new BundleException(
+ "R4 bundle manifests must include bundle symbolic name.");
+ }
+
//
- // Parse Export-Package.
+ // Parse Fragment-Host.
//
- // Get exported packages from bundle manifest.
- ICapability[] exportCaps = parseExportHeader(
- owner, (String) headerMap.get(Constants.EXPORT_PACKAGE));
+ List<Requirement> hostReqs = parseFragmentHost(m_logger, m_headerMap);
- // Verify that "java.*" packages are not exported.
- for (int capIdx = 0; capIdx < exportCaps.length; capIdx++)
- {
- // Verify that the named package has not already been declared.
- String pkgName = (String)
- exportCaps[capIdx].getProperties().get(ICapability.PACKAGE_PROPERTY);
- // Verify that java.* packages are not exported.
- if (pkgName.startsWith("java."))
- {
- throw new BundleException(
- "Exporting java.* packages not allowed: " + pkgName);
- }
- capList.add(exportCaps[capIdx]);
- }
+ //
+ // Parse Require-Bundle
+ //
- // Create an array of all capabilities.
- m_capabilities = (ICapability[]) capList.toArray(new ICapability[capList.size()]);
+ List<ParsedHeaderClause> requireClauses =
+ parseStandardHeader((String) headerMap.get(Constants.REQUIRE_BUNDLE));
+ requireClauses = normalizeRequireClauses(m_logger, requireClauses, getManifestVersion());
+ List<Requirement> requireReqs = convertRequires(requireClauses);
//
- // Parse Fragment-Host.
+ // Parse Import-Package.
//
- IRequirement req = parseFragmentHost(m_logger, m_headerMap);
- if (req != null)
+ List<ParsedHeaderClause> importClauses =
+ parseStandardHeader((String) headerMap.get(Constants.IMPORT_PACKAGE));
+ importClauses = normalizeImportClauses(m_logger, importClauses, getManifestVersion());
+ List<Requirement> importReqs = convertImports(importClauses);
+
+ //
+ // Parse DynamicImport-Package.
+ //
+
+ List<ParsedHeaderClause> dynamicClauses =
+ parseStandardHeader((String) headerMap.get(Constants.DYNAMICIMPORT_PACKAGE));
+ dynamicClauses = normalizeDynamicImportClauses(m_logger, dynamicClauses, getManifestVersion());
+ m_dynamicRequirements = convertImports(dynamicClauses);
+
+ //
+ // Parse Export-Package.
+ //
+
+ // Get exported packages from bundle manifest.
+ List<ParsedHeaderClause> exportClauses =
+ parseStandardHeader((String) headerMap.get(Constants.EXPORT_PACKAGE));
+ exportClauses = normalizeExportClauses(logger, exportClauses,
+ getManifestVersion(), m_bundleSymbolicName, m_bundleVersion);
+ List<Capability> exportCaps = convertExports(exportClauses, owner);
+
+ //
+ // Calculate implicit imports.
+ //
+
+ if (!getManifestVersion().equals("2"))
{
- reqList.add(req);
- }
+ List<ParsedHeaderClause> implicitClauses =
+ calculateImplicitImports(exportCaps, importClauses);
+ importReqs.addAll(convertImports(implicitClauses));
+
+ List<ParsedHeaderClause> allImportClauses =
+ new ArrayList<ParsedHeaderClause>(implicitClauses.size() + importClauses.size());
+ allImportClauses.addAll(importClauses);
+ allImportClauses.addAll(implicitClauses);
+
+ exportCaps = calculateImplicitUses(exportCaps, allImportClauses);
+ }
+
+ // Combine all capabilities.
+ m_capabilities = new ArrayList(
+ capList.size() + exportCaps.size());
+ m_capabilities.addAll(capList);
+ m_capabilities.addAll(exportCaps);
+
+ // Combine all requirements.
+ m_requirements = new ArrayList(
+ importReqs.size() + requireReqs.size() + hostReqs.size());
+ m_requirements.addAll(importReqs);
+ m_requirements.addAll(requireReqs);
+ m_requirements.addAll(hostReqs);
//
- // Parse Require-Bundle
+ // Parse Bundle-NativeCode.
//
- IRequirement[] bundleReq = parseRequireBundleHeader(
- (String) headerMap.get(Constants.REQUIRE_BUNDLE));
- for (int reqIdx = 0; reqIdx < bundleReq.length; reqIdx++)
+ // Get native library entry names for module library sources.
+ m_libraryClauses =
+ parseLibraryStrings(
+ m_logger,
+ parseDelimitedString((String) m_headerMap.get(Constants.BUNDLE_NATIVECODE), ","));
+
+ // Check to see if there was an optional native library clause, which is
+ // represented by a null library header; if so, record it and remove it.
+ if ((m_libraryClauses.size() > 0) &&
+ (m_libraryClauses.get(m_libraryClauses.size() - 1).getLibraryEntries() == null))
{
- reqList.add(bundleReq[reqIdx]);
+ m_libraryHeadersOptional = true;
+ m_libraryClauses.remove(m_libraryClauses.size() - 1);
}
//
- // Parse Import-Package.
+ // Parse activation policy.
//
- // Get import packages from bundle manifest.
- IRequirement[] importReqs = parseImportHeader(
- (String) headerMap.get(Constants.IMPORT_PACKAGE));
+ // This sets m_activationPolicy, m_includedPolicyClasses, and
+ // m_excludedPolicyClasses.
+ parseActivationPolicy(headerMap);
+
+ m_isExtension = checkExtensionBundle(headerMap);
+ }
+
+ private static List<ParsedHeaderClause> normalizeImportClauses(
+ Logger logger, List<ParsedHeaderClause> clauses, String mv)
+ throws BundleException
+ {
+ // Verify that the values are equals if the package specifies
+ // both version and specification-version attributes.
+ Map<String, Attribute> attrMap = new HashMap();
+ for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
+ {
+ // Put attributes for current clause in a map for easy lookup.
+ attrMap.clear();
+ for (int attrIdx = 0;
+ attrIdx < clauses.get(clauseIdx).m_attrs.size();
+ attrIdx++)
+ {
+ Attribute attr = clauses.get(clauseIdx).m_attrs.get(attrIdx);
+ attrMap.put(attr.getName(), attr);
+ }
+
+ // Check for "version" and "specification-version" attributes
+ // and verify they are the same if both are specified.
+ Attribute v = attrMap.get(Constants.VERSION_ATTRIBUTE);
+ Attribute sv = attrMap.get(Constants.PACKAGE_SPECIFICATION_VERSION);
+ if ((v != null) && (sv != null))
+ {
+ // Verify they are equal.
+ if (!((String) v.getValue()).trim().equals(((String) sv.getValue()).trim()))
+ {
+ throw new IllegalArgumentException(
+ "Both version and specification-version are specified, but they are not equal.");
+ }
+ }
- // Verify there are no duplicate import declarations.
+ // Ensure that only the "version" attribute is used and convert
+ // it to the VersionRange type.
+ if ((v != null) || (sv != null))
+ {
+ attrMap.remove(Constants.PACKAGE_SPECIFICATION_VERSION);
+ v = (v == null) ? sv : v;
+ attrMap.put(Constants.VERSION_ATTRIBUTE,
+ new Attribute(
+ Constants.VERSION_ATTRIBUTE,
+ VersionRange.parse(v.getValue().toString()),
+ v.isMandatory()));
+ }
+
+ // If bundle version is specified, then convert its type to VersionRange.
+ v = attrMap.get(Constants.BUNDLE_VERSION_ATTRIBUTE);
+ if (v != null)
+ {
+ attrMap.put(Constants.BUNDLE_VERSION_ATTRIBUTE,
+ new Attribute(
+ Constants.BUNDLE_VERSION_ATTRIBUTE,
+ VersionRange.parse(v.getValue().toString()),
+ v.isMandatory()));
+ }
+
+ // Re-copy the attributes in case they changed.
+ clauses.get(clauseIdx).m_attrs.clear();
+ clauses.get(clauseIdx).m_attrs.addAll(attrMap.values());
+ }
+
+ // Verify java.* is not imported, nor any duplicate imports.
Set dupeSet = new HashSet();
- for (int reqIdx = 0; reqIdx < importReqs.length; reqIdx++)
+ for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
{
// Verify that the named package has not already been declared.
- String pkgName = ((Requirement) importReqs[reqIdx]).getTargetName();
- if (!dupeSet.contains(pkgName))
+ List<String> paths = clauses.get(clauseIdx).m_paths;
+ for (int pathIdx = 0; pathIdx < paths.size(); pathIdx++)
{
- // Verify that java.* packages are not imported.
- if (pkgName.startsWith("java."))
+ String pkgName = paths.get(pathIdx);
+ if (!dupeSet.contains(pkgName))
{
- throw new BundleException(
- "Importing java.* packages not allowed: " + pkgName);
+ // Verify that java.* packages are not imported.
+ if (pkgName.startsWith("java."))
+ {
+ throw new BundleException(
+ "Importing java.* packages not allowed: " + pkgName);
+ }
+ // Make sure a package name was specified.
+ else if (clauses.get(clauseIdx).m_paths.get(pathIdx).length() == 0)
+ {
+ throw new BundleException(
+ "Imported package names cannot be zero length.");
+ }
+ dupeSet.add(pkgName);
+ }
+ else
+ {
+ throw new BundleException("Duplicate import: " + pkgName);
}
- dupeSet.add(pkgName);
}
- else
+ }
+
+ if (!mv.equals("2"))
+ {
+ // Check to make sure that R3 bundles have only specified
+ // the 'specification-version' attribute and no directives
+ // on their imports; ignore all unknown attributes.
+ for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
{
- throw new BundleException("Duplicate import - " + pkgName);
+ // R3 bundles cannot have directives on their imports.
+ if (clauses.get(clauseIdx).m_dirs.size() != 0)
+ {
+ throw new BundleException("R3 imports cannot contain directives.");
+ }
+
+ // Remove and ignore all attributes other than version.
+ // NOTE: This is checking for "version" rather than "specification-version"
+ // because the package class normalizes to "version" to avoid having
+ // future special cases. This could be changed if more strict behavior
+ // is required.
+ if (clauses.get(clauseIdx).m_attrs.size() != 0)
+ {
+ // R3 package requirements should only have version attributes.
+ Attribute pkgVersion =
+ new Attribute(Capability.VERSION_ATTR,
+ new VersionRange(Version.emptyVersion, true, null, true), false);
+ for (int attrIdx = 0;
+ attrIdx < clauses.get(clauseIdx).m_attrs.size();
+ attrIdx++)
+ {
+ if (clauses.get(clauseIdx).m_attrs.get(attrIdx)
+ .getName().equals(Capability.VERSION_ATTR))
+ {
+ pkgVersion = clauses.get(clauseIdx).m_attrs.get(attrIdx);
+ }
+ else
+ {
+ logger.log(Logger.LOG_WARNING,
+ "Unknown R3 import attribute: "
+ + clauses.get(clauseIdx).m_attrs.get(attrIdx).getName());
+ }
+ }
+
+ // Recreate the import to remove any other attributes
+ // and add version if missing.
+ ArrayList<Attribute> attrs = new ArrayList<Attribute>(1);
+ attrs.add(pkgVersion);
+ clauses.set(clauseIdx, new ParsedHeaderClause(
+ clauses.get(clauseIdx).m_paths,
+ clauses.get(clauseIdx).m_dirs,
+ attrs));
+ }
}
- // If it has not already been imported, then add it to the list
- // of requirements.
- reqList.add(importReqs[reqIdx]);
}
- // Create an array of all requirements.
- m_requirements = (IRequirement[]) reqList.toArray(new IRequirement[reqList.size()]);
+ return clauses;
+ }
- //
- // Parse DynamicImport-Package.
- //
+ private static List<Requirement> convertImports(List<ParsedHeaderClause> clauses)
+ {
+ // Now convert generic header clauses into requirements.
+ List reqList = new ArrayList();
+ for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
+ {
+ for (int pathIdx = 0;
+ pathIdx < clauses.get(clauseIdx).m_paths.size();
+ pathIdx++)
+ {
+ // Prepend the package name to the array of attributes.
+ List<Attribute> attrs = clauses.get(clauseIdx).m_attrs;
+ List<Attribute> newAttrs = new ArrayList<Attribute>(attrs.size() + 1);
+ newAttrs.add(new Attribute(
+ Capability.PACKAGE_ATTR,
+ clauses.get(clauseIdx).m_paths.get(pathIdx), false));
+ newAttrs.addAll(attrs);
+
+ // Create package requirement and add to requirement list.
+ reqList.add(
+ new RequirementImpl(
+ Capability.PACKAGE_NAMESPACE,
+ clauses.get(clauseIdx).m_dirs,
+ newAttrs));
+ }
+ }
+
+ return reqList;
+ }
- // Get dynamic import packages from bundle manifest.
- m_dynamicRequirements = parseImportHeader(
- (String) headerMap.get(Constants.DYNAMICIMPORT_PACKAGE));
+ private static List<ParsedHeaderClause> normalizeDynamicImportClauses(
+ Logger logger, List<ParsedHeaderClause> clauses, String mv)
+ throws BundleException
+ {
+ // Verify that the values are equals if the package specifies
+ // both version and specification-version attributes.
+ Map<String, Attribute> attrMap = new HashMap();
+ for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
+ {
+ // Put attributes for current clause in a map for easy lookup.
+ attrMap.clear();
+ for (int attrIdx = 0;
+ attrIdx < clauses.get(clauseIdx).m_attrs.size();
+ attrIdx++)
+ {
+ Attribute attr = clauses.get(clauseIdx).m_attrs.get(attrIdx);
+ attrMap.put(attr.getName(), attr);
+ }
+
+ // Check for "version" and "specification-version" attributes
+ // and verify they are the same if both are specified.
+ Attribute v = attrMap.get(Constants.VERSION_ATTRIBUTE);
+ Attribute sv = attrMap.get(Constants.PACKAGE_SPECIFICATION_VERSION);
+ if ((v != null) && (sv != null))
+ {
+ // Verify they are equal.
+ if (!((String) v.getValue()).trim().equals(((String) sv.getValue()).trim()))
+ {
+ throw new IllegalArgumentException(
+ "Both version and specification-version are specified, but they are not equal.");
+ }
+ }
+
+ // Ensure that only the "version" attribute is used and convert
+ // it to the VersionRange type.
+ if ((v != null) || (sv != null))
+ {
+ attrMap.remove(Constants.PACKAGE_SPECIFICATION_VERSION);
+ v = (v == null) ? sv : v;
+ attrMap.put(Constants.VERSION_ATTRIBUTE,
+ new Attribute(
+ Constants.VERSION_ATTRIBUTE,
+ VersionRange.parse(v.getValue().toString()),
+ v.isMandatory()));
+ }
+
+ // If bundle version is specified, then convert its type to VersionRange.
+ v = attrMap.get(Constants.BUNDLE_VERSION_ATTRIBUTE);
+ if (v != null)
+ {
+ attrMap.put(Constants.BUNDLE_VERSION_ATTRIBUTE,
+ new Attribute(
+ Constants.BUNDLE_VERSION_ATTRIBUTE,
+ VersionRange.parse(v.getValue().toString()),
+ v.isMandatory()));
+ }
+
+ // Re-copy the attributes in case they changed.
+ clauses.get(clauseIdx).m_attrs.clear();
+ clauses.get(clauseIdx).m_attrs.addAll(attrMap.values());
+ }
// Dynamic imports can have duplicates, so just check for import
// of java.*.
- for (int reqIdx = 0; reqIdx < m_dynamicRequirements.length; reqIdx++)
+ for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
{
// Verify that java.* packages are not imported.
- String pkgName = ((Requirement) m_dynamicRequirements[reqIdx]).getTargetName();
- if (pkgName.startsWith("java."))
+ List<String> paths = clauses.get(clauseIdx).m_paths;
+ for (int pathIdx = 0; pathIdx < paths.size(); pathIdx++)
{
- throw new BundleException(
- "Dynamically importing java.* packages not allowed: " + pkgName);
+ String pkgName = paths.get(pathIdx);
+ if (pkgName.startsWith("java."))
+ {
+ throw new BundleException(
+ "Dynamically importing java.* packages not allowed: " + pkgName);
+ }
+ else if (!pkgName.equals("*") && pkgName.endsWith("*") && !pkgName.endsWith(".*"))
+ {
+ throw new BundleException(
+ "Partial package name wild carding is not allowed: " + pkgName);
+ }
}
- else if (!pkgName.equals("*") && pkgName.endsWith("*") && !pkgName.endsWith(".*"))
+ }
+
+ if (!mv.equals("2"))
+ {
+ // Check to make sure that R3 bundles have only specified
+ // the 'specification-version' attribute and no directives
+ // on their imports; ignore all unknown attributes.
+ for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
{
- throw new BundleException(
- "Partial package name wild carding is not allowed: " + pkgName);
+ // R3 bundles cannot have directives on their imports.
+ if (clauses.get(clauseIdx).m_dirs.size() != 0)
+ {
+ throw new BundleException("R3 imports cannot contain directives.");
+ }
}
}
- //
- // Parse Bundle-NativeCode.
- //
+ return clauses;
+ }
- // Get native library entry names for module library sources.
- m_libraryHeaders =
- parseLibraryStrings(
- m_logger,
- parseDelimitedString((String) m_headerMap.get(Constants.BUNDLE_NATIVECODE), ","));
+ private static List<ParsedHeaderClause> normalizeExportClauses(
+ Logger logger, List<ParsedHeaderClause> clauses,
+ String mv, String bsn, Version bv)
+ throws BundleException
+ {
+ // Verify that "java.*" packages are not exported.
+ for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
+ {
+ // Verify that the named package has not already been declared.
+ for (int pathIdx = 0; pathIdx < clauses.get(clauseIdx).m_paths.size(); pathIdx++)
+ {
+ // Verify that java.* packages are not exported.
+ if (clauses.get(clauseIdx).m_paths.get(pathIdx).startsWith("java."))
+ {
+ throw new BundleException(
+ "Exporting java.* packages not allowed: "
+ + clauses.get(clauseIdx).m_paths.get(pathIdx));
+ }
+ else if (clauses.get(clauseIdx).m_paths.get(pathIdx).length() == 0)
+ {
+ throw new BundleException(
+ "Exported package names cannot be zero length.");
+ }
+ }
+ }
- // Check to see if there was an optional native library clause, which is
- // represented by a null library header; if so, record it and remove it.
- if ((m_libraryHeaders.length > 0) &&
- (m_libraryHeaders[m_libraryHeaders.length - 1].getLibraryEntries() == null))
+ // If both version and specification-version attributes are specified,
+ // then verify that the values are equal.
+ Map<String, Attribute> attrMap = new HashMap();
+ for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
{
- m_libraryHeadersOptional = true;
- R4LibraryClause[] tmp = new R4LibraryClause[m_libraryHeaders.length - 1];
- System.arraycopy(m_libraryHeaders, 0, tmp, 0, m_libraryHeaders.length - 1);
- m_libraryHeaders = tmp;
+ // Put attributes for current clause in a map for easy lookup.
+ attrMap.clear();
+ for (int attrIdx = 0;
+ attrIdx < clauses.get(clauseIdx).m_attrs.size();
+ attrIdx++)
+ {
+ Attribute attr = clauses.get(clauseIdx).m_attrs.get(attrIdx);
+ attrMap.put(attr.getName(), attr);
+ }
+
+ // Check for "version" and "specification-version" attributes
+ // and verify they are the same if both are specified.
+ Attribute v = attrMap.get(Constants.VERSION_ATTRIBUTE);
+ Attribute sv = attrMap.get(Constants.PACKAGE_SPECIFICATION_VERSION);
+ if ((v != null) && (sv != null))
+ {
+ // Verify they are equal.
+ if (!((String) v.getValue()).trim().equals(((String) sv.getValue()).trim()))
+ {
+ throw new IllegalArgumentException(
+ "Both version and specification-version are specified, but they are not equal.");
+ }
+ }
+
+ // Always add the default version if not specified.
+ if ((v == null) && (sv == null))
+ {
+ v = new Attribute(
+ Constants.VERSION_ATTRIBUTE, Version.emptyVersion, false);
+ }
+
+ // Ensure that only the "version" attribute is used and convert
+ // it to the appropriate type.
+ if ((v != null) || (sv != null))
+ {
+ // Convert version attribute to type Version.
+ attrMap.remove(Constants.PACKAGE_SPECIFICATION_VERSION);
+ v = (v == null) ? sv : v;
+ attrMap.put(Constants.VERSION_ATTRIBUTE,
+ new Attribute(
+ Constants.VERSION_ATTRIBUTE,
+ Version.parseVersion(v.getValue().toString()),
+ v.isMandatory()));
+
+ // Re-copy the attributes since they have changed.
+ clauses.get(clauseIdx).m_attrs.clear();
+ clauses.get(clauseIdx).m_attrs.addAll(attrMap.values());
+ }
}
- //
- // Parse activation policy.
- //
+ // If this is an R4 bundle, then make sure it doesn't specify
+ // bundle symbolic name or bundle version attributes.
+ if (mv.equals("2"))
+ {
+ for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
+ {
+ // R3 package capabilities should only have a version attribute.
+ List<Attribute> attrs = clauses.get(clauseIdx).m_attrs;
+ for (int attrIdx = 0; attrIdx < attrs.size(); attrIdx++)
+ {
+ // Find symbolic name and version attribute, if present.
+ if (attrs.get(attrIdx).getName().equals(Constants.BUNDLE_VERSION_ATTRIBUTE) ||
+ attrs.get(attrIdx).getName().equals(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE))
+ {
+ throw new BundleException(
+ "Exports must not specify bundle symbolic name or bundle version.");
+ }
+ }
- // This sets m_activationPolicy, m_includedPolicyClasses, and
- // m_excludedPolicyClasses.
- parseActivationPolicy(headerMap);
+ // Now that we know that there are no bundle symbolic name and version
+ // attributes, add them since the spec says they are there implicitly.
+ attrs.add(new Attribute(
+ Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, bsn, false));
+ attrs.add(new Attribute(
+ Constants.BUNDLE_VERSION_ATTRIBUTE, bv, false));
+ ((ArrayList) attrs).trimToSize();
+ }
+ }
+ else if (!mv.equals("2"))
+ {
+ // Check to make sure that R3 bundles have only specified
+ // the 'specification-version' attribute and no directives
+ // on their exports; ignore all unknown attributes.
+ for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
+ {
+ // R3 bundles cannot have directives on their exports.
+ if (clauses.get(clauseIdx).m_dirs.size() != 0)
+ {
+ throw new BundleException("R3 exports cannot contain directives.");
+ }
+
+ // Remove and ignore all attributes other than version.
+ // NOTE: This is checking for "version" rather than "specification-version"
+ // because the package class normalizes to "version" to avoid having
+ // future special cases. This could be changed if more strict behavior
+ // is required.
+ if (clauses.get(clauseIdx).m_attrs.size() != 0)
+ {
+ // R3 package capabilities should only have a version attribute.
+ List<Attribute> attrs = clauses.get(clauseIdx).m_attrs;
+ Attribute pkgVersion = new Attribute(Capability.VERSION_ATTR, Version.emptyVersion, false);
+ for (int attrIdx = 0; attrIdx < attrs.size(); attrIdx++)
+ {
+ if (attrs.get(attrIdx).getName().equals(Capability.VERSION_ATTR))
+ {
+ pkgVersion = attrs.get(attrIdx);
+ }
+ else
+ {
+ logger.log(
+ Logger.LOG_WARNING,
+ "Unknown R3 export attribute: "
+ + attrs.get(attrIdx).getName());
+ }
+ }
- // Do final checks and normalization of manifest.
- if (getManifestVersion().equals("2"))
- {
- checkAndNormalizeR4();
- }
- else
- {
- checkAndNormalizeR3();
+ // Recreate the export to remove any other attributes
+ // and add version if missing.
+ List<Attribute> newAttrs = new ArrayList<Attribute>(2);
+ newAttrs.add(pkgVersion);
+ clauses.set(clauseIdx, new ParsedHeaderClause(
+ clauses.get(clauseIdx).m_paths,
+ clauses.get(clauseIdx).m_dirs,
+ newAttrs));
+ }
+ }
}
+ return clauses;
}
public String getManifestVersion()
@@ -302,24 +711,24 @@
return m_bundleVersion;
}
- public ICapability[] getCapabilities()
+ public List<Capability> getCapabilities()
{
return m_capabilities;
}
- public IRequirement[] getRequirements()
+ public List<Requirement> getRequirements()
{
return m_requirements;
}
- public IRequirement[] getDynamicRequirements()
+ public List<Requirement> getDynamicRequirements()
{
return m_dynamicRequirements;
}
- public R4LibraryClause[] getLibraryClauses()
+ public List<R4LibraryClause> getLibraryClauses()
{
- return m_libraryHeaders;
+ return m_libraryClauses;
}
/**
@@ -348,18 +757,18 @@
* @return <tt>null</tt> if there are no native libraries, a zero-length
* array if no libraries matched, or an array of selected libraries.
**/
- public R4Library[] getLibraries()
+ public List<R4Library> getLibraries()
{
- R4Library[] libs = null;
+ ArrayList<R4Library> libs = null;
try
{
R4LibraryClause clause = getSelectedLibraryClause();
if (clause != null)
{
String[] entries = clause.getLibraryEntries();
- libs = new R4Library[entries.length];
+ libs = new ArrayList<R4Library>(entries.length);
int current = 0;
- for (int i = 0; i < libs.length; i++)
+ for (int i = 0; i < entries.length; i++)
{
String name = getName(entries[i]);
boolean found = false;
@@ -369,23 +778,18 @@
}
if (!found)
{
- libs[current++] = new R4Library(
+ libs.add(new R4Library(
clause.getLibraryEntries()[i],
clause.getOSNames(), clause.getProcessors(), clause.getOSVersions(),
- clause.getLanguages(), clause.getSelectionFilter());
+ clause.getLanguages(), clause.getSelectionFilter()));
}
}
- if (current < libs.length)
- {
- R4Library[] tmp = new R4Library[current];
- System.arraycopy(libs, 0, tmp, 0, current);
- libs = tmp;
- }
+ libs.trimToSize();
}
}
catch (Exception ex)
{
- libs = new R4Library[0];
+ libs = new ArrayList<R4Library>(0);
}
return libs;
}
@@ -402,16 +806,16 @@
private R4LibraryClause getSelectedLibraryClause() throws BundleException
{
- if ((m_libraryHeaders != null) && (m_libraryHeaders.length > 0))
+ if ((m_libraryClauses != null) && (m_libraryClauses.size() > 0))
{
List clauseList = new ArrayList();
// Search for matching native clauses.
- for (int i = 0; i < m_libraryHeaders.length; i++)
+ for (int i = 0; i < m_libraryClauses.size(); i++)
{
- if (m_libraryHeaders[i].match(m_configMap))
+ if (m_libraryClauses.get(i).match(m_configMap))
{
- clauseList.add(m_libraryHeaders[i]);
+ clauseList.add(m_libraryClauses.get(i));
}
}
@@ -468,9 +872,9 @@
for (int k = 0; (osversions != null) && (k < osversions.length); k++)
{
VersionRange range = VersionRange.parse(osversions[k]);
- if ((range.getLow()).compareTo(osVersionRangeMaxFloor) >= 0)
+ if ((range.getFloor()).compareTo(osVersionRangeMaxFloor) >= 0)
{
- osVersionRangeMaxFloor = range.getLow();
+ osVersionRangeMaxFloor = range.getFloor();
}
}
}
@@ -492,7 +896,7 @@
for (int k = 0; k < osversions.length; k++)
{
VersionRange range = VersionRange.parse(osversions[k]);
- if ((range.getLow()).compareTo(osVersionRangeMaxFloor) >= 0)
+ if ((range.getFloor()).compareTo(osVersionRangeMaxFloor) >= 0)
{
selection.add("" + indexList.get(i));
}
@@ -541,306 +945,130 @@
}
}
- private void checkAndNormalizeR3() throws BundleException
+ private static List<ParsedHeaderClause> calculateImplicitImports(
+ List<Capability> exports, List<ParsedHeaderClause> imports)
+ throws BundleException
{
- // Check to make sure that R3 bundles have only specified
- // the 'specification-version' attribute and no directives
- // on their exports; ignore all unknown attributes.
- for (int capIdx = 0;
- (m_capabilities != null) && (capIdx < m_capabilities.length);
- capIdx++)
- {
- if (m_capabilities[capIdx].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
- {
- // R3 bundles cannot have directives on their exports.
- if (((Capability) m_capabilities[capIdx]).getDirectives().length != 0)
- {
- throw new BundleException("R3 exports cannot contain directives.");
- }
-
- // Remove and ignore all attributes other than version.
- // NOTE: This is checking for "version" rather than "specification-version"
- // because the package class normalizes to "version" to avoid having
- // future special cases. This could be changed if more strict behavior
- // is required.
- if (((Capability) m_capabilities[capIdx]).getAttributes() != null)
- {
- // R3 package capabilities should only have name and
- // version attributes.
- R4Attribute pkgName = null;
- R4Attribute pkgVersion = new R4Attribute(ICapability.VERSION_PROPERTY, Version.emptyVersion, false);
- for (int attrIdx = 0;
- attrIdx < ((Capability) m_capabilities[capIdx]).getAttributes().length;
- attrIdx++)
- {
- if (((Capability) m_capabilities[capIdx]).getAttributes()[attrIdx]
- .getName().equals(ICapability.PACKAGE_PROPERTY))
- {
- pkgName = ((Capability) m_capabilities[capIdx]).getAttributes()[attrIdx];
- }
- else if (((Capability) m_capabilities[capIdx]).getAttributes()[attrIdx]
- .getName().equals(ICapability.VERSION_PROPERTY))
- {
- pkgVersion = ((Capability) m_capabilities[capIdx]).getAttributes()[attrIdx];
- }
- else
- {
- m_logger.log(Logger.LOG_WARNING,
- "Unknown R3 export attribute: "
- + ((Capability) m_capabilities[capIdx]).getAttributes()[attrIdx].getName());
- }
- }
-
- // Recreate the export to remove any other attributes
- // and add version if missing.
- m_capabilities[capIdx] = new Capability(
- m_capabilities[capIdx].getModule(),
- ICapability.PACKAGE_NAMESPACE,
- null,
- new R4Attribute[] { pkgName, pkgVersion } );
- }
- }
- }
-
- // Check to make sure that R3 bundles have only specified
- // the 'specification-version' attribute and no directives
- // on their imports; ignore all unknown attributes.
- for (int reqIdx = 0; (m_requirements != null) && (reqIdx < m_requirements.length); reqIdx++)
- {
- if (m_requirements[reqIdx].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
- {
- // R3 bundles cannot have directives on their imports.
- if (((Requirement) m_requirements[reqIdx]).getDirectives().length != 0)
- {
- throw new BundleException("R3 imports cannot contain directives.");
- }
-
- // Remove and ignore all attributes other than version.
- // NOTE: This is checking for "version" rather than "specification-version"
- // because the package class normalizes to "version" to avoid having
- // future special cases. This could be changed if more strict behavior
- // is required.
- if (((Requirement) m_requirements[reqIdx]).getAttributes() != null)
- {
- // R3 package requirements should only have name and
- // version attributes.
- R4Attribute pkgName = null;
- R4Attribute pkgVersion =
- new R4Attribute(ICapability.VERSION_PROPERTY,
- new VersionRange(Version.emptyVersion, true, null, true), false);
- for (int attrIdx = 0;
- attrIdx < ((Requirement) m_requirements[reqIdx]).getAttributes().length;
- attrIdx++)
- {
- if (((Requirement) m_requirements[reqIdx]).getAttributes()[attrIdx]
- .getName().equals(ICapability.PACKAGE_PROPERTY))
- {
- pkgName = ((Requirement) m_requirements[reqIdx]).getAttributes()[attrIdx];
- }
- else if (((Requirement) m_requirements[reqIdx]).getAttributes()[attrIdx]
- .getName().equals(ICapability.VERSION_PROPERTY))
- {
- pkgVersion = ((Requirement) m_requirements[reqIdx]).getAttributes()[attrIdx];
- }
- else
- {
- m_logger.log(Logger.LOG_WARNING,
- "Unknown R3 import attribute: "
- + ((Requirement) m_requirements[reqIdx]).getAttributes()[attrIdx].getName());
- }
- }
-
- // Recreate the import to remove any other attributes
- // and add version if missing.
- m_requirements[reqIdx] = new Requirement(
- ICapability.PACKAGE_NAMESPACE,
- null,
- new R4Attribute[] { pkgName, pkgVersion });
- }
- }
- }
+ List<ParsedHeaderClause> clauseList = new ArrayList();
// Since all R3 exports imply an import, add a corresponding
// requirement for each existing export capability. Do not
// duplicate imports.
Map map = new HashMap();
// Add existing imports.
- for (int i = 0; i < m_requirements.length; i++)
+ for (int impIdx = 0; impIdx < imports.size(); impIdx++)
{
- if (m_requirements[i].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
+ for (int pathIdx = 0; pathIdx < imports.get(impIdx).m_paths.size(); pathIdx++)
{
map.put(
- ((Requirement) m_requirements[i]).getTargetName(),
- m_requirements[i]);
+ imports.get(impIdx).m_paths.get(pathIdx),
+ imports.get(impIdx).m_paths.get(pathIdx));
}
}
// Add import requirement for each export capability.
- for (int i = 0; i < m_capabilities.length; i++)
+ for (int i = 0; i < exports.size(); i++)
{
- if (m_capabilities[i].getNamespace().equals(ICapability.PACKAGE_NAMESPACE) &&
- (map.get(m_capabilities[i].getProperties().get(ICapability.PACKAGE_PROPERTY)) == null))
+ if (map.get(exports.get(i).getAttribute(Capability.PACKAGE_ATTR).getValue()) == null)
{
// Convert Version to VersionRange.
- R4Attribute[] attrs = (R4Attribute[]) ((Capability) m_capabilities[i]).getAttributes().clone();
- for (int attrIdx = 0; (attrs != null) && (attrIdx < attrs.length); attrIdx++)
+ List<Attribute> attrs = new ArrayList<Attribute>(exports.get(i).getAttributes());
+ for (int attrIdx = 0; (attrs != null) && (attrIdx < attrs.size()); attrIdx++)
{
- if (attrs[attrIdx].getName().equals(Constants.VERSION_ATTRIBUTE))
+ if (attrs.get(attrIdx).getName().equals(Constants.VERSION_ATTRIBUTE))
{
- attrs[attrIdx] = new R4Attribute(
- attrs[attrIdx].getName(),
- VersionRange.parse(attrs[attrIdx].getValue().toString()),
- attrs[attrIdx].isMandatory());
+ attrs.set(attrIdx, new Attribute(
+ attrs.get(attrIdx).getName(),
+ VersionRange.parse(attrs.get(attrIdx).getValue().toString()),
+ attrs.get(attrIdx).isMandatory()));
}
}
- map.put(
- m_capabilities[i].getProperties().get(ICapability.PACKAGE_PROPERTY),
- new Requirement(ICapability.PACKAGE_NAMESPACE, null, attrs));
+ List<String> paths = new ArrayList();
+ paths.add((String)
+ exports.get(i).getAttribute(Capability.PACKAGE_ATTR).getValue());
+ clauseList.add(
+ new ParsedHeaderClause(paths, new ArrayList<Directive>(0), attrs));
}
}
- m_requirements =
- (IRequirement[]) map.values().toArray(new IRequirement[map.size()]);
+ return clauseList;
+ }
+
+ private static List<Capability> calculateImplicitUses(
+ List<Capability> exports, List<ParsedHeaderClause> imports)
+ throws BundleException
+ {
// Add a "uses" directive onto each export of R3 bundles
// that references every other import (which will include
// exports, since export implies import); this is
// necessary since R3 bundles assumed a single class space,
// but R4 allows for multiple class spaces.
String usesValue = "";
- for (int i = 0; (m_requirements != null) && (i < m_requirements.length); i++)
+ for (int i = 0; i < imports.size(); i++)
{
- if (m_requirements[i].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
+ for (int pathIdx = 0; pathIdx < imports.get(i).m_paths.size(); pathIdx++)
{
usesValue = usesValue
+ ((usesValue.length() > 0) ? "," : "")
- + ((Requirement) m_requirements[i]).getTargetName();
+ + imports.get(i).m_paths.get(pathIdx);
}
}
- R4Directive uses = new R4Directive(
+ Directive uses = new Directive(
Constants.USES_DIRECTIVE, usesValue);
- for (int i = 0; (m_capabilities != null) && (i < m_capabilities.length); i++)
+ for (int i = 0; i < exports.size(); i++)
{
- if (m_capabilities[i].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
- {
- m_capabilities[i] = new Capability(
- m_capabilities[i].getModule(),
- ICapability.PACKAGE_NAMESPACE,
- new R4Directive[] { uses },
- ((Capability) m_capabilities[i]).getAttributes());
- }
+ List<Directive> dirList = new ArrayList<Directive>(1);
+ dirList.add(uses);
+ exports.set(i, new CapabilityImpl(
+ exports.get(i).getModule(),
+ Capability.PACKAGE_NAMESPACE,
+ dirList,
+ exports.get(i).getAttributes()));
}
- // Check to make sure that R3 bundles have no attributes or
- // directives on their dynamic imports.
- for (int i = 0;
- (m_dynamicRequirements != null) && (i < m_dynamicRequirements.length);
- i++)
- {
- if (((Requirement) m_dynamicRequirements[i]).getDirectives().length != 0)
- {
- throw new BundleException("R3 dynamic imports cannot contain directives.");
- }
- if (((Requirement) m_dynamicRequirements[i]).getAttributes().length != 0)
- {
-// throw new BundleException("R3 dynamic imports cannot contain attributes.");
- }
- }
+ return exports;
}
- private void checkAndNormalizeR4() throws BundleException
+ private static boolean checkExtensionBundle(Map headerMap) throws BundleException
{
- // Verify that bundle symbolic name is specified.
- if (m_bundleSymbolicName == null)
- {
- throw new BundleException("R4 bundle manifests must include bundle symbolic name.");
- }
-
- m_capabilities = checkAndNormalizeR4Exports(
- m_capabilities, m_bundleSymbolicName, m_bundleVersion);
-
- R4Directive extension = parseExtensionBundleHeader((String)
- m_headerMap.get(Constants.FRAGMENT_HOST));
+ Directive extension = parseExtensionBundleHeader(
+ (String) headerMap.get(Constants.FRAGMENT_HOST));
if (extension != null)
{
- if (!(Constants.EXTENSION_FRAMEWORK.equals(extension.getValue()) ||
+ if (!(Constants.EXTENSION_FRAMEWORK.equals(extension.getValue()) ||
Constants.EXTENSION_BOOTCLASSPATH.equals(extension.getValue())))
{
throw new BundleException(
"Extension bundle must have either 'extension:=framework' or 'extension:=bootclasspath'");
}
- checkExtensionBundle();
- m_isExtension = true;
- }
- }
-
- private static ICapability[] checkAndNormalizeR4Exports(
- ICapability[] caps, String bsn, Version bv)
- throws BundleException
- {
- // Verify that the exports do not specify bundle symbolic name
- // or bundle version.
- for (int i = 0; (caps != null) && (i < caps.length); i++)
- {
- if (caps[i].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
+ if (headerMap.containsKey(Constants.IMPORT_PACKAGE) ||
+ headerMap.containsKey(Constants.REQUIRE_BUNDLE) ||
+ headerMap.containsKey(Constants.BUNDLE_NATIVECODE) ||
+ headerMap.containsKey(Constants.DYNAMICIMPORT_PACKAGE) ||
+ headerMap.containsKey(Constants.BUNDLE_ACTIVATOR))
{
- R4Attribute[] attrs = ((Capability) caps[i]).getAttributes();
- for (int attrIdx = 0; attrIdx < attrs.length; attrIdx++)
- {
- // 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))
- {
- throw new BundleException(
- "Exports must not specify bundle symbolic name or bundle version.");
- }
- }
-
- // Now that we know that there are no bundle symbolic name and version
- // attributes, add them since the spec says they are there implicitly.
- R4Attribute[] newAttrs = new R4Attribute[attrs.length + 2];
- System.arraycopy(attrs, 0, newAttrs, 0, attrs.length);
- newAttrs[attrs.length] = new R4Attribute(
- Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, bsn, false);
- newAttrs[attrs.length + 1] = new R4Attribute(
- Constants.BUNDLE_VERSION_ATTRIBUTE, bv, false);
- caps[i] = new Capability(
- caps[i].getModule(),
- ICapability.PACKAGE_NAMESPACE,
- ((Capability) caps[i]).getDirectives(),
- newAttrs);
+ throw new BundleException("Invalid extension bundle manifest");
}
+ return true;
}
-
- return caps;
- }
-
- private void checkExtensionBundle() throws BundleException
- {
- if (m_headerMap.containsKey(Constants.IMPORT_PACKAGE) ||
- m_headerMap.containsKey(Constants.REQUIRE_BUNDLE) ||
- m_headerMap.containsKey(Constants.BUNDLE_NATIVECODE) ||
- m_headerMap.containsKey(Constants.DYNAMICIMPORT_PACKAGE) ||
- m_headerMap.containsKey(Constants.BUNDLE_ACTIVATOR))
- {
- throw new BundleException("Invalid extension bundle manifest");
- }
+ return false;
}
- private static ICapability parseBundleSymbolicName(IModule owner, Map headerMap)
+ private static Capability parseBundleSymbolicName(Module owner, Map headerMap)
throws BundleException
{
- Object[][][] clauses = parseStandardHeader(
+ List<ParsedHeaderClause> clauses = parseStandardHeader(
(String) headerMap.get(Constants.BUNDLE_SYMBOLICNAME));
- if (clauses.length > 0)
+ if (clauses.size() > 0)
{
- if (clauses.length > 1)
+ if (clauses.size() > 1)
{
throw new BundleException(
"Cannot have multiple symbolic names: "
+ headerMap.get(Constants.BUNDLE_SYMBOLICNAME));
}
- else if (clauses[0][CLAUSE_PATHS_INDEX].length > 1)
+ else if (clauses.get(0).m_paths.size() > 1)
{
throw new BundleException(
"Cannot have multiple symbolic names: "
@@ -869,42 +1097,42 @@
}
// Create a module capability and return it.
- String symName = (String) clauses[0][CLAUSE_PATHS_INDEX][0];
- R4Attribute[] attrs = new R4Attribute[2];
- attrs[0] = new R4Attribute(
- Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, symName, false);
- attrs[1] = new R4Attribute(
- Constants.BUNDLE_VERSION_ATTRIBUTE, bundleVersion, false);
- return new Capability(
+ String symName = (String) clauses.get(0).m_paths.get(0);
+ List<Attribute> attrs = new ArrayList<Attribute>(2);
+ attrs.add(new Attribute(
+ Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, symName, false));
+ attrs.add(new Attribute(
+ Constants.BUNDLE_VERSION_ATTRIBUTE, bundleVersion, false));
+ return new CapabilityImpl(
owner,
- ICapability.MODULE_NAMESPACE,
- (R4Directive[]) clauses[0][CLAUSE_DIRECTIVES_INDEX],
+ Capability.MODULE_NAMESPACE,
+ clauses.get(0).m_dirs,
attrs);
}
return null;
}
- private static IRequirement parseFragmentHost(Logger logger, Map headerMap)
+ private static List<Requirement> parseFragmentHost(Logger logger, Map headerMap)
throws BundleException
{
- IRequirement req = null;
+ List<Requirement> reqs = new ArrayList();
String mv = getManifestVersion(headerMap);
if ((mv != null) && mv.equals("2"))
{
- Object[][][] clauses = parseStandardHeader(
+ List<ParsedHeaderClause> clauses = parseStandardHeader(
(String) headerMap.get(Constants.FRAGMENT_HOST));
- if (clauses.length > 0)
+ if (clauses.size() > 0)
{
// Make sure that only one fragment host symbolic name is specified.
- if (clauses.length > 1)
+ if (clauses.size() > 1)
{
throw new BundleException(
"Fragments cannot have multiple hosts: "
+ headerMap.get(Constants.FRAGMENT_HOST));
}
- else if (clauses[0][CLAUSE_PATHS_INDEX].length > 1)
+ else if (clauses.get(0).m_paths.size() > 1)
{
throw new BundleException(
"Fragments cannot have multiple hosts: "
@@ -914,31 +1142,31 @@
// If the bundle version matching attribute is specified, then
// convert it to the proper type.
for (int attrIdx = 0;
- attrIdx < clauses[0][CLAUSE_ATTRIBUTES_INDEX].length;
+ attrIdx < clauses.get(0).m_attrs.size();
attrIdx++)
{
- R4Attribute attr = (R4Attribute) clauses[0][CLAUSE_ATTRIBUTES_INDEX][attrIdx];
+ Attribute attr = clauses.get(0).m_attrs.get(attrIdx);
if (attr.getName().equals(Constants.BUNDLE_VERSION_ATTRIBUTE))
{
- clauses[0][CLAUSE_ATTRIBUTES_INDEX][attrIdx] =
- new R4Attribute(
+ clauses.get(0).m_attrs.set(attrIdx,
+ new Attribute(
Constants.BUNDLE_VERSION_ATTRIBUTE,
VersionRange.parse(attr.getValue().toString()),
- attr.isMandatory());
+ attr.isMandatory()));
}
}
// Prepend the host symbolic name to the array of attributes.
- R4Attribute[] attrs = (R4Attribute[]) clauses[0][CLAUSE_ATTRIBUTES_INDEX];
- R4Attribute[] newAttrs = new R4Attribute[attrs.length + 1];
- newAttrs[0] = new R4Attribute(
+ List<Attribute> attrs = clauses.get(0).m_attrs;
+ List<Attribute> newAttrs = new ArrayList<Attribute>(attrs.size() + 1);
+ newAttrs.add(new Attribute(
Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE,
- clauses[0][CLAUSE_PATHS_INDEX][0], false);
- System.arraycopy(attrs, 0, newAttrs, 1, attrs.length);
+ clauses.get(0).m_paths.get(0), false));
+ newAttrs.addAll(attrs);
- req = new Requirement(ICapability.HOST_NAMESPACE,
- (R4Directive[]) clauses[0][CLAUSE_DIRECTIVES_INDEX],
- newAttrs);
+ reqs.add(new RequirementImpl(Capability.HOST_NAMESPACE,
+ clauses.get(0).m_dirs,
+ newAttrs));
}
}
else
@@ -946,17 +1174,19 @@
logger.log(Logger.LOG_WARNING, "Only R4 bundles can be fragments.");
}
- return req;
+ return reqs;
}
- public static ICapability[] parseExportHeader(
- IModule owner, String header, String bsn, Version bv)
- throws BundleException
+ public static List<Capability> parseExportHeader(
+ Logger logger, Module owner, String header, String bsn, Version bv)
{
- ICapability[] caps = parseExportHeader(owner, header);
+
+ List<Capability> caps = null;
try
{
- caps = checkAndNormalizeR4Exports(caps, bsn, bv);
+ List<ParsedHeaderClause> exportClauses = parseStandardHeader(header);
+ exportClauses = normalizeExportClauses(logger, exportClauses, "2", bsn, bv);
+ caps = convertExports(exportClauses, owner);
}
catch (BundleException ex)
{
@@ -965,279 +1195,121 @@
return caps;
}
- private static ICapability[] parseExportHeader(IModule owner, String header)
+ private static List<Capability> convertExports(
+ List<ParsedHeaderClause> clauses, Module owner)
{
- Object[][][] clauses = parseStandardHeader(header);
-
-// TODO: FRAMEWORK - Perhaps verification/normalization should be completely
-// separated from parsing, since verification/normalization may vary.
-
- // If both version and specification-version attributes are specified,
- // then verify that the values are equal.
- Map attrMap = new HashMap();
- for (int clauseIdx = 0; clauseIdx < clauses.length; clauseIdx++)
- {
- // Put attributes for current clause in a map for easy lookup.
- attrMap.clear();
- for (int attrIdx = 0;
- attrIdx < clauses[clauseIdx][CLAUSE_ATTRIBUTES_INDEX].length;
- attrIdx++)
- {
- R4Attribute attr = (R4Attribute) clauses[clauseIdx][CLAUSE_ATTRIBUTES_INDEX][attrIdx];
- attrMap.put(attr.getName(), attr);
- }
-
- // Check for "version" and "specification-version" attributes
- // and verify they are the same if both are specified.
- R4Attribute v = (R4Attribute) attrMap.get(Constants.VERSION_ATTRIBUTE);
- R4Attribute sv = (R4Attribute) attrMap.get(Constants.PACKAGE_SPECIFICATION_VERSION);
- if ((v != null) && (sv != null))
- {
- // Verify they are equal.
- 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.");
- }
- }
-
- // Always add the default version if not specified.
- if ((v == null) && (sv == null))
- {
- v = new R4Attribute(
- Constants.VERSION_ATTRIBUTE, Version.emptyVersion, false);
- }
-
- // Ensure that only the "version" attribute is used and convert
- // it to the appropriate type.
- if ((v != null) || (sv != null))
- {
- // Convert version attribute to type Version.
- attrMap.remove(Constants.PACKAGE_SPECIFICATION_VERSION);
- v = (v == null) ? sv : v;
- attrMap.put(Constants.VERSION_ATTRIBUTE,
- new R4Attribute(
- Constants.VERSION_ATTRIBUTE,
- Version.parseVersion(v.getValue().toString()),
- v.isMandatory()));
-
- // Re-copy the attribute array since it has changed.
- clauses[clauseIdx][CLAUSE_ATTRIBUTES_INDEX] =
- attrMap.values().toArray(new R4Attribute[attrMap.size()]);
- }
- }
-
- // Now convert generic header clauses into capabilities.
- List capList = new ArrayList();
- for (int clauseIdx = 0; clauseIdx < clauses.length; clauseIdx++)
+ List<Capability> capList = new ArrayList();
+ for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
{
for (int pathIdx = 0;
- pathIdx < clauses[clauseIdx][CLAUSE_PATHS_INDEX].length;
+ pathIdx < clauses.get(clauseIdx).m_paths.size();
pathIdx++)
{
- // Make sure a package name was specified.
- if (((String) clauses[clauseIdx][CLAUSE_PATHS_INDEX][pathIdx]).length() == 0)
- {
- throw new IllegalArgumentException(
- "An empty package name was specified: " + header);
- }
// Prepend the package name to the array of attributes.
- R4Attribute[] attrs = (R4Attribute[]) clauses[clauseIdx][CLAUSE_ATTRIBUTES_INDEX];
- R4Attribute[] newAttrs = new R4Attribute[attrs.length + 1];
- newAttrs[0] = new R4Attribute(
- ICapability.PACKAGE_PROPERTY,
- clauses[clauseIdx][CLAUSE_PATHS_INDEX][pathIdx], false);
- System.arraycopy(attrs, 0, newAttrs, 1, attrs.length);
+ List<Attribute> attrs = clauses.get(clauseIdx).m_attrs;
+ List<Attribute> newAttrs = new ArrayList<Attribute>(attrs.size() + 1);
+ newAttrs.add(new Attribute(
+ Capability.PACKAGE_ATTR,
+ clauses.get(clauseIdx).m_paths.get(pathIdx), false));
+ newAttrs.addAll(attrs);
// Create package capability and add to capability list.
capList.add(
- new Capability(
+ new CapabilityImpl(
owner,
- ICapability.PACKAGE_NAMESPACE,
- (R4Directive[]) clauses[clauseIdx][CLAUSE_DIRECTIVES_INDEX],
+ Capability.PACKAGE_NAMESPACE,
+ clauses.get(clauseIdx).m_dirs,
newAttrs));
}
}
- return (ICapability[]) capList.toArray(new ICapability[capList.size()]);
+ return capList;
}
- private static IRequirement[] parseImportHeader(String header)
+ private static List<ParsedHeaderClause> normalizeRequireClauses(
+ Logger logger, List<ParsedHeaderClause> clauses, String mv)
{
- Object[][][] clauses = parseStandardHeader(header);
-
-// TODO: FRAMEWORK - Perhaps verification/normalization should be completely
-// separated from parsing, since verification/normalization may vary.
-
- // Verify that the values are equals if the package specifies
- // both version and specification-version attributes.
- Map attrMap = new HashMap();
- for (int clauseIdx = 0; clauseIdx < clauses.length; clauseIdx++)
+ // R3 bundles cannot require other bundles.
+ if (!mv.equals("2"))
{
- // Put attributes for current clause in a map for easy lookup.
- attrMap.clear();
- for (int attrIdx = 0;
- attrIdx < clauses[clauseIdx][CLAUSE_ATTRIBUTES_INDEX].length;
- attrIdx++)
- {
- R4Attribute attr = (R4Attribute) clauses[clauseIdx][CLAUSE_ATTRIBUTES_INDEX][attrIdx];
- attrMap.put(attr.getName(), attr);
- }
-
- // Check for "version" and "specification-version" attributes
- // and verify they are the same if both are specified.
- R4Attribute v = (R4Attribute) attrMap.get(Constants.VERSION_ATTRIBUTE);
- R4Attribute sv = (R4Attribute) attrMap.get(Constants.PACKAGE_SPECIFICATION_VERSION);
- if ((v != null) && (sv != null))
- {
- // Verify they are equal.
- 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.");
- }
- }
-
- // Ensure that only the "version" attribute is used and convert
- // it to the VersionRange type.
- if ((v != null) || (sv != null))
- {
- attrMap.remove(Constants.PACKAGE_SPECIFICATION_VERSION);
- v = (v == null) ? sv : v;
- attrMap.put(Constants.VERSION_ATTRIBUTE,
- new R4Attribute(
- Constants.VERSION_ATTRIBUTE,
- VersionRange.parse(v.getValue().toString()),
- v.isMandatory()));
- }
-
- // If bundle version is specified, then convert its type to VersionRange.
- v = (R4Attribute) attrMap.get(Constants.BUNDLE_VERSION_ATTRIBUTE);
- if (v != null)
- {
- attrMap.put(Constants.BUNDLE_VERSION_ATTRIBUTE,
- new R4Attribute(
- Constants.BUNDLE_VERSION_ATTRIBUTE,
- VersionRange.parse(v.getValue().toString()),
- v.isMandatory()));
- }
-
- // Re-copy the attribute array in case it has changed.
- clauses[clauseIdx][CLAUSE_ATTRIBUTES_INDEX] =
- attrMap.values().toArray(new R4Attribute[attrMap.size()]);
+ clauses.clear();
}
-
- // Now convert generic header clauses into requirements.
- List reqList = new ArrayList();
- for (int clauseIdx = 0; clauseIdx < clauses.length; clauseIdx++)
+ else
{
- for (int pathIdx = 0;
- pathIdx < clauses[clauseIdx][CLAUSE_PATHS_INDEX].length;
- pathIdx++)
+ // Convert bundle version attribute to VersionRange type.
+ for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
{
- // Make sure a package name was specified.
- if (((String) clauses[clauseIdx][CLAUSE_PATHS_INDEX][pathIdx]).length() == 0)
+ for (int attrIdx = 0;
+ attrIdx < clauses.get(clauseIdx).m_attrs.size();
+ attrIdx++)
{
- throw new IllegalArgumentException(
- "An empty package name was specified: " + header);
+ Attribute attr = clauses.get(clauseIdx).m_attrs.get(attrIdx);
+ if (attr.getName().equals(Constants.BUNDLE_VERSION_ATTRIBUTE))
+ {
+ clauses.get(clauseIdx).m_attrs.set(attrIdx,
+ new Attribute(
+ Constants.BUNDLE_VERSION_ATTRIBUTE,
+ VersionRange.parse(attr.getValue().toString()),
+ attr.isMandatory()));
+ }
}
- // Prepend the package name to the array of attributes.
- R4Attribute[] attrs = (R4Attribute[]) clauses[clauseIdx][CLAUSE_ATTRIBUTES_INDEX];
- R4Attribute[] newAttrs = new R4Attribute[attrs.length + 1];
- newAttrs[0] = new R4Attribute(
- ICapability.PACKAGE_PROPERTY,
- clauses[clauseIdx][CLAUSE_PATHS_INDEX][pathIdx], false);
- System.arraycopy(attrs, 0, newAttrs, 1, attrs.length);
-
- // Create package requirement and add to requirement list.
- reqList.add(
- new Requirement(
- ICapability.PACKAGE_NAMESPACE,
- (R4Directive[]) clauses[clauseIdx][CLAUSE_DIRECTIVES_INDEX],
- newAttrs));
}
}
- return (IRequirement[]) reqList.toArray(new IRequirement[reqList.size()]);
+ return clauses;
}
- private static IRequirement[] parseRequireBundleHeader(String header)
+ private static List<Requirement> convertRequires(List<ParsedHeaderClause> clauses)
{
- Object[][][] clauses = parseStandardHeader(header);
-
-// TODO: FRAMEWORK - Perhaps verification/normalization should be completely
-// separated from parsing, since verification/normalization may vary.
-
- // Convert bundle version attribute to VersionRange type.
- for (int clauseIdx = 0; clauseIdx < clauses.length; clauseIdx++)
+ List<Requirement> reqList = new ArrayList();
+ for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
{
- for (int attrIdx = 0;
- attrIdx < clauses[clauseIdx][CLAUSE_ATTRIBUTES_INDEX].length;
- attrIdx++)
- {
- R4Attribute attr = (R4Attribute) clauses[clauseIdx][CLAUSE_ATTRIBUTES_INDEX][attrIdx];
- if (attr.getName().equals(Constants.BUNDLE_VERSION_ATTRIBUTE))
- {
- clauses[clauseIdx][CLAUSE_ATTRIBUTES_INDEX][attrIdx] =
- new R4Attribute(
- Constants.BUNDLE_VERSION_ATTRIBUTE,
- VersionRange.parse(attr.getValue().toString()),
- attr.isMandatory());
- }
- }
- }
+ List<Attribute> attrs = clauses.get(clauseIdx).m_attrs;
- // Now convert generic header clauses into requirements.
- List reqList = new ArrayList();
- for (int clauseIdx = 0; clauseIdx < clauses.length; clauseIdx++)
- {
for (int pathIdx = 0;
- pathIdx < clauses[clauseIdx][CLAUSE_PATHS_INDEX].length;
+ pathIdx < clauses.get(clauseIdx).m_paths.size();
pathIdx++)
{
// Prepend the symbolic name to the array of attributes.
- R4Attribute[] attrs = (R4Attribute[]) clauses[clauseIdx][CLAUSE_ATTRIBUTES_INDEX];
- R4Attribute[] newAttrs = new R4Attribute[attrs.length + 1];
- newAttrs[0] = new R4Attribute(
+ List<Attribute> newAttrs = new ArrayList<Attribute>(attrs.size() + 1);
+ newAttrs.add(new Attribute(
Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE,
- clauses[clauseIdx][CLAUSE_PATHS_INDEX][pathIdx], false);
- System.arraycopy(attrs, 0, newAttrs, 1, attrs.length);
+ clauses.get(clauseIdx).m_paths.get(pathIdx), false));
+ newAttrs.addAll(attrs);
// Create package requirement and add to requirement list.
reqList.add(
- new Requirement(
- ICapability.MODULE_NAMESPACE,
- (R4Directive[]) clauses[clauseIdx][CLAUSE_DIRECTIVES_INDEX],
+ new RequirementImpl(
+ Capability.MODULE_NAMESPACE,
+ clauses.get(clauseIdx).m_dirs,
newAttrs));
}
}
- return (IRequirement[]) reqList.toArray(new IRequirement[reqList.size()]);
+ return reqList;
}
- public static R4Directive parseExtensionBundleHeader(String header)
+ public static Directive parseExtensionBundleHeader(String header)
throws BundleException
{
- Object[][][] clauses = parseStandardHeader(header);
+ List<ParsedHeaderClause> clauses = parseStandardHeader(header);
- R4Directive result = null;
+ Directive result = null;
- if (clauses.length == 1)
+ if (clauses.size() == 1)
{
// See if there is the "extension" directive.
- for (int i = 0;
- (result == null) && (i < clauses[0][CLAUSE_DIRECTIVES_INDEX].length);
- i++)
+ List<Directive> dirs = clauses.get(0).m_dirs;
+ for (int dirIdx = 0; (result == null) && (dirIdx < dirs.size()); dirIdx++)
{
- if (Constants.EXTENSION_DIRECTIVE.equals(((R4Directive)
- clauses[0][CLAUSE_DIRECTIVES_INDEX][i]).getName()))
+ if (Constants.EXTENSION_DIRECTIVE.equals(dirs.get(dirIdx).getName()))
{
// If the extension directive is specified, make sure
// the target is the system bundle.
- if (FelixConstants.SYSTEM_BUNDLE_SYMBOLICNAME.equals(clauses[0][CLAUSE_PATHS_INDEX][0]) ||
- Constants.SYSTEM_BUNDLE_SYMBOLICNAME.equals(clauses[0][CLAUSE_PATHS_INDEX][0]))
+ if (FelixConstants.SYSTEM_BUNDLE_SYMBOLICNAME.equals(clauses.get(0).m_paths.get(0)) ||
+ Constants.SYSTEM_BUNDLE_SYMBOLICNAME.equals(clauses.get(0).m_paths.get(0)))
{
- result = (R4Directive) clauses[0][CLAUSE_DIRECTIVES_INDEX][i];
+ result = (Directive) dirs.get(dirIdx);
}
else
{
@@ -1253,32 +1325,30 @@
private void parseActivationPolicy(Map headerMap)
{
- m_activationPolicy = IModule.EAGER_ACTIVATION;
+ m_activationPolicy = Module.EAGER_ACTIVATION;
- Object[][][] clauses = parseStandardHeader(
+ List<ParsedHeaderClause> clauses = parseStandardHeader(
(String) headerMap.get(Constants.BUNDLE_ACTIVATIONPOLICY));
- if (clauses.length > 0)
+ if (clauses.size() > 0)
{
// Just look for a "path" matching the lazy policy, ignore
// everything else.
- for (int i = 0;
- i < clauses[0][CLAUSE_PATHS_INDEX].length;
- i++)
+ for (int clauseIdx = 0; clauseIdx < clauses.get(0).m_paths.size(); clauseIdx++)
{
- if (clauses[0][CLAUSE_PATHS_INDEX][i].equals(Constants.ACTIVATION_LAZY))
+ if (clauses.get(0).m_paths.get(clauseIdx).equals(Constants.ACTIVATION_LAZY))
{
- m_activationPolicy = IModule.LAZY_ACTIVATION;
- for (int j = 0; j < clauses[0][CLAUSE_DIRECTIVES_INDEX].length; j++)
+ m_activationPolicy = Module.LAZY_ACTIVATION;
+ for (int dirIdx = 0; dirIdx < clauses.get(0).m_dirs.size(); dirIdx++)
{
- R4Directive dir = (R4Directive) clauses[0][CLAUSE_DIRECTIVES_INDEX][j];
+ Directive dir = clauses.get(0).m_dirs.get(dirIdx);
if (dir.getName().equalsIgnoreCase(Constants.INCLUDE_DIRECTIVE))
{
- m_activationIncludeDir = dir.getValue();
+ m_activationIncludeDir = (String) dir.getValue();
}
else if (dir.getName().equalsIgnoreCase(Constants.EXCLUDE_DIRECTIVE))
{
- m_activationExcludeDir = dir.getValue();
+ m_activationExcludeDir = (String) dir.getValue();
}
}
break;
@@ -1293,9 +1363,9 @@
// Like this: path; path; dir1:=dirval1; dir2:=dirval2; attr1=attrval1; attr2=attrval2,
// path; path; dir1:=dirval1; dir2:=dirval2; attr1=attrval1; attr2=attrval2
- private static Object[][][] parseStandardHeader(String header)
+ private static List<ParsedHeaderClause> parseStandardHeader(String header)
{
- Object[][][] clauses = null;
+ List<ParsedHeaderClause> clauses = new ArrayList();
if (header != null)
{
@@ -1305,26 +1375,24 @@
"A header cannot be an empty string.");
}
- String[] clauseStrings = parseDelimitedString(
+ List<String> clauseStrings = parseDelimitedString(
header, FelixConstants.CLASS_PATH_SEPARATOR);
- List completeList = new ArrayList();
- for (int i = 0; (clauseStrings != null) && (i < clauseStrings.length); i++)
+ for (int i = 0; (clauseStrings != null) && (i < clauseStrings.size()); i++)
{
- completeList.add(parseStandardHeaderClause(clauseStrings[i]));
+ clauses.add(parseStandardHeaderClause(clauseStrings.get(i)));
}
- clauses = (Object[][][]) completeList.toArray(new Object[completeList.size()][][]);
}
- return (clauses == null) ? new Object[0][][] : clauses;
+ return clauses;
}
// Like this: path; path; dir1:=dirval1; dir2:=dirval2; attr1=attrval1; attr2=attrval2
- private static Object[][] parseStandardHeaderClause(String clauseString)
+ private static ParsedHeaderClause parseStandardHeaderClause(String clauseString)
throws IllegalArgumentException
{
// Break string into semi-colon delimited pieces.
- String[] pieces = parseDelimitedString(
+ List<String> pieces = parseDelimitedString(
clauseString, FelixConstants.PACKAGE_SEPARATOR);
// Count the number of different paths; paths
@@ -1332,9 +1400,9 @@
// that paths come first, before directives and
// attributes.
int pathCount = 0;
- for (int pieceIdx = 0; pieceIdx < pieces.length; pieceIdx++)
+ for (int pieceIdx = 0; pieceIdx < pieces.size(); pieceIdx++)
{
- if (pieces[pieceIdx].indexOf('=') >= 0)
+ if (pieces.get(pieceIdx).indexOf('=') >= 0)
{
break;
}
@@ -1349,23 +1417,26 @@
}
// Create an array of paths.
- String[] paths = new String[pathCount];
- System.arraycopy(pieces, 0, paths, 0, pathCount);
+ List<String> paths = new ArrayList<String>(pathCount);
+ for (int pathIdx = 0; pathIdx < pathCount; pathIdx++)
+ {
+ paths.add(pieces.get(pathIdx));
+ }
// Parse the directives/attributes.
- Map dirsMap = new HashMap();
- Map attrsMap = new HashMap();
+ Map<String, Directive> dirsMap = new HashMap();
+ Map<String, Attribute> attrsMap = new HashMap();
int idx = -1;
String sep = null;
- for (int pieceIdx = pathCount; pieceIdx < pieces.length; pieceIdx++)
+ for (int pieceIdx = pathCount; pieceIdx < pieces.size(); pieceIdx++)
{
// Check if it is a directive.
- if ((idx = pieces[pieceIdx].indexOf(FelixConstants.DIRECTIVE_SEPARATOR)) >= 0)
+ if ((idx = pieces.get(pieceIdx).indexOf(FelixConstants.DIRECTIVE_SEPARATOR)) >= 0)
{
sep = FelixConstants.DIRECTIVE_SEPARATOR;
}
// Check if it is an attribute.
- else if ((idx = pieces[pieceIdx].indexOf(FelixConstants.ATTRIBUTE_SEPARATOR)) >= 0)
+ else if ((idx = pieces.get(pieceIdx).indexOf(FelixConstants.ATTRIBUTE_SEPARATOR)) >= 0)
{
sep = FelixConstants.ATTRIBUTE_SEPARATOR;
}
@@ -1375,8 +1446,8 @@
throw new IllegalArgumentException("Not a directive/attribute: " + clauseString);
}
- String key = pieces[pieceIdx].substring(0, idx).trim();
- String value = pieces[pieceIdx].substring(idx + sep.length()).trim();
+ String key = pieces.get(pieceIdx).substring(0, idx).trim();
+ String value = pieces.get(pieceIdx).substring(idx + sep.length()).trim();
// Remove quotes, if value is quoted.
if (value.startsWith("\"") && value.endsWith("\""))
@@ -1393,7 +1464,7 @@
throw new IllegalArgumentException(
"Duplicate directive: " + key);
}
- dirsMap.put(key, new R4Directive(key, value));
+ dirsMap.put(key, new Directive(key, value));
}
else
{
@@ -1403,25 +1474,22 @@
throw new IllegalArgumentException(
"Duplicate attribute: " + key);
}
- attrsMap.put(key, new R4Attribute(key, value, false));
+ attrsMap.put(key, new Attribute(key, value, false));
}
}
- // Create directive array.
- R4Directive[] dirs = (R4Directive[])
- dirsMap.values().toArray(new R4Directive[dirsMap.size()]);
-
- // Create attribute array.
- R4Attribute[] attrs = (R4Attribute[])
- attrsMap.values().toArray(new R4Attribute[attrsMap.size()]);
-
- // Create an array to hold the parsed paths, directives, and attributes.
- Object[][] clause = new Object[3][];
- clause[CLAUSE_PATHS_INDEX] = paths;
- clause[CLAUSE_DIRECTIVES_INDEX] = dirs;
- clause[CLAUSE_ATTRIBUTES_INDEX] = attrs;
+ List<Directive> dirs = new ArrayList<Directive>(dirsMap.size());
+ for (Entry<String, Directive> entry : dirsMap.entrySet())
+ {
+ dirs.add(entry.getValue());
+ }
+ List<Attribute> attrs = new ArrayList<Attribute>(attrsMap.size());
+ for (Entry<String, Attribute> entry : attrsMap.entrySet())
+ {
+ attrs.add(entry.getValue());
+ }
- return clause;
+ return new ParsedHeaderClause(paths, dirs, attrs);
}
/**
@@ -1433,14 +1501,14 @@
* @param delim the characters delimiting the tokens.
* @return an array of string tokens or null if there were no tokens.
**/
- public static String[] parseDelimitedString(String value, String delim)
+ public static List<String> parseDelimitedString(String value, String delim)
{
if (value == null)
{
value = "";
}
- List list = new ArrayList();
+ List<String> list = new ArrayList();
int CHAR = 1;
int DELIMITER = 2;
@@ -1489,7 +1557,7 @@
list.add(sb.toString().trim());
}
- return (String[]) list.toArray(new String[list.size()]);
+ return list;
}
/**
@@ -1499,22 +1567,23 @@
* @return an array of <tt>LibraryInfo</tt> objects for the
* passed in strings.
**/
- private static R4LibraryClause[] parseLibraryStrings(Logger logger, String[] libStrs)
+ private static List<R4LibraryClause> parseLibraryStrings(
+ Logger logger, List<String> libStrs)
throws IllegalArgumentException
{
if (libStrs == null)
{
- return new R4LibraryClause[0];
+ return new ArrayList<R4LibraryClause>(0);
}
- List libList = new ArrayList();
+ List<R4LibraryClause> libList = new ArrayList(libStrs.size());
- for (int i = 0; i < libStrs.length; i++)
+ for (int i = 0; i < libStrs.size(); i++)
{
- R4LibraryClause clause = R4LibraryClause.parse(logger, libStrs[i]);
+ R4LibraryClause clause = R4LibraryClause.parse(logger, libStrs.get(i));
libList.add(clause);
}
- return (R4LibraryClause[]) libList.toArray(new R4LibraryClause[libList.size()]);
+ return libList;
}
}