DSMLSearchOperation.java revision 480256311ff1597d92043303772f072d8d67fb3c
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at
* trunk/opends/resource/legal-notices/OpenDS.LICENSE
* or https://OpenDS.dev.java.net/OpenDS.LICENSE.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at
* trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
* add the following below this CDDL HEADER, with the fields enclosed
* by brackets "[]" replaced with your own identifying information:
* Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
*
* Portions Copyright 2006-2007 Sun Microsystems, Inc.
*/
package org.opends.dsml.protocol;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import org.opends.server.protocols.asn1.ASN1Element;
import org.opends.server.protocols.asn1.ASN1Exception;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.protocols.asn1.ASN1Sequence;
import org.opends.server.protocols.ldap.LDAPAttribute;
import org.opends.server.protocols.ldap.LDAPConstants;
import org.opends.server.protocols.ldap.LDAPFilter;
import org.opends.server.protocols.ldap.LDAPMessage;
import org.opends.server.protocols.ldap.ProtocolOp;
import org.opends.server.protocols.ldap.SearchRequestProtocolOp;
import org.opends.server.protocols.ldap.SearchResultEntryProtocolOp;
import org.opends.server.protocols.ldap.SearchResultReferenceProtocolOp;
import org.opends.server.protocols.ldap.SearchResultDoneProtocolOp;
import org.opends.server.tools.LDAPConnection;
import org.opends.server.types.DereferencePolicy;
import org.opends.server.types.LDAPException;
import org.opends.server.types.SearchScope;
/**
* This class provides the functionality for the performing an
* LDAP SEARCH operation based on the specified DSML request.
*/
public class DSMLSearchOperation
{
private LDAPConnection connection;
/**
* Create the instance with the specified connection.
*
* @param connection The LDAP connection to send the request on.
*/
public DSMLSearchOperation(LDAPConnection connection)
{
this.connection = connection;
}
/**
* Perform the LDAP SEARCH operation and send the result back to the
* client.
*
* @param objFactory The object factory for this operation.
* @param searchRequest The search request for this operation.
*
* @return The result of the add operation.
*
* @throws IOException If an I/O problem occurs.
*
* @throws LDAPException If an error occurs while interacting with an LDAP
* element.
*/
public SearchResponse doSearch(ObjectFactory objFactory,
SearchRequest searchRequest)
throws IOException, LDAPException
{
SearchResponse searchResponse = objFactory.createSearchResponse();
searchResponse.setRequestID(searchRequest.getRequestID());
ArrayList<LDAPFilter> filters = new ArrayList<LDAPFilter> ();
LDAPFilter f = null;
if(searchRequest.getFilter().getPresent() != null)
{
f = LDAPFilter.decode(searchRequest.getFilter().getPresent().getName() +
"=*");
} else if(searchRequest.getFilter().getEqualityMatch() != null)
{
AttributeValueAssertion fgem =
searchRequest.getFilter().getEqualityMatch();
f = LDAPFilter.createEqualityFilter(fgem.getName(),
new ASN1OctetString(fgem.getValue()));
}
if(f != null)
{
filters.add(f);
}
DereferencePolicy derefPolicy = DereferencePolicy.NEVER_DEREF_ALIASES;
String derefStr = searchRequest.getDerefAliases().toLowerCase();
if (derefStr.equals("derefinsearching"))
{
derefPolicy = DereferencePolicy.DEREF_IN_SEARCHING;
}
else if (derefStr.equals("dereffindingbaseobj"))
{
derefPolicy = DereferencePolicy.DEREF_FINDING_BASE_OBJECT;
}
else if (derefStr.equals("derefalways"))
{
derefPolicy = DereferencePolicy.DEREF_ALWAYS;
}
SearchScope scope = SearchScope.WHOLE_SUBTREE;
String scopeStr = searchRequest.getScope().toLowerCase();
if(scopeStr.equals("singlelevel") || scopeStr.equals("one"))
{
scope = SearchScope.SINGLE_LEVEL;
} else if(scopeStr.equals("baseobject") || scopeStr.equals("base"))
{
scope = SearchScope.BASE_OBJECT;
}
LinkedHashSet<String> attributes = new LinkedHashSet<String>();
// Get the list of attributes.
AttributeDescriptions attrDescriptions = searchRequest.getAttributes();
if(attrDescriptions != null)
{
List<AttributeDescription> attrDesc = attrDescriptions.getAttribute();
for(AttributeDescription desc : attrDesc)
{
attributes.add(desc.getName());
}
}
for (LDAPFilter filter: filters)
{
SearchRequestProtocolOp protocolOp = new SearchRequestProtocolOp(
new ASN1OctetString(searchRequest.getDn()),
scope, derefPolicy,
(int) searchRequest.getSizeLimit(),
(int) searchRequest.getTimeLimit(),
false, filter, attributes);
try
{
LDAPMessage msg = new LDAPMessage(DSMLServlet.nextMessageID(),
protocolOp);
connection.getLDAPWriter().writeMessage(msg);
byte opType;
do
{
int resultCode = 0;
String errorMessage = null;
LDAPMessage responseMessage =
connection.getLDAPReader().readMessage();
opType = responseMessage.getProtocolOpType();
switch(opType)
{
case LDAPConstants.OP_TYPE_SEARCH_RESULT_ENTRY:
SearchResultEntryProtocolOp searchEntryOp =
responseMessage.getSearchResultEntryProtocolOp();
SearchResultEntry entry = objFactory.createSearchResultEntry();
java.util.List<DsmlAttr> attrList = entry.getAttr();
LinkedList<LDAPAttribute> attrs = searchEntryOp.getAttributes();
for(LDAPAttribute attr : attrs)
{
String nm = attr.getAttributeType();
DsmlAttr dsmlAttr = objFactory.createDsmlAttr();
dsmlAttr.setName(nm);
List<String> dsmlAttrVal = dsmlAttr.getValue();
ArrayList<ASN1OctetString> vals = attr.getValues();
for(ASN1OctetString val : vals)
{
dsmlAttrVal.add(val.toString());
}
attrList.add(dsmlAttr);
}
entry.setDn(searchEntryOp.getDN().toString());
searchResponse.getSearchResultEntry().add(entry);
/*
StringBuilder sb = new StringBuilder();
searchEntryOp.toLDIF(sb, 80);
System.out.println(sb.toString());
*/
break;
case LDAPConstants.OP_TYPE_SEARCH_RESULT_REFERENCE:
SearchResultReferenceProtocolOp searchRefOp =
responseMessage.getSearchResultReferenceProtocolOp();
System.out.println(searchRefOp.toString());
break;
case LDAPConstants.OP_TYPE_SEARCH_RESULT_DONE:
SearchResultDoneProtocolOp searchOp =
responseMessage.getSearchResultDoneProtocolOp();
resultCode = searchOp.getResultCode();
errorMessage = searchOp.getErrorMessage();
LDAPResult result = objFactory.createLDAPResult();
ResultCode code = objFactory.createResultCode();
code.setCode(resultCode);
result.setResultCode(code);
result.setErrorMessage(errorMessage);
if(searchOp.getMatchedDN() != null)
{
result.setMatchedDN(searchOp.getMatchedDN().toString());
}
searchResponse.setSearchResultDone(result);
break;
default:
// FIXME - throw exception
System.err.println("Invalid protocol operation:" + opType);
break;
}
if(resultCode != 0 && resultCode != 10)
{
org.opends.server.types.ResultCode rc =
org.opends.server.types.ResultCode.valueOf(resultCode);
// FIXME.
int msgID = 0;
throw new LDAPException(resultCode, msgID, rc.toString());
}
} while(opType != LDAPConstants.OP_TYPE_SEARCH_RESULT_DONE);
} catch(ASN1Exception ae)
{
ae.printStackTrace();
throw new IOException(ae.getMessage());
}
}
return searchResponse;
}
}