/*
 *  BasicAspVisitor.java v0.10 20-DEC-1999
 *  Copyright (c) TKK/TLM/Calypso
 *  Author: Alexey Mednonogov
 */

package codec.visit;

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

import codec.*;
import codec.adapt.*;
import codec.convert.*;
import codec.debug.*;
import codec.dyntree.*;
import codec.export.*;
import codec.orb.*;
import codec.pco.*;
import codec.server.*;
import codec.client.*;
import codec.visit.*;
import codec.build.*;

/** Class implementing default Gateway-oriented Visitor behaviour for
 *  introspecting incoming PDU to be relayed further to SUT in the form
 *  of CORBA request/response. */
public class BasicAspVisitor extends com.t3.ot.misc.VisitorImpl {

	// --------------------- DEFAULT INPUT PARAMETERS -------------------
   	/** PDU processed by Visitor. */
   	protected com.t3.ot.pco.ASP asp;

   	/** PCO name through which PDU was sent. */
   	protected String pcoName;

    // ------------ ------- DEFAULT INTERNAL VARIABLES ------------------

   	/** Reference to CORBA ORB. */
   	protected org.omg.CORBA.ORB orb;

	// ---------------------- DEFAULT INTERNAL STATE --------------------

   	/** State of TTCN table analysis. The "tableState" must be initially
     *  set to "TABLE_INACTIVE", then set to "TABLE_ACTIVE" by method
     *  visitTableBegin() which must come as the first visit() method,
     *  then set to "TABLE_COMPLETE" by visitTableEnd() which must come
     *  as the last visit() method. This ensures that PDU contains only
     *  one TTCN table which encapsulates all other PDU data.  */
   	protected int tableState;

   	protected static final int STATE_TABLE_INACTIVE = 0;
    protected static final int STATE_TABLE_ACTIVE   = 1;
    protected static final int STATE_TABLE_COMPLETE = 2;

   	/** Temporarily added state - due to incorrect handling of CHOICE
     *  on Tester side. */
    protected int choiceCount;

	// ----------------------- DEFAULT CONSTRUCTOR ----------------------

	public BasicAspVisitor(String pcoName_, com.t3.ot.pco.ASP asp_) {

		pcoName = pcoName_;
		asp = asp_;

		CodecObject codec = CorbaServer.getCodecObject();
		orb = codec.getOrbGeneric().getORB();

		tableState = STATE_TABLE_INACTIVE;
		choiceCount = 0;
	}

	// ---------------------- DEFAULT POSTPROCESSOR ---------------------
	
    protected void finalizeVisitor() throws com.t3.ot.misc.OtException {

        if (tableState != STATE_TABLE_COMPLETE)
			throw new VisitorInvalidFormat("TTCN table is incomplete.");
	}

	// --------------------- DEFAULT VISITOR METHODS --------------------

   	final public void visitBitStringValue(com.t3.ot.misc.StringValue value)
		throws com.t3.ot.misc.OtException {

		// Fields of this kind shall never be present in PDU:
		throw new VisitorInvalidFormat("BITSTRING values shall " +
			"not be present in PDU.");
	}

    public void visitBooleanValue(com.t3.ot.misc.BooleanValue value)
		throws com.t3.ot.misc.OtException {

		// Fields of this kind shall never be present in PDU:
		throw new VisitorInvalidFormat("BOOLEAN values shall " +
			"not be present in PDU.");
	}

    public void visitCharStringValue(com.t3.ot.misc.StringValue value)
		throws com.t3.ot.misc.OtException {

		// Fields of this kind shall never be present in PDU:
		throw new VisitorInvalidFormat("CharacterString values shall " +
			"not be present in PDU.");
	}

    public void visitChoiceBegin(com.t3.ot.misc.StructValue value)
		throws com.t3.ot.misc.OtException {

		// Fields of this kind shall never be present in PDU:
		throw new VisitorInvalidFormat("CHOICE values shall " +
			"not be present in PDU.");
	}

    public void visitChoiceEnd(com.t3.ot.misc.StructValue value)
		throws com.t3.ot.misc.OtException {

		// Fields of this kind shall never be present in PDU:
		throw new VisitorInvalidFormat("CHOICE values shall " +
			"not be present in PDU.");
	}

    public void visitEnumeratedValue(com.t3.ot.misc.EnumeratedValue value)
		throws com.t3.ot.misc.OtException {

		// Fields of this kind shall never be present in PDU:
		throw new VisitorInvalidFormat("ENUMERATED values shall " +
			"not be present in PDU.");
	}

    final public void visitHexStringValue(com.t3.ot.misc.StringValue value)
		throws com.t3.ot.misc.OtException {

        // Fields of this kind shall never be present in PDU:
		throw new VisitorInvalidFormat("HEXSTRING values shall " +
			"not be present in PDU.");
	}

    public void visitIntegerValue(com.t3.ot.misc.IntegerValue value)
		throws com.t3.ot.misc.OtException {

		// Fields of this kind shall never be present in PDU:
		throw new VisitorInvalidFormat("INTEGER values shall " +
			"not be present in PDU.");
	}

    final public void visitNullValue(com.t3.ot.misc.NullValue value)
		throws com.t3.ot.misc.OtException {

        // Fields of this kind shall never be present in PDU:
		throw new VisitorInvalidFormat("NULL values " +
			"shall not be present in PDU.");
	}

    final public void visitObjectIdentifierBegin(
		com.t3.ot.misc.StructValue value)
		throws com.t3.ot.misc.OtException {

        // Fields of this kind shall never be present in PDU:
		throw new VisitorInvalidFormat("OBJECT IDENTIFIER values " +
			"shall not be present in PDU.");
	}

    final public void visitObjectIdentifierEnd(
		com.t3.ot.misc.StructValue value)
		throws com.t3.ot.misc.OtException {

        // Fields of this kind shall never be present in Call PDU:
		throw new VisitorInvalidFormat("OBJECT IDENTIFIER values " +
			"shall not be present in PDU.");
	}

    public void visitOctetStringValue(com.t3.ot.misc.StringValue value)
		throws com.t3.ot.misc.OtException {

		// Fields of this kind shall never be present in PDU:
		throw new VisitorInvalidFormat("OCTETSTRING values shall " +
			"not be present in PDU.");
	}

    public void visitSequenceBegin(com.t3.ot.misc.StructValue value)
		throws com.t3.ot.misc.OtException {

		// Fields of this kind shall never be present in PDU:
		throw new VisitorInvalidFormat("SEQUENCE values shall " +
			"not be present in PDU.");
	}

    public void visitSequenceEnd(com.t3.ot.misc.StructValue value)
		throws com.t3.ot.misc.OtException {

		// Fields of this kind shall never be present in PDU:
		throw new VisitorInvalidFormat("SEQUENCE values shall " +
			"not be present in PDU.");
	}

    public void visitSequenceOfBegin(com.t3.ot.misc.StructValue value)
		throws com.t3.ot.misc.OtException {

		// Fields of this kind shall never be present in PDU:
		throw new VisitorInvalidFormat("SEQUENCE OF values shall " +
			"not be present in PDU.");
	}

    public void visitSequenceOfEnd(com.t3.ot.misc.StructValue value)
		throws com.t3.ot.misc.OtException {

		// Fields of this kind shall never be present in PDU:
		throw new VisitorInvalidFormat("SEQUENCE OF values shall " +
			"not be present in PDU.");
	}

    final public void visitStructValueBegin(com.t3.ot.misc.StructValue value)
		throws com.t3.ot.misc.OtException {

        // Fields of this kind shall never be present in PDU:
		throw new VisitorInvalidFormat("Unsupported structured " +
			"data type definition was found while parsing PDU.");
	}

    final public void visitStructValueEnd(com.t3.ot.misc.StructValue value)
		throws com.t3.ot.misc.OtException {

        // Fields of this kind shall never be present in PDU:
		throw new VisitorInvalidFormat("Unsupported structured " +
			"data type definition was found while parsing PDU.");
	}

	final public void visitTableBegin(com.t3.ot.misc.StructValue value)
		throws com.t3.ot.misc.OtException {

		switch (tableState) {

			case STATE_TABLE_INACTIVE:

				tableState = STATE_TABLE_ACTIVE;
				return;

			case STATE_TABLE_ACTIVE:

				// What we have received now must be the beginning of
				// CHOICE value. When Tester bug is fixed, an exception
				// must be thrown here:

				choiceCount++;
				this.visitChoiceBegin(value);
				return;

				// throw new VisitorInvalidFormat("No other TTCN table " +
				//     "shall be present inside TTCN table.");

			case STATE_TABLE_COMPLETE:

				throw new VisitorInvalidFormat("TTCN table shall " +
					"appear in PDU no more than once.");

			default:

				System.err.println("BasicVisitor::visitTableBegin(): " +
				    "Internal error.");
				System.exit(0);
		}
	}

    final public void visitTableEnd(com.t3.ot.misc.StructValue value)
		throws com.t3.ot.misc.OtException {

		// Check that all CHOICE values are processed. If not, then
		// what we have received must be the end of CHOICE value:

		if (choiceCount > 0) {

			visitChoiceEnd(value);
			choiceCount--;
			return;
		}
        // Ensure that this method is invoked no more than once
        // and only after visitTableBegin():

		if (tableState != STATE_TABLE_ACTIVE)
			throw new VisitorInvalidFormat(
				"Incorrect definition of TTCN table.");

		tableState = STATE_TABLE_COMPLETE;
	}

    final public void visitValue(com.t3.ot.misc.Value value)
		throws com.t3.ot.misc.OtException {

        // Fields of this kind shall never be present in PDU:
        throw new VisitorInvalidFormat("Unsupported data type " +
			"definition was found while parsing PDU.");
	}
}
