You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by gn...@apache.org on 2014/04/11 19:20:42 UTC
[20/33] Revert "[KARAF-2852] Merge features/core and features/command"
http://git-wip-us.apache.org/repos/asf/karaf/blob/0c8e8a81/features/src/main/java/org/apache/karaf/features/internal/resolver/ResolveContextImpl.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/resolver/ResolveContextImpl.java b/features/src/main/java/org/apache/karaf/features/internal/resolver/ResolveContextImpl.java
deleted file mode 100644
index e2ff793..0000000
--- a/features/src/main/java/org/apache/karaf/features/internal/resolver/ResolveContextImpl.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.features.internal.resolver;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.osgi.framework.Constants;
-import org.osgi.resource.Capability;
-import org.osgi.resource.Requirement;
-import org.osgi.resource.Resource;
-import org.osgi.resource.Wiring;
-import org.osgi.service.repository.Repository;
-import org.osgi.service.resolver.HostedCapability;
-import org.osgi.service.resolver.ResolveContext;
-
-/**
-*/
-public class ResolveContextImpl extends ResolveContext {
-
- private final Set<Resource> mandatory;
- private final Set<Resource> optional;
- private final Repository repository;
- private final Map<Resource, Wiring> wirings;
- private final boolean resolveOptional;
-
- private final CandidateComparator candidateComparator = new CandidateComparator();
-
- public ResolveContextImpl(Set<Resource> mandatory,
- Set<Resource> optional,
- Repository repository,
- boolean resolveOptional) {
- this.mandatory = mandatory;
- this.optional = optional;
- this.repository = repository;
- this.wirings = new HashMap<Resource, Wiring>();
- this.resolveOptional = resolveOptional;
- }
-
- @Override
- public Collection<Resource> getMandatoryResources() {
- return mandatory;
- }
-
- @Override
- public Collection<Resource> getOptionalResources() {
- return optional;
- }
-
- @Override
- public List<Capability> findProviders(Requirement requirement) {
- List<Capability> caps = new ArrayList<Capability>();
- Map<Requirement, Collection<Capability>> resMap =
- repository.findProviders(Collections.singleton(requirement));
- Collection<Capability> res = resMap != null ? resMap.get(requirement) : null;
- if (res != null) {
- caps.addAll(res);
- }
- Collections.sort(caps, candidateComparator);
- return caps;
- }
- @Override
- public int insertHostedCapability(List capabilities, HostedCapability hostedCapability) {
- for (int i=0; i < capabilities.size(); i++) {
- Capability cap = (Capability) capabilities.get(i);
- if (candidateComparator.compare(hostedCapability, cap) <= 0) {
- capabilities.add(i, hostedCapability);
- return i;
- }
- }
- capabilities.add(hostedCapability);
- return capabilities.size() - 1;
- }
- @Override
- public boolean isEffective(Requirement requirement) {
- return resolveOptional ||
- !Constants.RESOLUTION_OPTIONAL.equals(requirement.getDirectives().get(Constants.RESOLUTION_DIRECTIVE));
- }
- @Override
- public Map<Resource, Wiring> getWirings() {
- return wirings;
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0c8e8a81/features/src/main/java/org/apache/karaf/features/internal/resolver/ResourceBuilder.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/resolver/ResourceBuilder.java b/features/src/main/java/org/apache/karaf/features/internal/resolver/ResourceBuilder.java
deleted file mode 100644
index cb2c36a..0000000
--- a/features/src/main/java/org/apache/karaf/features/internal/resolver/ResourceBuilder.java
+++ /dev/null
@@ -1,1129 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.features.internal.resolver;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.felix.utils.version.VersionRange;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.Constants;
-import org.osgi.framework.Version;
-import org.osgi.framework.namespace.IdentityNamespace;
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.resource.Capability;
-import org.osgi.resource.Requirement;
-import org.osgi.resource.Resource;
-
-public class ResourceBuilder {
-
- public static final String RESOLUTION_DYNAMIC = "dynamic";
-
- public static Resource build(String uri, Map<String, String> headerMap)
- throws BundleException {
-
- // Verify that only manifest version 2 is specified.
- String manifestVersion = getManifestVersion(headerMap);
- if (manifestVersion == null || !manifestVersion.equals("2")) {
- throw new BundleException("Unsupported 'Bundle-ManifestVersion' value: " + manifestVersion);
- }
-
- //
- // Parse bundle version.
- //
-
- Version bundleVersion = Version.emptyVersion;
- if (headerMap.get(Constants.BUNDLE_VERSION) != null) {
- bundleVersion = Version.parseVersion(headerMap.get(Constants.BUNDLE_VERSION));
- }
-
- //
- // Parse bundle symbolic name.
- //
-
- String bundleSymbolicName = null;
- ParsedHeaderClause bundleCap = parseBundleSymbolicName(headerMap);
- if (bundleCap == null) {
- throw new BundleException("Bundle manifest must include bundle symbolic name");
- }
- bundleSymbolicName = (String) bundleCap.attrs.get(BundleRevision.BUNDLE_NAMESPACE);
-
- // Now that we have symbolic name and version, create the resource
- String type = headerMap.get(Constants.FRAGMENT_HOST) == null ? IdentityNamespace.TYPE_BUNDLE : IdentityNamespace.TYPE_FRAGMENT;
- ResourceImpl resource = new ResourceImpl(bundleSymbolicName, type, bundleVersion);
- if (uri != null) {
- Map<String, Object> attrs = new HashMap<String, Object>();
- attrs.put(UriNamespace.URI_NAMESPACE, uri);
- resource.addCapability(new CapabilityImpl(resource, UriNamespace.URI_NAMESPACE, Collections.<String, String>emptyMap(), attrs));
- }
-
- // Add a bundle and host capability to all
- // non-fragment bundles. A host capability is the same
- // as a require capability, but with a different capability
- // namespace. Bundle capabilities resolve required-bundle
- // dependencies, while host capabilities resolve fragment-host
- // dependencies.
- if (headerMap.get(Constants.FRAGMENT_HOST) == null) {
- // All non-fragment bundles have bundle capability.
- resource.addCapability(new CapabilityImpl(resource, BundleRevision.BUNDLE_NAMESPACE, bundleCap.dirs, bundleCap.attrs));
- // A non-fragment bundle can choose to not have a host capability.
- String attachment = bundleCap.dirs.get(Constants.FRAGMENT_ATTACHMENT_DIRECTIVE);
- attachment = (attachment == null) ? Constants.FRAGMENT_ATTACHMENT_RESOLVETIME : attachment;
- if (!attachment.equalsIgnoreCase(Constants.FRAGMENT_ATTACHMENT_NEVER)) {
- Map<String, Object> hostAttrs = new HashMap<String, Object>(bundleCap.attrs);
- Object value = hostAttrs.remove(BundleRevision.BUNDLE_NAMESPACE);
- hostAttrs.put(BundleRevision.HOST_NAMESPACE, value);
- resource.addCapability(new CapabilityImpl(
- resource, BundleRevision.HOST_NAMESPACE,
- bundleCap.dirs,
- hostAttrs));
- }
- }
-
- //
- // Parse Fragment-Host.
- //
-
- List<RequirementImpl> hostReqs = parseFragmentHost(resource, headerMap);
-
- //
- // Parse Require-Bundle
- //
-
- List<ParsedHeaderClause> rbClauses = parseStandardHeader(headerMap.get(Constants.REQUIRE_BUNDLE));
- rbClauses = normalizeRequireClauses(rbClauses);
- List<Requirement> rbReqs = convertRequires(rbClauses, resource);
-
- //
- // Parse Import-Package.
- //
-
- List<ParsedHeaderClause> importClauses = parseStandardHeader(headerMap.get(Constants.IMPORT_PACKAGE));
- importClauses = normalizeImportClauses(importClauses);
- List<Requirement> importReqs = convertImports(importClauses, resource);
-
- //
- // Parse DynamicImport-Package.
- //
-
- List<ParsedHeaderClause> dynamicClauses = parseStandardHeader(headerMap.get(Constants.DYNAMICIMPORT_PACKAGE));
- dynamicClauses = normalizeDynamicImportClauses(dynamicClauses);
- List<Requirement> dynamicReqs = convertImports(dynamicClauses, resource);
-
- //
- // Parse Require-Capability.
- //
-
- List<ParsedHeaderClause> requireClauses = parseStandardHeader(headerMap.get(Constants.REQUIRE_CAPABILITY));
- requireClauses = normalizeRequireCapabilityClauses(requireClauses);
- List<Requirement> requireReqs = convertRequireCapabilities(requireClauses, resource);
-
- //
- // Parse Export-Package.
- //
-
- List<ParsedHeaderClause> exportClauses = parseStandardHeader(headerMap.get(Constants.EXPORT_PACKAGE));
- exportClauses = normalizeExportClauses(exportClauses, bundleSymbolicName, bundleVersion);
- List<Capability> exportCaps = convertExports(exportClauses, resource);
-
- //
- // Parse Provide-Capability.
- //
-
- List<ParsedHeaderClause> provideClauses = parseStandardHeader(headerMap.get(Constants.PROVIDE_CAPABILITY));
- provideClauses = normalizeProvideCapabilityClauses(provideClauses);
- List<Capability> provideCaps = convertProvideCapabilities(provideClauses, resource);
-
- //
- // Parse Import-Service and Export-Service
- // if Require-Capability and Provide-Capability are not set for services
- //
-
- boolean hasServiceReferenceCapability = false;
- for (Capability cap : exportCaps) {
- hasServiceReferenceCapability |= ServiceNamespace.SERVICE_NAMESPACE.equals(cap.getNamespace());
- }
- if (!hasServiceReferenceCapability) {
- List<ParsedHeaderClause> exportServices = parseStandardHeader(headerMap.get(Constants.EXPORT_SERVICE));
- List<Capability> caps = convertExportService(exportServices, resource);
- provideCaps.addAll(caps);
- }
-
- boolean hasServiceReferenceRequirement = false;
- for (Requirement req : requireReqs) {
- hasServiceReferenceRequirement |= ServiceNamespace.SERVICE_NAMESPACE.equals(req.getNamespace());
- }
- if (!hasServiceReferenceRequirement) {
- List<ParsedHeaderClause> importServices = parseStandardHeader(headerMap.get(Constants.IMPORT_SERVICE));
- List<Requirement> reqs = convertImportService(importServices, resource);
- requireReqs.addAll(reqs);
- }
-
- // Combine all capabilities.
- resource.addCapabilities(exportCaps);
- resource.addCapabilities(provideCaps);
-
- // Combine all requirements.
- resource.addRequirements(hostReqs);
- resource.addRequirements(importReqs);
- resource.addRequirements(rbReqs);
- resource.addRequirements(requireReqs);
- resource.addRequirements(dynamicReqs);
-
- return resource;
- }
-
- public static List<Requirement> parseImport(Resource resource, String imports) throws BundleException {
- List<ParsedHeaderClause> importClauses = parseStandardHeader(imports);
- importClauses = normalizeImportClauses(importClauses);
- List<Requirement> importReqs = convertImports(importClauses, resource);
- return importReqs;
- }
-
- public static List<Requirement> parseRequirement(Resource resource, String requirement) throws BundleException {
- List<ParsedHeaderClause> requireClauses = parseStandardHeader(requirement);
- requireClauses = normalizeRequireCapabilityClauses(requireClauses);
- List<Requirement> requireReqs = convertRequireCapabilities(requireClauses, resource);
- return requireReqs;
- }
-
- public static List<Capability> parseExport(Resource resource, String bundleSymbolicName, Version bundleVersion, String exports) throws BundleException {
- List<ParsedHeaderClause> exportClauses = parseStandardHeader(exports);
- exportClauses = normalizeExportClauses(exportClauses, bundleSymbolicName, bundleVersion);
- List<Capability> exportCaps = convertExports(exportClauses, resource);
- return exportCaps;
- }
-
- public static List<Capability> parseCapability(Resource resource, String capability) throws BundleException {
- List<ParsedHeaderClause> provideClauses = parseStandardHeader(capability);
- provideClauses = normalizeProvideCapabilityClauses(provideClauses);
- List<Capability> provideCaps = convertProvideCapabilities(provideClauses, resource);
- return provideCaps;
- }
-
- @SuppressWarnings( "deprecation" )
- private static List<ParsedHeaderClause> normalizeImportClauses(
- List<ParsedHeaderClause> clauses)
- throws BundleException {
- // Verify that the values are equals if the package specifies
- // both version and specification-version attributes.
- Set<String> dupeSet = new HashSet<String>();
- for (ParsedHeaderClause clause : clauses) {
- // Check for "version" and "specification-version" attributes
- // and verify they are the same if both are specified.
- Object v = clause.attrs.get(Constants.VERSION_ATTRIBUTE);
- Object sv = clause.attrs.get(Constants.PACKAGE_SPECIFICATION_VERSION);
- if ((v != null) && (sv != null)) {
- // Verify they are equal.
- if (!((String) v).trim().equals(((String) sv).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)) {
- clause.attrs.remove(Constants.PACKAGE_SPECIFICATION_VERSION);
- v = (v == null) ? sv : v;
- clause.attrs.put(Constants.VERSION_ATTRIBUTE, VersionRange.parseVersionRange(v.toString()));
- }
-
- // If bundle version is specified, then convert its type to VersionRange.
- v = clause.attrs.get(Constants.BUNDLE_VERSION_ATTRIBUTE);
- if (v != null) {
- clause.attrs.put(Constants.BUNDLE_VERSION_ATTRIBUTE, VersionRange.parseVersionRange(v.toString()));
- }
-
- // Verify java.* is not imported, nor any duplicate imports.
- for (String pkgName : clause.paths) {
- if (!dupeSet.contains(pkgName)) {
- // Verify that java.* packages are not imported.
- if (pkgName.startsWith("java.")) {
- throw new BundleException("Importing java.* packages not allowed: " + pkgName);
- }
- // The character "." has no meaning in the OSGi spec except
- // when placed on the bundle class path. Some people, however,
- // mistakenly think it means the default package when imported
- // or exported. This is not correct. It is invalid.
- else if (pkgName.equals(".")) {
- throw new BundleException("Importing '.' is invalid.");
- }
- // Make sure a package name was specified.
- else if (pkgName.length() == 0) {
- throw new BundleException(
- "Imported package names cannot be zero length.");
- }
- dupeSet.add(pkgName);
- } else {
- throw new BundleException("Duplicate import: " + pkgName);
- }
- }
- }
-
- return clauses;
- }
-
- private static List<Capability> convertExportService(List<ParsedHeaderClause> clauses, Resource resource) {
- List<Capability> capList = new ArrayList<Capability>();
- for (ParsedHeaderClause clause : clauses) {
- for (String path : clause.paths) {
- Map<String, String> dirs = new LinkedHashMap<String, String>();
- dirs.put(ServiceNamespace.CAPABILITY_EFFECTIVE_DIRECTIVE, ServiceNamespace.EFFECTIVE_ACTIVE);
- Map<String, Object> attrs = new LinkedHashMap<String, Object>();
- attrs.put(Constants.OBJECTCLASS, path);
- attrs.putAll(clause.attrs);
- capList.add(new CapabilityImpl(
- resource,
- ServiceNamespace.SERVICE_NAMESPACE,
- dirs,
- attrs));
- }
- }
- return capList;
- }
-
- private static List<Requirement> convertImportService(List<ParsedHeaderClause> clauses, Resource resource) throws BundleException {
- try {
- List<Requirement> reqList = new ArrayList<Requirement>();
- for (ParsedHeaderClause clause : clauses) {
- for (String path : clause.paths) {
- String multiple = clause.dirs.get("multiple");
- String avail = clause.dirs.get("availability");
- String filter = (String) clause.attrs.get("filter");
- Map<String, String> dirs = new LinkedHashMap<String, String>();
- dirs.put(ServiceNamespace.REQUIREMENT_EFFECTIVE_DIRECTIVE, ServiceNamespace.EFFECTIVE_ACTIVE);
- if ("optional".equals(avail)) {
- dirs.put(ServiceNamespace.REQUIREMENT_RESOLUTION_DIRECTIVE, ServiceNamespace.RESOLUTION_OPTIONAL);
- }
- if ("true".equals(multiple)) {
- dirs.put(ServiceNamespace.REQUIREMENT_CARDINALITY_DIRECTIVE, ServiceNamespace.CARDINALITY_MULTIPLE);
- }
- if (filter == null) {
- filter = "(" + Constants.OBJECTCLASS + "=" + path + ")";
- } else if (!filter.startsWith("(") && !filter.endsWith(")")) {
- filter = "(&(" + Constants.OBJECTCLASS + "=" + path + ")(" + filter + "))";
- } else {
- filter = "(&(" + Constants.OBJECTCLASS + "=" + path + ")" + filter + ")";
- }
- dirs.put(ServiceNamespace.REQUIREMENT_FILTER_DIRECTIVE, filter);
- reqList.add(new RequirementImpl(
- resource,
- ServiceNamespace.SERVICE_NAMESPACE,
- dirs,
- Collections.<String, Object>emptyMap(),
- SimpleFilter.parse(filter)));
- }
- }
- return reqList;
- } catch (Exception ex) {
- throw new BundleException("Error creating requirement: " + ex, ex);
- }
- }
-
- private static List<Requirement> convertImports(List<ParsedHeaderClause> clauses, Resource resource) {
- // Now convert generic header clauses into requirements.
- List<Requirement> reqList = new ArrayList<Requirement>();
- for (ParsedHeaderClause clause : clauses) {
- for (String path : clause.paths) {
- // Prepend the package name to the array of attributes.
- Map<String, Object> attrs = clause.attrs;
- // Note that we use a linked hash map here to ensure the
- // package attribute is first, which will make indexing
- // more efficient.
- // TODO: OSGi R4.3 - This is ordering is kind of hacky.
- // Prepend the package name to the array of attributes.
- Map<String, Object> newAttrs = new LinkedHashMap<String, Object>(attrs.size() + 1);
- // We want this first from an indexing perspective.
- newAttrs.put(BundleRevision.PACKAGE_NAMESPACE, path);
- newAttrs.putAll(attrs);
- // But we need to put it again to make sure it wasn't overwritten.
- newAttrs.put(BundleRevision.PACKAGE_NAMESPACE, path);
-
- // Create filter now so we can inject filter directive.
- SimpleFilter sf = SimpleFilter.convert(newAttrs);
-
- // Inject filter directive.
- // TODO: OSGi R4.3 - Can we insert this on demand somehow?
- Map<String, String> dirs = clause.dirs;
- Map<String, String> newDirs = new HashMap<String, String>(dirs.size() + 1);
- newDirs.putAll(dirs);
- newDirs.put(Constants.FILTER_DIRECTIVE, sf.toString());
-
- // Create package requirement and add to requirement list.
- reqList.add(
- new RequirementImpl(
- resource,
- BundleRevision.PACKAGE_NAMESPACE,
- newDirs,
- Collections.<String, Object>emptyMap(),
- sf));
- }
- }
-
- return reqList;
- }
-
- @SuppressWarnings( "deprecation" )
- private static List<ParsedHeaderClause> normalizeDynamicImportClauses(
- List<ParsedHeaderClause> clauses)
- throws BundleException {
- // Verify that the values are equals if the package specifies
- // both version and specification-version attributes.
- for (ParsedHeaderClause clause : clauses) {
- // Add the resolution directive to indicate that these are
- // dynamic imports.
- clause.dirs.put(Constants.RESOLUTION_DIRECTIVE, RESOLUTION_DYNAMIC);
-
- // Check for "version" and "specification-version" attributes
- // and verify they are the same if both are specified.
- Object v = clause.attrs.get(Constants.VERSION_ATTRIBUTE);
- Object sv = clause.attrs.get(Constants.PACKAGE_SPECIFICATION_VERSION);
- if ((v != null) && (sv != null)) {
- // Verify they are equal.
- if (!((String) v).trim().equals(((String) sv).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)) {
- clause.attrs.remove(Constants.PACKAGE_SPECIFICATION_VERSION);
- v = (v == null) ? sv : v;
- clause.attrs.put(Constants.VERSION_ATTRIBUTE, VersionRange.parseVersionRange(v.toString()));
- }
-
- // If bundle version is specified, then convert its type to VersionRange.
- v = clause.attrs.get(Constants.BUNDLE_VERSION_ATTRIBUTE);
- if (v != null) {
- clause.attrs.put(Constants.BUNDLE_VERSION_ATTRIBUTE, VersionRange.parseVersionRange(v.toString()));
- }
-
- // Dynamic imports can have duplicates, so verify that java.*
- // packages are not imported.
- for (String pkgName : clause.paths) {
- 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);
- }
- }
- }
-
- return clauses;
- }
-
- private static List<ParsedHeaderClause> normalizeRequireCapabilityClauses(
- List<ParsedHeaderClause> clauses)
- throws BundleException {
-
- return clauses;
- }
-
- private static List<ParsedHeaderClause> normalizeProvideCapabilityClauses(
- List<ParsedHeaderClause> clauses)
- throws BundleException
- {
-
- // Convert attributes into specified types.
- for (ParsedHeaderClause clause : clauses)
- {
- for (Map.Entry<String, String> entry : clause.types.entrySet())
- {
- String type = entry.getValue();
- if (!type.equals("String"))
- {
- if (type.equals("Double"))
- {
- clause.attrs.put(
- entry.getKey(),
- new Double(clause.attrs.get(entry.getKey()).toString().trim()));
- }
- else if (type.equals("Version"))
- {
- clause.attrs.put(
- entry.getKey(),
- new Version(clause.attrs.get(entry.getKey()).toString().trim()));
- }
- else if (type.equals("Long"))
- {
- clause.attrs.put(
- entry.getKey(),
- new Long(clause.attrs.get(entry.getKey()).toString().trim()));
- }
- else if (type.startsWith("List"))
- {
- int startIdx = type.indexOf('<');
- int endIdx = type.indexOf('>');
- if (((startIdx > 0) && (endIdx <= startIdx))
- || ((startIdx < 0) && (endIdx > 0)))
- {
- throw new BundleException(
- "Invalid Provide-Capability attribute list type for '"
- + entry.getKey()
- + "' : "
- + type);
- }
-
- String listType = "String";
- if (endIdx > startIdx)
- {
- listType = type.substring(startIdx + 1, endIdx).trim();
- }
-
- List<String> tokens = parseDelimitedString(
- clause.attrs.get(entry.getKey()).toString(), ",", false);
- List<Object> values = new ArrayList<Object>(tokens.size());
- for (String token : tokens)
- {
- if (listType.equals("String"))
- {
- values.add(token);
- }
- else if (listType.equals("Double"))
- {
- values.add(new Double(token.trim()));
- }
- else if (listType.equals("Version"))
- {
- values.add(new Version(token.trim()));
- }
- else if (listType.equals("Long"))
- {
- values.add(new Long(token.trim()));
- }
- else
- {
- throw new BundleException(
- "Unknown Provide-Capability attribute list type for '"
- + entry.getKey()
- + "' : "
- + type);
- }
- }
- clause.attrs.put(
- entry.getKey(),
- values);
- }
- else
- {
- throw new BundleException(
- "Unknown Provide-Capability attribute type for '"
- + entry.getKey()
- + "' : "
- + type);
- }
- }
- }
- }
-
- return clauses;
- }
-
- private static List<Requirement> convertRequireCapabilities(
- List<ParsedHeaderClause> clauses, Resource resource)
- throws BundleException {
- // Now convert generic header clauses into requirements.
- List<Requirement> reqList = new ArrayList<Requirement>();
- for (ParsedHeaderClause clause : clauses) {
- try {
- String filterStr = clause.dirs.get(Constants.FILTER_DIRECTIVE);
- SimpleFilter sf = (filterStr != null)
- ? SimpleFilter.parse(filterStr)
- : new SimpleFilter(null, null, SimpleFilter.MATCH_ALL);
- for (String path : clause.paths) {
- // Create requirement and add to requirement list.
- reqList.add(new RequirementImpl(
- resource, path, clause.dirs, clause.attrs, sf));
- }
- } catch (Exception ex) {
- throw new BundleException("Error creating requirement: " + ex, ex);
- }
- }
-
- return reqList;
- }
-
- private static List<Capability> convertProvideCapabilities(
- List<ParsedHeaderClause> clauses, Resource resource)
- throws BundleException {
- List<Capability> capList = new ArrayList<Capability>();
- for (ParsedHeaderClause clause : clauses) {
- for (String path : clause.paths) {
- if (path.startsWith("osgi.wiring.")) {
-// throw new BundleException("Manifest cannot use Provide-Capability for '" + path + "' namespace.");
- }
-
- // Create package capability and add to capability list.
- capList.add(new CapabilityImpl(resource, path, clause.dirs, clause.attrs));
- }
- }
-
- return capList;
- }
-
- @SuppressWarnings( "deprecation" )
- private static List<ParsedHeaderClause> normalizeExportClauses(
- List<ParsedHeaderClause> clauses,
- String bsn, Version bv)
- throws BundleException {
- // Verify that "java.*" packages are not exported.
- for (ParsedHeaderClause clause : clauses) {
- // Verify that the named package has not already been declared.
- for (String pkgName : clause.paths) {
- // Verify that java.* packages are not exported.
- if (pkgName.startsWith("java.")) {
- throw new BundleException("Exporting java.* packages not allowed: " + pkgName);
- }
- // The character "." has no meaning in the OSGi spec except
- // when placed on the bundle class path. Some people, however,
- // mistakenly think it means the default package when imported
- // or exported. This is not correct. It is invalid.
- else if (pkgName.equals(".")) {
- throw new BundleException("Exporing '.' is invalid.");
- }
- // Make sure a package name was specified.
- else if (pkgName.length() == 0) {
- throw new BundleException("Exported package names cannot be zero length.");
- }
- }
-
- // Check for "version" and "specification-version" attributes
- // and verify they are the same if both are specified.
- Object v = clause.attrs.get(Constants.VERSION_ATTRIBUTE);
- Object sv = clause.attrs.get(Constants.PACKAGE_SPECIFICATION_VERSION);
- if ((v != null) && (sv != null)) {
- // Verify they are equal.
- if (!((String) v).trim().equals(((String) sv).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 = Version.emptyVersion;
- }
-
- // 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.
- clause.attrs.remove(Constants.PACKAGE_SPECIFICATION_VERSION);
- v = (v == null) ? sv : v;
- clause.attrs.put(Constants.VERSION_ATTRIBUTE, Version.parseVersion(v.toString()));
- }
-
- // Find symbolic name and version attribute, if present.
- if (clause.attrs.containsKey(Constants.BUNDLE_VERSION_ATTRIBUTE)
- || clause.attrs.containsKey(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.
- clause.attrs.put(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, bsn);
- clause.attrs.put(Constants.BUNDLE_VERSION_ATTRIBUTE, bv);
- }
-
- return clauses;
- }
-
- private static List<Capability> convertExports(
- List<ParsedHeaderClause> clauses, Resource resource) {
- List<Capability> capList = new ArrayList<Capability>();
- for (ParsedHeaderClause clause : clauses) {
- for (String pkgName : clause.paths) {
- // Prepend the package name to the array of attributes.
- Map<String, Object> attrs = clause.attrs;
- Map<String, Object> newAttrs = new HashMap<String, Object>(attrs.size() + 1);
- newAttrs.putAll(attrs);
- newAttrs.put(BundleRevision.PACKAGE_NAMESPACE, pkgName);
-
- // Create package capability and add to capability list.
- capList.add(new CapabilityImpl(resource, BundleRevision.PACKAGE_NAMESPACE, clause.dirs, newAttrs));
- }
- }
-
- return capList;
- }
-
- private static String getManifestVersion(Map<String, String> headerMap) {
- String manifestVersion = headerMap.get(Constants.BUNDLE_MANIFESTVERSION);
- return (manifestVersion == null) ? "1" : manifestVersion.trim();
- }
-
- private static List<ParsedHeaderClause> calculateImplicitImports(
- List<BundleCapability> exports, List<ParsedHeaderClause> imports)
- throws BundleException {
- List<ParsedHeaderClause> clauseList = new ArrayList<ParsedHeaderClause>();
-
- // Since all R3 exports imply an import, add a corresponding
- // requirement for each existing export capability. Do not
- // duplicate imports.
- Map<String, String> map = new HashMap<String, String>();
- // Add existing imports.
- for (ParsedHeaderClause anImport : imports) {
- for (int pathIdx = 0; pathIdx < anImport.paths.size(); pathIdx++) {
- map.put(anImport.paths.get(pathIdx), anImport.paths.get(pathIdx));
- }
- }
- // Add import requirement for each export capability.
- for (BundleCapability export : exports) {
- if (map.get(export.getAttributes().get(BundleRevision.PACKAGE_NAMESPACE).toString()) == null) {
- // Convert Version to VersionRange.
- Object version = export.getAttributes().get(Constants.VERSION_ATTRIBUTE);
- ParsedHeaderClause clause = new ParsedHeaderClause();
- if (version != null) {
- clause.attrs.put(Constants.VERSION_ATTRIBUTE, VersionRange.parseVersionRange(version.toString()));
- }
- clause.paths.add((String) export.getAttributes().get(BundleRevision.PACKAGE_NAMESPACE));
- clauseList.add(clause);
- }
- }
-
- 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 (ParsedHeaderClause anImport : imports) {
- for (int pathIdx = 0; pathIdx < anImport.paths.size(); pathIdx++) {
- usesValue = usesValue
- + ((usesValue.length() > 0) ? "," : "")
- + anImport.paths.get(pathIdx);
- }
- }
- for (int i = 0; i < exports.size(); i++) {
- Map<String, String> dirs = new HashMap<String, String>(1);
- dirs.put(Constants.USES_DIRECTIVE, usesValue);
- exports.set(i, new CapabilityImpl(
- exports.get(i).getResource(),
- BundleRevision.PACKAGE_NAMESPACE,
- dirs,
- exports.get(i).getAttributes()));
- }
-
- return exports;
- }
-
- private static ParsedHeaderClause parseBundleSymbolicName(Map<String, String> headerMap)
- throws BundleException {
- List<ParsedHeaderClause> clauses = parseStandardHeader(headerMap.get(Constants.BUNDLE_SYMBOLICNAME));
- if (clauses.size() > 0) {
- if (clauses.size() > 1 || clauses.get(0).paths.size() > 1) {
- throw new BundleException("Cannot have multiple symbolic names: " + headerMap.get(Constants.BUNDLE_SYMBOLICNAME));
- }
-
- // Get bundle version.
- Version bundleVersion = Version.emptyVersion;
- if (headerMap.get(Constants.BUNDLE_VERSION) != null) {
- bundleVersion = Version.parseVersion(headerMap.get(Constants.BUNDLE_VERSION));
- }
-
- // Create a require capability and return it.
- ParsedHeaderClause clause = clauses.get(0);
- String symName = clause.paths.get(0);
- clause.attrs.put(BundleRevision.BUNDLE_NAMESPACE, symName);
- clause.attrs.put(Constants.BUNDLE_VERSION_ATTRIBUTE, bundleVersion);
- return clause;
- }
-
- return null;
- }
-
- private static List<RequirementImpl> parseFragmentHost(
- Resource resource, Map<String, String> headerMap)
- throws BundleException {
- List<RequirementImpl> reqs = new ArrayList<RequirementImpl>();
-
- List<ParsedHeaderClause> clauses = parseStandardHeader(headerMap.get(Constants.FRAGMENT_HOST));
- if (clauses.size() > 0) {
- // Make sure that only one fragment host symbolic name is specified.
- if (clauses.size() > 1 || clauses.get(0).paths.size() > 1) {
- throw new BundleException("Fragments cannot have multiple hosts: " + headerMap.get(Constants.FRAGMENT_HOST));
- }
-
- // If the bundle-version attribute is specified, then convert
- // it to the proper type.
- Object value = clauses.get(0).attrs.get(Constants.BUNDLE_VERSION_ATTRIBUTE);
- value = (value == null) ? "0.0.0" : value;
- clauses.get(0).attrs.put(Constants.BUNDLE_VERSION_ATTRIBUTE, VersionRange.parseVersionRange(value.toString()));
-
- // Note that we use a linked hash map here to ensure the
- // host symbolic name is first, which will make indexing
- // more efficient.
- // TODO: OSGi R4.3 - This is ordering is kind of hacky.
- // Prepend the host symbolic name to the map of attributes.
- Map<String, Object> attrs = clauses.get(0).attrs;
- Map<String, Object> newAttrs = new LinkedHashMap<String, Object>(attrs.size() + 1);
- // We want this first from an indexing perspective.
- newAttrs.put(BundleRevision.HOST_NAMESPACE, clauses.get(0).paths.get(0));
- newAttrs.putAll(attrs);
- // But we need to put it again to make sure it wasn't overwritten.
- newAttrs.put(BundleRevision.HOST_NAMESPACE, clauses.get(0).paths.get(0));
-
- // Create filter now so we can inject filter directive.
- SimpleFilter sf = SimpleFilter.convert(newAttrs);
-
- // Inject filter directive.
- // TODO: OSGi R4.3 - Can we insert this on demand somehow?
- Map<String, String> dirs = clauses.get(0).dirs;
- Map<String, String> newDirs = new HashMap<String, String>(dirs.size() + 1);
- newDirs.putAll(dirs);
- newDirs.put(Constants.FILTER_DIRECTIVE, sf.toString());
-
- reqs.add(new RequirementImpl(
- resource, BundleRevision.HOST_NAMESPACE,
- newDirs,
- newAttrs));
- }
-
- return reqs;
- }
-
- private static List<ParsedHeaderClause> normalizeRequireClauses(List<ParsedHeaderClause> clauses) {
- // Convert bundle version attribute to VersionRange type.
- for (ParsedHeaderClause clause : clauses) {
- Object value = clause.attrs.get(Constants.BUNDLE_VERSION_ATTRIBUTE);
- if (value != null) {
- clause.attrs.put(Constants.BUNDLE_VERSION_ATTRIBUTE, VersionRange.parseVersionRange(value.toString()));
- }
- }
-
- return clauses;
- }
-
- private static List<Requirement> convertRequires(List<ParsedHeaderClause> clauses, Resource resource) {
- List<Requirement> reqList = new ArrayList<Requirement>();
- for (ParsedHeaderClause clause : clauses) {
- for (String path : clause.paths) {
- // Prepend the bundle symbolic name to the array of attributes.
- Map<String, Object> attrs = clause.attrs;
- // Note that we use a linked hash map here to ensure the
- // symbolic name attribute is first, which will make indexing
- // more efficient.
- // TODO: OSGi R4.3 - This is ordering is kind of hacky.
- // Prepend the symbolic name to the array of attributes.
- Map<String, Object> newAttrs = new LinkedHashMap<String, Object>(attrs.size() + 1);
- // We want this first from an indexing perspective.
- newAttrs.put(BundleRevision.BUNDLE_NAMESPACE, path);
- newAttrs.putAll(attrs);
- // But we need to put it again to make sure it wasn't overwritten.
- newAttrs.put(BundleRevision.BUNDLE_NAMESPACE, path);
-
- // Create filter now so we can inject filter directive.
- SimpleFilter sf = SimpleFilter.convert(newAttrs);
-
- // Inject filter directive.
- // TODO: OSGi R4.3 - Can we insert this on demand somehow?
- Map<String, String> dirs = clause.dirs;
- Map<String, String> newDirs = new HashMap<String, String>(dirs.size() + 1);
- newDirs.putAll(dirs);
- newDirs.put(Constants.FILTER_DIRECTIVE, sf.toString());
-
- // Create package requirement and add to requirement list.
- reqList.add(new RequirementImpl(resource, BundleRevision.BUNDLE_NAMESPACE, newDirs, newAttrs));
- }
- }
-
- return reqList;
- }
-
- private static final char EOF = (char) -1;
-
- private static char charAt(int pos, String headers, int length)
- {
- if (pos >= length)
- {
- return EOF;
- }
- return headers.charAt(pos);
- }
-
- private static final int CLAUSE_START = 0;
- private static final int PARAMETER_START = 1;
- private static final int KEY = 2;
- private static final int DIRECTIVE_OR_TYPEDATTRIBUTE = 4;
- private static final int ARGUMENT = 8;
- private static final int VALUE = 16;
-
- @SuppressWarnings({ "unchecked", "rawtypes" })
- private static List<ParsedHeaderClause> parseStandardHeader(String header)
- {
- List<ParsedHeaderClause> clauses = new ArrayList<ParsedHeaderClause>();
- if (header == null)
- {
- return clauses;
- }
- ParsedHeaderClause clause = null;
- String key = null;
- Map targetMap = null;
- int state = CLAUSE_START;
- int currentPosition = 0;
- int startPosition = 0;
- int length = header.length();
- boolean quoted = false;
- boolean escaped = false;
-
- char currentChar = EOF;
- do
- {
- currentChar = charAt(currentPosition, header, length);
- switch (state)
- {
- case CLAUSE_START:
- clause = new ParsedHeaderClause();
- clauses.add(clause);
- state = PARAMETER_START;
- case PARAMETER_START:
- startPosition = currentPosition;
- state = KEY;
- case KEY:
- switch (currentChar)
- {
- case ':':
- case '=':
- key = header.substring(startPosition, currentPosition).trim();
- startPosition = currentPosition + 1;
- targetMap = clause.attrs;
- state = currentChar == ':' ? DIRECTIVE_OR_TYPEDATTRIBUTE : ARGUMENT;
- break;
- case EOF:
- case ',':
- case ';':
- clause.paths.add(header.substring(startPosition, currentPosition).trim());
- state = currentChar == ',' ? CLAUSE_START : PARAMETER_START;
- break;
- default:
- break;
- }
- currentPosition++;
- break;
- case DIRECTIVE_OR_TYPEDATTRIBUTE:
- switch(currentChar)
- {
- case '=':
- if (startPosition != currentPosition)
- {
- clause.types.put(key, header.substring(startPosition, currentPosition).trim());
- }
- else
- {
- targetMap = clause.dirs;
- }
- state = ARGUMENT;
- startPosition = currentPosition + 1;
- break;
- default:
- break;
- }
- currentPosition++;
- break;
- case ARGUMENT:
- if (currentChar == '\"')
- {
- quoted = true;
- currentPosition++;
- }
- else
- {
- quoted = false;
- }
- if (!Character.isWhitespace(currentChar)) {
- state = VALUE;
- }
- else {
- currentPosition++;
- }
- break;
- case VALUE:
- if (escaped)
- {
- escaped = false;
- }
- else
- {
- if (currentChar == '\\' )
- {
- escaped = true;
- }
- else if (quoted && currentChar == '\"')
- {
- quoted = false;
- }
- else if (!quoted)
- {
- String value = null;
- switch(currentChar)
- {
- case EOF:
- case ';':
- case ',':
- value = header.substring(startPosition, currentPosition).trim();
- if (value.startsWith("\"") && value.endsWith("\""))
- {
- value = value.substring(1, value.length() - 1);
- }
- if (targetMap.put(key, value) != null)
- {
- throw new IllegalArgumentException(
- "Duplicate '" + key + "' in: " + header);
- }
- state = currentChar == ';' ? PARAMETER_START : CLAUSE_START;
- break;
- default:
- break;
- }
- }
- }
- currentPosition++;
- break;
- default:
- break;
- }
- } while ( currentChar != EOF);
-
- if (state > PARAMETER_START)
- {
- throw new IllegalArgumentException("Unable to parse header: " + header);
- }
- return clauses;
- }
-
- public static List<String> parseDelimitedString(String value, String delim)
- {
- return parseDelimitedString(value, delim, true);
- }
-
- /**
- * Parses delimited string and returns an array containing the tokens. This
- * parser obeys quotes, so the delimiter character will be ignored if it is
- * inside of a quote. This method assumes that the quote character is not
- * included in the set of delimiter characters.
- * @param value the delimited string to parse.
- * @param delim the characters delimiting the tokens.
- * @return a list of string or an empty list if there are none.
- **/
- public static List<String> parseDelimitedString(String value, String delim, boolean trim)
- {
- if (value == null)
- {
- value = "";
- }
-
- List<String> list = new ArrayList();
-
- int CHAR = 1;
- int DELIMITER = 2;
- int STARTQUOTE = 4;
- int ENDQUOTE = 8;
-
- StringBuffer sb = new StringBuffer();
-
- int expecting = (CHAR | DELIMITER | STARTQUOTE);
-
- boolean isEscaped = false;
- for (int i = 0; i < value.length(); i++)
- {
- char c = value.charAt(i);
-
- boolean isDelimiter = (delim.indexOf(c) >= 0);
-
- if (!isEscaped && (c == '\\'))
- {
- isEscaped = true;
- continue;
- }
-
- if (isEscaped)
- {
- sb.append(c);
- }
- else if (isDelimiter && ((expecting & DELIMITER) > 0))
- {
- if (trim)
- {
- list.add(sb.toString().trim());
- }
- else
- {
- list.add(sb.toString());
- }
- sb.delete(0, sb.length());
- expecting = (CHAR | DELIMITER | STARTQUOTE);
- }
- else if ((c == '"') && ((expecting & STARTQUOTE) > 0))
- {
- sb.append(c);
- expecting = CHAR | ENDQUOTE;
- }
- else if ((c == '"') && ((expecting & ENDQUOTE) > 0))
- {
- sb.append(c);
- expecting = (CHAR | STARTQUOTE | DELIMITER);
- }
- else if ((expecting & CHAR) > 0)
- {
- sb.append(c);
- }
- else
- {
- throw new IllegalArgumentException("Invalid delimited string: " + value);
- }
-
- isEscaped = false;
- }
-
- if (sb.length() > 0)
- {
- if (trim)
- {
- list.add(sb.toString().trim());
- }
- else
- {
- list.add(sb.toString());
- }
- }
-
- return list;
- }
-
-
- static class ParsedHeaderClause {
- public final List<String> paths = new ArrayList<String>();
- public final Map<String, String> dirs = new LinkedHashMap<String, String>();
- public final Map<String, Object> attrs = new LinkedHashMap<String, Object>();
- public final Map<String, String> types = new LinkedHashMap<String, String>();
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0c8e8a81/features/src/main/java/org/apache/karaf/features/internal/resolver/ResourceImpl.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/resolver/ResourceImpl.java b/features/src/main/java/org/apache/karaf/features/internal/resolver/ResourceImpl.java
deleted file mode 100644
index 18e0dc3..0000000
--- a/features/src/main/java/org/apache/karaf/features/internal/resolver/ResourceImpl.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.features.internal.resolver;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.osgi.framework.Version;
-import org.osgi.framework.namespace.IdentityNamespace;
-import org.osgi.resource.Capability;
-import org.osgi.resource.Requirement;
-import org.osgi.resource.Resource;
-
-/**
- */
-public class ResourceImpl implements Resource {
-
- private final List<Capability> m_caps;
- private final List<Requirement> m_reqs;
-
- public ResourceImpl(String name, Version version) {
- this(name, IdentityNamespace.TYPE_BUNDLE, version);
- }
-
- public ResourceImpl(String name, String type, Version version)
- {
- m_caps = new ArrayList<Capability>();
- m_caps.add(0, new IdentityCapability(this, name, type, version));
- m_reqs = new ArrayList<Requirement>();
- }
-
- public void addCapability(Capability capability) {
- assert capability.getResource() == this;
- m_caps.add(capability);
- }
-
- public void addCapabilities(Iterable<? extends Capability> capabilities) {
- for (Capability cap : capabilities) {
- addCapability(cap);
- }
- }
-
- public void addRequirement(Requirement requirement) {
- assert requirement.getResource() == this;
- m_reqs.add(requirement);
- }
-
- public void addRequirements(Iterable<? extends Requirement> requirements) {
- for (Requirement req : requirements) {
- addRequirement(req);
- }
- }
-
- public List<Capability> getCapabilities(String namespace)
- {
- List<Capability> result = m_caps;
- if (namespace != null)
- {
- result = new ArrayList<Capability>();
- for (Capability cap : m_caps)
- {
- if (cap.getNamespace().equals(namespace))
- {
- result.add(cap);
- }
- }
- }
- return result;
- }
-
- public List<Requirement> getRequirements(String namespace)
- {
- List<Requirement> result = m_reqs;
- if (namespace != null)
- {
- result = new ArrayList<Requirement>();
- for (Requirement req : m_reqs)
- {
- if (req.getNamespace().equals(namespace))
- {
- result.add(req);
- }
- }
- }
- return result;
- }
-
- @Override
- public String toString()
- {
- Capability cap = getCapabilities(IdentityNamespace.IDENTITY_NAMESPACE).get(0);
- return cap.getAttributes().get(IdentityNamespace.IDENTITY_NAMESPACE) + "/"
- + cap.getAttributes().get(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0c8e8a81/features/src/main/java/org/apache/karaf/features/internal/resolver/ServiceNamespace.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/resolver/ServiceNamespace.java b/features/src/main/java/org/apache/karaf/features/internal/resolver/ServiceNamespace.java
deleted file mode 100644
index 4fe3bf8..0000000
--- a/features/src/main/java/org/apache/karaf/features/internal/resolver/ServiceNamespace.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.features.internal.resolver;
-
-import org.osgi.resource.Namespace;
-
-/**
- */
-public final class ServiceNamespace extends Namespace {
-
- public static final String SERVICE_NAMESPACE = "service-reference";
-
- private ServiceNamespace() {
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0c8e8a81/features/src/main/java/org/apache/karaf/features/internal/resolver/SimpleFilter.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/resolver/SimpleFilter.java b/features/src/main/java/org/apache/karaf/features/internal/resolver/SimpleFilter.java
deleted file mode 100644
index ae10441..0000000
--- a/features/src/main/java/org/apache/karaf/features/internal/resolver/SimpleFilter.java
+++ /dev/null
@@ -1,649 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.features.internal.resolver;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import org.apache.felix.utils.version.VersionRange;
-
-public class SimpleFilter
-{
- public static final int MATCH_ALL = 0;
- public static final int AND = 1;
- public static final int OR = 2;
- public static final int NOT = 3;
- public static final int EQ = 4;
- public static final int LTE = 5;
- public static final int GTE = 6;
- public static final int SUBSTRING = 7;
- public static final int PRESENT = 8;
- public static final int APPROX = 9;
-
- private final String m_name;
- private final Object m_value;
- private final int m_op;
-
- public SimpleFilter(String attr, Object value, int op)
- {
- m_name = attr;
- m_value = value;
- m_op = op;
- }
-
- public String getName()
- {
- return m_name;
- }
-
- public Object getValue()
- {
- return m_value;
- }
-
- public int getOperation()
- {
- return m_op;
- }
-
- public String toString()
- {
- String s = null;
- switch (m_op)
- {
- case AND:
- s = "(&" + toString((List) m_value) + ")";
- break;
- case OR:
- s = "(|" + toString((List) m_value) + ")";
- break;
- case NOT:
- s = "(!" + toString((List) m_value) + ")";
- break;
- case EQ:
- s = "(" + m_name + "=" + toEncodedString(m_value) + ")";
- break;
- case LTE:
- s = "(" + m_name + "<=" + toEncodedString(m_value) + ")";
- break;
- case GTE:
- s = "(" + m_name + ">=" + toEncodedString(m_value) + ")";
- break;
- case SUBSTRING:
- s = "(" + m_name + "=" + unparseSubstring((List<String>) m_value) + ")";
- break;
- case PRESENT:
- s = "(" + m_name + "=*)";
- break;
- case APPROX:
- s = "(" + m_name + "~=" + toEncodedString(m_value) + ")";
- break;
- case MATCH_ALL:
- s = "(*)";
- break;
- }
- return s;
- }
-
- private static String toString(List list)
- {
- StringBuffer sb = new StringBuffer();
- for (int i = 0; i < list.size(); i++)
- {
- sb.append(list.get(i).toString());
- }
- return sb.toString();
- }
-
- private static String toDecodedString(String s, int startIdx, int endIdx)
- {
- StringBuffer sb = new StringBuffer(endIdx - startIdx);
- boolean escaped = false;
- for (int i = 0; i < (endIdx - startIdx); i++)
- {
- char c = s.charAt(startIdx + i);
- if (!escaped && (c == '\\'))
- {
- escaped = true;
- }
- else
- {
- escaped = false;
- sb.append(c);
- }
- }
-
- return sb.toString();
- }
-
- private static String toEncodedString(Object o)
- {
- if (o instanceof String)
- {
- String s = (String) o;
- StringBuffer sb = new StringBuffer();
- for (int i = 0; i < s.length(); i++)
- {
- char c = s.charAt(i);
- if ((c == '\\') || (c == '(') || (c == ')') || (c == '*'))
- {
- sb.append('\\');
- }
- sb.append(c);
- }
-
- o = sb.toString();
- }
-
- return o.toString();
- }
-
- public static SimpleFilter parse(String filter)
- {
- int idx = skipWhitespace(filter, 0);
-
- if ((filter == null) || (filter.length() == 0) || (idx >= filter.length()))
- {
- throw new IllegalArgumentException("Null or empty filter.");
- }
- else if (filter.charAt(idx) != '(')
- {
- throw new IllegalArgumentException("Missing opening parenthesis: " + filter);
- }
-
- SimpleFilter sf = null;
- List stack = new ArrayList();
- boolean isEscaped = false;
- while (idx < filter.length())
- {
- if (sf != null)
- {
- throw new IllegalArgumentException(
- "Only one top-level operation allowed: " + filter);
- }
-
- if (!isEscaped && (filter.charAt(idx) == '('))
- {
- // Skip paren and following whitespace.
- idx = skipWhitespace(filter, idx + 1);
-
- if (filter.charAt(idx) == '&')
- {
- int peek = skipWhitespace(filter, idx + 1);
- if (filter.charAt(peek) == '(')
- {
- idx = peek - 1;
- stack.add(0, new SimpleFilter(null, new ArrayList(), SimpleFilter.AND));
- }
- else
- {
- stack.add(0, new Integer(idx));
- }
- }
- else if (filter.charAt(idx) == '|')
- {
- int peek = skipWhitespace(filter, idx + 1);
- if (filter.charAt(peek) == '(')
- {
- idx = peek - 1;
- stack.add(0, new SimpleFilter(null, new ArrayList(), SimpleFilter.OR));
- }
- else
- {
- stack.add(0, new Integer(idx));
- }
- }
- else if (filter.charAt(idx) == '!')
- {
- int peek = skipWhitespace(filter, idx + 1);
- if (filter.charAt(peek) == '(')
- {
- idx = peek - 1;
- stack.add(0, new SimpleFilter(null, new ArrayList(), SimpleFilter.NOT));
- }
- else
- {
- stack.add(0, new Integer(idx));
- }
- }
- else
- {
- stack.add(0, new Integer(idx));
- }
- }
- else if (!isEscaped && (filter.charAt(idx) == ')'))
- {
- Object top = stack.remove(0);
- if (top instanceof SimpleFilter)
- {
- if (!stack.isEmpty() && (stack.get(0) instanceof SimpleFilter))
- {
- ((List) ((SimpleFilter) stack.get(0)).m_value).add(top);
- }
- else
- {
- sf = (SimpleFilter) top;
- }
- }
- else if (!stack.isEmpty() && (stack.get(0) instanceof SimpleFilter))
- {
- ((List) ((SimpleFilter) stack.get(0)).m_value).add(
- SimpleFilter.subfilter(filter, ((Integer) top).intValue(), idx));
- }
- else
- {
- sf = SimpleFilter.subfilter(filter, ((Integer) top).intValue(), idx);
- }
- }
- else if (!isEscaped && (filter.charAt(idx) == '\\'))
- {
- isEscaped = true;
- }
- else
- {
- isEscaped = false;
- }
-
- idx = skipWhitespace(filter, idx + 1);
- }
-
- if (sf == null)
- {
- throw new IllegalArgumentException("Missing closing parenthesis: " + filter);
- }
-
- return sf;
- }
-
- private static SimpleFilter subfilter(String filter, int startIdx, int endIdx)
- {
- final String opChars = "=<>~";
-
- // Determine the ending index of the attribute name.
- int attrEndIdx = startIdx;
- for (int i = 0; i < (endIdx - startIdx); i++)
- {
- char c = filter.charAt(startIdx + i);
- if (opChars.indexOf(c) >= 0)
- {
- break;
- }
- else if (!Character.isWhitespace(c))
- {
- attrEndIdx = startIdx + i + 1;
- }
- }
- if (attrEndIdx == startIdx)
- {
- throw new IllegalArgumentException(
- "Missing attribute name: " + filter.substring(startIdx, endIdx));
- }
- String attr = filter.substring(startIdx, attrEndIdx);
-
- // Skip the attribute name and any following whitespace.
- startIdx = skipWhitespace(filter, attrEndIdx);
-
- // Determine the operator type.
- int op = -1;
- switch (filter.charAt(startIdx))
- {
- case '=':
- op = EQ;
- startIdx++;
- break;
- case '<':
- if (filter.charAt(startIdx + 1) != '=')
- {
- throw new IllegalArgumentException(
- "Unknown operator: " + filter.substring(startIdx, endIdx));
- }
- op = LTE;
- startIdx += 2;
- break;
- case '>':
- if (filter.charAt(startIdx + 1) != '=')
- {
- throw new IllegalArgumentException(
- "Unknown operator: " + filter.substring(startIdx, endIdx));
- }
- op = GTE;
- startIdx += 2;
- break;
- case '~':
- if (filter.charAt(startIdx + 1) != '=')
- {
- throw new IllegalArgumentException(
- "Unknown operator: " + filter.substring(startIdx, endIdx));
- }
- op = APPROX;
- startIdx += 2;
- break;
- default:
- throw new IllegalArgumentException(
- "Unknown operator: " + filter.substring(startIdx, endIdx));
- }
-
- // Parse value.
- Object value = toDecodedString(filter, startIdx, endIdx);
-
- // Check if the equality comparison is actually a substring
- // or present operation.
- if (op == EQ)
- {
- String valueStr = filter.substring(startIdx, endIdx);
- List<String> values = parseSubstring(valueStr);
- if ((values.size() == 2)
- && (values.get(0).length() == 0)
- && (values.get(1).length() == 0))
- {
- op = PRESENT;
- }
- else if (values.size() > 1)
- {
- op = SUBSTRING;
- value = values;
- }
- }
-
- return new SimpleFilter(attr, value, op);
- }
-
- public static List<String> parseSubstring(String value)
- {
- List<String> pieces = new ArrayList();
- StringBuffer ss = new StringBuffer();
- // int kind = SIMPLE; // assume until proven otherwise
- boolean wasStar = false; // indicates last piece was a star
- boolean leftstar = false; // track if the initial piece is a star
- boolean rightstar = false; // track if the final piece is a star
-
- int idx = 0;
-
- // We assume (sub)strings can contain leading and trailing blanks
- boolean escaped = false;
- loop: for (;;)
- {
- if (idx >= value.length())
- {
- if (wasStar)
- {
- // insert last piece as "" to handle trailing star
- rightstar = true;
- }
- else
- {
- pieces.add(ss.toString());
- // accumulate the last piece
- // note that in the case of
- // (cn=); this might be
- // the string "" (!=null)
- }
- ss.setLength(0);
- break loop;
- }
-
- // Read the next character and account for escapes.
- char c = value.charAt(idx++);
- if (!escaped && (c == '*'))
- {
- // If we have successive '*' characters, then we can
- // effectively collapse them by ignoring succeeding ones.
- if (!wasStar)
- {
- if (ss.length() > 0)
- {
- pieces.add(ss.toString()); // accumulate the pieces
- // between '*' occurrences
- }
- ss.setLength(0);
- // if this is a leading star, then track it
- if (pieces.isEmpty())
- {
- leftstar = true;
- }
- wasStar = true;
- }
- }
- else if (!escaped && (c == '\\'))
- {
- escaped = true;
- }
- else
- {
- escaped = false;
- wasStar = false;
- ss.append(c);
- }
- }
- if (leftstar || rightstar || pieces.size() > 1)
- {
- // insert leading and/or trailing "" to anchor ends
- if (rightstar)
- {
- pieces.add("");
- }
- if (leftstar)
- {
- pieces.add(0, "");
- }
- }
- return pieces;
- }
-
- public static String unparseSubstring(List<String> pieces)
- {
- StringBuffer sb = new StringBuffer();
- for (int i = 0; i < pieces.size(); i++)
- {
- if (i > 0)
- {
- sb.append("*");
- }
- sb.append(toEncodedString(pieces.get(i)));
- }
- return sb.toString();
- }
-
- public static boolean compareSubstring(List<String> pieces, String s)
- {
- // Walk the pieces to match the string
- // There are implicit stars between each piece,
- // and the first and last pieces might be "" to anchor the match.
- // assert (pieces.length > 1)
- // minimal case is <string>*<string>
-
- boolean result = true;
- int len = pieces.size();
-
- // Special case, if there is only one piece, then
- // we must perform an equality test.
- if (len == 1)
- {
- return s.equals(pieces.get(0));
- }
-
- // Otherwise, check whether the pieces match
- // the specified string.
-
- int index = 0;
-
- loop: for (int i = 0; i < len; i++)
- {
- String piece = pieces.get(i);
-
- // If this is the first piece, then make sure the
- // string starts with it.
- if (i == 0)
- {
- if (!s.startsWith(piece))
- {
- result = false;
- break loop;
- }
- }
-
- // If this is the last piece, then make sure the
- // string ends with it.
- if (i == (len - 1))
- {
- if (s.endsWith(piece) && (s.length() >= (index + piece.length())))
- {
- result = true;
- }
- else
- {
- result = false;
- }
- break loop;
- }
-
- // If this is neither the first or last piece, then
- // make sure the string contains it.
- if ((i > 0) && (i < (len - 1)))
- {
- index = s.indexOf(piece, index);
- if (index < 0)
- {
- result = false;
- break loop;
- }
- }
-
- // Move string index beyond the matching piece.
- index += piece.length();
- }
-
- return result;
- }
-
- private static int skipWhitespace(String s, int startIdx)
- {
- int len = s.length();
- while ((startIdx < len) && Character.isWhitespace(s.charAt(startIdx)))
- {
- startIdx++;
- }
- return startIdx;
- }
-
- /**
- * Converts a attribute map to a filter. The filter is created by iterating
- * over the map's entry set. If ordering of attributes is important (e.g.,
- * for hitting attribute indices), then the map's entry set should iterate
- * in the desired order. Equality testing is assumed for all attribute types
- * other than version ranges, which are handled appropriated. If the attribute
- * map is empty, then a filter that matches anything is returned.
- * @param attrs Map of attributes to convert to a filter.
- * @return A filter corresponding to the attributes.
- */
- public static SimpleFilter convert(Map<String, Object> attrs)
- {
- // Rather than building a filter string to be parsed into a SimpleFilter,
- // we will just create the parsed SimpleFilter directly.
-
- List<SimpleFilter> filters = new ArrayList<SimpleFilter>();
-
- for (Entry<String, Object> entry : attrs.entrySet())
- {
- if (entry.getValue() instanceof VersionRange)
- {
- VersionRange vr = (VersionRange) entry.getValue();
- if (!vr.isOpenFloor())
- {
- filters.add(
- new SimpleFilter(
- entry.getKey(),
- vr.getFloor().toString(),
- SimpleFilter.GTE));
- }
- else
- {
- SimpleFilter not =
- new SimpleFilter(null, new ArrayList(), SimpleFilter.NOT);
- ((List) not.getValue()).add(
- new SimpleFilter(
- entry.getKey(),
- vr.getFloor().toString(),
- SimpleFilter.LTE));
- filters.add(not);
- }
-
- if (vr.getCeiling() != null)
- {
- if (!vr.isOpenCeiling())
- {
- filters.add(
- new SimpleFilter(
- entry.getKey(),
- vr.getCeiling().toString(),
- SimpleFilter.LTE));
- }
- else
- {
- SimpleFilter not =
- new SimpleFilter(null, new ArrayList(), SimpleFilter.NOT);
- ((List) not.getValue()).add(
- new SimpleFilter(
- entry.getKey(),
- vr.getCeiling().toString(),
- SimpleFilter.GTE));
- filters.add(not);
- }
- }
- }
- else
- {
- List<String> values = SimpleFilter.parseSubstring(entry.getValue().toString());
- if (values.size() > 1)
- {
- filters.add(
- new SimpleFilter(
- entry.getKey(),
- values,
- SimpleFilter.SUBSTRING));
- }
- else
- {
- filters.add(
- new SimpleFilter(
- entry.getKey(),
- values.get(0),
- SimpleFilter.EQ));
- }
- }
- }
-
- SimpleFilter sf = null;
-
- if (filters.size() == 1)
- {
- sf = filters.get(0);
- }
- else if (attrs.size() > 1)
- {
- sf = new SimpleFilter(null, filters, SimpleFilter.AND);
- }
- else if (filters.isEmpty())
- {
- sf = new SimpleFilter(null, null, SimpleFilter.MATCH_ALL);
- }
-
- return sf;
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0c8e8a81/features/src/main/java/org/apache/karaf/features/internal/resolver/Slf4jResolverLog.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/resolver/Slf4jResolverLog.java b/features/src/main/java/org/apache/karaf/features/internal/resolver/Slf4jResolverLog.java
deleted file mode 100644
index 2f4a1f3..0000000
--- a/features/src/main/java/org/apache/karaf/features/internal/resolver/Slf4jResolverLog.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.features.internal.resolver;
-
-import org.slf4j.Logger;
-
-/**
- */
-public class Slf4jResolverLog extends org.apache.felix.resolver.Logger {
-
- private final Logger logger;
-
- public Slf4jResolverLog(Logger logger) {
- super(LOG_DEBUG);
- this.logger = logger;
- }
-
- @Override
- protected void doLog(int level, String msg, Throwable throwable) {
- switch (level) {
- case LOG_ERROR:
- logger.error(msg, throwable);
- break;
- case LOG_WARNING:
- logger.warn(msg, throwable);
- break;
- case LOG_INFO:
- logger.info(msg, throwable);
- break;
- case LOG_DEBUG:
- logger.debug(msg, throwable);
- break;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0c8e8a81/features/src/main/java/org/apache/karaf/features/internal/resolver/UriNamespace.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/resolver/UriNamespace.java b/features/src/main/java/org/apache/karaf/features/internal/resolver/UriNamespace.java
deleted file mode 100644
index b5158bf..0000000
--- a/features/src/main/java/org/apache/karaf/features/internal/resolver/UriNamespace.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.features.internal.resolver;
-
-import java.util.List;
-
-import org.osgi.resource.Capability;
-import org.osgi.resource.Namespace;
-import org.osgi.resource.Resource;
-
-/**
- */
-public final class UriNamespace extends Namespace {
-
- public static final String URI_NAMESPACE = "karaf.uri";
-
- public static String getUri(Resource resource)
- {
- List<Capability> caps = resource.getCapabilities(null);
- for (Capability cap : caps)
- {
- if (cap.getNamespace().equals(UriNamespace.URI_NAMESPACE))
- {
- return cap.getAttributes().get(UriNamespace.URI_NAMESPACE).toString();
- }
- }
- return null;
- }
-
-
- private UriNamespace() {
- }
-}