/* * 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.message; import com.slamd.asn1.ASN1Element; import com.slamd.asn1.ASN1Exception; import com.slamd.asn1.ASN1Integer; import com.slamd.asn1.ASN1OctetString; import com.slamd.asn1.ASN1Sequence; import com.slamd.common.Constants; import com.slamd.common.SLAMDException; /** * This class defines a class transfer response message that the SLAMD server * uses to send Java class files to clients that do not have them. The class * will be saved locally on the client system so that it is will not be * necessary to request it again. * * * @author Neil A. Wilson */ public class ClassTransferResponseMessage extends Message { // The byte array containing the encoded class data. private final byte[] classData; // The response code that indicates whether the class information has been // provided. private final int responseCode; // The name of the Java class specified in this message. private final String className; /** * Creates a new class transfer response message with the specified * information. * * @param messageID The message ID for this message. * @param responseCode The response code that indicates whether the class * information has been provided. * @param className The name of the class file associated with this class * transfer response message. * @param classData The encoded class data. */ public ClassTransferResponseMessage(int messageID, int responseCode, String className, byte[] classData) { super(messageID, ASN1_TYPE_CLASS_TRANSFER_RESPONSE); this.responseCode = responseCode; this.className = className; this.classData = classData; } /** * Retrieves the response code associated with this message. The value will * be that of one of the MESSAGE_RESPONSE_* constants. * * @return The response code associated with this response message. */ public int getResponseCode() { return responseCode; } /** * Retrieves the Java class name associated with this class transfer response * message. * * @return The Java class name associated with this class transfer response * message. */ public String getClassName() { return className; } /** * Retrieves the encoded class data associated with this class transfer * response. * * @return The encoded class data associated with this class transfer * response. */ public byte[] getClassData() { return classData; } /** * Retrieves a string representation of this message. * * @return A string representation of this message. */ @Override() public String toString() { String eol = System.getProperty("line.separator"); return "Class Request Message" + eol + " Message ID: " + messageID + eol + " Response Code: " + responseCode + eol + " Class Name: " + className + eol + " Class Data: " + classData.length + " bytes" + eol; } /** * Decodes the provided ASN.1 element as a class transfer request message. * * @param messageID The message ID to use for this message. * @param element The ASN.1 element containing the encoded class name. * * @return The class transfer request message decoded from the ASN.1 element. * * @throws SLAMDException If the provided ASN.1 element cannot be decoded * as a class transfer request message. */ public static ClassTransferResponseMessage decodeTransferResponse(int messageID, ASN1Element element) throws SLAMDException { // Decode the element as a sequence and get the elements from it. ASN1Element[] elements = null; try { elements = element.decodeAsSequence().getElements(); } catch (ASN1Exception ae) { throw new SLAMDException("Unable to decode the transfer response " + "sequence.", ae); } // There must be three elements in the response sequence. if ((elements == null) || (elements.length != 3)) { throw new SLAMDException("Inappropriate number of elements for a " + "transfer response sequence."); } // The first element is the response code. int responseCode = Constants.MESSAGE_RESPONSE_LOCAL_ERROR; try { responseCode = elements[0].decodeAsInteger().getIntValue(); } catch (ASN1Exception ae) { throw new SLAMDException("The response code element cannot be decoded " + "as an integer.", ae); } // The second element is the class name. String className = null; try { ASN1OctetString nameString = elements[1].decodeAsOctetString(); className = nameString.getStringValue(); } catch (ASN1Exception ae) { throw new SLAMDException("The class name element cannot be decoded as " + "an octet string", ae); } // The third element is the class data. byte[] classData = null; try { classData = elements[2].decodeAsOctetString().getValue(); } catch (ASN1Exception ae) { throw new SLAMDException("The class data element cannot be decoded as " + "an octet string", ae); } return new ClassTransferResponseMessage(messageID, responseCode, className, classData); } /** * Encodes this message into an ASN.1 element. A file transfer response * message has the following ASN.1 syntax: * <BR><BR> * <CODE>ClassTransferResponse ::= [APPLICATION 13] SEQUENCE {</CODE> * <CODE> responseCode INTEGER,</CODE> * <CODE> className OCTET STRING,</CODE> * <CODE> classData OCTET STRING }</CODE> * <BR> * * @return An ASN.1 encoded representation of this message. */ @Override() public ASN1Element encode() { ASN1Element[] responseElements = new ASN1Element[] { new ASN1Integer(responseCode), new ASN1OctetString(className), new ASN1OctetString(classData) }; ASN1Element[] messageElements = new ASN1Element[] { new ASN1Integer(messageID), new ASN1Sequence(ASN1_TYPE_CLASS_TRANSFER_RESPONSE, responseElements) }; return new ASN1Sequence(messageElements); } }