/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (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.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ package netscape.ldap; import java.util.*; import netscape.ldap.client.opers.*; import netscape.ldap.ber.stream.*; import java.io.*; import java.net.*; /** * Base class for LDAP request and response messages. * This class represents the LDAPMessage in RFC2251. The * message is the entity that got transferred back and * fro between the server and the client interface. Each * message has a protocol operation. The protocol operation * indicates if it is a request or response. *
* LDAPMessage ::= SEQUENCE {
* messageID MessageID,
* protocolOp CHOICE {
* bindRequest BindRequest,
* ...
* }
* controls [0] Controls OPTIONAL
* }
*
*
* @version 1.0
*/
public class LDAPMessage implements java.io.Serializable {
static final long serialVersionUID = -1364094245850026720L;
public final static int BIND_REQUEST = 0;
public final static int BIND_RESPONSE = 1;
public final static int UNBIND_REQUEST = 2;
public final static int SEARCH_REQUEST = 3;
public final static int SEARCH_RESPONSE = 4;
public final static int SEARCH_RESULT = 5;
public final static int MODIFY_REQUEST = 6;
public final static int MODIFY_RESPONSE = 7;
public final static int ADD_REQUEST = 8;
public final static int ADD_RESPONSE = 9;
public final static int DEL_REQUEST = 10;
public final static int DEL_RESPONSE = 11;
public final static int MODIFY_RDN_REQUEST = 12;
public final static int MODIFY_RDN_RESPONSE = 13;
public final static int COMPARE_REQUEST = 14;
public final static int COMPARE_RESPONSE = 15;
public final static int ABANDON_REQUEST = 16;
public final static int SEARCH_RESULT_REFERENCE = 19;
public final static int EXTENDED_REQUEST = 23;
public final static int EXTENDED_RESPONSE = 24;
/**
* Internal variables
*/
private int m_msgid;
private JDAPProtocolOp m_protocolOp = null;
private LDAPControl m_controls[] = null;
/**
* Constructs a ldap message.
* @param msgid message identifier
* @param op operation protocol
*/
LDAPMessage(int msgid, JDAPProtocolOp op) {
m_msgid = msgid;
m_protocolOp = op;
}
LDAPMessage(int msgid, JDAPProtocolOp op, LDAPControl controls[]) {
m_msgid = msgid;
m_protocolOp = op;
m_controls = controls; /* LDAPv3 additions */
}
/**
* Creates a ldap message from a BERElement. This method is used
* to parse LDAP response messages
*
* @param element ber element constructed from incoming byte stream
*/
static LDAPMessage parseMessage(BERElement element) throws IOException {
int l_msgid;
JDAPProtocolOp l_protocolOp = null;
LDAPControl l_controls[] = null;
if (element.getType() != BERElement.SEQUENCE)
throw new IOException("SEQUENCE in jdap message expected");
BERSequence seq = (BERSequence)element;
BERInteger msgid = (BERInteger)seq.elementAt(0);
l_msgid = msgid.getValue();
BERElement protocolOp = (BERElement)seq.elementAt(1);
if (protocolOp.getType() != BERElement.TAG) {
throw new IOException("TAG in protocol operation is expected");
}
BERTag tag = (BERTag)protocolOp;
switch (tag.getTag()&0x1f) {
case JDAPProtocolOp.BIND_RESPONSE:
l_protocolOp = new JDAPBindResponse(protocolOp);
break;
case JDAPProtocolOp.SEARCH_RESPONSE:
l_protocolOp = new JDAPSearchResponse(protocolOp);
break;
/*
* If doing search without bind,
* x500.arc.nasa.gov returns tag SEARCH_REQUEST tag
* in SEARCH_RESULT.
*/
case JDAPProtocolOp.SEARCH_REQUEST:
case JDAPProtocolOp.SEARCH_RESULT:
l_protocolOp = new JDAPSearchResult(protocolOp);
break;
case JDAPProtocolOp.MODIFY_RESPONSE:
l_protocolOp = new JDAPModifyResponse(protocolOp);
break;
case JDAPProtocolOp.ADD_RESPONSE:
l_protocolOp = new JDAPAddResponse(protocolOp);
break;
case JDAPProtocolOp.DEL_RESPONSE:
l_protocolOp = new JDAPDeleteResponse(protocolOp);
break;
case JDAPProtocolOp.MODIFY_RDN_RESPONSE:
l_protocolOp = new JDAPModifyRDNResponse(protocolOp);
break;
case JDAPProtocolOp.COMPARE_RESPONSE:
l_protocolOp = new JDAPCompareResponse(protocolOp);
break;
case JDAPProtocolOp.SEARCH_RESULT_REFERENCE:
l_protocolOp = new JDAPSearchResultReference(protocolOp);
break;
case JDAPProtocolOp.EXTENDED_RESPONSE:
l_protocolOp = new JDAPExtendedResponse(protocolOp);
break;
default:
throw new IOException("Unknown protocol operation");
}
/* parse control */
if (seq.size() >= 3) {
tag = (BERTag)seq.elementAt(2);
if ( tag.getTag() == (BERTag.CONSTRUCTED|BERTag.CONTEXT|0) ) {
BERSequence controls = (BERSequence)tag.getValue();
l_controls = new LDAPControl[controls.size()];
for (int i = 0; i < controls.size(); i++) {
l_controls[i] = LDAPControl.parseControl(controls.elementAt(i));
}
}
}
if (l_protocolOp instanceof JDAPSearchResponse) {
return new LDAPSearchResult(l_msgid,
(JDAPSearchResponse) l_protocolOp, l_controls);
}
else if (l_protocolOp instanceof JDAPSearchResultReference) {
return new LDAPSearchResultReference(l_msgid,
(JDAPSearchResultReference) l_protocolOp, l_controls);
}
else if (l_protocolOp instanceof JDAPExtendedResponse) {
return new LDAPExtendedResponse(l_msgid,
(JDAPExtendedResponse) l_protocolOp, l_controls);
}
else {
return new LDAPResponse(l_msgid, l_protocolOp, l_controls);
}
}
/**
* Returns the message identifer.
* @return message identifer.
*/
public int getMessageID(){
return m_msgid;
}
/**
* Returns the LDAP operation type of the message
* @return message type.
*/
public int getType(){
return m_protocolOp.getType();
}
/**
* Retrieves the protocol operation.
* @return protocol operation.
*/
JDAPProtocolOp getProtocolOp() {
return m_protocolOp;
}
/**
* Retrieves list of controls.
* @return controls.
*/
public LDAPControl[] getControls() {
return m_controls;
}
/**
* Writes the ber encoding to stream.
* @param s output stream
*/
void write(OutputStream s) throws IOException {
BERSequence seq = new BERSequence();
BERInteger i = new BERInteger(m_msgid);
seq.addElement(i);
BERElement e = m_protocolOp.getBERElement();
if (e == null) {
throw new IOException("Bad BER element");
}
seq.addElement(e);
if (m_controls != null) { /* LDAPv3 additions */
BERSequence c = new BERSequence();
for (int j = 0; j < m_controls.length; j++) {
c.addElement(m_controls[j].getBERElement());
}
BERTag t = new BERTag(BERTag.CONTEXT|BERTag.CONSTRUCTED|0, c, true);
seq.addElement(t);
}
seq.write(s);
}
/**
* Returns string representation of an LDAP message.
* @return LDAP message.
*/
public String toString() {
StringBuffer sb = new StringBuffer("[LDAPMessage] ");
sb.append(m_msgid);
sb.append(" ");
sb.append(m_protocolOp.toString());
for (int i =0; m_controls != null && i < m_controls.length; i++) {
sb.append(" ");
sb.append(m_controls[i].toString());
}
return sb.toString();
}
/**
* Returns string representation of a ldap message with
* the time stamp. Used for message trace
* @return ldap message with the time stamp
*/
StringBuffer toTraceString() {
StringBuffer sb = new StringBuffer(" op=");
sb.append(m_msgid);
sb.append(" ");
sb.append(m_protocolOp.toString());
for (int i =0; m_controls != null && i < m_controls.length; i++) {
sb.append(" ");
sb.append(m_controls[i].toString());
}
return sb;
}
}