You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by qi...@apache.org on 2008/06/04 08:48:11 UTC
svn commit: r663009 - in /harmony/enhanced/classlib/trunk/modules/jndi/src:
main/java/org/apache/harmony/jndi/provider/ldap/
test/java/org/apache/harmony/jndi/provider/ldap/
Author: qiuxx
Date: Tue Jun 3 23:48:10 2008
New Revision: 663009
URL: http://svn.apache.org/viewvc?rev=663009&view=rev
Log:
Apply patch for HARMONY-5861,([classlib][jndi][ldap] - moving code of constructing NamingEnumeration from Context class to LdapSearchResult)
Added:
harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/ldap/LdapSearchResultTest.java (with props)
Modified:
harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapContextImpl.java
harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapNamingEnumeration.java
harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapSchemaContextImpl.java
harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapSearchResult.java
harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/ldapURLContext.java
Modified: harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapContextImpl.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapContextImpl.java?rev=663009&r1=663008&r2=663009&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapContextImpl.java (original)
+++ harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapContextImpl.java Tue Jun 3 23:48:10 2008
@@ -209,6 +209,11 @@
doBindOperation(connCtls);
}
+ public LdapContextImpl(LdapContextImpl context, String dn)
+ throws NamingException {
+ this(context.client, context.env, dn);
+ }
+
private void initial(LdapClient ldapClient,
Hashtable<Object, Object> environment, String dn)
throws InvalidNameException {
@@ -887,7 +892,6 @@
Hashtable<String, String> schemaDef = (Hashtable<String, String>) schemaTable
.get(schemaType.toLowerCase());
LdapAttribute attribute = (LdapAttribute) as.get(schemaType);
-
String value;
String attrName;
for (int i = 0; i < attribute.size(); i++) {
@@ -898,8 +902,8 @@
}
}
- ldapSchemaCtx = new LdapSchemaContextImpl(this, env, name,
- schemaTable, LdapSchemaContextImpl.SCHEMA_ROOT_LEVEL);
+ ldapSchemaCtx = new LdapSchemaContextImpl(this, env, name, schemaTable,
+ LdapSchemaContextImpl.SCHEMA_ROOT_LEVEL);
return ldapSchemaCtx;
}
@@ -1083,7 +1087,8 @@
filter.setValue("objectClass");
} else {
// only one attribute type and value pair
- if (attributes.size() == 1 && attributes.getAll().next().size() == 1) {
+ if (attributes.size() == 1
+ && attributes.getAll().next().size() == 1) {
filter = new Filter(Filter.EQUALITY_MATCH_FILTER);
Attribute att = attributes.getAll().next();
filter.setValue(new AttributeTypeAndValuePair(att.getID(), att
@@ -1111,33 +1116,10 @@
controls.setReturningAttributes(as);
LdapSearchResult result = doSearch(targetDN, filter, controls);
- List<SearchResult> list = new ArrayList<SearchResult>();
- Map<String, Attributes> entries = result.getEntries();
- Name tempName = new LdapName(contextDn.toString());
- tempName.addAll(name);
- String baseDN = tempName.toString();
- for (String dn : entries.keySet()) {
- 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 = LdapUtils.convertToRelativeName(dn,
- baseDN);
- sr = new SearchResult(relativeName, null, entries.get(dn));
- sr.setNameInNamespace(dn);
- }
- list.add(sr);
- }
-
- if (list.size() == 0 && result.getException() != null) {
+ if (result.isEmpty() && result.getException() != null) {
throw result.getException();
}
-
- return new LdapNamingEnumeration<SearchResult>(list, result
- .getException());
+ return result.toSearchResultEnumeration(targetDN);
}
public NamingEnumeration<SearchResult> search(Name name, String filter,
@@ -1170,33 +1152,11 @@
LdapSearchResult result = doSearch(targetDN, f, searchControls);
- List<SearchResult> list = new ArrayList<SearchResult>();
- Map<String, Attributes> entries = result.getEntries();
- Name tempName = new LdapName(contextDn.toString());
- tempName.addAll(name);
- String baseDN = tempName.toString();
- for (String dn : entries.keySet()) {
- 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 = LdapUtils.convertToRelativeName(dn,
- baseDN);
- sr = new SearchResult(relativeName, null, entries.get(dn));
- sr.setNameInNamespace(dn);
- }
- list.add(sr);
- }
-
- if (list.size() == 0 && result.getException() != null) {
+ if (result.isEmpty() && result.getException() != null) {
throw result.getException();
}
-
- return new LdapNamingEnumeration<SearchResult>(list, result
- .getException());
+
+ return result.toSearchResultEnumeration(targetDN);
}
public NamingEnumeration<SearchResult> search(Name name, String filter,
@@ -1285,33 +1245,34 @@
LdapResult result = op.getResult();
- op.getSearchResult().setException(
- LdapUtils.getExceptionFromResult(result));
-
- // has error, not deal with referrals
- if (result.getResultCode() != LdapResult.REFERRAL
- && op.getSearchResult().getException() != null) {
- return op.getSearchResult();
- }
+ if (result != null) {
+ op.getSearchResult().setException(
+ LdapUtils.getExceptionFromResult(result));
+
+ // has error, not deal with referrals
+ if (result.getResultCode() != LdapResult.REFERRAL
+ && op.getSearchResult().getException() != null) {
+ return op.getSearchResult();
+ }
- // baseObject is not located at the server
- 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);
+ // baseObject is not located at the server
+ 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();
}
- } 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) {
@@ -1605,34 +1566,11 @@
LdapSearchResult result = doSearch(targetDN, filter, controls);
- List<NameClassPair> list = new ArrayList<NameClassPair>();
- Map<String, Attributes> entries = result.getEntries();
- Name tempName = new LdapName(contextDn.toString());
- tempName.addAll(name);
- String baseDN = tempName.toString();
- for (String dn : entries.keySet()) {
- String relativeName = LdapUtils.convertToRelativeName(dn, baseDN);
- Attributes attrs = entries.get(dn);
- Attribute attrClass = attrs.get("javaClassName");
- String className = null;
- if (attrClass != null) {
- className = (String) attrClass.get(0);
- } else {
- className = DirContext.class.getName();
- }
- NameClassPair pair = new NameClassPair(relativeName, className,
- true);
- pair.setNameInNamespace(dn);
- list.add(pair);
- }
-
- // no entries return
- if (list.size() == 0 && result.getException() != null) {
+ if (result.isEmpty() && result.getException() != null) {
throw result.getException();
}
- return new LdapNamingEnumeration<NameClassPair>(list, result
- .getException());
+ return result.toNameClassPairEnumeration(targetDN);
}
protected String getTargetDN(Name name, Name prefix)
@@ -1750,28 +1688,23 @@
* there is only one ldap ns
*/
- NamingEnumeration<NameClassPair> enu = list(name);
-
- List<Binding> bindings = new ArrayList<Binding>();
+ // NamingEnumeration<NameClassPair> enu = list(name);
+ // absolute dn name to list
+ String targetDN = getTargetDN(name, contextDn);
- 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());
- }
+ // construct one-level search using filter "(objectclass=*)"
+ SearchControls controls = new SearchControls();
+ controls.setSearchScope(SearchControls.ONELEVEL_SCOPE);
+ Filter filter = new Filter(Filter.PRESENT_FILTER);
+ filter.setValue("objectClass");
- Binding binding = new Binding(pair.getName(), bound.getClass()
- .getName(), bound);
- binding.setNameInNamespace(pair.getNameInNamespace());
- bindings.add(binding);
+ LdapSearchResult result = doSearch(targetDN, filter, controls);
+ if (result.isEmpty() && result.getException() != null) {
+ throw result.getException();
}
- // FIXME: deal with exception
- return new LdapNamingEnumeration<Binding>(bindings, null);
+ return result.toBindingEnumeration(this, name);
}
public NamingEnumeration<Binding> listBindings(String s)
Modified: harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapNamingEnumeration.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapNamingEnumeration.java?rev=663009&r1=663008&r2=663009&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapNamingEnumeration.java (original)
+++ harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapNamingEnumeration.java Tue Jun 3 23:48:10 2008
@@ -17,66 +17,111 @@
package org.apache.harmony.jndi.provider.ldap;
-import java.util.ArrayList;
import java.util.Collection;
+import java.util.LinkedList;
import java.util.NoSuchElementException;
+import javax.naming.CommunicationException;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
+import org.apache.harmony.jndi.internal.nls.Messages;
+
/**
* TODO: dynamic load elements from server
*/
public class LdapNamingEnumeration<T> implements NamingEnumeration<T> {
- private ArrayList<T> values;
-
- private int currentIndex;
+ private LinkedList<T> values;
private NamingException exception;
/**
+ * flag to indicate whether all element have been added
+ */
+ private boolean isFinished;
+
+ /**
+ * max time to wait next element in millisconds
+ */
+ private long timeout = DEFAULT_TIMEOUT;
+
+ private static final long DEFAULT_TIMEOUT = 30000;
+
+ /**
+ * This constructor equals to
+ * <code>LdapNamingEnumeration(Collection<T>, NamingException, true)</code>
+ */
+ public LdapNamingEnumeration(Collection<T> list, NamingException ex) {
+ this(list, ex, true);
+ }
+
+ /**
* <code>list</code> and <code>ex</code> both can be <code>null</code>,
* <code>null</code> of <code>list</code> will be treated as empty List.
*
* @param list
- * All elements to be enumerate
+ * elements added to the enumeration.
* @param ex
- * exception would be thrown when over iterate
+ * exception would be thrown when over iterate.
+ * @param isFinished
+ * if all elements have been added.
*/
- public LdapNamingEnumeration(Collection<T> list, NamingException ex) {
+ public LdapNamingEnumeration(Collection<T> list, NamingException ex,
+ boolean isFinished) {
if (list == null) {
- values = new ArrayList<T>();
+ values = new LinkedList<T>();
} else {
- values = new ArrayList<T>(list);
+ values = new LinkedList<T>(list);
}
exception = ex;
- currentIndex = 0;
+ this.isFinished = isFinished;
}
/**
* release all relative resources, current implementation just set
- * enumeration values to <code>null</code>.
+ * enumeration values to <code>null</code> which indicate the enumeration
+ * is closed.
*/
- public void close() throws NamingException {
+ public void close() {
// no other resources need to release
- values = null;
+ synchronized (values) {
+ values.clear();
+ values = null;
+ }
}
public boolean hasMore() throws NamingException {
+ // has been closed
if (values == null) {
return false;
}
- if (currentIndex < values.size()) {
+ if (!values.isEmpty()) {
return true;
}
- // no elemnts to iterate, release resource first
+
+ synchronized (values) {
+ if (values.isEmpty() && !isFinished) {
+ waitMoreElement();
+ if (!values.isEmpty()) {
+ return true;
+ }
+ }
+ }
+
close();
+
if (exception != null) {
throw exception;
}
+
+ if (!isFinished) {
+ // ldap.31=Read LDAP response message time out
+ throw new CommunicationException(Messages.getString("ldap.31")); //$NON-NLS-1$
+ }
+
return false;
}
@@ -86,11 +131,27 @@
* invoked.
*/
public T next() throws NamingException {
- if (values == null || currentIndex >= values.size()) {
+ if (values == null || (values.isEmpty() && isFinished)) {
throw new NoSuchElementException();
}
- return values.get(currentIndex++);
+ synchronized (values) {
+ if (values.isEmpty() && !isFinished) {
+ waitMoreElement();
+ // wait timeout
+ if (values.isEmpty() && !isFinished) {
+ if (exception != null) {
+ throw exception;
+ }
+ // ldap.31=Read LDAP response message time out
+ throw new CommunicationException(Messages
+ .getString("ldap.31")); //$NON-NLS-1$
+ } else if (values.isEmpty()) {
+ throw new NoSuchElementException();
+ }
+ }
+ return values.poll();
+ }
}
public boolean hasMoreElements() {
@@ -98,26 +159,86 @@
return false;
}
- if (currentIndex < values.size()) {
+ if (!values.isEmpty()) {
return true;
}
+
+ synchronized (values) {
+ if (values.isEmpty() && !isFinished) {
+ waitMoreElement();
+ if (!values.isEmpty()) {
+ return true;
+ }
+ }
+ }
+
return false;
}
public T nextElement() {
- if (values == null || currentIndex >= values.size()) {
+ if (values == null || (values.isEmpty() && isFinished)) {
throw new NoSuchElementException();
}
- return values.get(currentIndex++);
+ synchronized (values) {
+ if (values.isEmpty() && !isFinished) {
+ waitMoreElement();
+ if (values.isEmpty()) {
+ throw new NoSuchElementException();
+ }
+ }
+ return values.poll();
+ }
+ }
+
+ private void waitMoreElement() {
+ try {
+ values.wait(timeout);
+ } catch (InterruptedException e) {
+ // ignore
+ }
}
- protected void setException(NamingException exception) {
+ void setException(NamingException exception) {
this.exception = exception;
}
-
- void add(T pair) {
- values.add(pair);
+
+ void add(T pair, boolean isFinished) {
+ if (values == null) {
+ return;
+ }
+
+ synchronized (values) {
+ values.add(pair);
+ if (isFinished) {
+ this.isFinished = true;
+ }
+ values.notifyAll();
+ }
}
+ void add(Collection<T> list, boolean isFinished) {
+ if (values == null) {
+ return;
+ }
+
+ synchronized (values) {
+ values.addAll(list);
+ if (isFinished) {
+ this.isFinished = true;
+ }
+ values.notifyAll();
+ }
+ }
+
+ boolean isFinished() {
+ return isFinished;
+ }
+
+ void setFinished() {
+ synchronized (values) {
+ isFinished = true;
+ values.notifyAll();
+ }
+ }
}
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=663009&r1=663008&r2=663009&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 Tue Jun 3 23:48:10 2008
@@ -16,6 +16,7 @@
*/
package org.apache.harmony.jndi.provider.ldap;
+import java.util.ArrayList;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
@@ -490,21 +491,19 @@
Hashtable<String, Object> tempSchema = doLookup(name, size);
- LdapNamingEnumeration<NameClassPair> enumeration = new LdapNamingEnumeration<NameClassPair>(
- null, null);
-
if (size == level - 1) {
- return enumeration;
+ return new LdapNamingEnumeration<NameClassPair>(null, null);
}
Iterator<String> keys = tempSchema.keySet().iterator();
+ List<NameClassPair> list = new ArrayList<NameClassPair>();
while (keys.hasNext()) {
- enumeration.add(new NameClassPair(ldap2jndi(keys.next()), this
- .getClass().getName()));
+ list.add(new NameClassPair(ldap2jndi(keys.next()), this.getClass()
+ .getName()));
}
- return enumeration;
+ return new LdapNamingEnumeration<NameClassPair>(list, null);
}
@Override
@@ -527,21 +526,19 @@
Hashtable<String, Object> tempSchema = doLookup(name, size);
- LdapNamingEnumeration<Binding> enumeration = new LdapNamingEnumeration<Binding>(
- null, null);
-
if (size == level - 1) {
- return enumeration;
+ return new LdapNamingEnumeration<Binding>(null, null);
}
Iterator<String> keys = tempSchema.keySet().iterator();
+ List<Binding> list = new ArrayList<Binding>();
while (keys.hasNext()) {
- enumeration.add(new Binding(ldap2jndi(keys.next()), this.getClass()
+ list.add(new Binding(ldap2jndi(keys.next()), this.getClass()
.getName()));
}
- return enumeration;
+ return new LdapNamingEnumeration<Binding>(list, null);
}
@Override
@@ -647,8 +644,6 @@
Hashtable<String, Object> subschemaTable = doLookup(name, size);
- LdapNamingEnumeration<SearchResult> enumeration = new LdapNamingEnumeration<SearchResult>(
- null, null);
SearchResult searchResult;
Attributes schemaAttributes;
String schemaName;
@@ -656,6 +651,7 @@
if (level - size > 1) {
keyset = subschemaTable.keySet();
+ List<SearchResult> list = new ArrayList<SearchResult>();
for (Iterator<String> i = keyset.iterator(); i.hasNext();) {
schemaName = ldap2jndi(i.next());
Name tempName = (Name) name.clone();
@@ -666,11 +662,12 @@
attributesToReturn);
searchResult = new SearchResult(ldap2jndi(schemaName), this
.getClass().getName(), null, schemaAttributes);
- enumeration.add(searchResult);
+ list.add(searchResult);
}
}
+ return new LdapNamingEnumeration<SearchResult>(list, null);
}
- return enumeration;
+ return new LdapNamingEnumeration<SearchResult>(null, null);
}
@Override
@@ -734,15 +731,13 @@
}
}
- LdapNamingEnumeration<SearchResult> enumeration = new LdapNamingEnumeration<SearchResult>(
- null, null);
-
iterator = searchResults.iterator();
+ List<SearchResult> list = new ArrayList<SearchResult>();
while (iterator.hasNext()) {
- enumeration.add(iterator.next());
+ list.add(iterator.next());
}
- return enumeration;
+ return new LdapNamingEnumeration<SearchResult>(list, null);
}
@Override
Modified: harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapSearchResult.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapSearchResult.java?rev=663009&r1=663008&r2=663009&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapSearchResult.java (original)
+++ harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapSearchResult.java Tue Jun 3 23:48:10 2008
@@ -23,9 +23,17 @@
import java.util.List;
import java.util.Map;
+import javax.naming.Binding;
+import javax.naming.Name;
+import javax.naming.NameClassPair;
+import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.SearchResult;
+import javax.naming.ldap.LdapName;
import org.apache.harmony.jndi.provider.ldap.asn1.LdapASN1Constant;
import org.apache.harmony.jndi.provider.ldap.asn1.Utils;
@@ -34,14 +42,14 @@
public class LdapSearchResult {
/**
- * all search result entries
+ * All search result entries
*/
- private Map<String, Attributes> entries = new HashMap<String, Attributes>();
+ protected HashMap<String, Attributes> entries = new HashMap<String, Attributes>();
/**
* SearchResultReference from server
*/
- private List<String> refURLs;
+ protected List<String> refURLs;
private LdapResult result;
@@ -51,13 +59,54 @@
private String[] binaryAttributes;
+ /**
+ * batch size for this search operation
+ */
+ private int batchSize;
+
+ /**
+ * NamingEnumeration for this LdapSearchResult. One LdapSearchResult
+ * instance can only has one corresponding NamingEnumeration instance.
+ */
+ private LdapNamingEnumeration<Object> enumeration;
+
+ /**
+ * Currently there are three different typs of LdapNamingEnumeration:
+ *
+ * <code>
+ * 1 NameClassPair
+ * 2 Binding
+ * 3 SearchResult
+ * </code>
+ */
+ private int enumerationType;
+
+ private String baseDN;
+
+ private LdapContextImpl context;
+
+ private Name name;
+
+ /**
+ * whether received all search result from server
+ */
+ private boolean isFinished;
+
+ public int getBatchSize() {
+ return batchSize;
+ }
+
+ public void setBatchSize(int batchSize) {
+ this.batchSize = batchSize;
+ }
+
public String getAddress() {
- return address;
- }
+ return address;
+ }
- public void setAddress(String address) {
- this.address = address;
- }
+ public void setAddress(String address) {
+ this.address = address;
+ }
public void decodeSearchResponse(Object[] values) {
ChosenValue chosen = (ChosenValue) values[0];
@@ -77,6 +126,8 @@
protected void decodeDone(Object value) {
result = new LdapResult();
result.decodeValues((Object[]) value);
+ isFinished = true;
+ addToEnumeration();
}
protected void decodeRef(Object value) {
@@ -92,19 +143,20 @@
protected void decodeEntry(Object value) {
Object[] values = (Object[]) value;
- String name = Utils.getString((byte[]) values[0]);
+ String name = Utils.getString(values[0]);
if (address != null) {
- name = address + name;
+ name = address + name;
}
Attributes attrs = null;
-
- if (entries.containsKey(name)) {
- attrs = entries.get(name);
- } else {
- attrs = new BasicAttributes(true);
- entries.put(name, attrs);
+ synchronized (entries) {
+ if (entries.containsKey(name)) {
+ attrs = entries.get(name);
+ } else {
+ attrs = new BasicAttributes(true);
+ entries.put(name, attrs);
+ }
}
Collection<Object[]> list = (Collection<Object[]>) values[1];
@@ -116,6 +168,7 @@
}
attrs.put(attr);
}
+ addToEnumeration();
}
public Map<String, Attributes> getEntries() {
@@ -134,12 +187,21 @@
return ex;
}
- public void setException(NamingException ex) {
- this.ex = ex;
+ public void setException(Exception ex) {
+ if (ex == null) {
+ this.ex = null;
+ return;
+ }
+ if (!(ex instanceof NamingException)) {
+ this.ex = new NamingException(ex.getMessage());
+ this.ex.initCause(ex);
+ } else {
+ this.ex = (NamingException) ex;
+ }
}
public boolean isEmpty() {
- return entries.size() == 0 && refURLs.size() == 0;
+ return entries.size() == 0 && (refURLs == null || refURLs.size() == 0);
}
public void setRefURLs(List<String> refURLs) {
@@ -154,4 +216,111 @@
this.binaryAttributes = binaryAttributes;
}
+ public NamingEnumeration<NameClassPair> toNameClassPairEnumeration(
+ String baseDN) {
+ enumerationType = 1;
+ enumeration = new LdapNamingEnumeration<Object>(null, null);
+ this.baseDN = baseDN;
+ addToEnumeration();
+ return (NamingEnumeration) enumeration;
+ }
+
+ public NamingEnumeration<Binding> toBindingEnumeration(
+ LdapContextImpl context, Name name) throws NamingException {
+ enumerationType = 2;
+ enumeration = new LdapNamingEnumeration<Object>(null, null);
+ this.context = context;
+ this.name = name;
+
+ Name tempName = new LdapName(context.getNameInNamespace());
+ tempName.addAll(name);
+ baseDN = tempName.toString();
+
+ addToEnumeration();
+
+ return (NamingEnumeration) enumeration;
+ }
+
+ public NamingEnumeration<SearchResult> toSearchResultEnumeration(
+ String baseDN) {
+ enumerationType = 3;
+ enumeration = new LdapNamingEnumeration<Object>(null, null);
+ this.baseDN = baseDN;
+
+ addToEnumeration();
+
+ return (NamingEnumeration) enumeration;
+ }
+
+ private void addToEnumeration() {
+ if (enumeration == null || entries == null || entries.isEmpty()) {
+ return;
+ }
+
+ List<Object> list = new ArrayList<Object>();
+ HashMap<String, Attributes> tempEntries = null;
+
+ synchronized (entries) {
+ tempEntries = (HashMap<String, Attributes>) entries.clone();
+ entries.clear();
+ }
+
+ try {
+ for (String dn : tempEntries.keySet()) {
+ String relativeName = LdapUtils.convertToRelativeName(dn,
+ baseDN);
+ Attributes attrs = tempEntries.get(dn);
+ Attribute attrClass = attrs.get("javaClassName"); //$NON-NLS-1$
+ String className = null;
+ switch (enumerationType) {
+ case 1:
+ if (attrClass != null) {
+ className = (String) attrClass.get(0);
+ } else {
+ className = DirContext.class.getName();
+ }
+ NameClassPair pair = new NameClassPair(relativeName,
+ className, true);
+ pair.setNameInNamespace(dn);
+ list.add(pair);
+ break;
+ case 2:
+ Object bound = null;
+
+ if (attrClass != null) {
+ className = (String) attrClass.get(0);
+ bound = context.lookup(name);
+ } else {
+ className = DirContext.class.getName();
+ bound = new LdapContextImpl(context, baseDN);
+ }
+
+ Binding binding = new Binding(relativeName, className,
+ bound);
+ binding.setNameInNamespace(dn);
+ list.add(binding);
+ break;
+ case 3:
+ SearchResult sr = null;
+ if (dn.startsWith("ldap://")) {
+ sr = new SearchResult(dn, null, attrs, false);
+ int index = dn.indexOf("/", 7);
+ sr.setNameInNamespace(dn.substring(index + 1, dn
+ .length()));
+ } else {
+ sr = new SearchResult(relativeName, null, attrs);
+ sr.setNameInNamespace(dn);
+ }
+ list.add(sr);
+ break;
+ }
+ }
+ } catch (NamingException e) {
+ ex = e;
+ isFinished = true;
+ }
+
+ enumeration.setException(ex);
+ enumeration.add(list, isFinished);
+ }
}
Modified: harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/ldapURLContext.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/ldapURLContext.java?rev=663009&r1=663008&r2=663009&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/ldapURLContext.java (original)
+++ harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/ldapURLContext.java Tue Jun 3 23:48:10 2008
@@ -548,22 +548,11 @@
LdapSearchResult result = context.doSearch(dn, filter, controls);
- List<SearchResult> list = new ArrayList<SearchResult>();
- Map<String, Attributes> entries = result.getEntries();
- for (String name : entries.keySet()) {
- String relativeName = convertToRelativeName(dn, name);
- SearchResult sr = new SearchResult(relativeName, null, entries
- .get(name));
- sr.setNameInNamespace(name);
- list.add(sr);
- }
-
- if (list.size() == 0 && result.getException() != null) {
+ if (result.isEmpty() && result.getException() != null) {
throw result.getException();
}
-
- return new LdapNamingEnumeration<SearchResult>(list, result
- .getException());
+
+ return result.toSearchResultEnumeration(dn);
} finally {
if (context != null) {
context.close();
@@ -609,22 +598,11 @@
LdapSearchResult result = context.doSearch(dn, f,
searchControls);
- List<SearchResult> list = new ArrayList<SearchResult>();
- Map<String, Attributes> entries = result.getEntries();
- for (String name : entries.keySet()) {
- String relativeName = convertToRelativeName(dn, name);
- SearchResult sr = new SearchResult(relativeName, null, entries
- .get(name));
- sr.setNameInNamespace(name);
- list.add(sr);
- }
-
- if (list.size() == 0 && result.getException() != null) {
+ if (result.isEmpty() && result.getException() != null) {
throw result.getException();
}
-
- return new LdapNamingEnumeration<SearchResult>(list, result
- .getException());
+
+ return result.toSearchResultEnumeration(dn);
} finally {
if (context != null) {
context.close();
Added: harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/ldap/LdapSearchResultTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/ldap/LdapSearchResultTest.java?rev=663009&view=auto
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/ldap/LdapSearchResultTest.java (added)
+++ harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/ldap/LdapSearchResultTest.java Tue Jun 3 23:48:10 2008
@@ -0,0 +1,202 @@
+/*
+ * 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.ArrayList;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.List;
+
+import javax.naming.Binding;
+import javax.naming.NameClassPair;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.SearchResult;
+import javax.naming.ldap.LdapName;
+
+import junit.framework.TestCase;
+
+public class LdapSearchResultTest extends TestCase {
+ public void test_getter_setter() {
+ LdapSearchResult result = new LdapSearchResult();
+
+ assertNull(result.getAddress());
+ assertNull(result.getBinaryAttributes());
+ assertNotNull(result.getEntries());
+ assertEquals(0, result.getEntries().size());
+ assertNull(result.getException());
+ assertNull(result.getRefURLs());
+ assertNull(result.getResult());
+ assertTrue(result.isEmpty());
+
+ result.setAddress("localhost");
+ assertEquals("localhost", result.getAddress());
+
+ result.setBinaryAttributes(new String[] { "cn", "objectClass" });
+ assertEquals("cn", result.getBinaryAttributes()[0]);
+ assertEquals("objectClass", result.getBinaryAttributes()[1]);
+
+ NamingException exception = new NamingException();
+ result.setException(exception);
+ assertSame(exception, result.getException());
+
+ List<String> refs = new ArrayList<String>();
+ refs.add("ldap://localhost:2008");
+ refs.add("ldap://localhost:1997/cn=test");
+ assertNull(result.getRefURLs());
+ result.setRefURLs(refs);
+
+ assertEquals(2, result.getRefURLs().size());
+ assertTrue(result.getRefURLs().contains("ldap://localhost:2008"));
+ assertTrue(result.getRefURLs()
+ .contains("ldap://localhost:1997/cn=test"));
+ }
+
+ public void test_toNameClassPairEnumeration() throws Exception {
+ HashMap<String, Attributes> entries = new HashMap<String, Attributes>();
+ entries.put("ou=harmony,o=apache,cn=test", new BasicAttributes("ou",
+ "harmony", true));
+ entries.put("module=jndi,cn=test", new BasicAttributes(
+ "javaClassName", String.class.getName()));
+
+ MockLdapSearchResult result = new MockLdapSearchResult();
+
+ result.decodeEntry(entries);
+
+ NamingEnumeration<NameClassPair> enu = result
+ .toNameClassPairEnumeration("cn=test");
+
+ HashMap<String, NameClassPair> values = new HashMap<String, NameClassPair>();
+ while (enu.hasMore()) {
+ NameClassPair pair = enu.next();
+ values.put(pair.getName(), pair);
+ }
+
+ assertEquals(entries.size(), values.size());
+
+ assertTrue(values.containsKey("ou=harmony,o=apache"));
+ NameClassPair pair = values.get("ou=harmony,o=apache");
+ assertEquals("ou=harmony,o=apache", pair.getName());
+ assertEquals(DirContext.class.getName(), pair.getClassName());
+ assertEquals("ou=harmony,o=apache,cn=test", pair.getNameInNamespace());
+
+ assertTrue(values.containsKey("module=jndi"));
+ pair = values.get("module=jndi");
+ assertEquals("module=jndi", pair.getName());
+ assertEquals(String.class.getName(), pair.getClassName());
+ assertEquals("module=jndi,cn=test", pair.getNameInNamespace());
+ }
+
+ public void test_toBindingEnumeration() throws Exception {
+ HashMap<String, Attributes> entries = new HashMap<String, Attributes>();
+ entries.put("ou=harmony,o=apache,cn=test", new BasicAttributes("ou",
+ "harmony", true));
+ entries.put("module=jndi,o=apache,cn=test", new BasicAttributes(
+ "javaClassName", String.class.getName()));
+
+ MockLdapSearchResult result = new MockLdapSearchResult();
+
+ result.decodeEntry(entries);
+
+ NamingEnumeration<Binding> enu = result.toBindingEnumeration(
+ new LdapContextImpl(new MockLdapClient(),
+ new Hashtable<Object, Object>(), "cn=test"),
+ new LdapName("o=apache"));
+
+ HashMap<String, Binding> values = new HashMap<String, Binding>();
+ while (enu.hasMore()) {
+ Binding binding = enu.next();
+ values.put(binding.getName(), binding);
+ }
+
+ assertEquals(entries.size(), values.size());
+
+ assertTrue(values.containsKey("ou=harmony"));
+ Binding binding = values.get("ou=harmony");
+ assertEquals("ou=harmony", binding.getName());
+ assertEquals(DirContext.class.getName(), binding.getClassName());
+ assertEquals("ou=harmony,o=apache,cn=test", binding
+ .getNameInNamespace());
+ assertEquals(LdapContextImpl.class, binding.getObject().getClass());
+
+ assertTrue(values.containsKey("module=jndi"));
+ binding = values.get("module=jndi");
+ assertEquals("module=jndi", binding.getName());
+ assertEquals(String.class.getName(), binding.getClassName());
+ assertEquals("module=jndi,o=apache,cn=test", binding
+ .getNameInNamespace());
+ }
+
+ public void test_toSearchResultEnumeration() throws Exception {
+ HashMap<String, Attributes> entries = new HashMap<String, Attributes>();
+ entries.put("ou=harmony,o=apache,cn=test", new BasicAttributes("ou",
+ "harmony", true));
+ entries.put("module=jndi,o=apache,cn=test", new BasicAttributes(
+ "javaClassName", String.class.getName()));
+
+ MockLdapSearchResult result = new MockLdapSearchResult();
+
+ result.decodeEntry(entries);
+
+ NamingEnumeration<SearchResult> enu = result
+ .toSearchResultEnumeration("cn=test");
+
+ HashMap<String, SearchResult> values = new HashMap<String, SearchResult>();
+ while (enu.hasMore()) {
+ SearchResult searchResult = enu.next();
+ values.put(searchResult.getName(), searchResult);
+ }
+
+ assertEquals(entries.size(), values.size());
+
+ assertTrue(values.containsKey("ou=harmony,o=apache"));
+ SearchResult searchResult = values.get("ou=harmony,o=apache");
+ assertEquals("ou=harmony,o=apache", searchResult.getName());
+ assertNull(searchResult.getClassName());
+ assertEquals("ou=harmony,o=apache,cn=test", searchResult
+ .getNameInNamespace());
+ assertNull(searchResult.getObject());
+
+ Attributes attrs = searchResult.getAttributes();
+ assertEquals(1, attrs.size());
+ assertEquals(1, attrs.get("ou").size());
+ assertEquals("harmony", attrs.get("ou").get());
+
+ assertTrue(values.containsKey("module=jndi,o=apache"));
+ searchResult = values.get("module=jndi,o=apache");
+ assertEquals("module=jndi,o=apache", searchResult.getName());
+ assertNull(searchResult.getClassName());
+ assertEquals("module=jndi,o=apache,cn=test", searchResult
+ .getNameInNamespace());
+ assertNull(searchResult.getObject());
+
+ attrs = searchResult.getAttributes();
+ assertEquals(1, attrs.size());
+ assertEquals(1, attrs.get("javaClassName").size());
+ assertEquals(String.class.getName(), attrs.get("javaClassName").get());
+ }
+
+ public static class MockLdapSearchResult extends LdapSearchResult {
+ public void decodeEntry(Object value) {
+ entries = (HashMap<String, Attributes>) ((HashMap<String, Attributes>) value)
+ .clone();
+ }
+ }
+}
Propchange: harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/ldap/LdapSearchResultTest.java
------------------------------------------------------------------------------
svn:eol-style = native