harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From telli...@apache.org
Subject svn commit: r652375 - in /harmony/enhanced/classlib/trunk/modules/jndi/src: main/java/org/apache/harmony/jndi/internal/nls/ main/java/org/apache/harmony/jndi/provider/ldap/ test/java/org/apache/harmony/jndi/provider/ldap/
Date Wed, 30 Apr 2008 12:42:44 GMT
Author: tellison
Date: Wed Apr 30 05:42:44 2008
New Revision: 652375

URL: http://svn.apache.org/viewvc?rev=652375&view=rev
Log:
Apply patch HARMONY-5795 ([classlib][jndi][ldap] - Refine search methods in LdapSchemaContextImpl)

Added:
    harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapSchemaFilter.java   (with props)
Modified:
    harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/internal/nls/messages.properties
    harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapSchemaContextImpl.java
    harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/ldap/LdapSchemaContextTest.java

Modified: harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/internal/nls/messages.properties
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/internal/nls/messages.properties?rev=652375&r1=652374&r2=652375&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/internal/nls/messages.properties (original)
+++ harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/internal/nls/messages.properties Wed Apr 30 05:42:44 2008
@@ -160,7 +160,6 @@
 jndi.8E=Cannot create new entry under schema root
 jndi.8F=Class definition doesn'thave a numeric OID
 jndi.90={0} does not have a syntax associated with it
-jndi.err.00=. The stack trace of the root exception is: 
 ldap.00=Should not be null
 ldap.01=is not an LdapName
 ldap.02=Posn must be in the range [0,size()]
@@ -219,3 +218,4 @@
 ldap.36=Must have numeric OID
 ldap.37=Can't delete schema root
 ldap.38=Can't modify schema root
+ldap.39=Can't rename schema

Modified: harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapSchemaContextImpl.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapSchemaContextImpl.java?rev=652375&r1=652374&r2=652375&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapSchemaContextImpl.java (original)
+++ harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapSchemaContextImpl.java Wed Apr 30 05:42:44 2008
@@ -16,14 +16,11 @@
  */
 package org.apache.harmony.jndi.provider.ldap;
 
-import java.util.ArrayList;
-import java.util.Arrays;
+import java.util.HashSet;
 import java.util.Hashtable;
 import java.util.Iterator;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Set;
-import java.util.TreeSet;
 
 import javax.naming.Binding;
 import javax.naming.CompositeName;
@@ -42,35 +39,31 @@
 import javax.naming.directory.BasicAttribute;
 import javax.naming.directory.BasicAttributes;
 import javax.naming.directory.DirContext;
-import javax.naming.directory.InvalidSearchFilterException;
 import javax.naming.directory.ModificationItem;
 import javax.naming.directory.SchemaViolationException;
 import javax.naming.directory.SearchControls;
 import javax.naming.directory.SearchResult;
 
 import org.apache.harmony.jndi.internal.nls.Messages;
-import org.apache.harmony.jndi.internal.parser.AttributeTypeAndValuePair;
-import org.apache.harmony.jndi.provider.ldap.parser.FilterParser;
-import org.apache.harmony.jndi.provider.ldap.parser.ParseException;
 import org.apache.harmony.jndi.provider.ldap.parser.SchemaParser;
 
 public class LdapSchemaContextImpl extends LdapContextImpl {
 
-    public static final String CLASS_DEFINITION = "ClassDefinition";
+    public static final String CLASS_DEFINITION = "ClassDefinition"; //$NON-NLS-1$
 
-    public static final String ATTRIBUTE_DEFINITION = "AttributeDefinition";
+    public static final String ATTRIBUTE_DEFINITION = "AttributeDefinition"; //$NON-NLS-1$
 
-    public static final String SYNTAX_DEFINITION = "SyntaxDefinition";
+    public static final String SYNTAX_DEFINITION = "SyntaxDefinition"; //$NON-NLS-1$
 
-    public static final String MATCHING_RULE = "MatchingRule";
+    public static final String MATCHING_RULE = "MatchingRule"; //$NON-NLS-1$
 
-    public static final String OBJECT_CLASSES = "objectclasses";
+    public static final String OBJECT_CLASSES = "objectclasses"; //$NON-NLS-1$
 
-    public static final String ATTRIBUTE_TYPES = "attributetypes";
+    public static final String ATTRIBUTE_TYPES = "attributetypes"; //$NON-NLS-1$
 
-    public static final String LDAP_SYNTAXES = "ldapsyntaxes";
+    public static final String LDAP_SYNTAXES = "ldapsyntaxes"; //$NON-NLS-1$
 
-    public static final String MATCHING_RULES = "matchingrules";
+    public static final String MATCHING_RULES = "matchingrules"; //$NON-NLS-1$
 
     public static final int SCHEMA_ROOT_LEVEL = 3;
 
@@ -102,13 +95,6 @@
     private int level;
 
     public LdapSchemaContextImpl(LdapContextImpl ctx,
-            Hashtable<Object, Object> env, Name dn) throws InvalidNameException {
-        super(ctx, env, dn.getPrefix(0).toString());
-        parent = ctx;
-        rdn = dn;
-    }
-
-    public LdapSchemaContextImpl(LdapContextImpl ctx,
             Hashtable<Object, Object> env, Name dn,
             Hashtable<String, Object> schemaTable, int level)
             throws InvalidNameException {
@@ -475,24 +461,6 @@
         destroySubcontext(convertFromStringToName(name));
     }
 
-    private String ldap2jndi(String jndiName) {
-        String ldapName = schemaLdap2Jndi.get(jndiName);
-        if (null == ldapName) {
-            ldapName = jndiName;
-        }
-
-        return ldapName;
-    }
-
-    private String jndi2ldap(String ldapName) {
-        String jndiName = schemaJndi2Ldap.get(ldapName.toLowerCase());
-        if (null == jndiName) {
-            jndiName = ldapName;
-        }
-
-        return jndiName.toLowerCase();
-    }
-
     @Override
     public NamingEnumeration<NameClassPair> list(Name name)
             throws NamingException {
@@ -624,300 +592,229 @@
         return lookup(convertFromStringToName(name));
     }
 
+    @Override
     public void rename(Name nOld, Name nNew) throws NamingException {
-        throw new SchemaViolationException(Messages.getString("jndi.err.01"));
+        // ldap.39=Can't rename schema
+        throw new SchemaViolationException(Messages.getString("ldap.39")); //$NON-NLS-1$
     }
 
+    @Override
     public void rename(String sOld, String sNew) throws NamingException {
-        throw new SchemaViolationException(Messages.getString("jndi.err.01"));
+        // ldap.39=Can't rename schema
+        throw new SchemaViolationException(Messages.getString("ldap.39")); //$NON-NLS-1$
     }
 
+    @Override
     public NamingEnumeration<SearchResult> search(Name name,
             Attributes attributes) throws NamingException {
         return search(name, attributes, null);
     }
 
+    @Override
     public NamingEnumeration<SearchResult> search(Name name,
-    // Used to filter attribute value
-            Attributes attributes,
-            // Used to filter attribute name
-            String[] as) throws NamingException {
-        checkName(name);
-
-        Name targetDN = name.addAll(rdn);
-
-        /*
-         * Formalize attributes, change all ids to lowercase, if attributes is
-         * non-null
-         */
-
-        boolean hasMatchingAttributes = (null != attributes && 0 != attributes
-                .size());
-        boolean hasAttributes2Return = (null != as && 0 != as.length);
-
-        // Attribute matcher
-        BasicAttributes attrMatcher = new BasicAttributes(true);
-        if (hasMatchingAttributes) {
-            NamingEnumeration<? extends Attribute> attrEnum = attributes
-                    .getAll();
-            while (attrEnum.hasMore()) {
-                Attribute old = attrEnum.next();
-                BasicAttribute newAttr = new BasicAttribute(old.getID()
-                        .toLowerCase());
-                for (int i = 0; i < old.size(); i++) {
-                    if (old.get(i) instanceof String) {
-                        newAttr.add(((String) old.get(i)).toLowerCase());
-                    } else {
-                        newAttr.add(old.get(i));
-                    }
-                }
-                attrMatcher.put(newAttr);
-            }
-        }
+            Attributes matchingAttributes, String[] attributesToReturn)
+            throws NamingException {
+        int size = name.size();
 
-        // Attribute selector
-        TreeSet<String> attrSel = new TreeSet<String>();
+        Hashtable<String, Object> subschemaTable = doLookup(name, size);
 
-        // Construct result NamingEnumeration
         LdapNamingEnumeration<SearchResult> enumeration = new LdapNamingEnumeration<SearchResult>(
                 null, null);
-        String schemaType = null;
+        SearchResult searchResult;
+        Attributes schemaAttributes;
+        String schemaName;
+        Set<String> keyset;
 
-        LinkedList<String> attrValues = new LinkedList<String>();
-        int size = targetDN.size();
-        switch (size) {
-        case 0:
-            /*
-             * Name is a empty string, search against root, may return schema
-             * types: (classdefinition, attributedefinition, syntaxdefinition,
-             * matchingrule)
-             */
-            attrValues.addAll(LdapContextImpl.schemaTree.keySet());
-            /*
-             * Filter attribute names - whether the single attribute name
-             * 'objectclass' is chosen.
-             */
-            int objectclassIndex = -1;
-            if (hasAttributes2Return) {
-                for (int i = 0; i < as.length; i++) {
-                    if (as[i].equalsIgnoreCase("objectclass")) {
-                        objectclassIndex = i;
-                        break;
-                    }
+        if (level - size > 1) {
+            keyset = subschemaTable.keySet();
+            for (Iterator<String> i = keyset.iterator(); i.hasNext();) {
+                schemaName = ldap2jndi(i.next());
+                Name tempName = (Name) name.clone();
+                schemaAttributes = getAttributes(tempName.add(schemaName));
+
+                if (isMatch(schemaAttributes, matchingAttributes)) {
+                    schemaAttributes = filterAttributes(schemaAttributes,
+                            attributesToReturn);
+                    searchResult = new SearchResult(
+                            ldap2jndi(schemaName), this.getClass().getName(),
+                            null, schemaAttributes);
+                    enumeration.add(searchResult);
                 }
             }
-            attrSel.add("objectclass");
+        }
+        return enumeration;
+    }
 
-            /*
-             * Filter attribute values - choose from (classdefinition,
-             * attributedefinition, syntaxdefinition, matchingrule)
-             */
-            if (hasMatchingAttributes) {
-                Attribute attribute = attrMatcher.get("objectclass");
-                if (null == attribute) {
-                    return enumeration;
-                }
-                for (int i = 0; i < attrValues.size(); i++) {
-                    schemaType = schemaLdap2Jndi.get(attrValues.get(i));
-                    /*
-                     * RI's behavior is odd here - it only retrieves the first
-                     * encountered attribute value,
-                     */
-                    if (attribute.contains(schemaType)) {
-                        BasicAttributes basicAttributes = new BasicAttributes(
-                                true);
-                        /*
-                         * if(objectclassIndex == -1), then No name was choose,
-                         * which means SearchResult will have empty
-                         * BasicAttributes.
-                         */
-                        if (objectclassIndex != -1) {
-                            basicAttributes.put("objectclass", schemaType);
-                        }
-                        SearchResult pair = new SearchResult(schemaType, null,
-                                basicAttributes);
-                        enumeration.add(pair);
-                        break;
-                    }
-                }
-            } else {
-                for (int i = 0; i < attrValues.size(); i++) {
-                    schemaType = schemaLdap2Jndi.get(attrValues.get(i));
-                    BasicAttributes basicAttributes = new BasicAttributes(true);
-                    /*
-                     * if(objectclassIndex == -1), then No name was choose,
-                     * which means SearchResult will have empty BasicAttributes.
-                     */
-                    if (objectclassIndex != -1) {
-                        basicAttributes.put("objectclass", schemaType);
-                    }
-                    SearchResult pair = new SearchResult(schemaType, null,
-                            basicAttributes);
-                    enumeration.add(pair);
-                }
-            }
-            break;
-        case 1:
-            if (hasAttributes2Return) {
-                attrSel.addAll(Arrays.asList(as));
-            }
-            schemaType = schemaJndi2Ldap.get(name.get(0).toLowerCase());
-            if (null == schemaType) {
-                throw new NameNotFoundException(name.toString());
-            }
-            Hashtable<String, Hashtable<String, Object>> schemas = LdapContextImpl.schemaTree
-                    .get(schemaType);
-            attrValues.addAll(schemas.keySet());
-            BasicAttributes basicAttributes = null;
-            if (hasMatchingAttributes) {
-                for (int i = 0; i < attrValues.size(); i++) {
-                    NamingEnumeration<Attribute> filters = attrMatcher.getAll();
-                    String id = attrValues.get(i);
-                    Hashtable<String, Object> schemaDef = schemas.get(id);
-                    boolean matched = true;
-                    while (filters.hasMore()) {
-                        Attribute filter = filters.next();
-                        Object values = schemaDef.get(filter.getID());
-                        /*
-                         * Attribute definition will only be retrieved when it
-                         * is designated in attrFilter
-                         */
-                        if (values == null || !match(filter, values)) {
-                            matched = false;
-                            break;
-                        }
-                    }
-                    if (matched) {
-                        basicAttributes = new BasicAttributes(true);
-                        for (Iterator<String> iterator = schemaDef.keySet()
-                                .iterator(); iterator.hasNext();) {
-                            String key = iterator.next();
-                            if (key.equals("orig")) {
-                                continue;
-                            }
-                            if (hasAttributes2Return && attrSel.contains(key)
-                                    || !hasAttributes2Return) {
-                                basicAttributes.put(key, schemaDef.get(key));
-                            }
-                        }
-                        SearchResult pair = new SearchResult(id, null,
-                                basicAttributes);
-                        enumeration.add(pair);
-                    }
+    @Override
+    public NamingEnumeration<SearchResult> search(Name name, String filter,
+            SearchControls searchControls) throws NamingException {
+        return search(name, filter, null, searchControls);
+    }
+
+    @Override
+    public NamingEnumeration<SearchResult> search(Name name, String filter,
+            Object[] filterArgs, SearchControls searchControls)
+            throws NamingException {
+
+        HashSet<SearchResult> searchResults = new HashSet<SearchResult>();
+        Iterator<SearchResult> iterator;
+        SearchResult searchResult;
+
+        Attributes schemaAttributes;
+
+        // Default search scope is ONELEVEL_SCOPE.
+        if (searchControls == null
+                || searchControls.getSearchScope() == SearchControls.ONELEVEL_SCOPE) {
+            searchResults = doSimpleSearch(name, false);
+
+        }
+        // SearchControls.SUBTREE_SCOPE
+        else if (searchControls.getSearchScope() == SearchControls.SUBTREE_SCOPE) {
+            searchResults = doSimpleSearch(name, true);
+        }
+
+        // SearchControls.OBJECT_SCOPE.
+        else {
+            schemaAttributes = getAttributes(name);
+            searchResult = new SearchResult(
+                    ldap2jndi(name.toString()), this.getClass().getName(),
+                    null, schemaAttributes);
+            searchResults.add(searchResult);
+        }
+
+        LdapSchemaFilter schemaFilter = new LdapSchemaFilter(filter, filterArgs);
+        searchResults = schemaFilter.filter(searchResults);
+
+        if (searchControls != null
+                && searchControls.getReturningAttributes() != null) {
+            String[] attributesToReturn = searchControls
+                    .getReturningAttributes();
+            // Take the 0 as special case to improve perfomance.
+            if (attributesToReturn.length > 0) {
+                iterator = searchResults.iterator();
+                while (iterator.hasNext()) {
+                    searchResult = iterator.next();
+                    schemaAttributes = filterAttributes(searchResult
+                            .getAttributes(), attributesToReturn);
+                    searchResult.setAttributes(schemaAttributes);
                 }
             } else {
-                for (int i = 0; i < attrValues.size(); i++) {
-                    Hashtable<String, Object> schemaDef = schemas
-                            .get(attrValues.get(i));
-                    basicAttributes = new BasicAttributes(true);
-                    for (Iterator<String> iterator = schemaDef.keySet()
-                            .iterator(); iterator.hasNext();) {
-                        String key = iterator.next();
-                        if (key.equals("orig")) {
-                            continue;
-                        }
-                        if (hasAttributes2Return && attrSel.contains(key)
-                                || !hasAttributes2Return) {
-                            basicAttributes.put(key, schemaDef.get(key));
-                        }
-                    }
-                    SearchResult pair = new SearchResult(attrValues.get(i),
-                            null, basicAttributes);
-                    enumeration.add(pair);
+                iterator = searchResults.iterator();
+                while (iterator.hasNext()) {
+                    searchResult = iterator.next();
+                    searchResult.setAttributes(new BasicAttributes(true));
                 }
             }
-            break;
+        }
 
-        default:
-            schemaType = schemaJndi2Ldap.get(name.getPrefix(1).toString()
-                    .toLowerCase());
-            if (null == schemaType) {
-                throw new NameNotFoundException(name.toString());
-            }
-            search(name.getSuffix(1), attributes, as);
+        LdapNamingEnumeration<SearchResult> enumeration = new LdapNamingEnumeration<SearchResult>(
+                null, null);
+
+        iterator = searchResults.iterator();
+        while (iterator.hasNext()) {
+            enumeration.add(iterator.next());
         }
-        return enumeration;
 
+        return enumeration;
     }
 
-    private boolean match(Attribute filter, Object values)
-            throws NamingException {
-        NamingEnumeration<?> attrValues = filter.getAll();
-        ArrayList<Object> v = null;
-        if (values instanceof ArrayList) {
-            v = (ArrayList<Object>) values;
-        } else {
-            v = new ArrayList<Object>();
-            v.add(values);
+    private HashSet<SearchResult> doSimpleSearch(Name name,
+            boolean searchSubTree) throws NamingException {
+        int size = name.size();
+        Hashtable<String, Object> subschemaTable = doLookup(name, size);
+
+        HashSet<SearchResult> searchResults = new HashSet<SearchResult>();
+        HashSet<SearchResult> tempResults;
+        SearchResult searchResult;
+        Attributes schemaAttributes;
+        String schemaName;
+        Set<String> keyset;
+
+        keyset = subschemaTable.keySet();
+        for (Iterator<String> i = keyset.iterator(); i.hasNext();) {
+            schemaName = ldap2jndi(i.next());
+            Name tempName = (Name) name.clone();
+            tempName = tempName.add(schemaName);
+            if (tempName.size() < level) {
+                schemaAttributes = getAttributes(tempName);
+                searchResult = new SearchResult(tempName.toString(),
+                        this.getClass().getName(), null, schemaAttributes);
+                searchResults.add(searchResult);
+
+                if (searchSubTree) {
+                    tempResults = doSimpleSearch(tempName, searchSubTree);
+                    searchResults.addAll(tempResults);
+                }
+            }
+        }
+        return searchResults;
+    }
+
+    private Attributes filterAttributes(Attributes attributes,
+            String[] attributesToReturn) {
+        if (attributesToReturn == null) {
+            return attributes;
         }
 
-        while (attrValues.hasMore()) {
-            Object attrValue = attrValues.next();
-            for (int i = 0; i < v.size(); i++) {
-                if (attrValue.equals("*") || attrValue.equals(v.get(i))) {
-                    return true;
+        Attribute attribute;
+        Attributes filteredAttrs = new BasicAttributes(true);
+        for (int i = 0; i < attributesToReturn.length; i++) {
+            if (attributesToReturn[i] != null) {
+                attribute = attributes.get(attributesToReturn[i]);
+                if (attribute != null) {
+                    filteredAttrs.put(attribute);
                 }
             }
         }
-        return false;
+
+        return filteredAttrs;
     }
 
-    public NamingEnumeration<SearchResult> search(Name name, String filter,
-            Object[] objs, SearchControls searchControls)
-            throws NamingException {
+    private boolean isMatch(Attributes schemaAttributes,
+            Attributes matchingAttributes) throws NamingException {
+        if (matchingAttributes == null) {
+            return true;
+        }
 
-        checkName(name);
+        NamingEnumeration<? extends Attribute> enumeration = matchingAttributes
+                .getAll();
+        Attribute matchAttribute;
+        Attribute schemaAttribute;
+        String id;
+        while (enumeration.hasMore()) {
+            matchAttribute = enumeration.next();
+            id = matchAttribute.getID();
+            schemaAttribute = schemaAttributes.get(id);
+            if (schemaAttribute == null) {
+                return false;
+            }
 
-        if (filter == null) {
-            throw new NullPointerException(Messages.getString("ldap.28")); //$NON-NLS-1$
-        }
-        if (filter.length() == 0) {
-            throw new StringIndexOutOfBoundsException();
-        }
-        if (!filter.startsWith("(")) {
-            StringBuilder filterWrapper = new StringBuilder("(");
-            filterWrapper.append(filter).append(")");
-            filter = filterWrapper.toString();
+            NamingEnumeration<?> singleEnu = matchAttribute.getAll();
+            while (singleEnu.hasMore()) {
+                if (!schemaAttribute.contains(singleEnu.next())) {
+                    return false;
+                }
+            }
         }
 
-        if (null == searchControls) {
-            searchControls = new SearchControls();
+        return true;
+    }
+
+    private String ldap2jndi(String jndiName) {
+        String ldapName = schemaLdap2Jndi.get(jndiName);
+        if (null == ldapName) {
+            ldapName = jndiName;
         }
 
-        FilterParser filterParser = new FilterParser(filter);
-        filterParser.setArgs(objs);
-        Filter f = null;
-        try {
-            f = filterParser.parse();
-        } catch (ParseException e) {
-            InvalidSearchFilterException ex = new InvalidSearchFilterException(
-                    Messages.getString("ldap.29")); //$NON-NLS-1$
-            ex.setRootCause(e);
-            throw ex;
-        }
-
-        BasicAttributes matchingAttrs = new BasicAttributes(true);
-        extractMatchingAttributes(f, matchingAttrs);
-
-        return search(name, matchingAttrs, searchControls
-                .getReturningAttributes());
-    }
-
-    private void extractMatchingAttributes(Filter f,
-            BasicAttributes matchingAttrs) {
-        if (!f.isLeaf()) {
-            List<Filter> children = f.getChildren();
-            for (Iterator<Filter> iter = children.iterator(); iter.hasNext();) {
-                extractMatchingAttributes(iter.next(), matchingAttrs);
-            }
-        } else {
-            Object value = f.getValue();
-            if (value instanceof AttributeTypeAndValuePair) {
-                AttributeTypeAndValuePair pair = (AttributeTypeAndValuePair) value;
-                matchingAttrs.put(pair.getType(), pair.getValue());
-            } else {
-                matchingAttrs.put((String) value, "*");
-            }
+        return ldapName;
+    }
+
+    private String jndi2ldap(String ldapName) {
+        String jndiName = schemaJndi2Ldap.get(ldapName.toLowerCase());
+        if (null == jndiName) {
+            jndiName = ldapName;
         }
+
+        return jndiName.toLowerCase();
     }
 }

Added: harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapSchemaFilter.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapSchemaFilter.java?rev=652375&view=auto
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapSchemaFilter.java (added)
+++ harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapSchemaFilter.java Wed Apr 30 05:42:44 2008
@@ -0,0 +1,249 @@
+/* 
+ *  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.harmony.jndi.provider.ldap;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.InvalidSearchFilterException;
+import javax.naming.directory.SearchResult;
+
+import org.apache.harmony.jndi.internal.nls.Messages;
+import org.apache.harmony.jndi.internal.parser.AttributeTypeAndValuePair;
+import org.apache.harmony.jndi.provider.ldap.Filter.SubstringFilter;
+import org.apache.harmony.jndi.provider.ldap.asn1.ASN1ChoiceWrap.ChosenValue;
+import org.apache.harmony.jndi.provider.ldap.parser.FilterParser;
+import org.apache.harmony.jndi.provider.ldap.parser.ParseException;
+
+public class LdapSchemaFilter {
+    private Filter commonFilter;
+
+    public LdapSchemaFilter(String filterValue, Object[] filterArgs)
+            throws InvalidSearchFilterException {
+        try {
+            FilterParser commonFilterParser = new FilterParser(filterValue);
+            commonFilterParser.setArgs(filterArgs);
+            commonFilter = commonFilterParser.parse();
+        } catch (ParseException e) {
+            // ldap.29=Invalid search filter
+            throw new InvalidSearchFilterException(Messages
+                    .getString("ldap.29")); //$NON-NLS-1$
+        }
+    }
+
+    public HashSet<SearchResult> filter(
+            HashSet<SearchResult> results) throws NamingException {
+        return doFilter(results, commonFilter);
+    }
+
+    private HashSet<SearchResult> doFilter(
+            HashSet<SearchResult> currentResults, Filter filter)
+            throws NamingException {
+        List<Filter> filters;
+
+        HashSet<SearchResult> filteredResults = null;
+        HashSet<SearchResult> tempResults;
+        Iterator<SearchResult> iterator;
+        AttributeTypeAndValuePair pair;
+        String attributeType;
+        Object attributeValue;
+        SearchResult searchResult;
+        Attribute attr;
+        NamingEnumeration<?> valuesEnum;
+        Object value;
+        boolean hasMatch;
+
+        switch (filter.getType()) {
+        case Filter.AND_FILTER:
+            filteredResults = currentResults;
+            filters = filter.getChildren();
+            for (int i = 0; i < filters.size(); i++) {
+                filteredResults = doFilter(filteredResults, filters.get(i));
+            }
+            break;
+
+        case Filter.OR_FILTER:
+            filters = filter.getChildren();
+            filteredResults = new HashSet<SearchResult>();
+            for (int i = 0; i < filters.size(); i++) {
+                tempResults = doFilter(currentResults, filters.get(i));
+                filteredResults.addAll(tempResults);
+            }
+            break;
+
+        case Filter.NOT_FILTER:
+            filteredResults = new HashSet<SearchResult>();
+            Filter tempFilter = (Filter) filter.getValue();
+            tempResults = doFilter(currentResults, tempFilter);
+
+            iterator = currentResults.iterator();
+            while (iterator.hasNext()) {
+                searchResult = iterator.next();
+                if (!tempResults.contains(searchResult)) {
+                    filteredResults.add(searchResult);
+                }
+            }
+            break;
+
+        case Filter.EQUALITY_MATCH_FILTER:
+        case Filter.APPROX_MATCH_FILTER:
+            filteredResults = new HashSet<SearchResult>();
+            pair = (AttributeTypeAndValuePair) filter.getValue();
+            attributeType = pair.getType();
+            attributeValue = pair.getValue();
+
+            iterator = currentResults.iterator();
+            while (iterator.hasNext()) {
+                searchResult = iterator.next();
+                attr = searchResult.getAttributes().get(attributeType);
+                if (attr != null) {
+                    hasMatch = false;
+                    valuesEnum = attr.getAll();
+
+                    while (valuesEnum.hasMore()) {
+                        value = valuesEnum.next();
+                        if (attributeValue.toString().equalsIgnoreCase(
+                                value.toString())) {
+                            hasMatch = true;
+                        }
+                    }
+                    if (hasMatch) {
+                        filteredResults.add(searchResult);
+                    }
+                }
+            }
+            break;
+
+        case Filter.SUBSTRINGS_FILTER:
+            filteredResults = new HashSet<SearchResult>();
+            Filter.SubstringFilter substringFilter = (SubstringFilter) filter
+                    .getValue();
+            attributeType = substringFilter.getType();
+            List<ChosenValue> list = substringFilter.getSubstrings();
+            String attributePatternValue = ""; //$NON-NLS-1$
+            for (int i = 0; i < list.size(); i++) {
+                attributePatternValue += list.get(i).getValue().toString();
+            }
+
+            attributePatternValue = attributePatternValue.replaceAll("\\*", //$NON-NLS-1$
+                    ".*"); //$NON-NLS-1$
+            Pattern pattern = Pattern.compile(attributePatternValue,
+                    Pattern.CASE_INSENSITIVE);
+
+            iterator = currentResults.iterator();
+            while (iterator.hasNext()) {
+                searchResult = iterator.next();
+                attr = searchResult.getAttributes().get(attributeType);
+                if (attr != null) {
+                    hasMatch = false;
+                    valuesEnum = attr.getAll();
+                    while (valuesEnum.hasMore()) {
+                        value = valuesEnum.next();
+                        if (pattern.matcher(value.toString()).matches()) {
+                            hasMatch = true;
+                        }
+                    }
+                    if (hasMatch) {
+                        filteredResults.add(searchResult);
+                    }
+                }
+            }
+
+            break;
+
+        case Filter.GREATER_OR_EQUAL_FILTER:
+            filteredResults = new HashSet<SearchResult>();
+            pair = (AttributeTypeAndValuePair) filter.getValue();
+            attributeType = pair.getType();
+            attributeValue = pair.getValue();
+            iterator = currentResults.iterator();
+            while (iterator.hasNext()) {
+                searchResult = iterator.next();
+                attr = searchResult.getAttributes().get(attributeType);
+                if (attr != null) {
+                    hasMatch = false;
+                    valuesEnum = attr.getAll();
+                    while (valuesEnum.hasMore()) {
+                        value = valuesEnum.next();
+                        if ((value.toString().compareTo(attributeValue
+                                .toString())) >= 0) {
+                            hasMatch = true;
+                        }
+                    }
+                    if (hasMatch) {
+                        filteredResults.add(searchResult);
+                    }
+                }
+            }
+            break;
+
+        case Filter.LESS_OR_EQUAL_FILTER:
+            filteredResults = new HashSet<SearchResult>();
+            pair = (AttributeTypeAndValuePair) filter.getValue();
+            attributeType = pair.getType();
+            attributeValue = pair.getValue();
+            iterator = currentResults.iterator();
+            while (iterator.hasNext()) {
+                searchResult = iterator.next();
+                attr = searchResult.getAttributes().get(attributeType);
+                if (attr != null) {
+                    hasMatch = false;
+                    valuesEnum = attr.getAll();
+                    while (valuesEnum.hasMore()) {
+                        value = valuesEnum.next();
+
+                        if ((value.toString().compareTo(attributeValue
+                                .toString())) <= 0) {
+                            hasMatch = true;
+                        }
+                    }
+                    if (hasMatch) {
+                        filteredResults.add(searchResult);
+                    }
+                }
+            }
+            break;
+
+        case Filter.PRESENT_FILTER:
+            filteredResults = new HashSet<SearchResult>();
+            attributeType = filter.getValue().toString();
+            iterator = currentResults.iterator();
+            while (iterator.hasNext()) {
+                searchResult = iterator.next();
+                attr = searchResult.getAttributes().get(attributeType);
+                if (attr != null) {
+                    filteredResults.add(searchResult);
+                }
+            }
+            break;
+
+        case Filter.EXTENSIBLE_MATCH_FILTER:
+            // TODO
+            break;
+
+        default:
+            // Never reach here.
+        }
+
+        return filteredResults;
+    }
+}

Propchange: harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapSchemaFilter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/ldap/LdapSchemaContextTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/ldap/LdapSchemaContextTest.java?rev=652375&r1=652374&r2=652375&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/ldap/LdapSchemaContextTest.java (original)
+++ harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/ldap/LdapSchemaContextTest.java Wed Apr 30 05:42:44 2008
@@ -22,6 +22,7 @@
 
 import javax.naming.Binding;
 import javax.naming.CompositeName;
+import javax.naming.InvalidNameException;
 import javax.naming.Name;
 import javax.naming.NameClassPair;
 import javax.naming.NameNotFoundException;
@@ -33,18 +34,27 @@
 import javax.naming.directory.BasicAttribute;
 import javax.naming.directory.BasicAttributes;
 import javax.naming.directory.DirContext;
+import javax.naming.directory.InvalidSearchFilterException;
 import javax.naming.directory.ModificationItem;
 import javax.naming.directory.SchemaViolationException;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
 
 import junit.framework.TestCase;
 
 public class LdapSchemaContextTest extends TestCase {
     private LdapSchemaContextImpl schema;
 
+    private Hashtable<String, Object> schemaTable;
+
+    private LdapContextImpl context;
+
+    Name name;
+
     @Override
     public void setUp() throws Exception {
         // Construct the schema table.
-        Hashtable<String, Object> schemaTable = new Hashtable<String, Object>();
+        schemaTable = new Hashtable<String, Object>();
 
         Hashtable<String, Object> subSchema = new Hashtable<String, Object>();
         subSchema
@@ -91,9 +101,8 @@
                         "( 0.9.2342.19200300.100.1.49 name 'dsaquality' desc 'rfc1274: dsa quality'  syntax 1.3.6.1.4.1.1466.115.121.1.19 single-value usage userapplications x-schema 'cosine' )");
         schemaTable.put("attributetypes", subSchema);
 
-        LdapContextImpl context = new LdapContextImpl(new MockLdapClient(),
-                null, "");
-        Name name = new CompositeName("");
+        context = new LdapContextImpl(new MockLdapClient(), null, "");
+        name = new CompositeName("");
         schema = new LdapSchemaContextImpl(context, null, name, schemaTable,
                 LdapSchemaContextImpl.SCHEMA_ROOT_LEVEL);
     }
@@ -1402,4 +1411,660 @@
             // expected
         }
     }
+
+    public void testSimpleSearch() throws NamingException {
+        Attributes matchAttrs = new BasicAttributes();
+
+        // "" as parameter.
+        NamingEnumeration<SearchResult> ne = schema.search("", matchAttrs);
+
+        ArrayList<String> verifyList = new ArrayList<String>();
+        verifyList.add("ClassDefinition");
+        verifyList.add("AttributeDefinition");
+        verifyList.add("MatchingRule");
+        verifyList.add("SyntaxDefinition");
+
+        SearchResult result;
+        int count = 0;
+        int attributeCount = 0;
+        while (ne.hasMore()) {
+            result = ne.next();
+            count++;
+            assertTrue(verifyList.remove(result.getName()));
+            attributeCount += result.getAttributes().size();
+        }
+        assertEquals(4, count);
+        assertEquals(4, attributeCount);
+
+        ne = schema.search("", null);
+        count = 0;
+        attributeCount = 0;
+        while (ne.hasMore()) {
+            result = ne.next();
+            count++;
+            attributeCount += result.getAttributes().size();
+        }
+        assertEquals(4, count);
+        assertEquals(4, attributeCount);
+
+        ne = schema.search("classdefinition", matchAttrs);
+
+        count = 0;
+        attributeCount = 0;
+        while (ne.hasMore()) {
+            result = ne.next();
+            count++;
+            attributeCount += result.getAttributes().size();
+        }
+        assertEquals(3, count);
+        assertEquals(18, attributeCount);
+
+        ne = schema.search("classdefinition/javaClass", matchAttrs);
+        assertFalse(ne.hasMore());
+    }
+
+    public void testSearchException() throws NamingException {
+        String nullString = null;
+        Name nullName = null;
+        try {
+            schema.search(nullString, null);
+            fail("Should throw NullPointerException.");
+        } catch (NullPointerException e) {
+            // Expected.
+        }
+
+        try {
+            schema.search(nullName, null);
+            fail("Should throw NullPointerException.");
+        } catch (NullPointerException e) {
+            // Expected.
+        }
+
+        try {
+            schema.search("invalid", null);
+            fail("Should throw NameNotFoundException.");
+        } catch (NameNotFoundException e) {
+            // Expected.
+        }
+
+        try {
+            schema.search("invalid/invalid/invalid", null);
+            fail("Should throw NameNotFoundException.");
+        } catch (NameNotFoundException e) {
+            // Expected.
+        }
+
+        try {
+            schema.search("invalid/invalid", null);
+            fail("Should throw NameNotFoundException.");
+        } catch (NameNotFoundException e) {
+            // Expected.
+        }
+
+        try {
+            schema.search("classdefinition/invalid", null);
+            fail("Should throw NameNotFoundException.");
+        } catch (NameNotFoundException e) {
+            // Expected.
+        }
+
+        try {
+            schema.search("classdefinition/javaClass/name", null);
+            fail("Should throw NameNotFoundException.");
+        } catch (NameNotFoundException e) {
+            // Expected.
+        }
+
+        try {
+            schema.search("classdefinition/javaClass/invalid", null);
+            fail("Should throw NameNotFoundException.");
+        } catch (NameNotFoundException e) {
+            // Expected.
+        }
+    }
+
+    public void testSearch_Filter() throws NamingException {
+        SearchControls controls = new SearchControls();
+        NamingEnumeration<SearchResult> ne = schema.search("",
+                "(objectclass=classdefinition)", controls);
+
+        SearchResult result;
+        int count = 0;
+        while (ne.hasMore()) {
+            result = ne.next();
+            count++;
+        }
+        assertEquals(1, count);
+
+        ne = schema.search("", "(!(objectclass=classdefinition))", controls);
+        count = 0;
+        while (ne.hasMore()) {
+            result = ne.next();
+            count++;
+        }
+        assertEquals(3, count);
+
+        ne = schema.search("",
+                "(|(objectclass=classdefinition)(objectclass=matchingrule))",
+                controls);
+        count = 0;
+        while (ne.hasMore()) {
+            result = ne.next();
+            count++;
+        }
+        assertEquals(2, count);
+
+        controls.setSearchScope(SearchControls.OBJECT_SCOPE);
+        controls.setCountLimit(5);
+        ne = schema.search("classdefinition", "(objectclass~=classdefinition)",
+                controls);
+        count = 0;
+        while (ne.hasMore()) {
+            result = ne.next();
+            count++;
+        }
+        assertEquals(1, count);
+    }
+
+    public void testSearch_matchAttributes() throws NamingException {
+        Attributes matchAttrs = new BasicAttributes();
+        NamingEnumeration<SearchResult> ne = schema.search("", matchAttrs);
+
+        Attributes returnedAttributes;
+        SearchResult result;
+        int count = 0;
+
+        // TODO
+        // The problem of ldap-jndi conversion
+        // There are too many places to handle the case-sensitive problem.
+        matchAttrs.put("obJectclass", "ClassDefinition");
+        ne = schema.search("", matchAttrs);
+        count = 0;
+        while (ne.hasMore()) {
+            result = ne.next();
+            count++;
+        }
+        assertEquals(1, count);
+
+        matchAttrs = new BasicAttributes(true);
+        matchAttrs.put("obJectclass", "ClasSDefinition");
+        ne = schema.search("", matchAttrs);
+        assertFalse(ne.hasMore());
+
+        matchAttrs.put("invalid", "ClassDefinition");
+        ne = schema.search("", matchAttrs);
+        assertFalse(ne.hasMore());
+    }
+
+    public void testSearch_AttributesToReturn() throws NamingException {
+        String[] attributesToReturn = new String[] { "objecTClass" };
+        NamingEnumeration<SearchResult> ne = schema.search("", null,
+                attributesToReturn);
+
+        Attributes returnedAttributes;
+        SearchResult result;
+        int count = 0;
+        while (ne.hasMore()) {
+            result = ne.next();
+            returnedAttributes = result.getAttributes();
+            assertEquals(1, returnedAttributes.size());
+            count++;
+        }
+        assertEquals(4, count);
+
+        attributesToReturn = new String[] { "objecTClass", "invalid" };
+        ne = schema.search("", null, attributesToReturn);
+
+        count = 0;
+        while (ne.hasMore()) {
+            result = ne.next();
+            returnedAttributes = result.getAttributes();
+            assertEquals(1, returnedAttributes.size());
+            count++;
+        }
+        assertEquals(4, count);
+
+        attributesToReturn = new String[] { "invalid", "invalid2" };
+        ne = schema.search("", null, attributesToReturn);
+        count = 0;
+        while (ne.hasMore()) {
+            result = ne.next();
+            returnedAttributes = result.getAttributes();
+            assertEquals(0, returnedAttributes.size());
+            // System.out.println(result);
+            count++;
+        }
+        assertEquals(4, count);
+
+        attributesToReturn = new String[] {};
+        ne = schema.search("", null, attributesToReturn);
+        count = 0;
+        while (ne.hasMore()) {
+            result = ne.next();
+            returnedAttributes = result.getAttributes();
+            assertEquals(0, returnedAttributes.size());
+            count++;
+        }
+        assertEquals(4, count);
+
+        attributesToReturn = new String[] { "name" };
+        ne = schema.search("classdefinition", null, attributesToReturn);
+        count = 0;
+        while (ne.hasMore()) {
+            result = ne.next();
+            returnedAttributes = result.getAttributes();
+            assertEquals(1, returnedAttributes.size());
+            count++;
+        }
+        assertEquals(3, count);
+
+        attributesToReturn = new String[] { "name" };
+        ne = schema.search("classdefinition/javaClass", null,
+                attributesToReturn);
+        assertFalse(ne.hasMore());
+
+        attributesToReturn = new String[] { "objecTClass", "invalid", null };
+        ne = schema.search("", null, attributesToReturn);
+
+        count = 0;
+
+        try {
+            // No-bug difference.
+            // RI will throw NullPointerException.
+            while (ne.hasMore()) {
+                result = ne.next();
+                returnedAttributes = result.getAttributes();
+                assertEquals(1, returnedAttributes.size());
+                count++;
+            }
+            assertEquals(4, count);
+        }
+
+        catch (NullPointerException e) {
+            // Expected.
+        }
+    }
+
+    public void testSearch_Filter2() throws NamingException {
+        ArrayList<String> verifyList = new ArrayList<String>();
+        SearchControls controls = new SearchControls();
+        NamingEnumeration<SearchResult> ne = schema.search("",
+                "(objectclass=classdefinition)", controls);
+
+        SearchResult result;
+        int count = 0;
+        verifyList.add("ClassDefinition");
+        while (ne.hasMore()) {
+            result = ne.next();
+            count++;
+            assertTrue(verifyList.remove(result.getName()));
+        }
+        assertEquals(1, count);
+
+        verifyList.add("SyntaxDefinition");
+        verifyList.add("AttributeDefinition");
+        verifyList.add("MatchingRule");
+        ne = schema.search("", "(!(objectclass=classdefinition))", controls);
+        count = 0;
+        while (ne.hasMore()) {
+            result = ne.next();
+            count++;
+            assertTrue(verifyList.remove(result.getName()));
+        }
+        assertEquals(3, count);
+
+        verifyList.add("MatchingRule");
+        verifyList.add("ClassDefinition");
+        ne = schema.search("",
+                "(|(objectclass=classdefinition)(objectclass=matchingrule))",
+                controls);
+        count = 0;
+        while (ne.hasMore()) {
+            result = ne.next();
+            count++;
+            assertTrue(verifyList.remove(result.getName()));
+        }
+        assertEquals(2, count);
+
+        verifyList.add("ClassDefinition");
+        ne = schema
+                .search(
+                        "",
+                        "(&(objectclass=classdefinition)(!(objectclass=matchingrule)))",
+                        controls);
+        count = 0;
+        while (ne.hasMore()) {
+            result = ne.next();
+            count++;
+            assertTrue(verifyList.remove(result.getName()));
+        }
+        assertEquals(1, count);
+
+        ne = schema.search("", "(objectclass=*)", controls);
+        count = 0;
+        while (ne.hasMore()) {
+            result = ne.next();
+            count++;
+        }
+        assertEquals(4, count);
+
+        verifyList.add("SyntaxDefinition");
+        verifyList.add("ClassDefinition");
+        ne = schema.search("", "(objectclass=*s*defi*)", controls);
+        count = 0;
+        while (ne.hasMore()) {
+            result = ne.next();
+            count++;
+            assertTrue(verifyList.remove(result.getName()));
+        }
+        assertEquals(2, count);
+
+        verifyList.add("SyntaxDefinition");
+        ne = schema.search("", "(objectclass=s*defi*)", controls);
+        count = 0;
+        while (ne.hasMore()) {
+            result = ne.next();
+            count++;
+            assertTrue(verifyList.remove(result.getName()));
+        }
+        assertEquals(1, count);
+
+        ne = schema.search("", "(objectclass~=sdefi)", controls);
+        assertFalse(ne.hasMore());
+
+        ne = schema.search("", "(objectclass<=a)", controls);
+        count = 0;
+        while (ne.hasMore()) {
+            result = ne.next();
+            count++;
+        }
+        assertEquals(4, count);
+
+        verifyList.add("MatchingRule");
+        verifyList.add("SyntaxDefinition");
+        ne = schema.search("", "(objectclass>=M)", controls);
+        count = 0;
+        while (ne.hasMore()) {
+            result = ne.next();
+            count++;
+            assertTrue(verifyList.remove(result.getName()));
+        }
+        assertEquals(2, count);
+        
+        ne = schema.search("",
+                "(|(!(objectclass=classdefinition))(!(objectclass=matchingrule)))",
+                controls);
+        count = 0;
+        while (ne.hasMore()) {
+            result = ne.next();
+            count++;
+        }
+        assertEquals(4, count);
+    }
+
+    public void testSearch_Subtree() throws NamingException {
+        addMoreSchemaData();
+
+        ArrayList<String> verifyList = new ArrayList<String>();
+        SearchControls controls = new SearchControls();
+        controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
+        NamingEnumeration<SearchResult> ne = schema.search("", "(must=cn)",
+                controls);
+
+        SearchResult result;
+        int count = 0;
+        while (ne.hasMore()) {
+            result = ne.next();
+            count++;
+            assertTrue(result.getName().startsWith("ClassDefinition"));
+            assertTrue(result.getAttributes().get("must").contains("cn"));
+        }
+        assertEquals(3, count);
+
+        ne = schema.search("", "(x-schema=*)", controls);
+
+        count = 0;
+        while (ne.hasMore()) {
+            result = ne.next();
+            count++;
+            assertTrue(result.getName().contains("/"));
+            assertNotNull(result.getAttributes().get("x-schema"));
+        }
+        assertEquals(10, count);
+
+        // Nonexist attributename;
+        ne = schema.search("", "(schema=*)", controls);
+        assertFalse(ne.hasMore());
+    }
+
+    public void testSearch_ReturnAtributes() throws NamingException {
+        addMoreSchemaData();
+        ArrayList<String> verifyList = new ArrayList<String>();
+        SearchControls controls = new SearchControls();
+        controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
+        controls.setReturningAttributes(new String[] {});
+        NamingEnumeration<SearchResult> ne = schema.search("", "(must=cn)",
+                controls);
+
+        SearchResult result;
+        int count = 0;
+        while (ne.hasMore()) {
+            result = ne.next();
+            count++;
+            assertEquals(0, result.getAttributes().size());
+        }
+        assertEquals(3, count);
+
+        controls.setReturningAttributes(new String[] { "may" });
+        ne = schema.search("", "(&(mUst=cn)(maY=*))", controls);
+
+        count = 0;
+        while (ne.hasMore()) {
+            result = ne.next();
+            count++;
+            assertEquals(1, result.getAttributes().size());
+            assertNotNull(result.getAttributes().get("MAY"));
+        }
+        assertEquals(3, count);
+    }
+
+    public void testFilterSearchException() throws NamingException {
+        SearchControls controls = new SearchControls();
+        try {
+            schema.search("", "", controls);
+            fail("Should throw StringIndexOutOfBoundsException");
+        } catch (InvalidSearchFilterException e) {
+            // Excpected.
+        } catch (StringIndexOutOfBoundsException e) {
+            // RI's problem.
+        }
+
+        try {
+            schema.search("invalid", "invalid", controls);
+            fail("Should throw NameNotFoundException.");
+        } catch (NameNotFoundException e) {
+            // Expected.
+        }
+
+        try {
+            schema.search("invalid/invalid/invalid", "invalid", controls);
+            fail("Should throw NameNotFoundException.");
+        } catch (NameNotFoundException e) {
+            // Expected.
+        }
+
+        try {
+            schema.search("invalid/invalid", "invalid", controls);
+            fail("Should throw NameNotFoundException.");
+        } catch (NameNotFoundException e) {
+            // Expected.
+        }
+
+        try {
+            schema.search("classdefinition/invalid", "invalid", controls);
+            fail("Should throw NameNotFoundException.");
+        } catch (NameNotFoundException e) {
+            // Expected.
+        }
+
+        try {
+            schema
+                    .search("classdefinition/javaClass/name", "invalid",
+                            controls);
+            fail("Should throw NameNotFoundException.");
+        } catch (NameNotFoundException e) {
+            // Expected.
+        }
+
+        try {
+            schema.search("classdefinition/javaClass/invalid", "invalid",
+                    controls);
+            fail("Should throw NameNotFoundException.");
+        } catch (NameNotFoundException e) {
+            // Expected.
+        }
+    }
+
+    private void addMoreSchemaData() throws InvalidNameException {
+        // Add more schema data.
+        Hashtable subschemaTable = (Hashtable) schemaTable.get("objectclasses");
+
+        subschemaTable
+                .put(
+                        "applicationprocess",
+                        "( 2.5.6.11 name 'applicationprocess' "
+                                + "desc 'rfc2256: an application process' "
+                                + "sup top structural "
+                                + "must cn may ( seealso $ ou $ l $ description ) x-schema 'core' )");
+
+        subschemaTable
+                .put(
+                        "documentseries",
+                        "( 0.9.2342.19200300.100.4.9 name 'documentseries' "
+                                + "sup top structural must cn "
+                                + "may ( description $ seealso $ telephonenumber $ l $ o $ ou ) "
+                                + "x-schema 'cosine' )");
+
+        subschemaTable
+                .put(
+                        "groupofuniquenames",
+                        "( 2.5.6.17 name 'groupofuniquenames' "
+                                + "desc 'rfc2256: a group of unique names (dn and unique identifier)' "
+                                + "sup top structural must ( uniquemember $ cn ) "
+                                + "may ( businesscategory $ seealso $ owner $ ou $ o $ description ) x-schema 'core' )");
+        schema = new LdapSchemaContextImpl(context, null, name, schemaTable,
+                LdapSchemaContextImpl.SCHEMA_ROOT_LEVEL);
+    }
+
+    public void testSearch_FilterWithArgs() throws NamingException {
+        ArrayList<String> verifyList = new ArrayList<String>();
+        SearchControls controls = new SearchControls();
+        Object[] filterArgs = new Object[] { "ClassDeFInition" };
+        NamingEnumeration<SearchResult> ne = schema.search("",
+                "(objectclass={0})", filterArgs, controls);
+
+        SearchResult result;
+        int count = 0;
+        verifyList.add("ClassDefinition");
+        while (ne.hasMore()) {
+            result = ne.next();
+            count++;
+            assertTrue(verifyList.remove(result.getName()));
+        }
+        assertEquals(1, count);
+
+        verifyList.add("SyntaxDefinition");
+        verifyList.add("AttributeDefinition");
+        verifyList.add("MatchingRule");
+        filterArgs = new Object[] { "ClassDeFInition" };
+        ne = schema.search("", "(!(objectclass={0}))", filterArgs, controls);
+        count = 0;
+        while (ne.hasMore()) {
+            result = ne.next();
+            count++;
+            assertTrue(verifyList.remove(result.getName()));
+        }
+        assertEquals(3, count);
+
+        verifyList.add("MatchingRule");
+        verifyList.add("ClassDefinition");
+        filterArgs = new Object[] { "ClassDeFInition", "matchingrule" };
+        ne = schema.search("", "(|(objectclass={0})(objectclass={1}))",
+                filterArgs, controls);
+        count = 0;
+        while (ne.hasMore()) {
+            result = ne.next();
+            count++;
+            assertTrue(verifyList.remove(result.getName()));
+        }
+        assertEquals(2, count);
+
+        verifyList.add("ClassDefinition");
+        filterArgs = new Object[] { "ClassDeFInition", "matchingrule" };
+        ne = schema.search("", "(&(objectclass={0})(!(objectclass={1})))",
+                filterArgs, controls);
+        count = 0;
+        while (ne.hasMore()) {
+            result = ne.next();
+            count++;
+            assertTrue(verifyList.remove(result.getName()));
+        }
+        assertEquals(1, count);
+
+        ne = schema.search("", "(objectclass=*)", controls);
+        count = 0;
+        while (ne.hasMore()) {
+            result = ne.next();
+            count++;
+        }
+        assertEquals(4, count);
+
+        verifyList.add("SyntaxDefinition");
+        verifyList.add("ClassDefinition");
+        filterArgs = new Object[] { "defi" };
+        ne = schema.search("", "(objectclass=*s*{0}*)", filterArgs, controls);
+        count = 0;
+        while (ne.hasMore()) {
+            result = ne.next();
+            count++;
+            assertTrue(verifyList.remove(result.getName()));
+        }
+        assertEquals(2, count);
+
+        verifyList.add("SyntaxDefinition");
+        filterArgs = new Object[] { "defi" };
+        ne = schema.search("", "(objectclass=s*{0}*)", filterArgs, controls);
+        count = 0;
+        while (ne.hasMore()) {
+            result = ne.next();
+            count++;
+            assertTrue(verifyList.remove(result.getName()));
+        }
+        assertEquals(1, count);
+
+        filterArgs = new Object[] { "sdefi" };
+        ne = schema.search("", "(objectclass~={0})", filterArgs, controls);
+        assertFalse(ne.hasMore());
+
+        filterArgs = new Object[] { "a" };
+        ne = schema.search("", "(objectclass<={0})", filterArgs, controls);
+        count = 0;
+        while (ne.hasMore()) {
+            result = ne.next();
+            count++;
+        }
+        assertEquals(4, count);
+
+        verifyList.add("MatchingRule");
+        verifyList.add("SyntaxDefinition");
+        filterArgs = new Object[] { "M" };
+        ne = schema.search("", "(objectclass>={0})", filterArgs, controls);
+        count = 0;
+        while (ne.hasMore()) {
+            result = ne.next();
+            count++;
+            assertTrue(verifyList.remove(result.getName()));
+        }
+        assertEquals(2, count);
+    }
 }



Mime
View raw message