http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/resolver/CandidateComparator.java ---------------------------------------------------------------------- diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/CandidateComparator.java b/features/core/src/main/java/org/apache/karaf/features/internal/resolver/CandidateComparator.java deleted file mode 100644 index ad4cc85..0000000 --- a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/CandidateComparator.java +++ /dev/null @@ -1,129 +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.Comparator; - -import org.osgi.framework.Version; -import org.osgi.framework.namespace.BundleNamespace; -import org.osgi.framework.namespace.PackageNamespace; -import org.osgi.framework.wiring.BundleCapability; -import org.osgi.resource.Capability; - -public class CandidateComparator implements Comparator<Capability> -{ - public int compare(Capability cap1, Capability cap2) - { - int c = 0; - // Always prefer system bundle - if (cap1 instanceof BundleCapability && !(cap2 instanceof BundleCapability)) { - c = -1; - } else if (!(cap1 instanceof BundleCapability) && cap2 instanceof BundleCapability) { - c = 1; - } - // Compare revision capabilities. - if ((c == 0) && cap1.getNamespace().equals(BundleNamespace.BUNDLE_NAMESPACE)) - { - c = ((Comparable) cap1.getAttributes().get(BundleNamespace.BUNDLE_NAMESPACE)) - .compareTo(cap2.getAttributes().get(BundleNamespace.BUNDLE_NAMESPACE)); - if (c == 0) - { - Version v1 = (!cap1.getAttributes().containsKey(BundleNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE)) - ? Version.emptyVersion - : (Version) cap1.getAttributes().get(BundleNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE); - Version v2 = (!cap2.getAttributes().containsKey(BundleNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE)) - ? Version.emptyVersion - : (Version) cap2.getAttributes().get(BundleNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE); - // Compare these in reverse order, since we want - // highest version to have priority. - c = compareVersions(v2, v1); - } - } - // Compare package capabilities. - else if ((c == 0) && cap1.getNamespace().equals(PackageNamespace.PACKAGE_NAMESPACE)) - { - c = ((Comparable) cap1.getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE)) - .compareTo(cap2.getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE)); - if (c == 0) - { - Version v1 = (!cap1.getAttributes().containsKey(PackageNamespace.CAPABILITY_VERSION_ATTRIBUTE)) - ? Version.emptyVersion - : (Version) cap1.getAttributes().get(PackageNamespace.CAPABILITY_VERSION_ATTRIBUTE); - Version v2 = (!cap2.getAttributes().containsKey(PackageNamespace.CAPABILITY_VERSION_ATTRIBUTE)) - ? Version.emptyVersion - : (Version) cap2.getAttributes().get(PackageNamespace.CAPABILITY_VERSION_ATTRIBUTE); - // Compare these in reverse order, since we want - // highest version to have priority. - c = compareVersions(v2, v1); - // if same version, rather compare on the bundle version - if (c == 0) - { - v1 = (!cap1.getAttributes().containsKey(BundleNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE)) - ? Version.emptyVersion - : (Version) cap1.getAttributes().get(BundleNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE); - v2 = (!cap2.getAttributes().containsKey(BundleNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE)) - ? Version.emptyVersion - : (Version) cap2.getAttributes().get(BundleNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE); - // Compare these in reverse order, since we want - // highest version to have priority. - c = compareVersions(v2, v1); - } - } - } - // Compare feature capabilities - else if ((c == 0) && cap1.getNamespace().equals(FeatureNamespace.FEATURE_NAMESPACE)) - { - c = ((Comparable) cap1.getAttributes().get(FeatureNamespace.FEATURE_NAMESPACE)) - .compareTo(cap2.getAttributes().get(FeatureNamespace.FEATURE_NAMESPACE)); - if (c == 0) - { - Version v1 = (!cap1.getAttributes().containsKey(FeatureNamespace.CAPABILITY_VERSION_ATTRIBUTE)) - ? Version.emptyVersion - : (Version) cap1.getAttributes().get(FeatureNamespace.CAPABILITY_VERSION_ATTRIBUTE); - Version v2 = (!cap2.getAttributes().containsKey(FeatureNamespace.CAPABILITY_VERSION_ATTRIBUTE)) - ? Version.emptyVersion - : (Version) cap2.getAttributes().get(FeatureNamespace.CAPABILITY_VERSION_ATTRIBUTE); - // Compare these in reverse order, since we want - // highest version to have priority. - c = compareVersions(v2, v1); - } - } - return c; - } - - private int compareVersions(Version v1, Version v2) { - int c = v1.getMajor() - v2.getMajor(); - if (c != 0) { - return c; - } - c = v1.getMinor() - v2.getMinor(); - if (c != 0) { - return c; - } - c = v1.getMicro() - v2.getMicro(); - if (c != 0) { - return c; - } - String q1 = cleanQualifierForComparison(v1.getQualifier()); - String q2 = cleanQualifierForComparison(v2.getQualifier()); - return q1.compareTo(q2); - } - - private String cleanQualifierForComparison(String qualifier) { - return qualifier.replaceAll("(redhat-[0-9]{3})([0-9]{3})", "$1-$2"); - } -}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/resolver/CapabilityImpl.java ---------------------------------------------------------------------- diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/CapabilityImpl.java b/features/core/src/main/java/org/apache/karaf/features/internal/resolver/CapabilityImpl.java deleted file mode 100644 index bfe9b40..0000000 --- a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/CapabilityImpl.java +++ /dev/null @@ -1,165 +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.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.StringTokenizer; - -import org.osgi.framework.Constants; -import org.osgi.resource.Capability; -import org.osgi.resource.Resource; - -public class CapabilityImpl extends BaseClause implements Capability { - - private final Resource m_resource; - private final String m_namespace; - private final Map<String, String> m_dirs; - private final Map<String, Object> m_attrs; - private final List<String> m_uses; - private final List<List<String>> m_includeFilter; - private final List<List<String>> m_excludeFilter; - private final Set<String> m_mandatory; - - public CapabilityImpl(Capability capability) { - this(null, capability.getNamespace(), capability.getDirectives(), capability.getAttributes()); - } - - public CapabilityImpl(Resource resource, String namespace, - Map<String, String> dirs, Map<String, Object> attrs) { - m_namespace = namespace; - m_resource = resource; - m_dirs = dirs; - m_attrs = attrs; - - // Find all export directives: uses, mandatory, include, and exclude. - - List<String> uses = Collections.emptyList(); - String value = m_dirs.get(Constants.USES_DIRECTIVE); - if (value != null) { - // Parse these uses directive. - StringTokenizer tok = new StringTokenizer(value, ","); - uses = new ArrayList<String>(tok.countTokens()); - while (tok.hasMoreTokens()) { - uses.add(tok.nextToken().trim()); - } - } - m_uses = uses; - - value = m_dirs.get(Constants.INCLUDE_DIRECTIVE); - if (value != null) { - List<String> filters = ResourceBuilder.parseDelimitedString(value, ","); - m_includeFilter = new ArrayList<List<String>>(filters.size()); - for (String filter : filters) { - List<String> substrings = SimpleFilter.parseSubstring(filter); - m_includeFilter.add(substrings); - } - } else { - m_includeFilter = null; - } - - value = m_dirs.get(Constants.EXCLUDE_DIRECTIVE); - if (value != null) { - List<String> filters = ResourceBuilder.parseDelimitedString(value, ","); - m_excludeFilter = new ArrayList<List<String>>(filters.size()); - for (String filter : filters) { - List<String> substrings = SimpleFilter.parseSubstring(filter); - m_excludeFilter.add(substrings); - } - } else { - m_excludeFilter = null; - } - - Set<String> mandatory = Collections.emptySet(); - value = m_dirs.get(Constants.MANDATORY_DIRECTIVE); - if (value != null) { - List<String> names = ResourceBuilder.parseDelimitedString(value, ","); - mandatory = new HashSet<String>(names.size()); - for (String name : names) { - // If attribute exists, then record it as mandatory. - if (m_attrs.containsKey(name)) { - mandatory.add(name); - } - // Otherwise, report an error. - else { - throw new IllegalArgumentException("Mandatory attribute '" + name + "' does not exist."); - } - } - } - m_mandatory = mandatory; - } - - public Resource getResource() { - return m_resource; - } - - public String getNamespace() { - return m_namespace; - } - - public Map<String, String> getDirectives() { - return m_dirs; - } - - public Map<String, Object> getAttributes() { - return m_attrs; - } - - public boolean isAttributeMandatory(String name) { - return !m_mandatory.isEmpty() && m_mandatory.contains(name); - } - - public List<String> getUses() { - return m_uses; - } - - public boolean isIncluded(String name) { - if ((m_includeFilter == null) && (m_excludeFilter == null)) { - return true; - } - - // Get the class name portion of the target class. - String className = getClassName(name); - - // If there are no include filters then all classes are included - // by default, otherwise try to find one match. - boolean included = (m_includeFilter == null); - for (int i = 0; !included && m_includeFilter != null && i < m_includeFilter.size(); i++) { - included = SimpleFilter.compareSubstring(m_includeFilter.get(i), className); - } - - // If there are no exclude filters then no classes are excluded - // by default, otherwise try to find one match. - boolean excluded = false; - for (int i = 0; (!excluded) && (m_excludeFilter != null) && (i < m_excludeFilter.size()); i++) { - excluded = SimpleFilter.compareSubstring(m_excludeFilter.get(i), className); - } - return included && !excluded; - } - - private static String getClassName(String className) { - if (className == null) { - className = ""; - } - return (className.lastIndexOf('.') < 0) ? "" : className.substring(className.lastIndexOf('.') + 1); - } - -} http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/resolver/CapabilitySet.java ---------------------------------------------------------------------- diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/CapabilitySet.java b/features/core/src/main/java/org/apache/karaf/features/internal/resolver/CapabilitySet.java deleted file mode 100644 index 4c5656d..0000000 --- a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/CapabilitySet.java +++ /dev/null @@ -1,612 +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.lang.reflect.Array; -import java.lang.reflect.Constructor; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.TreeMap; - -import org.osgi.framework.Constants; -import org.osgi.resource.Capability; - -public class CapabilitySet -{ - private final Map<String, Map<Object, Set<Capability>>> m_indices; - private final Set<Capability> m_capSet = new HashSet<Capability>(); - -public void dump() -{ - for (Entry<String, Map<Object, Set<Capability>>> entry : m_indices.entrySet()) - { - boolean header1 = false; - for (Entry<Object, Set<Capability>> entry2 : entry.getValue().entrySet()) - { - boolean header2 = false; - for (Capability cap : entry2.getValue()) - { - if (!header1) - { - System.out.println(entry.getKey() + ":"); - header1 = true; - } - if (!header2) - { - System.out.println(" " + entry2.getKey()); - header2 = true; - } - System.out.println(" " + cap); - } - } - } -} - - public CapabilitySet(List<String> indexProps) - { - m_indices = new TreeMap<String, Map<Object, Set<Capability>>>(); - for (int i = 0; (indexProps != null) && (i < indexProps.size()); i++) - { - m_indices.put( - indexProps.get(i), new HashMap<Object, Set<Capability>>()); - } - } - - public void addCapability(Capability cap) - { - m_capSet.add(cap); - - // Index capability. - for (Entry<String, Map<Object, Set<Capability>>> entry : m_indices.entrySet()) - { - Object value = cap.getAttributes().get(entry.getKey()); - if (value != null) - { - if (value.getClass().isArray()) - { - value = convertArrayToList(value); - } - - Map<Object, Set<Capability>> index = entry.getValue(); - - if (value instanceof Collection) - { - Collection c = (Collection) value; - for (Object o : c) - { - indexCapability(index, cap, o); - } - } - else - { - indexCapability(index, cap, value); - } - } - } - } - - private void indexCapability( - Map<Object, Set<Capability>> index, Capability cap, Object capValue) - { - Set<Capability> caps = index.get(capValue); - if (caps == null) - { - caps = new HashSet<Capability>(); - index.put(capValue, caps); - } - caps.add(cap); - } - - public void removeCapability(Capability cap) - { - if (m_capSet.remove(cap)) - { - for (Entry<String, Map<Object, Set<Capability>>> entry : m_indices.entrySet()) - { - Object value = cap.getAttributes().get(entry.getKey()); - if (value != null) - { - if (value.getClass().isArray()) - { - value = convertArrayToList(value); - } - - Map<Object, Set<Capability>> index = entry.getValue(); - - if (value instanceof Collection) - { - Collection c = (Collection) value; - for (Object o : c) - { - deindexCapability(index, cap, o); - } - } - else - { - deindexCapability(index, cap, value); - } - } - } - } - } - - private void deindexCapability( - Map<Object, Set<Capability>> index, Capability cap, Object value) - { - Set<Capability> caps = index.get(value); - if (caps != null) - { - caps.remove(cap); - if (caps.isEmpty()) - { - index.remove(value); - } - } - } - - public Set<Capability> match(SimpleFilter sf, boolean obeyMandatory) - { - Set<Capability> matches = match(m_capSet, sf); - return (obeyMandatory) - ? matchMandatory(matches, sf) - : matches; - } - - private Set<Capability> match(Set<Capability> caps, SimpleFilter sf) - { - Set<Capability> matches = new HashSet<Capability>(); - - if (sf.getOperation() == SimpleFilter.MATCH_ALL) - { - matches.addAll(caps); - } - else if (sf.getOperation() == SimpleFilter.AND) - { - // Evaluate each subfilter against the remaining capabilities. - // For AND we calculate the intersection of each subfilter. - // We can short-circuit the AND operation if there are no - // remaining capabilities. - List<SimpleFilter> sfs = (List<SimpleFilter>) sf.getValue(); - for (int i = 0; (caps.size() > 0) && (i < sfs.size()); i++) - { - matches = match(caps, sfs.get(i)); - caps = matches; - } - } - else if (sf.getOperation() == SimpleFilter.OR) - { - // Evaluate each subfilter against the remaining capabilities. - // For OR we calculate the union of each subfilter. - List<SimpleFilter> sfs = (List<SimpleFilter>) sf.getValue(); - for (int i = 0; i < sfs.size(); i++) - { - matches.addAll(match(caps, sfs.get(i))); - } - } - else if (sf.getOperation() == SimpleFilter.NOT) - { - // Evaluate each subfilter against the remaining capabilities. - // For OR we calculate the union of each subfilter. - matches.addAll(caps); - List<SimpleFilter> sfs = (List<SimpleFilter>) sf.getValue(); - for (int i = 0; i < sfs.size(); i++) - { - matches.removeAll(match(caps, sfs.get(i))); - } - } - else - { - Map<Object, Set<Capability>> index = m_indices.get(sf.getName()); - if ((sf.getOperation() == SimpleFilter.EQ) && (index != null)) - { - Set<Capability> existingCaps = index.get(sf.getValue()); - if (existingCaps != null) - { - matches.addAll(existingCaps); - matches.retainAll(caps); - } - } - else - { - for (Iterator<Capability> it = caps.iterator(); it.hasNext(); ) - { - Capability cap = it.next(); - Object lhs = cap.getAttributes().get(sf.getName()); - if (lhs != null) - { - if (compare(lhs, sf.getValue(), sf.getOperation())) - { - matches.add(cap); - } - } - } - } - } - - return matches; - } - - public static boolean matches(Capability cap, SimpleFilter sf) - { - return matchesInternal(cap, sf) && matchMandatory(cap, sf); - } - - private static boolean matchesInternal(Capability cap, SimpleFilter sf) - { - boolean matched = true; - - if (sf.getOperation() == SimpleFilter.MATCH_ALL) - { - matched = true; - } - else if (sf.getOperation() == SimpleFilter.AND) - { - // Evaluate each subfilter against the remaining capabilities. - // For AND we calculate the intersection of each subfilter. - // We can short-circuit the AND operation if there are no - // remaining capabilities. - List<SimpleFilter> sfs = (List<SimpleFilter>) sf.getValue(); - for (int i = 0; matched && (i < sfs.size()); i++) - { - matched = matchesInternal(cap, sfs.get(i)); - } - } - else if (sf.getOperation() == SimpleFilter.OR) - { - // Evaluate each subfilter against the remaining capabilities. - // For OR we calculate the union of each subfilter. - matched = false; - List<SimpleFilter> sfs = (List<SimpleFilter>) sf.getValue(); - for (int i = 0; !matched && (i < sfs.size()); i++) - { - matched = matchesInternal(cap, sfs.get(i)); - } - } - else if (sf.getOperation() == SimpleFilter.NOT) - { - // Evaluate each subfilter against the remaining capabilities. - // For OR we calculate the union of each subfilter. - List<SimpleFilter> sfs = (List<SimpleFilter>) sf.getValue(); - for (int i = 0; i < sfs.size(); i++) - { - matched = !(matchesInternal(cap, sfs.get(i))); - } - } - else - { - matched = false; - Object lhs = cap.getAttributes().get(sf.getName()); - if (lhs != null) - { - matched = compare(lhs, sf.getValue(), sf.getOperation()); - } - } - - return matched; - } - - private static Set<Capability> matchMandatory( - Set<Capability> caps, SimpleFilter sf) - { - for (Iterator<Capability> it = caps.iterator(); it.hasNext(); ) - { - Capability cap = it.next(); - if (!matchMandatory(cap, sf)) - { - it.remove(); - } - } - return caps; - } - - private static boolean matchMandatory(Capability cap, SimpleFilter sf) - { - if (cap instanceof CapabilityImpl) { - for (Entry<String, Object> entry : cap.getAttributes().entrySet()) - { - if (((CapabilityImpl) cap).isAttributeMandatory(entry.getKey()) - && !matchMandatoryAttribute(entry.getKey(), sf)) - { - return false; - } - } - } else { - String value = cap.getDirectives().get(Constants.MANDATORY_DIRECTIVE); - if (value != null) { - List<String> names = ResourceBuilder.parseDelimitedString(value, ","); - for (Entry<String, Object> entry : cap.getAttributes().entrySet()) - { - if (names.contains(entry.getKey()) - && !matchMandatoryAttribute(entry.getKey(), sf)) - { - return false; - } - } - } - - } - return true; - } - - private static boolean matchMandatoryAttribute(String attrName, SimpleFilter sf) - { - if ((sf.getName() != null) && sf.getName().equals(attrName)) - { - return true; - } - else if (sf.getOperation() == SimpleFilter.AND) - { - List list = (List) sf.getValue(); - for (int i = 0; i < list.size(); i++) - { - SimpleFilter sf2 = (SimpleFilter) list.get(i); - if ((sf2.getName() != null) - && sf2.getName().equals(attrName)) - { - return true; - } - } - } - return false; - } - - private static final Class<?>[] STRING_CLASS = new Class[] { String.class }; - - private static boolean compare(Object lhs, Object rhsUnknown, int op) - { - if (lhs == null) - { - return false; - } - - // If this is a PRESENT operation, then just return true immediately - // since we wouldn't be here if the attribute wasn't present. - if (op == SimpleFilter.PRESENT) - { - return true; - } - - // If the type is comparable, then we can just return the - // result immediately. - if (lhs instanceof Comparable) - { - // Spec says SUBSTRING is false for all types other than string. - if ((op == SimpleFilter.SUBSTRING) && !(lhs instanceof String)) - { - return false; - } - - Object rhs; - if (op == SimpleFilter.SUBSTRING) - { - rhs = rhsUnknown; - } - else - { - try - { - rhs = coerceType(lhs, (String) rhsUnknown); - } - catch (Exception ex) - { - return false; - } - } - - switch (op) - { - case SimpleFilter.EQ : - try - { - return (((Comparable) lhs).compareTo(rhs) == 0); - } - catch (Exception ex) - { - return false; - } - case SimpleFilter.GTE : - try - { - return (((Comparable) lhs).compareTo(rhs) >= 0); - } - catch (Exception ex) - { - return false; - } - case SimpleFilter.LTE : - try - { - return (((Comparable) lhs).compareTo(rhs) <= 0); - } - catch (Exception ex) - { - return false; - } - case SimpleFilter.APPROX : - return compareApproximate(((Comparable) lhs), rhs); - case SimpleFilter.SUBSTRING : - return SimpleFilter.compareSubstring((List<String>) rhs, (String) lhs); - default: - throw new RuntimeException( - "Unknown comparison operator: " + op); - } - } - // Booleans do not implement comparable, so special case them. - else if (lhs instanceof Boolean) - { - Object rhs; - try - { - rhs = coerceType(lhs, (String) rhsUnknown); - } - catch (Exception ex) - { - return false; - } - - switch (op) - { - case SimpleFilter.EQ : - case SimpleFilter.GTE : - case SimpleFilter.LTE : - case SimpleFilter.APPROX : - return (lhs.equals(rhs)); - default: - throw new RuntimeException( - "Unknown comparison operator: " + op); - } - } - - // If the LHS is not a comparable or boolean, check if it is an - // array. If so, convert it to a list so we can treat it as a - // collection. - if (lhs.getClass().isArray()) - { - lhs = convertArrayToList(lhs); - } - - // If LHS is a collection, then call compare() on each element - // of the collection until a match is found. - if (lhs instanceof Collection) - { - for (Iterator iter = ((Collection) lhs).iterator(); iter.hasNext(); ) - { - if (compare(iter.next(), rhsUnknown, op)) - { - return true; - } - } - - return false; - } - - // Spec says SUBSTRING is false for all types other than string. - if ((op == SimpleFilter.SUBSTRING) && !(lhs instanceof String)) - { - return false; - } - - // Since we cannot identify the LHS type, then we can only perform - // equality comparison. - try - { - return lhs.equals(coerceType(lhs, (String) rhsUnknown)); - } - catch (Exception ex) - { - return false; - } - } - - private static boolean compareApproximate(Object lhs, Object rhs) - { - if (rhs instanceof String) - { - return removeWhitespace((String) lhs) - .equalsIgnoreCase(removeWhitespace((String) rhs)); - } - else if (rhs instanceof Character) - { - return Character.toLowerCase(((Character) lhs)) - == Character.toLowerCase(((Character) rhs)); - } - return lhs.equals(rhs); - } - - private static String removeWhitespace(String s) - { - StringBuffer sb = new StringBuffer(s.length()); - for (int i = 0; i < s.length(); i++) - { - if (!Character.isWhitespace(s.charAt(i))) - { - sb.append(s.charAt(i)); - } - } - return sb.toString(); - } - - private static Object coerceType(Object lhs, String rhsString) throws Exception - { - // If the LHS expects a string, then we can just return - // the RHS since it is a string. - if (lhs.getClass() == rhsString.getClass()) - { - return rhsString; - } - - // Try to convert the RHS type to the LHS type by using - // the string constructor of the LHS class, if it has one. - Object rhs = null; - try - { - // The Character class is a special case, since its constructor - // does not take a string, so handle it separately. - if (lhs instanceof Character) - { - rhs = new Character(rhsString.charAt(0)); - } - else - { - // Spec says we should trim number types. - if ((lhs instanceof Number) || (lhs instanceof Boolean)) - { - rhsString = rhsString.trim(); - } - Constructor ctor = lhs.getClass().getConstructor(STRING_CLASS); - ctor.setAccessible(true); - rhs = ctor.newInstance(new Object[] { rhsString }); - } - } - catch (Exception ex) - { - throw new Exception( - "Could not instantiate class " - + lhs.getClass().getName() - + " from string constructor with argument '" - + rhsString + "' because " + ex); - } - - return rhs; - } - - /** - * This is an ugly utility method to convert an array of primitives - * to an array of primitive wrapper objects. This method simplifies - * processing LDAP filters since the special case of primitive arrays - * can be ignored. - * @param array An array of primitive types. - * @return An corresponding array using pritive wrapper objects. - **/ - private static List convertArrayToList(Object array) - { - int len = Array.getLength(array); - List list = new ArrayList(len); - for (int i = 0; i < len; i++) - { - list.add(Array.get(array, i)); - } - return list; - } -} http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/resolver/FeatureNamespace.java ---------------------------------------------------------------------- diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/FeatureNamespace.java b/features/core/src/main/java/org/apache/karaf/features/internal/resolver/FeatureNamespace.java deleted file mode 100644 index e211618..0000000 --- a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/FeatureNamespace.java +++ /dev/null @@ -1,72 +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.framework.Version; -import org.osgi.resource.Capability; -import org.osgi.resource.Namespace; -import org.osgi.resource.Resource; - -/** - */ -public final class FeatureNamespace extends Namespace { - - public static final String FEATURE_NAMESPACE = "karaf.feature"; - - public static final String CAPABILITY_VERSION_ATTRIBUTE = "version"; - - /** - * The attribute value identifying the resource - * {@link org.osgi.framework.namespace.IdentityNamespace#CAPABILITY_TYPE_ATTRIBUTE type} as an OSGi bundle. - * - * @see org.osgi.framework.namespace.IdentityNamespace#CAPABILITY_TYPE_ATTRIBUTE - */ - public static final String TYPE_FEATURE = "karaf.feature"; - - public static String getName(Resource resource) - { - List<Capability> caps = resource.getCapabilities(null); - for (Capability cap : caps) - { - if (cap.getNamespace().equals(FEATURE_NAMESPACE)) - { - return cap.getAttributes().get(FEATURE_NAMESPACE).toString(); - } - } - return null; - } - - public static Version getVersion(Resource resource) - { - List<Capability> caps = resource.getCapabilities(null); - for (Capability cap : caps) - { - if (cap.getNamespace().equals(FEATURE_NAMESPACE)) - { - return (Version) - cap.getAttributes().get(CAPABILITY_VERSION_ATTRIBUTE); - } - } - return null; - } - - - private FeatureNamespace() { - } -} http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/resolver/FeatureResource.java ---------------------------------------------------------------------- diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/FeatureResource.java b/features/core/src/main/java/org/apache/karaf/features/internal/resolver/FeatureResource.java deleted file mode 100644 index 88f08ae..0000000 --- a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/FeatureResource.java +++ /dev/null @@ -1,121 +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.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.felix.utils.version.VersionRange; -import org.apache.felix.utils.version.VersionTable; -import org.apache.karaf.features.BundleInfo; -import org.apache.karaf.features.Conditional; -import org.apache.karaf.features.Dependency; -import org.apache.karaf.features.Feature; -import org.apache.karaf.features.internal.util.Macro; -import org.osgi.framework.BundleException; -import org.osgi.framework.Constants; -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 FeatureResource extends ResourceImpl { - - private final Feature feature; - - public static Resource build(Feature feature, Conditional conditional, String featureRange, Map<String, Resource> locToRes) throws BundleException { - Feature fcond = conditional.asFeature(feature.getName(), feature.getVersion()); - FeatureResource resource = (FeatureResource) build(fcond, featureRange, locToRes); - for (Dependency dep : conditional.getCondition()) { - addDependency(resource, dep, featureRange); - } - org.apache.karaf.features.internal.model.Dependency dep = new org.apache.karaf.features.internal.model.Dependency(); - dep.setName(feature.getName()); - dep.setVersion(feature.getVersion()); - addDependency(resource, dep, featureRange); - return resource; - } - - public static Resource build(Feature feature, String featureRange, Map<String, Resource> locToRes) throws BundleException { - FeatureResource resource = new FeatureResource(feature); - Map<String, String> dirs = new HashMap<String, String>(); - Map<String, Object> attrs = new HashMap<String, Object>(); - attrs.put(FeatureNamespace.FEATURE_NAMESPACE, feature.getName()); - attrs.put(FeatureNamespace.CAPABILITY_VERSION_ATTRIBUTE, VersionTable.getVersion(feature.getVersion())); - resource.addCapability(new CapabilityImpl(resource, FeatureNamespace.FEATURE_NAMESPACE, dirs, attrs)); - for (BundleInfo info : feature.getBundles()) { - if (!info.isDependency()) { - Resource res = locToRes.get(info.getLocation()); - if (res == null) { - throw new IllegalStateException("Resource not found for url " + info.getLocation()); - } - List<Capability> caps = res.getCapabilities(IdentityNamespace.IDENTITY_NAMESPACE); - if (caps.size() != 1) { - throw new IllegalStateException("Resource does not have a single " + IdentityNamespace.IDENTITY_NAMESPACE + " capability"); - } - dirs = new HashMap<String, String>(); - attrs = new HashMap<String, Object>(); - attrs.put(IdentityNamespace.IDENTITY_NAMESPACE, caps.get(0).getAttributes().get(IdentityNamespace.IDENTITY_NAMESPACE)); - attrs.put(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE, caps.get(0).getAttributes().get(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE)); - attrs.put(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE, new VersionRange((Version) caps.get(0).getAttributes().get(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE), true)); - resource.addRequirement(new RequirementImpl(resource, IdentityNamespace.IDENTITY_NAMESPACE, dirs, attrs)); - } - } - for (Dependency dep : feature.getDependencies()) { - addDependency(resource, dep, featureRange); - } - for (org.apache.karaf.features.Capability cap : feature.getCapabilities()) { - resource.addCapabilities(ResourceBuilder.parseCapability(resource, cap.getValue())); - } - for (org.apache.karaf.features.Requirement req : feature.getRequirements()) { - resource.addRequirements(ResourceBuilder.parseRequirement(resource, req.getValue())); - } - return resource; - } - - protected static void addDependency(FeatureResource resource, Dependency dep, String featureRange) { - Map<String, String> dirs; - Map<String, Object> attrs; - String name = dep.getName(); - String version = dep.getVersion(); - if (version.equals("0.0.0")) { - version = null; - } else if (!version.startsWith("[") && !version.startsWith("(")) { - version = Macro.transform(featureRange, version); - } - dirs = new HashMap<String, String>(); - attrs = new HashMap<String, Object>(); - attrs.put(FeatureNamespace.FEATURE_NAMESPACE, name); - if (version != null) { - attrs.put(FeatureNamespace.CAPABILITY_VERSION_ATTRIBUTE, new VersionRange(version)); - } - resource.addRequirement(new RequirementImpl(resource, FeatureNamespace.FEATURE_NAMESPACE, dirs, attrs)); - } - - public FeatureResource(Feature feature) { - super(feature.getName(), FeatureNamespace.TYPE_FEATURE, VersionTable.getVersion(feature.getVersion())); - this.feature = feature; - } - - public Feature getFeature() { - return feature; - } -} http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/resolver/IdentityCapability.java ---------------------------------------------------------------------- diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/IdentityCapability.java b/features/core/src/main/java/org/apache/karaf/features/internal/resolver/IdentityCapability.java deleted file mode 100644 index cdc00d1..0000000 --- a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/IdentityCapability.java +++ /dev/null @@ -1,63 +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.HashMap; -import java.util.Map; - -import org.osgi.framework.Version; -import org.osgi.framework.namespace.IdentityNamespace; -import org.osgi.resource.Capability; -import org.osgi.resource.Resource; - -class IdentityCapability extends BaseClause implements Capability -{ - private final Resource m_resource; - private final Map<String, String> m_dirs; - private final Map<String, Object> m_attrs; - - public IdentityCapability(Resource resource, String name, String type, Version version) - { - m_resource = resource; - m_dirs = new HashMap<String, String>(); - m_attrs = new HashMap<String, Object>(); - m_attrs.put(IdentityNamespace.IDENTITY_NAMESPACE, name); - m_attrs.put(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE, type); - m_attrs.put(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE, version); - } - - public String getNamespace() - { - return IdentityNamespace.IDENTITY_NAMESPACE; - } - - public Map<String, String> getDirectives() - { - return m_dirs; - } - - public Map<String, Object> getAttributes() - { - return m_attrs; - } - - public Resource getResource() - { - return m_resource; - } - -} http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/resolver/RequirementImpl.java ---------------------------------------------------------------------- diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/RequirementImpl.java b/features/core/src/main/java/org/apache/karaf/features/internal/resolver/RequirementImpl.java deleted file mode 100644 index a4ef775..0000000 --- a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/RequirementImpl.java +++ /dev/null @@ -1,80 +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.Map; - -import org.osgi.framework.Constants; -import org.osgi.resource.Capability; -import org.osgi.resource.Requirement; -import org.osgi.resource.Resource; - -public class RequirementImpl extends BaseClause implements Requirement { - private final Resource m_resource; - private final String m_namespace; - private final SimpleFilter m_filter; - private final boolean m_optional; - private final Map<String, String> m_dirs; - private final Map<String, Object> m_attrs; - - public RequirementImpl( - Resource resource, String namespace, - Map<String, String> dirs, Map<String, Object> attrs, SimpleFilter filter) { - m_resource = resource; - m_namespace = namespace; - m_dirs = dirs; - m_attrs = attrs; - m_filter = filter; - // Find resolution import directives. - m_optional = Constants.RESOLUTION_OPTIONAL.equals(m_dirs.get(Constants.RESOLUTION_DIRECTIVE)); - } - - public RequirementImpl( - Resource resource, String namespace, - Map<String, String> dirs, Map<String, Object> attrs) { - this(resource, namespace, dirs, attrs, SimpleFilter.convert(attrs)); - } - - public String getNamespace() { - return m_namespace; - } - - public Map<String, String> getDirectives() { - return m_dirs; - } - - public Map<String, Object> getAttributes() { - return m_attrs; - } - - public Resource getResource() { - return m_resource; - } - - public boolean matches(Capability cap) { - return CapabilitySet.matches(cap, getFilter()); - } - - public boolean isOptional() { - return m_optional; - } - - public SimpleFilter getFilter() { - return m_filter; - } - -} http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/resolver/ResolveContextImpl.java ---------------------------------------------------------------------- diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/ResolveContextImpl.java b/features/core/src/main/java/org/apache/karaf/features/internal/resolver/ResolveContextImpl.java deleted file mode 100644 index e2ff793..0000000 --- a/features/core/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; - } -}