/* RestrictedORB.java --
   Copyright (C) 2005 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package gnu.CORBA;

import gnu.CORBA.CDR.BufferedCdrOutput;
import gnu.CORBA.typecodes.AliasTypeCode;
import gnu.CORBA.typecodes.ArrayTypeCode;
import gnu.CORBA.typecodes.PrimitiveTypeCode;
import gnu.CORBA.typecodes.RecordTypeCode;
import gnu.CORBA.typecodes.StringTypeCode;

import org.omg.CORBA.Any;
import org.omg.CORBA.BAD_PARAM;
import org.omg.CORBA.Context;
import org.omg.CORBA.ContextList;
import org.omg.CORBA.Environment;
import org.omg.CORBA.ExceptionList;
import org.omg.CORBA.NO_IMPLEMENT;
import org.omg.CORBA.NVList;
import org.omg.CORBA.NamedValue;
import org.omg.CORBA.ORB;
import org.omg.CORBA.ORBPackage.InvalidName;
import org.omg.CORBA.Request;
import org.omg.CORBA.StructMember;
import org.omg.CORBA.TCKind;
import org.omg.CORBA.TypeCode;
import org.omg.CORBA.TypeCodePackage.BadKind;
import org.omg.CORBA.UnionMember;
import org.omg.CORBA.portable.OutputStream;
import org.omg.CORBA.portable.ValueFactory;
import org.omg.PortableInterceptor.ClientRequestInterceptorOperations;
import org.omg.PortableInterceptor.IORInterceptor_3_0Operations;
import org.omg.PortableInterceptor.ServerRequestInterceptorOperations;

import java.applet.Applet;

import java.util.Hashtable;
import java.util.Properties;

/**
 * This class implements so-called Singleton ORB, a highly restricted version
 * that cannot communicate over network. This ORB is provided for the
 * potentially malicious applets with heavy security restrictions. It, however,
 * supports some basic features that might be needed even when the network
 * access is not granted.
 *
 * This ORB can only create typecodes, {@link Any}, {@link ContextList},
 * {@link NVList} and {@link org.omg.CORBA.portable.OutputStream} that writes to
 * an internal buffer.
 *
 * All other methods throw the {@link NO_IMPLEMENT} exception.
 *
 * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
 */
public class OrbRestricted extends org.omg.CORBA_2_3.ORB
{
  /**
   * The singleton instance of this ORB.
   */
  public static final ORB Singleton = new OrbRestricted();

  /**
   * The cumulated listener for all IOR interceptors. Interceptors are used by
   * {@link gnu.CORBA.Poa.ORB_1_4}.
   */
  public IORInterceptor_3_0Operations iIor;

  /**
   * The cumulated listener for all server request interceptors. Interceptors
   * are used by {@link gnu.CORBA.Poa.ORB_1_4}.
   */
  public ServerRequestInterceptorOperations iServer;

  /**
   * The cumulated listener for all client request interceptros. Interceptors
   * are used by {@link gnu.CORBA.Poa.ORB_1_4}.
   */
  public ClientRequestInterceptorOperations iClient;

  /**
   * The required size of the interceptor slot array.
   */
  public int icSlotSize = 0;

  /**
   * The value factories.
   */
  protected Hashtable factories = new Hashtable();

  /**
   * The policy factories.
   */
  protected Hashtable policyFactories = new Hashtable();

  /**
       * Create a new instance of the RestrictedORB. This is used in derived classes
   * only.
   */
  protected OrbRestricted()
  {
  }

  /** {@inheritDoc} */
  public TypeCode create_alias_tc(String id, String name, TypeCode typecode)
  {
    return new AliasTypeCode(typecode, id, name);
  }

  /** {@inheritDoc} */
  public Any create_any()
  {
    gnuAny any = new gnuAny();
    any.setOrb(this);
    return any;
  }

  /** {@inheritDoc} */
  public TypeCode create_array_tc(int length, TypeCode element_type)
  {
    ArrayTypeCode p =
      new ArrayTypeCode(TCKind.tk_array, element_type);
    p.setLength(length);
    return p;
  }

  /** {@inheritDoc} */
  public ContextList create_context_list()
  {
    return new gnuContextList();
  }

  /** {@inheritDoc} */
  public TypeCode create_enum_tc(String id, String name, String[] values)
  {
    RecordTypeCode r = new RecordTypeCode(TCKind.tk_enum);
    for (int i = 0; i < values.length; i++)
      {
        r.field().name = values [ i ];
      }

    r.setId(id);
    r.setName(name);

    return r;
  }

  /** {@inheritDoc} */
  public Environment create_environment()
  {
    return new gnuEnvironment();
  }

  /** {@inheritDoc} */
  public ExceptionList create_exception_list()
  {
    return new gnuExceptionList();
  }

  /** {@inheritDoc} */
  public TypeCode create_exception_tc(String id, String name,
    StructMember[] members
  )
  {
    RecordTypeCode r = new RecordTypeCode(TCKind.tk_except);
    r.setId(id);
    r.setName(name);

    for (int i = 0; i < members.length; i++)
      {
        r.add(members [ i ]);
      }

    return r;
  }

  /**
   * This method is not allowed for a RestrictedORB.
   *
   * @throws NO_IMPLEMENT, always.
   */
  public TypeCode create_interface_tc(String id, String name)
  {
    no();
    return null;
  }

  /** {@inheritDoc} */
  public NVList create_list(int count)
  {
    return new gnuNVList(count);
  }

  /** {@inheritDoc} */
  public NamedValue create_named_value(String s, Any any, int flags)
  {
    return new gnuNamedValue();
  }

  /** {@inheritDoc} */
  public OutputStream create_output_stream()
  {
    BufferedCdrOutput stream = new BufferedCdrOutput();
    stream.setOrb(this);
    return stream;
  }

  /** {@inheritDoc} */
  public TypeCode create_sequence_tc(int bound, TypeCode element_type)
  {
    ArrayTypeCode p =
      new ArrayTypeCode(TCKind.tk_sequence, element_type);
    p.setLength(bound);
    return p;
  }

  /** {@inheritDoc} */
  public TypeCode create_string_tc(int bound)
  {
    StringTypeCode p = new StringTypeCode(TCKind.tk_string);
    p.setLength(bound);
    return p;
  }

  /** {@inheritDoc} */
  public TypeCode create_struct_tc(String id, String name,
    StructMember[] members
  )
  {
    RecordTypeCode r = new RecordTypeCode(TCKind.tk_struct);
    r.setId(id);
    r.setName(name);

    for (int i = 0; i < members.length; i++)
      {
        r.add(members [ i ]);
      }

    return r;
  }

  /** {@inheritDoc} */
  public TypeCode create_union_tc(String id, String name,
    TypeCode discriminator_type, UnionMember[] members
  )
  {
    RecordTypeCode r = new RecordTypeCode(TCKind.tk_union);
    r.setId(id);
    r.setName(name);
    r.setDiscriminator_type(discriminator_type);
    r.setDefaultIndex(0);

    for (int i = 0; i < members.length; i++)
      {
        r.add(members [ i ]);
      }

    return r;
  }

  /** {@inheritDoc} */
  public TypeCode create_wstring_tc(int bound)
  {
    StringTypeCode p = new StringTypeCode(TCKind.tk_wstring);
    p.setLength(bound);
    return p;
  }

  /** {@inheritDoc} */
  public TypeCode get_primitive_tc(TCKind tcKind)
  {
    try
      {
        return TypeKindNamer.getPrimitveTC(tcKind);
      }
    catch (BadKind ex)
      {
        throw new BAD_PARAM("This is not a primitive type code: " +
          tcKind.value()
        );
      }
  }

  /**
   * This method is not allowed for a RestrictedORB.
   *
   * @throws NO_IMPLEMENT, always.
   */
  public String[] list_initial_services()
  {
    no();
    throw new InternalError();
  }

  /**
   * This method is not allowed for a RestrictedORB.
   *
   * @throws NO_IMPLEMENT, always.
   */
  public String object_to_string(org.omg.CORBA.Object forObject)
  {
    no();
    throw new InternalError();
  }

  /**
   * This method is not allowed for a RestrictedORB.
   *
   * @throws InvalidName never in this class, but it is thrown in the derived
   * classes.
   *
   * @throws NO_IMPLEMENT, always.
   */
  public org.omg.CORBA.Object resolve_initial_references(String name)
    throws InvalidName
  {
    no();
    throw new InternalError();
  }

  /**
   * Shutdown the ORB server.
   *
   * For RestrictedORB, returns witout action.
   */
  public void run()
  {
  }

  /**
   * Shutdown the ORB server.
   *
   * For RestrictedORB, returns witout action.
   */
  public void shutdown(boolean wait_for_completion)
  {
  }

  /**
   * This method is not allowed for a RestrictedORB.
   *
   * @throws NO_IMPLEMENT, always.
   */
  public org.omg.CORBA.Object string_to_object(String IOR)
  {
    no();
    throw new InternalError();
  }

  /**
   * This method is not allowed for a RestrictedORB.
   *
   * @throws NO_IMPLEMENT, always.
   */
  protected void set_parameters(Applet app, Properties props)
  {
    no();
  }

  /**
   * This method is not allowed for a RestrictedORB.
   *
   * @throws NO_IMPLEMENT, always.
   */
  protected void set_parameters(String[] args, Properties props)
  {
    no();
  }

  /**
   * Throws an exception, stating that the given method is not supported by the
   * Restricted ORB.
   */
  private final void no()
  {
    // Apart the programming errors, this can only happen if the
    // malicious code is trying to do that it is not allowed.
    throw new NO_IMPLEMENT("Use init(args, props) for the functional version.");
  }

  /**
   * This method is not allowed for a RestrictedORB.
   *
   * @throws NO_IMPLEMENT, always.
   */
  public Request get_next_response() throws org.omg.CORBA.WrongTransaction
  {
    no();
    throw new InternalError();
  }

  /**
   * This method is not allowed for a RestrictedORB.
   *
   * @throws NO_IMPLEMENT, always.
   */
  public boolean poll_next_response()
  {
    no();
    throw new InternalError();
  }

  /**
   * This method is not allowed for a RestrictedORB.
   *
   * @throws NO_IMPLEMENT, always.
   */
  public void send_multiple_requests_deferred(Request[] requests)
  {
    no();
  }

  /**
   * This method is not allowed for a RestrictedORB.
   *
   * @throws NO_IMPLEMENT, always.
   */
  public void send_multiple_requests_oneway(Request[] requests)
  {
    no();
  }

  /**
   * Register the value factory under the given repository id.
   */
  public ValueFactory register_value_factory(String repository_id,
    ValueFactory factory
  )
  {
    factories.put(repository_id, factory);
    return factory;
  }

  /**
   * Unregister the value factroy.
   */
  public void unregister_value_factory(String id)
  {
    factories.remove(id);
  }

  /**
   * Look for the value factory for the value, having the given repository id.
       * The implementation checks for the registered value factories first. If none
       * found, it tries to load and instantiate the class, mathing the given naming
   * convention. If this faild, null is returned.
   *
   * @param repository_id a repository id.
   *
   * @return a found value factory, null if none.
   */
  public ValueFactory lookup_value_factory(String repository_id)
  {
    ValueFactory f = (ValueFactory) factories.get(repository_id);
    if (f != null)
      {
        return f;
      }

    f = (ValueFactory) ObjectCreator.createObject(repository_id,
        "DefaultFactory"
      );
    if (f != null)
      {
        factories.put(repository_id, f);
      }
    return f;
  }

  /**
   * Destroy the interceptors, if they are present.
   */
  public void destroy()
  {
    if (iIor != null)
      {
        iIor.destroy();
        iIor = null;
      }

    if (iServer != null)
      {
        iServer.destroy();
        iServer = null;
      }

    if (iClient != null)
      {
        iClient.destroy();
        iClient = null;
      }

    super.destroy();
  }
  
  /**
   * Create a typecode, representing a tree-like structure.
   * This structure contains a member that is a sequence of the same type,
   * as the structure itself. You can imagine as if the folder definition
   * contains a variable-length array of the enclosed (nested) folder
   * definitions. In this way, it is possible to have a tree like
   * structure that can be transferred via CORBA CDR stream.
   *
   * @deprecated It is easier and clearler to use a combination of
   * create_recursive_tc and create_sequence_tc instead.
   *
   * @param bound the maximal expected number of the nested components
   * on each node; 0 if not limited.
   *
   * @param offset the position of the field in the returned structure
   * that contains the sequence of the structures of the same field.
   * The members before this field are intialised using parameterless
   * StructMember constructor.
   *
   * @return a typecode, defining a stucture, where a member at the
   * <code>offset</code> position defines an array of the identical
   * structures.
   *
   * @see #create_recursive_tc(String)
   * @see #create_sequence_tc(int, TypeCode)
   */
  public TypeCode create_recursive_sequence_tc(int bound, int offset)
  {
    RecordTypeCode r = new RecordTypeCode(TCKind.tk_struct);
    for (int i = 0; i < offset; i++)
      r.add(new StructMember());

    TypeCode recurs = new PrimitiveTypeCode(TCKind.tk_sequence);

    r.add(new StructMember("", recurs, null));
    return r;
  }
  
  /**
   * Get the default context of this ORB. This is an initial root of all
   * contexts.
   *
   * The default method returns a new context with the empty name and
   * no parent context.
   *
   * @return the default context of this ORB.
   */
  public Context get_default_context()
  {
    return new gnuContext("", null);
  }
  
}