Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
Copyright (C) FuseSource, Inc. http://fusesource.com Licensed 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.fusesource.fabric.dosgi.capset;
 
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
 public class CapabilitySet<C extends Capability>
 {
     private final Map<StringMap<ObjectSet<C>>> m_indices;
     private final Set<C> m_capSet = new HashSet<C>();
     private final ReadWriteLock m_lock = new ReentrantReadWriteLock();
 
     public CapabilitySet(List<StringindexPropsboolean caseSensitive)
     {
          = (caseSensitive)
             ? new TreeMap<StringMap<ObjectSet<C>>>()
             : new TreeMap<StringMap<ObjectSet<C>>>(.);
         for (int i = 0; (indexProps != null) && (i < indexProps.size()); i++)
         {
             .put(indexProps.get(i), new HashMap<ObjectSet<C>>());
         }
     }
 
     public void addCapability(C cap)
     {
         .writeLock().lock();
         try
         {
             doAddCapability(cap);
         }
         finally
         {
             .writeLock().unlock();
         }
     }
 
     private void doAddCapability(C cap)
     {
         .add(cap);
 
         // Index capability.
         for (Entry<StringMap<ObjectSet<C>>> entry : .entrySet())
         {
             Attribute capAttr = cap.getAttribute(entry.getKey());
             if (capAttr != null)
             {
                 Object capValue = capAttr.getValue();
                 if (capValue.getClass().isArray())
                 {
                     capValue = convertArrayToList(capValue);
                 }
 
                 Map<ObjectSet<C>> index = entry.getValue();
 
                 if (capValue instanceof Collection)
                 {
                     Collection c = (CollectioncapValue;
                     for (Object o : c)
                     {
                         indexCapability(indexcapo);
                     }
                 }
                 else
                 {
                     indexCapability(indexcapcapValue);
                 }
             }
         }
     }
 
     private void indexCapability(
         Map<ObjectSet<C>> index, C capObject capValue)
    {
        Set<C> caps = index.get(capValue);
        if (caps == null)
        {
            caps = new HashSet<C>();
            index.put(capValuecaps);
        }
        caps.add(cap);
    }
    public void removeCapability(C cap)
    {
        .writeLock().lock();
        try
        {
            doRemoveCapability(cap);
        }
        finally
        {
            .writeLock().unlock();
        }
    }
    private void doRemoveCapability(C cap)
    {
        if (.remove(cap))
        {
            for (Entry<StringMap<ObjectSet<C>>> entry : .entrySet())
            {
                Attribute capAttr = cap.getAttribute(entry.getKey());
                if (capAttr != null)
                {
                    Object capValue = capAttr.getValue();
                    if (capValue.getClass().isArray())
                    {
                        capValue = convertArrayToList(capValue);
                    }
                    Map<ObjectSet<C>> index = entry.getValue();
                    if (capValue instanceof Collection)
                    {
                        Collection c = (CollectioncapValue;
                        for (Object o : c)
                        {
                            deindexCapability(indexcapo);
                        }
                    }
                    else
                    {
                        deindexCapability(indexcapcapValue);
                    }
                }
            }
        }
    }
    private void deindexCapability(
        Map<ObjectSet<C>> index, C capObject capValue)
    {
        Set<C> caps = index.get(capValue);
        if (caps != null)
        {
            caps.remove(cap);
            if (caps.isEmpty())
            {
                index.remove(capValue);
            }
        }
    }
    public Set<C> match(SimpleFilter sf)
    {
        .readLock().lock();
        try
        {
            return match(sf);
        }
        finally
        {
            .readLock().unlock();
        }
    }
    private Set<C> match(Set<C> capsSimpleFilter sf)
    {
        Set<C> matches = new HashSet<C>();
        if (sf.getOperation() == .)
        {
            matches.addAll(caps);
        }
        else if (sf.getOperation() == .)
        {
            // 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<SimpleFiltersfs = (List<SimpleFilter>) sf.getValue();
            for (int i = 0; (caps.size() > 0) && (i < sfs.size()); i++)
            {
                matches = match(capssfs.get(i));
                caps = matches;
            }
        }
        else if (sf.getOperation() == .)
        {
            // Evaluate each subfilter against the remaining capabilities.
            // For OR we calculate the union of each subfilter.
            List<SimpleFiltersfs = (List<SimpleFilter>) sf.getValue();
            for (int i = 0; i < sfs.size(); i++)
            {
                matches.addAll(match(capssfs.get(i)));
            }
        }
        else if (sf.getOperation() == .)
        {
            // Evaluate each subfilter against the remaining capabilities.
            // For OR we calculate the union of each subfilter.
            matches.addAll(caps);
            List<SimpleFiltersfs = (List<SimpleFilter>) sf.getValue();
            for (int i = 0; i < sfs.size(); i++)
            {
                matches.removeAll(match(capssfs.get(i)));
            }
        }
        else
        {
            Map<ObjectSet<C>> index = .get(sf.getName());
            if ((sf.getOperation() == .) && (index != null))
            {
                Set<C> existingCaps = index.get(sf.getValue());
                if (existingCaps != null)
                {
                    matches.addAll(existingCaps);
                    matches.retainAll(caps);
                }
            }
            else
            {
                for (Iterator<C> it = caps.iterator(); it.hasNext(); )
                {
                    C cap = it.next();
                    Attribute attr = cap.getAttribute(sf.getName());
                    if (attr != null)
                    {
                        Object lhs = attr.getValue();
                        if (compare(lhssf.getValue(), sf.getOperation()))
                        {
                            matches.add(cap);
                        }
                    }
                }
            }
        }
        return matches;
    }
    public static boolean matches(Capability capSimpleFilter sf)
    {
        return matchesInternal(capsf);
    }
    private static boolean matchesInternal(Capability capSimpleFilter sf)
    {
        boolean matched = true;
        if (sf.getOperation() == .)
        {
            // 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<SimpleFiltersfs = (List<SimpleFilter>) sf.getValue();
            for (int i = 0; matched && (i < sfs.size()); i++)
            {
                matched = matchesInternal(capsfs.get(i));
            }
        }
        else if (sf.getOperation() == .)
        {
            // Evaluate each subfilter against the remaining capabilities.
            // For OR we calculate the union of each subfilter.
            matched = false;
            List<SimpleFiltersfs = (List<SimpleFilter>) sf.getValue();
            for (int i = 0; !matched && (i < sfs.size()); i++)
            {
                matched = matchesInternal(capsfs.get(i));
            }
        }
        else if (sf.getOperation() == .)
        {
            // Evaluate each subfilter against the remaining capabilities.
            // For OR we calculate the union of each subfilter.
            List<SimpleFiltersfs = (List<SimpleFilter>) sf.getValue();
            for (int i = 0; i < sfs.size(); i++)
            {
                matched = !(matchesInternal(capsfs.get(i)));
            }
        }
        else
        {
            matched = false;
            Attribute attr = cap.getAttribute(sf.getName());
            if (attr != null)
            {
                Object lhs = attr.getValue();
                matched = compare(lhssf.getValue(), sf.getOperation());
            }
        }
        return matched;
    }
    private static final Class[] STRING_CLASS = new Class[] { String.class };
    private static boolean compare(Object lhsObject rhsUnknownint op)
    {
        // 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 == .)
        {
            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 == .) && !(lhs instanceof String))
            {
                return false;
            }
            Object rhs;
            if (op == .)
            {
                rhs = rhsUnknown;
            }
            else
            {
                try
                {
                    rhs = coerceType(lhs, (StringrhsUnknown);
                }
                catch (Exception ex)
                {
                    return false;
                }
            }
            switch (op)
            {
                case . :
                    return (((Comparablelhs).compareTo(rhs) == 0);
                case . :
                    return (((Comparablelhs).compareTo(rhs) >= 0);
                case . :
                    return (((Comparablelhs).compareTo(rhs) <= 0);
                case . :
                    return compareApproximate(((Comparablelhs), rhs);
                case . :
                    return SimpleFilter.compareSubstring((List<String>) rhs, (Stringlhs);
                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, (StringrhsUnknown);
            }
            catch (Exception ex)
            {
                return false;
            }
            switch (op)
            {
                case . :
                case . :
                case . :
                case . :
                    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 = ((Collectionlhs).iterator(); iter.hasNext(); )
            {
                if (compare(iter.next(), rhsUnknownop))
                {
                    return true;
                }
            }
            return false;
        }
        // Spec says SUBSTRING is false for all types other than string.
        if ((op == .) && !(lhs instanceof String))
        {
            return false;
        }
        // Since we cannot identify the LHS type, then we can only perform
        // equality comparison.
// TODO: COMPLIANCE - This should be changed to return false in case
//       of an exception, but the R4.2 CT has a mistake in it, so for
//       now we'll throw exceptions from equals().
//        try
//        {
//            return lhs.equals(coerceType(lhs, (String) rhsUnknown));
//        }
//        catch (Exception ex)
//        {
//            return false;
//        }
        Object rhsObj = null;
        try
        {
            rhsObj = coerceType(lhs, (StringrhsUnknown);
        }
        catch (Exception ex)
        {
            return false;
        }
        return lhs.equals(rhsObj);
    }
    private static boolean compareApproximate(Object lhsObject rhs)
    {
        if (rhs instanceof String)
        {
            return removeWhitespace((Stringlhs)
                .equalsIgnoreCase(removeWhitespace((Stringrhs));
        }
        else if (rhs instanceof Character)
        {
            return Character.toLowerCase(((Characterlhs))
                == Character.toLowerCase(((Characterrhs));
        }
        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 lhsString rhsStringthrows 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;
        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 = rhsString.charAt(0);
            }
            else
            {
                Constructor ctor = lhs.getClass().getConstructor();
                ctor.setAccessible(true);
                rhs = ctor.newInstance(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.

Parameters:
array An array of primitive types.
Returns:
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 < leni++)
        {
            list.add(Array.get(arrayi));
        }
        return list;
    }
New to GrepCode? Check out our FAQ X