escaping problem with custom partition search results
-----------------------------------------------------
Key: DIRSERVER-374
URL: http://issues.apache.org/jira/browse/DIRSERVER-374
Project: Directory ApacheDS
Type: Bug
Components: core
Environment: winxp,jdk 1.4.2
Reporter: Norbert Reilly
Assignee: Alex Karasulu
Attachments: DummyProxyPartition.java, apacheds-dummy-partition.xml
I have observed a strange problem in implementing a custom
partition that proxies to another remote LDAP server: the results
of search() operations have blanks replaced with "%20" so that
JXplorer is unable to explore them. The temporary solution I have
in place is to wrap the original search results returned by the
remote server using the following class:
============================
/**
* ApacheDS seems to have a bug where SearchResult s with
relative DNs
* have URL encoding applied twice, so blanks come out as %20.
*/
public static final class AvoidEscapingNamingEnumeration
implements NamingEnumeration
{
private final String baseDN;
private final NamingEnumeration ne;
public AvoidEscapingNamingEnumeration(final String baseDN,
final NamingEnumeration ne)
{
this.baseDN = baseDN;
this.ne = ne;
}
public void close() throws NamingException
{
ne.close();
}
public boolean hasMore() throws NamingException
{
return ne.hasMore();
}
public Object next() throws NamingException
{
final SearchResult sr = (SearchResult)ne.next();
final String fullDN;
final SearchResult sr2;
final String name = sr.getName();
if (!sr.isRelative() || (name == null) || "".equals
(name))
return sr;
fullDN = name + "," + baseDN;
sr.setName(fullDN);
sr.setRelative(false);
return sr;
}
public boolean hasMoreElements()
{
try
{
return hasMore();
}
catch (NamingException e)
{
log.error(this.getClass().getName()
+ ": error in hasMoreElements", e);
return false;
}
}
public Object nextElement()
{
try
{
return next();
}
catch (NamingException e)
{
log.error(this.getClass().getName()
+ ": error in nextElement", e);
return null;
}
}
}
==========================
where the search method itself looks like this:
==========================
public NamingEnumeration search(Name base, final Map env,
final ExprNode filter, final SearchControls
searchControls)
throws NamingException
{
final String deref = (String)env.get
("java.naming.ldap.derefAliases");
final int scope = searchControls.getSearchScope();
String attrIds[] =
searchControls.getReturningAttributes();
final String newFilter;
final StringBuffer sb;
final String baseDn;
final String[] attrNames;
final String last;
if (attrIds == null)
attrIds = BLANK_ATTRS;
sb = new StringBuffer();
filter.printToBuffer(sb);
newFilter = sb.toString();
baseDn = base.toString();
last = base.get(0);
if (! "dc=etadb".equals(last))
{
// don't want to change name seen by outside world
base = (Name)base.clone();
base.add("dc=etadb");
}
attrNames = normaliseAttrNames(attrIds);
final SearchControls sc = new SearchControls();
sc.setSearchScope(scope);
sc.setReturningAttributes(attrNames);
sc.setDerefLinkFlag(Boolean.valueOf(deref).booleanValue
());
final NamingEnumeration ne = _ctx.search(base, newFilter,
sc);
return new AvoidEscapingNamingEnumeration(baseDn, ne);
}
==========================
so it seems whatever is doing the escaping leaves results with
full DNs alone (note that just setting sr.setRelative(false) has
no effect by itself). I'm not familiar enough with the DS
architecture yet to work out where the escaping is occurring and
hence come up with a better fix.