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.PrintStream;
import org.slf4j.Logger;
import org.jacorb.orb.TypeCode;
import org.omg.CORBA.INTERNAL;
import org.omg.DynamicAny.DynAnyFactory;
import org.omg.DynamicAny.DynEnum;
import org.omg.DynamicAny.DynEnumHelper;
import org.omg.CORBA.ORB;
/**
* This class prints IDL from IR-Descriptions to PrintStreams
*
* @author (c) Gerald Brose, FU Berlin 2000
*/
public class IdlWriter
{
private final PrintStream printStream;
private final org.omg.CORBA.Repository ir;
private final DynAnyFactory factory;
private final Logger logger;
private int indent = 0;
/**
* create a new IdlWriter for the default JacORB IR
* which writes to a specific PrintStream
*
* @param orb
* @param ps a PrintStream
* @param logger
*/
public IdlWriter( ORB orb, PrintStream ps, Logger logger )
{
printStream = ps;
this.logger = logger;
try
{
ir = org.omg.CORBA.RepositoryHelper.narrow(
orb.resolve_initial_references("InterfaceRepository"));
factory =
org.omg.DynamicAny.DynAnyFactoryHelper.narrow (orb.resolve_initial_references ("DynAnyFactory"));
}
catch( org.omg.CORBA.ORBPackage.InvalidName e )
{
throw new INTERNAL(e.toString());
}
if( ir == null )
{
logger.error("No IR configured! Exiting..");
System.exit(1);
}
}
public void close()
{
printStream.flush();
printStream.close();
}
private void indent(int indentation)
{
indent = indentation;
}
private void print( String s )
{
for( int i = 0; i < indent; i++ )
printStream.print(" ");
printStream.print(s);
}
/**
* print the IDL definition for a contained objec
*
* @param c the contained object
* @param indentation how many spaces to use for indentation
*/
public void printContained( org.omg.CORBA.Contained c,
int indentation )
{
org.omg.CORBA.ContainedPackage.Description descr = c.describe();
switch (descr.kind.value())
{
case org.omg.CORBA.DefinitionKind._dk_Module:
{
printModule( org.omg.CORBA.ModuleDescriptionHelper.extract( descr.value ),
indentation+3 );
break;
}
case org.omg.CORBA.DefinitionKind._dk_Interface:
{
org.omg.CORBA.InterfaceDef idef =
org.omg.CORBA.InterfaceDefHelper.narrow(
ir.lookup_id(
org.omg.CORBA.InterfaceDescriptionHelper.extract(descr.value).id ));
printInterface( idef,
indentation+3 );
break;
}
case org.omg.CORBA.DefinitionKind._dk_Attribute:
{
printAttribute( org.omg.CORBA.AttributeDescriptionHelper.extract( descr.value ),
indentation+3 );
break;
}
case org.omg.CORBA.DefinitionKind._dk_Operation:
{
printOperation( org.omg.CORBA.OperationDescriptionHelper.extract( descr.value ),
indentation+3 );
break;
}
case org.omg.CORBA.DefinitionKind._dk_Exception:
{
printException( org.omg.CORBA.ExceptionDescriptionHelper.extract( descr.value ),
indentation+3 );
break;
}
case org.omg.CORBA.DefinitionKind._dk_Constant:
{
printConstant( org.omg.CORBA.ConstantDescriptionHelper.extract( descr.value ),
indentation+3 );
break;
}
case org.omg.CORBA.DefinitionKind._dk_Struct:
{
printStruct( org.omg.CORBA.TypeDescriptionHelper.extract( descr.value ),
indentation+3 );
break;
}
case org.omg.CORBA.DefinitionKind._dk_Enum:
{
printEnum( org.omg.CORBA.TypeDescriptionHelper.extract( descr.value ),
indentation+3 );
break;
}
case org.omg.CORBA.DefinitionKind._dk_Union:
{
printUnion( org.omg.CORBA.TypeDescriptionHelper.extract( descr.value ),
indentation+3 );
break;
}
case org.omg.CORBA.DefinitionKind._dk_Alias:
{
printAlias( org.omg.CORBA.TypeDescriptionHelper.extract( descr.value ),
indentation+3 );
break;
}
}
}
/**
* print the IDL definition for a module
*
* @param mdes the module description
* @param indentation how many spaces to use for indentation
*/
public void printModule( org.omg.CORBA.ModuleDescription mdes,
int indentation )
{
indent( indentation );
org.omg.CORBA.ModuleDef mdef =
org.omg.CORBA.ModuleDefHelper.narrow( ir.lookup_id( mdes.id ));
print("module " + mdef.name() + "\n" );
print("{\n");
org.omg.CORBA.Contained[] contents =
mdef.contents( org.omg.CORBA.DefinitionKind.dk_all, true );
for( int x = 0; x < contents.length; x++){
printContained( contents[x], indentation );
}
indent( indentation );
print("};" + "\n\n");
}
/**
* print an IDL interface
*/
public void printInterface( org.omg.CORBA.InterfaceDef idef,
int indentation )
{
org.omg.CORBA.InterfaceDefPackage.FullInterfaceDescription idfid =
idef.describe_interface();
org.omg.CORBA.Contained[] contents =
idef.contents( org.omg.CORBA.DefinitionKind.dk_all, true );
indent( indentation );
StringBuffer inheritanceSb = new StringBuffer();
if( idfid.base_interfaces.length > 0 )
inheritanceSb.append(" : " + idfid.base_interfaces[0] );
for( int b = 1; b < idfid.base_interfaces.length; b++){
inheritanceSb.append(", " + idfid.base_interfaces[b]);
}
print("interface " + idfid.name + inheritanceSb.toString() + "\n");
print("{" + "\n");
for( int x = 0; x < contents.length; x++){
printContained( contents[x], indentation );
}
indent( indentation );
print("};" + "\n\n" );
}
/** print an IDL exception def
*/
public void printException( org.omg.CORBA.ExceptionDescription e,
int indentation )
{
org.omg.CORBA.ExceptionDef e_def =
org.omg.CORBA.ExceptionDefHelper.narrow( ir.lookup_id( e.id ));
if( e_def != null )
{
org.omg.CORBA.StructMember [] members = e_def.members();
indent( indentation );
print( "exception " + e.name + " {" + "\n" );
indent( indentation + 3 );
for( int i = 0; i< members.length; i++){
print( TypeCode.idlTypeName( members[i].type ) + " " + members[i].name +
";" + "\n" );
}
indent( indentation );
print( "};" + "\n\n" );
}
else
{
logger.error("Error, could not find exception " + e.id + " in IR ");
}
}
/** print an IDL struct def
*/
public void printStruct( org.omg.CORBA.TypeDescription t, int indentation )
{
org.omg.CORBA.StructDef s_def =
org.omg.CORBA.StructDefHelper.narrow(ir.lookup_id( t.id ));
if( s_def != null )
{
org.omg.CORBA.StructMember [] members = s_def.members();
org.omg.CORBA.Contained [] contents =
s_def.contents(org.omg.CORBA.DefinitionKind.dk_all, false);
indent( indentation );
print( "struct " + s_def.name() + " {" + "\n" );
indent( indentation + 3 );
for( int i = 0; i < members.length; i++)
{
print( TypeCode.idlTypeName( members[i].type ) + " " +
members[i].name + ";" + "\n" );
}
for( int i = 0; i< contents.length; i++)
{
printContained( contents[i], indentation );
}
indent( indentation );
print( "};" + "\n\n" );
}
else
{
logger.error("Error, could not find struct " + t.id + " in IR ");
}
}
/** print an IDL const
*/
public void printConstant( org.omg.CORBA.ConstantDescription c,
int indentation )
{
indent( indentation );
StringBuffer sb =
new StringBuffer ( "const " + TypeCode.idlTypeName( c.type )
+ " " + c.name + " = " );
switch ( c.type.kind().value() )
{
case org.omg.CORBA.TCKind._tk_string:
sb.append( "\"" + c.value.extract_string() + "\"" );
break;
case org.omg.CORBA.TCKind._tk_wstring:
sb.append( "\"" + c.value.extract_wstring() + "\"" );
break;
case org.omg.CORBA.TCKind._tk_boolean:
sb.append( c.value.extract_boolean() );
break;
case org.omg.CORBA.TCKind._tk_long:
sb.append( c.value.extract_long() );
break;
case org.omg.CORBA.TCKind._tk_ulong:
sb.append( c.value.extract_ulong() );
break;
case org.omg.CORBA.TCKind._tk_longlong:
sb.append( c.value.extract_longlong() );
break;
case org.omg.CORBA.TCKind._tk_ulonglong:
sb.append( c.value.extract_ulonglong() );
break;
case org.omg.CORBA.TCKind._tk_short:
sb.append( c.value.extract_short() );
break;
case org.omg.CORBA.TCKind._tk_ushort:
sb.append( c.value.extract_ushort() );
break;
case org.omg.CORBA.TCKind._tk_float:
sb.append( c.value.extract_float() );
break;
case org.omg.CORBA.TCKind._tk_octet:
sb.append( c.value.extract_octet() );
break;
case org.omg.CORBA.TCKind._tk_char:
sb.append( "\'" + c.value.extract_char() + "\'" );
break;
case org.omg.CORBA.TCKind._tk_wchar:
sb.append( "\'" + c.value.extract_wchar() + "\'" );
break;
case org.omg.CORBA.TCKind._tk_fixed:
sb.append( c.value.extract_fixed() );
break;
}
print( sb.toString()+";\n\n");
}
/** print an IDL attribute
*/
public void printAttribute( org.omg.CORBA.AttributeDescription a,
int indentation )
{
indent( indentation );
String mode = "";
if( a.mode.equals( org.omg.CORBA.AttributeMode.ATTR_READONLY ))
mode = "readonly ";
print( mode + "attribute " + TypeCode.idlTypeName(a.type)
+ " " + a.name + ";" + "\n" );
}
/** print an IDL Enum
*/
public void printEnum( org.omg.CORBA.TypeDescription t,
int indentation )
{
org.omg.CORBA.EnumDef e_def =
org.omg.CORBA.EnumDefHelper.narrow( ir.lookup_id( t.id ));
if( e_def != null )
{
String [] members = e_def.members();
indent( indentation );
StringBuffer vals = new StringBuffer();
if( members.length > 0 )
vals.append( members[0] );
for( int i = 1; i< members.length; i++){
vals.append( "," + members[i] );
}
print( "enum " + e_def.name() + " {" + vals + "};" + "\n\n" );
}
else
{
logger.error("Error, could not find enum " + t.id + " in IR ");
}
}
/** print an IDL Union
*/
public void printUnion( org.omg.CORBA.TypeDescription t,
int indentation )
{
org.omg.CORBA.UnionDef u_def =
org.omg.CORBA.UnionDefHelper.narrow( ir.lookup_id( t.id ));
if( u_def != null )
{
org.omg.CORBA.UnionMember [] members = u_def.members();
indent( indentation );
print( "union " + u_def.name() + " switch ( " +
TypeCode.idlTypeName(u_def.discriminator_type())
+ " )\n");
print("{\n" );
indent( indentation + 4 );
int def_idx = -1;
for( int i = 0; i < members.length; i++ )
{
if( members[i].label.type().kind() == org.omg.CORBA.TCKind.tk_octet &&
( members[i].label.extract_octet() == (byte)0 ))
{
def_idx = i;
}
else if( members[i].label.type().kind() == org.omg.CORBA.TCKind.tk_char )
{
print("case \'" + members[i].label.extract_char() + "\' : " +
TypeCode.idlTypeName(members[i].type) + " "
+ members[i].name + ";" + "\n");
}
else if( members[i].label.type().kind() == org.omg.CORBA.TCKind.tk_enum )
{
// int val = members[i].label.extract_long();
try
{
DynEnum dEnum =
DynEnumHelper.narrow(
factory.create_dyn_any( members[i].label ));
// print("case " + members[i].label.type().member_name(val) + " : " +
print("case " + dEnum.get_as_string() + " : " +
TypeCode.idlTypeName(members[i].type) + " " +
members[i].name + ";" + "\n");
}
catch( Exception bk )
{
logger.error("unexpected exception", bk);
}
}
else
print("case " + members[i].label.type() + " : " +
TypeCode.idlTypeName(members[i].type) + " " +
members[i].name + ";" + "\n");
}
if( def_idx != -1 )
{
print("default : " + TypeCode.idlTypeName(members[def_idx].type) + " " +
members[def_idx].name +";" + "\n" );
}
indent( indentation );
print( "};" + "\n\n");
}
else
{
logger.error("Error, could not find union " +
t.id + " in IR ");
}
}
/**
* print an IDL alias
*/
public void printAlias( org.omg.CORBA.TypeDescription t, int indentation )
{
org.omg.CORBA.AliasDef adef =
org.omg.CORBA.AliasDefHelper.narrow( ir.lookup_id( t.id ));
indent( indentation );
String originalTypeName = TypeCode.idlTypeName( adef.original_type_def().type());
print("typedef " + originalTypeName +
" " + adef.name() + ";\n\n");
}
/**
* print an IDL operation
*/
public void printOperation(org.omg.CORBA.OperationDescription op,
int indentation )
{
indent( indentation );
String mode = "";
if( op.mode.equals(org.omg.CORBA.OperationMode.OP_ONEWAY ))
mode = "oneway ";
print( mode + TypeCode.idlTypeName(op.result) + " " + op.name + "(");
indent(0);
for( int i = 0; i < op.parameters.length-1; i++){
printParameter(op.parameters[i], ",");
}
if( op.parameters.length > 0 )
printParameter(op.parameters[op.parameters.length -1], "");
print(")");
if( op.exceptions.length > 0 ){
print(" raises (");
print( TypeCode.idlTypeName(op.exceptions[0].type ) );
for( int i = 1; i < op.exceptions.length; i++){
print( TypeCode.idlTypeName(op.exceptions[0].type ) + ",");
}
print(")");
}
print( ";" + "\n" );
indent( indentation );
}
public void printParameter( org.omg.CORBA.ParameterDescription p,
String separator )
{
if( p.mode.equals( org.omg.CORBA.ParameterMode.PARAM_OUT) )
print("out ");
else if ( p.mode.equals( org.omg.CORBA.ParameterMode.PARAM_INOUT ))
print("inout ");
else
print("in ");
print( TypeCode.idlTypeName(p.type) + " " + p.name );
print( separator );
}
}