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, Cambrigde, MA 02139, USA. */ import java.io.FileOutputStream; import java.io.PrintWriter; import java.net.URL; import java.net.URLClassLoader; import java.util.StringTokenizer; import java.util.Vector; import org.jacorb.config.Configurable; import org.jacorb.config.Configuration; import org.jacorb.config.ConfigurationException; import org.omg.CORBA.AbstractInterfaceDef; import org.jacorb.config.JacORBConfiguration; import org.omg.CORBA.ExtInitializer; import org.omg.CORBA.ExtValueDef; import org.omg.CORBA.InterfaceDef; import org.omg.CORBA.LocalInterfaceDef; import org.omg.CORBA.NO_IMPLEMENT; import org.slf4j.Logger; import org.jacorb.config.Configurable; import org.jacorb.config.Configuration; import org.jacorb.config.ConfigurationException; import org.omg.CORBA.ORB; import org.omg.CORBA.Policy; import org.omg.CORBA.Repository; import org.omg.CORBA.RepositoryHelper; import org.omg.CORBA.RepositoryPOATie; import org.omg.CORBA.ValueDef; import org.omg.PortableServer.IdAssignmentPolicyValue; import org.omg.PortableServer.LifespanPolicyValue; import org.omg.PortableServer.POA; import org.omg.PortableServer.POAHelper; import org.omg.PortableServer.Servant; import org.slf4j.Logger; /** * The Interface Repository. * <p> * This class represents the repository itself as * well as the executable server. * <p> * Methods from the "write" interface to the IR * are not supported. * <p> * * @author Gerald Brose */ public class RepositoryImpl extends IRObject implements org.omg.CORBA.RepositoryOperations, Configurable { private Container[] containers ; private Container delegate ; private POA poa; /** the configuration object for this IR instance */ private org.jacorb.config.Configuration configuration = null; /** the IR logger instance */ private Logger logger = null; private boolean patchPragmaPrefix; /** * constructor to launch a repository with the contents of <tt>classpath</tt> * * @param classpath a classpath string made up of directories separated by ":" */ public RepositoryImpl( String classpath, String outfile, URLClassLoader loader, ORB orb) throws Exception { def_kind = org.omg.CORBA.DefinitionKind.dk_Repository; name = "Repository"; // parse classpath and create a top-level container for // each directory in the path StringTokenizer strtok = new StringTokenizer( classpath , java.io.File.pathSeparator ); String [] paths = new String [ strtok.countTokens() ]; containers = new Container[ paths.length ]; this.configure(JacORBConfiguration.getConfiguration (null,orb,false)); // need a regular SYSTEM_ID poa for IfR operation poa = POAHelper.narrow(orb.resolve_initial_references("RootPOA")); //create necessary policies Policy[] policies = new Policy[]{ poa.create_lifespan_policy(LifespanPolicyValue.PERSISTENT), poa.create_id_assignment_policy(IdAssignmentPolicyValue.USER_ID)}; //create persistent POA for IfR object POA ifrPOA = poa.create_POA( "InterfaceRepositoryPOA", poa.the_POAManager(), policies ); //destroy policies for (int i=0; i<policies.length; i++) { policies[i].destroy(); } Servant servant = new RepositoryPOATie( this ); ifrPOA.activate_object_with_id("IfR".getBytes(), servant); Repository myRef = RepositoryHelper.narrow( ifrPOA.servant_to_reference( servant ) ); for( int i = 0; strtok.hasMoreTokens(); i++ ) { paths[i] = strtok.nextToken(); if (this.logger.isDebugEnabled()) { logger.debug("found path: " + paths[i]); } containers[i] = new Container( this, paths[i], null, loader, poa, logger ); } // dummy delegate = containers[0]; PrintWriter out = new PrintWriter( new FileOutputStream( outfile ), true); out.println( orb.object_to_string( myRef ) ); setReference( myRef ); out.close(); ifrPOA.the_POAManager().activate(); poa.the_POAManager().activate(); if (this.logger.isInfoEnabled()) { URL urls[] = loader.getURLs(); StringBuffer sb = new StringBuffer("IR configured for class path: "); for( int i = 0; i < urls.length; i++ ) { sb.append( urls[i].toString() ).append("\n"); } logger.info(sb.toString()); } } public void configure(Configuration myConfiguration) throws ConfigurationException { this.configuration = (org.jacorb.config.Configuration)myConfiguration; this.logger = configuration.getLogger("org.jacorb.ir"); patchPragmaPrefix = configuration.getAttributeAsBoolean("jacorb.ir.patch_pragma_prefix", false); } // Repository private String idToScopedName(String id) { return idToScopedName(id, patchPragmaPrefix); } /** * convert a repository ID to a scoped name * @param id a string in Repository ID format, e.g. "IDL:myModule/MyInterface:1.0" * @return a scoped name, e.g. "::myModule::MyInterface", or null * if the id argument does not begin with "IDL:" */ public static String idToScopedName( String id, boolean patchPrefix) { String scoped = ""; if( !id.startsWith("IDL:") || !id.endsWith( ":1.0")) { return null; } // strip "IDL:" and ":1.0") String base = id.substring( id.indexOf(':')+1, id.lastIndexOf(':')).replace( fileSeparator, '/' ); if( base.startsWith( "omg.org") ) { base = "org/omg" + base.substring( 7 ); } if (patchPrefix) { int firstSeparator = base.indexOf('/'); if (firstSeparator >= 0) { base = base.substring(0, firstSeparator).replace('.', '/') + "/" + base.substring(firstSeparator + 1); } } StringTokenizer strtok = new StringTokenizer( base, "/" ); for( int i = 0; strtok.hasMoreTokens(); i++ ) { scoped = scoped + "::" + strtok.nextToken(); } return scoped; } /** * lookup a repository ID * @param search_id a string in Repository ID format, * e.g. "IDL:myModule/MyInterface:1.0" * @return a reference to the object or null, if not found */ public org.omg.CORBA.Contained lookup_id( String search_id ) { if (this.logger.isDebugEnabled()) { this.logger.debug("IR lookup_id: " + search_id ); } String name = idToScopedName( search_id ); if( name == null ) { return null; } return lookup( name ); } public org.omg.CORBA.PrimitiveDef get_primitive(org.omg.CORBA.PrimitiveKind kind) { try { return org.omg.CORBA.PrimitiveDefHelper.narrow( poa.servant_to_reference( new org.omg.CORBA.PrimitiveDefPOATie( new PrimitiveDef( kind.value() )))); } catch( Exception e ) { logger.error("unexpected exception", e); return null; } } /** * not supported */ public org.omg.CORBA.StringDef create_string(int bound) { return null; } /** * not supported */ public org.omg.CORBA.WstringDef create_wstring(int bound) { return null; } /** * not supported */ public org.omg.CORBA.FixedDef create_fixed(short digits, short scale) { return null; } /** * not supported */ public org.omg.CORBA.SequenceDef create_sequence(int bound, org.omg.CORBA.IDLType element_type) { return null; } /** * not supported */ public org.omg.CORBA.ArrayDef create_array(int length, org.omg.CORBA.IDLType element_type) { return null; } public org.omg.CORBA.TypeCode get_canonical_typecode(org.omg.CORBA.TypeCode tc) { return null; } // container /** * lookup a scoped name in the repository * * @param name the name to look for * @return a reference to the item with the specified name * or null, if not found */ public org.omg.CORBA.Contained lookup( String name ) { if (this.logger.isDebugEnabled()) { this.logger.debug("IR lookup : " + name ); } org.omg.CORBA.Contained result = null; for( int i = 0; i < containers.length; i++ ) { result = containers[i].lookup( name ); if( result != null ) break; } return result; } /** * lookup a simple name in the repository * (neither scoped nor ID formatted) * * @param search_name the name to look for * @param levels_to_search if 1, search only this object, if -1, search * all containers contained in this repository, else search * until the specified depth is reached * @param limit_type limit the description to objects of this type * @param exclude_inherited exclude inherited items from the description * @return an array of items with the specified name */ public org.omg.CORBA.Contained[] lookup_name( String search_name, int levels_to_search, org.omg.CORBA.DefinitionKind limit_type, boolean exclude_inherited ) { if (this.logger.isDebugEnabled()) { this.logger.debug("IR lookup_name: " + search_name); } org.omg.CORBA.Contained[] result = null; Vector intermediate = new Vector(); for( int i = 0; i < containers.length; i++ ) { intermediate.addElement( containers[i].lookup_name( search_name, levels_to_search, limit_type, exclude_inherited )); } int size = 0; for( int i = 0; i < intermediate.size(); i++ ) { size += ((Object[])intermediate.elementAt(i)).length; } result = new org.omg.CORBA.Contained[size]; int start = 0; for( int i = 0; i < intermediate.size(); i++ ) { org.omg.CORBA.Contained[] src = (org.omg.CORBA.Contained[])intermediate.elementAt(i); System.arraycopy( src, 0, result, start, src.length ); start += src.length; } return result; } /** * list the contents of the repository * @param limit_type limit the description to objects of this type * @param exclude_inherited exclude inherited items from the description * @return an array of items contained in this repository */ public org.omg.CORBA.Contained[] contents(org.omg.CORBA.DefinitionKind limit_type, boolean exclude_inherited) { org.omg.CORBA.Contained[] result = null; Vector intermediate = new Vector(); for( int i = 0; i < containers.length; i++ ) { intermediate.addElement( containers[i].contents( limit_type, exclude_inherited )); } int size = 0; for( int i = 0; i < intermediate.size(); i++ ) { size += ((Object[])intermediate.elementAt(i)).length; } result = new org.omg.CORBA.Contained[size]; int start = 0; // assemble result array for( int i = 0; i < intermediate.size(); i++ ) { org.omg.CORBA.Contained[] src = (org.omg.CORBA.Contained[])intermediate.elementAt(i); System.arraycopy( src, 0, result, start, src.length ); start += src.length; } return result; } /** * describe the contents of the repository * @param limit_type limit the description to objects of this type * @param exclude_inherited exclude inherited items from the description * @param max_returned_objs return only so many items * @return an array of descriptions */ public org.omg.CORBA.ContainerPackage.Description[] describe_contents( org.omg.CORBA.DefinitionKind limit_type, boolean exclude_inherited, int max_returned_objs) { org.omg.CORBA.Contained[] c = contents( limit_type, exclude_inherited ); int size; if( max_returned_objs > c.length ) size = max_returned_objs; else size = c.length; org.omg.CORBA.ContainerPackage.Description[] result = new org.omg.CORBA.ContainerPackage.Description[size]; for( int i = 0; i < size; i++ ) { result[i] = new org.omg.CORBA.ContainerPackage.Description(); org.omg.CORBA.ContainedPackage.Description cd_descr = c[i].describe(); result[i].contained_object = c[i]; result[i].kind = cd_descr.kind; result[i].value = cd_descr.value; } return result; } void define() { // do nothing } public void loadContents() { if (this.logger.isInfoEnabled()) { this.logger.info("Repository loads contents..."); } for( int i = 0; i < containers.length; i++ ) { containers[i].loadContents(); } for( int i = 0; i < containers.length; i++ ) { containers[i].define(); } if (this.logger.isInfoEnabled()) { this.logger.info("Repository contents loaded"); } } public org.omg.CORBA.ModuleDef create_module( String id, String name, String version) { return delegate.create_module( id, name, version); } public org.omg.CORBA.ConstantDef create_constant( String id, String name, String version, org.omg.CORBA.IDLType type, org.omg.CORBA.Any value) { return delegate.create_constant( id, name, version, type, value); } public org.omg.CORBA.StructDef create_struct( String id, String name, String version, org.omg.CORBA.StructMember[] members) { return delegate.create_struct( id, name, version, members); } 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 delegate.create_union( id, name, version, discriminator_type, members); } public org.omg.CORBA.EnumDef create_enum( String id, String name, String version, String[] members) { return delegate.create_enum( id, name, version, members); } public org.omg.CORBA.AliasDef create_alias( String id, String name, String version, org.omg.CORBA.IDLType original_type) { return delegate.create_alias( id, name, version, original_type); } public org.omg.CORBA.ExceptionDef create_exception( String id, String name, String version, org.omg.CORBA.StructMember[] member ) { return delegate.create_exception(id, name, version, member); } /** * not supported */ public org.omg.CORBA.InterfaceDef create_interface(String id, String name, String version, org.omg.CORBA.InterfaceDef[] base_interfaces ) { return delegate.create_interface( id, name, version, base_interfaces); } /** * not supported */ public org.omg.CORBA.ValueBoxDef create_value_box(String id, String name, String version, org.omg.CORBA.IDLType type) { return delegate.create_value_box(id, name, version, type); } /** * not supported */ public org.omg.CORBA.ValueDef create_value( String id, String name, 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 delegate.create_value(id, name, version,is_custom, is_abstract, base_value, is_truncatable, abstract_base_values, supported_interfaces, initializers); } /** * not supported */ public org.omg.CORBA.NativeDef create_native(String id, String name, String version) { return delegate.create_native( id, name, version); } public void destroy() { delegate.destroy(); } 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"); } }