package org.jacorb.idl; /* * 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.io.PrintWriter; import java.util.HashSet; import java.util.Set; import java.util.logging.Level; /** * @author Gerald Brose */ public class ValueBoxDecl extends Value { private boolean written = false; private boolean parsed = false; TypeSpec typeSpec; public ValueBoxDecl(int num) { super(num); pack_name = ""; } public Object clone() { return null; } public TypeDeclaration declaration() { return this; } public String typeName() { if (typeName == null) { setPrintPhaseNames(); } if (typeSpec.typeSpec() instanceof BaseType) { return typeName; } else { return unwindTypedefs(typeSpec).typeName(); } } public String boxTypeName() { if (typeName == null) setPrintPhaseNames(); return typeName; } public boolean basic() { return false; } public void set_included(boolean i) { included = i; } public void setPackage(String s) { s = parser.pack_replace(s); if (pack_name.length() > 0) pack_name = s + "." + pack_name; else pack_name = s; typeSpec.setPackage(s); } public void setEnclosingSymbol(IdlSymbol s) { if (enclosing_symbol != null && enclosing_symbol != s) { parser.logger.log(Level.SEVERE, "was " + enclosing_symbol.getClass().getName() + " now: " + s.getClass().getName()); throw new RuntimeException("Compiler Error: trying to reassign container for " + name); } enclosing_symbol = s; } public String toString() { return typeName(); } public void parse() { if (parsed) throw new RuntimeException("Compiler error: Value box already parsed!"); escapeName(); typeSpec.parse(); try { ConstrTypeSpec ctspec = new ConstrTypeSpec(new_num()); ctspec.c_type_spec = this; NameTable.define(full_name(), IDLTypes.TYPE); TypeMap.typedef(full_name(), ctspec); } catch (NameAlreadyDefined nad) { parser.error("Value box " + typeName() + " already defined", token); } parsed = true; } public String className() { String fullName = typeName(); if (fullName.indexOf('.') > 0) { return fullName.substring(fullName.lastIndexOf('.') + 1); } else { return fullName; } } public String printReadExpression(String streamname) { return "(" + typeName() + ")((org.omg.CORBA_2_3.portable.InputStream)" + streamname + ").read_value (new " + helperName() + "())"; } public String printWriteStatement(String var_name, String streamname) { return "((org.omg.CORBA_2_3.portable.OutputStream)" + streamname + ").write_value (" + var_name + ", new " + helperName() + "());"; } public String holderName() { return boxTypeName() + "Holder"; } public String helperName() { return boxTypeName() + "Helper"; } /** * @return a string for an expression of type TypeCode that * describes this type * */ public String getTypeCodeExpression(Set knownTypes) { if (knownTypes.contains(this)) { return this.getRecursiveTypeCodeExpression(); } else { knownTypes.add(this); StringBuffer sb = new StringBuffer(); String className = boxTypeName(); if (className.indexOf('.') > 0) className = className.substring(className.lastIndexOf('.') + 1); sb.append("org.omg.CORBA.ORB.init().create_value_box_tc(" + helperName() + ".id(),\"" + className + "\"," + typeSpec.typeSpec().getTypeCodeExpression(knownTypes) + ")"); return sb.toString(); } } public String getTypeCodeExpression() { return this.getTypeCodeExpression(new HashSet()); } private void printHolderClass(String className, PrintWriter ps) { if (!pack_name.equals("")) { ps.println("package " + pack_name + ";"); } ps.println("public" + parser.getFinalString() + " class " + className + "Holder"); ps.println("\timplements org.omg.CORBA.portable.Streamable"); ps.println("{"); ps.println("\tpublic " + typeName() + " value;" + Environment.NL); ps.println("\tpublic " + className + "Holder ()"); ps.println("\t{"); ps.println("\t}"); ps.println("\tpublic " + className + "Holder (final " + typeName() + " initial)"); ps.println("\t{"); ps.println("\t\tvalue = initial;"); ps.println("\t}"); ps.println("\tpublic org.omg.CORBA.TypeCode _type ()"); ps.println("\t{"); ps.println("\t\treturn " + helperName() + ".type ();"); ps.println("\t}"); ps.println("\tpublic void _read (final org.omg.CORBA.portable.InputStream _in)"); ps.println("\t{"); ps.println("\t\tvalue = " + helperName() + ".read (_in);"); ps.println("\t}"); ps.println("\tpublic void _write (final org.omg.CORBA.portable.OutputStream _out)"); ps.println("\t{"); ps.println("\t\t" + helperName() + ".write (_out,value);"); ps.println("\t}"); ps.println("}"); } private void printHelperClass(String className, PrintWriter ps) { if (!pack_name.equals("")) { ps.println("package " + pack_name + ";"); } ps.println("public" + parser.getFinalString() + " class " + className + "Helper"); ps.println("\timplements org.omg.CORBA.portable.BoxedValueHelper"); ps.println("{"); ps.println("\tprivate static org.omg.CORBA.TypeCode _type = " + getTypeCodeExpression() + ";"); String type = typeName(); ps.println( "\tpublic static org.omg.CORBA.TypeCode type()" ); ps.println( "\t{" ); ps.println( "\t\treturn _type;" ); ps.println( "\t}" ); ps.println(); ps.println( "\tpublic static void insert (final org.omg.CORBA.Any any, final " + type + " s)" ); ps.println( "\t{" ); ps.println( "\t\tany.insert_Value(s, type());" ); ps.println( "\t}" + Environment.NL ); ps.println( "\tpublic static " + type + " extract (final org.omg.CORBA.Any any)" ); ps.println( "\t{" ); ps.println( "\t\treturn (" + type + ") any.extract_Value();" ); ps.println( "\t}" + Environment.NL ); printIdMethod(ps); // inherited from IdlSymbol /* read */ ps.println("\tpublic static " + type + " read (final org.omg.CORBA.portable.InputStream in)"); ps.println("\t{"); if (typeSpec.typeSpec() instanceof BaseType) { ps.println("\t\t" + type + " result = new " + type + "(" + typeSpec.typeSpec().printReadExpression("in") + ");"); } else { ps.println("\t\t" + type + " result;"); ps.println("\t\t" + typeSpec.typeSpec().printReadStatement("result", "in")); } ps.println("\t\treturn result;"); ps.println("\t}"); /* write */ ps.println("\tpublic static void write (final org.omg.CORBA.portable.OutputStream out, final " + type + " s)"); ps.println("\t{"); if (typeSpec.typeSpec() instanceof BaseType) { ps.println("\t\t" + typeSpec.typeSpec().printWriteStatement("s.value", "out")); } else ps.println("\t\t" + typeSpec.typeSpec().printWriteStatement("s", "out")); ps.println("\t}"); ps.println("\tpublic java.io.Serializable read_value (final org.omg.CORBA.portable.InputStream is)"); ps.println("\t{"); ps.println("\t\treturn " + helperName() + ".read (is);"); ps.println("\t}"); ps.println("\tpublic void write_value (final org.omg.CORBA.portable.OutputStream os, final java.io.Serializable value)"); ps.println("\t{"); ps.println("\t\t" + helperName() + ".write (os, (" + type + ")value);"); ps.println("\t}"); ps.println("\tpublic java.lang.String get_id()"); ps.println("\t{"); ps.println("\t\treturn " + helperName() + ".id();"); ps.println("\t}"); ps.println("}"); } private void printValueClass(String className, PrintWriter ps) { if (!pack_name.equals("")) { ps.println("package " + pack_name + ";"); } ps.println("public class " + className); ps.println("\timplements org.omg.CORBA.portable.ValueBase"); ps.println("{"); printSerialVersionUID(ps); ps.println("\tpublic " + typeSpec.typeName() + " value;"); ps.println("\tprivate static String[] _ids = { " + className + "Helper.id() };"); ps.println("\tpublic " + className + "(" + typeSpec.typeName() + " initial)"); ps.println("\t{"); ps.println("\t\tvalue = initial;"); ps.println("\t}"); ps.println("\tpublic String[] _truncatable_ids()"); ps.println("\t{"); ps.println("\t\treturn _ids;"); ps.println("\t}"); ps.println("}"); } /** generate required classes */ public void print(PrintWriter ps) { setPrintPhaseNames(); // no code generation for included definitions if (included && !generateIncluded()) return; // only write once if (!written) { try { String className = boxTypeName(); if (className.indexOf('.') > 0) className = className.substring(className.lastIndexOf('.') + 1); String path = parser.out_dir + fileSeparator + pack_name.replace('.', fileSeparator); File dir = new File(path); if (!dir.exists()) { if (!dir.mkdirs()) { org.jacorb.idl.parser.fatal_error("Unable to create " + path, null); } } // print the mapped java class PrintWriter decl_ps; String fname = className + ".java"; File f = new File(dir, fname); if (typeSpec.typeSpec() instanceof BaseType) { if (GlobalInputStream.isMoreRecentThan(f)) { decl_ps = new PrintWriter(new java.io.FileWriter(f)); printValueClass(className, decl_ps); decl_ps.close(); } } // print the holder class */ fname = className + "Holder.java"; f = new File(dir, fname); if (GlobalInputStream.isMoreRecentThan(f)) { decl_ps = new PrintWriter(new java.io.FileWriter(f)); printHolderClass(className, decl_ps); decl_ps.close(); } // print the helper class fname = className + "Helper.java"; f = new File(dir, fname); if (GlobalInputStream.isMoreRecentThan(f)) { decl_ps = new PrintWriter(new java.io.FileWriter(f)); printHelperClass(className, decl_ps); decl_ps.close(); } written = true; } catch (java.io.IOException i) { throw new RuntimeException("File IO error" + i); } } } public void printInsertIntoAny(PrintWriter ps, String anyname, String varname) { ps.println("\t\t" + anyname + ".type(" + getTypeCodeExpression() +");"); ps.println("\t\t" + helperName() + ".write(" + anyname + ".create_output_stream()," + varname + ");"); } public void printExtractResult(PrintWriter ps, String resultname, String anyname, String resulttype) { ps.println("\t\t" + resultname + " = (" + resulttype + ")" + anyname + ".extract_Value();"); } public void accept(IDLTreeVisitor visitor) { visitor.visitValue(this); } private TypeSpec unwindTypedefs(TypeSpec typedef) { TypeSpec spec = typedef.typeSpec(); TypeSpec typeSpec2 = spec.typeSpec(); if (typeSpec2 instanceof ScopedName) { ScopedName scopedName = (ScopedName) typeSpec2; TypeSpec resolvedTSpec = scopedName.resolvedTypeSpec(); //unwind any typedefs while (resolvedTSpec instanceof AliasTypeSpec ) { resolvedTSpec = ((AliasTypeSpec)resolvedTSpec).originalType(); } return resolvedTSpec; } return typedef; } }