blob: 664fba93932b76cffaceec81f003ec5cbd1bf519 [file] [log] [blame]
/*
* Copyright (c) 1999, 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* COMPONENT_NAME: idl.toJava
*
* ORIGINS: 27
*
* Licensed Materials - Property of IBM
* 5639-D57 (C) COPYRIGHT International Business Machines Corp. 1997, 1999
* RMI-IIOP v1.0
*
*/
package com.sun.tools.corba.se.idl.toJavaPortable;
// NOTES:
// -F46082.51<daz> Remove -stateful feature.
// -D57118 <klr> Fix "narrow" in helper for abstract interface
// -D58889 <klr> re-Fix "narrow" in helper for abstract interface
// -D59383 <klr> 'get_class' in value helper returns value class, not helper.
// -D59413 <klr> Remove Helper interface references for non-value types.
// -D59435 <klr> Remove read_Object, write_Object completely.
// -D59418 <klr> Move read_Value, write_Value to generator's helperRead.
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.Vector;
import com.sun.tools.corba.se.idl.GenFileStream;
import com.sun.tools.corba.se.idl.InterfaceEntry;
import com.sun.tools.corba.se.idl.MethodEntry;
import com.sun.tools.corba.se.idl.ParameterEntry;
import com.sun.tools.corba.se.idl.SymtabEntry;
import com.sun.tools.corba.se.idl.ValueEntry;
import com.sun.tools.corba.se.idl.ValueBoxEntry;
import com.sun.tools.corba.se.idl.TypedefEntry;
import com.sun.tools.corba.se.idl.InterfaceState;
import com.sun.tools.corba.se.idl.PrimitiveEntry;
import com.sun.tools.corba.se.idl.StructEntry;
/**
*
**/
public class Helper implements AuxGen
{
/**
* Public zero-argument constructor.
**/
public Helper ()
{
} // ctor
/**
* Generate the helper class. Provides general algorithm
* for auxiliary binding generation:
*
* 1.) Initialize symbol table and symbol table entry members,
* common to all generators.
* 2.) Initialize members unique to this generator.
* 3.) Open print stream
* 4.) Write class heading: package, prologue, class statement, open curly
* 5.) Write class body: member data and methods
* 6.) Write class closing: close curly
* 7.) Close the print stream
**/
public void generate (java.util.Hashtable symbolTable, com.sun.tools.corba.se.idl.SymtabEntry entry)
{
this.symbolTable = symbolTable;
this.entry = entry;
init ();
openStream ();
if (stream == null)
return;
writeHeading ();
writeBody ();
writeClosing ();
closeStream ();
} // generate
/**
* Initialize variables unique to this generator.
**/
protected void init ()
{
helperClass = entry.name () + "Helper";
if (entry instanceof ValueBoxEntry)
{
ValueBoxEntry v = (ValueBoxEntry) entry;
TypedefEntry member = ((InterfaceState) v.state ().elementAt (0)).entry;
SymtabEntry mType = member.type ();
if (mType instanceof PrimitiveEntry)
helperType = Util.javaName (entry);
else
helperType = Util.javaName (mType);
}
else
helperType = Util.javaName (entry);
} // init
/**
* Open the print stream for subsequent output.
**/
protected void openStream ()
{
stream = Util.stream (entry, "Helper.java");
} // openStream
/**
* Generate the heading, including package, imports, class statements,
* and open curly.
**/
protected void writeHeading ()
{
Util.writePackage (stream, entry, Util.HelperFile);
Util.writeProlog (stream, stream.name ());
// Transfer comment to target <30jul1997daz>.
if (entry.comment () != null)
entry.comment ().generate ("", stream);
stream.print ("public final class " + helperClass);
if (entry instanceof ValueEntry)
stream.println (" implements org.omg.CORBA.portable.ValueHelper");
else
stream.println ();
stream.println ('{');
}
/**
* Generate members of this class.
**/
protected void writeBody ()
{
writeInstVars ();
writeCtors ();
writeInsert ();
writeExtract ();
writeType ();
writeID ();
writeRead ();
writeWrite ();
if (entry instanceof InterfaceEntry && !(entry instanceof ValueEntry)) {
writeNarrow ();
writeUncheckedNarrow ();
}
writeHelperInterface ();
if (entry instanceof ValueEntry)
writeValueHelperInterface ();
} // writeBody
/**
* Generate members of the Helper interface.
**/
protected void writeHelperInterface ()
{
} // writeHelperInterface
/**
* Generate members of the ValueHelper interface.
**/
protected void writeValueHelperInterface ()
{
writeGetID (); // moved for <d59413>
writeGetType (); // moved for <d59413>
writeGetInstance (); // not in ValueHelper interface
writeGetClass ();
writeGetSafeBaseIds ();
} // writeHelperInterface
/**
* Generate the closing statements.
**/
protected void writeClosing ()
{
stream.println ('}');
}
/**
* Write the stream to file by closing the print stream.
**/
protected void closeStream ()
{
stream.close ();
}
/**
* Generate the instance variables.
**/
protected void writeInstVars ()
{
stream.println (" private static String _id = \"" + Util.stripLeadingUnderscoresFromID (entry.repositoryID ().ID ()) + "\";");
if (entry instanceof ValueEntry)
{
stream.println ();
stream.println (" private static " + helperClass + " helper = new " + helperClass + " ();");
stream.println ();
stream.println (" private static String[] _truncatable_ids = {");
stream.print (" _id");
// Any safe ValueEntry must have a concete value parent.
// The topmost parent cannot be safe since it doesn't have
// a concrete parent.
ValueEntry child = (ValueEntry) entry;
while (child.isSafe ())
{
stream.println(",");
ValueEntry parent = (ValueEntry)child.derivedFrom ().elementAt (0);
stream.print(" \"" + Util.stripLeadingUnderscoresFromID (parent.repositoryID ().ID ()) + "\"");
child = parent;
}
stream.println(" };");
}
stream.println ();
} // writeInstVars
/**
* Generate the constructors.
**/
protected void writeCtors ()
{
stream.println (" public " + helperClass + "()");
stream.println (" {");
stream.println (" }");
stream.println ();
} // writeCtors
/**
* Generate the insert method.
**/
protected void writeInsert ()
{
stream.println (" public static void insert (org.omg.CORBA.Any a, " + helperType + " that)");
stream.println (" {");
stream.println (" org.omg.CORBA.portable.OutputStream out = a.create_output_stream ();");
stream.println (" a.type (type ());");
stream.println (" write (out, that);");
stream.println (" a.read_value (out.create_input_stream (), type ());");
stream.println (" }");
stream.println ();
} // writeInsert
/**
* Generate the extract method.
**/
protected void writeExtract ()
{
stream.println (" public static " + helperType + " extract (org.omg.CORBA.Any a)");
stream.println (" {");
stream.println (" return read (a.create_input_stream ());");
stream.println (" }");
stream.println ();
} // writeExtract
/**
* Generate the typecode variable and type method.
**/
protected void writeType ()
{
boolean canRecurse = entry instanceof ValueEntry
|| entry instanceof ValueBoxEntry
|| entry instanceof StructEntry;
stream.println (" private static org.omg.CORBA.TypeCode __typeCode = null;");
if (canRecurse)
stream.println (" private static boolean __active = false;");
stream.println (" synchronized public static org.omg.CORBA.TypeCode type ()");
stream.println (" {");
stream.println (" if (__typeCode == null)");
stream.println (" {");
if (canRecurse) {
stream.println (" synchronized (org.omg.CORBA.TypeCode.class)");
stream.println (" {");
stream.println (" if (__typeCode == null)");
stream.println (" {");
stream.println (" if (__active)");
stream.println (" {");
stream.println (" return org.omg.CORBA.ORB.init().create_recursive_tc ( _id );");
stream.println (" }");
stream.println (" __active = true;");
((JavaGenerator)entry.generator ()).helperType (0, " ", new TCOffsets (), "__typeCode", entry, stream);
}
else
((JavaGenerator)entry.generator ()).helperType (0, " ", new TCOffsets (), "__typeCode", entry, stream);
// Generate body of type() method
if (canRecurse) {
stream.println (" __active = false;");
stream.println (" }");
stream.println (" }");
}
stream.println (" }");
stream.println (" return __typeCode;");
stream.println (" }");
stream.println ();
} // writeType
/**
* Generate the ID method.
**/
protected void writeID ()
{
stream.println (" public static String id ()");
stream.println (" {");
stream.println (" return _id;");
stream.println (" }");
stream.println ();
} // writeID
/**
* Generate the read method.
**/
protected void writeRead ()
{
boolean isLocalInterface = false;
if (entry instanceof InterfaceEntry) {
InterfaceEntry ie = (InterfaceEntry) entry;
// for #pragma sun_local or sun_localservant, or actual local
// local interface, set the flag by checking on both
isLocalInterface = ie.isLocal() | ie.isLocalServant();
}
stream.println (" public static " + helperType + " read (org.omg.CORBA.portable.InputStream istream)");
stream.println (" {");
if ( !isLocalInterface ) { // nonLocal Interface and other types
((JavaGenerator)entry.generator ()).helperRead (helperType, entry, stream);
} else { //Local interface should throw exception
stream.println (" throw new org.omg.CORBA.MARSHAL ();");
}
stream.println (" }");
stream.println ();
} // writeRead
/**
* Generate the write method.
**/
protected void writeWrite ()
{
boolean isLocalInterface = false;
if (entry instanceof InterfaceEntry) {
InterfaceEntry ie = (InterfaceEntry) entry;
// for #pragma sun_local or sun_localservant, or actual local
// local interface, set the flag by checking on both
isLocalInterface = ie.isLocal() | ie.isLocalServant();
}
stream.println (" public static void write (org.omg.CORBA.portable.OutputStream ostream, " + helperType + " value)");
stream.println (" {");
if ( !isLocalInterface ) { // nonLocal Interface and other types
((JavaGenerator)entry.generator ()).helperWrite (entry, stream);
} else { //Local interface should throw exception
stream.println (" throw new org.omg.CORBA.MARSHAL ();");
}
stream.println (" }");
stream.println ();
} // writeWrite
/**
* Generate the narrow method.
**/
protected void writeNarrow ()
{
writeRemoteNarrow ();
stream.println ();
}
/**
* Write the narrow() method for a remotable object.
**/
protected void writeRemoteNarrow ()
{
InterfaceEntry ie = (InterfaceEntry) entry;
// narrow for LocalObject interface
if (ie.isLocal ()) {
writeRemoteNarrowForLocal (false);
return;
}
// narrow for Abstract interface
if (ie.isAbstract ()) {
writeRemoteNarrowForAbstract (false);
return;
} else {
// Determine if the non-abstract interface has any abstract parents
for (int i = 0; i < ie.derivedFrom ().size (); i++) {
SymtabEntry parent = (SymtabEntry) ie.derivedFrom ().elementAt (i);
if (((InterfaceEntry) parent).isAbstract ()) {
writeRemoteNarrowForAbstract (true);
break;
}
}
}
stream.println (" public static " + helperType + " narrow (org.omg.CORBA.Object obj)");
stream.println (" {");
stream.println (" if (obj == null)");
stream.println (" return null;");
stream.println (" else if (obj instanceof " + helperType + ')');
stream.println (" return (" + helperType + ")obj;");
stream.println (" else if (!obj._is_a (id ()))");
stream.println (" throw new org.omg.CORBA.BAD_PARAM ();");
stream.println (" else");
stream.println (" {");
stream.println (" org.omg.CORBA.portable.Delegate delegate = ((org.omg.CORBA.portable.ObjectImpl)obj)._get_delegate ();");
String stubNameofEntry = stubName ((InterfaceEntry)entry);
stream.println (" " + stubNameofEntry + " stub = new " + stubNameofEntry + " ();");
stream.println (" stub._set_delegate(delegate);");
stream.println (" return stub;");
stream.println (" }");
stream.println (" }");
} // writeRemoteNarrow
/**
* Write the narrow() method for local interface.
**/
private void writeRemoteNarrowForLocal (boolean hasAbstractParent)
{
stream.println (" public static " + helperType + " narrow (org.omg.CORBA.Object obj)");
stream.println (" {");
stream.println (" if (obj == null)");
stream.println (" return null;");
stream.println (" else if (obj instanceof " + helperType + ')');
stream.println (" return (" + helperType + ")obj;");
stream.println (" else");
stream.println (" throw new org.omg.CORBA.BAD_PARAM ();");
stream.println (" }");
} // writeRemoteNarrowForLocal
/**
* Write the narrow() method for abstract interface.
**/
private void writeRemoteNarrowForAbstract (boolean hasAbstractParent)
{
stream.print (" public static " + helperType + " narrow (java.lang.Object obj)");
stream.println (" {");
stream.println (" if (obj == null)");
stream.println (" return null;");
if (hasAbstractParent)
{
stream.println (" else if (obj instanceof org.omg.CORBA.Object)");
stream.println (" return narrow ((org.omg.CORBA.Object) obj);");
}
else
{
stream.println (" else if (obj instanceof " + helperType + ')');
stream.println (" return (" + helperType + ")obj;");
}
// If hasAbstractParent is false, then THIS entry must be abstract.
// This method is also called in case THIS entry is not abstract, but
// there is an abstract parent. If this entry is not abstract,
// it can never narrow to a CORBA object reference.
if (!hasAbstractParent) { // <d58889>
String stubNameofEntry = stubName ((InterfaceEntry)entry);
stream.println (" else if ((obj instanceof org.omg.CORBA.portable.ObjectImpl) &&");
stream.println (" (((org.omg.CORBA.Object)obj)._is_a (id ()))) {");
stream.println (" org.omg.CORBA.portable.ObjectImpl impl = (org.omg.CORBA.portable.ObjectImpl)obj ;" ) ;
stream.println (" org.omg.CORBA.portable.Delegate delegate = impl._get_delegate() ;" ) ;
stream.println (" " + stubNameofEntry + " stub = new " + stubNameofEntry + " ();");
stream.println (" stub._set_delegate(delegate);");
stream.println (" return stub;" ) ;
stream.println (" }" ) ;
};
// end <d57118 - check for remotable - klr>
stream.println (" throw new org.omg.CORBA.BAD_PARAM ();");
stream.println (" }");
stream.println ();
} // writeRemoteNarrowForAbstract
/**
* Generate the unchecked narrow method.
**/
protected void writeUncheckedNarrow ()
{
writeUncheckedRemoteNarrow ();
stream.println ();
}
/**
* Write the unchecked narrow() method for a remotable object.
**/
protected void writeUncheckedRemoteNarrow ()
{
InterfaceEntry ie = (InterfaceEntry) entry;
// unchecked narrow for LocalObject interface
if (ie.isLocal ()) {
writeRemoteUncheckedNarrowForLocal (false);
return;
}
// unchecked narrow for Abstract interface
if (ie.isAbstract ()) {
writeRemoteUncheckedNarrowForAbstract (false);
return;
} else {
// Determine if the non-abstract interface has any abstract parents
for (int i = 0; i < ie.derivedFrom ().size (); i++) {
SymtabEntry parent = (SymtabEntry) ie.derivedFrom ().elementAt (i);
if (((InterfaceEntry) parent).isAbstract ()) {
writeRemoteUncheckedNarrowForAbstract (true);
break;
}
}
}
stream.println (" public static " + helperType + " unchecked_narrow (org.omg.CORBA.Object obj)");
stream.println (" {");
stream.println (" if (obj == null)");
stream.println (" return null;");
stream.println (" else if (obj instanceof " + helperType + ')');
stream.println (" return (" + helperType + ")obj;");
stream.println (" else");
stream.println (" {");
stream.println (" org.omg.CORBA.portable.Delegate delegate = ((org.omg.CORBA.portable.ObjectImpl)obj)._get_delegate ();");
String stubNameofEntry = stubName ((InterfaceEntry)entry);
stream.println (" " + stubNameofEntry + " stub = new " + stubNameofEntry + " ();");
stream.println (" stub._set_delegate(delegate);");
stream.println (" return stub;");
stream.println (" }");
stream.println (" }");
} // writeUncheckedRemoteNarrow
/**
* Write the unchecked narrow() method for local interface.
**/
private void writeRemoteUncheckedNarrowForLocal (boolean hasAbstractParent)
{
stream.println (" public static " + helperType + " unchecked_narrow (org.omg.CORBA.Object obj)");
stream.println (" {");
stream.println (" if (obj == null)");
stream.println (" return null;");
stream.println (" else if (obj instanceof " + helperType + ')');
stream.println (" return (" + helperType + ")obj;");
stream.println (" else");
stream.println (" throw new org.omg.CORBA.BAD_PARAM ();");
stream.println (" }");
} // writeRemoteUncheckedNarrowForLocal
/**
* Write the unchecked narrow() method for abstract interface.
**/
private void writeRemoteUncheckedNarrowForAbstract (boolean hasAbstractParent)
{
stream.print (" public static " + helperType + " unchecked_narrow (java.lang.Object obj)");
stream.println (" {");
stream.println (" if (obj == null)");
stream.println (" return null;");
if (hasAbstractParent)
{
stream.println (" else if (obj instanceof org.omg.CORBA.Object)");
stream.println (" return unchecked_narrow ((org.omg.CORBA.Object) obj);");
}
else
{
stream.println (" else if (obj instanceof " + helperType + ')');
stream.println (" return (" + helperType + ")obj;");
}
if (!hasAbstractParent) {
String stubNameofEntry = stubName ((InterfaceEntry)entry);
stream.println (" else if (obj instanceof org.omg.CORBA.portable.ObjectImpl) {");
stream.println (" org.omg.CORBA.portable.ObjectImpl impl = (org.omg.CORBA.portable.ObjectImpl)obj ;" ) ;
stream.println (" org.omg.CORBA.portable.Delegate delegate = impl._get_delegate() ;" ) ;
stream.println (" " + stubNameofEntry + " stub = new " + stubNameofEntry + " ();");
stream.println (" stub._set_delegate(delegate);");
stream.println (" return stub;" ) ;
stream.println (" }" ) ;
};
stream.println (" throw new org.omg.CORBA.BAD_PARAM ();");
stream.println (" }");
stream.println ();
} // writeRemoteUncheckedNarrowForAbstract
/**
* Generate the GetID method.
**/
protected void writeGetID ()
{
if ( !Util.IDLEntity (entry))
return;
stream.println (" public String get_id ()");
stream.println (" {");
stream.println (" return _id;");
stream.println (" }");
stream.println ();
} // writeGetID
/**
* Generate the GetType method.
**/
protected void writeGetType ()
{
if ( !Util.IDLEntity (entry))
return;
stream.println (" public org.omg.CORBA.TypeCode get_type ()");
stream.println (" {");
stream.println (" return type ();");
stream.println (" }");
stream.println ();
} // writeGetID
/**
* Generate the get_class method.
**/
protected void writeGetClass ()
{
stream.println (" public Class get_class ()");
stream.println (" {");
stream.println (" return " + helperType + ".class;"); //<d59383>
stream.println (" }");
stream.println ();
} // writeGetClass
/**
* Generate the get_instance method.
**/
protected void writeGetInstance ()
{
stream.println (" public static org.omg.CORBA.portable.ValueHelper get_instance ()");
stream.println (" {");
stream.println (" return helper;");
stream.println (" }");
stream.println ();
} // writeGetInstance
/**
* Generate the GetSafeBaseIds method.
**/
protected void writeGetSafeBaseIds ()
{
stream.println (" public String[] get_truncatable_base_ids ()");
stream.println (" {");
stream.println (" return _truncatable_ids;");
stream.println (" }");
stream.println ();
} // writeGetSafeBaseIds
/**
* Return the stub name for the interface entry.
**/
protected String stubName (InterfaceEntry entry)
{
String name;
if (entry.container ().name ().equals (""))
name = '_' + entry.name () + "Stub";
else
{
name = Util.containerFullName (entry.container ()) + "._" + entry.name () + "Stub";
}
return name.replace ('/', '.');
} // stubName
protected java.util.Hashtable symbolTable;
protected com.sun.tools.corba.se.idl.SymtabEntry entry;
protected GenFileStream stream;
// Unique to this generator
protected String helperClass;
protected String helperType;
} // class Helper