package org.jacorb.orb;
/*
* JacORB - a free Java ORB
*
* Copyright (C) 1997-2004 Gerald Brose.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
import java.util.HashSet;
import org.jacorb.config.*;
import org.slf4j.Logger;
import org.jacorb.config.JacORBConfiguration;
import org.omg.CORBA.BAD_PARAM;
import org.omg.CORBA.BAD_TYPECODE;
import org.omg.CORBA.CompletionStatus;
import org.omg.CORBA.INTERNAL;
import org.omg.CORBA.TCKind;
import org.omg.CORBA.TypeCode;
/**
* @author Gerald Brose, FU Berlin
* @version $Id: ORBSingleton.java,v 1.53 2009-05-03 21:35:55 andre.spiegel Exp $
*/
public class ORBSingleton
extends org.omg.CORBA_2_5.ORB
{
private static final String FACTORY_METHODS_MESG = "The Singleton ORB only permits factory methods";
private boolean doStrictCheckOnTypecodeCreation;
private Logger logger;
/**
* in case a singleton orb is created the c'tor will access the JacORB configuration
* to configure the orb. otherwise configure needs to be called to properly set up
* the created instance.
*
* @param isSingleton determine if a singleton orb is created.
*/
protected ORBSingleton(boolean isSingleton)
{
super();
try
{
if (isSingleton)
{
Configuration configuration = JacORBConfiguration.getConfiguration(null, null, false);
// Don't call configure method as if this has been called from ORB::ctor
// class construction order can cause issues.
logger = ((org.jacorb.config.Configuration)configuration).getLogger
("jacorb.orb.singleton");
doStrictCheckOnTypecodeCreation = configuration.getAttributeAsBoolean
("jacorb.interop.strict_check_on_tc_creation", true);
if (logger.isDebugEnabled())
{
logger.debug("jacorb.interop.strict_check_on_tc_creation set to " + doStrictCheckOnTypecodeCreation);
}
logger.info("created ORBSingleton");
}
}
catch (ConfigurationException e)
{
throw new INTERNAL(e.toString());
}
}
public ORBSingleton()
{
this(true);
}
protected void configure(Configuration configuration) throws ConfigurationException
{
logger =
((org.jacorb.config.Configuration)configuration).getLogger("jacorb.orb");
doStrictCheckOnTypecodeCreation = configuration.getAttributeAsBoolean
("jacorb.interop.strict_check_on_tc_creation", true);
if (logger.isDebugEnabled())
{
logger.debug("jacorb.interop.strict_check_on_tc_creation set to " + doStrictCheckOnTypecodeCreation);
}
}
/**
* Returns the logger of this singleton ORB. Used for testing.
*/
public Logger getLogger()
{
return logger;
}
/* factory methods: */
public org.omg.CORBA.Any create_any()
{
return new org.jacorb.orb.Any(this);
}
/**
* Determine if a character is ok to start an id.
* (Note that '_' is allowed here - it might have
* been inserted by the IDL compiler to avoid clashes
* with reserved Java identifiers )
* @param character the character in question.
*/
final protected static boolean legalStartChar(int character)
{
return ( character >= 'a' && character <= 'z')
|| ( character == '_')
|| ( character >= 'A' && character <= 'Z');
}
/**
* Determine if a character is ok for the middle of an id.
* @param ch the character in question.
*/
final protected static boolean legalNameChar(int ch)
{
return legalStartChar(ch)
|| (ch == '_')
|| (ch >= '0' && ch <= '9');
}
/**
* code>checkTCName</code> checks that a name is a legal IDL name
* (CORBA 2.6 4-59).
* @throws org.omg.CORBA.BAD_PARAM
*/
private void checkTCName (String name) throws BAD_PARAM
{
checkTCName(name, false);
}
/**
* <code>checkTCName</code> checks the name is a legal IDL name and
* may optionally allow a null string (CORBA 2.6 4-59).
*
* @param name a <code>String</code> value
* @param allowNull a <code>boolean</code> value
* @exception BAD_PARAM if an error occurs
*/
private void checkTCName (String name, boolean allowNull)
throws BAD_PARAM
{
if (name == null)
{
if (allowNull)
{
return;
}
throw new BAD_PARAM("Illegal null IDL name",
15,
CompletionStatus.COMPLETED_NO );
}
if( name.length() > 0 )
{
// check that name begins with an ASCII char
if( !legalStartChar( name.charAt(0)) )
{
throw new BAD_PARAM
(
"Illegal start character to IDL name: " + name,
15,
CompletionStatus.COMPLETED_NO
);
}
for( int i = 0; i < name.length(); i++ )
{
if( ! legalNameChar( name.charAt(i) ))
{
throw new BAD_PARAM("Illegal IDL name: " + name,
15,
CompletionStatus.COMPLETED_NO );
}
}
}
else
{
throw new BAD_PARAM("Illegal blank IDL name",
15,
CompletionStatus.COMPLETED_NO );
}
}
/**
* Check that a repository ID is legal
* (cf. CORBA 2.4 chapter 10, section 7.3
* @param repId a <code>String</code> value
* @exception BAD_PARAM if an error occurs
*/
private void checkTCRepositoryId( String repId )
throws BAD_PARAM
{
if( repId == null || repId.indexOf( ':' ) < 0 )
{
throw new BAD_PARAM("Illegal Repository ID: " + repId,
16,
CompletionStatus.COMPLETED_NO );
}
}
/**
* check that a type is a legal member type
* (cf. CORBA 2.4 chapter 10, section 7.3
* @throws org.omg.CORBA.BAD_PARAM
*/
private void checkTCMemberType( TypeCode typeCode )
throws BAD_TYPECODE
{
if( !org.jacorb.orb.TypeCode.isRecursive(typeCode) &&
(typeCode == null ||
typeCode.kind().value() == TCKind._tk_null ||
typeCode.kind().value() == TCKind._tk_void ||
typeCode.kind().value() == TCKind._tk_except
)
)
{
throw new BAD_TYPECODE("Illegal member TypeCode",
2,
CompletionStatus.COMPLETED_NO );
}
}
/* TypeCode factory section */
public TypeCode create_alias_tc( String id,
String name,
TypeCode original_type)
{
checkTCRepositoryId( id );
checkTCName (name, true);
checkTCMemberType( original_type );
return new org.jacorb.orb.TypeCode( org.omg.CORBA.TCKind._tk_alias,
id,
name,
original_type);
}
public TypeCode create_array_tc( int length, TypeCode element_type)
{
checkTCMemberType( element_type );
return new org.jacorb.orb.TypeCode( org.omg.CORBA.TCKind._tk_array,
length,
element_type);
}
public TypeCode create_enum_tc( String id,
String name,
String[] members)
{
return create_enum_tc (id, name, members, true);
}
/**
* Allows the possibility of not checking the name when creating this
* typecode. This is to cater for compact typecodes where the name
* may not be set. Checking of the name will always be true for user
* driven requests
* @param id
* @param name
* @param members
* @param checkName
* @returns TypeCode
*/
TypeCode create_enum_tc( String id,
String name,
String [] members,
boolean checkName)
{
checkTCRepositoryId( id );
checkTCName (name, true);
if (checkName)
{
// check that member names are legal and unique
final HashSet names = new HashSet() ;
for( int i = 0; i < members.length; i++ )
{
boolean fault = false;
try
{
checkTCName( members[i] );
}
catch( BAD_PARAM e )
{
fault = true;
logger.debug("Typecode name check failed", e);
}
if((members[i] != null && names.contains(members[i])) || fault )
{
throw new BAD_PARAM("Illegal enum member name: " + members[i],
17,
CompletionStatus.COMPLETED_NO );
}
names.add(members[i]);
}
}
return new org.jacorb.orb.TypeCode( id, name, members);
}
public TypeCode create_exception_tc( String id,
String name,
org.omg.CORBA.StructMember[] members)
{
return create_exception_tc(id, name, members, true);
}
/**
* Allows the possibility of not checking the name when creating this
* typecode. This is to cater for compact typecodes where the name
* may not be set. Checking of the name will always be true for user
* driven requests
* @param id
* @param name
* @param members
* @param checkName
* @returns TypeCode
*/
TypeCode create_exception_tc( String id,
String name,
org.omg.CORBA.StructMember[] members,
boolean checkName)
{
checkTCRepositoryId( id );
checkTCName (name, true);
// check that member names are legal and unique
final HashSet names = new HashSet() ;
for( int i = 0; i < members.length; i++ )
{
checkTCMemberType( members[i].type );
if (checkName)
{
boolean fault = false;
try
{
checkTCName( members[i].name );
}
catch( BAD_PARAM e )
{
fault = true;
logger.debug("Typecode name check failed", e);
}
if((members[i].name != null && names.contains( members[i].name )) || fault )
{
throw new BAD_PARAM("Illegal exception member name: " + members[i].name,
17,
CompletionStatus.COMPLETED_NO );
}
names.add(members[i].name);
}
}
return new org.jacorb.orb.TypeCode( org.omg.CORBA.TCKind._tk_except,
id,
name,
members);
}
public TypeCode create_interface_tc( String id, String name)
{
checkTCRepositoryId( id );
checkTCName (name, true);
return new org.jacorb.orb.TypeCode( org.omg.CORBA.TCKind._tk_objref,
id,
name);
}
public org.omg.CORBA.TypeCode create_fixed_tc( short digits,
short scale)
{
if (digits <= 0 || scale < 0 || scale > digits)
{
throw new org.omg.CORBA.BAD_PARAM
("Invalid combination of digits and scale factor");
}
return new org.jacorb.orb.TypeCode(digits, scale);
}
public org.omg.CORBA.TypeCode create_recursive_tc( String id )
{
checkTCRepositoryId( id );
return new org.jacorb.orb.TypeCode( id );
}
public TypeCode create_sequence_tc( int bound, TypeCode element_type)
{
checkTCMemberType( element_type );
TypeCode typeCode =
new org.jacorb.orb.TypeCode( org.omg.CORBA.TCKind._tk_sequence,
bound,
element_type);
return typeCode;
}
public TypeCode create_string_tc(int bound)
{
return new org.jacorb.orb.TypeCode( org.omg.CORBA.TCKind._tk_string, bound );
}
public TypeCode create_wstring_tc(int bound)
{
return new org.jacorb.orb.TypeCode( org.omg.CORBA.TCKind._tk_wstring, bound);
}
public TypeCode create_struct_tc(String id,
String name,
org.omg.CORBA.StructMember[] members)
{
return create_struct_tc (id, name, members, true);
}
/**
* Allows the possibility of not checking the name when creating this
* typecode. This is to cater for compact typecodes where the name
* may not be set. Checking of the name will always be true for user
* driven requests
* @param id
* @param name
* @param members
* @param checkName
* @returns TypeCode
*/
TypeCode create_struct_tc(String id,
String name,
org.omg.CORBA.StructMember [] members,
boolean checkName)
{
checkTCRepositoryId( id );
checkTCName (name, true);
// check that member names are legal and unique
final HashSet names = new HashSet();
for( int i = 0; i < members.length; i++ )
{
if (checkName)
{
checkTCMemberType( members[i].type );
boolean fault = false;
try
{
checkTCName( members[i].name );
}
catch( BAD_PARAM e )
{
fault = true;
logger.debug("Typecode name check failed", e);
}
if((members[i].name != null && names.contains(members[i].name)) || fault )
{
throw new BAD_PARAM("Illegal struct member name: " + members[i].name + (fault? " (Bad PARAM) ": "" ),
17,
CompletionStatus.COMPLETED_NO );
}
names.add(members[i].name);
}
}
org.jacorb.orb.TypeCode typeCode =
new org.jacorb.orb.TypeCode( org.omg.CORBA.TCKind._tk_struct,
id,
name,
members);
// resolve any recursive references to this TypeCode in its members
typeCode.resolveRecursion();
return typeCode;
}
public TypeCode create_union_tc( String id,
String name,
TypeCode discriminator_type,
org.omg.CORBA.UnionMember[] members)
{
return create_union_tc(id, name, discriminator_type, members, true);
}
/**
* Allows the possibility of not checking the name when creating this
* typecode. This is to cater for compact typecodes where the name
* may not be set. Checking of the name will always be true for user
* driven requests
* @param id
* @param name
* @param members
* @param checkName
* @returns TypeCode
*/
TypeCode create_union_tc( String id,
String name,
TypeCode discriminator_type,
org.omg.CORBA.UnionMember [] members,
boolean checkName)
{
checkTCRepositoryId( id );
checkTCName (name, true);
// check discriminator type
TypeCode disc_tc =
org.jacorb.orb.TypeCode.originalType(discriminator_type);
if (disc_tc == null ||
!(disc_tc.kind().value() == TCKind._tk_short ||
disc_tc.kind().value() == TCKind._tk_long ||
disc_tc.kind().value() == TCKind._tk_longlong ||
disc_tc.kind().value() == TCKind._tk_ushort ||
disc_tc.kind().value() == TCKind._tk_ulong ||
disc_tc.kind().value() == TCKind._tk_ulonglong ||
disc_tc.kind().value() == TCKind._tk_char ||
disc_tc.kind().value() == TCKind._tk_boolean ||
disc_tc.kind().value() == TCKind._tk_enum
)
)
{
throw new BAD_PARAM("Illegal union discriminator type",
20,
CompletionStatus.COMPLETED_NO );
}
// check that member names are legal (they do not need to be unique)
for( int i = 0; i < members.length; i++ )
{
checkTCMemberType( members[i].type );
if (checkName)
{
try
{
checkTCName( members[i].name );
}
catch( BAD_PARAM e )
{
logger.debug("Typecode name check failed", e);
throw new BAD_PARAM("Illegal union member name: " + members[i].name,
17,
CompletionStatus.COMPLETED_NO );
}
}
// check that member type matches discriminator type or is default
org.omg.CORBA.Any label = members[i].label;
if (! discriminator_type.equivalent( label.type() ) &&
! ( label.type().kind().value() == TCKind._tk_octet &&
label.extract_octet() == (byte)0
)
)
{
throw new BAD_PARAM("Label type does not match discriminator type",
19,
CompletionStatus.COMPLETED_NO );
}
// check that member labels are unique
for( int j = 0; j < i; j++ )
{
if( label.equal( members[j].label ))
{
throw new BAD_PARAM("Duplicate union case label",
18,
CompletionStatus.COMPLETED_NO );
}
}
}
org.jacorb.orb.TypeCode typeCode =
new org.jacorb.orb.TypeCode( id,
name,
discriminator_type,
members);
// resolve any recursive references to this TypeCode in its members
typeCode.resolveRecursion();
return typeCode;
}
public TypeCode get_primitive_tc(org.omg.CORBA.TCKind tcKind)
{
return org.jacorb.orb.TypeCode.get_primitive_tc( tcKind.value() );
}
public org.omg.CORBA.TypeCode create_value_tc(String id,
String name,
short type_modifier,
TypeCode concrete_base,
org.omg.CORBA.ValueMember[] members)
{
checkTCRepositoryId( id );
// The name parameter should be a valid IDL name, but in the case of
// an RMI valuetype the ORB in jdk1.4 sends a dotted name (such as
// "some.package.SomeClass") over the wire. For interoperability with
// Sun's ORB we skip the name check in this case.
if ( !id.startsWith("RMI:") )
{
checkTCName (name, true);
}
return new org.jacorb.orb.TypeCode (id,
name,
type_modifier,
concrete_base,
members);
}
public org.omg.CORBA.TypeCode create_value_box_tc(String id,
String name,
TypeCode boxed_type)
{
checkTCRepositoryId( id );
checkTCName (name, true);
return new org.jacorb.orb.TypeCode (org.omg.CORBA.TCKind._tk_value_box,
id,
name,
boxed_type);
}
public org.omg.CORBA.TypeCode create_abstract_interface_tc(String id,
String name)
{
checkTCRepositoryId( id );
// strict_check_on_tc_creation is incompatible with Sun's ValueHandler,
// which calls create_abstract_interface_tc() passing an empty string
// as the name parameter. checkTCName() then throws
//`org.omg.CORBA.BAD_PARAM: Illegal blank IDL name'.
if ( doStrictCheckOnTypecodeCreation )
{
checkTCName (name, true);
}
return new org.jacorb.orb.TypeCode (org.omg.CORBA.TCKind._tk_abstract_interface,
id,
name);
}
public org.omg.CORBA.TypeCode create_local_interface_tc(String id,
String name)
{
checkTCRepositoryId( id );
checkTCName (name, true);
return new org.jacorb.orb.TypeCode (org.omg.CORBA.TCKind._tk_local_interface,
id,
name);
}
public org.omg.CORBA.TypeCode create_native_tc(String id,
String name)
{
checkTCRepositoryId( id );
checkTCName (name, true);
return new org.jacorb.orb.TypeCode (org.omg.CORBA.TCKind._tk_native,
id,
name);
}
/* not allowed on the singleton: */
public org.omg.CORBA.ExceptionList create_exception_list()
{
throw new org.omg.CORBA.NO_IMPLEMENT (FACTORY_METHODS_MESG);
}
public org.omg.CORBA.NVList create_list (int count)
{
throw new org.omg.CORBA.NO_IMPLEMENT (FACTORY_METHODS_MESG);
}
public org.omg.CORBA.NamedValue create_named_value
(String name, org.omg.CORBA.Any value, int flags)
{
throw new org.omg.CORBA.NO_IMPLEMENT (FACTORY_METHODS_MESG);
}
public org.omg.CORBA.NVList create_operation_list
(org.omg.CORBA.OperationDef oper)
{
throw new org.omg.CORBA.NO_IMPLEMENT (FACTORY_METHODS_MESG);
}
public org.omg.CORBA.NVList create_operation_list
(org.omg.CORBA.Object obj)
{
throw new org.omg.CORBA.NO_IMPLEMENT (FACTORY_METHODS_MESG);
}
public org.omg.CORBA.Object string_to_object(String str)
{
throw new org.omg.CORBA.NO_IMPLEMENT (FACTORY_METHODS_MESG);
}
public org.omg.CORBA.Environment create_environment()
{
throw new org.omg.CORBA.NO_IMPLEMENT (FACTORY_METHODS_MESG);
}
public org.omg.CORBA.ContextList create_context_list()
{
throw new org.omg.CORBA.NO_IMPLEMENT (FACTORY_METHODS_MESG);
}
public org.omg.CORBA.portable.OutputStream create_output_stream()
{
throw new org.omg.CORBA.NO_IMPLEMENT (FACTORY_METHODS_MESG);
}
public org.omg.CORBA.Current get_current()
{
throw new org.omg.CORBA.NO_IMPLEMENT (FACTORY_METHODS_MESG);
}
public org.omg.CORBA.Context get_default_context()
{
throw new org.omg.CORBA.NO_IMPLEMENT (FACTORY_METHODS_MESG);
}
public org.omg.CORBA.Request get_next_response()
{
throw new org.omg.CORBA.NO_IMPLEMENT (FACTORY_METHODS_MESG);
}
public String[] list_initial_services()
{
throw new org.omg.CORBA.NO_IMPLEMENT (FACTORY_METHODS_MESG);
}
public String object_to_string( org.omg.CORBA.Object obj)
{
throw new org.omg.CORBA.NO_IMPLEMENT (FACTORY_METHODS_MESG);
}
public boolean poll_next_response()
{
throw new org.omg.CORBA.NO_IMPLEMENT (FACTORY_METHODS_MESG);
}
public org.omg.CORBA.Object resolve_initial_references(String identifier)
throws org.omg.CORBA.ORBPackage.InvalidName
{
throw new org.omg.CORBA.NO_IMPLEMENT (FACTORY_METHODS_MESG);
}
public void send_multiple_requests_deferred(org.omg.CORBA.Request[] req)
{
throw new org.omg.CORBA.NO_IMPLEMENT (FACTORY_METHODS_MESG);
}
public void send_multiple_requests_oneway(org.omg.CORBA.Request[] req)
{
throw new org.omg.CORBA.NO_IMPLEMENT (FACTORY_METHODS_MESG);
}
protected void set_parameters(String[] args, java.util.Properties props)
{
throw new org.omg.CORBA.NO_IMPLEMENT (FACTORY_METHODS_MESG);
}
protected void set_parameters(java.applet.Applet app, java.util.Properties props)
{
throw new org.omg.CORBA.NO_IMPLEMENT (FACTORY_METHODS_MESG);
}
public void run()
{
throw new org.omg.CORBA.NO_IMPLEMENT (FACTORY_METHODS_MESG);
}
public void shutdown(boolean wait_for_completion)
{
throw new org.omg.CORBA.NO_IMPLEMENT (FACTORY_METHODS_MESG);
}
public boolean work_pending()
{
throw new org.omg.CORBA.NO_IMPLEMENT (FACTORY_METHODS_MESG);
}
public void perform_work()
{
throw new org.omg.CORBA.NO_IMPLEMENT (FACTORY_METHODS_MESG);
}
}