harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From telli...@apache.org
Subject svn commit: r601315 [3/11] - in /harmony/enhanced/classlib/branches/java6: depends/build/ modules/accessibility/src/main/java/javax/accessibility/ modules/accessibility/src/test/api/java/common/javax/accessibility/ modules/awt/src/main/java/common/java...
Date Wed, 05 Dec 2007 12:26:14 GMT
Modified: harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapContextImpl.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapContextImpl.java?rev=601315&r1=601314&r2=601315&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapContextImpl.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapContextImpl.java Wed Dec  5 04:25:42 2007
@@ -17,8 +17,14 @@
 
 package org.apache.harmony.jndi.provider.ldap;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
 import java.util.ArrayList;
+import java.util.Enumeration;
 import java.util.EventObject;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -28,6 +34,7 @@
 import java.util.Map;
 import java.util.Set;
 import java.util.StringTokenizer;
+import java.util.TreeMap;
 
 import javax.naming.AuthenticationNotSupportedException;
 import javax.naming.Binding;
@@ -37,16 +44,22 @@
 import javax.naming.ConfigurationException;
 import javax.naming.Context;
 import javax.naming.InvalidNameException;
+import javax.naming.LimitExceededException;
 import javax.naming.Name;
 import javax.naming.NameClassPair;
 import javax.naming.NameNotFoundException;
 import javax.naming.NameParser;
 import javax.naming.NamingEnumeration;
 import javax.naming.NamingException;
+import javax.naming.PartialResultException;
 import javax.naming.RefAddr;
 import javax.naming.Reference;
+import javax.naming.Referenceable;
+import javax.naming.ReferralException;
+import javax.naming.StringRefAddr;
 import javax.naming.directory.Attribute;
 import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttribute;
 import javax.naming.directory.BasicAttributes;
 import javax.naming.directory.DirContext;
 import javax.naming.directory.InvalidSearchFilterException;
@@ -72,6 +85,7 @@
 import javax.naming.ldap.UnsolicitedNotificationListener;
 import javax.naming.spi.DirectoryManager;
 import javax.naming.spi.NamingManager;
+import javax.naming.spi.DirStateFactory.Result;
 
 import org.apache.harmony.jndi.internal.nls.Messages;
 import org.apache.harmony.jndi.internal.parser.AttributeTypeAndValuePair;
@@ -79,7 +93,9 @@
 import org.apache.harmony.jndi.provider.ldap.asn1.Utils;
 import org.apache.harmony.jndi.provider.ldap.event.ECNotificationControl;
 import org.apache.harmony.jndi.provider.ldap.event.PersistentSearchResult;
+import org.apache.harmony.jndi.provider.ldap.ext.StartTlsResponseImpl;
 import org.apache.harmony.jndi.provider.ldap.parser.FilterParser;
+import org.apache.harmony.jndi.provider.ldap.parser.LdapUrlParser;
 import org.apache.harmony.jndi.provider.ldap.parser.ParseException;
 import org.apache.harmony.jndi.provider.ldap.sasl.SaslBind;
 
@@ -93,7 +109,7 @@
      * ldap connection
      */
     private LdapClient client;
-    
+
     private boolean isClosed;
 
     /**
@@ -131,6 +147,8 @@
 
     private static final String LDAP_DEREF_ALIASES = "java.naming.ldap.derefAliases"; //$NON-NLS-1$
 
+    private static final String LDAP_CONTROL_CONNECT = "java.naming.ldap.control.connect"; //$NON-NLS-1$
+
     private static final String LDAP_TYPES_ONLY = "java.naming.ldap.typesOnly"; //$NON-NLS-1$
 
     /**
@@ -147,7 +165,7 @@
         connectionProperties.add(Context.SECURITY_CREDENTIALS);
         connectionProperties.add(Context.SECURITY_PRINCIPAL);
         connectionProperties.add(Context.SECURITY_PROTOCOL);
-        connectionProperties.add("java.naming.ldap.factory.socket");
+        connectionProperties.add("java.naming.ldap.factory.socket"); //$NON-NLS-1$
     }
 
     /**
@@ -162,6 +180,10 @@
             Hashtable<Object, Object> environment, String dn)
             throws InvalidNameException {
         initial(context.client, environment, dn);
+
+        // connection request controls are inheritied
+        connCtls = context.connCtls;
+        // request controls are not inheritied
     }
 
     /**
@@ -199,6 +221,13 @@
 
         contextDn = new LdapName(dn);
         parser = new LdapNameParser(dn);
+
+        if (env.get(Context.REFERRAL) == null
+                || env.get(Context.REFERRAL).equals("ignore")) { //$NON-NLS-1$
+            requestControls = new Control[] { NON_CRITICAL_MANAGE_REF_CONTROL };
+        }
+
+        connCtls = (Control[]) env.get(LDAP_CONTROL_CONNECT);
     }
 
     /**
@@ -239,13 +268,26 @@
 
     public ExtendedResponse extendedOperation(ExtendedRequest request)
             throws NamingException {
-        // TODO not yet implemented
-        throw new NotYetImplementedException();
+        ExtendedOp op = new ExtendedOp(request);
+        try {
+            doBasicOperation(op);
+        } catch (ReferralException e) {
+            if (isFollowReferral(e)) {
+                LdapContext referralContext = (LdapContext) getReferralContext(e);
+                return referralContext.extendedOperation(request);
+            }
+            throw e;
+        }
+        ExtendedResponse response = op.getExtendedResponse();
+        // set existing underlying socket to startTls extended response
+        if (response instanceof StartTlsResponseImpl) {
+            ((StartTlsResponseImpl) response).setSocket(client.getSocket());
+        }
+        return response;
     }
 
     public Control[] getConnectControls() throws NamingException {
-        // TODO not yet implemented
-        throw new NotYetImplementedException();
+        return copyControls(connCtls);
     }
 
     public Control[] getRequestControls() throws NamingException {
@@ -266,14 +308,22 @@
         return rtValue;
     }
 
-    public LdapContext newInstance(Control[] ac) throws NamingException {
-        // TODO not yet implemented
-        throw new NotYetImplementedException();
+    public LdapContext newInstance(Control[] reqCtrls) throws NamingException {
+        LdapContextImpl instance = new LdapContextImpl(this, env, contextDn
+                .toString());
+        instance.setRequestControls(reqCtrls);
+        return instance;
     }
 
     public void reconnect(Control[] ac) throws NamingException {
-        // TODO not yet implemented
-        throw new NotYetImplementedException();
+        connCtls = ac;
+        try {
+            doBindOperation(connCtls);
+        } catch (IOException e) {
+            CommunicationException ex = new CommunicationException();
+            ex.setRootCause(e);
+            throw ex;
+        }
     }
 
     public void setRequestControls(Control[] controls) throws NamingException {
@@ -305,8 +355,158 @@
 
     public void bind(Name name, Object obj, Attributes attributes)
             throws NamingException {
-        // TODO not yet implemented
-        throw new NotYetImplementedException();
+        checkName(name);
+
+        if (name instanceof CompositeName && name.size() > 1) {
+            /*
+             * multi ns, find next ns context, delegate operation to the next
+             * contex
+             */
+            DirContext nns = (DirContext) findNnsContext(name);
+            Name remainingName = name.getSuffix(1);
+            nns.bind(remainingName, attributes);
+            return;
+        }
+
+        /*
+         * there is only one ldap ns
+         */
+        if (obj == null && attributes == null) {
+            // ldap.2E=cannot bind null object without attributes
+            throw new IllegalArgumentException(Messages.getString("ldap.2E")); //$NON-NLS-1$
+        }
+
+        if (obj == null) {
+            createSubcontext(name, attributes);
+            return;
+        }
+
+        Result result = DirectoryManager.getStateToBind(obj, name, this, env,
+                attributes);
+        Object o = result.getObject();
+
+        Attributes attrs = null;
+
+        if (o instanceof Reference) {
+            attrs = convertRefToAttribute((Reference) o);
+        } else if (o instanceof Referenceable) {
+            attrs = convertRefToAttribute(((Referenceable) o).getReference());
+        } else if (o instanceof Serializable) {
+            attrs = convertSerialToAttribute((Serializable) o);
+        } else if (o instanceof DirContext) {
+            DirContext cxt = (DirContext) o;
+            attrs = cxt.getAttributes("");
+        } else {
+            throw new IllegalArgumentException(Messages.getString("ldap.24")); //$NON-NLS-1$
+        }
+
+        NamingEnumeration<? extends Attribute> enu = attrs.getAll();
+        if (result.getAttributes() != null) {
+            Attributes resultAttributes = result.getAttributes();
+
+            while (enu.hasMore()) {
+                Attribute element = enu.next();
+                if (element.getID().equalsIgnoreCase("objectClass")) {
+                    element = mergeAttribute(resultAttributes
+                            .get("objectClass"), element);
+                    if (resultAttributes.get("objectClass") != null) {
+                        element.remove("javaContainer");
+                    }
+                    resultAttributes.put(element);
+                } else if (resultAttributes.get(element.getID()) == null) {
+                    resultAttributes.put(element);
+                }
+            }
+
+            createSubcontext(name, resultAttributes);
+        } else {
+            createSubcontext(name, attrs);
+        }
+    }
+
+    private Attributes convertSerialToAttribute(Serializable serializable)
+            throws NamingException {
+        Attributes attrs = new BasicAttributes();
+
+        Attribute objectClass = new BasicAttribute("objectClass");
+        objectClass.add("top");
+        objectClass.add("javaContainer");
+        objectClass.add("javaObject");
+        objectClass.add("javaSerializedObject");
+        attrs.put(objectClass);
+
+        Attribute javaClassNames = new BasicAttribute("javaClassNames");
+        javaClassNames.add(serializable.getClass().getName());
+        javaClassNames.add(Object.class.getName());
+
+        Class[] cs = serializable.getClass().getInterfaces();
+        for (Class c : cs) {
+            javaClassNames.add(c.getName());
+        }
+
+        // add all ancestors class
+        Class sup = serializable.getClass().getSuperclass();
+        while (sup != null && !sup.getName().equals(Object.class.getName())) {
+            javaClassNames.add(sup.getName());
+            sup = sup.getSuperclass();
+        }
+        attrs.put(javaClassNames);
+
+        attrs.put("javaClassName", serializable.getClass().getName());
+
+        ByteArrayOutputStream bout = new ByteArrayOutputStream();
+
+        try {
+            ObjectOutputStream out = new ObjectOutputStream(bout);
+            out.writeObject(serializable);
+            out.close();
+        } catch (IOException e) {
+            // TODO need add more detail messages?
+            NamingException ex = new NamingException();
+            ex.setRootCause(e);
+            throw ex;
+        }
+
+        byte[] bytes = bout.toByteArray();
+        attrs.put("javaSerializedData", bytes);
+
+        return attrs;
+    }
+
+    private Attributes convertRefToAttribute(Reference ref) {
+        Attributes attrs = new BasicAttributes();
+
+        Attribute objectClass = new BasicAttribute("objectClass");
+        objectClass.add("top");
+        objectClass.add("javaContainer");
+        objectClass.add("javaObject");
+        objectClass.add("javaNamingReference");
+        attrs.put(objectClass);
+
+        Attribute className = new BasicAttribute("javaClassName");
+        className.add(ref.getClassName());
+        attrs.put(className);
+
+        Attribute address = new BasicAttribute("javaReferenceAddress");
+        Enumeration<RefAddr> enu = ref.getAll();
+        int index = 0;
+        String separator = (String) env.get("java.naming.ldap.ref.separator");
+        if (separator == null) {
+            // use default separator '#'
+            separator = "#";
+        }
+        while (enu.hasMoreElements()) {
+            RefAddr addr = enu.nextElement();
+            StringBuilder builder = new StringBuilder();
+            builder.append(separator + index);
+            builder.append(separator + addr.getType());
+            builder.append(separator + addr.getContent());
+            address.add(builder.toString());
+            index++;
+        }
+        attrs.put(address);
+
+        return attrs;
     }
 
     public void bind(String s, Object obj, Attributes attributes)
@@ -355,13 +555,59 @@
 
         // do add operation
         AddOp op = new AddOp(targetDN, la);
-
-        doBasicOperation(op);
+        try {
+            doBasicOperation(op);
+        } catch (ReferralException e) {
+            if (isFollowReferral(e)) {
+                DirContext referralContext = getReferralContext(e);
+                return referralContext.createSubcontext(name, attributes);
+            }
+            throw e;
+        }
 
         LdapResult result = op.getResult();
         return new LdapContextImpl(this, env, result.getMachedDN());
     }
 
+    private DirContext getReferralContext(ReferralException e)
+            throws LimitExceededException, NamingException {
+        int limit = 0;
+        if (env.get("java.naming.ldap.referral.limit") != null) {
+            limit = Integer.valueOf(
+                    (String) env.get("java.naming.ldap.referral.limit"))
+                    .intValue();
+        }
+
+        if (limit == -1) {
+            throw new LimitExceededException(Messages.getString("ldap.25")); //$NON-NLS-1$
+        }
+
+        if (limit == 1) {
+            limit = -1;
+        } else if (limit != 0) {
+            limit -= 1;
+        }
+
+        Hashtable<Object, Object> newEnv = (Hashtable<Object, Object>) env
+                .clone();
+        newEnv.put("java.naming.ldap.referral.limit", String.valueOf(limit));
+        DirContext referralContext = null;
+
+        while (true) {
+            try {
+                referralContext = (DirContext) e.getReferralContext(newEnv);
+                break;
+            } catch (NamingException ex) {
+                if (e.skipReferral()) {
+                    continue;
+                }
+                throw ex;
+            }
+        }
+
+        return referralContext;
+    }
+
     /**
      * merge two instanceof <code>Attributes</code> to one
      * 
@@ -480,8 +726,16 @@
         LdapSearchResult result = doSearch(targetDN, filter, controls);
         Iterator<Attributes> it = result.getEntries().values().iterator();
         if (it.hasNext()) {
+            Attributes attributes = it.next();
+            NamingEnumeration<String> ids = attributes.getIDs();
+            while (ids.hasMore()) {
+                LdapAttribute attribute = (LdapAttribute) attributes.get(ids
+                        .next());
+                attribute.setContext(this);
+            }
+
             // FIXME: there must be only one Attributes?
-            return it.next();
+            return attributes;
         } else if (result.getException() != null) {
             throw result.getException();
         }
@@ -499,7 +753,6 @@
         return getAttributes(convertFromStringToName(s), as);
     }
 
-
     public static Hashtable<String, Hashtable<String, Hashtable<String, Object>>> schemaTree = new Hashtable<String, Hashtable<String, Hashtable<String, Object>>>();
 
     private LdapSchemaContextImpl ldapSchemaCtx = null;
@@ -639,8 +892,7 @@
      * 'numericStringMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 ) TODO check
      * with RFC to see whether all the schema definition has been catered for
      */
-    private static void parseValue(String schemaType,
-            String value,
+    private static void parseValue(String schemaType, String value,
             Hashtable<String, Hashtable<String, Object>> schemaDefs) {
         StringTokenizer st = new StringTokenizer(value);
         // Skip (
@@ -771,10 +1023,11 @@
         return new LdapSchemaAttrDefContextImpl(new CompositeName(name), env,
                 attrDef, this);
     }
+
     public DirContext getSchemaClassDefinition(Name name)
             throws NamingException {
         if (null == ldapSchemaCtx) {
-            getSchema(name);
+            getSchema("");
         }
 
         Hashtable<String, ArrayList<String>> classTree = new Hashtable<String, ArrayList<String>>();
@@ -893,13 +1146,16 @@
         for (ModificationItem item : modificationItems) {
             switch (item.getModificationOp()) {
             case DirContext.ADD_ATTRIBUTE:
-                op.addModification(0, new LdapAttribute(item.getAttribute(), this));
+                op.addModification(0, new LdapAttribute(item.getAttribute(),
+                        this));
                 break;
             case DirContext.REMOVE_ATTRIBUTE:
-                op.addModification(1, new LdapAttribute(item.getAttribute(), this));
+                op.addModification(1, new LdapAttribute(item.getAttribute(),
+                        this));
                 break;
             case DirContext.REPLACE_ATTRIBUTE:
-                op.addModification(2, new LdapAttribute(item.getAttribute(), this));
+                op.addModification(2, new LdapAttribute(item.getAttribute(),
+                        this));
                 break;
             default:
                 throw new IllegalArgumentException(Messages.getString(
@@ -907,7 +1163,16 @@
             }
         }
 
-        doBasicOperation(op);
+        try {
+            doBasicOperation(op);
+        } catch (ReferralException e) {
+            if (isFollowReferral(e)) {
+                DirContext referralContext = getReferralContext(e);
+                referralContext.modifyAttributes(name, modificationItems);
+                return;
+            }
+            throw e;
+        }
     }
 
     public void modifyAttributes(String s, int i, Attributes attributes)
@@ -922,8 +1187,25 @@
 
     public void rebind(Name name, Object obj, Attributes attributes)
             throws NamingException {
-        // TODO not yet implemented
-        throw new NotYetImplementedException();
+        Attributes attrs = null;
+        try {
+            attrs = getAttributes(name);
+        } catch (NameNotFoundException e) {
+            // entry does not exist, just do bind
+            bind(name, obj, attributes);
+            return;
+        }
+
+        if (attributes == null && obj instanceof DirContext) {
+            attributes = ((DirContext) obj).getAttributes("");
+            if (attributes == null) {
+                attributes = attrs;
+            }
+        }
+
+        destroySubcontext(name);
+
+        bind(name, obj, attributes);
     }
 
     public void rebind(String s, Object obj, Attributes attributes)
@@ -987,13 +1269,24 @@
         tempName.addAll(name);
         String baseDN = tempName.toString();
         for (String dn : entries.keySet()) {
-            String relativeName = convertToRelativeName(dn, baseDN);
-            SearchResult sr = new SearchResult(relativeName, null, entries
-                    .get(dn));
-            sr.setNameInNamespace(dn);
+            SearchResult sr = null;
+            if (dn.startsWith("ldap://")) {
+                sr = new SearchResult(dn, null, entries.get(dn), false);
+                int index = dn.indexOf("/", 7);
+                sr.setNameInNamespace(dn.substring(index + 1, dn.length()));
+                list.add(sr);
+            } else {
+                String relativeName = convertToRelativeName(dn, baseDN);
+                sr = new SearchResult(relativeName, null, entries.get(dn));
+                sr.setNameInNamespace(dn);
+            }
             list.add(sr);
         }
 
+        if (list.size() == 0 && result.getException() != null) {
+            throw result.getException();
+        }
+
         return new LdapNamingEnumeration<SearchResult>(list, result
                 .getException());
     }
@@ -1016,13 +1309,6 @@
         /*
          * there is only one ldap ns
          */
-        if (filter == null) {
-            throw new NullPointerException(Messages.getString("ldap.28")); //$NON-NLS-1$
-        }
-
-        if (objs == null) {
-            objs = new Object[0];
-        }
 
         if (searchControls == null) {
             searchControls = new SearchControls();
@@ -1030,17 +1316,8 @@
 
         // get absolute dn name
         String targetDN = getTargetDN(name, contextDn);
-        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;
-        }
+
+        Filter f = LdapUtils.parseFilter(filter, objs);
 
         LdapSearchResult result = doSearch(targetDN, f, searchControls);
 
@@ -1050,13 +1327,24 @@
         tempName.addAll(name);
         String baseDN = tempName.toString();
         for (String dn : entries.keySet()) {
-            String relativeName = convertToRelativeName(dn, baseDN);
-            SearchResult sr = new SearchResult(relativeName, null, entries
-                    .get(dn));
-            sr.setNameInNamespace(dn);
+            SearchResult sr = null;
+            if (dn.startsWith("ldap://")) {
+                sr = new SearchResult(dn, null, entries.get(dn), false);
+                int index = dn.indexOf("/", 7);
+                sr.setNameInNamespace(dn.substring(index + 1, dn.length()));
+                list.add(sr);
+            } else {
+                String relativeName = convertToRelativeName(dn, baseDN);
+                sr = new SearchResult(relativeName, null, entries.get(dn));
+                sr.setNameInNamespace(dn);
+            }
             list.add(sr);
         }
 
+        if (list.size() == 0 && result.getException() != null) {
+            throw result.getException();
+        }
+
         return new LdapNamingEnumeration<SearchResult>(list, result
                 .getException());
     }
@@ -1147,26 +1435,101 @@
                 LdapUtils.getExceptionFromResult(result));
 
         // has error, not deal with referrals
-        if (op.getSearchResult().getException() != null) {
+        if (result.getResultCode() != LdapResult.REFERRAL
+                && op.getSearchResult().getException() != null) {
             return op.getSearchResult();
         }
 
         // baseObject is not located at the server
-        if (result.getResultCode() == 10) {
-            // TODO deal with referrals
-            throw new NotYetImplementedException();
+        if (result.getResultCode() == LdapResult.REFERRAL) {
+            ReferralException ex = new ReferralExceptionImpl(contextDn
+                    .toString(), result.getReferrals(), env);
+            try {
+                if (isFollowReferral(ex)) {
+                    LdapContextImpl ctx = (LdapContextImpl) getReferralContext(ex);
+                    return ctx.doSearch(op);
+                } else {
+                    op.getSearchResult().setException(ex);
+                    return op.getSearchResult();
+                }
+            } catch (PartialResultException e) {
+                op.getSearchResult().setException(e);
+                return op.getSearchResult();
+            }
         }
 
         // there are SearchResultReference in search result
         if (op.getSearchResult().getRefURLs() != null
                 && op.getSearchResult().getRefURLs().size() != 0) {
-            // TODO deal with referrals
-            throw new NotYetImplementedException();
+            ReferralException ex = new ReferralExceptionImpl(contextDn
+                    .toString(), op.getSearchResult().getRefURLs().toArray(
+                    new String[0]), env);
+            try {
+                if (isFollowReferral(ex)) {
+                    processSearchRef(op, ex);
+                } else {
+                    op.getSearchResult().setException(ex);
+                    return op.getSearchResult();
+                }
+            } catch (PartialResultException e) {
+                op.getSearchResult().setException(e);
+                return op.getSearchResult();
+            }
         }
 
         return op.getSearchResult();
     }
 
+    /**
+     * Follow referrals in SearchResultReference. Referrals in
+     * SearchResultReference is different with LDAPResult, which may contians
+     * filter parts. Filter and dn part of url will overwrite filter and
+     * baseObject of last search operation.
+     * 
+     * @param op
+     *            last search operation
+     * @param ex
+     */
+    private void processSearchRef(SearchOp op, ReferralException ex) {
+        LdapSearchResult result = op.getSearchResult();
+        List<String> urls = result.getRefURLs();
+
+        // clean referrals
+        result.setRefURLs(null);
+
+        try {
+            for (String url : urls) {
+
+                LdapUrlParser urlParser = LdapUtils.parserURL(url, true);
+                // if url has dn part overwrite baseObject of last search
+                // operation
+                if (!urlParser.getBaseObject().equals("")) {
+                    op.setBaseObject(urlParser.getBaseObject());
+                }
+                // if url has filter part overwrite filter of last search
+                // operation
+                if (urlParser.hasFilter()) {
+                    op.setFilter(urlParser.getFilter());
+                }
+                LdapContextImpl ctx = (LdapContextImpl) getReferralContext(ex);
+                result.setAddress("ldap://" + urlParser.getHost() + ":"
+                        + urlParser.getPort() + "/");
+                ctx.doSearch(op);
+                result.setAddress(null);
+            }
+        } catch (NamingException e) {
+            /*
+             * occrus exception, set to search result and return, not continue
+             * to follow referral
+             * 
+             * TODO test the behavior of ri
+             * 
+             */
+            result.setException(e);
+            return;
+        }
+    }
+
     LdapSearchResult doSearch(String dn, Filter filter, SearchControls controls)
             throws NamingException {
         SearchOp op = new SearchOp(dn, controls, filter);
@@ -1291,6 +1654,13 @@
         DeleteOp op = new DeleteOp(targetDN);
         try {
             doBasicOperation(op);
+        } catch (ReferralException e) {
+            if (isFollowReferral(e)) {
+                DirContext referralContext = getReferralContext(e);
+                referralContext.destroySubcontext(name);
+                return;
+            }
+            throw e;
         } catch (NameNotFoundException e) {
             // target dn doesn't exist, do nothing
         }
@@ -1381,6 +1751,11 @@
             list.add(pair);
         }
 
+        // no entries return
+        if (list.size() == 0 && result.getException() != null) {
+            throw result.getException();
+        }
+
         return new LdapNamingEnumeration<NameClassPair>(list, result
                 .getException());
     }
@@ -1409,8 +1784,8 @@
         return dn.substring(0, index - 1);
     }
 
-    protected String getTargetDN(Name name, Name prefix) throws NamingException,
-            InvalidNameException {
+    protected String getTargetDN(Name name, Name prefix)
+            throws NamingException, InvalidNameException {
         Name target = null;
         if (name.size() == 0) {
             target = prefix;
@@ -1486,8 +1861,44 @@
 
     public NamingEnumeration<Binding> listBindings(Name name)
             throws NamingException {
-        // TODO not yet implemented
-        throw new NotYetImplementedException();
+        checkName(name);
+
+        if (name instanceof CompositeName && name.size() > 1) {
+            /*
+             * multi ns, find next ns context, delegate operation to the next
+             * contex
+             */
+            DirContext nns = (DirContext) findNnsContext(name);
+            Name remainingName = name.getSuffix(1);
+            return nns.listBindings(remainingName);
+        }
+
+        /*
+         * there is only one ldap ns
+         */
+
+        NamingEnumeration<NameClassPair> enu = list(name);
+
+        List<Binding> bindings = new ArrayList<Binding>();
+
+        while (enu.hasMore()) {
+            NameClassPair pair = enu.next();
+            Object bound = null;
+            if (!pair.getClassName().equals(DirContext.class.getName())) {
+                bound = lookup(pair.getName());
+            } else {
+                bound = new LdapContextImpl(this, env, contextDn.toString());
+            }
+
+            Binding binding = new Binding(pair.getName(), bound.getClass()
+                    .getName(), bound);
+            binding.setNameInNamespace(pair.getNameInNamespace());
+            bindings.add(binding);
+
+        }
+
+        // FIXME: deal with exception
+        return new LdapNamingEnumeration<Binding>(bindings, null);
     }
 
     public NamingEnumeration<Binding> listBindings(String s)
@@ -1496,8 +1907,134 @@
     }
 
     public Object lookup(Name name) throws NamingException {
-        // TODO not yet implemented
-        throw new NotYetImplementedException();
+        checkName(name);
+
+        if (name instanceof CompositeName && name.size() > 1) {
+            /*
+             * multi ns, find next ns context, delegate operation to the next
+             * context
+             */
+            DirContext nns = (DirContext) findNnsContext(name);
+            Name remainingName = name.getSuffix(1);
+            return nns.lookup(remainingName);
+        }
+
+        /*
+         * there is only one ldap ns
+         */
+        Attributes attributes = getAttributes(name);
+        if (!hasAttribute(attributes, "objectClass", "javaContainer")
+                && !hasAttribute(attributes, "objectClass", "javaObject")) {
+            // this is no java object, return the context
+
+            // get absolute dn name
+            String targetDN = getTargetDN(name, contextDn);
+            return new LdapContextImpl(this, env, targetDN);
+        }
+
+        Object boundObject = null;
+        // serializable object
+        if (hasAttribute(attributes, "objectClass", "javaSerializedObject")) {
+            byte[] data = (byte[]) attributes.get("javaSerializedData").get();
+            ObjectInputStream in = null;
+            try {
+                in = new ObjectInputStream(new ByteArrayInputStream(data));
+                boundObject = in.readObject();
+            } catch (IOException e) {
+                NamingException ex = new NamingException();
+                ex.setRootCause(e);
+                throw ex;
+            } catch (ClassNotFoundException e) {
+                // TODO use javaCodebase attribute to load class defination
+            } finally {
+                if (in != null) {
+                    try {
+                        in.close();
+                    } catch (IOException e) {
+                        // ignore
+                    }
+                }
+            }
+        } else if (hasAttribute(attributes, "objectClass",
+                "javaNamingReference")) {
+            String className = (String) attributes.get("javaClassName").get();
+
+            Attribute temp = attributes.get("javaFactory");
+            String factory = null;
+            if (temp != null) {
+                factory = (String) temp.get();
+            }
+
+            temp = attributes.get("javaCodebase");
+            String location = null;
+            if (temp != null) {
+                location = (String) temp.get();
+            }
+
+            Reference ref = new Reference(className, factory, location);
+            Attribute refAddress = attributes.get("javaReferenceAddress");
+            if (refAddress != null) {
+                NamingEnumeration<?> enu = refAddress.getAll();
+                String separator = (String) env
+                        .get("java.naming.ldap.ref.separator");
+                if (separator == null) {
+                    separator = "#";
+                }
+                TreeMap<Integer, StringRefAddr> addrsMap = new TreeMap<Integer, StringRefAddr>();
+
+                // sort addresses to TreeMap
+                while (enu.hasMore()) {
+                    String address = (String) enu.next();
+                    StringTokenizer st = new StringTokenizer(address, separator);
+                    int index = Integer.parseInt(st.nextToken());
+                    String type = st.nextToken();
+                    String content = st.nextToken();
+                    StringRefAddr refAddr = new StringRefAddr(type, content);
+                    addrsMap.put(Integer.valueOf(index), refAddr);
+                    // ref.add(index, refAddr);
+                }
+
+                for (StringRefAddr addr : addrsMap.values()) {
+                    ref.add(addr);
+                }
+            }
+            boundObject = ref;
+        }
+
+        try {
+            boundObject = DirectoryManager.getObjectInstance(boundObject, name,
+                    this, env);
+            if (boundObject == null) {
+                boundObject = new LdapContextImpl(this, env, getTargetDN(name,
+                        contextDn));
+            }
+            return boundObject;
+
+        } catch (NamingException e) {
+            throw e;
+        } catch (Exception e) {
+            // jndi.83=NamingManager.getObjectInstance() failed
+            throw (NamingException) new NamingException(Messages
+                    .getString("jndi.83")).initCause(e); //$NON-NLS-1$
+        }
+    }
+
+    private boolean hasAttribute(Attributes attributes, String type,
+            Object value) throws NamingException {
+        Attribute attr = attributes.get(type);
+        if (attr == null) {
+            return false;
+        }
+
+        NamingEnumeration<?> enu = attr.getAll();
+        while (enu.hasMore()) {
+            Object o = enu.next();
+            if (value.equals(o)) {
+                return true;
+            }
+        }
+
+        return false;
     }
 
     public Object lookup(String s) throws NamingException {
@@ -1515,7 +2052,8 @@
      * @throws InvalidNameException
      *             occurs error while converting
      */
-    protected Name convertFromStringToName(String s) throws InvalidNameException {
+    protected Name convertFromStringToName(String s)
+            throws InvalidNameException {
         if (s == null) {
             // jndi.2E=The name is null
             throw new NullPointerException(Messages.getString("jndi.2E")); //$NON-NLS-1$
@@ -1613,7 +2151,16 @@
         ModifyDNOp op = new ModifyDNOp(oldTargetDN, rdn.toString(),
                 isDeleteRdn, name.getPrefix(name.size() - 1).toString());
 
-        doBasicOperation(op);
+        try {
+            doBasicOperation(op);
+        } catch (ReferralException e) {
+            if (isFollowReferral(e)) {
+                DirContext referralContext = getReferralContext(e);
+                referralContext.rename(nOld, nNew);
+                return;
+            }
+            throw e;
+        }
     }
 
     private boolean isInSameNamespace(Name first, Name second) {
@@ -1667,12 +2214,37 @@
         responseControls = narrowingControls(rawControls);
 
         LdapResult result = op.getResult();
+        if (result.getResultCode() == LdapResult.REFERRAL) {
+            throw new ReferralExceptionImpl(contextDn.toString(), result
+                    .getReferrals(), env);
+        }
 
-        // TODO deal with referrals
+        if (LdapUtils.getExceptionFromResult(result) != null) {
+            throw LdapUtils.getExceptionFromResult(result);
+        }
+    }
 
-        NamingException ex = LdapUtils.getExceptionFromResult(result);
-        if (ex != null) {
-            throw ex;
+    private boolean isFollowReferral(ReferralException e)
+            throws ReferralException, PartialResultException {
+        // ignore referral
+        String action = (String) env.get(Context.REFERRAL);
+        if (action == null) {
+            action = "ignore";
+        }
+
+        if ("follow".equals(action)) {
+            return true;
+        } else if ("throw".equals(action)) {
+            return false;
+
+        } else if ("ignore".equals(action)) {
+            // ldap.1A=[LDAP: error code 10 - Referral]
+            throw new PartialResultException(Messages.getString("ldap.1A"));
+
+        } else {
+            throw new IllegalArgumentException(Messages.getString(
+                    "ldap.30", new Object[] { //$NON-NLS-1$
+                    env.get(Context.REFERRAL), Context.REFERRAL }));
         }
     }
 
@@ -1752,29 +2324,11 @@
             }
         }
 
-        if (filter == null) {
-            throw new NullPointerException(Messages.getString("ldap.28")); //$NON-NLS-1$
-        }
-
-        if (filterArgs == null) {
-            filterArgs = new Object[0];
-        }
-
         if (searchControls == null) {
             searchControls = new SearchControls();
         }
 
-        FilterParser filterParser = new FilterParser(filter);
-        filterParser.setArgs(filterArgs);
-        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;
-        }
+        Filter f = LdapUtils.parseFilter(filter, filterArgs);
 
         String targetDN = getTargetDN(name, contextDn);
 

Modified: harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapMessage.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapMessage.java?rev=601315&r1=601314&r2=601315&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapMessage.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapMessage.java Wed Dec  5 04:25:42 2007
@@ -20,6 +20,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
 
 import javax.naming.ldap.Control;
@@ -178,6 +179,16 @@
             responseOp.decodeValues((Object[]) chosen.getValue());
         }
 
+        if (values[2] != null) {
+            Collection<Object[]> list = (Collection<Object[]>) values[2];
+            controls = new Control[list.size()];
+            int index = 0;
+            for (Object[] objects : list) {
+                LdapControl lcontrol = new LdapControl();
+                lcontrol.decodeValues(objects);
+                controls[index++] = lcontrol.getControl();
+            }
+        }
     }
 
     public void encodeValues(Object[] values) {
@@ -216,6 +227,10 @@
 
     public ASN1Decodable getResponseOp() {
         return responseOp;
+    }
+
+    public ASN1Encodable getRequestOp() {
+        return requestOp;
     }
 
 }

Modified: harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapResult.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapResult.java?rev=601315&r1=601314&r2=601315&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapResult.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapResult.java Wed Dec  5 04:25:42 2007
@@ -149,22 +149,6 @@
         return referrals;
     }
 
-    public void setErrorMessage(String errorMessage) {
-        this.errorMessage = errorMessage;
-    }
-
-    public void setMachedDN(String machedDN) {
-        this.machedDN = machedDN;
-    }
-
-    public void setReferrals(String[] referrals) {
-        this.referrals = referrals;
-    }
-
-    public void setResultCode(int resultCode) {
-        this.resultCode = resultCode;
-    }
-
     public int getResultCode() {
         return resultCode;
     }

Modified: harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapSchemaAttrDefContextImpl.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapSchemaAttrDefContextImpl.java?rev=601315&r1=601314&r2=601315&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapSchemaAttrDefContextImpl.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapSchemaAttrDefContextImpl.java Wed Dec  5 04:25:42 2007
@@ -72,10 +72,4 @@
     public Attributes getAttributes(String s) throws NamingException {
         return getAttributes(convertFromStringToName(s));
     }
-
-    public Attributes getAttributes(String s, String[] as)
-            throws NamingException {
-        return getAttributes(convertFromStringToName(s), as);
-    }
-
 }

Modified: harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapSchemaClassDefContextImpl.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapSchemaClassDefContextImpl.java?rev=601315&r1=601314&r2=601315&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapSchemaClassDefContextImpl.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapSchemaClassDefContextImpl.java Wed Dec  5 04:25:42 2007
@@ -54,8 +54,9 @@
             for (int j = 0; j < classes.size(); j++) {
                 String className = classes.get(j);
                 Hashtable<String, Object> classDefInfo = context
-                        .findSchemaDefInfo(LdapSchemaContextImpl.OBJECT_CLASSES,
-                                className);
+                        .findSchemaDefInfo(
+                                LdapSchemaContextImpl.OBJECT_CLASSES, className
+                                        .toLowerCase());
                 as = new BasicAttributes();
                 Set<String> keySet = classDefInfo.keySet();
                 for (Iterator<String> iterator = keySet.iterator(); iterator

Modified: harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapSchemaContextImpl.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapSchemaContextImpl.java?rev=601315&r1=601314&r2=601315&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapSchemaContextImpl.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapSchemaContextImpl.java Wed Dec  5 04:25:42 2007
@@ -18,7 +18,6 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Enumeration;
 import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.LinkedList;
@@ -27,6 +26,7 @@
 import java.util.TreeSet;
 
 import javax.naming.Binding;
+import javax.naming.CompositeName;
 import javax.naming.ConfigurationException;
 import javax.naming.Context;
 import javax.naming.InvalidNameException;
@@ -93,10 +93,8 @@
 
     private Name rdn = null;
 
-    private BasicAttributes schemaAttributes;
-
-    public LdapSchemaContextImpl(LdapContextImpl ctx,
-            Hashtable<Object, Object> env, Name dn) throws InvalidNameException {
+    public LdapSchemaContextImpl(LdapContextImpl ctx, Hashtable<Object, Object> env,
+            Name dn) throws InvalidNameException {
         super(ctx, env, dn.getPrefix(0).toString());
         parent = ctx;
         rdn = dn;
@@ -134,8 +132,11 @@
             throw new SchemaViolationException(Messages.getString("jndi.8D"));
         }
 
-        if (!LdapContextImpl.schemaTree.keySet().contains(
-                schemaJndi2Ldap.get(schemaType.toString().toLowerCase()))) {
+        String schema = schemaJndi2Ldap.get(schemaType.toString().toLowerCase());
+        if (null == schema) {
+            throw new SchemaViolationException(Messages.getString("jndi.8D"));
+        }
+        if (!LdapContextImpl.schemaTree.keySet().contains(schema)) {
             throw new SchemaViolationException(Messages.getString("jndi.8E"));
         }
         String targetDN = rdn.toString() + parent.subschemasubentry;
@@ -166,8 +167,7 @@
 
         ModifyOp op = new ModifyOp(targetDN);
         BasicAttribute schemaEntry = new LdapAttribute(new BasicAttribute(
-                schemaJndi2Ldap.get(schemaType.toString().toLowerCase()),
-                builder.toString()), parent);
+                schema, builder.toString()), parent);
         op.addModification(jndi2ldap[DirContext.ADD_ATTRIBUTE],
                 new LdapAttribute(schemaEntry, parent));
 
@@ -181,36 +181,45 @@
 
     public DirContext createSubcontext(String name, Attributes attributes)
             throws NamingException {
-        return createSubcontext(convertFromStringToName(name), attributes);
+        Name n = convertFromStringToName(name);
+        return createSubcontext(n, attributes);
     }
 
     public Attributes getAttributes(Name name) throws NamingException {
-        if (null != schemaAttributes) {
-            return schemaAttributes;
-        }
-        Name schemaName = name;
-        if (schemaName.size() == 0) {
-            schemaName = rdn;
-        }
-        if (schemaName.size() != 2) {
-            throw new NameNotFoundException(name.toString());
-        }
-        Hashtable<String, Object> schemaDef = parent.findSchemaDefInfo(
-                schemaJndi2Ldap.get(schemaName.get(0).toLowerCase()),
-                schemaName.get(1).toLowerCase());
-        if (null == schemaDef) {
-            throw new NameNotFoundException(name.toString());
-        }
-        schemaAttributes = new BasicAttributes();
-        Enumeration<String> keys = schemaDef.keys();
-        while (keys.hasMoreElements()) {
-            String id = keys.nextElement();
-            if (id.equals("orig")) {
-                continue;
-            }
-            Object value = schemaDef.get(id);
-            schemaAttributes.put(new LdapAttribute(
-                    new BasicAttribute(id, value), parent));
+        Name targetDN = (rdn.size() != 0) ? name.addAll(rdn) : name;
+
+        BasicAttributes schemaAttributes = new BasicAttributes();
+
+        Set<String> keyset = null;
+        int size = targetDN.size();
+        switch (size) {
+        case 0:
+            break;
+        case 1:
+            String schemaType = schemaJndi2Ldap.get(name.get(0).toLowerCase());
+            if (null == schemaType) {
+                throw new NameNotFoundException(name.toString());
+            }
+            schemaAttributes.put(new BasicAttribute("objectclass", name.get(0)
+                    .toLowerCase()));
+            break;
+        default:
+            Hashtable<String, Object> classDef = parent.findSchemaDefInfo(
+                    schemaJndi2Ldap.get(name.get(0).toLowerCase()), name.get(1));
+            if (null == classDef) {
+                throw new NameNotFoundException(name.toString());
+            }
+            schemaAttributes = new BasicAttributes();
+            keyset = classDef.keySet();
+            for (Iterator<String> i = keyset.iterator(); i.hasNext();) {
+                String id = i.next();
+                if (id.equals("orig")) {
+                    continue;
+                }
+                Object value = classDef.get(id);
+                schemaAttributes
+                        .put(new BasicAttribute(id.toLowerCase(), value));
+            }
         }
         return schemaAttributes;
     }
@@ -231,13 +240,13 @@
 
     public Attributes getAttributes(String attributeName)
             throws NamingException {
-        Name name = convertFromStringToName(attributeName);
+        Name name = new CompositeName(attributeName);
         return getAttributes(name);
     }
 
     public Attributes getAttributes(String name, String[] as)
             throws NamingException {
-        return getAttributes(convertFromStringToName(name), as);
+        return getAttributes(new CompositeName(name), as);
     }
 
     private void checkName(Name name) {
@@ -282,20 +291,35 @@
             throws NamingException {
         checkName(name);
 
-        if (modificationItems == null) {
-            // FIXME: spec say ModificationItem may not be null, but ri
-            // silence in this case
-            throw new NullPointerException(Messages.getString("ldap.27")); //$NON-NLS-1$
-        }
+        Name targetDN = (rdn.size() != 0) ? name.addAll(rdn) : name;
+        int size = targetDN.size();
+        ModifyOp op = new ModifyOp(targetDN.toString());
+        String oldValue = "(objectclass)";
+        switch (size) {
+        case 0:
+            break;
+        case 1:
+            String schemaType = schemaJndi2Ldap.get(name.get(0).toLowerCase());
+            if (null == schemaType) {
+                throw new NameNotFoundException(name.toString());
+            }
+            if (modificationItems == null) {
+                throw new NullPointerException(Messages.getString("ldap.27")); //$NON-NLS-1$
+            }
+            break;
+        default:
+            Hashtable<String, Object> classDef = parent
+                    .findSchemaDefInfo(schemaJndi2Ldap.get(name.get(0)
+                            .toLowerCase()), name.get(1));
+            if (modificationItems == null) {
+                throw new NullPointerException(Messages.getString("ldap.27")); //$NON-NLS-1$
+            }
+            if (null == classDef) {
+                throw new NameNotFoundException(name.toString());
+            }
 
-        String targetDN = rdn.toString() + parent.subschemasubentry;
-        ModifyOp op = new ModifyOp(targetDN);
-        Hashtable<String, Object> classDef = parent.findSchemaDefInfo(
-                schemaJndi2Ldap.get(name.get(0).toLowerCase()), name.get(1));
-        if (null == classDef) {
-            throw new NameNotFoundException(name.toString());
+            oldValue = (String) classDef.get("orig");
         }
-        String oldValue = (String) classDef.get("orig");
         BasicAttribute oldAttr = new LdapAttribute(new BasicAttribute(
                 OBJECT_CLASSES, oldValue), parent);
         StringBuilder addValue = new StringBuilder();
@@ -304,39 +328,43 @@
             addValue.append(attr.getID()).append(" ").append(attr.get());
         }
         addValue.append(" )");
-        BasicAttribute newAttr = new LdapAttribute(new BasicAttribute(
-                OBJECT_CLASSES, oldValue.replace(")", addValue.toString())),
-                this);
+        BasicAttribute newAttr = new LdapAttribute(
+                new BasicAttribute(OBJECT_CLASSES, oldValue.replace(")",
+                        addValue.toString())), this);
         op.addModification(jndi2ldap[DirContext.REMOVE_ATTRIBUTE],
                 new LdapAttribute(oldAttr, parent));
         op.addModification(jndi2ldap[DirContext.ADD_ATTRIBUTE],
                 new LdapAttribute(newAttr, parent));
-
+        
         try {
             doBasicOperation(op);
-        } catch (ReferralException e) {
-            // TODO handle referral in the future
+        } catch (Exception e) {
+            throw new SchemaViolationException("Cannot modify schema root");
         }
 
     }
 
     public void modifyAttributes(String s, int i, Attributes attributes)
             throws NamingException {
-        modifyAttributes(convertFromStringToName(s), i, attributes);
+        Name name = convertFromStringToName(s);
+        modifyAttributes(name, i, attributes);
     }
 
     public void modifyAttributes(String s, ModificationItem[] modificationItems)
             throws NamingException {
-        modifyAttributes(convertFromStringToName(s), modificationItems);
+        Name name = convertFromStringToName(s);
+        modifyAttributes(name, modificationItems);
 
     }
 
     public Context createSubcontext(Name name) throws NamingException {
-        return createSubcontext(name, null);
+        DirContext subContext = createSubcontext(name, null);
+        return subContext;
     }
 
     public Context createSubcontext(String name) throws NamingException {
-        return createSubcontext(convertFromStringToName(name));
+        Name n = convertFromStringToName(name);
+        return createSubcontext(n);
     }
 
     public void destroySubcontext(Name name) throws NamingException {
@@ -374,15 +402,47 @@
         destroySubcontext(convertFromStringToName(name));
     }
 
-    public NamingEnumeration<NameClassPair> list(Name n) throws NamingException {
-        Set<String> keyset = LdapContextImpl.schemaTree.keySet();
+    public NamingEnumeration<NameClassPair> list(Name name)
+            throws NamingException {
+        Name targetDN = name.addAll(rdn);
+
         LdapNamingEnumeration<NameClassPair> enumeration = new LdapNamingEnumeration<NameClassPair>(
                 null, null);
-        for (Iterator<String> i = keyset.iterator(); i.hasNext();) {
-            String schemaType = i.next();
-            NameClassPair pair = new NameClassPair(schemaLdap2Jndi
-                    .get(schemaType.toLowerCase()), this.getClass().getName());
-            enumeration.add(pair);
+        Set<String> keyset = null;
+        int size = targetDN.size();
+        switch (size) {
+        case 0:
+            keyset = LdapContextImpl.schemaTree.keySet();
+            for (Iterator<String> i = keyset.iterator(); i.hasNext();) {
+                String schemaType = i.next();
+                NameClassPair pair = new NameClassPair(schemaLdap2Jndi
+                        .get(schemaType.toLowerCase()), this.getClass()
+                        .getName());
+                enumeration.add(pair);
+            }
+            break;
+        case 1:
+            String 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);
+            keyset = schemas.keySet();
+            for (Iterator<String> i = keyset.iterator(); i.hasNext();) {
+                schemaType = i.next();
+                NameClassPair pair = new NameClassPair(
+                        schemaType.toLowerCase(), this.getClass().getName());
+                enumeration.add(pair);
+            }
+            break;
+        default:
+            schemaType = schemaJndi2Ldap.get(name.getPrefix(1).toString()
+                    .toLowerCase());
+            if (null == schemaType) {
+                throw new NameNotFoundException(name.toString());
+            }
+            list(name.getSuffix(1));
         }
         return enumeration;
     }
@@ -394,37 +454,56 @@
         return list(convertFromStringToName(name));
     }
 
-    public NamingEnumeration<Binding> listBindings(Name n)
+    public NamingEnumeration<Binding> listBindings(Name name)
             throws NamingException {
-        // TODO Auto-generated method stub
-        return null;
+        Name targetDN = name.addAll(rdn);
+
+        LdapNamingEnumeration<Binding> enumeration = new LdapNamingEnumeration<Binding>(
+                null, null);
+        Set<String> keyset = null;
+        int size = targetDN.size();
+        switch (size) {
+        case 0:
+            keyset = LdapContextImpl.schemaTree.keySet();
+            for (Iterator<String> i = keyset.iterator(); i.hasNext();) {
+                String schemaType = i.next();
+                Binding binding = new Binding(schemaLdap2Jndi.get(schemaType
+                        .toLowerCase()), this.getClass().getName(), null);
+                enumeration.add(binding);
+            }
+            break;
+        case 1:
+            String 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);
+            keyset = schemas.keySet();
+            for (Iterator<String> i = keyset.iterator(); i.hasNext();) {
+                schemaType = i.next();
+                Binding binding = new Binding(schemaType.toLowerCase(), this
+                        .getClass().getName(), null);
+                enumeration.add(binding);
+            }
+            break;
+        default:
+            schemaType = schemaJndi2Ldap.get(name.getPrefix(1).toString()
+                    .toLowerCase());
+            if (null == schemaType) {
+                throw new NameNotFoundException(name.toString());
+            }
+            list(name.getSuffix(1));
+        }
+        return enumeration;
     }
 
-    public NamingEnumeration<Binding> listBindings(String s)
+    public NamingEnumeration<Binding> listBindings(String name)
             throws NamingException {
-        // TODO Auto-generated method stub
-        return null;
+        return listBindings(convertFromStringToName(name));
     }
 
     public Object lookup(Name n) throws NamingException {
-        if (n.size() == 0) {
-            return this;
-        }
-        if (n.size() == 1) {
-            throw new NameNotFoundException(n.toString());
-        }
-        Hashtable<String, Object> schemaDef = parent.findSchemaDefInfo(
-        // mapping jndi schema type name to ldap native name
-                schemaJndi2Ldap.get(
-                // get [0, 1) as the jndi schema type name
-                        n.getPrefix(1).toString().toLowerCase()),
-                // schema name
-                n.getSuffix(1).toString().toLowerCase()); // find SchemaDef
-        // Info.
-
-        if (null == schemaDef) {
-            throw new NameNotFoundException(n.toString());
-        }
         return new LdapSchemaContextImpl(parent, env, n.addAll(rdn));
     }
 
@@ -438,6 +517,11 @@
 
     public void rename(String sOld, String sNew) throws NamingException {
         throw new SchemaViolationException(Messages.getString("jndi.err.01"));
+    }
+
+    public NamingEnumeration<SearchResult> search(Name name,
+            Attributes attributes) throws NamingException {
+        return search(name, attributes, null);
     }
 
     public NamingEnumeration<SearchResult> search(Name name,

Modified: harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapSearchResult.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapSearchResult.java?rev=601315&r1=601314&r2=601315&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapSearchResult.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapSearchResult.java Wed Dec  5 04:25:42 2007
@@ -40,14 +40,23 @@
 
     /**
      * SearchResultReference from server
-     * TODO: deal with the references
      */
-    private List<String> refURLs = new ArrayList<String>();
+    private List<String> refURLs;
 
     private LdapResult result;
 
     private NamingException ex;
 
+    private String address;
+
+    public String getAddress() {
+		return address;
+	}
+
+	public void setAddress(String address) {
+		this.address = address;
+	}
+
     public void decodeSearchResponse(Object[] values) {
         ChosenValue chosen = (ChosenValue) values[0];
         switch (chosen.getIndex()) {
@@ -69,6 +78,10 @@
     }
 
     protected void decodeRef(Object value) {
+        if (refURLs == null) {
+            refURLs = new ArrayList<String>();
+        }
+
         Collection<byte[]> list = (Collection<byte[]>) value;
         for (byte[] bs : list) {
             refURLs.add(Utils.getString(bs));
@@ -78,6 +91,10 @@
     protected void decodeEntry(Object value) {
         Object[] values = (Object[]) value;
         String name = Utils.getString((byte[]) values[0]);
+
+        if (address != null) {
+        	name = address + name;
+        }
 
         Attributes attrs = null;
 

Modified: harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapUtils.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapUtils.java?rev=601315&r1=601314&r2=601315&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapUtils.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapUtils.java Wed Dec  5 04:25:42 2007
@@ -89,7 +89,7 @@
         errorCodesMap.put(80, NamingException.class);
     }
 
-    public static Filter parseFilter(String filter)
+    public static Filter parseFilter(String filter, Object[] args)
             throws InvalidSearchFilterException {
         if (filter == null) {
             // ldap.28=Parameter of filter should not be null
@@ -97,6 +97,13 @@
         }
 
         FilterParser parser = new FilterParser(filter);
+        
+        if (args == null) {
+            args = new Object[0];
+        }
+        
+        parser.setArgs(args);
+        
         try {
             return parser.parse();
         } catch (ParseException e) {

Modified: harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/UnsolicitedNotificationImpl.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/UnsolicitedNotificationImpl.java?rev=601315&r1=601314&r2=601315&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/UnsolicitedNotificationImpl.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/UnsolicitedNotificationImpl.java Wed Dec  5 04:25:42 2007
@@ -21,7 +21,6 @@
 import javax.naming.ldap.Control;
 import javax.naming.ldap.UnsolicitedNotification;
 
-import org.apache.harmony.jndi.internal.Util;
 import org.apache.harmony.jndi.provider.ldap.asn1.ASN1Decodable;
 import org.apache.harmony.jndi.provider.ldap.asn1.Utils;
 
@@ -48,7 +47,7 @@
     }
 
     public NamingException getException() {
-        return Util.getExceptionFromErrorCode(result.getResultCode());
+        return LdapUtils.getExceptionFromResult(result);
     }
 
     public String[] getReferrals() {

Modified: harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/ldapURLContext.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/ldapURLContext.java?rev=601315&r1=601314&r2=601315&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/ldapURLContext.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/ldapURLContext.java Wed Dec  5 04:25:42 2007
@@ -571,13 +571,9 @@
             context = new LdapContextImpl(client,
                     (Hashtable<Object, Object>) environment, dn);
 
-            if (objs == null) {
-                objs = new Object[0];
-            }
-
             Filter f = parser.getFilter();
             if (f == null) {
-                f = LdapUtils.parseFilter(filter);
+                f = LdapUtils.parseFilter(filter, objs);
             }
 
             if (searchControls == null) {

Modified: harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/sasl/SaslBind.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/sasl/SaslBind.java?rev=601315&r1=601314&r2=601315&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/sasl/SaslBind.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/sasl/SaslBind.java Wed Dec  5 04:25:42 2007
@@ -25,13 +25,7 @@
 import javax.naming.AuthenticationNotSupportedException;
 import javax.naming.Context;
 import javax.naming.ldap.Control;
-import javax.security.auth.callback.Callback;
 import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.NameCallback;
-import javax.security.auth.callback.PasswordCallback;
-import javax.security.auth.callback.UnsupportedCallbackException;
-import javax.security.sasl.RealmCallback;
-import javax.security.sasl.RealmChoiceCallback;
 import javax.security.sasl.Sasl;
 import javax.security.sasl.SaslClient;
 import javax.security.sasl.SaslException;
@@ -39,7 +33,6 @@
 import org.apache.harmony.jndi.provider.ldap.BindOp;
 import org.apache.harmony.jndi.provider.ldap.LdapClient;
 import org.apache.harmony.jndi.provider.ldap.LdapResult;
-import org.apache.harmony.jndi.provider.ldap.asn1.Utils;
 import org.apache.harmony.jndi.provider.ldap.parser.ParseException;
 
 /**
@@ -253,59 +246,5 @@
             }
         }
         return "";
-    }
-}
-
-/*
- * Default callback handler, may be customized through
- * "java.naming.security.sasl.realm".
- */
-class DefaultCallbackHandler implements CallbackHandler {
-    
-    private static final String JAVA_NAMING_SECURITY_SASL_REALM = "java.naming.security.sasl.realm";
-
-    private Hashtable env;
-
-    private String realm = "";
-
-    public DefaultCallbackHandler() {
-
-    }
-
-    public DefaultCallbackHandler(Hashtable env) {
-        this.env = env;
-    }
-
-    public void handle(Callback[] callbacks) throws java.io.IOException,
-            UnsupportedCallbackException {
-        for (int i = 0; i < callbacks.length; i++) {
-            if (callbacks[i] instanceof RealmChoiceCallback) {
-                // TODO what to do here?
-                // RealmChoiceCallback rcc = (RealmChoiceCallback) callbacks[i];
-
-            } else if (callbacks[i] instanceof RealmCallback) {
-                RealmCallback rc = (RealmCallback) callbacks[i];
-                if (env.get(JAVA_NAMING_SECURITY_SASL_REALM) != null) {
-                    realm = (String) env.get(JAVA_NAMING_SECURITY_SASL_REALM);
-                    rc.setText(realm);
-                } else {
-                    rc.setText(realm);
-                }
-            } else if (callbacks[i] instanceof PasswordCallback) {
-                PasswordCallback pc = (PasswordCallback) callbacks[i];
-                pc.setPassword(Utils.getCharArray(env
-                        .get(Context.SECURITY_CREDENTIALS)));
-            } else if (callbacks[i] instanceof NameCallback) {
-                //authentication Id
-                NameCallback nc = (NameCallback) callbacks[i];
-                nc.setName((String) env.get(Context.SECURITY_PRINCIPAL));
-            } else {
-                throw new UnsupportedCallbackException(callbacks[i]);
-            }
-        }
-    }
-
-    public void setRealm(String realm) {
-        this.realm = realm;
     }
 }

Modified: harmony/enhanced/classlib/branches/java6/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/ldap/LdapContextImplTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/ldap/LdapContextImplTest.java?rev=601315&r1=601314&r2=601315&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/ldap/LdapContextImplTest.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/ldap/LdapContextImplTest.java Wed Dec  5 04:25:42 2007
@@ -18,7 +18,9 @@
 package org.apache.harmony.jndi.provider.ldap;
 
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Hashtable;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
@@ -26,6 +28,7 @@
 import javax.naming.Context;
 import javax.naming.InvalidNameException;
 import javax.naming.Name;
+import javax.naming.NamingEnumeration;
 import javax.naming.NamingException;
 import javax.naming.directory.Attribute;
 import javax.naming.directory.Attributes;
@@ -42,6 +45,8 @@
 import javax.naming.ldap.BasicControl;
 import javax.naming.ldap.Control;
 import javax.naming.ldap.LdapName;
+import javax.naming.ldap.PagedResultsControl;
+import javax.naming.ldap.SortControl;
 
 import junit.framework.TestCase;
 
@@ -50,7 +55,7 @@
 
 public class LdapContextImplTest extends TestCase {
     private LdapContextImpl context;
-    
+
     public void test_getSchema() throws NamingException {
         context = new LdapContextImpl(new MockLdapClient(), null, "");
         try {
@@ -59,7 +64,7 @@
         } catch (NullPointerException e) {
             // expected
         }
-        
+
         try {
             context.getSchema((String) null);
             fail("Should throw NullPointerException");
@@ -67,6 +72,23 @@
             // expected
         }
     }
+    
+    public void test_getSchemaClassDefinition() throws NamingException {
+        context = new LdapContextImpl(new MockLdapClient(), null, "");
+        try {
+            context.getSchemaClassDefinition((Name) null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        
+        try {
+            context.getSchemaClassDefinition((String) null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
 
     public void test_composeName_LNameLName() throws Exception {
         context = new LdapContextImpl(new MockLdapClient(), null, "");
@@ -551,6 +573,113 @@
         assertFalse(returnedEnv.containsKey(Context.REFERRAL));
     }
 
+    public void test_bind() throws Exception {
+        MockLdapClient client = new MockLdapClient();
+        Hashtable<Object, Object> env = new Hashtable<Object, Object>();
+
+        context = new LdapContextImpl(client, env, "cn=test");
+        context.bind("cn=bind", "it's bind");
+
+        AddOp op = (AddOp) client.getRequest();
+        assertEquals("cn=bind,cn=test", op.getEntry());
+        List<LdapAttribute> attrList = op.getAttributeList();
+        // has attribute: objectClass, javaClassNames, javaClassName,
+        // javaSerializedData, cn
+        assertEquals(5, attrList.size());
+        Map<String, LdapAttribute> map = new HashMap<String, LdapAttribute>();
+        for (Iterator iter = attrList.iterator(); iter.hasNext();) {
+            LdapAttribute attr = (LdapAttribute) iter.next();
+            map.put(attr.getID(), attr);
+        }
+
+        assertTrue(map.containsKey("objectClass"));
+        Attribute attribute = map.get("objectClass");
+        NamingEnumeration<?> enu = attribute.getAll();
+        HashSet<Object> valueSet = new HashSet<Object>();
+        while (enu.hasMore()) {
+            valueSet.add(enu.next());
+        }
+        // objectClass has values: top, javaContainer, javaObject,
+        // javaSerializedObject
+        assertEquals(4, valueSet.size());
+        assertTrue(valueSet.contains("top"));
+        assertTrue(valueSet.contains("javaContainer"));
+        assertTrue(valueSet.contains("javaObject"));
+        assertTrue(valueSet.contains("javaSerializedObject"));
+
+        assertTrue(map.containsKey("javaClassNames"));
+        attribute = map.get("javaClassNames");
+        enu = attribute.getAll();
+        valueSet = new HashSet<Object>();
+        while (enu.hasMore()) {
+            valueSet.add(enu.next());
+        }
+
+        assertEquals(5, valueSet.size());
+        assertTrue(valueSet.contains("java.io.Serializable"));
+        assertTrue(valueSet.contains("java.lang.CharSequence"));
+        assertTrue(valueSet.contains("java.lang.Comparable"));
+        assertTrue(valueSet.contains("java.lang.Object"));
+        assertTrue(valueSet.contains("java.lang.String"));
+
+        assertTrue(map.containsKey("javaClassName"));
+        attribute = map.get("javaClassName");
+        assertEquals(1, attribute.size());
+        assertEquals(String.class.getName(), attribute.get(0));
+
+        assertTrue(map.containsKey("javaSerializedData"));
+        assertEquals(1, attribute.size());
+        attribute = map.get("javaSerializedData");
+
+        assertTrue(map.containsKey("cn"));
+        attribute = map.get("cn");
+        assertEquals(1, attribute.size());
+        assertEquals("bind", attribute.get(0));
+    }
+
+    public void test_lookup() throws Exception {
+        MockLdapClient client = new MockLdapClient();
+        Hashtable<Object, Object> env = new Hashtable<Object, Object>();
+
+        context = new LdapContextImpl(client, env, "cn=test");
+        context.lookup("cn=lookup");
+
+        SearchOp op = (SearchOp) client.getRequest();
+        assertEquals("cn=lookup,cn=test", op.getBaseObject());
+        SearchControls controls = op.getControls();
+        assertEquals(SearchControls.OBJECT_SCOPE, controls.getSearchScope());
+        assertNull(controls.getReturningAttributes());
+
+        Filter filter = op.getFilter();
+        assertEquals(Filter.PRESENT_FILTER, filter.getType());
+        assertEquals("objectClass", filter.getValue());
+    }
+
+    public void test_listBinding() throws Exception {
+        MockLdapClient client = new MockLdapClient();
+        context = new LdapContextImpl(client, new Hashtable<Object, Object>(),
+                "cn=test");
+
+        context.list("cn=listBinding");
+
+        SearchOp op = (SearchOp) client.getRequest();
+        assertEquals("cn=listBinding,cn=test", op.getBaseObject());
+        assertFalse(op.isTypesOnly());
+        SearchControls controls = op.getControls();
+        assertEquals(SearchControls.ONELEVEL_SCOPE, controls.getSearchScope());
+        Filter filter = op.getFilter();
+        assertEquals(Filter.PRESENT_FILTER, filter.getType());
+        assertEquals("objectClass", (String) filter.getValue());
+
+        Name name = new CompositeName("usr/bin");
+        try {
+            context.list(name);
+            fail("should throws InvalidNameException");
+        } catch (InvalidNameException e) {
+            // expected
+        }
+    }
+
     public void test_addNamingListener() throws Exception {
         MockLdapClient client = new MockLdapClient();
         Hashtable<Object, Object> env = new Hashtable<Object, Object>();
@@ -668,6 +797,37 @@
         context.removeNamingListener(listener);
     }
 
+    public void test_reconnect() throws Exception {
+        Hashtable<Object, Object> env = new Hashtable<Object, Object>();
+        env
+        .put("java.naming.ldap.control.connect",
+                new Control[] { new PagedResultsControl(10,
+                        Control.NONCRITICAL) });
+
+        MockLdapClient client = new MockLdapClient();
+        context = new LdapContextImpl(client, env, "cn=test");
+        
+        Control[] controls = context.getConnectControls();
+        assertNotNull(controls);
+        Control c = controls[0];
+        assertTrue(c instanceof PagedResultsControl);
+        assertEquals(Control.NONCRITICAL, ((PagedResultsControl) c).isCritical());
+
+        context.reconnect(new Control[] { new SortControl("",
+                Control.NONCRITICAL) });
+        
+        controls = context.getConnectControls();
+        assertNotNull(controls);
+        assertEquals(1, controls.length);
+        c = controls[0];
+        assertTrue(c instanceof SortControl);
+        assertEquals(Control.NONCRITICAL, ((SortControl) c).isCritical());
+        
+        context.reconnect(null);
+        
+        assertNull(context.getConnectControls());
+    }
+    
     public static class TestNamingListener implements NamespaceChangeListener {
 
         private NamingEvent event;

Modified: harmony/enhanced/classlib/branches/java6/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/ldap/LdapSchemaContextImplTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/ldap/LdapSchemaContextImplTest.java?rev=601315&r1=601314&r2=601315&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/ldap/LdapSchemaContextImplTest.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/ldap/LdapSchemaContextImplTest.java Wed Dec  5 04:25:42 2007
@@ -21,6 +21,7 @@
 import javax.naming.CompositeName;
 import javax.naming.Name;
 import javax.naming.NamingException;
+import javax.naming.OperationNotSupportedException;
 import javax.naming.directory.BasicAttributes;
 import javax.naming.directory.ModificationItem;
 import javax.naming.directory.SchemaViolationException;
@@ -123,5 +124,23 @@
 			// expected
 		}
 	}
+
+    public void test_getNameInNamespace() throws NamingException {
+        try {
+            context.getNameInNamespace();
+            fail("Should throw OperationNotSupportedException");
+        } catch (OperationNotSupportedException e) {
+            // expected
+        }
+    }
+    
+    public void test_getSchemaClassDefinition() throws NamingException {
+        try {
+            context.getSchemaClassDefinition(new CompositeName(""));
+            fail("Should throw OperationNotSupportedException");
+        } catch (OperationNotSupportedException e) {
+            // expected
+        }
+    }
 
 }

Modified: harmony/enhanced/classlib/branches/java6/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/ldap/LdapUtilsTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/ldap/LdapUtilsTest.java?rev=601315&r1=601314&r2=601315&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/ldap/LdapUtilsTest.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/ldap/LdapUtilsTest.java Wed Dec  5 04:25:42 2007
@@ -20,9 +20,11 @@
 import javax.naming.CommunicationException;
 import javax.naming.NamingException;
 import javax.naming.TimeLimitExceededException;
+import javax.naming.directory.InvalidSearchFilterException;
 
 import junit.framework.TestCase;
 
+import org.apache.harmony.jndi.internal.parser.AttributeTypeAndValuePair;
 import org.apache.harmony.jndi.provider.ldap.asn1.Utils;
 import org.apache.harmony.security.asn1.ASN1Integer;
 
@@ -50,6 +52,37 @@
         ex = LdapUtils.getExceptionFromResult(result);
         assertTrue(ex instanceof TimeLimitExceededException);
         assertEquals("[LDAP: error code 3]", ex.getMessage());
+    }
+
+    public void test_parseFilter() throws Exception {
+        try {
+            LdapUtils.parseFilter(null, new Object[0]);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            LdapUtils.parseFilter("object=*", null);
+            fail("Should throw InvalidSearchFilterException");
+        } catch (InvalidSearchFilterException e) {
+            // expected
+        }
+        
+
+        Filter filter = LdapUtils.parseFilter("(cn={0})", new Object[] { "value" });
+        assertEquals(Filter.EQUALITY_MATCH_FILTER, filter.getType());
+        assertTrue(filter.getValue() instanceof AttributeTypeAndValuePair);
+        AttributeTypeAndValuePair pair = (AttributeTypeAndValuePair) filter.getValue();
+        assertEquals("cn", pair.getType());
+        assertEquals("value", pair.getValue());
+
+        filter = LdapUtils.parseFilter("(cn=test)", null);
+        assertEquals(Filter.EQUALITY_MATCH_FILTER, filter.getType());
+        assertTrue(filter.getValue() instanceof AttributeTypeAndValuePair);
+        pair = (AttributeTypeAndValuePair) filter.getValue();
+        assertEquals("cn", pair.getType());
+        assertEquals("test", pair.getValue());
     }
 
     private LdapResult getLdapResult(int errorCode, String message) {

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/io/StreamTokenizer.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/io/StreamTokenizer.java?rev=601315&r1=601314&r2=601315&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/io/StreamTokenizer.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/io/StreamTokenizer.java Wed Dec  5 04:25:42 2007
@@ -607,8 +607,13 @@
                 result.append(sval);
                 break;
             default:
-                result.append(sval);
-                break;
+                if (ttype == TT_UNKNOWN || tokenTypes[ttype] == TOKEN_QUOTE) {
+                    result.append(sval);
+                } else {
+                    result.append('\'');
+                    result.append((char) ttype);
+                    result.append('\'');
+                }
         }
         result.append("], line "); //$NON-NLS-1$
         result.append(lineNumber);

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/lang/reflect/Proxy.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/lang/reflect/Proxy.java?rev=601315&r1=601314&r2=601315&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/lang/reflect/Proxy.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/lang/reflect/Proxy.java Wed Dec  5 04:25:42 2007
@@ -163,10 +163,10 @@
                 }
             } else {
                 newClass = ref.get();
-                assert newClass != null : "interfaceKey=" + interfaceKey
-                                        + "loaderCache=" + loaderCache 
-                                        + "\nintfCache=" + interfaceCache
-                                        + "\nproxyCache=" + proxyCache; 
+                assert newClass != null : "\ninterfaceKey=\"" + interfaceKey + "\""
+                                        + "\nloaderCache=\"" + loaderCache + "\""
+                                        + "\nintfCache=\"" + interfaceCache + "\""
+                                        + "\nproxyCache=\"" + proxyCache + "\"";
             }
             return newClass;
         }



Mime
View raw message