/*
 *  NamingContextVisitor.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 introspection of Registration PDU that encapsulates
 *  location of CORBA object in Naming Service. */
final public class NamingContextVisitor extends BasicAspVisitor {

    // --------------------- CLASS OUTPUT PARAMETERS --------------------

   	private String[] namingContext;
	
   	/** Get location in Naming Service extracted by Visitor. */
   	public String[] getNamingContext() throws com.t3.ot.misc.OtException {

		if (namingContext == null) finalizeVisitor();
		return namingContext;
	}

	// ---------------------- CLASS INTERNAL STATE ----------------------

	private Vector constructedContext;

	private int arrayState;

   	private static final int STATE_ARRAY_INACTIVE = 0;
    private static final int STATE_ARRAY_ACTIVE   = 1;
    private static final int STATE_ARRAY_COMPLETE = 2;

    // ----------------------- CLASS CONSTRUCTOR ------------------------

   	public NamingContextVisitor(String pcoName_, com.t3.ot.pco.ASP asp_)
		throws com.t3.ot.misc.OtException {

		super(pcoName_, asp_);

		namingContext = null;
		constructedContext = new Vector(5,5);
		arrayState = STATE_ARRAY_INACTIVE;
	}

    // ----------------------- CLASS POSTPROCESSOR ----------------------

   	/** Make final actions on invocation request prepared by Visitor
     *  after Visitor is accepted. */
   	protected void finalizeVisitor() throws com.t3.ot.misc.OtException {

        super.finalizeVisitor();

		if (arrayState != STATE_ARRAY_COMPLETE)
			throw new VisitorInvalidFormat("Structural problems in PDU.");

		if (constructedContext.size() == 0)
			throw new VisitorInvalidFormat("Registration PDU is empty.");

		namingContext = (String[]) constructedContext.toArray(new String[1]);
	}

    // ---------------------- CLASS VISITOR METHODS ---------------------

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

		if (tableState != STATE_TABLE_ACTIVE)
			throw new VisitorInvalidFormat("CharacterString " +
				"value is defined outside TTCN table.");

		if (arrayState != STATE_ARRAY_ACTIVE)
			throw new VisitorInvalidFormat("CharacterString " +
				"value is defined outside SEQUENCE OF.");

		String strVal = value.getCharString();
		constructedContext.add(strVal);	
	}

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

        if (tableState != STATE_TABLE_ACTIVE)
			throw new VisitorInvalidFormat("SEQUENCE OF " +
				"is defined outside TTCN table.");

		if (value.getName().equals("NSERV") == false) {
			throw new VisitorInvalidFormat("Registration PDU field " +
				"name shall not be anything else than \"NSERV\" in " +
				"this context.");
		}

		switch (arrayState) {

			case STATE_ARRAY_INACTIVE:

				arrayState = STATE_ARRAY_ACTIVE;
				return;

			case STATE_ARRAY_ACTIVE:

				throw new VisitorInvalidFormat("No other SEQUENCE OF " +
					"shall be present inside SEQUENCE OF.");

			case STATE_ARRAY_COMPLETE:

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

			default:

				System.err.println("NamingContextVisitor::" +
				    "visitSequenceOfBegin(): Internal error.");
				System.exit(0);
		}
	}

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

		if (tableState != STATE_TABLE_ACTIVE)
			throw new VisitorInvalidFormat("SEQUENCE OF " +
				"is defined outside TTCN table.");

		if (value.getName().equals("NSERV") == false) {
			throw new VisitorInvalidFormat("Registration PDU field " +
				"name shall not be anything else than \"NSERV\" in " +
				"this context.");
		}

		if (arrayState != STATE_ARRAY_ACTIVE)
			throw new VisitorInvalidFormat(
				"Incorrect definition of SEQUENCE OF.");

		arrayState = STATE_ARRAY_COMPLETE;
	}
}
