aboutsummaryrefslogtreecommitdiff
path: root/src/share/classes/sun/rmi/rmic/newrmic/jrmp/JrmpGenerator.java
diff options
context:
space:
mode:
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.java226
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);
+ }
+ }
+}