FileDocCategorySizeDatePackage
EventSequence.javaAPI DocJ2ME MIDP 2.08103Thu Nov 07 12:02:22 GMT 2002com.sun.midp.lcdui

EventSequence.java

/*
 * @(#)EventSequence.java	1.20 02/07/24 @(#)
 *
 * Copyright (c) 2001-2002 Sun Microsystems, Inc.  All rights reserved.
 * PROPRIETARY/CONFIDENTIAL
 * Use is subject to license terms.
 */

package com.sun.midp.lcdui;

import java.io.*;
import java.util.Vector;

/**
 * <code>EventSequence</code> is a class that encapsulates the semantics
 * of a single MIDP event.
 *
 * This class is designed to automate UI testing. It is the representation
 * of a sequence of events and the corresponding screen capture taken at
 * the end of those events.
 */

public class EventSequence {

    private byte[] capture;

    /**
     * An input stream of bytes represents events
     * that have been recorded previously and that are
     * passed to this EventSequence
     */
    private ByteArrayInputStream  inputStream;

    /**
     * The byte array associated with the event sequence.
     */
    private byte[] byteArray;

    /**
     * The output stream represents events that are 
     * to be recorded in this EventSequence
     */
    private ByteArrayOutputStream outputStream;


    EventSequence() {

	// set up the empty input stream and byte array
	byteArray = new byte[0];
	inputStream = new ByteArrayInputStream(byteArray);

	outputStream = new ByteArrayOutputStream();
    }

    void appendEvent(RecordedEvent event) {

	try {

	    outputStream.write(EVENT_START_MARKER);
	    outputStream.write(event.lengthOfByteRep());
	    outputStream.write(event.getAsByte());

	} catch (java.io.IOException e) {
	    System.out.println("EXCEPTION!");
	    // EXCEPTION!
	}

    }

    void setScreenCapture(byte[] capture) {

        this.capture = capture;

	    outputStream.write(CAPTURE_START_MARKER);
	    outputStream.write(capture.length);

	for (int byteCounter = 0; byteCounter < capture.length; 
	    byteCounter++) {
		outputStream.write(capture[byteCounter]);

	}

    }

    /**
     * Recreate a stored event sequence and its associated screen
     * capture from the given input stream.
     *
     * @param input The byte[] which was obtained from a previous
     *              EventSequence from its getEventSequence() method.
     */
    public EventSequence(byte[] input) {
	byteArray = input;
	inputStream = new ByteArrayInputStream(byteArray);
	
	outputStream = new ByteArrayOutputStream();
    }
    
    /**
     * Create a new EventSequence Object based on a set of other
     * EventSequences. This will create a composite EventSequence
     * object which will be treated as a single sequence by the
     * AutomatedHandler when testing. That is, a call to
     * replayEventSequence() with a composite EventSequence Object
     * will test each sub sequence and its screen capture. If any
     * sub sequence fails, it will return false. If all of the sub
     * sequences pass, it will return true.
     *
     * @param sequences An array of EventSequence objects to construct
     *                  a new composite EventSequence from
     */
    public EventSequence(EventSequence[] sequences) {
	try {
	    for (int i = 0; i < sequences.length; i++) {
		this.outputStream.write(sequences[i].toByteArray());
	    }
	} catch (IOException e) {
	    // System.out.println("Exception in writing to stream");
	}
    }
    
    /**
     * Create a new EventSequence Object based on a set of other
     * EventSequences. This will create a composite EventSequence
     * object which will be treated as a single sequence by the
     * AutomatedHandler when testing. That is, a call to
     * replayEventSequence() with a composite EventSequence Object
     * will test each sub sequence and its screen capture. If any
     * sub sequence fails, it will return false. If all of the sub
     * sequences pass, it will return true.
     *
     * @param sequences A Vector of EventSequence objects to construct
     *                  a new composite EventSequence from
     */
    public EventSequence(Vector sequences) {
	
	int length = sequences.size();
	EventSequence q;
	
	try {
	    for (int i = 0; i < length; i++) {
		q = (EventSequence)sequences.elementAt(i);
		this.outputStream.write(q.toByteArray());
	    }
	} catch (IOException e) {
	    // System.out.println("Exception in writing to stream");
	}
    }
    
    /**
     * Store this EventSequence and its corresponding screen
     * capture to the designated output stream.
     *
     * @return The contents of this event sequence as an array
     *         of bytes. This array of bytes can be passed to
     *         the constructor to re-create the event sequence.
     */
    public byte[] toByteArray() {
	// the entire eventSequence consists of the original input sequence
	// null if there was no original input sequence
	// plus the events that were appended
	
	// therefore when we are returning the byte representation,
	// we actually do three things.
	// 1. append any existing bytes in the output array to the input array.
	// 2. reset the output array
	// 3. return the bytearray
	
	byte[] tempByteArray = new byte[byteArray.length + 
					outputStream.toByteArray().length];
	
	// Copy existing bytes in the byteArray to tempByteArray
	System.arraycopy(byteArray,
			 0,
			 tempByteArray,
			 0,
			 byteArray.length);
	
	// Append bytes from the output streams' byte array
	// to tempByteArray
	// byteArray.length is the offset to start from in the dst
	System.arraycopy(outputStream.toByteArray(),
			 0,
			 tempByteArray,
			 byteArray.length,
			 outputStream.toByteArray().length);
	
	// now tempByteArray holds all the bytes!
	// make it the byteArray!
	byteArray = tempByteArray;
	
	// reset the output stream
	outputStream.reset();
	
	return byteArray;
    }
    
    /**
     * Append the given EventSequence to this sequence and create
     * a composite event sequence as a result.
     *
     * @param sequence The EventSequence to append to the end of
     *                 this sequence.
     */
    public void appendSequence(EventSequence sequence) {
	try {
	    this.outputStream.write(sequence.toByteArray());
	} catch (IOException e) {
	    // System.out.println("Exception in writing to stream");
	}
    }


    // --- Retrieve Individual Events and Screen Captures ---

    void initializeReplay() {
	
	byte[] tempByteArray = new byte[byteArray.length + 
					outputStream.toByteArray().length];

         // Copy existing bytes in the byteArray to tempByteArray
	 System.arraycopy(byteArray,
			  0,
			  tempByteArray,
			  0,
			  byteArray.length);

	 // Append bytes from the output streams' byte array
	 // to tempByteArray
	 // byteArray.length is the offset to start from in the dst
	 System.arraycopy(outputStream.toByteArray(),
			  0,
			  tempByteArray,
			  byteArray.length,
			  outputStream.toByteArray().length);

	 // now tempByteArray holds all the bytes!
	 // make it the byteArray!
	 byteArray = tempByteArray;

	 // reset the output stream
	 outputStream.reset();
	 
	 inputStream = new ByteArrayInputStream(byteArray);
	 // input stream now points at 0 index in the byteArray
    }

    int getNextObjectType() {
	
	return (inputStream.read());
	// returns -1 if end of input stream is reached.
	
    }

    RecordedEvent getNextEvent() {
	
	RecordedEvent event = null;
	
	int length = inputStream.read();

	if (length == 0xFF) {
	    // if the length byte's value is 0xFF,
	    // then the length is greater than 127 and
	    // needs to be read as an int.

	    // using this as most events' length will
	    // be small engouh, that a byte is sufficient 
	    // to represent it.
	    
	}

	byte[] eventByteArray = new byte[length];

	inputStream.read(eventByteArray, 0, length);

	event = RecordedEvent.recreateRecordedEvent(eventByteArray, 
						    0, length);

	return event;
    }

    byte[] getCapture() {

	int length = inputStream.read();
	
	byte[] captureByteArray = new byte[length];

	inputStream.read(captureByteArray, 0, length);

	return captureByteArray;
	 
    }

    // encoding
    static final int EVENT_START_MARKER   =  0;
    static final int CAPTURE_START_MARKER =  1;
    static final int END_OF_EVENT_SEQUENCE = -1;
}