package org.jacorb.ir;
/*
* JacORB - a free Java ORB
*
* Copyright (C) 1997-2014 Gerald Brose / The JacORB Team.
*
* 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.io.File;
import java.util.Enumeration;
import java.util.Hashtable;
import org.omg.CORBA.AbstractInterfaceDef;
import org.omg.CORBA.ExtInitializer;
import org.omg.CORBA.ExtValueDef;
import org.omg.CORBA.INTF_REPOS;
import org.omg.CORBA.InterfaceDef;
import org.omg.CORBA.LocalInterfaceDef;
import org.omg.CORBA.NO_IMPLEMENT;
import org.omg.CORBA.ValueDef;
import org.omg.PortableServer.POA;
import org.slf4j.Logger;
public class StructDef
extends TypedefDef
implements org.omg.CORBA.StructDefOperations, ContainerType
{
private org.omg.CORBA.TypeCode type;
private Class myClass;
private Class helperClass;
private org.omg.CORBA.StructMember[] members;
/** local references to contained objects */
private Hashtable containedLocals = new Hashtable();
/** CORBA references to contained objects */
private Hashtable contained = new Hashtable();
private File my_dir;
private String path;
private boolean defined = false;
private Logger logger;
private ClassLoader loader;
private POA poa;
public StructDef(Class c,
String path,
org.omg.CORBA.Container _defined_in,
org.omg.CORBA.Repository ir,
Logger logger,
ClassLoader loader,
POA poa)
{
this.logger = logger;
this.loader = loader;
this.poa = poa;
def_kind = org.omg.CORBA.DefinitionKind.dk_Struct;
containing_repository = ir;
defined_in = _defined_in;
this.path = path;
if (defined_in == null)
{
throw new INTF_REPOS ("defined_in = null");
}
if (containing_repository == null)
{
throw new INTF_REPOS ("containing_repository = null");
}
try
{
String classId = c.getName();
myClass = c;
version( "1.0" );
full_name = classId;
if( classId.indexOf('.') > 0 )
{
name( classId.substring( classId.lastIndexOf('.')+1 ) );
absolute_name =
org.omg.CORBA.ContainedHelper.narrow( defined_in ).absolute_name() +
"::" + name;
}
else
{
name( classId );
absolute_name = "::" + name;
}
helperClass = this.loader.loadClass( classId + "Helper") ;
id( (String)helperClass.getDeclaredMethod( "id", (Class[]) null ).invoke( null, (Object[]) null ));
type = (org.omg.CORBA.TypeCode)helperClass.getDeclaredMethod(
"type",
(Class[]) null ).invoke( null, (Object[]) null );
members = new org.omg.CORBA.StructMember[ type.member_count() ];
for( int i = 0; i < members.length; i++ )
{
org.omg.CORBA.TypeCode type_code = type.member_type(i);
String member_name = type.member_name(i);
if (this.logger.isDebugEnabled())
{
this.logger.debug("StructDef " + absolute_name +
" member " + member_name);
}
members[i] = new org.omg.CORBA.StructMember( member_name,
type_code,
null );
}
/* get directory for nested definitions' classes */
File f = new File( path + fileSeparator +
classId.replace('.', fileSeparator) + "Package" );
if( f.exists() && f.isDirectory() )
my_dir = f;
if (this.logger.isDebugEnabled())
{
this.logger.debug("StructDef: " + absolute_name);
}
}
catch ( Exception e )
{
logger.error("Caught Exception", e);
throw new INTF_REPOS( ErrorMsg.IR_Not_Implemented,
org.omg.CORBA.CompletionStatus.COMPLETED_NO);
}
}
public void loadContents()
{
// read from the class (operations and atributes)
if (getReference () == null)
{
throw new INTF_REPOS ("getReference returns null");
}
org.omg.CORBA.StructDef myReference =
org.omg.CORBA.StructDefHelper.narrow( getReference());
if (myReference == null)
{
throw new INTF_REPOS ("narrow failed for " + getReference() );
}
/* load nested definitions from interfacePackage directory */
String[] classes = null;
if( my_dir != null )
{
classes = my_dir.list( new IRFilenameFilter(".class") );
// load class files in this interface's Package directory
if( classes != null)
{
for( int j = 0; j < classes.length; j++ )
{
try
{
if (this.logger.isDebugEnabled())
{
this.logger.debug("Struct " +name+ " tries " +
full_name +
"Package." +
classes[j].substring( 0, classes[j].indexOf(".class")));
}
ClassLoader loader = getClass().getClassLoader();
if( loader == null )
{
loader = this.loader;
}
Class cl =
loader.loadClass(
( full_name +
"Package." +
classes[j].substring( 0, classes[j].indexOf(".class"))
));
Contained containedObject =
Contained.createContained( cl,
path,
myReference,
containing_repository,
this.logger,
this.loader,
this.poa);
if( containedObject == null )
continue;
org.omg.CORBA.Contained containedRef =
Contained.createContainedReference(containedObject,
this.logger,
this.poa);
if( containedObject instanceof ContainerType )
((ContainerType)containedObject).loadContents();
containedRef.move( myReference, containedRef.name(), containedRef.version() );
if (this.logger.isDebugEnabled())
{
this.logger.debug("Struct " + full_name +
" loads "+ containedRef.name() );
}
contained.put( containedRef.name() , containedRef );
containedLocals.put( containedRef.name(), containedObject );
}
catch ( Exception e )
{
logger.error("Caught Exception", e);
}
}
}
}
}
/**
*/
public void define()
{
if (this.logger.isDebugEnabled())
{
this.logger.debug("Struct " + name + " defining...");
}
for( Enumeration e = containedLocals.elements();
e.hasMoreElements();
((IRObject)e.nextElement()).define())
;
for( int i = 0; i < members.length; i++ )
{
members[i].type_def =
IDLType.create( members[i].type, containing_repository,
this.logger, this.poa);
if (members[i].type_def == null)
{
throw new INTF_REPOS ("No type_def for member " + members[i].name +
" in struct " + full_name );
}
}
defined = true;
if (this.logger.isDebugEnabled())
{
this.logger.debug("Struct " + name + " defined");
}
}
/**
*/
org.omg.CORBA.TypeDescription describe_struct()
{
if ( ! defined)
{
throw new INTF_REPOS ("Struct " + full_name + " not defined! ");
}
return new org.omg.CORBA.TypeDescription(name(),
id(),
org.omg.CORBA.ContainedHelper.narrow( defined_in ).id(),
version(),
type());
}
public org.omg.CORBA.TypeCode type()
{
if (type == null)
{
throw new INTF_REPOS ("Struct TypeCode is null");
}
return type;
}
public org.omg.CORBA.Contained lookup( String scopedname )
{
if (this.logger.isDebugEnabled())
{
this.logger.debug("Struct " + this.name + " lookup " + scopedname);
}
String top_level_name;
String rest_of_name;
String name;
if( scopedname.startsWith("::") )
{
name = scopedname.substring(2);
}
else
name = scopedname;
if( name.indexOf("::") > 0 )
{
top_level_name = name.substring( 0, name.indexOf("::") );
rest_of_name = name.substring( name.indexOf("::") + 2);
}
else
{
top_level_name = name;
rest_of_name = null;
}
try
{
org.omg.CORBA.Contained top =
(org.omg.CORBA.Contained)contained.get( top_level_name );
if( top == null )
{
if (this.logger.isDebugEnabled())
{
this.logger.debug("Interface " + this.name +
" top " + top_level_name +
" not found ");
}
return null;
}
if( rest_of_name == null )
{
return top;
}
else
{
if( top instanceof org.omg.CORBA.Container)
{
return ((org.omg.CORBA.Container)top).lookup( rest_of_name );
}
else
{
if (this.logger.isDebugEnabled())
{
this.logger.debug("Interface " + this.name +
" " + scopedname + " not found");
}
return null;
}
}
}
catch( Exception e )
{
logger.error("Caught Exception", e);
return null;
}
}
public org.omg.CORBA.StructMember[] members()
{
if ( ! defined)
{
throw new INTF_REPOS ("Struct " + full_name + " not defined! ");
}
return members;
}
// write interface not supported!
public void members(org.omg.CORBA.StructMember[] a)
{
}
public org.omg.CORBA.ModuleDef create_module( String id, String name, String version)
{
return null;
}
public org.omg.CORBA.ConstantDef create_constant(java.lang.String id,
java.lang.String name,
java.lang.String version,
org.omg.CORBA.IDLType type,
org.omg.CORBA.Any value)
{
return null;
}
public org.omg.CORBA.StructDef create_struct( String id, String name,
String version,
org.omg.CORBA.StructMember[] members){
return null;
}
public org.omg.CORBA.UnionDef create_union( String id, String name,
String version,
org.omg.CORBA.IDLType discriminator_type,
org.omg.CORBA.UnionMember[] members){
return null;
}
public org.omg.CORBA.EnumDef create_enum( String id, String name,
String version, String[] members){
return null;
}
public org.omg.CORBA.AliasDef create_alias( String id, String name,
String version,
org.omg.CORBA.IDLType original_type){
return null;
}
/**
* not supported
*/
public org.omg.CORBA.ExceptionDef create_exception(java.lang.String id,
java.lang.String name ,
java.lang.String version,
org.omg.CORBA.StructMember[] member )
{
return null;
}
/**
* not supported
*/
public org.omg.CORBA.InterfaceDef create_interface(
String id,
String name,
String version,
org.omg.CORBA.InterfaceDef[] base_interfaces)
{
return null;
}
/**
* not supported
*/
public org.omg.CORBA.ValueBoxDef create_value_box(java.lang.String id,
java.lang.String name,
java.lang.String version,
org.omg.CORBA.IDLType type)
{
return null;
}
/**
* not supported
*/
public org.omg.CORBA.ValueDef create_value(
java.lang.String id,
java.lang.String name,
java.lang.String version,
boolean is_custom,
boolean is_abstract,
org.omg.CORBA.ValueDef base_value,
boolean is_truncatable,
org.omg.CORBA.ValueDef[] abstract_base_values,
org.omg.CORBA.InterfaceDef[] supported_interfaces,
org.omg.CORBA.Initializer[] initializers)
{
return null;
}
/**
* not supported
*/
public org.omg.CORBA.NativeDef create_native(java.lang.String id,
java.lang.String name,
java.lang.String version)
{
return null;
}
public void destroy()
{
throw new INTF_REPOS(ErrorMsg.IR_Not_Implemented,
org.omg.CORBA.CompletionStatus.COMPLETED_NO);
}
public org.omg.CORBA.Contained[] lookup_name( String search_name,
int levels_to_search,
org.omg.CORBA.DefinitionKind limit_type,
boolean exclude_inherited )
{
if( levels_to_search == 0 )
return null;
org.omg.CORBA.Contained[] c = contents( limit_type, exclude_inherited );
Hashtable found = new Hashtable();
for( int i = 0; i < c.length; i++)
if( c[i].name().equals( search_name ) )
found.put( c[i], "" );
if( levels_to_search > 1 || levels_to_search == -1 )
{
// search up to a specific depth or undefinitely
for( int i = 0; i < c.length; i++)
{
if( c[i] instanceof org.omg.CORBA.Container )
{
org.omg.CORBA.Contained[] tmp_seq =
((org.omg.CORBA.Container)c[i]).lookup_name( search_name,
levels_to_search-1,
limit_type,
exclude_inherited);
if( tmp_seq != null )
for( int j = 0; j < tmp_seq.length; j++)
found.put( tmp_seq[j], "" );
}
}
}
org.omg.CORBA.Contained[] result = new org.omg.CORBA.Contained[ found.size() ];
int idx = 0;
for( Enumeration e = found.keys(); e.hasMoreElements(); )
result[ idx++] = (org.omg.CORBA.Contained)e.nextElement();
return result;
}
public org.omg.CORBA.ContainerPackage.Description[] describe_contents(
org.omg.CORBA.DefinitionKind limit_type,
boolean exclude_inherited,
int max_returned_objs )
{
return null;
}
public org.omg.CORBA.Contained[] contents(org.omg.CORBA.DefinitionKind limit_type,
boolean exclude_inherited)
{
Hashtable limited = new Hashtable();
// analog constants, exceptions etc.
for( Enumeration e = contained.elements(); e.hasMoreElements(); )
{
org.omg.CORBA.Contained c = (org.omg.CORBA.Contained)e.nextElement();
if( limit_type == org.omg.CORBA.DefinitionKind.dk_all ||
limit_type == c.def_kind() )
{
limited.put( c, "" );
}
}
org.omg.CORBA.Contained[] c = new org.omg.CORBA.Contained[limited.size()];
int i;
Enumeration e;
for( e = limited.keys(), i=0 ; e.hasMoreElements(); i++ )
c[i] = (org.omg.CORBA.Contained)e.nextElement();
return c;
}
// from Contained
public org.omg.CORBA.ContainedPackage.Description describe()
{
if ( ! defined)
{
throw new INTF_REPOS ("Struct " + full_name + " not defined! ");
}
org.omg.CORBA.Any a = orb.create_any();
org.omg.CORBA.TypeDescription ed = describe_struct();
org.omg.CORBA.TypeDescriptionHelper.insert( a, ed );
return new org.omg.CORBA.ContainedPackage.Description(
org.omg.CORBA.DefinitionKind.dk_Struct, a);
}
public AbstractInterfaceDef create_abstract_interface (String id, String name, String version,
AbstractInterfaceDef[] baseInterfaces)
{
throw new NO_IMPLEMENT ("NYI");
}
public ExtValueDef create_ext_value (String id, String name, String version, boolean isCustom,
boolean isAbstract, ValueDef baseValue, boolean isTruncatable,
ValueDef[] abstractBaseValues, InterfaceDef[] supportedInterfaces,
ExtInitializer[] initializers)
{
throw new NO_IMPLEMENT ("NYI");
}
public LocalInterfaceDef create_local_interface (String id, String name, String version,
InterfaceDef[] baseInterfaces)
{
throw new NO_IMPLEMENT ("NYI");
}
}