/* * Sun Public License * * The contents of this file are subject to the Sun Public License Version * 1.0 (the "License"). You may not use this file except in compliance with * the License. A copy of the License is available at http://www.sun.com/ * * The Original Code is the SLAMD Distributed Load Generation Engine. * The Initial Developer of the Original Code is Neil A. Wilson. * Portions created by Neil A. Wilson are Copyright (C) 2004-2010. * Some preexisting portions Copyright (C) 2002-2006 Sun Microsystems, Inc. * All Rights Reserved. * * Contributor(s): Neil A. Wilson */ package com.slamd.tools.ldapdecoder.protocol; import java.io.PrintStream; import java.util.ArrayList; import java.util.Date; import com.slamd.asn1.ASN1Element; import com.slamd.asn1.ASN1OctetString; import com.slamd.asn1.ASN1Sequence; /** * This class defines an LDAP extended response, which provides information * about the result of processing an intermediate response. * * * @author Neil A. Wilson */ public class IntermediateResponse extends ProtocolOp { /** * The ASN.1 type that should be used to encode a response OID. */ public static final byte RESPONSE_OID_TYPE = (byte) 0x80; /** * The ASN.1 type that should be used to encode a response value. */ public static final byte RESPONSE_VALUE_TYPE = (byte) 0x81; // The value for the extended response. private ASN1OctetString responseValue; // The OID for the extended response. private String responseOID; /** * Creates a new intermediate response with the provided information. * * @param responseOID The OID for this intermediate response. * @param responseValue The value for this intermediate response. */ public IntermediateResponse(String responseOID, ASN1OctetString responseValue) { this.responseOID = responseOID; this.responseValue = responseValue; } /** * Retrieves the OID for this extended response. * * @return The OID for this extended response. */ public String getReponseOID() { return responseOID; } /** * Retrieves the value for this extended response. * * @return The value for this extended response. */ public ASN1OctetString getResponseValue() { return responseValue; } /** * Encodes this protocol op to an ASN.1 element. * * @return The ASN.1 element containing the encoded protocol op. */ public ASN1Element encode() { ArrayList<ASN1Element> elementList = new ArrayList<ASN1Element>(); if (responseOID != null) { elementList.add(new ASN1OctetString(RESPONSE_OID_TYPE, responseOID)); } if (responseValue != null) { elementList.add(new ASN1OctetString(RESPONSE_VALUE_TYPE, responseValue.getValue())); } ASN1Element[] responseElements = new ASN1Element[elementList.size()]; elementList.toArray(responseElements); return new ASN1Sequence(EXTENDED_RESPONSE_TYPE, responseElements); } /** * Decodes the provided ASN.1 element as an extended response protocol op. * * @param element The ASN.1 element to be decoded. * * @return The decoded extended response. * * @throws ProtocolException If a problem occurs while decoding the provided * ASN.1 element as an extended response. */ public static IntermediateResponse decodeIntermediateResponse( ASN1Element element) throws ProtocolException { ASN1Element[] responseElements; try { responseElements = element.decodeAsSequence().getElements(); } catch (Exception e) { throw new ProtocolException("Unable to decode extended response sequence", e); } if (responseElements.length > 2) { throw new ProtocolException("There must be no more than 2 elements in " + "an intermediate response sequence"); } String responseOID = null; ASN1OctetString responseValue = null; for (ASN1Element e : responseElements) { switch (e.getType()) { case RESPONSE_OID_TYPE: try { responseOID = e.decodeAsOctetString().getStringValue(); } catch (Exception ex) { throw new ProtocolException("Unable to decode the intermediate " + "response OID", ex); } break; case RESPONSE_VALUE_TYPE: try { responseValue = e.decodeAsOctetString(); } catch (Exception ex) { throw new ProtocolException("Unable to decode the intermediate " + "response value", ex); } break; default: throw new ProtocolException("Unknown intermediate response element " + "type " + e.getType()); } } // FIXME: Add specific decoding for special intermediate response types return new IntermediateResponse(responseOID, responseValue); } /** * Retrieves a user-friendly name for this protocol op. * * @return A user-friendly name for this protocol op. */ public String getProtocolOpType() { return "LDAP Intermediate Response"; } /** * Retrieves a string representation of this protocol op with the specified * indent. * * @param indent The number of spaces to indent the output. * * @return A string representation of this protocol op with the specified * indent. */ public String toString(int indent) { StringBuilder indentBuf = new StringBuilder(indent); for (int i=0; i < indent; i++) { indentBuf.append(' '); } StringBuilder buffer = new StringBuilder(); if (responseOID != null) { buffer.append(indentBuf).append("Response OID: ").append(responseOID). append(LDAPMessage.EOL); } if (responseValue!= null) { byte[] valueBytes = responseValue.getValue(); buffer.append(indentBuf).append("Response Value:"). append(LDAPMessage.EOL); buffer.append(LDAPMessage.byteArrayToString(valueBytes, (indent+4))); } return buffer.toString(); } /** * Constructs a string representation of this LDAP message in a form that can * be written to a SLAMD script. It may be empty if this message isn't one * that would be generated as part of a client request. * * @param scriptWriter The print stream to which the script contents should * be written. */ public void toSLAMDScript(PrintStream scriptWriter) { // This is not something that would be generated by a client and therefore // no operation needs to be performed. However, we can write a comment // to the script indicating that an add response was received. scriptWriter.println("#### Intermediate response captured at " + new Date()); if (responseOID != null) { scriptWriter.println("# Response OID: " + responseOID); } scriptWriter.println(); scriptWriter.println(); } }