diff options
Diffstat (limited to 'src/share/classes/sun/rmi/rmic/newrmic/jrmp/JrmpGenerator.java')
-rw-r--r-- | src/share/classes/sun/rmi/rmic/newrmic/jrmp/JrmpGenerator.java | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/src/share/classes/sun/rmi/rmic/newrmic/jrmp/JrmpGenerator.java b/src/share/classes/sun/rmi/rmic/newrmic/jrmp/JrmpGenerator.java new file mode 100644 index 000000000..49e83a4bd --- /dev/null +++ b/src/share/classes/sun/rmi/rmic/newrmic/jrmp/JrmpGenerator.java @@ -0,0 +1,226 @@ +/* + * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package sun.rmi.rmic.newrmic.jrmp; + +import com.sun.javadoc.ClassDoc; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import sun.rmi.rmic.newrmic.BatchEnvironment; +import sun.rmi.rmic.newrmic.Generator; +import sun.rmi.rmic.newrmic.IndentingWriter; +import sun.rmi.rmic.newrmic.Main; +import sun.rmi.rmic.newrmic.Resources; + +import static sun.rmi.rmic.newrmic.jrmp.Constants.*; + +/** + * JRMP rmic back end; generates source code for JRMP stub and + * skeleton classes. + * + * WARNING: The contents of this source file are not part of any + * supported API. Code that depends on them does so at its own risk: + * they are subject to change or removal without notice. + * + * @author Peter Jones + **/ +public class JrmpGenerator implements Generator { + + private static final Map<String,StubVersion> versionOptions = + new HashMap<String,StubVersion>(); + static { + versionOptions.put("-v1.1", StubVersion.V1_1); + versionOptions.put("-vcompat", StubVersion.VCOMPAT); + versionOptions.put("-v1.2", StubVersion.V1_2); + } + + private static final Set<String> bootstrapClassNames = + new HashSet<String>(); + static { + bootstrapClassNames.add("java.lang.Exception"); + bootstrapClassNames.add("java.rmi.Remote"); + bootstrapClassNames.add("java.rmi.RemoteException"); + bootstrapClassNames.add("java.lang.RuntimeException"); + }; + + /** version of the JRMP stub protocol to generate code for */ + private StubVersion version = StubVersion.V1_2; // default is -v1.2 + + /** + * Creates a new JrmpGenerator. + **/ + public JrmpGenerator() { } + + /** + * The JRMP generator recognizes command line options for + * selecting the JRMP stub protocol version to generate classes + * for. Only one such option is allowed. + **/ + public boolean parseArgs(String[] args, Main main) { + String explicitVersion = null; + for (int i = 0; i < args.length; i++) { + String arg = args[i]; + if (versionOptions.containsKey(arg)) { + if (explicitVersion != null && !explicitVersion.equals(arg)) { + main.error("rmic.cannot.use.both", explicitVersion, arg); + return false; + } + explicitVersion = arg; + version = versionOptions.get(arg); + args[i] = null; + } + } + return true; + } + + /** + * The JRMP generator does not require an environment class more + * specific than BatchEnvironment. + **/ + public Class<? extends BatchEnvironment> envClass() { + return BatchEnvironment.class; + } + + public Set<String> bootstrapClassNames() { + return Collections.unmodifiableSet(bootstrapClassNames); + } + + /** + * Generates the source file(s) for the JRMP stub class and + * (optionally) skeleton class for the specified remote + * implementation class. + **/ + public void generate(BatchEnvironment env, + ClassDoc inputClass, + File destDir) + { + RemoteClass remoteClass = RemoteClass.forClass(env, inputClass); + if (remoteClass == null) { + return; // an error must have occurred + } + + StubSkeletonWriter writer = + new StubSkeletonWriter(env, remoteClass, version); + + File stubFile = sourceFileForClass(writer.stubClassName(), destDir); + try { + IndentingWriter out = new IndentingWriter( + new OutputStreamWriter(new FileOutputStream(stubFile))); + writer.writeStub(out); + out.close(); + if (env.verbose()) { + env.output(Resources.getText("rmic.wrote", + stubFile.getPath())); + } + env.addGeneratedFile(stubFile); + } catch (IOException e) { + env.error("rmic.cant.write", stubFile.toString()); + return; + } + + File skeletonFile = + sourceFileForClass(writer.skeletonClassName(), destDir); + if (version == StubVersion.V1_1 || + version == StubVersion.VCOMPAT) + { + try { + IndentingWriter out = new IndentingWriter( + new OutputStreamWriter( + new FileOutputStream(skeletonFile))); + writer.writeSkeleton(out); + out.close(); + if (env.verbose()) { + env.output(Resources.getText("rmic.wrote", + skeletonFile.getPath())); + } + env.addGeneratedFile(skeletonFile); + } catch (IOException e) { + env.error("rmic.cant.write", skeletonFile.toString()); + return; + } + } else { + /* + * If skeleton files are not being generated for this run, + * delete old skeleton source or class files for this + * remote implementation class that were (presumably) left + * over from previous runs, to avoid user confusion from + * extraneous or inconsistent generated files. + */ + File skeletonClassFile = + classFileForClass(writer.skeletonClassName(), destDir); + + skeletonFile.delete(); // ignore failures (no big deal) + skeletonClassFile.delete(); + } + } + + + /** + * Returns the File object to be used as the source file for a + * class with the specified binary name, with the specified + * destination directory as the top of the package hierarchy. + **/ + private File sourceFileForClass(String binaryName, File destDir) { + return fileForClass(binaryName, destDir, ".java"); + } + + /** + * Returns the File object to be used as the class file for a + * class with the specified binary name, with the supplied + * destination directory as the top of the package hierarchy. + **/ + private File classFileForClass(String binaryName, File destDir) { + return fileForClass(binaryName, destDir, ".class"); + } + + private File fileForClass(String binaryName, File destDir, String ext) { + int i = binaryName.lastIndexOf('.'); + String classFileName = binaryName.substring(i + 1) + ext; + if (i != -1) { + String packageName = binaryName.substring(0, i); + String packagePath = packageName.replace('.', File.separatorChar); + File packageDir = new File(destDir, packagePath); + /* + * Make sure that the directory for this package exists. + * We assume that the caller has verified that the top- + * level destination directory exists, so we need not + * worry about creating it unintentionally. + */ + if (!packageDir.exists()) { + packageDir.mkdirs(); + } + return new File(packageDir, classFileName); + } else { + return new File(destDir, classFileName); + } + } +} |