diff options
author | Andrew John Hughes <gnu_andrew@member.fsf.org> | 2006-03-02 22:46:57 +0000 |
---|---|---|
committer | Andrew John Hughes <gnu_andrew@member.fsf.org> | 2006-03-02 22:46:57 +0000 |
commit | d76b7d24ece83e165721fe80b3bb52ae13171820 (patch) | |
tree | d70ba4771c93319646ffff46d8534ac97d6ca924 | |
parent | 9feea8b823c069addfda8b43e0c14c7f46d5be19 (diff) | |
download | classpath-d76b7d24ece83e165721fe80b3bb52ae13171820.tar.gz |
2005-03-02 Andrew John Hughes <gnu_andrew@member.fsf.org>
* Merge tools directory from HEAD to generics branch.
37 files changed, 4260 insertions, 0 deletions
diff --git a/tools/.cvsignore b/tools/.cvsignore new file mode 100644 index 000000000..eaae7d326 --- /dev/null +++ b/tools/.cvsignore @@ -0,0 +1,3 @@ +Makefile.in +Makefile +tools.zip diff --git a/tools/Makefile.am b/tools/Makefile.am new file mode 100755 index 000000000..2983bf06a --- /dev/null +++ b/tools/Makefile.am @@ -0,0 +1,105 @@ +## Input file for automake to generate the Makefile.in used by configure + +# Setup the compiler to use the GNU Classpath library we just build +if FOUND_GCJX +JCOMPILER = $(GCJX) -bootclasspath '' -sourcepath '' -classpath $(top_builddir)/lib:. +else +if FOUND_ECJ +JCOMPILER = $(ECJ) -bootclasspath '$(top_builddir)/lib' -classpath . +else +error dunno how to setup the JCOMPILER and compile +endif +endif + +# All our example java source files +TOOLS_JAVA_FILES = $(srcdir)/gnu/classpath/tools/*.java $(srcdir)/gnu/classpath/tools/*/*.java $(srcdir)/gnu/classpath/tools/*/*/*.java + + +# The zip files with classes we want to produce. +TOOLS_ZIP = tools.zip + +# Extra objects that will not exist until configure-time +BUILT_SOURCES = $(TOOLS_ZIP) + +# The templates that must be included into the generated zip file. +GRMIC_TEMPLATES = $(srcdir)/gnu/classpath/tools/giop/grmic/templates/*.jav +RMIC_TEMPLATES = $(srcdir)/gnu/classpath/tools/rmi/rmic/templates/*.jav + +TOOLS_TEMPLATES = $(GRMIC_TEMPLATES) $(RMIC_TEMPLATES) + +# This covers the built-in help texts, both for giop and rmic subpackages. +GIOP_HELPS = $(srcdir)/gnu/classpath/tools/giop/*.txt +RMI_HELPS = $(srcdir)/gnu/classpath/tools/rmi/*.txt + +TOOLS_HELPS = $(GIOP_HELPS) $(RMI_HELPS) + +# The tool specific README files. +READMES = $(srcdir)/gnu/classpath/tools/giop/README + +# All the files we find "interesting" +ALL_TOOLS_FILES = $(TOOLS_JAVA_FILES) $(TOOLS_TEMPLATES) $(TOOLS_HELPS) $(READMES) + +# Some architecture independent data to be installed. +TOOLS_DATA = $(TOOLS_ZIP) + +# Where we want these data files installed. +TOOLSdir = $(pkgdatadir)/tools + +# Make sure all sources and icons are also installed so users can use them. +# (Be careful to strip off the srcdir part of the path when installing.) +install-data-local: + srcdir_cnt=`echo $(srcdir) | wc -c`; \ + for file in $(ALL_TOOLS_FILES); do \ + f=`echo $$file | cut -c$$srcdir_cnt-`; \ + fdir=`dirname $$f`; \ + if test ! -d $(DESTDIR)$(pkgdatadir)/tools/$$fdir; then \ + echo "$(mkinstalldirs) $(DESTDIR)$(pkgdatadir)/tools/$$fdir"; \ + $(mkinstalldirs) $(DESTDIR)$(pkgdatadir)/tools/$$fdir; \ + fi; \ + echo "$(INSTALL_DATA) $$file $(DESTDIR)$(pkgdatadir)/tools/$$f"; \ + $(INSTALL_DATA) $$file $(DESTDIR)$(pkgdatadir)/tools/$$f; \ + done + +uninstall-local: + srcdir_cnt=`echo $(srcdir) | wc -c`; \ + for file in $(ALL_TOOLS_FILES); do \ + f=`echo $$file | cut -c$$srcdir_cnt-`; \ + echo "rm -f $(DESTDIR)$(pkgdatadir)/tools/$$f"; \ + rm -f $(DESTDIR)$(pkgdatadir)/tools/$$f; \ + done + +# Make sure everything is included in the distribution. +EXTRA_DIST = Makefile.am +dist-hook: + srcdir_cnt=`echo $(srcdir) | wc -c`; \ + for file in $(ALL_TOOLS_FILES); do \ + f=`echo $$file | cut -c$$srcdir_cnt-`; \ + fdir=`dirname $$f`; \ + if test ! -d $(distdir)/$$fdir; then \ + echo "$(makeinstalldirs) $(distdir)/$$fdir"; \ + $(mkinstalldirs) $(distdir)/$$fdir; \ + fi; \ + echo "cp -p $$file $(distdir)/$$f"; \ + cp -p $$file $(distdir)/$$f; \ + done + +# To generate the example zip just depend on the sources and ignore the +# class files. Always regenerate all .class files and remove them immediatly. +# And copy the template files we use to the classes dir so they get also included. +$(TOOLS_ZIP): $(TOOLS_JAVA_FILES) + mkdir -p classes/gnu/classpath/tools/giop/grmic/templates + mkdir -p classes/gnu/classpath/tools/rmi/rmic/templates + cp $(RMIC_TEMPLATES) classes/gnu/classpath/tools/rmi/rmic/templates + cp $(GRMIC_TEMPLATES) classes/gnu/classpath/tools/giop/grmic/templates + cp $(RMI_HELPS) classes/gnu/classpath/tools/rmi/ + cp $(GIOP_HELPS) classes/gnu/classpath/tools/giop/ + $(JCOMPILER) -d classes $(TOOLS_JAVA_FILES) + (cd classes; \ + if test "$(ZIP)" != ""; then $(ZIP) -r ../$(TOOLS_ZIP) .; fi; \ + if test "$(FASTJAR)" != ""; then $(FASTJAR) cf ../$(TOOLS_ZIP) .; fi; \ + cd ..) + rm -rf classes + +# Zip file be gone! (and make sure the classes are gone too) +clean-local: + rm -rf $(TOOLS_ZIP) classes diff --git a/tools/gnu/classpath/tools/AbstractMethodGenerator.java b/tools/gnu/classpath/tools/AbstractMethodGenerator.java new file mode 100644 index 000000000..d82284988 --- /dev/null +++ b/tools/gnu/classpath/tools/AbstractMethodGenerator.java @@ -0,0 +1,53 @@ +/* AbstractMethodGenerator.java -- the abstract method generator + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.classpath.tools; + +public interface AbstractMethodGenerator +{ + /** + * Generate this method for the Stub (remote caller) class. + */ + String generateStubMethod(); + + /** + * Generate this method for the Tie (remote servant) class. + */ + String generateTieMethod(); + +} diff --git a/tools/gnu/classpath/tools/HelpPrinter.java b/tools/gnu/classpath/tools/HelpPrinter.java new file mode 100644 index 000000000..61a3e683b --- /dev/null +++ b/tools/gnu/classpath/tools/HelpPrinter.java @@ -0,0 +1,99 @@ +/* HelpPrinter -- help message printer + Copyright (C) 2006 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.classpath.tools; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +/** + * The shared class to print the help message and exit, when applicable. + * Support the --help key. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class HelpPrinter +{ + /** + * Check for the --help, -help and -? keys. If one is found, print help and + * exit the program. + * + * @param args the program arguments. + * @param helpResourcePath the path to the help resource, related to the + * HelpPrinter class. + */ + public static void checkHelpKey(String[] args, String helpResourcePath) + { + for (int i = 0; i < args.length; i++) + { + String a = args[i]; + if (a.equals("-?") || a.equalsIgnoreCase("-help") + || a.equalsIgnoreCase("--help")) + printHelpAndExit(helpResourcePath); + } + } + + /** + * Prints the help message and terminates. + * + * @param helpResourcePath the path to the help resource, related to the + * HelpPrinter class. + */ + public static void printHelpAndExit(String helpResourcePath) + { + InputStream in = HelpPrinter.class.getResourceAsStream(helpResourcePath); + BufferedReader r = new BufferedReader(new InputStreamReader(in)); + + try + { + String s; + while ((s = r.readLine()) != null) + { + System.out.println(s); + } + r.close(); + } + catch (IOException e) + { + System.err.print("Resource loading is broken:"); + e.printStackTrace(); + } + System.exit(0); + } +} diff --git a/tools/gnu/classpath/tools/giop/GRMIC.java b/tools/gnu/classpath/tools/giop/GRMIC.java new file mode 100644 index 000000000..16ff96f56 --- /dev/null +++ b/tools/gnu/classpath/tools/giop/GRMIC.java @@ -0,0 +1,200 @@ +/* GRMIC.java -- GIOP support for RMIC. + Copyright (C) 2006 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.classpath.tools.giop; + +import gnu.classpath.tools.HelpPrinter; +import gnu.classpath.tools.giop.grmic.GiopRmicCompiler; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +/** + * The main class of the GIOP compiler to generate stubs and ties for + * javax.rmi package. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class GRMIC +{ + /** + * The version of the compiler. + */ + public static String VERSION = "0.0 alpha pre"; + + /** + * The GRMIC compiler methods + * + * @param args the compiler parameters. + */ + public static void main(String[] args) + { + boolean noWrite = false; + boolean verbose = false; + + String HelpPath = "giop/GRMIC.txt"; + + HelpPrinter.checkHelpKey(args, HelpPath); + + File output = new File("."); + + if (args.length == 0) + { + HelpPrinter.printHelpAndExit(HelpPath); + } + else + { + GiopRmicCompiler compiler = new GiopRmicCompiler(); + + int cl = - 1; + + Options: for (int i = 0; i < args.length; i++) + { + String c = args[i]; + if (c.equals("-poa")) + compiler.setPoaMode(true); + else if (c.equals("-impl")) + compiler.setPoaMode(false); + else if (c.equals("-v")) + { + printVersion(); + System.exit(0); + } + else if (c.equals("-nowrite")) + noWrite = true; + else if (c.equals("-nowarn")) + compiler.setWarnings(false); + else if (c.equals("-verbose")) + { + verbose = true; + compiler.setVerbose(true); + } + else if (c.equals("-d")) + { + int f = i + 1; + if (f < args.length) + { + output = new File(args[f]); + i++; + } + else + HelpPrinter.printHelpAndExit(HelpPath); + } + else if (c.charAt(0) != '-') + // No more options - start of class list. + { + cl = i; + break Options; + } + } + + if (cl < 0) + HelpPrinter.printHelpAndExit(HelpPath); + + if (verbose) + System.out.println("Compiling to " + output.getAbsolutePath()); + + // Compile classes + Compile: for (int i = cl; i < args.length; i++) + { + if (args[i].charAt(0) != '-') + { + compiler.reset(); + Class c = null; + try + { + c = Thread.currentThread().getContextClassLoader().loadClass( + args[i]); + } + catch (ClassNotFoundException e) + { + System.err.println(args[i] + " class not found."); + System.exit(1); + } + + compiler.compile(c); + String packag = compiler.getPackageName().replace('.', '/'); + File fw = new File(output, packag); + + // Generate stub. + String stub = compiler.generateStub(); + String subName = "_" + compiler.getStubName() + "_Stub.java"; + + compiler.reset(); + compiler.compile(c); + + // Generate tie + String tie = compiler.generateTie(); + String tieName = "_" + compiler.name(c) + "_Tie.java"; + + if (noWrite) + continue Compile; + + try + { + fw.mkdirs(); + OutputStream out = new FileOutputStream(new File(fw, + subName)); + out.write(stub.getBytes()); + out.close(); + + out = new FileOutputStream(new File(fw, tieName)); + out.write(tie.getBytes()); + out.close(); + } + catch (IOException ioex) + { + System.err.println("Output path not accessible"); + ioex.printStackTrace(); + System.exit(1); + } + } + } + } + } + + /** + * Print the version information. + */ + public static void printVersion() + { + System.out.println + ("grmic v "+VERSION+" - GIOP stub and tie generator for javax.rmi.* "); + } +} diff --git a/tools/gnu/classpath/tools/giop/GRMIC.txt b/tools/gnu/classpath/tools/giop/GRMIC.txt new file mode 100644 index 000000000..fcde83895 --- /dev/null +++ b/tools/gnu/classpath/tools/giop/GRMIC.txt @@ -0,0 +1,28 @@ +GIOP stub and tie generator source code generator for javax.rmi.*, omg.org.* + +Copyright 2006 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +Please report bugs at http://www.gnu.org/software/classpath/bugs.html + +Usage: grmic <options> <class names> + + where <options> includes: + -poa Generate the Servant based ties (default) + -impl Generate the obsoleted ObjectImpl based ties + (for backward compatibility) + -nowarn Show no warnings + -nowrite Do not write any files (check for errors only) + -d <folder> Place generated files into the given folder + + -help Print this help text + -v Print version + -verbose Verbose output + + and <class names> can include one or more non abstract classes that implement + Remote and are accessible via current class path. + +* This tool generates the source code that must be compiled with java compiler. +* GRMIC is invoked from RMIC if the -iiop or -giop keys are specified. + diff --git a/tools/gnu/classpath/tools/giop/IorParser.java b/tools/gnu/classpath/tools/giop/IorParser.java new file mode 100644 index 000000000..7d70c8aca --- /dev/null +++ b/tools/gnu/classpath/tools/giop/IorParser.java @@ -0,0 +1,125 @@ +/* IorParser.java -- IOR parser. + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.classpath.tools.giop; + +import gnu.CORBA.IOR; +import gnu.classpath.tools.HelpPrinter; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; + +import org.omg.CORBA.BAD_PARAM; + +/** + * Parses the information, encoded in the Interoperable Object References + * (IORs). + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class IorParser +{ + /** + * Parse and print IOR reference. The system exit code is 0 if the parsed + * IOR was correct, 1 if it was invalid or missing. + * + * @param args supports -f file to read IOR from the file. + */ + public static void main(String[] args) + { + boolean ok = false; + String HelpResource = "giop/IorParser.txt"; + HelpPrinter.checkHelpKey(args, HelpResource); + if (args.length == 0) + HelpPrinter.printHelpAndExit(HelpResource); + else if (args[0].equals("-f") && args.length==2) + { + File file = new File(args[1]); + if (!file.exists()) + System.err.println("The file "+file.getAbsolutePath()+" is missing."); + // Read IOR reference from file. + String ior = null; + try + { + FileReader fr = new FileReader(file); + BufferedReader br = new BufferedReader(fr); + ior = br.readLine(); + br.close(); + ok = parseAndPrint(ior); + } + catch (IOException e) + { + System.err.print("Unable to read the file "+file); + e.printStackTrace(); + } + + } + else if (args.length == 1) + ok = parseAndPrint(args[0]); + else + HelpPrinter.printHelpAndExit(HelpResource); + + if (ok) + System.exit(0); + else + System.exit(1); + } + + /** + * Parse and print IOR. + * + * @param ior the IOR string to anlyse. + * @return true if the passed value is a valid IOR, false otherwise. + */ + public static boolean parseAndPrint(String ior) + { + try + { + IOR gior = IOR.parse(ior); + System.out.println(gior.toStringFormatted()); + return true; + } + catch (BAD_PARAM e) + { + System.out.println("Invalid ior: "+e.getMessage()); + return false; + } + } +} diff --git a/tools/gnu/classpath/tools/giop/IorParser.txt b/tools/gnu/classpath/tools/giop/IorParser.txt new file mode 100644 index 000000000..3b04224f1 --- /dev/null +++ b/tools/gnu/classpath/tools/giop/IorParser.txt @@ -0,0 +1,10 @@ +Copyright 2006 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +Please report bugs at http://www.gnu.org/software/classpath/bugs.html + +IOR (interoperable GIOP object reference) parser, + usage: IorParser -f ior_file + or: IorParser -f ior_string + diff --git a/tools/gnu/classpath/tools/giop/NameService.java b/tools/gnu/classpath/tools/giop/NameService.java new file mode 100644 index 000000000..7e13185f2 --- /dev/null +++ b/tools/gnu/classpath/tools/giop/NameService.java @@ -0,0 +1,75 @@ +/* NameService.java -- Transient GIOP naming service. + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.classpath.tools.giop; + +import gnu.CORBA.NamingService.NamingServiceTransient; +import gnu.classpath.tools.HelpPrinter; + +/** + * The implementation of the transient naming service. The naming service + * is a kind of the network server that registers local and remote objects + * by name, and later can provide the object reference in response to the + * given name. + * + * GNU Classpath currently works with this naming service and is also + * interoperable with the Sun Microsystems naming services from releases 1.3 and + * 1.4, both transient <i>tnameserv</i> and persistent <i>orbd</i>. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class NameService +{ + /** + * Start the naming service on the current host at the given port. The + * parameter -org.omg.CORBA.ORBInitialPort NNN or -ORBInitialPort NNN, if + * present, specifies the port, on that the service must be started. If this + * key is not specified, the service starts at the port 900. + * + * The parameter -ior FILE_NAME, if present, forces to store the ior string of + * this naming service to the specified file. + * + * @param args the parameter string. + */ + public static void main(String[] args) + { + HelpPrinter.checkHelpKey(args, "giop/NamingService.txt"); + System.out.println("Please use --help for options."); + NamingServiceTransient.main(args); + } + +} diff --git a/tools/gnu/classpath/tools/giop/NameServicePersistent.java b/tools/gnu/classpath/tools/giop/NameServicePersistent.java new file mode 100644 index 000000000..df0c9539d --- /dev/null +++ b/tools/gnu/classpath/tools/giop/NameServicePersistent.java @@ -0,0 +1,186 @@ +/* NamingServicePersistent.java -- The persistent naming service. + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.classpath.tools.giop; + +import gnu.CORBA.OrbFunctional; +import gnu.CORBA.IOR; +import gnu.CORBA.NamingService.Ext; +import gnu.classpath.tools.HelpPrinter; +import gnu.classpath.tools.giop.nameservice.PersistentContext; + +import org.omg.CosNaming.NamingContextExt; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.PrintStream; +import java.io.UnsupportedEncodingException; + +/** + * The server for the gnu classpath persistent naming service. + * + * GNU Classpath currently works with this naming service and is also + * interoperable with the Sun Microsystems naming services from releases 1.3 and + * 1.4, both transient <i>tnameserv</i> and persistent <i>orbd</i>. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class NameServicePersistent +{ + /** + * The default port (900), on that the naming service starts if no + * -ORBInitialPort is specified in the command line. + */ + public static final int PORT = 900; + + /** + * Get the object key for the naming service. The default key is the string + * "NameService" in ASCII. + * + * @return the byte array. + */ + public static byte[] getDefaultKey() + { + try + { // NameService + return "NameService".getBytes("UTF-8"); + } + catch (UnsupportedEncodingException ex) + { + throw new InternalError("UTF-8 unsupported"); + } + } + + /** + * Start the naming service on the current host at the given port. The + * parameter -org.omg.CORBA.ORBInitialPort NNN or -ORBInitialPort NNN, if + * present, specifies the port, on that the service must be started. If this + * key is not specified, the service starts at the port 900. The parameter + * -ior FILE_NAME, if present, forces to store the ior string of this naming + * service to the specified file. + * + * @param args the parameter string. + */ + public static void main(String[] args) + { + HelpPrinter.checkHelpKey(args, "giop/NameServicePersistent.txt"); + System.out.println("Please use --help for options."); + + int port = PORT; + String iorf = null; + boolean reset = false; + String folder = ""; + try + { + // Create and initialize the ORB + final OrbFunctional orb = new OrbFunctional(); + + for (int i = 0; i < args.length; i++) + { + if (i < args.length - 1) + { + if (args[i].endsWith("ORBInitialPort")) + port = Integer.parseInt(args[i + 1]); + + if (args[i].equals("-ior")) + iorf = args[i + 1]; + + if (args[i].equals("-folder")) + folder = args[i + 1]; + } + if (args[i].equals("-reset")) + reset = true; + } + + OrbFunctional.setPort(port); + + // Create the servant and register it with the ORB + File dataFolder = new File(folder); + System.out.println("Persistent data stored at " + + dataFolder.getAbsolutePath()); + dataFolder.mkdirs(); + + // / TODO support more starting modes. + NamingContextExt namer = new Ext( + new PersistentContext( + orb, + dataFolder, + reset)); + + // Case with the key "NameService". + orb.connect(namer, "NameService".getBytes()); + + // Storing the IOR reference. + String ior = orb.object_to_string(namer); + IOR iorr = IOR.parse(ior); + if (iorf != null) + { + FileOutputStream f = new FileOutputStream(iorf); + PrintStream p = new PrintStream(f); + p.print(ior); + p.close(); + } + + System.out.println("GNU Classpath persistent naming service " + + "started at " + iorr.Internet.host + ":" + + iorr.Internet.port + " key 'NameService'.\n\n" + + "Copyright (C) 2006 Free Software Foundation\n" + + "This tool comes with ABSOLUTELY NO WARRANTY. " + + "This is free software, and you are\nwelcome to " + + "redistribute it under conditions, defined in " + + "GNU Classpath license.\n\n" + ior); + + new Thread() + { + public void run() + { + // Wait for invocations from clients. + orb.run(); + } + }.start(); + } + catch (Exception e) + { + System.err.println("ERROR: " + e); + e.printStackTrace(System.out); + } + + // Restore the default value for allocating ports for the subsequent + // objects. + OrbFunctional.setPort(OrbFunctional.DEFAULT_INITIAL_PORT); + } +} diff --git a/tools/gnu/classpath/tools/giop/NameServicePersistent.txt b/tools/gnu/classpath/tools/giop/NameServicePersistent.txt new file mode 100644 index 000000000..3de15f62a --- /dev/null +++ b/tools/gnu/classpath/tools/giop/NameServicePersistent.txt @@ -0,0 +1,28 @@ +Copyright 2006 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +Please report bugs at http://www.gnu.org/software/classpath/bugs.html + +GNU Classpath GIOP persitent naming service. + usage: NameServicePersistent <options> + + where <options> includes: +* -org.omg.CORBA.ORBInitialPort NNN + or -ORBInitialPort NNN - specifies the port, on that the + service must be started. If this key + is not specified, the service starts + at the port 900. + +* -ior FILE_NAME - store the IOR reference to this naming + service to the specified file. The + IOR reference contains enough + information to locate the service + on the web. +* - folder FOLDER - store the persistent information + to the given folder +* - reset - discard any previously stored + persistent information (cold start) + + + diff --git a/tools/gnu/classpath/tools/giop/NamingService.txt b/tools/gnu/classpath/tools/giop/NamingService.txt new file mode 100644 index 000000000..f57e4ac66 --- /dev/null +++ b/tools/gnu/classpath/tools/giop/NamingService.txt @@ -0,0 +1,21 @@ +Copyright 2006 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +Please report bugs at http://www.gnu.org/software/classpath/bugs.html + +GNU Classpath GIOP naming service, usage: NameService <options> + + where <options> includes: +* -org.omg.CORBA.ORBInitialPort NNN or +* -ORBInitialPort NNN - specifies the port, on that the + service must be started. If this key + is not specified, the service starts + at the port 900. + +* -ior FILE_NAME - store the IOR reference to this naming + service to the specified file. The + IOR reference contains enough + information to locate the service + on the web. + diff --git a/tools/gnu/classpath/tools/giop/README b/tools/gnu/classpath/tools/giop/README new file mode 100644 index 000000000..f1be7b674 --- /dev/null +++ b/tools/gnu/classpath/tools/giop/README @@ -0,0 +1,18 @@ +This package defines GIOP tools for creating the applications that use this +protocol. It provides necessary support for org.omg.* and javax.rmi.* +packages. + +All GIOP tools support the --help option. + +The list of the currently available tools: + +* GRMIC - RMI-IIOP stub and tie generator. +* NameService - GIOP transient naming service (this tool is called + tnameserv in Sun's package). +* NameService - GIOP persistent naming service (this tool is called + orbd in Sun's package). +* IorParser - Parses the stringified form of the interoperable + object references (IOR's). +* RMIC - RMI stub and tie source code generator (complements + the ASM based bytecode generator in the separate + tools package).
\ No newline at end of file diff --git a/tools/gnu/classpath/tools/giop/grmic/CompilationError.java b/tools/gnu/classpath/tools/giop/grmic/CompilationError.java new file mode 100644 index 000000000..c6b3e56e8 --- /dev/null +++ b/tools/gnu/classpath/tools/giop/grmic/CompilationError.java @@ -0,0 +1,68 @@ +/* CompilationError.java -- Thrown on compilation error. + Copyright (C) 2006 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.classpath.tools.giop.grmic; + +/** + * This error is thrown when the target being compiled has illegal + * strutures. + * + * @author Audrius Meskauskas, Lithuania (audriusa@Bioinformatics.org) + */ +public class CompilationError extends Error +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * Create error with explaining message and cause. + */ + public CompilationError(String message, Throwable cause) + { + super(message, cause); + } + + /** + * Create error with explaining message + */ + public CompilationError(String message) + { + super(message); + } +} diff --git a/tools/gnu/classpath/tools/giop/grmic/Generator.java b/tools/gnu/classpath/tools/giop/grmic/Generator.java new file mode 100644 index 000000000..a45e8d398 --- /dev/null +++ b/tools/gnu/classpath/tools/giop/grmic/Generator.java @@ -0,0 +1,144 @@ +/* Generator.java -- Generic code generator. + Copyright (C) 2006 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.classpath.tools.giop.grmic; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.StringReader; +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; + +/** + * Contains basic methods, used in code generation. + * + * @author Audrius Meskauskas, Lithuania (audriusa@Bioinformatics.org) + */ +public class Generator +{ + /** + * Get resource with the given name, as string. + * + * @param name the resource name + * @return the resourse string (in subfolder /templates). + */ + public String getResource(String name) + { + String resourcePath = "templates/" + name; + InputStream in = getClass().getResourceAsStream(resourcePath); + + if (in == null) + throw new InternalError(getClass().getName() + ": no resource " + + resourcePath); + + BufferedReader r = new BufferedReader(new InputStreamReader(in)); + StringBuffer b = new StringBuffer(); + + String s; + try + { + while ((s = r.readLine()) != null) + { + b.append(s); + b.append('\n'); + } + r.close(); + } + catch (IOException e) + { + InternalError ierr = new InternalError("No expected resource " + name); + ierr.initCause(e); + throw ierr; + } + + return b.toString(); + } + + /** + * Replace the variable references (starting from #) in the template string by + * the values, present in the given map. The strings, not present in the + * variable map, are ignored. + * + * @param template + * the template string + * @param variables + * the map of variables (name to value) to replace. + * @return the string with replaced values. + */ + public String replaceAll(String template, Map variables) + { + BufferedReader r = new BufferedReader(new StringReader(template)); + String s; + StringBuffer b = new StringBuffer(template.length()); + try + { + Iterator iter; + Collection vars = variables.keySet(); + while ((s = r.readLine()) != null) + { + // At least one variable must appear in the string to make + // the string scan sensible. + if (s.indexOf('#') >= 0) + { + iter = vars.iterator(); + String variable; + while (iter.hasNext()) + { + variable = (String) iter.next(); + if (s.indexOf(variable) >= 0) + s = s.replaceAll(variable, + (String) variables.get(variable)); + } + } + b.append(s); + b.append('\n'); + } + r.close(); + } + catch (IOException e) + { + // This should never happen. + InternalError ierr = new InternalError(""); + ierr.initCause(e); + throw ierr; + } + return b.toString(); + } +} diff --git a/tools/gnu/classpath/tools/giop/grmic/GiopIo.java b/tools/gnu/classpath/tools/giop/grmic/GiopIo.java new file mode 100644 index 000000000..3714c4ce4 --- /dev/null +++ b/tools/gnu/classpath/tools/giop/grmic/GiopIo.java @@ -0,0 +1,128 @@ +/* GiopIo.java -- Generates GIOP input/output statements. + Copyright (C) 2006 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.classpath.tools.giop.grmic; + +import java.rmi.Remote; + +import org.omg.CORBA.portable.ObjectImpl; + +/** + * Generates the code for reading and writing data over GIOP stream. + * + * @author Audrius Meskauskas, Lithuania (audriusa@Bioinformatics.org) + */ +public class GiopIo +{ + /** + * Get the statement for writing the variable of the given type to the GIOP ({@link org.omg.CORBA_2_3.portable.OutputStream) stream. The + * stream is always named "out". + * + * @param c + * the class of the object being written + * @param variable + * the variable, where the object value is stored + * @param r + * the parent generator, used to name the class + * @return the write statement. + */ + public static String getWriteStatement(Class c, String variable, GiopRmicCompiler r) + { + if (c.equals(boolean.class)) + return "out.write_boolean(" + variable + ");"; + if (c.equals(byte.class)) + return "out.write_octet(" + variable + ");"; + else if (c.equals(short.class)) + return "out.write_int(" + variable + ");"; + else if (c.equals(int.class)) + return "out.write_long(" + variable + ");"; + else if (c.equals(long.class)) + return "out.write_long_long(" + variable + ");"; + else if (c.equals(double.class)) + return "out.write_double(" + variable + ");"; + else if (c.equals(float.class)) + return "out.write_float(" + variable + ");"; + else if (c.equals(char.class)) + return "out.write_char(" + variable + ");"; + else if (Remote.class.isAssignableFrom(c)) + return "Util.writeRemoteObject(out, " + variable + ");"; + else if (ObjectImpl.class.isAssignableFrom(c)) + return "out.write_Object(" + variable + ");"; + else + return "out.write_value(" + variable + ", " + r.name(c) + ".class);"; + } + + /** + * Get the statement for reading the value of the given type from to the GIOP ({@link org.omg.CORBA_2_3.portable.InputStream) stream. The + * stream is always named "in". + * + * @param c + * the class of the object being written + * @param r + * the parent generator, used to name the class + * @return the right side of the read statement. + */ + public static String getReadStatement(Class c, GiopRmicCompiler r) + { + if (c.equals(boolean.class)) + return "in.read_boolean();"; + else if (c.equals(byte.class)) + return "in.read_octet();"; + else if (c.equals(short.class)) + return "in.read_int();"; + else if (c.equals(int.class)) + return "in.read_long();"; + else if (c.equals(long.class)) + return "in.read_long_long();"; + else if (c.equals(double.class)) + return "in.read_double();"; + else if (c.equals(float.class)) + return "in.read_float();"; + else if (c.equals(char.class)) + return "in.read_char();"; + else if (Remote.class.isAssignableFrom(c)) + return "(" + r.name(c) + + ") PortableRemoteObject.narrow(in.read_Object()," + r.name(c) + + ".class);"; + else if (ObjectImpl.class.isAssignableFrom(c)) + return "in.read_Object();"; + else + return "(" + r.name(c) + + ") in.read_value(" + r.name(c) + ".class);"; + } + +} diff --git a/tools/gnu/classpath/tools/giop/grmic/GiopRmicCompiler.java b/tools/gnu/classpath/tools/giop/grmic/GiopRmicCompiler.java new file mode 100644 index 000000000..c19f635c6 --- /dev/null +++ b/tools/gnu/classpath/tools/giop/grmic/GiopRmicCompiler.java @@ -0,0 +1,514 @@ +/* GiopRmicCompiler -- Central GIOP-based RMI stub and tie compiler class. + Copyright (C) 2006 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.classpath.tools.giop.grmic; + +import gnu.classpath.tools.AbstractMethodGenerator; + +import java.lang.reflect.Method; +import java.rmi.Remote; +import java.rmi.RemoteException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Properties; +import java.util.TreeSet; + +/** + * Provides the extended rmic functionality to generate the POA - based classes + * for GIOP (javax.rmi.CORBA package). + * + * @author Audrius Meskauskas, Lithuania (audriusa@Bioinformatics.org) + */ +public class GiopRmicCompiler + extends Generator implements Comparator +{ + /** The package name. */ + protected String packag; + + /** + * The "basic" name (normally, the interface name, unless several Remote - + * derived interfaces are implemented. + */ + protected String name; + + /** + * The name (without package) of the class, passed as the parameter. + */ + protected String implName; + + /** + * The proposed name for the stub. + */ + protected String stubName; + + /** + * The Remote's, implemented by this class. + */ + protected Collection implementedRemotes = new HashSet(); + + /** + * The extra classes that must be imported. + */ + protected Collection extraImports = new HashSet(); + + /** + * The methods we must implement. + */ + protected Collection methods = new HashSet(); + + /** + * The map of all code generator variables. + */ + public Properties vars = new Properties(); + + /** + * If this flag is set (true by default), the compiler generates the Servant + * based classes. If set to false, the compiler generates the old style + * ObjectImpl based classes. + */ + protected boolean poaMode = true; + + /** + * If this flag is set (true by default), the compiler emits warnings. + */ + protected boolean warnings = true; + + /** + * Verbose output + */ + protected boolean verbose = false; + + /** + * Clear data, preparing for the next compilation. + */ + public void reset() + { + packag = name = implName = stubName = null; + implementedRemotes.clear(); + extraImports.clear(); + methods.clear(); + vars.clear(); + } + + /** + * Compile the given class (the instance of Remote), generating the stub and + * tie for it. + * + * @param remote + * the class to compile. + */ + public synchronized void compile(Class remote) + { + reset(); + String s; + + // Get the package. + s = remote.getName(); + int p = s.lastIndexOf('.'); + if (p < 0) + { + // Root package. + packag = ""; + implName = name = s; + } + else + { + packag = s.substring(0, p); + implName = name = s.substring(p + 1); + } + + name = convertStubName(name); + + stubName = name; + + vars.put("#name", name); + vars.put("#package", packag); + vars.put("#implName", implName); + + if (verbose) + System.out.println("Package " + packag + ", name " + name + " impl " + + implName); + + // Get the implemented remotes. + Class[] interfaces = remote.getInterfaces(); + + for (int i = 0; i < interfaces.length; i++) + { + if (Remote.class.isAssignableFrom(interfaces[i])) + { + if (! interfaces[i].equals(Remote.class)) + { + implementedRemotes.add(interfaces[i]); + } + } + } + + vars.put("#idList", getIdList(implementedRemotes)); + + // Collect and process methods. + Iterator iter = implementedRemotes.iterator(); + + while (iter.hasNext()) + { + Class c = (Class) iter.next(); + Method[] m = c.getMethods(); + + // Check if throws RemoteException. + for (int i = 0; i < m.length; i++) + { + Class[] exc = m[i].getExceptionTypes(); + boolean remEx = false; + + for (int j = 0; j < exc.length; j++) + { + if (RemoteException.class.isAssignableFrom(exc[j])) + { + remEx = true; + break; + } + if (! remEx) + throw new CompilationError(m[i].getName() + ", defined in " + + c.getName() + + ", does not throw " + + RemoteException.class.getName()); + } + AbstractMethodGenerator mm = createMethodGenerator(m[i]); + methods.add(mm); + } + } + } + + /** + * Create the method generator for the given method. + * + * @param m the method + * + * @return the created method generator + */ + protected AbstractMethodGenerator createMethodGenerator(Method m) + { + return new MethodGenerator(m, this); + } + + /** + * Get the name of the given class. The class is added to imports, if not + * already present and not from java.lang and not from the current package. + * + * @param nameIt + * the class to name + * @return the name of class as it should appear in java language + */ + public String name(Class nameIt) + { + if (nameIt.isArray()) + { + // Mesure dimensions: + int dimension = 0; + Class finalComponent = nameIt; + while (finalComponent.isArray()) + { + finalComponent = finalComponent.getComponentType(); + dimension++; + } + + StringBuffer brackets = new StringBuffer(); + + for (int i = 0; i < dimension; i++) + { + brackets.append("[]"); + } + + return name(finalComponent) + " " + brackets; + } + else + { + String n = nameIt.getName(); + if (! nameIt.isArray() && ! nameIt.isPrimitive()) + if (! n.startsWith("java.lang") + && ! (packag != null && n.startsWith(packag))) + extraImports.add(n); + + int p = n.lastIndexOf('.'); + if (p < 0) + return n; + else + return n.substring(p + 1); + } + } + + /** + * Get the RMI-style repository Id for the given class. + * + * @param c + * the interface, for that the repository Id must be created. + * @return the repository id + */ + public String getId(Class c) + { + return "RMI:" + c.getName() + ":0000000000000000"; + } + + /** + * Get repository Id string array declaration. + * + * @param remotes + * the collection of interfaces + * @return the fully formatted string array. + */ + public String getIdList(Collection remotes) + { + StringBuffer b = new StringBuffer(); + + // Keep the Ids sorted, ensuring, that the same order will be preserved + // between compilations. + TreeSet sortedIds = new TreeSet(); + + Iterator iter = remotes.iterator(); + while (iter.hasNext()) + { + sortedIds.add(getId((Class) iter.next())); + } + + iter = sortedIds.iterator(); + while (iter.hasNext()) + { + b.append(" \"" + iter.next() + "\""); + if (iter.hasNext()) + b.append(", \n"); + } + return b.toString(); + } + + /** + * Generate stub. Can only be called from {@link #compile}. + * + * @return the string, containing the text of the generated stub. + */ + public String generateStub() + { + String template = getResource("Stub.jav"); + + // Generate methods. + StringBuffer b = new StringBuffer(); + Iterator iter = methods.iterator(); + while (iter.hasNext()) + { + AbstractMethodGenerator m = (AbstractMethodGenerator) iter.next(); + b.append(m.generateStubMethod()); + } + + vars.put("#stub_methods", b.toString()); + vars.put("#imports", getImportStatements()); + vars.put("#interfaces", getAllInterfaces()); + + String output = replaceAll(template, vars); + return output; + } + + /** + * Get the list of all interfaces, implemented by the class, that are + * derived from Remote. + * + * @return the string - all interfaces. + */ + public String getAllInterfaces() + { + StringBuffer b = new StringBuffer(); + Iterator iter = implementedRemotes.iterator(); + + while (iter.hasNext()) + { + b.append(name((Class) iter.next())); + if (iter.hasNext()) + b.append(", "); + } + + return b.toString(); + } + + /** + * Generate Tie. Can only be called from {@link #compile}. + * + * @return the string, containing the text of the generated Tie. + */ + public String generateTie() + { + String template; + if (poaMode) + template = getResource("Tie.jav"); + else + template = getResource("ImplTie.jav"); + + // Generate methods. + HashFinder hashFinder = new HashFinder(); + + // Find the hash character position: + Iterator iter = methods.iterator(); + String[] names = new String[methods.size()]; + int p = 0; + + for (int i = 0; i < names.length; i++) + names[i] = ((MethodGenerator) iter.next()).getGiopMethodName(); + + int hashCharPosition = hashFinder.findHashCharPosition(names); + + iter = methods.iterator(); + while (iter.hasNext()) + ((MethodGenerator) iter.next()).hashCharPosition = hashCharPosition; + + vars.put("#hashCharPos", Integer.toString(hashCharPosition)); + + ArrayList sortedMethods = new ArrayList(methods); + Collections.sort(sortedMethods, this); + + iter = sortedMethods.iterator(); + + StringBuffer b = new StringBuffer(); + + MethodGenerator prev = null; + + while (iter.hasNext()) + { + MethodGenerator m = (MethodGenerator) iter.next(); + m.previous = prev; + m.hashCharPosition = hashCharPosition; + prev = m; + b.append(m.generateTieMethod()); + } + + vars.put("#tie_methods", b.toString()); + + vars.put("#imports", getImportStatements()); + + String output = replaceAll(template, vars); + return output; + } + + public int compare(Object a, Object b) + { + MethodGenerator g1 = (MethodGenerator) a; + MethodGenerator g2 = (MethodGenerator) b; + + return g1.getHashChar() - g2.getHashChar(); + } + + /** + * Import the extra classes, used as the method parameters and return values. + * + * @return the additional import block. + */ + protected String getImportStatements() + { + TreeSet imp = new TreeSet(); + + Iterator it = extraImports.iterator(); + while (it.hasNext()) + { + String ic = it.next().toString(); + imp.add("import " + ic + ";\n"); + } + + StringBuffer b = new StringBuffer(); + it = imp.iterator(); + + while (it.hasNext()) + { + b.append(it.next()); + } + return b.toString(); + } + + /** + * If this flag is set (true by default), the compiler generates the Servant + * based classes. If set to false, the compiler generates the old style + * ObjectImpl based classes. + */ + public void setPoaMode(boolean mode) + { + poaMode = mode; + } + + /** + * Set the verbose output mode (false by default) + * + * @param isVerbose the verbose output mode + */ + public void setVerbose(boolean isVerbose) + { + verbose = isVerbose; + } + + /** + * If this flag is set (true by default), the compiler emits warnings. + */ + public void setWarnings(boolean warn) + { + warnings = warn; + } + + /** + * Get the package name. + */ + public String getPackageName() + { + return packag; + } + + /** + * Get the proposed stub name + */ + public String getStubName() + { + return stubName; + } + + /** + * Additional processing of the stub name. + */ + public String convertStubName(String name) + { + // Drop the Impl suffix, if one exists. + if (name.endsWith("Impl")) + return name.substring(0, name.length() - "Impl".length()); + else + return name; + } +} diff --git a/tools/gnu/classpath/tools/giop/grmic/HashFinder.java b/tools/gnu/classpath/tools/giop/grmic/HashFinder.java new file mode 100644 index 000000000..216e73953 --- /dev/null +++ b/tools/gnu/classpath/tools/giop/grmic/HashFinder.java @@ -0,0 +1,62 @@ +package gnu.classpath.tools.giop.grmic; + +import java.util.HashSet; + +/** + * This class finds the hash character (the most different character in + * the passed array of strings). This character is used to accelerate the + * method invocation by name. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class HashFinder +{ + /** + * Find the hash char position in the given collection of strings. + * + * @param strings the string collection + * + * @return the optimal hash character position, always less then the + * length of the shortest string. + */ + public int findHashCharPosition(String[] strings) + { + // Find the length of the shortest string: + + int l = strings[0].length(); + for (int i = 1; i < strings.length; i++) + { + if (strings[i].length() < l) + l = strings[i].length(); + } + + // Find the position with the smallest number of the matching characters: + HashSet[] charLists = new HashSet[l]; + + for (int i = 0; i < charLists.length; i++) + { + charLists[i] = new HashSet(strings.length); + } + + for (int i = 0; i < strings.length; i++) + for (int p = 0; p < l; p++) + { + charLists[p].add(new Integer(strings[i].charAt(p))); + } + + int m = 0; + int v = charLists[0].size(); + + for (int i = 1; i < charLists.length; i++) + { + // Replace on equality also, seeking the hash char closer to the end + // of line. + if (charLists[i].size()>=v) + { + m = i; + v = charLists[i].size(); + } + } + return m; + } +} diff --git a/tools/gnu/classpath/tools/giop/grmic/MethodGenerator.java b/tools/gnu/classpath/tools/giop/grmic/MethodGenerator.java new file mode 100644 index 000000000..9a44fad79 --- /dev/null +++ b/tools/gnu/classpath/tools/giop/grmic/MethodGenerator.java @@ -0,0 +1,301 @@ +/* MethodGenerator.java -- Generates methods for GIOP rmic compiler. + Copyright (C) 2006 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.classpath.tools.giop.grmic; + +import gnu.classpath.tools.AbstractMethodGenerator; + +import java.lang.reflect.Method; +import java.util.Properties; + +/** + * Keeps information about the single method and generates the code fragments, + * related to that method. + * + * @author Audrius Meskauskas, Lithuania (audriusa@Bioinformatics.org) + */ +public class MethodGenerator implements AbstractMethodGenerator +{ + /** + * The method being defined. + */ + Method method; + + /** + * The parent code generator. + */ + GiopRmicCompiler rmic; + + /** + * The previous method in the list, null for the first element. + * Used to avoid repretetive inclusion of the same hash code label. + */ + MethodGenerator previous = null; + + /** + * The hash character position. + */ + int hashCharPosition; + + /** + * Create the new method generator for the given method. + * + * @param aMethod + * the related method. + * @param aRmic + * the Rmic generator instance, where more class - related + * information is defined. + */ + public MethodGenerator(Method aMethod, GiopRmicCompiler aRmic) + { + method = aMethod; + rmic = aRmic; + } + + /** + * Get the method name. + * + * @return the name of the method. + */ + public String getGiopMethodName() + { + String m = method.getName(); + if (m.startsWith("get")) + return "_get_J" + m.substring("get".length()); + else if (m.startsWith("set")) + return "_set_J" + m.substring("set".length()); + else + return m; + } + + /** + * Get the method parameter declaration. + * + * @return the string - method parameter declaration. + */ + public String getArgumentList() + { + StringBuffer b = new StringBuffer(); + + Class[] args = method.getParameterTypes(); + + for (int i = 0; i < args.length; i++) + { + b.append(rmic.name(args[i])); + b.append(" p" + i); + if (i < args.length - 1) + b.append(", "); + } + return b.toString(); + } + + /** + * Get the method parameter list only (no type declarations). This is used to + * generate the method invocations statement. + * + * @return the string - method parameter list. + */ + public String getArgumentNames() + { + StringBuffer b = new StringBuffer(); + + Class[] args = method.getParameterTypes(); + + for (int i = 0; i < args.length; i++) + { + b.append(" p" + i); + if (i < args.length - 1) + b.append(", "); + } + return b.toString(); + } + + /** + * Get the list of exceptions, thrown by this method. + * + * @return the list of exceptions. + */ + public String getThrows() + { + StringBuffer b = new StringBuffer(); + + Class[] args = method.getExceptionTypes(); + + for (int i = 0; i < args.length; i++) + { + b.append(rmic.name(args[i])); + if (i < args.length - 1) + b.append(", "); + } + return b.toString(); + } + + /** + * Generate this method for the Stub class. + * + * @return the method body for the stub class. + */ + public String generateStubMethod() + { + String templateName; + + Properties vars = new Properties(rmic.vars); + vars.put("#return_type", rmic.name(method.getReturnType())); + vars.put("#method_name", method.getName()); + vars.put("#giop_method_name", getGiopMethodName()); + vars.put("#argument_list", getArgumentList()); + vars.put("#argument_names", getArgumentNames()); + + vars.put("#argument_write", getStubParaWriteStatement()); + + if (method.getReturnType().equals(void.class)) + vars.put("#read_return", "return;"); + else + vars.put("#read_return", + "return " + + GiopIo.getReadStatement(method.getReturnType(), rmic)); + String thr = getThrows(); + if (thr.length() > 0) + vars.put("#throws", "\n throws " + thr); + else + vars.put("#throws", ""); + + if (method.getReturnType().equals(void.class)) + templateName = "StubMethodVoid.jav"; + else + { + vars.put("#write_result", + GiopIo.getWriteStatement(method.getReturnType(), "result", + rmic)); + templateName = "StubMethod.jav"; + } + + String template = rmic.getResource(templateName); + String generated = rmic.replaceAll(template, vars); + return generated; + } + + /** + * Generate this method handling fragment for the Tie class. + * + * @return the fragment to handle this method for the Tie class. + */ + public String generateTieMethod() + { + String templateName; + + Properties vars = new Properties(rmic.vars); + vars.put("#return_type", rmic.name(method.getReturnType())); + vars.put("#method_name", method.getName()); + vars.put("#giop_method_name", getGiopMethodName()); + vars.put("#argument_list", getArgumentList()); + vars.put("#argument_names", getArgumentNames()); + + vars.put("#argument_write", getStubParaWriteStatement()); + + if (previous == null || previous.getHashChar()!=getHashChar()) + vars.put("#hashCodeLabel"," case '"+getHashChar()+"':"); + else + vars.put("#hashCodeLabel"," // also '"+getHashChar()+"':"); + + if (method.getReturnType().equals(void.class)) + templateName = "TieMethodVoid.jav"; + else + { + vars.put("#write_result", + GiopIo.getWriteStatement(method.getReturnType(), "result", + rmic)); + templateName = "TieMethod.jav"; + } + vars.put("#read_and_define_args", getRda()); + + String template = rmic.getResource(templateName); + String generated = rmic.replaceAll(template, vars); + return generated; + } + + /** + * Generate sentences for Reading and Defining Arguments. + * + * @return the sequence of sentences for reading and defining arguments. + */ + public String getRda() + { + StringBuffer b = new StringBuffer(); + Class[] args = method.getParameterTypes(); + + for (int i = 0; i < args.length; i++) + { + b.append(" "); + b.append(rmic.name(args[i])); + b.append(" "); + b.append("p"+i); + b.append(" = "); + b.append(GiopIo.getReadStatement(args[i], rmic)); + if (i<args.length-1) + b.append("\n"); + } + return b.toString(); + } + + /** + * Get the write statement for writing parameters inside the stub. + * + * @return the write statement. + */ + public String getStubParaWriteStatement() + { + StringBuffer b = new StringBuffer(); + Class[] args = method.getParameterTypes(); + + for (int i = 0; i < args.length; i++) + { + b.append(" "); + b.append(GiopIo.getWriteStatement(args[i], "p" + i, rmic)); + b.append("\n"); + } + return b.toString(); + } + + /** + * Get the hash char. + */ + public char getHashChar() + { + return getGiopMethodName().charAt(hashCharPosition); + } +} diff --git a/tools/gnu/classpath/tools/giop/grmic/templates/ImplTie.jav b/tools/gnu/classpath/tools/giop/grmic/templates/ImplTie.jav new file mode 100644 index 000000000..aff606b90 --- /dev/null +++ b/tools/gnu/classpath/tools/giop/grmic/templates/ImplTie.jav @@ -0,0 +1,152 @@ +package #package; + +#imports +import java.rmi.Remote; +import javax.rmi.PortableRemoteObject; +import javax.rmi.CORBA.Tie; + +import org.omg.CORBA.BAD_OPERATION; +import org.omg.CORBA.ORB; +import org.omg.CORBA.SystemException; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.ResponseHandler; +import org.omg.CORBA.portable.UnknownException; +import org.omg.PortableServer.Servant; + +import org.omg.CORBA_2_3.portable.ObjectImpl; +import org.omg.CORBA_2_3.portable.InputStream; + +// This Tie type is obsolete. Use the POA - based tie (key -poa). + +/** + * This class accepts remote calls to the served GIOP object and delegates them + * to the enclosed implementing class. Being derived from the ObjectImpl, + * it directly implements the GIOP Object. + * + * It is normally generated with grmic -impl + */ +public class _#nameImpl_Tie extends ObjectImpl implements Tie +{ + /** + * All decoded remote calls are forwarded to this target. + */ + #implName target; + + /** + * The array of repository ids, supported by this GIOP Object + */ + private static final String[] type_ids = + { +#idList + }; + + /** + * Get an array of all interfaces (repository ids), + * supported by this Object. + * + * @return the array of Ids. + */ + public String[] _ids() + { + return type_ids; + } + + /** + * Set the invocation target, where all received calls are finally + * forwarded. + * + * @param a_target the forwarding target + * + * @throws ClassCastException if the target is not an instance of + * #implName + */ + public void setTarget(Remote a_target) + { + this.target = (#implName) a_target; + } + + /** + * Get the invocation target, where all received calls are finally + * forwarded. + * + * @return the target, an instance of + * #implName + */ + public Remote getTarget() + { + return target; + } + + /** + * Return the actual GIOP object that would handle this request. + * + * @return <code>this</code>, always. + */ + public org.omg.CORBA.Object thisObject() + { + return this; + } + + /** + * Deactivates this object, disconnecting it from the orb. + */ + public void deactivate() + { + _orb().disconnect(this); + _set_delegate(null); + target = null; + } + + /** + * Get the {@link ORB} where this {@link Servant} is connected. + * + * @return the ORB + */ + public ORB orb() + { + return _orb(); + } + + /** + * Connect this servant to the given ORB. + */ + public void orb(ORB orb) + { + orb.connect(this); + } + +/** + * This method is invoked by ORB in response to the remote call. It redirects + * the call to one of the methods in the target. + * + * @param method the name of the method to call. + * @param parameter_stream the input stream, from where the parameters must be + * read. + * @param reply the response hander, providing methods to return the result. + * + * @return the output stream, created by the response handler + * + * @throws SystemException if one occurs during method invocation. + */ + public OutputStream _invoke(String method, + org.omg.CORBA.portable.InputStream parameter_stream, + ResponseHandler reply) + { + try + { + InputStream in =(InputStream) parameter_stream; + +#tie_methods + + throw new BAD_OPERATION("No such method: '"+method+"'"); + } + catch (SystemException ex) + { + throw ex; + } + catch (Throwable ex) + { + throw new UnknownException(ex); + } + } +}
\ No newline at end of file diff --git a/tools/gnu/classpath/tools/giop/grmic/templates/Stub.jav b/tools/gnu/classpath/tools/giop/grmic/templates/Stub.jav new file mode 100644 index 000000000..371e12d44 --- /dev/null +++ b/tools/gnu/classpath/tools/giop/grmic/templates/Stub.jav @@ -0,0 +1,47 @@ +package #package; + +#imports +import java.rmi.UnexpectedException; + +import javax.rmi.CORBA.Stub; +import javax.rmi.CORBA.Util; + +import org.omg.CORBA.SystemException; +import org.omg.CORBA.portable.ApplicationException; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.RemarshalException; + +import org.omg.CORBA_2_3.portable.OutputStream; + +/** + * This class delegates its method calls to the remote GIOP object. + * It is normally generated with grmic. + */ +public class _#name_Stub extends Stub + implements #interfaces +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The array of repository ids, supported by this GIOP Object + */ + private static final String[] type_ids = + { +#idList + }; + + /** + * Return the array of repository ids, supported by this GIOP Object. + * + * @return the array of Ids. + */ + public String[] _ids() + { + return type_ids; + } + +#stub_methods +}
\ No newline at end of file diff --git a/tools/gnu/classpath/tools/giop/grmic/templates/StubMethod.jav b/tools/gnu/classpath/tools/giop/grmic/templates/StubMethod.jav new file mode 100644 index 000000000..17636deb6 --- /dev/null +++ b/tools/gnu/classpath/tools/giop/grmic/templates/StubMethod.jav @@ -0,0 +1,33 @@ + /** @inheritDoc */ + public #return_type #method_name(#argument_list) #throws + { + try + { + InputStream in = null; + try + { + OutputStream out = + (OutputStream) _request("#giop_method_name", true); +#argument_write + in = _invoke(out); + #read_return + } + catch (ApplicationException ex) + { + in = ex.getInputStream(); + throw new UnexpectedException(in.read_string()); + } + catch (RemarshalException ex) + { + return #method_name(#argument_names); + } + finally + { + _releaseReply(in); + } + } + catch (SystemException ex) + { + throw Util.mapSystemException(ex); + } + } diff --git a/tools/gnu/classpath/tools/giop/grmic/templates/StubMethodVoid.jav b/tools/gnu/classpath/tools/giop/grmic/templates/StubMethodVoid.jav new file mode 100644 index 000000000..0125a02b0 --- /dev/null +++ b/tools/gnu/classpath/tools/giop/grmic/templates/StubMethodVoid.jav @@ -0,0 +1,32 @@ + /** @inheritDoc */ + public #return_type #method_name(#argument_list) #throws + { + try + { + InputStream in = null; + try + { + OutputStream out = + (OutputStream) _request("#giop_method_name", true); +#argument_write + in = _invoke(out); + } + catch (ApplicationException ex) + { + in = ex.getInputStream(); + throw new UnexpectedException(in.read_string()); + } + catch (RemarshalException ex) + { + #method_name(#argument_names); + } + finally + { + _releaseReply(in); + } + } + catch (SystemException ex) + { + throw Util.mapSystemException(ex); + } + } diff --git a/tools/gnu/classpath/tools/giop/grmic/templates/Tie.jav b/tools/gnu/classpath/tools/giop/grmic/templates/Tie.jav new file mode 100644 index 000000000..797ae1401 --- /dev/null +++ b/tools/gnu/classpath/tools/giop/grmic/templates/Tie.jav @@ -0,0 +1,184 @@ +package #package; + +#imports +import java.rmi.Remote; +import javax.rmi.PortableRemoteObject; +import javax.rmi.CORBA.Tie; + +import org.omg.CORBA.BAD_OPERATION; +import org.omg.CORBA.ORB; +import org.omg.CORBA.SystemException; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.ResponseHandler; +import org.omg.CORBA.portable.UnknownException; +import org.omg.PortableServer.Servant; +import org.omg.PortableServer.POA; +import org.omg.PortableServer.POAPackage.WrongPolicy; +import org.omg.PortableServer.POAPackage.ObjectNotActive; +import org.omg.PortableServer.POAPackage.ServantNotActive; + +import org.omg.CORBA_2_3.portable.InputStream; + +/** + * This class accepts remote calls to the served GIOP object and delegates them + * to the enclosed implementing class. Being servant, it must be connected to + * the ORB Poa. + * It is normally generated with grmic -poa + */ +public class _#nameImpl_Tie extends Servant implements Tie +{ + /** + * All decoded remote calls are forwarded to this target. + */ + #implName target; + + /** + * The array of repository ids, supported by this GIOP Object + */ + private static final String[] type_ids = + { +#idList + }; + + /** + * Get an array of all interfaces, supported by this + * {@link Servant}. + * + * @param poa unused + * @param objectId unused + * + * @return the array of Ids. + */ + public String[] _all_interfaces(POA poa, + byte[] objectId + ) + { + return type_ids; + } + + + /** + * Set the invocation target, where all received calls are finally + * forwarded. + * + * @param a_target the forwarding target + * + * @throws ClassCastException if the target is not an instance of + * #implName + */ + public void setTarget(Remote a_target) + { + this.target = (#implName) a_target; + } + + /** + * Get the invocation target, where all received calls are finally + * forwarded. + * + * @return the target, an instance of + * #implName + */ + public Remote getTarget() + { + return target; + } + + /** + * Return the actual GIOP object that would handle this request. + * + * @return the GIOP object. + */ + public org.omg.CORBA.Object thisObject() + { + return _this_object(); + } + + /** + * Deactivate this {@link Servant}. The WrongPolicy, ObjectNotActive + * and ServantNotActive exceptions, if thrown during deactivation, are + * catched and silently ignored. + */ + public void deactivate() + { + try + { + _poa().deactivate_object(_poa().servant_to_id(this)); + } + catch (WrongPolicy exception) + { + } + catch (ObjectNotActive exception) + { + } + catch (ServantNotActive exception) + { + } + } + + /** + * Get the {@link ORB} where this {@link Servant} is connected. + * + * @return the ORB + */ + public ORB orb() + { + return _orb(); + } + + /** + * Connect this servant to the given ORB. It is recommended to connect + * servant to the ORBs root or other POA rather than using this method. + */ + public void orb(ORB orb) + { + try + { + ((org.omg.CORBA_2_3.ORB) orb).set_delegate(this); + } + catch (ClassCastException e) + { + throw new org.omg.CORBA.BAD_PARAM( + "POA Servant requires an instance of org.omg.CORBA_2_3.ORB" + ); + } + } + +/** + * This method is invoked by ORB in response to the remote call. It redirects + * the call to one of the methods in the target. + * + * @param method the name of the method to call. + * @param parameter_stream the input stream, from where the parameters must be + * read. + * @param reply the response hander, providing methods to return the result. + * + * @return the output stream, created by the response handler + * + * @throws SystemException if one occurs during method invocation. + */ + public OutputStream _invoke(String method, + org.omg.CORBA.portable.InputStream parameter_stream, + ResponseHandler reply + ) throws SystemException + { + try + { + InputStream in =(InputStream) parameter_stream; + switch (method.charAt(#hashCharPos)) + { +#tie_methods + default: break; + } + + throw new BAD_OPERATION("No such method: '"+method+"'"); + } + catch (SystemException ex) + { + throw ex; + } + catch (Throwable ex) + { + throw new UnknownException(ex); + } + } +}
\ No newline at end of file diff --git a/tools/gnu/classpath/tools/giop/grmic/templates/TieMethod.jav b/tools/gnu/classpath/tools/giop/grmic/templates/TieMethod.jav new file mode 100644 index 000000000..493f0009b --- /dev/null +++ b/tools/gnu/classpath/tools/giop/grmic/templates/TieMethod.jav @@ -0,0 +1,11 @@ + #hashCodeLabel + // #method_name + if (method.equals("#giop_method_name")) + { +#read_and_define_args + OutputStream out = reply.createReply(); + #return_type result = + target.#method_name(#argument_names); + #write_result + return out; + } diff --git a/tools/gnu/classpath/tools/giop/grmic/templates/TieMethodVoid.jav b/tools/gnu/classpath/tools/giop/grmic/templates/TieMethodVoid.jav new file mode 100644 index 000000000..3db17da7c --- /dev/null +++ b/tools/gnu/classpath/tools/giop/grmic/templates/TieMethodVoid.jav @@ -0,0 +1,9 @@ + #hashCodeLabel + // #method_name + if (method.equals("#giop_method_name")) + { +#read_and_define_args + OutputStream out = reply.createReply(); + target.#method_name(#argument_names); + return out; + } diff --git a/tools/gnu/classpath/tools/giop/nameservice/PersistentContext.java b/tools/gnu/classpath/tools/giop/nameservice/PersistentContext.java new file mode 100644 index 000000000..9f0903f0a --- /dev/null +++ b/tools/gnu/classpath/tools/giop/nameservice/PersistentContext.java @@ -0,0 +1,152 @@ +/* PersistentContext.java -- The persistent naming context. + Copyright (C) 2006 Free Software Foundation, Inc. + + This file is part of GNU Classpath. + + GNU Classpath is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU Classpath 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 for more details. + + You should have received a copy of the GNU General Public License + along with GNU Classpath; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. */ + + +package gnu.classpath.tools.giop.nameservice; + +import gnu.CORBA.NamingService.NameTransformer; +import gnu.CORBA.NamingService.TransientContext; + +import java.io.File; + +import org.omg.CORBA.ORB; +import org.omg.CosNaming.NameComponent; +import org.omg.CosNaming.NamingContext; +import org.omg.CosNaming.NamingContextPackage.AlreadyBound; +import org.omg.CosNaming.NamingContextPackage.CannotProceed; +import org.omg.CosNaming.NamingContextPackage.InvalidName; +import org.omg.CosNaming.NamingContextPackage.NotFound; + +/** + * This class implements the persistent naming service, defined by + * {@link NamingContext}. The 'persistent' means that the service remembers the + * mappings, stored between restarts. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class PersistentContext + extends TransientContext +{ + /** + * Use serial version UID for interoperability. + */ + private static final long serialVersionUID = 2; + + /** + * The folder, where the persistent context information is stored. + */ + File contextFolder; + + /** + * The uinque context identifier. + */ + static long num = System.currentTimeMillis(); + + /** + * The naming service orb. + */ + ORB orb; + + /** + * Create the persistent naming context that will store the files in the given + * folder of the local file system. This method also connects object to the + * passed ORB. + * + * @param an_orb the naming service ORB, used to obtain and produce the object + * stringified references. + * @param folder the folder, where the persistent information is stored. + * @param reset if true, the previous naming data are discarded. If false + * (normally expected), they are loaded from the persistent memory to + * provide the persistence. + */ + public PersistentContext(ORB an_orb, File folder, boolean reset) + { + super( + new PersistentContextMap(an_orb, new File(folder, "contexts.txt"), reset), + new PersistentMap(an_orb, new File(folder, "objects.txt"), reset)); + contextFolder = folder; + folder.mkdirs(); + orb = an_orb; + orb.connect(this); + } + + /** + * Get the unique context number; + * + * @return the context number + */ + static synchronized String getNum() + { + return Long.toHexString(num++); + } + + /** + * Create new persistent context. + */ + public NamingContext new_context() + { + File ctxFolder = new File(contextFolder, "ctx_"+getNum()); + return new PersistentContext(orb, ctxFolder, true); + } + + /** + * Create a new context and give it a given name (bound it) in the current + * context. The method benefits from passing the better readable context name. + * + * @param a_name the name being given to the new context. + * @return the newly created context. + * @throws AlreadyBound if the name is already in use. + * @throws InvalidName if the name has zero length or otherwise invalid. + */ + public NamingContext bind_new_context(NameComponent[] a_name) + throws NotFound, AlreadyBound, CannotProceed, InvalidName + { + if (named_contexts.containsKey(a_name[0]) + || named_objects.containsKey(a_name[0])) + throw new AlreadyBound(); + + NameTransformer transformer = new NameTransformer(); + + File ctxFolder = new File(contextFolder, + transformer.toString(a_name).replace('/', '.') + + ".v" + getNum()); + + NamingContext child = new PersistentContext(orb, ctxFolder, true); + bind_context(a_name, child); + return child; + } +} diff --git a/tools/gnu/classpath/tools/giop/nameservice/PersistentContextMap.java b/tools/gnu/classpath/tools/giop/nameservice/PersistentContextMap.java new file mode 100644 index 000000000..ce0188cf2 --- /dev/null +++ b/tools/gnu/classpath/tools/giop/nameservice/PersistentContextMap.java @@ -0,0 +1,87 @@ +/* PersistentContextMap.java -- The persistent context naming map + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.classpath.tools.giop.nameservice; + +import java.io.File; + +import org.omg.CORBA.ORB; +import org.omg.CORBA.Object; + +/** + * The persistent context naming map for the persistent naming service. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class PersistentContextMap extends PersistentMap +{ + /** + * Create the persistent context map that stores information in the given + * file. + * + * @param an_orb the naming service ORB, used to obtain and produce the object + * stringified references. + * @param mapFile the file, where the persistent information is stored. + * @param reset if true, the previous naming data are discarded. If false + * (normally expected), they are loaded from the persistent memory to + * provide the persistence. + */ + public PersistentContextMap(ORB an_orb, File mapFile, boolean reset) + { + super(an_orb, mapFile, reset); + } + + /** + * This method expects the PersistentContext as its parameter. The returned + * description line is the name of the context parent folder. + */ + protected String object_to_string(Object object) + { + PersistentContext pc = (PersistentContext) object; + return pc.contextFolder.getAbsolutePath(); + } + + /** + * This method restores the PersistenContext. The description line is + * interpreted as the folder name, absolute path. + */ + protected Object string_to_object(String description) + { + return new PersistentContext(orb, new File(description), reset); + } +} diff --git a/tools/gnu/classpath/tools/giop/nameservice/PersistentMap.java b/tools/gnu/classpath/tools/giop/nameservice/PersistentMap.java new file mode 100644 index 000000000..6939ede17 --- /dev/null +++ b/tools/gnu/classpath/tools/giop/nameservice/PersistentMap.java @@ -0,0 +1,454 @@ +/* PersistentMap.java -- The persistent object naming map + Copyright (C) 2006 Free Software Foundation, Inc. + + This file is part of GNU Classpath. + + GNU Classpath is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU Classpath 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 for more details. + + You should have received a copy of the GNU General Public License + along with GNU Classpath; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. */ + + +package gnu.classpath.tools.giop.nameservice; + +import gnu.CORBA.NamingService.NamingMap; + +import java.io.BufferedOutputStream; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.util.Iterator; +import java.util.Map; + +import org.omg.CORBA.ORB; +import org.omg.CosNaming.NameComponent; +import org.omg.CosNaming.NamingContextPackage.AlreadyBound; +import org.omg.CosNaming.NamingContextPackage.InvalidName; + +/** + * The persistent object naming map for the persistent naming service. The + * inherited (super.) naming map implementation is transient and is used as a + * cache. During the normal work, the naming map does not read from the disk, + * just stores the changes there. Map only reads from the disk when it starts. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class PersistentMap + extends NamingMap +{ + /** + * The data entry. + */ + public static class Entry + { + String id; + + String kind; + + String ior; + + /** + * Get the name component node. + */ + public NameComponent getComponent() + { + return new NameComponent(id, kind); + } + + /** + * Write the naming map entry to the output stream. + */ + public void write(OutputStream out) throws IOException + { + // Format: id.kind <eoln> ior <eoln><eoln> + out.write(getKey(id, kind).getBytes()); + out.write('\n'); + out.write(ior.getBytes()); + out.write('\n'); + out.close(); + } + + /** + * Read the name component from the input stream + */ + public boolean read(BufferedReader in) throws IOException + { + String key = in.readLine(); + String xior = in.readLine(); + + if (key != null && xior != null) + { + if (key.length() < 2) + { + // A single char key cannot have the kind part. + id = key; + kind = ""; + } + else + { + // Search for the id/kind splitter, dot: + int iks = - 1; + for (int i = 1; i < key.length(); i++) + { + if (key.charAt(i) == '.') + // The id is separated from kind by dot, unless preceeded by + // the + // escape character, \. + if (key.charAt(i - 1) != '\\') + { + iks = i; + break; + } + } + + // May also end by dot, if the kind field is missing. + if (iks < 0) + { + id = key; + kind = ""; + } + else if (iks == key.length() - 1) + { + id = key.substring(0, key.length() - 1); + kind = ""; + } + else + { + id = key.substring(0, iks); + kind = key.substring(iks + 1); + } + } + ior = xior; + return true; + } + else + return false; + } + + /** + * Get the key value from the name component. + * + * @param id the component id + * @param kind the component kind + * @return the key value + */ + public String getKey(String id, String kind) + { + StringBuffer b = new StringBuffer(id.length() + 8); + appEscaping(b, id); + b.append('.'); + if (kind != null && kind.length() > 0) + appEscaping(b, kind); + return b.toString(); + } + + /** + * Append the contents of the string to this string buffer, inserting the + * escape sequences, where required. + * + * @param b a buffer to append the contents to. + * @param s a string to append. + */ + void appEscaping(StringBuffer b, String s) + { + char c; + for (int i = 0; i < s.length(); i++) + { + c = s.charAt(i); + switch (c) + { + case '.': + case '/': + case '\\': + b.append('\\'); + b.append(c); + break; + + default: + b.append(c); + break; + } + } + } + } + + /** + * The file, where the persistent naming map stores the information. The + * format of this file is n*(id LF kind LF ior LFLF). + */ + public final File file; + + /** + * The naming service ORB, used to obtain and produce the object stringified + * references. + */ + ORB orb; + + /** + * If true, all existing data on the file system are discarded. + */ + boolean reset; + + /** + * Create the persistent map that stores information in the given file. + * + * @param an_orb the naming service ORB, used to obtain and produce the object + * stringified references. + * @param mapFile the file, where the persistent information is stored. + * @param a_reset if true, the previous naming data are discarded. If false + * (normally expected), they are loaded from the persistent memory to + * provide the persistence. + */ + public PersistentMap(ORB an_orb, File mapFile, boolean a_reset) + { + super(); + orb = an_orb; + file = mapFile; + reset = a_reset; + + // Initialise the persistent map with existing data. + if (file.exists() && ! reset) + { + + BufferedReader in; + try + { + FileInputStream fin = new FileInputStream(file); + in = new BufferedReader(new InputStreamReader(fin)); + Entry e = new Entry(); + boolean ok; + + while (e.read(in)) + { + org.omg.CORBA .Object object = string_to_object(e.ior); + orb.connect(object); + map.put(e.getComponent(), object); + } + } + catch (Exception ex) + { + InternalError ierr = new InternalError(file.getAbsolutePath()); + ierr.initCause(ex); + throw ierr; + } + } + } + + /** + * Restore object from its string description. + * + * @param description the string, describing the object + * + * @return the object. + */ + protected org.omg.CORBA.Object string_to_object(String description) + { + return orb.string_to_object(description); + } + + /** + * Convert the object to its string description + * + * @param object the object to convert + * @return the string description of the object + */ + protected String object_to_string(org.omg.CORBA .Object object) + { + return orb.object_to_string(object); + } + + /** + * Put the given GIOP object, specifying the given name as a key. If the entry + * with the given name already exists, or if the given object is already + * mapped under another name, the {@link AlreadyBound} exception will be + * thrown. + * + * @param name the name + * @param object the object + */ + public void bind(NameComponent name, org.omg.CORBA.Object object) + throws AlreadyBound, InvalidName + { + if (!containsKey(name)) + { + super.bind(name, object); + register(name, object); + } + else + throw new AlreadyBound(name.id + "." + name.kind); + } + + /** + * Put the given CORBA object, specifying the given name as a key. Remove all + * pre - existing mappings for the given name and object. + * + * @param name the name. + * @param object the object + */ + public void rebind(NameComponent name, org.omg.CORBA.Object object) + throws InvalidName + { + if (containsKey(name)) + { + org.omg.CORBA.Object existing = get(name); + String ior = object_to_string(object); + String xior = object_to_string(existing); + + // Same name and same ior - nothing to do. + if (ior.equals(xior)) + return; + else + remove(name); + } + + Iterator iter = entries().iterator(); + Map.Entry item; + + // Remove the existing mapping for the given object, if present. + while (iter.hasNext()) + { + item = (Map.Entry) iter.next(); + if (item.getValue().equals(object)) + iter.remove(); + } + + map.put(name, object); + register(name, object); + } + + /** + * Removes the given name, if present. + * + * @param name a name to remove. + */ + public void remove(NameComponent name) + { + super.remove(name); + unregister(name); + } + + /** + * Register this name - object pair in the persistent storage. + * + * @param name the name. + * @param object the object + */ + public void register(NameComponent name, org.omg.CORBA.Object object) + { + // If this key is already known, and this is the same object, + // then return without action. + String ior = object_to_string(object); + + synchronized (file) + { + try + { + FileOutputStream fou; + + if (! file.exists()) + fou = new FileOutputStream(file); + else + fou = new FileOutputStream(file, true); + + Entry e = new Entry(); + e.id = name.id; + e.kind = name.kind; + e.ior = ior; + e.write(fou); + fou.close(); + } + catch (Exception e) + { + InternalError ierr = new InternalError(file.getAbsolutePath()); + ierr.initCause(e); + throw ierr; + } + } + } + + /** + * Remove this name from the persistent storage. + * + * @param name the name to remove + */ + public void unregister(NameComponent name) + { + synchronized (file) + { + try + { + File nf = new File(file.getParent(), file.getName() + "_t"); + FileInputStream fin = new FileInputStream(file); + FileOutputStream fou = new FileOutputStream(nf); + BufferedOutputStream ou = new BufferedOutputStream(fou); + + BufferedReader in = new BufferedReader(new InputStreamReader(fin)); + String s; + String nk = name.kind; + if (nk == null) + nk = ""; + + Entry e = new Entry(); + + while (e.read(in)) + { + if (e.id.equals(name.id) && e.kind.equals(nk)) + { + // Do nothing - skip. + } + else + { + e.write(ou); + } + } + + File deleteIt = new File(file.getParent(), file.getName() + "_d"); + if (deleteIt.exists()) + deleteIt.delete(); + + if (! file.renameTo(deleteIt)) + throw new IOException(file.getAbsolutePath() + " rename failed"); + + if (! nf.renameTo(file)) + throw new IOException(file.getAbsolutePath() + " rename failed"); + } + catch (Exception e) + { + InternalError ierr = new InternalError(file.getAbsolutePath()); + ierr.initCause(e); + throw ierr; + } + } + } +} diff --git a/tools/gnu/classpath/tools/rmi/RMIC.java b/tools/gnu/classpath/tools/rmi/RMIC.java new file mode 100644 index 000000000..09021dd3f --- /dev/null +++ b/tools/gnu/classpath/tools/rmi/RMIC.java @@ -0,0 +1,198 @@ +/* RMIC.java -- RMI stub generator. + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.classpath.tools.rmi; + +import gnu.classpath.tools.HelpPrinter; +import gnu.classpath.tools.giop.GRMIC; +import gnu.classpath.tools.giop.grmic.GiopRmicCompiler; +import gnu.classpath.tools.rmi.rmic.RmicCompiler; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +/** + * Generates the ordinary stubs (not GIOP based) for java.rmi.* package. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class RMIC +{ + /** + * The version of the compiler. + */ + public static String VERSION = "0.0 alpha pre"; + + /** + * The GRMIC compiler methods + * + * @param args the compiler parameters. + */ + public static void main(String[] args) + { + // Check for the -iiop or -giop keys. If one of these keys is present, + // forward all call to GRMIC. + for (int i = 0; i < args.length; i++) + { + if (args[i].equals("-giop") || args[i].equals("-iiop")) + { + GRMIC.main(args); + return; + } + } + + boolean noWrite = false; + boolean verbose = false; + + String HelpPath = "rmi/RMIC.txt"; + + HelpPrinter.checkHelpKey(args, HelpPath); + + File output = new File("."); + + if (args.length == 0) + { + HelpPrinter.printHelpAndExit(HelpPath); + } + else + { + RmicCompiler compiler = new RmicCompiler(); + + int cl = - 1; + + Options: for (int i = 0; i < args.length; i++) + { + String c = args[i]; + if (c.equals("-v")) + { + printVersion(); + System.exit(0); + } + else if (c.equals("-nowrite")) + noWrite = true; + else if (c.equals("-nowarn")) + compiler.setWarnings(false); + else if (c.equals("-verbose")) + { + verbose = true; + compiler.setVerbose(true); + } + else if (c.equals("-d")) + { + int f = i + 1; + if (f < args.length) + { + output = new File(args[f]); + i++; + } + else + HelpPrinter.printHelpAndExit(HelpPath); + } + else if (c.charAt(0) != '-') + // No more options - start of class list. + { + cl = i; + break Options; + } + } + + if (cl < 0) + HelpPrinter.printHelpAndExit(HelpPath); + + if (verbose) + System.out.println("Compiling to " + output.getAbsolutePath()); + + // Compile classes + Compile: for (int i = cl; i < args.length; i++) + { + if (args[i].charAt(0) != '-') + { + compiler.reset(); + Class c = null; + try + { + c = Thread.currentThread().getContextClassLoader().loadClass( + args[i]); + } + catch (ClassNotFoundException e) + { + System.err.println(args[i] + " class not found."); + System.exit(1); + } + + compiler.compile(c); + String packag = compiler.getPackageName().replace('.', '/'); + File fw = new File(output, packag); + + // Generate stub. + String stub = compiler.generateStub(); + String subName = compiler.getStubName() + "_Stub.java"; + + if (noWrite) + continue Compile; + + try + { + fw.mkdirs(); + OutputStream out = new FileOutputStream(new File(fw, + subName)); + out.write(stub.getBytes()); + out.close(); + } + catch (IOException ioex) + { + System.err.println("Output path not accessible"); + ioex.printStackTrace(); + System.exit(1); + } + } + } + } + } + + /** + * Print the version information. + */ + public static void printVersion() + { + System.out.println + ("rmic v "+VERSION+" - RMI stub generator for java.rmi.* "); + } +} diff --git a/tools/gnu/classpath/tools/rmi/RMIC.txt b/tools/gnu/classpath/tools/rmi/RMIC.txt new file mode 100644 index 000000000..df1de9ea6 --- /dev/null +++ b/tools/gnu/classpath/tools/rmi/RMIC.txt @@ -0,0 +1,39 @@ +RMI stub and tie source code generator for java.rmi.*, javax.rmi.* + +Copyright 2006 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +Please report bugs at http://www.gnu.org/software/classpath/bugs.html + +Usage: rmic <options> <class names> + + where <options> includes: + -nowarn Show no warnings + -nowrite Do not write any files (check for errors only) + -d <folder> Place generated files into the given folder + + -help Print this help text + -v Print version + -verbose Verbose output + + -1.2 Generate v 1.2 stubs (default)* + + -iiop Generate stubs and ties for the GIOP based RMI package extension, + javax.rmi. With this key, the two additional keys are accepted: + -poa Generate the Servant based ties (default) + -impl Generate the obsoleted ObjectImpl based ties + (for backward compatibility) + -help Show more details on the giop stub and tie generator options. + -giop Same as -iiop* + + + and <class names> can include one or more non abstract classes that implement + Remote and are accessible via current class path. + +* This tool generates the source code that must be compiled with java compiler. +* The deprecated 1.1 version stubs are currently not supported (the v 1.2 + style stubs are always generated). +* -iiop is a standard key for this tool, but it is also a registered OMG mark + when giop is not. + diff --git a/tools/gnu/classpath/tools/rmi/rmic/RmiMethodGenerator.java b/tools/gnu/classpath/tools/rmi/rmic/RmiMethodGenerator.java new file mode 100644 index 000000000..9b7f9358b --- /dev/null +++ b/tools/gnu/classpath/tools/rmi/rmic/RmiMethodGenerator.java @@ -0,0 +1,299 @@ +/* MethodGenerator.java -- Generates methods for rmi compiler. + Copyright (C) 2006 Free Software Foundation + + This file is part of GNU Classpath. + + GNU Classpath is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU Classpath 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 for more details. + + You should have received a copy of the GNU General Public License + along with GNU Classpath; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. */ + + +package gnu.classpath.tools.rmi.rmic; + +import gnu.classpath.tools.AbstractMethodGenerator; +import gnu.java.rmi.server.RMIHashes; + +import java.lang.reflect.Method; +import java.util.Properties; +import java.util.zip.Adler32; + +/** + * Keeps information about the single method and generates the code fragments, + * related to that method. + * + * @author Audrius Meskauskas, Lithuania (audriusa@Bioinformatics.org) + */ +public class RmiMethodGenerator + implements AbstractMethodGenerator +{ + /** + * The method being defined. + */ + Method method; + + /** + * The parent code generator. + */ + RmicCompiler rmic; + + /** + * Create the new method generator for the given method. + * + * @param aMethod the related method. + * @param aRmic the Rmic generator instance, where more class - related + * information is defined. + */ + public RmiMethodGenerator(Method aMethod, RmicCompiler aRmic) + { + method = aMethod; + rmic = aRmic; + if (method.getParameterTypes().length == 0) + rmic.addZeroSizeObjecArray = true; + } + + /** + * Get the method parameter declaration. + * + * @return the string - method parameter declaration. + */ + public String getArgumentList() + { + StringBuffer b = new StringBuffer(); + + Class[] args = method.getParameterTypes(); + + for (int i = 0; i < args.length; i++) + { + b.append(rmic.name(args[i])); + b.append(" p" + i); + if (i < args.length - 1) + b.append(", "); + } + return b.toString(); + } + + /** + * Get the method parameter list only (no type declarations). This is used to + * generate the method invocations statement. + * + * @return the string - method parameter list. + */ + public String getArgumentNames() + { + StringBuffer b = new StringBuffer(); + + Class[] args = method.getParameterTypes(); + + for (int i = 0; i < args.length; i++) + { + b.append(" p" + i); + if (i < args.length - 1) + b.append(", "); + } + return b.toString(); + } + + /** + * Get the list of exceptions, thrown by this method. + * + * @return the list of exceptions. + */ + public String getThrows() + { + StringBuffer b = new StringBuffer(); + + Class[] args = method.getExceptionTypes(); + + for (int i = 0; i < args.length; i++) + { + b.append(rmic.name(args[i])); + if (i < args.length - 1) + b.append(", "); + } + return b.toString(); + } + + /** + * Generate this method for the Stub class. + * + * @return the method body for the stub class. + */ + public String generateStubMethod() + { + String templateName; + + Properties vars = new Properties(rmic.vars); + vars.put("#return_type", rmic.name(method.getReturnType())); + vars.put("#method_name", method.getName()); + vars.put("#method_hash", getMethodHashCode()); + vars.put("#argument_list", getArgumentList()); + vars.put("#object_arg_list", getArgListAsObjectArray()); + vars.put("#declaring_class", rmic.name(method.getDeclaringClass())); + vars.put("#class_arg_list", getArgListAsClassArray()); + + String thr = getThrows(); + if (thr.length() > 0) + vars.put("#throws", "\n throws " + thr); + else + vars.put("#throws", ""); + + if (method.getReturnType().equals(void.class)) + templateName = "Stub_12MethodVoid.jav"; + else + { + templateName = "Stub_12Method.jav"; + vars.put("#return_statement", getReturnStatement()); + } + + String template = rmic.getResource(templateName); + String generated = rmic.replaceAll(template, vars); + return generated; + } + + /** + * Generate sentences for Reading and Defining Arguments. + * + * @return the sequence of sentences for reading and defining arguments. + */ + public String getStaticMethodDeclarations() + { + StringBuffer b = new StringBuffer(); + Class[] args = method.getParameterTypes(); + + for (int i = 0; i < args.length; i++) + { + b.append(" "); + b.append(rmic.name(args[i])); + b.append(" "); + b.append("p" + i); + b.append(" = "); + if (i < args.length - 1) + b.append("\n"); + } + return b.toString(); + } + + /** + * Get the write statement for writing parameters inside the stub. + * + * @return the write statement. + */ + public String getArgListAsObjectArray() + { + Class[] args = method.getParameterTypes(); + + if (args.length==0) + return "NO_ARGS"; + + StringBuffer b = new StringBuffer("new Object[] {"); + + for (int i = 0; i < args.length; i++) + { + if (!args[i].isPrimitive()) + b.append("p"+i); + else + { + b.append("new "+rmic.name(WrapUnWrapper.getWrappingClass(args[i]))); + b.append("(p"+i+")"); + } + if (i<args.length-1) + b.append(", "); + } + b.append("}"); + return b.toString(); + } + + /** + * Get the return statement, assuming that the returned object is placed into + * the variable "result". + */ + public String getReturnStatement() + { + Class r = method.getReturnType(); + if (r.equals(void.class)) + return ""; + else + { + if (r.isPrimitive()) + { + String wcd = rmic.name(WrapUnWrapper.getWrappingClass(r)); + return "return ((" + wcd + ") result)." + + WrapUnWrapper.getUnwrappingMethod(r) + ";"; + } + else + return "return (" + rmic.name(r) + ") result;"; + } + } + + /** + * Get argument list as class array. + */ + public String getArgListAsClassArray() + { + StringBuffer b = new StringBuffer(); + Class[] args = method.getParameterTypes(); + + for (int i = 0; i < args.length; i++) + { + b.append(rmic.name(args[i])); + b.append(".class"); + if (i < args.length - 1) + b.append(", "); + } + return b.toString(); + } + + /** + * RMI ties (previously named Skeletons) are no longer used since v 1.2. This + * method should never be called. + */ + public String generateTieMethod() + { + throw new InternalError(); + } + + /** + * Get the method hash code. + */ + public String getMethodHashCode() + { + return RMIHashes.getMethodHash(method)+"L"; + } + + /** + * Additional processing of the stub name (nothing to do for JRMP stubs). + */ + public String convertStubName(String name) + { + return name; + } + +} diff --git a/tools/gnu/classpath/tools/rmi/rmic/RmicCompiler.java b/tools/gnu/classpath/tools/rmi/rmic/RmicCompiler.java new file mode 100644 index 000000000..498dff7b2 --- /dev/null +++ b/tools/gnu/classpath/tools/rmi/rmic/RmicCompiler.java @@ -0,0 +1,182 @@ +/* RmicCompiler.java -- RMI stub generator for java.rmi.* + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.classpath.tools.rmi.rmic; + +import java.lang.reflect.Method; +import java.util.Iterator; + +import gnu.classpath.tools.AbstractMethodGenerator; +import gnu.classpath.tools.giop.grmic.GiopRmicCompiler; + +/** + * RMI stub source code generator, required to support java.rmi.* + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class RmicCompiler extends GiopRmicCompiler +{ + /** + * If true, the zero size object array is declared in the stub to reduce + * garbage generation. + */ + public boolean addZeroSizeObjecArray; + + /** + * Generate a RMI stub. + * + * @return the string, containing the text of the generated stub. + */ + public String generateStub() + { + String template = getResource("Stub_12.jav"); + + // Generate methods. + StringBuffer b = new StringBuffer(); + Iterator iter = methods.iterator(); + while (iter.hasNext()) + { + RmiMethodGenerator m = (RmiMethodGenerator) iter.next(); + b.append(m.generateStubMethod()); + } + + vars.put("#stub_methods", b.toString()); + vars.put("#imports", getImportStatements()); + vars.put("#interfaces", getAllInterfaces()); + vars.put("#stub_method_declarations", getStubMethodDeclarations()); + vars.put("#stub_method_initializations", getStubMethodInitializations()); + if (addZeroSizeObjecArray) + { + vars.put("#zeroSizeObjecArray", + "private static final Object[] NO_ARGS = new Object[0];"); + vars.put("#zeroSizeClassArray", + "final Class[] NO_ARGSc = new Class[0];"); + } + else + { + vars.put("#zeroSizeObjecArray",""); + vars.put("#zeroSizeClassArray",""); + } + + String output = replaceAll(template, vars); + return output; + } + + /** + * Create a method generator, applicable for RMI stub methods. + */ + protected AbstractMethodGenerator createMethodGenerator(Method m) + { + return new RmiMethodGenerator(m, this); + } + + /** + * Get the stub method declarations. + */ + public String getStubMethodDeclarations() + { + StringBuffer b = new StringBuffer(); + + Iterator iter = methods.iterator(); + + while (iter.hasNext()) + { + RmiMethodGenerator method = (RmiMethodGenerator) iter.next(); + b.append(" "); + b.append("private static final Method met_"); + b.append(method.method.getName()); + b.append(';'); + if (iter.hasNext()) + b.append('\n'); + } + return b.toString(); + } + + /** + * Get stub method initializations. These must be done in a try-catch + * statement to catch {@link NoSuchMethodException}. + */ + public String getStubMethodInitializations() + { + StringBuffer b = new StringBuffer(); + + Iterator iter = methods.iterator(); + + while (iter.hasNext()) + { + RmiMethodGenerator method = (RmiMethodGenerator) iter.next(); + b.append(" "); + b.append("met_"); + b.append(method.method.getName()); + b.append(" =\n "); + b.append(name(method.method.getDeclaringClass())); + b.append(".class.getMethod("); + b.append('"'); + b.append(method.method.getName()); + b.append("\", "); + if (method.method.getParameterTypes().length == 0) + b.append("NO_ARGSc);"); + else + { + b.append("new Class[]\n {\n "); + b.append(method.getArgListAsClassArray()); + b.append("\n }"); + b.append(");"); + } + b.append('\n'); + } + return b.toString(); + } + + /** + * Prepare for the compilation of the next class. + */ + public void reset() + { + addZeroSizeObjecArray = false; + super.reset(); + } + + /** + * Additional processing of the stub name (nothing to do for JRMP stubs). + */ + public String convertStubName(String name) + { + return name; + } +} diff --git a/tools/gnu/classpath/tools/rmi/rmic/WrapUnWrapper.java b/tools/gnu/classpath/tools/rmi/rmic/WrapUnWrapper.java new file mode 100644 index 000000000..6451a7074 --- /dev/null +++ b/tools/gnu/classpath/tools/rmi/rmic/WrapUnWrapper.java @@ -0,0 +1,100 @@ +/* WrapUnWrapper.java -- Wrapper and unwrapper for primitive types. + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.classpath.tools.rmi.rmic; + +import java.lang.reflect.Method; + +public class WrapUnWrapper +{ + /** + * Get the wrapper class for the primitive type + * + * @param primitive the class of the primitive type + * + * @return the wrapper class + */ + public static Class getWrappingClass(Class primitive) + { + if (primitive.equals(byte.class)) + return Byte.class; + if (primitive.equals(int.class)) + return Integer.class; + if (primitive.equals(long.class)) + return Long.class; + if (primitive.equals(boolean.class)) + return Boolean.class; + if (primitive.equals(double.class)) + return Double.class; + if (primitive.equals(float.class)) + return Float.class; + if (primitive.equals(char.class)) + return Character.class; + else + return null; + } + + /** + * Get the method, invocation of that would return the wrapped value. + * + * @param primitive the class of the primitive type. + * + * @return the wrapper method that unwraps the value to the primitive type. + */ + public static String getUnwrappingMethod(Class primitive) + { + if (primitive.equals(byte.class)) + return "byteValue()"; + if (primitive.equals(int.class)) + return "intValue()"; + if (primitive.equals(long.class)) + return "longValue()"; + if (primitive.equals(boolean.class)) + return "booleanValue()"; + if (primitive.equals(double.class)) + return "doubleValue()"; + if (primitive.equals(float.class)) + return "floatValue()"; + if (primitive.equals(char.class)) + return "charValue()"; + else + return null; + } + + +} diff --git a/tools/gnu/classpath/tools/rmi/rmic/templates/Stub_12.jav b/tools/gnu/classpath/tools/rmi/rmic/templates/Stub_12.jav new file mode 100644 index 000000000..1c55a0597 --- /dev/null +++ b/tools/gnu/classpath/tools/rmi/rmic/templates/Stub_12.jav @@ -0,0 +1,62 @@ +package #package; + +#imports +import java.lang.reflect.Method; +import java.rmi.server.RemoteRef; +import java.rmi.server.RemoteStub; +import java.rmi.UnexpectedException; + +/** + * This class delegates its method calls to the remote RMI object, referenced + * by {@link RemoteRef}. + * + * It is normally generated with rmic. + */ +public final class #name_Stub + extends RemoteStub + implements #interfaces +{ + /** + * Use serialVersionUID for interoperability + */ + private static final long serialVersionUID = 2; + + /** + * The explaining message for {@ling UnexpectedException}. + */ + private static final String exception_message = + "undeclared checked exception"; + + /* All remote methods, invoked by this stub: */ +#stub_method_declarations + #zeroSizeObjecArray + static + { + #zeroSizeClassArray + try + { +#stub_method_initializations + } + catch (NoSuchMethodException nex) + { + NoSuchMethodError err = new NoSuchMethodError( + "#name_Stub class initialization failed"); + err.initCause(nex); + throw err; + } + } + + /** + * Create the instance for _#name_Stub that forwards method calls to the + * remote object. + * + * @para the reference to the remote object. + */ + public #name_Stub(RemoteRef reference) + { + super(reference); + } + + /* Methods */ +#stub_methods +} diff --git a/tools/gnu/classpath/tools/rmi/rmic/templates/Stub_12Method.jav b/tools/gnu/classpath/tools/rmi/rmic/templates/Stub_12Method.jav new file mode 100644 index 000000000..1069884b9 --- /dev/null +++ b/tools/gnu/classpath/tools/rmi/rmic/templates/Stub_12Method.jav @@ -0,0 +1,26 @@ + /** @inheritDoc */ + public #return_type #method_name(#argument_list) #throws + { + try + { + Object result = ref.invoke(this, met_#method_name, + #object_arg_list, + #method_hash); + #return_statement + } + catch (RuntimeException e) + { + throw e; + } + catch (RemoteException e) + { + throw e; + } + catch (Exception e) + { + UnexpectedException uex = new UnexpectedException(exception_message); + uex.initCause(e); + throw uex; + } + } +
\ No newline at end of file diff --git a/tools/gnu/classpath/tools/rmi/rmic/templates/Stub_12MethodVoid.jav b/tools/gnu/classpath/tools/rmi/rmic/templates/Stub_12MethodVoid.jav new file mode 100644 index 000000000..f67098a4f --- /dev/null +++ b/tools/gnu/classpath/tools/rmi/rmic/templates/Stub_12MethodVoid.jav @@ -0,0 +1,25 @@ + /** @inheritDoc */ + public void #method_name(#argument_list) #throws + { + try + { + ref.invoke(this, met_#method_name, + #object_arg_list, + #method_hash); + } + catch (RuntimeException e) + { + throw e; + } + catch (RemoteException e) + { + throw e; + } + catch (Exception e) + { + UnexpectedException uex = new UnexpectedException(exception_message); + uex.initCause(e); + throw uex; + } + } +
\ No newline at end of file |