feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
445
jdkSrc/jdk8/sun/rmi/rmic/BatchEnvironment.java
Normal file
445
jdkSrc/jdk8/sun/rmi/rmic/BatchEnvironment.java
Normal file
@@ -0,0 +1,445 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Copyright (c) IBM Corporation 1998 */
|
||||
/* */
|
||||
/* (C) Copyright IBM Corp. 1998 */
|
||||
/* */
|
||||
/*****************************************************************************/
|
||||
|
||||
package sun.rmi.rmic;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Collection;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.Vector;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.jar.Manifest;
|
||||
import java.util.jar.Attributes;
|
||||
import sun.tools.java.ClassPath;
|
||||
|
||||
/**
|
||||
* BatchEnvironment for rmic extends javac's version in four ways:
|
||||
* 1. It overrides errorString() to handle looking for rmic-specific
|
||||
* error messages in rmic's resource bundle
|
||||
* 2. It provides a mechanism for recording intermediate generated
|
||||
* files so that they can be deleted later.
|
||||
* 3. It holds a reference to the Main instance so that generators
|
||||
* can refer to it.
|
||||
* 4. It provides access to the ClassPath passed to the constructor.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
public class BatchEnvironment extends sun.tools.javac.BatchEnvironment {
|
||||
|
||||
/** instance of Main which created this environment */
|
||||
private Main main;
|
||||
|
||||
/**
|
||||
* Create a ClassPath object for rmic from a class path string.
|
||||
*/
|
||||
public static ClassPath createClassPath(String classPathString) {
|
||||
ClassPath[] paths = classPaths(null, classPathString, null, null);
|
||||
return paths[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a ClassPath object for rmic from the relevant command line
|
||||
* options for class path, boot class path, and extension directories.
|
||||
*/
|
||||
public static ClassPath createClassPath(String classPathString,
|
||||
String sysClassPathString,
|
||||
String extDirsString)
|
||||
{
|
||||
/**
|
||||
* Previously, this method delegated to the
|
||||
* sun.tools.javac.BatchEnvironment.classPaths method in order
|
||||
* to supply default values for paths not specified on the
|
||||
* command line, expand extensions directories into specific
|
||||
* JAR files, and construct the ClassPath object-- but as part
|
||||
* of the fix for 6473331, which adds support for Class-Path
|
||||
* manifest entries in JAR files, those steps are now handled
|
||||
* here directly, with the help of a Path utility class copied
|
||||
* from the new javac implementation (see below).
|
||||
*/
|
||||
Path path = new Path();
|
||||
|
||||
if (sysClassPathString == null) {
|
||||
sysClassPathString = System.getProperty("sun.boot.class.path");
|
||||
}
|
||||
if (sysClassPathString != null) {
|
||||
path.addFiles(sysClassPathString);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class-Path manifest entries are supported for JAR files
|
||||
* everywhere except in the boot class path.
|
||||
*/
|
||||
path.expandJarClassPaths(true);
|
||||
|
||||
if (extDirsString == null) {
|
||||
extDirsString = System.getProperty("java.ext.dirs");
|
||||
}
|
||||
if (extDirsString != null) {
|
||||
path.addDirectories(extDirsString);
|
||||
}
|
||||
|
||||
/*
|
||||
* In the application class path, an empty element means
|
||||
* the current working directory.
|
||||
*/
|
||||
path.emptyPathDefault(".");
|
||||
|
||||
if (classPathString == null) {
|
||||
// The env.class.path property is the user's CLASSPATH
|
||||
// environment variable, and it set by the wrapper (ie,
|
||||
// javac.exe).
|
||||
classPathString = System.getProperty("env.class.path");
|
||||
if (classPathString == null) {
|
||||
classPathString = ".";
|
||||
}
|
||||
}
|
||||
path.addFiles(classPathString);
|
||||
|
||||
return new ClassPath(path.toArray(new String[path.size()]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a BatchEnvironment for rmic with the given class path,
|
||||
* stream for messages and Main.
|
||||
*/
|
||||
public BatchEnvironment(OutputStream out, ClassPath path, Main main) {
|
||||
super(out, new ClassPath(""), path);
|
||||
// use empty "sourcePath" (see 4666958)
|
||||
this.main = main;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the instance of Main which created this environment.
|
||||
*/
|
||||
public Main getMain() {
|
||||
return main;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ClassPath.
|
||||
*/
|
||||
public ClassPath getClassPath() {
|
||||
return binaryPath;
|
||||
}
|
||||
|
||||
/** list of generated source files created in this environment */
|
||||
private Vector<File> generatedFiles = new Vector<>();
|
||||
|
||||
/**
|
||||
* Remember a generated source file generated so that it
|
||||
* can be removed later, if appropriate.
|
||||
*/
|
||||
public void addGeneratedFile(File file) {
|
||||
generatedFiles.addElement(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all the generated source files made during the execution
|
||||
* of this environment (those that have been registered with the
|
||||
* "addGeneratedFile" method).
|
||||
*/
|
||||
public void deleteGeneratedFiles() {
|
||||
synchronized(generatedFiles) {
|
||||
Enumeration<File> enumeration = generatedFiles.elements();
|
||||
while (enumeration.hasMoreElements()) {
|
||||
File file = enumeration.nextElement();
|
||||
file.delete();
|
||||
}
|
||||
generatedFiles.removeAllElements();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Release resources, if any.
|
||||
*/
|
||||
public void shutdown() {
|
||||
main = null;
|
||||
generatedFiles = null;
|
||||
super.shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the formatted, localized string for a named error message
|
||||
* and supplied arguments. For rmic error messages, with names that
|
||||
* being with "rmic.", look up the error message in rmic's resource
|
||||
* bundle; otherwise, defer to java's superclass method.
|
||||
*/
|
||||
public String errorString(String err,
|
||||
Object arg0, Object arg1, Object arg2)
|
||||
{
|
||||
if (err.startsWith("rmic.") || err.startsWith("warn.rmic.")) {
|
||||
String result = Main.getText(err,
|
||||
(arg0 != null ? arg0.toString() : null),
|
||||
(arg1 != null ? arg1.toString() : null),
|
||||
(arg2 != null ? arg2.toString() : null));
|
||||
|
||||
if (err.startsWith("warn.")) {
|
||||
result = "warning: " + result;
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
return super.errorString(err, arg0, arg1, arg2);
|
||||
}
|
||||
}
|
||||
public void reset() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility for building paths of directories and JAR files. This
|
||||
* class was copied from com.sun.tools.javac.util.Paths as part of
|
||||
* the fix for 6473331, which adds support for Class-Path manifest
|
||||
* entries in JAR files. Diagnostic code is simply commented out
|
||||
* because rmic silently ignored these conditions historically.
|
||||
*/
|
||||
private static class Path extends LinkedHashSet<String> {
|
||||
private static final long serialVersionUID = 0;
|
||||
private static final boolean warn = false;
|
||||
|
||||
private static class PathIterator implements Collection<String> {
|
||||
private int pos = 0;
|
||||
private final String path;
|
||||
private final String emptyPathDefault;
|
||||
|
||||
public PathIterator(String path, String emptyPathDefault) {
|
||||
this.path = path;
|
||||
this.emptyPathDefault = emptyPathDefault;
|
||||
}
|
||||
public PathIterator(String path) { this(path, null); }
|
||||
public Iterator<String> iterator() {
|
||||
return new Iterator<String>() {
|
||||
public boolean hasNext() {
|
||||
return pos <= path.length();
|
||||
}
|
||||
public String next() {
|
||||
int beg = pos;
|
||||
int end = path.indexOf(File.pathSeparator, beg);
|
||||
if (end == -1)
|
||||
end = path.length();
|
||||
pos = end + 1;
|
||||
|
||||
if (beg == end && emptyPathDefault != null)
|
||||
return emptyPathDefault;
|
||||
else
|
||||
return path.substring(beg, end);
|
||||
}
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// required for Collection.
|
||||
public int size() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
public boolean isEmpty() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
public boolean contains(Object o) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
public Object[] toArray() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
public <T> T[] toArray(T[] a) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
public boolean add(String o) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
public boolean remove(Object o) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
public boolean containsAll(Collection<?> c) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
public boolean addAll(Collection<? extends String> c) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
public boolean removeAll(Collection<?> c) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
public boolean retainAll(Collection<?> c) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
public void clear() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
public boolean equals(Object o) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
public int hashCode() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
/** Is this the name of a zip file? */
|
||||
private static boolean isZip(String name) {
|
||||
return new File(name).isFile();
|
||||
}
|
||||
|
||||
private boolean expandJarClassPaths = false;
|
||||
|
||||
public Path expandJarClassPaths(boolean x) {
|
||||
expandJarClassPaths = x;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** What to use when path element is the empty string */
|
||||
private String emptyPathDefault = null;
|
||||
|
||||
public Path emptyPathDefault(String x) {
|
||||
emptyPathDefault = x;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Path() { super(); }
|
||||
|
||||
public Path addDirectories(String dirs, boolean warn) {
|
||||
if (dirs != null)
|
||||
for (String dir : new PathIterator(dirs))
|
||||
addDirectory(dir, warn);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Path addDirectories(String dirs) {
|
||||
return addDirectories(dirs, warn);
|
||||
}
|
||||
|
||||
private void addDirectory(String dir, boolean warn) {
|
||||
if (! new File(dir).isDirectory()) {
|
||||
// if (warn)
|
||||
// log.warning(Position.NOPOS,
|
||||
// "dir.path.element.not.found", dir);
|
||||
return;
|
||||
}
|
||||
|
||||
for (String direntry : new File(dir).list()) {
|
||||
String canonicalized = direntry.toLowerCase();
|
||||
if (canonicalized.endsWith(".jar") ||
|
||||
canonicalized.endsWith(".zip"))
|
||||
addFile(dir + File.separator + direntry, warn);
|
||||
}
|
||||
}
|
||||
|
||||
public Path addFiles(String files, boolean warn) {
|
||||
if (files != null)
|
||||
for (String file : new PathIterator(files, emptyPathDefault))
|
||||
addFile(file, warn);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Path addFiles(String files) {
|
||||
return addFiles(files, warn);
|
||||
}
|
||||
|
||||
private void addFile(String file, boolean warn) {
|
||||
if (contains(file)) {
|
||||
/* Discard duplicates and avoid infinite recursion */
|
||||
return;
|
||||
}
|
||||
|
||||
File ele = new File(file);
|
||||
if (! ele.exists()) {
|
||||
/* No such file or directory exist */
|
||||
if (warn)
|
||||
// log.warning(Position.NOPOS,
|
||||
// "path.element.not.found", file);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ele.isFile()) {
|
||||
/* File is an ordinay file */
|
||||
String arcname = file.toLowerCase();
|
||||
if (! (arcname.endsWith(".zip") ||
|
||||
arcname.endsWith(".jar"))) {
|
||||
/* File name don't have right extension */
|
||||
// if (warn)
|
||||
// log.warning(Position.NOPOS,
|
||||
// "invalid.archive.file", file);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now what we have left is either a directory or a file name
|
||||
confirming to archive naming convention */
|
||||
|
||||
super.add(file);
|
||||
if (expandJarClassPaths && isZip(file))
|
||||
addJarClassPath(file, warn);
|
||||
}
|
||||
|
||||
// Adds referenced classpath elements from a jar's Class-Path
|
||||
// Manifest entry. In some future release, we may want to
|
||||
// update this code to recognize URLs rather than simple
|
||||
// filenames, but if we do, we should redo all path-related code.
|
||||
private void addJarClassPath(String jarFileName, boolean warn) {
|
||||
try {
|
||||
String jarParent = new File(jarFileName).getParent();
|
||||
JarFile jar = new JarFile(jarFileName);
|
||||
|
||||
try {
|
||||
Manifest man = jar.getManifest();
|
||||
if (man == null) return;
|
||||
|
||||
Attributes attr = man.getMainAttributes();
|
||||
if (attr == null) return;
|
||||
|
||||
String path = attr.getValue(Attributes.Name.CLASS_PATH);
|
||||
if (path == null) return;
|
||||
|
||||
for (StringTokenizer st = new StringTokenizer(path);
|
||||
st.hasMoreTokens();) {
|
||||
String elt = st.nextToken();
|
||||
if (jarParent != null)
|
||||
elt = new File(jarParent, elt).getCanonicalPath();
|
||||
addFile(elt, warn);
|
||||
}
|
||||
} finally {
|
||||
jar.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// log.error(Position.NOPOS,
|
||||
// "error.reading.file", jarFileName,
|
||||
// e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
44
jdkSrc/jdk8/sun/rmi/rmic/Constants.java
Normal file
44
jdkSrc/jdk8/sun/rmi/rmic/Constants.java
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.rmi.rmic;
|
||||
|
||||
import sun.tools.java.Identifier;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
public interface Constants extends sun.tools.java.Constants {
|
||||
|
||||
/*
|
||||
* Identifiers potentially useful for all Generators
|
||||
*/
|
||||
public static final Identifier idRemote =
|
||||
Identifier.lookup("java.rmi.Remote");
|
||||
public static final Identifier idRemoteException =
|
||||
Identifier.lookup("java.rmi.RemoteException");
|
||||
}
|
||||
79
jdkSrc/jdk8/sun/rmi/rmic/Generator.java
Normal file
79
jdkSrc/jdk8/sun/rmi/rmic/Generator.java
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Licensed Materials - Property of IBM
|
||||
* RMI-IIOP v1.0
|
||||
* Copyright IBM Corp. 1998 1999 All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
package sun.rmi.rmic;
|
||||
|
||||
import java.io.File;
|
||||
import sun.tools.java.ClassDefinition;
|
||||
|
||||
/**
|
||||
* Generator defines the protocol for back-end implementations to be added
|
||||
* to rmic. See the rmic.properties file for a description of the format for
|
||||
* adding new Generators to rmic.
|
||||
* <p>
|
||||
* Classes implementing this interface must have a public default constructor
|
||||
* which should set any required arguments to their defaults. When Main
|
||||
* encounters a command line argument which maps to a specific Generator
|
||||
* subclass, it will instantiate one and call parseArgs(...). At some later
|
||||
* point, Main will invoke the generate(...) method once for _each_ class passed
|
||||
* on the command line.
|
||||
*
|
||||
* 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 Bryan Atsatt
|
||||
*/
|
||||
public interface Generator {
|
||||
|
||||
/**
|
||||
* Examine and consume command line arguments.
|
||||
* @param argv The command line arguments. Ignore null
|
||||
* and unknown arguments. Set each consumed argument to null.
|
||||
* @param main Report any errors using the main.error() methods.
|
||||
* @return true if no errors, false otherwise.
|
||||
*/
|
||||
public boolean parseArgs(String argv[], Main main);
|
||||
|
||||
/**
|
||||
* Generate output. Any source files created which need compilation should
|
||||
* be added to the compiler environment using the addGeneratedFile(File)
|
||||
* method.
|
||||
*
|
||||
* @param env The compiler environment
|
||||
* @param cdef The definition for the implementation class or interface from
|
||||
* which to generate output
|
||||
* @param destDir The directory for the root of the package hierarchy
|
||||
* for generated files. May be null.
|
||||
*/
|
||||
public void generate(BatchEnvironment env, ClassDefinition cdef, File destDir);
|
||||
}
|
||||
299
jdkSrc/jdk8/sun/rmi/rmic/IndentingWriter.java
Normal file
299
jdkSrc/jdk8/sun/rmi/rmic/IndentingWriter.java
Normal file
@@ -0,0 +1,299 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Copyright (c) IBM Corporation 1998 */
|
||||
/* */
|
||||
/* (C) Copyright IBM Corp. 1998 */
|
||||
/* */
|
||||
/*****************************************************************************/
|
||||
|
||||
package sun.rmi.rmic;
|
||||
|
||||
import java.io.Writer;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* IndentingWriter is a BufferedWriter subclass that supports automatic
|
||||
* indentation of lines of text written to the underlying Writer.
|
||||
*
|
||||
* Methods are provided for compact, convenient indenting, writing text,
|
||||
* and writing lines in various combinations.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
public class IndentingWriter extends BufferedWriter {
|
||||
|
||||
/** true if the next character written is the first on a line */
|
||||
private boolean beginningOfLine = true;
|
||||
|
||||
/** current number of spaces to prepend to lines */
|
||||
private int currentIndent = 0;
|
||||
|
||||
/** number of spaces to change indent when indenting in or out */
|
||||
private int indentStep = 4;
|
||||
|
||||
/** number of spaces to convert into tabs. Use MAX_VALUE to disable */
|
||||
private int tabSize = 8;
|
||||
|
||||
/**
|
||||
* Create a new IndentingWriter that writes indented text to the
|
||||
* given Writer. Use the default indent step of four spaces.
|
||||
*/
|
||||
public IndentingWriter(Writer out) {
|
||||
super(out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new IndentingWriter that writes indented text to the
|
||||
* given Writer and uses the supplied indent step.
|
||||
*/
|
||||
public IndentingWriter(Writer out, int step) {
|
||||
this(out);
|
||||
|
||||
if (indentStep < 0)
|
||||
throw new IllegalArgumentException("negative indent step");
|
||||
|
||||
indentStep = step;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new IndentingWriter that writes indented text to the
|
||||
* given Writer and uses the supplied indent step and tab size.
|
||||
*/
|
||||
public IndentingWriter(Writer out, int step, int tabSize) {
|
||||
this(out);
|
||||
|
||||
if (indentStep < 0)
|
||||
throw new IllegalArgumentException("negative indent step");
|
||||
|
||||
indentStep = step;
|
||||
this.tabSize = tabSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a single character.
|
||||
*/
|
||||
public void write(int c) throws IOException {
|
||||
checkWrite();
|
||||
super.write(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a portion of an array of characters.
|
||||
*/
|
||||
public void write(char[] cbuf, int off, int len) throws IOException {
|
||||
if (len > 0) {
|
||||
checkWrite();
|
||||
}
|
||||
super.write(cbuf, off, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a portion of a String.
|
||||
*/
|
||||
public void write(String s, int off, int len) throws IOException {
|
||||
if (len > 0) {
|
||||
checkWrite();
|
||||
}
|
||||
super.write(s, off, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a line separator. The next character written will be
|
||||
* preceded by an indent.
|
||||
*/
|
||||
public void newLine() throws IOException {
|
||||
super.newLine();
|
||||
beginningOfLine = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an indent needs to be written before writing the next
|
||||
* character.
|
||||
*
|
||||
* The indent generation is optimized (and made consistent with
|
||||
* certain coding conventions) by condensing groups of eight spaces
|
||||
* into tab characters.
|
||||
*/
|
||||
protected void checkWrite() throws IOException {
|
||||
if (beginningOfLine) {
|
||||
beginningOfLine = false;
|
||||
int i = currentIndent;
|
||||
while (i >= tabSize) {
|
||||
super.write('\t');
|
||||
i -= tabSize;
|
||||
}
|
||||
while (i > 0) {
|
||||
super.write(' ');
|
||||
-- i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Increase the current indent by the indent step.
|
||||
*/
|
||||
protected void indentIn() {
|
||||
currentIndent += indentStep;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrease the current indent by the indent step.
|
||||
*/
|
||||
protected void indentOut() {
|
||||
currentIndent -= indentStep;
|
||||
if (currentIndent < 0)
|
||||
currentIndent = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indent in.
|
||||
*/
|
||||
public void pI() {
|
||||
indentIn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indent out.
|
||||
*/
|
||||
public void pO() {
|
||||
indentOut();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write string.
|
||||
*/
|
||||
public void p(String s) throws IOException {
|
||||
write(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* End current line.
|
||||
*/
|
||||
public void pln() throws IOException {
|
||||
newLine();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write string; end current line.
|
||||
*/
|
||||
public void pln(String s) throws IOException {
|
||||
p(s);
|
||||
pln();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write string; end current line; indent in.
|
||||
*/
|
||||
public void plnI(String s) throws IOException {
|
||||
p(s);
|
||||
pln();
|
||||
pI();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indent out; write string.
|
||||
*/
|
||||
public void pO(String s) throws IOException {
|
||||
pO();
|
||||
p(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indent out; write string; end current line.
|
||||
*/
|
||||
public void pOln(String s) throws IOException {
|
||||
pO(s);
|
||||
pln();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indent out; write string; end current line; indent in.
|
||||
*
|
||||
* This method is useful for generating lines of code that both
|
||||
* end and begin nested blocks, like "} else {".
|
||||
*/
|
||||
public void pOlnI(String s) throws IOException {
|
||||
pO(s);
|
||||
pln();
|
||||
pI();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write Object.
|
||||
*/
|
||||
public void p(Object o) throws IOException {
|
||||
write(o.toString());
|
||||
}
|
||||
/**
|
||||
* Write Object; end current line.
|
||||
*/
|
||||
public void pln(Object o) throws IOException {
|
||||
p(o.toString());
|
||||
pln();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write Object; end current line; indent in.
|
||||
*/
|
||||
public void plnI(Object o) throws IOException {
|
||||
p(o.toString());
|
||||
pln();
|
||||
pI();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indent out; write Object.
|
||||
*/
|
||||
public void pO(Object o) throws IOException {
|
||||
pO();
|
||||
p(o.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Indent out; write Object; end current line.
|
||||
*/
|
||||
public void pOln(Object o) throws IOException {
|
||||
pO(o.toString());
|
||||
pln();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indent out; write Object; end current line; indent in.
|
||||
*
|
||||
* This method is useful for generating lines of code that both
|
||||
* end and begin nested blocks, like "} else {".
|
||||
*/
|
||||
public void pOlnI(Object o) throws IOException {
|
||||
pO(o.toString());
|
||||
pln();
|
||||
pI();
|
||||
}
|
||||
|
||||
}
|
||||
897
jdkSrc/jdk8/sun/rmi/rmic/Main.java
Normal file
897
jdkSrc/jdk8/sun/rmi/rmic/Main.java
Normal file
@@ -0,0 +1,897 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Licensed Materials - Property of IBM
|
||||
* RMI-IIOP v1.0
|
||||
* Copyright IBM Corp. 1998 1999 All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
package sun.rmi.rmic;
|
||||
|
||||
import java.util.Vector;
|
||||
import java.util.Enumeration;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.MissingResourceException;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.io.IOException;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
import sun.tools.java.ClassFile;
|
||||
import sun.tools.java.ClassDefinition;
|
||||
import sun.tools.java.ClassDeclaration;
|
||||
import sun.tools.java.ClassNotFound;
|
||||
import sun.tools.java.Identifier;
|
||||
import sun.tools.java.ClassPath;
|
||||
|
||||
import sun.tools.javac.SourceClass;
|
||||
import sun.tools.util.CommandLine;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* Main "rmic" program.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
public class Main implements sun.rmi.rmic.Constants {
|
||||
String sourcePathArg;
|
||||
String sysClassPathArg;
|
||||
String extDirsArg;
|
||||
String classPathString;
|
||||
File destDir;
|
||||
int flags;
|
||||
long tm;
|
||||
Vector<String> classes;
|
||||
boolean nowrite;
|
||||
boolean nocompile;
|
||||
boolean keepGenerated;
|
||||
boolean status;
|
||||
String[] generatorArgs;
|
||||
Vector<Generator> generators;
|
||||
Class<? extends BatchEnvironment> environmentClass =
|
||||
BatchEnvironment.class;
|
||||
boolean iiopGeneration = false;
|
||||
|
||||
/**
|
||||
* Name of the program.
|
||||
*/
|
||||
String program;
|
||||
|
||||
/**
|
||||
* The stream where error message are printed.
|
||||
*/
|
||||
OutputStream out;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public Main(OutputStream out, String program) {
|
||||
this.out = out;
|
||||
this.program = program;
|
||||
}
|
||||
|
||||
/**
|
||||
* Output a message.
|
||||
*/
|
||||
public void output(String msg) {
|
||||
PrintStream out =
|
||||
this.out instanceof PrintStream ? (PrintStream)this.out
|
||||
: new PrintStream(this.out, true);
|
||||
out.println(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Top level error message. This method is called when the
|
||||
* environment could not be set up yet.
|
||||
*/
|
||||
public void error(String msg) {
|
||||
output(getText(msg));
|
||||
}
|
||||
|
||||
public void error(String msg, String arg1) {
|
||||
output(getText(msg, arg1));
|
||||
}
|
||||
|
||||
public void error(String msg, String arg1, String arg2) {
|
||||
output(getText(msg, arg1, arg2));
|
||||
}
|
||||
|
||||
/**
|
||||
* Usage
|
||||
*/
|
||||
public void usage() {
|
||||
error("rmic.usage", program);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the compiler
|
||||
*/
|
||||
public synchronized boolean compile(String argv[]) {
|
||||
|
||||
/*
|
||||
* Handle internal option to use the new (and incomplete) rmic
|
||||
* implementation. This option is handled here, rather than
|
||||
* in parseArgs, so that none of the arguments will be nulled
|
||||
* before delegating to the new implementation.
|
||||
*/
|
||||
for (int i = 0; i < argv.length; i++) {
|
||||
if (argv[i].equals("-Xnew")) {
|
||||
return (new sun.rmi.rmic.newrmic.Main(out,
|
||||
program)).compile(argv);
|
||||
}
|
||||
}
|
||||
|
||||
if (!parseArgs(argv)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (classes.size() == 0) {
|
||||
usage();
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((flags & F_WARNINGS) != 0) {
|
||||
for (Generator g : generators) {
|
||||
if (g instanceof RMIGenerator) {
|
||||
output(getText("rmic.jrmp.stubs.deprecated", program));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return doCompile();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the destination directory.
|
||||
*/
|
||||
public File getDestinationDir() {
|
||||
return destDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the arguments for compile.
|
||||
*/
|
||||
public boolean parseArgs(String argv[]) {
|
||||
sourcePathArg = null;
|
||||
sysClassPathArg = null;
|
||||
extDirsArg = null;
|
||||
|
||||
classPathString = null;
|
||||
destDir = null;
|
||||
flags = F_WARNINGS;
|
||||
tm = System.currentTimeMillis();
|
||||
classes = new Vector<>();
|
||||
nowrite = false;
|
||||
nocompile = false;
|
||||
keepGenerated = false;
|
||||
generatorArgs = getArray("generator.args",true);
|
||||
if (generatorArgs == null) {
|
||||
return false;
|
||||
}
|
||||
generators = new Vector<>();
|
||||
|
||||
// Pre-process command line for @file arguments
|
||||
try {
|
||||
argv = CommandLine.parse(argv);
|
||||
} catch (FileNotFoundException e) {
|
||||
error("rmic.cant.read", e.getMessage());
|
||||
return false;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace(out instanceof PrintStream ?
|
||||
(PrintStream) out :
|
||||
new PrintStream(out, true));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Parse arguments
|
||||
for (int i = 0 ; i < argv.length ; i++) {
|
||||
if (argv[i] != null) {
|
||||
if (argv[i].equals("-g")) {
|
||||
flags &= ~F_OPT;
|
||||
flags |= F_DEBUG_LINES | F_DEBUG_VARS;
|
||||
argv[i] = null;
|
||||
} else if (argv[i].equals("-O")) {
|
||||
flags &= ~F_DEBUG_LINES;
|
||||
flags &= ~F_DEBUG_VARS;
|
||||
flags |= F_OPT | F_DEPENDENCIES;
|
||||
argv[i] = null;
|
||||
} else if (argv[i].equals("-nowarn")) {
|
||||
flags &= ~F_WARNINGS;
|
||||
argv[i] = null;
|
||||
} else if (argv[i].equals("-debug")) {
|
||||
flags |= F_DUMP;
|
||||
argv[i] = null;
|
||||
} else if (argv[i].equals("-depend")) {
|
||||
flags |= F_DEPENDENCIES;
|
||||
argv[i] = null;
|
||||
} else if (argv[i].equals("-verbose")) {
|
||||
flags |= F_VERBOSE;
|
||||
argv[i] = null;
|
||||
} else if (argv[i].equals("-nowrite")) {
|
||||
nowrite = true;
|
||||
argv[i] = null;
|
||||
} else if (argv[i].equals("-Xnocompile")) {
|
||||
nocompile = true;
|
||||
keepGenerated = true;
|
||||
argv[i] = null;
|
||||
} else if (argv[i].equals("-keep") ||
|
||||
argv[i].equals("-keepgenerated")) {
|
||||
keepGenerated = true;
|
||||
argv[i] = null;
|
||||
} else if (argv[i].equals("-show")) {
|
||||
error("rmic.option.unsupported", "-show");
|
||||
usage();
|
||||
return false;
|
||||
} else if (argv[i].equals("-classpath")) {
|
||||
if ((i + 1) < argv.length) {
|
||||
if (classPathString != null) {
|
||||
error("rmic.option.already.seen", "-classpath");
|
||||
usage();
|
||||
return false;
|
||||
}
|
||||
argv[i] = null;
|
||||
classPathString = argv[++i];
|
||||
argv[i] = null;
|
||||
} else {
|
||||
error("rmic.option.requires.argument", "-classpath");
|
||||
usage();
|
||||
return false;
|
||||
}
|
||||
} else if (argv[i].equals("-sourcepath")) {
|
||||
if ((i + 1) < argv.length) {
|
||||
if (sourcePathArg != null) {
|
||||
error("rmic.option.already.seen", "-sourcepath");
|
||||
usage();
|
||||
return false;
|
||||
}
|
||||
argv[i] = null;
|
||||
sourcePathArg = argv[++i];
|
||||
argv[i] = null;
|
||||
} else {
|
||||
error("rmic.option.requires.argument", "-sourcepath");
|
||||
usage();
|
||||
return false;
|
||||
}
|
||||
} else if (argv[i].equals("-bootclasspath")) {
|
||||
if ((i + 1) < argv.length) {
|
||||
if (sysClassPathArg != null) {
|
||||
error("rmic.option.already.seen", "-bootclasspath");
|
||||
usage();
|
||||
return false;
|
||||
}
|
||||
argv[i] = null;
|
||||
sysClassPathArg = argv[++i];
|
||||
argv[i] = null;
|
||||
} else {
|
||||
error("rmic.option.requires.argument", "-bootclasspath");
|
||||
usage();
|
||||
return false;
|
||||
}
|
||||
} else if (argv[i].equals("-extdirs")) {
|
||||
if ((i + 1) < argv.length) {
|
||||
if (extDirsArg != null) {
|
||||
error("rmic.option.already.seen", "-extdirs");
|
||||
usage();
|
||||
return false;
|
||||
}
|
||||
argv[i] = null;
|
||||
extDirsArg = argv[++i];
|
||||
argv[i] = null;
|
||||
} else {
|
||||
error("rmic.option.requires.argument", "-extdirs");
|
||||
usage();
|
||||
return false;
|
||||
}
|
||||
} else if (argv[i].equals("-d")) {
|
||||
if ((i + 1) < argv.length) {
|
||||
if (destDir != null) {
|
||||
error("rmic.option.already.seen", "-d");
|
||||
usage();
|
||||
return false;
|
||||
}
|
||||
argv[i] = null;
|
||||
destDir = new File(argv[++i]);
|
||||
argv[i] = null;
|
||||
if (!destDir.exists()) {
|
||||
error("rmic.no.such.directory", destDir.getPath());
|
||||
usage();
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
error("rmic.option.requires.argument", "-d");
|
||||
usage();
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!checkGeneratorArg(argv,i)) {
|
||||
usage();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Now that all generators have had a chance at the args,
|
||||
// scan what's left for classes and illegal args...
|
||||
|
||||
for (int i = 0; i < argv.length; i++) {
|
||||
if (argv[i] != null) {
|
||||
if (argv[i].startsWith("-")) {
|
||||
error("rmic.no.such.option", argv[i]);
|
||||
usage();
|
||||
return false;
|
||||
} else {
|
||||
classes.addElement(argv[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// If the generators vector is empty, add the default generator...
|
||||
|
||||
if (generators.size() == 0) {
|
||||
addGenerator("default");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* If this argument is for a generator, instantiate it, call
|
||||
* parseArgs(...) and add generator to generators vector.
|
||||
* Returns false on error.
|
||||
*/
|
||||
protected boolean checkGeneratorArg(String[] argv, int currentIndex) {
|
||||
boolean result = true;
|
||||
if (argv[currentIndex].startsWith("-")) {
|
||||
String arg = argv[currentIndex].substring(1).toLowerCase(); // Remove '-'
|
||||
for (int i = 0; i < generatorArgs.length; i++) {
|
||||
if (arg.equalsIgnoreCase(generatorArgs[i])) {
|
||||
// Got a match, add Generator and call parseArgs...
|
||||
Generator gen = addGenerator(arg);
|
||||
if (gen == null) {
|
||||
return false;
|
||||
}
|
||||
result = gen.parseArgs(argv,this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate and add a generator to the generators array.
|
||||
*/
|
||||
protected Generator addGenerator(String arg) {
|
||||
|
||||
Generator gen;
|
||||
|
||||
// Create an instance of the generator and add it to
|
||||
// the array...
|
||||
|
||||
String className = getString("generator.class." + arg);
|
||||
if (className == null) {
|
||||
error("rmic.missing.property",arg);
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
gen = (Generator) Class.forName(className).newInstance();
|
||||
} catch (Exception e) {
|
||||
error("rmic.cannot.instantiate",className);
|
||||
return null;
|
||||
}
|
||||
|
||||
generators.addElement(gen);
|
||||
|
||||
// Get the environment required by this generator...
|
||||
|
||||
Class<?> envClass = BatchEnvironment.class;
|
||||
String env = getString("generator.env." + arg);
|
||||
if (env != null) {
|
||||
try {
|
||||
envClass = Class.forName(env);
|
||||
|
||||
// Is the new class a subclass of the current one?
|
||||
|
||||
if (environmentClass.isAssignableFrom(envClass)) {
|
||||
|
||||
// Yes, so switch to the new one...
|
||||
|
||||
environmentClass = envClass.asSubclass(BatchEnvironment.class);
|
||||
|
||||
} else {
|
||||
|
||||
// No. Is the current class a subclass of the
|
||||
// new one?
|
||||
|
||||
if (!envClass.isAssignableFrom(environmentClass)) {
|
||||
|
||||
// No, so it's a conflict...
|
||||
|
||||
error("rmic.cannot.use.both",environmentClass.getName(),envClass.getName());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
error("rmic.class.not.found",env);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// If this is the iiop stub generator, cache
|
||||
// that fact for the jrmp generator...
|
||||
|
||||
if (arg.equals("iiop")) {
|
||||
iiopGeneration = true;
|
||||
}
|
||||
return gen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Grab a resource string and parse it into an array of strings. Assumes
|
||||
* comma separated list.
|
||||
* @param name The resource name.
|
||||
* @param mustExist If true, throws error if resource does not exist. If
|
||||
* false and resource does not exist, returns zero element array.
|
||||
*/
|
||||
protected String[] getArray(String name, boolean mustExist) {
|
||||
String[] result = null;
|
||||
String value = getString(name);
|
||||
if (value == null) {
|
||||
if (mustExist) {
|
||||
error("rmic.resource.not.found",name);
|
||||
return null;
|
||||
} else {
|
||||
return new String[0];
|
||||
}
|
||||
}
|
||||
|
||||
StringTokenizer parser = new StringTokenizer(value,", \t\n\r", false);
|
||||
int count = parser.countTokens();
|
||||
result = new String[count];
|
||||
for (int i = 0; i < count; i++) {
|
||||
result[i] = parser.nextToken();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the correct type of BatchEnvironment
|
||||
*/
|
||||
public BatchEnvironment getEnv() {
|
||||
|
||||
ClassPath classPath =
|
||||
BatchEnvironment.createClassPath(classPathString,
|
||||
sysClassPathArg,
|
||||
extDirsArg);
|
||||
BatchEnvironment result = null;
|
||||
try {
|
||||
Class<?>[] ctorArgTypes = {OutputStream.class,ClassPath.class,Main.class};
|
||||
Object[] ctorArgs = {out,classPath,this};
|
||||
Constructor<? extends BatchEnvironment> constructor =
|
||||
environmentClass.getConstructor(ctorArgTypes);
|
||||
result = constructor.newInstance(ctorArgs);
|
||||
result.reset();
|
||||
}
|
||||
catch (Exception e) {
|
||||
error("rmic.cannot.instantiate",environmentClass.getName());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Do the compile with the switches and files already supplied
|
||||
*/
|
||||
public boolean doCompile() {
|
||||
// Create batch environment
|
||||
BatchEnvironment env = getEnv();
|
||||
env.flags |= flags;
|
||||
|
||||
// Set the classfile version numbers
|
||||
// Compat and 1.1 stubs must retain the old version number.
|
||||
env.majorVersion = 45;
|
||||
env.minorVersion = 3;
|
||||
|
||||
// Preload the "out of memory" error string just in case we run
|
||||
// out of memory during the compile.
|
||||
String noMemoryErrorString = getText("rmic.no.memory");
|
||||
String stackOverflowErrorString = getText("rmic.stack.overflow");
|
||||
|
||||
try {
|
||||
/** Load the classes on the command line
|
||||
* Replace the entries in classes with the ClassDefinition for the class
|
||||
*/
|
||||
for (int i = classes.size()-1; i >= 0; i-- ) {
|
||||
Identifier implClassName =
|
||||
Identifier.lookup(classes.elementAt(i));
|
||||
|
||||
/*
|
||||
* Fix bugid 4049354: support using '.' as an inner class
|
||||
* qualifier on the command line (previously, only mangled
|
||||
* inner class names were understood, like "pkg.Outer$Inner").
|
||||
*
|
||||
* The following method, also used by "javap", resolves the
|
||||
* given unmangled inner class name to the appropriate
|
||||
* internal identifier. For example, it translates
|
||||
* "pkg.Outer.Inner" to "pkg.Outer. Inner".
|
||||
*/
|
||||
implClassName = env.resolvePackageQualifiedName(implClassName);
|
||||
/*
|
||||
* But if we use such an internal inner class name identifier
|
||||
* to load the class definition, the Java compiler will notice
|
||||
* if the impl class is a "private" inner class and then deny
|
||||
* skeletons (needed unless "-v1.2" is used) the ability to
|
||||
* cast to it. To work around this problem, we mangle inner
|
||||
* class name identifiers to their binary "outer" class name:
|
||||
* "pkg.Outer. Inner" becomes "pkg.Outer$Inner".
|
||||
*/
|
||||
implClassName = Names.mangleClass(implClassName);
|
||||
|
||||
ClassDeclaration decl = env.getClassDeclaration(implClassName);
|
||||
try {
|
||||
ClassDefinition def = decl.getClassDefinition(env);
|
||||
for (int j = 0; j < generators.size(); j++) {
|
||||
Generator gen = generators.elementAt(j);
|
||||
gen.generate(env, def, destDir);
|
||||
}
|
||||
} catch (ClassNotFound ex) {
|
||||
env.error(0, "rmic.class.not.found", implClassName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// compile all classes that need compilation
|
||||
if (!nocompile) {
|
||||
compileAllClasses(env);
|
||||
}
|
||||
} catch (OutOfMemoryError ee) {
|
||||
// The compiler has run out of memory. Use the error string
|
||||
// which we preloaded.
|
||||
env.output(noMemoryErrorString);
|
||||
return false;
|
||||
} catch (StackOverflowError ee) {
|
||||
env.output(stackOverflowErrorString);
|
||||
return false;
|
||||
} catch (Error ee) {
|
||||
// We allow the compiler to take an exception silently if a program
|
||||
// error has previously been detected. Presumably, this makes the
|
||||
// compiler more robust in the face of bad error recovery.
|
||||
if (env.nerrors == 0 || env.dump()) {
|
||||
env.error(0, "fatal.error");
|
||||
ee.printStackTrace(out instanceof PrintStream ?
|
||||
(PrintStream) out :
|
||||
new PrintStream(out, true));
|
||||
}
|
||||
} catch (Exception ee) {
|
||||
if (env.nerrors == 0 || env.dump()) {
|
||||
env.error(0, "fatal.exception");
|
||||
ee.printStackTrace(out instanceof PrintStream ?
|
||||
(PrintStream) out :
|
||||
new PrintStream(out, true));
|
||||
}
|
||||
}
|
||||
|
||||
env.flushErrors();
|
||||
|
||||
boolean status = true;
|
||||
if (env.nerrors > 0) {
|
||||
String msg = "";
|
||||
if (env.nerrors > 1) {
|
||||
msg = getText("rmic.errors", env.nerrors);
|
||||
} else {
|
||||
msg = getText("rmic.1error");
|
||||
}
|
||||
if (env.nwarnings > 0) {
|
||||
if (env.nwarnings > 1) {
|
||||
msg += ", " + getText("rmic.warnings", env.nwarnings);
|
||||
} else {
|
||||
msg += ", " + getText("rmic.1warning");
|
||||
}
|
||||
}
|
||||
output(msg);
|
||||
status = false;
|
||||
} else {
|
||||
if (env.nwarnings > 0) {
|
||||
if (env.nwarnings > 1) {
|
||||
output(getText("rmic.warnings", env.nwarnings));
|
||||
} else {
|
||||
output(getText("rmic.1warning"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// last step is to delete generated source files
|
||||
if (!keepGenerated) {
|
||||
env.deleteGeneratedFiles();
|
||||
}
|
||||
|
||||
// We're done
|
||||
if (env.verbose()) {
|
||||
tm = System.currentTimeMillis() - tm;
|
||||
output(getText("rmic.done_in", Long.toString(tm)));
|
||||
}
|
||||
|
||||
// Shutdown the environment object and release our resources.
|
||||
// Note that while this is unneccessary when rmic is invoked
|
||||
// the command line, there are environments in which rmic
|
||||
// from is invoked within a server process, so resource
|
||||
// reclamation is important...
|
||||
|
||||
env.shutdown();
|
||||
|
||||
sourcePathArg = null;
|
||||
sysClassPathArg = null;
|
||||
extDirsArg = null;
|
||||
classPathString = null;
|
||||
destDir = null;
|
||||
classes = null;
|
||||
generatorArgs = null;
|
||||
generators = null;
|
||||
environmentClass = null;
|
||||
program = null;
|
||||
out = null;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compile all classes that need to be compiled.
|
||||
*/
|
||||
public void compileAllClasses (BatchEnvironment env)
|
||||
throws ClassNotFound,
|
||||
IOException,
|
||||
InterruptedException {
|
||||
ByteArrayOutputStream buf = new ByteArrayOutputStream(4096);
|
||||
boolean done;
|
||||
|
||||
do {
|
||||
done = true;
|
||||
for (Enumeration<?> e = env.getClasses() ; e.hasMoreElements() ; ) {
|
||||
ClassDeclaration c = (ClassDeclaration)e.nextElement();
|
||||
done = compileClass(c,buf,env);
|
||||
}
|
||||
} while (!done);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compile a single class.
|
||||
* Fallthrough is intentional
|
||||
*/
|
||||
@SuppressWarnings("fallthrough")
|
||||
public boolean compileClass (ClassDeclaration c,
|
||||
ByteArrayOutputStream buf,
|
||||
BatchEnvironment env)
|
||||
throws ClassNotFound,
|
||||
IOException,
|
||||
InterruptedException {
|
||||
boolean done = true;
|
||||
env.flushErrors();
|
||||
SourceClass src;
|
||||
|
||||
switch (c.getStatus()) {
|
||||
case CS_UNDEFINED:
|
||||
{
|
||||
if (!env.dependencies()) {
|
||||
break;
|
||||
}
|
||||
// fall through
|
||||
}
|
||||
|
||||
case CS_SOURCE:
|
||||
{
|
||||
done = false;
|
||||
env.loadDefinition(c);
|
||||
if (c.getStatus() != CS_PARSED) {
|
||||
break;
|
||||
}
|
||||
// fall through
|
||||
}
|
||||
|
||||
case CS_PARSED:
|
||||
{
|
||||
if (c.getClassDefinition().isInsideLocal()) {
|
||||
break;
|
||||
}
|
||||
// If we get to here, then compilation is going
|
||||
// to occur. If the -Xnocompile switch is set
|
||||
// then fail. Note that this check is required
|
||||
// here because this method is called from
|
||||
// generators, not just from within this class...
|
||||
|
||||
if (nocompile) {
|
||||
throw new IOException("Compilation required, but -Xnocompile option in effect");
|
||||
}
|
||||
|
||||
done = false;
|
||||
|
||||
src = (SourceClass)c.getClassDefinition(env);
|
||||
src.check(env);
|
||||
c.setDefinition(src, CS_CHECKED);
|
||||
// fall through
|
||||
}
|
||||
|
||||
case CS_CHECKED:
|
||||
{
|
||||
src = (SourceClass)c.getClassDefinition(env);
|
||||
// bail out if there were any errors
|
||||
if (src.getError()) {
|
||||
c.setDefinition(src, CS_COMPILED);
|
||||
break;
|
||||
}
|
||||
done = false;
|
||||
buf.reset();
|
||||
src.compile(buf);
|
||||
c.setDefinition(src, CS_COMPILED);
|
||||
src.cleanup(env);
|
||||
|
||||
if (src.getError() || nowrite) {
|
||||
break;
|
||||
}
|
||||
|
||||
String pkgName = c.getName().getQualifier().toString().replace('.', File.separatorChar);
|
||||
String className = c.getName().getFlatName().toString().replace('.', SIGC_INNERCLASS) + ".class";
|
||||
|
||||
File file;
|
||||
if (destDir != null) {
|
||||
if (pkgName.length() > 0) {
|
||||
file = new File(destDir, pkgName);
|
||||
if (!file.exists()) {
|
||||
file.mkdirs();
|
||||
}
|
||||
file = new File(file, className);
|
||||
} else {
|
||||
file = new File(destDir, className);
|
||||
}
|
||||
} else {
|
||||
ClassFile classfile = (ClassFile)src.getSource();
|
||||
if (classfile.isZipped()) {
|
||||
env.error(0, "cant.write", classfile.getPath());
|
||||
break;
|
||||
}
|
||||
file = new File(classfile.getPath());
|
||||
file = new File(file.getParent(), className);
|
||||
}
|
||||
|
||||
// Create the file
|
||||
try {
|
||||
FileOutputStream out = new FileOutputStream(file.getPath());
|
||||
buf.writeTo(out);
|
||||
out.close();
|
||||
if (env.verbose()) {
|
||||
output(getText("rmic.wrote", file.getPath()));
|
||||
}
|
||||
} catch (IOException ee) {
|
||||
env.error(0, "cant.write", file.getPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
return done;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main program
|
||||
*/
|
||||
public static void main(String argv[]) {
|
||||
Main compiler = new Main(System.out, "rmic");
|
||||
System.exit(compiler.compile(argv) ? 0 : 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the string value of a named resource in the rmic.properties
|
||||
* resource bundle. If the resource is not found, null is returned.
|
||||
*/
|
||||
public static String getString(String key) {
|
||||
if (!resourcesInitialized) {
|
||||
initResources();
|
||||
}
|
||||
|
||||
// To enable extensions, search the 'resourcesExt'
|
||||
// bundle first, followed by the 'resources' bundle...
|
||||
|
||||
if (resourcesExt != null) {
|
||||
try {
|
||||
return resourcesExt.getString(key);
|
||||
} catch (MissingResourceException e) {}
|
||||
}
|
||||
|
||||
try {
|
||||
return resources.getString(key);
|
||||
} catch (MissingResourceException ignore) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean resourcesInitialized = false;
|
||||
private static ResourceBundle resources;
|
||||
private static ResourceBundle resourcesExt = null;
|
||||
|
||||
private static void initResources() {
|
||||
try {
|
||||
resources =
|
||||
ResourceBundle.getBundle("sun.rmi.rmic.resources.rmic");
|
||||
resourcesInitialized = true;
|
||||
try {
|
||||
resourcesExt =
|
||||
ResourceBundle.getBundle("sun.rmi.rmic.resources.rmicext");
|
||||
} catch (MissingResourceException e) {}
|
||||
} catch (MissingResourceException e) {
|
||||
throw new Error("fatal: missing resource bundle: " +
|
||||
e.getClassName());
|
||||
}
|
||||
}
|
||||
|
||||
public static String getText(String key) {
|
||||
String message = getString(key);
|
||||
if (message == null) {
|
||||
message = "no text found: \"" + key + "\"";
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
public static String getText(String key, int num) {
|
||||
return getText(key, Integer.toString(num), null, null);
|
||||
}
|
||||
|
||||
public static String getText(String key, String arg0) {
|
||||
return getText(key, arg0, null, null);
|
||||
}
|
||||
|
||||
public static String getText(String key, String arg0, String arg1) {
|
||||
return getText(key, arg0, arg1, null);
|
||||
}
|
||||
|
||||
public static String getText(String key,
|
||||
String arg0, String arg1, String arg2)
|
||||
{
|
||||
String format = getString(key);
|
||||
if (format == null) {
|
||||
format = "no text found: key = \"" + key + "\", " +
|
||||
"arguments = \"{0}\", \"{1}\", \"{2}\"";
|
||||
}
|
||||
|
||||
String[] args = new String[3];
|
||||
args[0] = (arg0 != null ? arg0 : "null");
|
||||
args[1] = (arg1 != null ? arg1 : "null");
|
||||
args[2] = (arg2 != null ? arg2 : "null");
|
||||
|
||||
return java.text.MessageFormat.format(format, (Object[]) args);
|
||||
}
|
||||
}
|
||||
88
jdkSrc/jdk8/sun/rmi/rmic/Names.java
Normal file
88
jdkSrc/jdk8/sun/rmi/rmic/Names.java
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.rmi.rmic;
|
||||
|
||||
import sun.tools.java.Identifier;
|
||||
|
||||
/**
|
||||
* Names provides static utility methods used by other rmic classes
|
||||
* for dealing with identifiers.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
public class Names {
|
||||
|
||||
/**
|
||||
* Return stub class name for impl class name.
|
||||
*/
|
||||
static final public Identifier stubFor(Identifier name) {
|
||||
return Identifier.lookup(name + "_Stub");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return skeleton class name for impl class name.
|
||||
*/
|
||||
static final public Identifier skeletonFor(Identifier name) {
|
||||
return Identifier.lookup(name + "_Skel");
|
||||
}
|
||||
|
||||
/**
|
||||
* If necessary, convert a class name to its mangled form, i.e. the
|
||||
* non-inner class name used in the binary representation of
|
||||
* inner classes. This is necessary to be able to name inner
|
||||
* classes in the generated source code in places where the language
|
||||
* does not permit it, such as when synthetically defining an inner
|
||||
* class outside of its outer class, and for generating file names
|
||||
* corresponding to inner classes.
|
||||
*
|
||||
* Currently this mangling involves modifying the internal names of
|
||||
* inner classes by converting occurrences of ". " into "$".
|
||||
*
|
||||
* This code is taken from the "mangleInnerType" method of
|
||||
* the "sun.tools.java.Type" class; this method cannot be accessed
|
||||
* itself because it is package protected.
|
||||
*/
|
||||
static final public Identifier mangleClass(Identifier className) {
|
||||
if (!className.isInner())
|
||||
return className;
|
||||
|
||||
/*
|
||||
* Get '.' qualified inner class name (with outer class
|
||||
* qualification and no package qualification) and replace
|
||||
* each '.' with '$'.
|
||||
*/
|
||||
Identifier mangled = Identifier.lookup(
|
||||
className.getFlatName().toString()
|
||||
.replace('.', sun.tools.java.Constants.SIGC_INNERCLASS));
|
||||
if (mangled.isInner())
|
||||
throw new Error("failed to mangle inner class name");
|
||||
|
||||
// prepend package qualifier back for returned identifier
|
||||
return Identifier.lookup(className.getQualifier(), mangled);
|
||||
}
|
||||
}
|
||||
80
jdkSrc/jdk8/sun/rmi/rmic/RMIConstants.java
Normal file
80
jdkSrc/jdk8/sun/rmi/rmic/RMIConstants.java
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Licensed Materials - Property of IBM
|
||||
* RMI-IIOP v1.0
|
||||
* Copyright IBM Corp. 1998 1999 All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
package sun.rmi.rmic;
|
||||
|
||||
import sun.tools.java.Identifier;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
public interface RMIConstants extends sun.rmi.rmic.Constants {
|
||||
|
||||
/*
|
||||
* identifiers for RMI classes referenced by rmic
|
||||
*/
|
||||
public static final Identifier idRemoteObject =
|
||||
Identifier.lookup("java.rmi.server.RemoteObject");
|
||||
public static final Identifier idRemoteStub =
|
||||
Identifier.lookup("java.rmi.server.RemoteStub");
|
||||
public static final Identifier idRemoteRef =
|
||||
Identifier.lookup("java.rmi.server.RemoteRef");
|
||||
public static final Identifier idOperation =
|
||||
Identifier.lookup("java.rmi.server.Operation");
|
||||
public static final Identifier idSkeleton =
|
||||
Identifier.lookup("java.rmi.server.Skeleton");
|
||||
public static final Identifier idSkeletonMismatchException =
|
||||
Identifier.lookup("java.rmi.server.SkeletonMismatchException");
|
||||
public static final Identifier idRemoteCall =
|
||||
Identifier.lookup("java.rmi.server.RemoteCall");
|
||||
public static final Identifier idMarshalException =
|
||||
Identifier.lookup("java.rmi.MarshalException");
|
||||
public static final Identifier idUnmarshalException =
|
||||
Identifier.lookup("java.rmi.UnmarshalException");
|
||||
public static final Identifier idUnexpectedException =
|
||||
Identifier.lookup("java.rmi.UnexpectedException");
|
||||
|
||||
/*
|
||||
* stub protocol versions
|
||||
*/
|
||||
public static final int STUB_VERSION_1_1 = 1;
|
||||
public static final int STUB_VERSION_FAT = 2;
|
||||
public static final int STUB_VERSION_1_2 = 3;
|
||||
|
||||
/** serialVersionUID for all stubs that can use 1.2 protocol */
|
||||
public static final long STUB_SERIAL_VERSION_UID = 2;
|
||||
|
||||
/** version number used to seed interface hash computation */
|
||||
public static final int INTERFACE_HASH_STUB_VERSION = 1;
|
||||
}
|
||||
1302
jdkSrc/jdk8/sun/rmi/rmic/RMIGenerator.java
Normal file
1302
jdkSrc/jdk8/sun/rmi/rmic/RMIGenerator.java
Normal file
File diff suppressed because it is too large
Load Diff
876
jdkSrc/jdk8/sun/rmi/rmic/RemoteClass.java
Normal file
876
jdkSrc/jdk8/sun/rmi/rmic/RemoteClass.java
Normal file
@@ -0,0 +1,876 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.rmi.rmic;
|
||||
|
||||
import java.util.Vector;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Enumeration;
|
||||
import java.io.IOException;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.DigestOutputStream;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import sun.tools.java.Type;
|
||||
import sun.tools.java.ClassDefinition;
|
||||
import sun.tools.java.ClassDeclaration;
|
||||
import sun.tools.java.MemberDefinition;
|
||||
import sun.tools.java.Identifier;
|
||||
import sun.tools.java.ClassNotFound;
|
||||
|
||||
/**
|
||||
* A RemoteClass object encapsulates RMI-specific information about
|
||||
* a remote implementation class, i.e. a class that implements
|
||||
* one or more remote interfaces.
|
||||
*
|
||||
* 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 RemoteClass implements sun.rmi.rmic.RMIConstants {
|
||||
|
||||
/**
|
||||
* Create a RemoteClass object representing the remote meta-information
|
||||
* of the given class.
|
||||
*
|
||||
* Returns true if successful. If the class is not a properly formed
|
||||
* remote implementation class or if some other error occurs, the
|
||||
* return value will be null, and errors will have been reported to
|
||||
* the supplied BatchEnvironment.
|
||||
*/
|
||||
public static RemoteClass forClass(BatchEnvironment env,
|
||||
ClassDefinition implClassDef)
|
||||
{
|
||||
RemoteClass rc = new RemoteClass(env, implClassDef);
|
||||
if (rc.initialize()) {
|
||||
return rc;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the ClassDefinition for this class.
|
||||
*/
|
||||
public ClassDefinition getClassDefinition() {
|
||||
return implClassDef;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of the class represented by this object.
|
||||
*/
|
||||
public Identifier getName() {
|
||||
return implClassDef.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of ClassDefinitions representing all of the remote
|
||||
* interfaces implemented by this class.
|
||||
*
|
||||
* A remote interface is any interface that extends Remote,
|
||||
* directly or indirectly. The remote interfaces of a class
|
||||
* are the interfaces directly listed in either the class's
|
||||
* "implements" clause, or the "implements" clause of any
|
||||
* of its superclasses, that are remote interfaces.
|
||||
*
|
||||
* The order of the array returned is arbitrary, and some elements
|
||||
* may be superfluous (i.e., superinterfaces of other interfaces
|
||||
* in the array).
|
||||
*/
|
||||
public ClassDefinition[] getRemoteInterfaces() {
|
||||
return remoteInterfaces.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of RemoteClass.Method objects representing all of
|
||||
* the remote methods implemented by this class, i.e. all of the
|
||||
* methods in the class's remote interfaces.
|
||||
*
|
||||
* The methods in the array are ordered according to the comparision
|
||||
* of the strings consisting of their method name followed by their
|
||||
* type signature, so each method's index in the array corresponds
|
||||
* to its "operation number" in the JDK 1.1 version of the
|
||||
* stub/skeleton protocol.
|
||||
*/
|
||||
public Method[] getRemoteMethods() {
|
||||
return remoteMethods.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the "interface hash" used to match a stub/skeleton pair for
|
||||
* this class in the JDK 1.1 version of the stub/skeleton protocol.
|
||||
*/
|
||||
public long getInterfaceHash() {
|
||||
return interfaceHash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return string representation of this object, consisting of
|
||||
* the string "remote class " followed by the class name.
|
||||
*/
|
||||
public String toString() {
|
||||
return "remote class " + implClassDef.getName().toString();
|
||||
}
|
||||
|
||||
/** rmic environment for this object */
|
||||
private BatchEnvironment env;
|
||||
|
||||
/** the remote implementation class this object corresponds to */
|
||||
private ClassDefinition implClassDef;
|
||||
|
||||
/** remote interfaces implemented by this class */
|
||||
private ClassDefinition[] remoteInterfaces;
|
||||
|
||||
/** all the remote methods of this class */
|
||||
private Method[] remoteMethods;
|
||||
|
||||
/** stub/skeleton "interface hash" for this class */
|
||||
private long interfaceHash;
|
||||
|
||||
/** cached definition for certain classes used in this environment */
|
||||
private ClassDefinition defRemote;
|
||||
private ClassDefinition defException;
|
||||
private ClassDefinition defRemoteException;
|
||||
|
||||
/**
|
||||
* Create a RemoteClass instance for the given class. The resulting
|
||||
* object is not yet initialized.
|
||||
*/
|
||||
private RemoteClass(BatchEnvironment env, ClassDefinition implClassDef) {
|
||||
this.env = env;
|
||||
this.implClassDef = implClassDef;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that the remote implementation class is properly formed
|
||||
* and fill in the data structures required by the public interface.
|
||||
*/
|
||||
private boolean initialize() {
|
||||
/*
|
||||
* Verify that the "impl" is really a class, not an interface.
|
||||
*/
|
||||
if (implClassDef.isInterface()) {
|
||||
env.error(0, "rmic.cant.make.stubs.for.interface",
|
||||
implClassDef.getName());
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize cached definitions for the Remote interface and
|
||||
* the RemoteException class.
|
||||
*/
|
||||
try {
|
||||
defRemote =
|
||||
env.getClassDeclaration(idRemote).getClassDefinition(env);
|
||||
defException =
|
||||
env.getClassDeclaration(idJavaLangException).
|
||||
getClassDefinition(env);
|
||||
defRemoteException =
|
||||
env.getClassDeclaration(idRemoteException).
|
||||
getClassDefinition(env);
|
||||
} catch (ClassNotFound e) {
|
||||
env.error(0, "rmic.class.not.found", e.name);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Here we find all of the remote interfaces of our remote
|
||||
* implementation class. For each class up the superclass
|
||||
* chain, add each directly-implemented interface that
|
||||
* somehow extends Remote to a list.
|
||||
*/
|
||||
Vector<ClassDefinition> remotesImplemented = // list of remote interfaces found
|
||||
new Vector<ClassDefinition>();
|
||||
for (ClassDefinition classDef = implClassDef;
|
||||
classDef != null;)
|
||||
{
|
||||
try {
|
||||
ClassDeclaration[] interfaces = classDef.getInterfaces();
|
||||
for (int i = 0; i < interfaces.length; i++) {
|
||||
ClassDefinition interfaceDef =
|
||||
interfaces[i].getClassDefinition(env);
|
||||
/*
|
||||
* Add interface to the list if it extends Remote and
|
||||
* it is not already there.
|
||||
*/
|
||||
if (!remotesImplemented.contains(interfaceDef) &&
|
||||
defRemote.implementedBy(env, interfaces[i]))
|
||||
{
|
||||
remotesImplemented.addElement(interfaceDef);
|
||||
/***** <DEBUG> */
|
||||
if (env.verbose()) {
|
||||
System.out.println("[found remote interface: " +
|
||||
interfaceDef.getName() + "]");
|
||||
/***** </DEBUG> */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify that the candidate remote implementation class
|
||||
* implements at least one remote interface directly.
|
||||
*/
|
||||
if (classDef == implClassDef && remotesImplemented.isEmpty()) {
|
||||
if (defRemote.implementedBy(env,
|
||||
implClassDef.getClassDeclaration()))
|
||||
{
|
||||
/*
|
||||
* This error message is used if the class does
|
||||
* implement a remote interface through one of
|
||||
* its superclasses, but not directly.
|
||||
*/
|
||||
env.error(0, "rmic.must.implement.remote.directly",
|
||||
implClassDef.getName());
|
||||
} else {
|
||||
/*
|
||||
* This error message is used if the class never
|
||||
* implements a remote interface.
|
||||
*/
|
||||
env.error(0, "rmic.must.implement.remote",
|
||||
implClassDef.getName());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get definition for next superclass.
|
||||
*/
|
||||
classDef = (classDef.getSuperClass() != null ?
|
||||
classDef.getSuperClass().getClassDefinition(env) :
|
||||
null);
|
||||
|
||||
} catch (ClassNotFound e) {
|
||||
env.error(0, "class.not.found", e.name, classDef.getName());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The "remotesImplemented" vector now contains all of the remote
|
||||
* interfaces directly implemented by the remote class or by any
|
||||
* of its superclasses.
|
||||
*
|
||||
* At this point, we could optimize the list by removing superfluous
|
||||
* entries, i.e. any interfaces that are implemented by some other
|
||||
* interface in the list anyway.
|
||||
*
|
||||
* This should be correct; would it be worthwhile?
|
||||
*
|
||||
* for (int i = 0; i < remotesImplemented.size();) {
|
||||
* ClassDefinition interfaceDef =
|
||||
* (ClassDefinition) remotesImplemented.elementAt(i);
|
||||
* boolean isOtherwiseImplemented = false;
|
||||
* for (int j = 0; j < remotesImplemented.size; j++) {
|
||||
* if (j != i &&
|
||||
* interfaceDef.implementedBy(env, (ClassDefinition)
|
||||
* remotesImplemented.elementAt(j).
|
||||
* getClassDeclaration()))
|
||||
* {
|
||||
* isOtherwiseImplemented = true;
|
||||
* break;
|
||||
* }
|
||||
* }
|
||||
* if (isOtherwiseImplemented) {
|
||||
* remotesImplemented.removeElementAt(i);
|
||||
* } else {
|
||||
* ++i;
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
|
||||
/*
|
||||
* Now we collect the methods from all of the remote interfaces
|
||||
* into a hashtable.
|
||||
*/
|
||||
Hashtable<String, Method> methods = new Hashtable<String, Method>();
|
||||
boolean errors = false;
|
||||
for (Enumeration<ClassDefinition> enumeration
|
||||
= remotesImplemented.elements();
|
||||
enumeration.hasMoreElements();)
|
||||
{
|
||||
ClassDefinition interfaceDef = enumeration.nextElement();
|
||||
if (!collectRemoteMethods(interfaceDef, methods))
|
||||
errors = true;
|
||||
}
|
||||
if (errors)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* Convert vector of remote interfaces to an array
|
||||
* (order is not important for this array).
|
||||
*/
|
||||
remoteInterfaces = new ClassDefinition[remotesImplemented.size()];
|
||||
remotesImplemented.copyInto(remoteInterfaces);
|
||||
|
||||
/*
|
||||
* Sort table of remote methods into an array. The elements are
|
||||
* sorted in ascending order of the string of the method's name
|
||||
* and type signature, so that each elements index is equal to
|
||||
* its operation number of the JDK 1.1 version of the stub/skeleton
|
||||
* protocol.
|
||||
*/
|
||||
String[] orderedKeys = new String[methods.size()];
|
||||
int count = 0;
|
||||
for (Enumeration<Method> enumeration = methods.elements();
|
||||
enumeration.hasMoreElements();)
|
||||
{
|
||||
Method m = enumeration.nextElement();
|
||||
String key = m.getNameAndDescriptor();
|
||||
int i;
|
||||
for (i = count; i > 0; --i) {
|
||||
if (key.compareTo(orderedKeys[i - 1]) >= 0) {
|
||||
break;
|
||||
}
|
||||
orderedKeys[i] = orderedKeys[i - 1];
|
||||
}
|
||||
orderedKeys[i] = key;
|
||||
++count;
|
||||
}
|
||||
remoteMethods = new Method[methods.size()];
|
||||
for (int i = 0; i < remoteMethods.length; i++) {
|
||||
remoteMethods[i] = methods.get(orderedKeys[i]);
|
||||
/***** <DEBUG> */
|
||||
if (env.verbose()) {
|
||||
System.out.print("[found remote method <" + i + ">: " +
|
||||
remoteMethods[i].getOperationString());
|
||||
ClassDeclaration[] exceptions =
|
||||
remoteMethods[i].getExceptions();
|
||||
if (exceptions.length > 0)
|
||||
System.out.print(" throws ");
|
||||
for (int j = 0; j < exceptions.length; j++) {
|
||||
if (j > 0)
|
||||
System.out.print(", ");
|
||||
System.out.print(exceptions[j].getName());
|
||||
}
|
||||
System.out.println("]");
|
||||
}
|
||||
/***** </DEBUG> */
|
||||
}
|
||||
|
||||
/**
|
||||
* Finally, pre-compute the interface hash to be used by
|
||||
* stubs/skeletons for this remote class.
|
||||
*/
|
||||
interfaceHash = computeInterfaceHash();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect and validate all methods from given interface and all of
|
||||
* its superinterfaces as remote methods. Remote methods are added
|
||||
* to the supplied hashtable. Returns true if successful,
|
||||
* or false if an error occurred.
|
||||
*/
|
||||
private boolean collectRemoteMethods(ClassDefinition interfaceDef,
|
||||
Hashtable<String, Method> table)
|
||||
{
|
||||
if (!interfaceDef.isInterface()) {
|
||||
throw new Error(
|
||||
"expected interface, not class: " + interfaceDef.getName());
|
||||
}
|
||||
|
||||
/*
|
||||
* rmic used to enforce that a remote interface could not extend
|
||||
* a non-remote interface, i.e. an interface that did not itself
|
||||
* extend from Remote. The current version of rmic does not have
|
||||
* this restriction, so the following code is now commented out.
|
||||
*
|
||||
* Verify that this interface extends Remote, since all interfaces
|
||||
* extended by a remote interface must implement Remote.
|
||||
*
|
||||
* try {
|
||||
* if (!defRemote.implementedBy(env,
|
||||
* interfaceDef.getClassDeclaration()))
|
||||
* {
|
||||
* env.error(0, "rmic.can.mix.remote.nonremote",
|
||||
* interfaceDef.getName());
|
||||
* return false;
|
||||
* }
|
||||
* } catch (ClassNotFound e) {
|
||||
* env.error(0, "class.not.found", e.name,
|
||||
* interfaceDef.getName());
|
||||
* return false;
|
||||
* }
|
||||
*/
|
||||
|
||||
boolean errors = false;
|
||||
|
||||
/*
|
||||
* Search interface's members for methods.
|
||||
*/
|
||||
nextMember:
|
||||
for (MemberDefinition member = interfaceDef.getFirstMember();
|
||||
member != null;
|
||||
member = member.getNextMember())
|
||||
{
|
||||
if (member.isMethod() &&
|
||||
!member.isConstructor() && !member.isInitializer())
|
||||
{
|
||||
/*
|
||||
* Verify that each method throws RemoteException.
|
||||
*/
|
||||
ClassDeclaration[] exceptions = member.getExceptions(env);
|
||||
boolean hasRemoteException = false;
|
||||
for (int i = 0; i < exceptions.length; i++) {
|
||||
/*
|
||||
* rmic used to enforce that a remote method had to
|
||||
* explicitly list RemoteException in its "throws"
|
||||
* clause; i.e., just throwing Exception was not
|
||||
* acceptable. The current version of rmic does not
|
||||
* have this restriction, so the following code is
|
||||
* now commented out. Instead, the method is
|
||||
* considered valid if RemoteException is a subclass
|
||||
* of any of the methods declared exceptions.
|
||||
*
|
||||
* if (exceptions[i].getName().equals(
|
||||
* idRemoteException))
|
||||
* {
|
||||
* hasRemoteException = true;
|
||||
* break;
|
||||
* }
|
||||
*/
|
||||
try {
|
||||
if (defRemoteException.subClassOf(
|
||||
env, exceptions[i]))
|
||||
{
|
||||
hasRemoteException = true;
|
||||
break;
|
||||
}
|
||||
} catch (ClassNotFound e) {
|
||||
env.error(0, "class.not.found", e.name,
|
||||
interfaceDef.getName());
|
||||
continue nextMember;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* If this method did not throw RemoteException as required,
|
||||
* generate the error but continue, so that multiple such
|
||||
* errors can be reported.
|
||||
*/
|
||||
if (!hasRemoteException) {
|
||||
env.error(0, "rmic.must.throw.remoteexception",
|
||||
interfaceDef.getName(), member.toString());
|
||||
errors = true;
|
||||
continue nextMember;
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify that the implementation of this method throws only
|
||||
* java.lang.Exception or its subclasses (fix bugid 4092486).
|
||||
* JRMP does not support remote methods throwing
|
||||
* java.lang.Throwable or other subclasses.
|
||||
*/
|
||||
try {
|
||||
MemberDefinition implMethod = implClassDef.findMethod(
|
||||
env, member.getName(), member.getType());
|
||||
if (implMethod != null) { // should not be null
|
||||
exceptions = implMethod.getExceptions(env);
|
||||
for (int i = 0; i < exceptions.length; i++) {
|
||||
if (!defException.superClassOf(
|
||||
env, exceptions[i]))
|
||||
{
|
||||
env.error(0, "rmic.must.only.throw.exception",
|
||||
implMethod.toString(),
|
||||
exceptions[i].getName());
|
||||
errors = true;
|
||||
continue nextMember;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (ClassNotFound e) {
|
||||
env.error(0, "class.not.found", e.name,
|
||||
implClassDef.getName());
|
||||
continue nextMember;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create RemoteClass.Method object to represent this method
|
||||
* found in a remote interface.
|
||||
*/
|
||||
Method newMethod = new Method(member);
|
||||
/*
|
||||
* Store remote method's representation in the table of
|
||||
* remote methods found, keyed by its name and parameter
|
||||
* signature.
|
||||
*
|
||||
* If the table already contains an entry with the same
|
||||
* method name and parameter signature, then we must
|
||||
* replace the old entry with a Method object that
|
||||
* represents a legal combination of the old and the new
|
||||
* methods; specifically, the combined method must have
|
||||
* a throws list that contains (only) all of the checked
|
||||
* exceptions that can be thrown by both the old or
|
||||
* the new method (see bugid 4070653).
|
||||
*/
|
||||
String key = newMethod.getNameAndDescriptor();
|
||||
Method oldMethod = table.get(key);
|
||||
if (oldMethod != null) {
|
||||
newMethod = newMethod.mergeWith(oldMethod);
|
||||
if (newMethod == null) {
|
||||
errors = true;
|
||||
continue nextMember;
|
||||
}
|
||||
}
|
||||
table.put(key, newMethod);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Recursively collect methods for all superinterfaces.
|
||||
*/
|
||||
try {
|
||||
ClassDeclaration[] superDefs = interfaceDef.getInterfaces();
|
||||
for (int i = 0; i < superDefs.length; i++) {
|
||||
ClassDefinition superDef =
|
||||
superDefs[i].getClassDefinition(env);
|
||||
if (!collectRemoteMethods(superDef, table))
|
||||
errors = true;
|
||||
}
|
||||
} catch (ClassNotFound e) {
|
||||
env.error(0, "class.not.found", e.name, interfaceDef.getName());
|
||||
return false;
|
||||
}
|
||||
|
||||
return !errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the "interface hash" of the stub/skeleton pair for this
|
||||
* remote implementation class. This is the 64-bit value used to
|
||||
* enforce compatibility between a stub and a skeleton using the
|
||||
* JDK 1.1 version of the stub/skeleton protocol.
|
||||
*
|
||||
* It is calculated using the first 64 bits of a SHA digest. The
|
||||
* digest is from a stream consisting of the following data:
|
||||
* (int) stub version number, always 1
|
||||
* for each remote method, in order of operation number:
|
||||
* (UTF) method name
|
||||
* (UTF) method type signature
|
||||
* for each declared exception, in alphabetical name order:
|
||||
* (UTF) name of exception class
|
||||
*
|
||||
*/
|
||||
private long computeInterfaceHash() {
|
||||
long hash = 0;
|
||||
ByteArrayOutputStream sink = new ByteArrayOutputStream(512);
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("SHA");
|
||||
DataOutputStream out = new DataOutputStream(
|
||||
new DigestOutputStream(sink, md));
|
||||
|
||||
out.writeInt(INTERFACE_HASH_STUB_VERSION);
|
||||
for (int i = 0; i < remoteMethods.length; i++) {
|
||||
MemberDefinition m = remoteMethods[i].getMemberDefinition();
|
||||
Identifier name = m.getName();
|
||||
Type type = m.getType();
|
||||
|
||||
out.writeUTF(name.toString());
|
||||
// type signatures already use mangled class names
|
||||
out.writeUTF(type.getTypeSignature());
|
||||
|
||||
ClassDeclaration exceptions[] = m.getExceptions(env);
|
||||
sortClassDeclarations(exceptions);
|
||||
for (int j = 0; j < exceptions.length; j++) {
|
||||
out.writeUTF(Names.mangleClass(
|
||||
exceptions[j].getName()).toString());
|
||||
}
|
||||
}
|
||||
out.flush();
|
||||
|
||||
// use only the first 64 bits of the digest for the hash
|
||||
byte hashArray[] = md.digest();
|
||||
for (int i = 0; i < Math.min(8, hashArray.length); i++) {
|
||||
hash += ((long) (hashArray[i] & 0xFF)) << (i * 8);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new Error(
|
||||
"unexpected exception computing intetrface hash: " + e);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new Error(
|
||||
"unexpected exception computing intetrface hash: " + e);
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort array of class declarations alphabetically by their mangled
|
||||
* fully-qualified class name. This is used to feed a method's exceptions
|
||||
* in a canonical order into the digest stream for the interface hash
|
||||
* computation.
|
||||
*/
|
||||
private void sortClassDeclarations(ClassDeclaration[] decl) {
|
||||
for (int i = 1; i < decl.length; i++) {
|
||||
ClassDeclaration curr = decl[i];
|
||||
String name = Names.mangleClass(curr.getName()).toString();
|
||||
int j;
|
||||
for (j = i; j > 0; j--) {
|
||||
if (name.compareTo(
|
||||
Names.mangleClass(decl[j - 1].getName()).toString()) >= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
decl[j] = decl[j - 1];
|
||||
}
|
||||
decl[j] = curr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A RemoteClass.Method object encapsulates RMI-specific information
|
||||
* about a particular remote method in the remote implementation class
|
||||
* represented by the outer instance.
|
||||
*/
|
||||
public class Method implements Cloneable {
|
||||
|
||||
/**
|
||||
* Return the definition of the actual class member corresponing
|
||||
* to this method of a remote interface.
|
||||
*
|
||||
* REMIND: Can this method be removed?
|
||||
*/
|
||||
public MemberDefinition getMemberDefinition() {
|
||||
return memberDef;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of this method.
|
||||
*/
|
||||
public Identifier getName() {
|
||||
return memberDef.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the type of this method.
|
||||
*/
|
||||
public Type getType() {
|
||||
return memberDef.getType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of the exception classes declared to be
|
||||
* thrown by this remote method.
|
||||
*
|
||||
* For methods with the same name and type signature inherited
|
||||
* from multiple remote interfaces, the array will contain
|
||||
* the set of exceptions declared in all of the interfaces'
|
||||
* methods that can be legally thrown in each of them.
|
||||
*/
|
||||
public ClassDeclaration[] getExceptions() {
|
||||
return exceptions.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the "method hash" used to identify this remote method
|
||||
* in the JDK 1.2 version of the stub protocol.
|
||||
*/
|
||||
public long getMethodHash() {
|
||||
return methodHash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the string representation of this method.
|
||||
*/
|
||||
public String toString() {
|
||||
return memberDef.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the string representation of this method appropriate
|
||||
* for the construction of a java.rmi.server.Operation object.
|
||||
*/
|
||||
public String getOperationString() {
|
||||
return memberDef.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string consisting of this method's name followed by
|
||||
* its method descriptor, using the Java VM's notation for
|
||||
* method descriptors (see section 4.3.3 of The Java Virtual
|
||||
* Machine Specification).
|
||||
*/
|
||||
public String getNameAndDescriptor() {
|
||||
return memberDef.getName().toString() +
|
||||
memberDef.getType().getTypeSignature();
|
||||
}
|
||||
|
||||
/**
|
||||
* Member definition for this method, from one of the remote
|
||||
* interfaces that this method was found in.
|
||||
*
|
||||
* Note that this member definition may be only one of several
|
||||
* member defintions that correspond to this remote method object,
|
||||
* if several of this class's remote interfaces contain methods
|
||||
* with the same name and type signature. Therefore, this member
|
||||
* definition may declare more exceptions thrown that this remote
|
||||
* method does.
|
||||
*/
|
||||
private MemberDefinition memberDef;
|
||||
|
||||
/** stub "method hash" to identify this method */
|
||||
private long methodHash;
|
||||
|
||||
/**
|
||||
* Exceptions declared to be thrown by this remote method.
|
||||
*
|
||||
* This list can include superfluous entries, such as
|
||||
* unchecked exceptions and subclasses of other entries.
|
||||
*/
|
||||
private ClassDeclaration[] exceptions;
|
||||
|
||||
/**
|
||||
* Create a new Method object corresponding to the given
|
||||
* method definition.
|
||||
*/
|
||||
/*
|
||||
* Temporarily comment out the private modifier until
|
||||
* the VM allows outer class to access inner class's
|
||||
* private constructor
|
||||
*/
|
||||
/* private */ Method(MemberDefinition memberDef) {
|
||||
this.memberDef = memberDef;
|
||||
exceptions = memberDef.getExceptions(env);
|
||||
methodHash = computeMethodHash();
|
||||
}
|
||||
|
||||
/**
|
||||
* Cloning is supported by returning a shallow copy of this object.
|
||||
*/
|
||||
protected Object clone() {
|
||||
try {
|
||||
return super.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw new Error("clone failed");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new Method object that is a legal combination of
|
||||
* this method object and another one.
|
||||
*
|
||||
* This requires determining the exceptions declared by the
|
||||
* combined method, which must be (only) all of the exceptions
|
||||
* declared in both old Methods that may thrown in either of
|
||||
* them.
|
||||
*/
|
||||
private Method mergeWith(Method other) {
|
||||
if (!getName().equals(other.getName()) ||
|
||||
!getType().equals(other.getType()))
|
||||
{
|
||||
throw new Error("attempt to merge method \"" +
|
||||
other.getNameAndDescriptor() + "\" with \"" +
|
||||
getNameAndDescriptor());
|
||||
}
|
||||
|
||||
Vector<ClassDeclaration> legalExceptions
|
||||
= new Vector<ClassDeclaration>();
|
||||
try {
|
||||
collectCompatibleExceptions(
|
||||
other.exceptions, exceptions, legalExceptions);
|
||||
collectCompatibleExceptions(
|
||||
exceptions, other.exceptions, legalExceptions);
|
||||
} catch (ClassNotFound e) {
|
||||
env.error(0, "class.not.found", e.name,
|
||||
getClassDefinition().getName());
|
||||
return null;
|
||||
}
|
||||
|
||||
Method merged = (Method) clone();
|
||||
merged.exceptions = new ClassDeclaration[legalExceptions.size()];
|
||||
legalExceptions.copyInto(merged.exceptions);
|
||||
|
||||
return merged;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add to the supplied list all exceptions in the "from" array
|
||||
* that are subclasses of an exception in the "with" array.
|
||||
*/
|
||||
private void collectCompatibleExceptions(ClassDeclaration[] from,
|
||||
ClassDeclaration[] with,
|
||||
Vector<ClassDeclaration> list)
|
||||
throws ClassNotFound
|
||||
{
|
||||
for (int i = 0; i < from.length; i++) {
|
||||
ClassDefinition exceptionDef = from[i].getClassDefinition(env);
|
||||
if (!list.contains(from[i])) {
|
||||
for (int j = 0; j < with.length; j++) {
|
||||
if (exceptionDef.subClassOf(env, with[j])) {
|
||||
list.addElement(from[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the "method hash" of this remote method. The method
|
||||
* hash is a long containing the first 64 bits of the SHA digest
|
||||
* from the UTF encoded string of the method name and descriptor.
|
||||
*
|
||||
* REMIND: Should this method share implementation code with
|
||||
* the outer class's computeInterfaceHash() method?
|
||||
*/
|
||||
private long computeMethodHash() {
|
||||
long hash = 0;
|
||||
ByteArrayOutputStream sink = new ByteArrayOutputStream(512);
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("SHA");
|
||||
DataOutputStream out = new DataOutputStream(
|
||||
new DigestOutputStream(sink, md));
|
||||
|
||||
String methodString = getNameAndDescriptor();
|
||||
/***** <DEBUG> */
|
||||
if (env.verbose()) {
|
||||
System.out.println("[string used for method hash: \"" +
|
||||
methodString + "\"]");
|
||||
}
|
||||
/***** </DEBUG> */
|
||||
out.writeUTF(methodString);
|
||||
|
||||
// use only the first 64 bits of the digest for the hash
|
||||
out.flush();
|
||||
byte hashArray[] = md.digest();
|
||||
for (int i = 0; i < Math.min(8, hashArray.length); i++) {
|
||||
hash += ((long) (hashArray[i] & 0xFF)) << (i * 8);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new Error(
|
||||
"unexpected exception computing intetrface hash: " + e);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new Error(
|
||||
"unexpected exception computing intetrface hash: " + e);
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
}
|
||||
136
jdkSrc/jdk8/sun/rmi/rmic/Util.java
Normal file
136
jdkSrc/jdk8/sun/rmi/rmic/Util.java
Normal file
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Licensed Materials - Property of IBM
|
||||
* RMI-IIOP v1.0
|
||||
* Copyright IBM Corp. 1998 1999 All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
package sun.rmi.rmic;
|
||||
|
||||
import java.io.File;
|
||||
import sun.tools.java.Identifier;
|
||||
|
||||
/**
|
||||
* Util provides static utility methods used by other rmic 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 Bryan Atsatt
|
||||
*/
|
||||
|
||||
public class Util implements sun.rmi.rmic.Constants {
|
||||
|
||||
/**
|
||||
* Return the directory that should be used for output for a given
|
||||
* class.
|
||||
* @param theClass The fully qualified name of the class.
|
||||
* @param rootDir The directory to use as the root of the
|
||||
* package hierarchy. May be null, in which case the current
|
||||
* working directory is used as the root.
|
||||
*/
|
||||
public static File getOutputDirectoryFor(Identifier theClass,
|
||||
File rootDir,
|
||||
BatchEnvironment env) {
|
||||
|
||||
File outputDir = null;
|
||||
String className = theClass.getFlatName().toString().replace('.', SIGC_INNERCLASS);
|
||||
String qualifiedClassName = className;
|
||||
String packagePath = null;
|
||||
String packageName = theClass.getQualifier().toString();
|
||||
|
||||
if (packageName.length() > 0) {
|
||||
qualifiedClassName = packageName + "." + className;
|
||||
packagePath = packageName.replace('.', File.separatorChar);
|
||||
}
|
||||
|
||||
// Do we have a root directory?
|
||||
|
||||
if (rootDir != null) {
|
||||
|
||||
// Yes, do we have a package name?
|
||||
|
||||
if (packagePath != null) {
|
||||
|
||||
// Yes, so use it as the root. Open the directory...
|
||||
|
||||
outputDir = new File(rootDir, packagePath);
|
||||
|
||||
// Make sure the directory exists...
|
||||
|
||||
ensureDirectory(outputDir,env);
|
||||
|
||||
} else {
|
||||
|
||||
// Default package, so use root as output dir...
|
||||
|
||||
outputDir = rootDir;
|
||||
}
|
||||
} else {
|
||||
|
||||
// No root directory. Get the current working directory...
|
||||
|
||||
String workingDirPath = System.getProperty("user.dir");
|
||||
File workingDir = new File(workingDirPath);
|
||||
|
||||
// Do we have a package name?
|
||||
|
||||
if (packagePath == null) {
|
||||
|
||||
// No, so use working directory...
|
||||
|
||||
outputDir = workingDir;
|
||||
|
||||
} else {
|
||||
|
||||
// Yes, so use working directory as the root...
|
||||
|
||||
outputDir = new File(workingDir, packagePath);
|
||||
|
||||
// Make sure the directory exists...
|
||||
|
||||
ensureDirectory(outputDir,env);
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, return the directory...
|
||||
|
||||
return outputDir;
|
||||
}
|
||||
|
||||
private static void ensureDirectory (File dir, BatchEnvironment env) {
|
||||
if (!dir.exists()) {
|
||||
dir.mkdirs();
|
||||
if (!dir.exists()) {
|
||||
env.error(0,"rmic.cannot.create.dir",dir.getAbsolutePath());
|
||||
throw new InternalError();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
205
jdkSrc/jdk8/sun/rmi/rmic/iiop/AbstractType.java
Normal file
205
jdkSrc/jdk8/sun/rmi/rmic/iiop/AbstractType.java
Normal file
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Licensed Materials - Property of IBM
|
||||
* RMI-IIOP v1.0
|
||||
* Copyright IBM Corp. 1998 1999 All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
package sun.rmi.rmic.iiop;
|
||||
|
||||
import java.util.Vector;
|
||||
import sun.tools.java.CompilerError;
|
||||
import sun.tools.java.ClassNotFound;
|
||||
import sun.tools.java.ClassDefinition;
|
||||
|
||||
/**
|
||||
* AbstractType represents any non-special interface which does not
|
||||
* inherit from java.rmi.Remote, for which all methods throw RemoteException.
|
||||
* <p>
|
||||
* The static forAbstract(...) method must be used to obtain an instance, and will
|
||||
* return null if the ClassDefinition is non-conforming.
|
||||
* @author Bryan Atsatt
|
||||
*/
|
||||
public class AbstractType extends RemoteType {
|
||||
|
||||
//_____________________________________________________________________
|
||||
// Public Interfaces
|
||||
//_____________________________________________________________________
|
||||
|
||||
/**
|
||||
* Create an AbstractType for the given class.
|
||||
*
|
||||
* If the class is not a properly formed or if some other error occurs, the
|
||||
* return value will be null, and errors will have been reported to the
|
||||
* supplied BatchEnvironment.
|
||||
*/
|
||||
public static AbstractType forAbstract(ClassDefinition classDef,
|
||||
ContextStack stack,
|
||||
boolean quiet)
|
||||
{
|
||||
boolean doPop = false;
|
||||
AbstractType result = null;
|
||||
|
||||
try {
|
||||
|
||||
// Do we already have it?
|
||||
|
||||
sun.tools.java.Type theType = classDef.getType();
|
||||
Type existing = getType(theType,stack);
|
||||
|
||||
if (existing != null) {
|
||||
|
||||
if (!(existing instanceof AbstractType)) return null; // False hit.
|
||||
|
||||
// Yep, so return it...
|
||||
|
||||
return (AbstractType) existing;
|
||||
|
||||
}
|
||||
|
||||
// Could this be an abstract?
|
||||
|
||||
if (couldBeAbstract(stack,classDef,quiet)) {
|
||||
|
||||
// Yes, so try it...
|
||||
|
||||
AbstractType it = new AbstractType(stack, classDef);
|
||||
putType(theType,it,stack);
|
||||
stack.push(it);
|
||||
doPop = true;
|
||||
|
||||
if (it.initialize(quiet,stack)) {
|
||||
stack.pop(true);
|
||||
result = it;
|
||||
} else {
|
||||
removeType(theType,stack);
|
||||
stack.pop(false);
|
||||
}
|
||||
}
|
||||
} catch (CompilerError e) {
|
||||
if (doPop) stack.pop(false);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string describing this type.
|
||||
*/
|
||||
public String getTypeDescription () {
|
||||
return "Abstract interface";
|
||||
}
|
||||
|
||||
//_____________________________________________________________________
|
||||
// Internal/Subclass Interfaces
|
||||
//_____________________________________________________________________
|
||||
|
||||
/**
|
||||
* Create a AbstractType instance for the given class. The resulting
|
||||
* object is not yet completely initialized.
|
||||
*/
|
||||
private AbstractType(ContextStack stack, ClassDefinition classDef) {
|
||||
super(stack,classDef,TYPE_ABSTRACT | TM_INTERFACE | TM_COMPOUND);
|
||||
}
|
||||
|
||||
//_____________________________________________________________________
|
||||
// Internal Interfaces
|
||||
//_____________________________________________________________________
|
||||
|
||||
|
||||
private static boolean couldBeAbstract(ContextStack stack, ClassDefinition classDef,
|
||||
boolean quiet) {
|
||||
|
||||
// Return true if interface and not remote...
|
||||
|
||||
boolean result = false;
|
||||
|
||||
if (classDef.isInterface()) {
|
||||
BatchEnvironment env = stack.getEnv();
|
||||
|
||||
try {
|
||||
result = ! env.defRemote.implementedBy(env, classDef.getClassDeclaration());
|
||||
if (!result) failedConstraint(15,quiet,stack,classDef.getName());
|
||||
} catch (ClassNotFound e) {
|
||||
classNotFound(stack,e);
|
||||
}
|
||||
} else {
|
||||
failedConstraint(14,quiet,stack,classDef.getName());
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize this instance.
|
||||
*/
|
||||
private boolean initialize (boolean quiet,ContextStack stack) {
|
||||
|
||||
boolean result = false;
|
||||
ClassDefinition self = getClassDefinition();
|
||||
|
||||
try {
|
||||
|
||||
// Get methods...
|
||||
|
||||
Vector directMethods = new Vector();
|
||||
|
||||
if (addAllMethods(self,directMethods,true,quiet,stack) != null) {
|
||||
|
||||
// Do we have any methods?
|
||||
|
||||
boolean validMethods = true;
|
||||
|
||||
if (directMethods.size() > 0) {
|
||||
|
||||
// Yes. Walk 'em, ensuring each is a valid remote method...
|
||||
|
||||
for (int i = 0; i < directMethods.size(); i++) {
|
||||
|
||||
if (! isConformingRemoteMethod((Method) directMethods.elementAt(i),true)) {
|
||||
validMethods = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (validMethods) {
|
||||
|
||||
// We're ok, so pass 'em up...
|
||||
|
||||
result = initialize(null,directMethods,null,stack,quiet);
|
||||
}
|
||||
}
|
||||
} catch (ClassNotFound e) {
|
||||
classNotFound(stack,e);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
270
jdkSrc/jdk8/sun/rmi/rmic/iiop/ArrayType.java
Normal file
270
jdkSrc/jdk8/sun/rmi/rmic/iiop/ArrayType.java
Normal file
@@ -0,0 +1,270 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Licensed Materials - Property of IBM
|
||||
* RMI-IIOP v1.0
|
||||
* Copyright IBM Corp. 1998 1999 All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
package sun.rmi.rmic.iiop;
|
||||
|
||||
import java.util.Vector;
|
||||
import java.util.HashSet;
|
||||
import sun.tools.java.CompilerError;
|
||||
import sun.tools.java.Identifier;
|
||||
import sun.tools.java.ClassDefinition;
|
||||
import java.lang.reflect.Array;
|
||||
|
||||
/**
|
||||
* ArrayType is a wrapper for any of the other types. The getElementType()
|
||||
* method can be used to get the array element type. The getArrayDimension()
|
||||
* method can be used to get the array dimension.
|
||||
*
|
||||
* @author Bryan Atsatt
|
||||
*/
|
||||
public class ArrayType extends Type {
|
||||
|
||||
private Type type;
|
||||
private int arrayDimension;
|
||||
private String brackets;
|
||||
private String bracketsSig;
|
||||
|
||||
//_____________________________________________________________________
|
||||
// Public Interfaces
|
||||
//_____________________________________________________________________
|
||||
|
||||
/**
|
||||
* Create an ArrayType object for the given type.
|
||||
*
|
||||
* If the class is not a properly formed or if some other error occurs, the
|
||||
* return value will be null, and errors will have been reported to the
|
||||
* supplied BatchEnvironment.
|
||||
*/
|
||||
public static ArrayType forArray( sun.tools.java.Type theType,
|
||||
ContextStack stack) {
|
||||
|
||||
|
||||
ArrayType result = null;
|
||||
sun.tools.java.Type arrayType = theType;
|
||||
|
||||
if (arrayType.getTypeCode() == TC_ARRAY) {
|
||||
|
||||
// Find real type...
|
||||
|
||||
while (arrayType.getTypeCode() == TC_ARRAY) {
|
||||
arrayType = arrayType.getElementType();
|
||||
}
|
||||
|
||||
// Do we already have it?
|
||||
|
||||
Type existing = getType(theType,stack);
|
||||
if (existing != null) {
|
||||
|
||||
if (!(existing instanceof ArrayType)) return null; // False hit.
|
||||
|
||||
// Yep, so return it...
|
||||
|
||||
return (ArrayType) existing;
|
||||
}
|
||||
|
||||
// Now try to make a Type from it...
|
||||
|
||||
Type temp = CompoundType.makeType(arrayType,null,stack);
|
||||
|
||||
if (temp != null) {
|
||||
|
||||
// Got a valid one. Make an array type...
|
||||
|
||||
result = new ArrayType(stack,temp,theType.getArrayDimension());
|
||||
|
||||
// Add it...
|
||||
|
||||
putType(theType,result,stack);
|
||||
|
||||
// Do the stack thing in case tracing on...
|
||||
|
||||
stack.push(result);
|
||||
stack.pop(true);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return signature for this type (e.g. com.acme.Dynamite
|
||||
* would return "com.acme.Dynamite", byte = "B")
|
||||
*/
|
||||
public String getSignature() {
|
||||
return bracketsSig + type.getSignature();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get element type. Returns null if not an array.
|
||||
*/
|
||||
public Type getElementType () {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get array dimension. Returns zero if not an array.
|
||||
*/
|
||||
public int getArrayDimension () {
|
||||
return arrayDimension;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get brackets string. Returns "" if not an array.
|
||||
*/
|
||||
public String getArrayBrackets () {
|
||||
return brackets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string representation of this type.
|
||||
*/
|
||||
public String toString () {
|
||||
return getQualifiedName() + brackets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string describing this type.
|
||||
*/
|
||||
public String getTypeDescription () {
|
||||
return "Array of " + type.getTypeDescription();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the name of this type. For arrays, will include "[]" if useIDLNames == false.
|
||||
* @param useQualifiedNames If true, print qualified names; otherwise, print unqualified names.
|
||||
* @param useIDLNames If true, print IDL names; otherwise, print java names.
|
||||
* @param globalIDLNames If true and useIDLNames true, prepends "::".
|
||||
*/
|
||||
public String getTypeName ( boolean useQualifiedNames,
|
||||
boolean useIDLNames,
|
||||
boolean globalIDLNames) {
|
||||
if (useIDLNames) {
|
||||
return super.getTypeName(useQualifiedNames,useIDLNames,globalIDLNames);
|
||||
} else {
|
||||
return super.getTypeName(useQualifiedNames,useIDLNames,globalIDLNames) + brackets;
|
||||
}
|
||||
}
|
||||
|
||||
//_____________________________________________________________________
|
||||
// Subclass/Internal Interfaces
|
||||
//_____________________________________________________________________
|
||||
|
||||
|
||||
/**
|
||||
* Convert all invalid types to valid ones.
|
||||
*/
|
||||
protected void swapInvalidTypes () {
|
||||
if (type.getStatus() != STATUS_VALID) {
|
||||
type = getValidType(type);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Add matching types to list. Return true if this type has not
|
||||
* been previously checked, false otherwise.
|
||||
*/
|
||||
protected boolean addTypes (int typeCodeFilter,
|
||||
HashSet checked,
|
||||
Vector matching) {
|
||||
|
||||
// Check self.
|
||||
|
||||
boolean result = super.addTypes(typeCodeFilter,checked,matching);
|
||||
|
||||
// Have we been checked before?
|
||||
|
||||
if (result) {
|
||||
|
||||
// No, so add element type...
|
||||
|
||||
getElementType().addTypes(typeCodeFilter,checked,matching);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an ArrayType instance for the given type. The resulting
|
||||
* object is not yet completely initialized.
|
||||
*/
|
||||
private ArrayType(ContextStack stack, Type type, int arrayDimension) {
|
||||
super(stack,TYPE_ARRAY);
|
||||
this.type = type;
|
||||
this.arrayDimension = arrayDimension;
|
||||
|
||||
// Create our brackets string...
|
||||
|
||||
brackets = "";
|
||||
bracketsSig = "";
|
||||
for (int i = 0; i < arrayDimension; i ++) {
|
||||
brackets += "[]";
|
||||
bracketsSig += "[";
|
||||
}
|
||||
|
||||
// Now set our names...
|
||||
|
||||
String idlName = IDLNames.getArrayName(type,arrayDimension);
|
||||
String[] module = IDLNames.getArrayModuleNames(type);
|
||||
setNames(type.getIdentifier(),module,idlName);
|
||||
|
||||
// Set our repositoryID...
|
||||
|
||||
setRepositoryID();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Load a Class instance. Return null if fail.
|
||||
*/
|
||||
protected Class loadClass() {
|
||||
Class result = null;
|
||||
Class elementClass = type.getClassInstance();
|
||||
if (elementClass != null) {
|
||||
result = Array.newInstance(elementClass, new int[arrayDimension]).getClass();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Release all resources
|
||||
*/
|
||||
protected void destroy () {
|
||||
super.destroy();
|
||||
if (type != null) {
|
||||
type.destroy();
|
||||
type = null;
|
||||
}
|
||||
brackets = null;
|
||||
bracketsSig = null;
|
||||
}
|
||||
}
|
||||
260
jdkSrc/jdk8/sun/rmi/rmic/iiop/BatchEnvironment.java
Normal file
260
jdkSrc/jdk8/sun/rmi/rmic/iiop/BatchEnvironment.java
Normal file
@@ -0,0 +1,260 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Licensed Materials - Property of IBM
|
||||
* RMI-IIOP v1.0
|
||||
* Copyright IBM Corp. 1998 1999 All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
package sun.rmi.rmic.iiop;
|
||||
|
||||
import sun.rmi.rmic.Main;
|
||||
import sun.tools.java.ClassPath;
|
||||
import java.io.OutputStream;
|
||||
import sun.tools.java.ClassDefinition;
|
||||
import sun.tools.java.ClassDeclaration;
|
||||
import sun.tools.java.Identifier;
|
||||
import sun.tools.java.ClassNotFound;
|
||||
import java.util.HashSet;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* BatchEnvironment for iiop extends rmic's version to add
|
||||
* parse state.
|
||||
*/
|
||||
public class BatchEnvironment extends sun.rmi.rmic.BatchEnvironment implements Constants {
|
||||
|
||||
/*
|
||||
* If the following flag is true, then the IDL generator can map
|
||||
* the methods and constants of non-conforming types. However,
|
||||
* this is very expensive, so the default should be false.
|
||||
*/
|
||||
private boolean parseNonConforming = false;
|
||||
|
||||
/**
|
||||
* This flag indicates that the stubs and ties need to be generated without
|
||||
* the package prefix (org.omg.stub).
|
||||
*/
|
||||
private boolean standardPackage;
|
||||
|
||||
/* Common objects used within package */
|
||||
|
||||
HashSet alreadyChecked = new HashSet();
|
||||
Hashtable allTypes = new Hashtable(3001, 0.5f);
|
||||
Hashtable invalidTypes = new Hashtable(256, 0.5f);
|
||||
DirectoryLoader loader = null;
|
||||
ClassPathLoader classPathLoader = null;
|
||||
Hashtable nameContexts = null;
|
||||
Hashtable namesCache = new Hashtable();
|
||||
NameContext modulesContext = new NameContext(false);
|
||||
|
||||
ClassDefinition defRemote = null;
|
||||
ClassDefinition defError = null;
|
||||
ClassDefinition defException = null;
|
||||
ClassDefinition defRemoteException = null;
|
||||
ClassDefinition defCorbaObject = null;
|
||||
ClassDefinition defSerializable = null;
|
||||
ClassDefinition defExternalizable = null;
|
||||
ClassDefinition defThrowable = null;
|
||||
ClassDefinition defRuntimeException = null;
|
||||
ClassDefinition defIDLEntity = null;
|
||||
ClassDefinition defValueBase = null;
|
||||
|
||||
sun.tools.java.Type typeRemoteException = null;
|
||||
sun.tools.java.Type typeIOException = null;
|
||||
sun.tools.java.Type typeException = null;
|
||||
sun.tools.java.Type typeThrowable = null;
|
||||
|
||||
ContextStack contextStack = null;
|
||||
|
||||
/**
|
||||
* Create a BatchEnvironment for rmic with the given class path,
|
||||
* stream for messages and Main.
|
||||
*/
|
||||
public BatchEnvironment(OutputStream out, ClassPath path, Main main) {
|
||||
|
||||
super(out,path,main);
|
||||
|
||||
// Make sure we have our definitions...
|
||||
|
||||
try {
|
||||
defRemote =
|
||||
getClassDeclaration(idRemote).getClassDefinition(this);
|
||||
defError =
|
||||
getClassDeclaration(idJavaLangError).getClassDefinition(this);
|
||||
defException =
|
||||
getClassDeclaration(idJavaLangException).getClassDefinition(this);
|
||||
defRemoteException =
|
||||
getClassDeclaration(idRemoteException).getClassDefinition(this);
|
||||
defCorbaObject =
|
||||
getClassDeclaration(idCorbaObject).getClassDefinition(this);
|
||||
defSerializable =
|
||||
getClassDeclaration(idJavaIoSerializable).getClassDefinition(this);
|
||||
defRuntimeException =
|
||||
getClassDeclaration(idJavaLangRuntimeException).getClassDefinition(this);
|
||||
defExternalizable =
|
||||
getClassDeclaration(idJavaIoExternalizable).getClassDefinition(this);
|
||||
defThrowable=
|
||||
getClassDeclaration(idJavaLangThrowable).getClassDefinition(this);
|
||||
defIDLEntity=
|
||||
getClassDeclaration(idIDLEntity).getClassDefinition(this);
|
||||
defValueBase=
|
||||
getClassDeclaration(idValueBase).getClassDefinition(this);
|
||||
typeRemoteException = defRemoteException.getClassDeclaration().getType();
|
||||
typeException = defException.getClassDeclaration().getType();
|
||||
typeIOException = getClassDeclaration(idJavaIoIOException).getType();
|
||||
typeThrowable = getClassDeclaration(idJavaLangThrowable).getType();
|
||||
|
||||
classPathLoader = new ClassPathLoader(path);
|
||||
|
||||
} catch (ClassNotFound e) {
|
||||
error(0, "rmic.class.not.found", e.name);
|
||||
throw new Error();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether or not to parse non-conforming types.
|
||||
*/
|
||||
public boolean getParseNonConforming () {
|
||||
return parseNonConforming;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether or not to parse non-conforming types.
|
||||
*/
|
||||
public void setParseNonConforming (boolean parseEm) {
|
||||
|
||||
// If we are transitioning from not parsing to
|
||||
// parsing, we need to throw out any previously
|
||||
// parsed types...
|
||||
|
||||
if (parseEm && !parseNonConforming) {
|
||||
reset();
|
||||
}
|
||||
|
||||
parseNonConforming = parseEm;
|
||||
}
|
||||
|
||||
void setStandardPackage(boolean standardPackage) {
|
||||
this.standardPackage = standardPackage;
|
||||
}
|
||||
|
||||
boolean getStandardPackage() {
|
||||
return standardPackage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear out any data from previous executions.
|
||||
*/
|
||||
public void reset () {
|
||||
|
||||
// First, find all Type instances and call destroy()
|
||||
// on them...
|
||||
|
||||
for (Enumeration e = allTypes.elements() ; e.hasMoreElements() ;) {
|
||||
Type type = (Type) e.nextElement();
|
||||
type.destroy();
|
||||
}
|
||||
|
||||
for (Enumeration e = invalidTypes.keys() ; e.hasMoreElements() ;) {
|
||||
Type type = (Type) e.nextElement();
|
||||
type.destroy();
|
||||
}
|
||||
|
||||
for (Iterator e = alreadyChecked.iterator() ; e.hasNext() ;) {
|
||||
Type type = (Type) e.next();
|
||||
type.destroy();
|
||||
}
|
||||
|
||||
if (contextStack != null) contextStack.clear();
|
||||
|
||||
// Remove and clear all NameContexts in the
|
||||
// nameContexts cache...
|
||||
|
||||
if (nameContexts != null) {
|
||||
for (Enumeration e = nameContexts.elements() ; e.hasMoreElements() ;) {
|
||||
NameContext context = (NameContext) e.nextElement();
|
||||
context.clear();
|
||||
}
|
||||
nameContexts.clear();
|
||||
}
|
||||
|
||||
// Now remove all table entries...
|
||||
|
||||
allTypes.clear();
|
||||
invalidTypes.clear();
|
||||
alreadyChecked.clear();
|
||||
namesCache.clear();
|
||||
modulesContext.clear();
|
||||
|
||||
// Clean up remaining...
|
||||
loader = null;
|
||||
parseNonConforming = false;
|
||||
|
||||
// REVISIT - can't clean up classPathLoader here
|
||||
}
|
||||
|
||||
/**
|
||||
* Release resources, if any.
|
||||
*/
|
||||
public void shutdown() {
|
||||
if (alreadyChecked != null) {
|
||||
//System.out.println();
|
||||
//System.out.println("allTypes.size() = "+ allTypes.size());
|
||||
//System.out.println(" InstanceCount before reset = "+Type.instanceCount);
|
||||
reset();
|
||||
//System.out.println(" InstanceCount AFTER reset = "+Type.instanceCount);
|
||||
|
||||
alreadyChecked = null;
|
||||
allTypes = null;
|
||||
invalidTypes = null;
|
||||
nameContexts = null;
|
||||
namesCache = null;
|
||||
modulesContext = null;
|
||||
defRemote = null;
|
||||
defError = null;
|
||||
defException = null;
|
||||
defRemoteException = null;
|
||||
defCorbaObject = null;
|
||||
defSerializable = null;
|
||||
defExternalizable = null;
|
||||
defThrowable = null;
|
||||
defRuntimeException = null;
|
||||
defIDLEntity = null;
|
||||
defValueBase = null;
|
||||
typeRemoteException = null;
|
||||
typeIOException = null;
|
||||
typeException = null;
|
||||
typeThrowable = null;
|
||||
|
||||
super.shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
117
jdkSrc/jdk8/sun/rmi/rmic/iiop/ClassPathLoader.java
Normal file
117
jdkSrc/jdk8/sun/rmi/rmic/iiop/ClassPathLoader.java
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package sun.rmi.rmic.iiop;
|
||||
|
||||
import java.io.*;
|
||||
import sun.tools.java.ClassPath ;
|
||||
import sun.tools.java.ClassFile ;
|
||||
|
||||
/**
|
||||
* A ClassLoader that will ultimately use a given sun.tools.java.ClassPath to
|
||||
* find the desired file. This works for any JAR files specified in the given
|
||||
* ClassPath as well -- reusing all of that wonderful sun.tools.java code.
|
||||
*
|
||||
*@author Everett Anderson
|
||||
*/
|
||||
public class ClassPathLoader extends ClassLoader
|
||||
{
|
||||
private ClassPath classPath;
|
||||
|
||||
public ClassPathLoader(ClassPath classPath) {
|
||||
this.classPath = classPath;
|
||||
}
|
||||
|
||||
// Called by the super class
|
||||
protected Class findClass(String name) throws ClassNotFoundException
|
||||
{
|
||||
byte[] b = loadClassData(name);
|
||||
return defineClass(name, b, 0, b.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the class with the given fully qualified name from the ClassPath.
|
||||
*/
|
||||
private byte[] loadClassData(String className)
|
||||
throws ClassNotFoundException
|
||||
{
|
||||
// Build the file name and subdirectory from the
|
||||
// class name
|
||||
String filename = className.replace('.', File.separatorChar)
|
||||
+ ".class";
|
||||
|
||||
// Have ClassPath find the file for us, and wrap it in a
|
||||
// ClassFile. Note: This is where it looks inside jar files that
|
||||
// are specified in the path.
|
||||
ClassFile classFile = classPath.getFile(filename);
|
||||
|
||||
if (classFile != null) {
|
||||
|
||||
// Provide the most specific reason for failure in addition
|
||||
// to ClassNotFound
|
||||
Exception reportedError = null;
|
||||
byte data[] = null;
|
||||
|
||||
try {
|
||||
// ClassFile is beautiful because it shields us from
|
||||
// knowing if it's a separate file or an entry in a
|
||||
// jar file.
|
||||
DataInputStream input
|
||||
= new DataInputStream(classFile.getInputStream());
|
||||
|
||||
// Can't rely on input available() since it will be
|
||||
// something unusual if it's a jar file! May need
|
||||
// to worry about a possible problem if someone
|
||||
// makes a jar file entry with a size greater than
|
||||
// max int.
|
||||
data = new byte[(int)classFile.length()];
|
||||
|
||||
try {
|
||||
input.readFully(data);
|
||||
} catch (IOException ex) {
|
||||
// Something actually went wrong reading the file. This
|
||||
// is a real error so save it to report it.
|
||||
data = null;
|
||||
reportedError = ex;
|
||||
} finally {
|
||||
// Just don't care if there's an exception on close!
|
||||
// I hate that close can throw an IOException!
|
||||
try { input.close(); } catch (IOException ex) {}
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
// Couldn't get the input stream for the file. This is
|
||||
// probably also a real error.
|
||||
reportedError = ex;
|
||||
}
|
||||
|
||||
if (data == null)
|
||||
throw new ClassNotFoundException(className, reportedError);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
// Couldn't find the file in the class path.
|
||||
throw new ClassNotFoundException(className);
|
||||
}
|
||||
}
|
||||
215
jdkSrc/jdk8/sun/rmi/rmic/iiop/ClassType.java
Normal file
215
jdkSrc/jdk8/sun/rmi/rmic/iiop/ClassType.java
Normal file
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Licensed Materials - Property of IBM
|
||||
* RMI-IIOP v1.0
|
||||
* Copyright IBM Corp. 1998 1999 All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
package sun.rmi.rmic.iiop;
|
||||
|
||||
import sun.tools.java.CompilerError;
|
||||
import sun.tools.java.ClassNotFound;
|
||||
import sun.tools.java.ClassDeclaration;
|
||||
import sun.tools.java.ClassDefinition;
|
||||
import sun.rmi.rmic.IndentingWriter;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* ClassType is an abstract base representing any non-special class
|
||||
* type.
|
||||
*
|
||||
* @author Bryan Atsatt
|
||||
*/
|
||||
public abstract class ClassType extends CompoundType {
|
||||
|
||||
private ClassType parent;
|
||||
|
||||
//_____________________________________________________________________
|
||||
// Public Interfaces
|
||||
//_____________________________________________________________________
|
||||
|
||||
/**
|
||||
* Return the parent class of this type. Returns null if this
|
||||
* type is an interface or if there is no parent.
|
||||
*/
|
||||
public ClassType getSuperclass() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Print this type.
|
||||
* @param writer The stream to print to.
|
||||
* @param useQualifiedNames If true, print qualified names; otherwise, print unqualified names.
|
||||
* @param useIDLNames If true, print IDL names; otherwise, print java names.
|
||||
* @param globalIDLNames If true and useIDLNames true, prepends "::".
|
||||
*/
|
||||
public void print ( IndentingWriter writer,
|
||||
boolean useQualifiedNames,
|
||||
boolean useIDLNames,
|
||||
boolean globalIDLNames) throws IOException {
|
||||
|
||||
if (isInner()) {
|
||||
writer.p("// " + getTypeDescription() + " (INNER)");
|
||||
} else {
|
||||
writer.p("// " + getTypeDescription());
|
||||
}
|
||||
writer.pln(" (" + getRepositoryID() + ")\n");
|
||||
|
||||
printPackageOpen(writer,useIDLNames);
|
||||
|
||||
if (!useIDLNames) {
|
||||
writer.p("public ");
|
||||
}
|
||||
|
||||
String prefix = "";
|
||||
writer.p("class " + getTypeName(false,useIDLNames,false));
|
||||
if (printExtends(writer,useQualifiedNames,useIDLNames,globalIDLNames)) {
|
||||
prefix = ",";
|
||||
}
|
||||
printImplements(writer,prefix,useQualifiedNames,useIDLNames,globalIDLNames);
|
||||
writer.plnI(" {");
|
||||
printMembers(writer,useQualifiedNames,useIDLNames,globalIDLNames);
|
||||
writer.pln();
|
||||
printMethods(writer,useQualifiedNames,useIDLNames,globalIDLNames);
|
||||
|
||||
if (useIDLNames) {
|
||||
writer.pOln("};");
|
||||
} else {
|
||||
writer.pOln("}");
|
||||
}
|
||||
|
||||
printPackageClose(writer,useIDLNames);
|
||||
}
|
||||
|
||||
|
||||
//_____________________________________________________________________
|
||||
// Subclass/Internal Interfaces
|
||||
//_____________________________________________________________________
|
||||
|
||||
protected void destroy () {
|
||||
if (!destroyed) {
|
||||
super.destroy();
|
||||
if (parent != null) {
|
||||
parent.destroy();
|
||||
parent = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a ClassType instance for the given class. NOTE: This constructor
|
||||
* is ONLY for SpecialClassType.
|
||||
*/
|
||||
protected ClassType(ContextStack stack, int typeCode, ClassDefinition classDef) {
|
||||
super(stack,typeCode,classDef); // Call special parent constructor.
|
||||
if ((typeCode & TM_CLASS) == 0 && classDef.isInterface()) {
|
||||
throw new CompilerError("Not a class");
|
||||
}
|
||||
parent = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a ClassType instance for the given class. NOTE: This constructor
|
||||
* is ONLY for ImplementationType. It does not walk the parent chain.
|
||||
*/
|
||||
protected ClassType(int typeCode, ClassDefinition classDef,ContextStack stack) {
|
||||
super(stack,classDef,typeCode);
|
||||
|
||||
if ((typeCode & TM_CLASS) == 0 && classDef.isInterface()) {
|
||||
throw new CompilerError("Not a class");
|
||||
}
|
||||
parent = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an ClassType instance for the given class. The resulting
|
||||
* object is not yet completely initialized. Subclasses must call
|
||||
* initialize(directInterfaces,directInterfaces,directConstants);
|
||||
*/
|
||||
protected ClassType(ContextStack stack,
|
||||
ClassDefinition classDef,
|
||||
int typeCode) {
|
||||
super(stack,classDef,typeCode);
|
||||
if ((typeCode & TM_CLASS) == 0 && classDef.isInterface()) {
|
||||
throw new CompilerError("Not a class");
|
||||
}
|
||||
parent = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert all invalid types to valid ones.
|
||||
*/
|
||||
protected void swapInvalidTypes () {
|
||||
super.swapInvalidTypes();
|
||||
if (parent != null && parent.getStatus() != STATUS_VALID) {
|
||||
parent = (ClassType) getValidType(parent);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify the type description with exception info.
|
||||
*/
|
||||
public String addExceptionDescription (String typeDesc) {
|
||||
if (isException) {
|
||||
if (isCheckedException) {
|
||||
typeDesc = typeDesc + " - Checked Exception";
|
||||
} else {
|
||||
typeDesc = typeDesc + " - Unchecked Exception";
|
||||
}
|
||||
}
|
||||
return typeDesc;
|
||||
}
|
||||
|
||||
|
||||
protected boolean initParents(ContextStack stack) {
|
||||
|
||||
stack.setNewContextCode(ContextStack.EXTENDS);
|
||||
BatchEnvironment env = stack.getEnv();
|
||||
|
||||
// Init parent...
|
||||
|
||||
boolean result = true;
|
||||
|
||||
try {
|
||||
ClassDeclaration parentDecl = getClassDefinition().getSuperClass(env);
|
||||
if (parentDecl != null) {
|
||||
ClassDefinition parentDef = parentDecl.getClassDefinition(env);
|
||||
parent = (ClassType) makeType(parentDef.getType(),parentDef,stack);
|
||||
if (parent == null) {
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
} catch (ClassNotFound e) {
|
||||
classNotFound(stack,e);
|
||||
throw new CompilerError("ClassType constructor");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
2703
jdkSrc/jdk8/sun/rmi/rmic/iiop/CompoundType.java
Normal file
2703
jdkSrc/jdk8/sun/rmi/rmic/iiop/CompoundType.java
Normal file
File diff suppressed because it is too large
Load Diff
297
jdkSrc/jdk8/sun/rmi/rmic/iiop/Constants.java
Normal file
297
jdkSrc/jdk8/sun/rmi/rmic/iiop/Constants.java
Normal file
@@ -0,0 +1,297 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Licensed Materials - Property of IBM
|
||||
* RMI-IIOP v1.0
|
||||
* Copyright IBM Corp. 1998 1999 All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
package sun.rmi.rmic.iiop;
|
||||
|
||||
import sun.tools.java.Identifier;
|
||||
|
||||
public interface Constants extends sun.rmi.rmic.Constants {
|
||||
|
||||
// Identifiers for referenced classes:
|
||||
|
||||
public static final Identifier idReplyHandler =
|
||||
Identifier.lookup("org.omg.CORBA.portable.ResponseHandler");
|
||||
public static final Identifier idStubBase =
|
||||
Identifier.lookup("javax.rmi.CORBA.Stub");
|
||||
public static final Identifier idTieBase =
|
||||
Identifier.lookup("org.omg.CORBA.portable.ObjectImpl");
|
||||
public static final Identifier idTieInterface =
|
||||
Identifier.lookup("javax.rmi.CORBA.Tie");
|
||||
public static final Identifier idPOAServantType =
|
||||
Identifier.lookup( "org.omg.PortableServer.Servant" ) ;
|
||||
public static final Identifier idDelegate =
|
||||
Identifier.lookup("org.omg.CORBA.portable.Delegate");
|
||||
public static final Identifier idOutputStream =
|
||||
Identifier.lookup("org.omg.CORBA.portable.OutputStream");
|
||||
public static final Identifier idExtOutputStream =
|
||||
Identifier.lookup("org.omg.CORBA_2_3.portable.OutputStream");
|
||||
public static final Identifier idInputStream =
|
||||
Identifier.lookup("org.omg.CORBA.portable.InputStream");
|
||||
public static final Identifier idExtInputStream =
|
||||
Identifier.lookup("org.omg.CORBA_2_3.portable.InputStream");
|
||||
public static final Identifier idSystemException =
|
||||
Identifier.lookup("org.omg.CORBA.SystemException");
|
||||
public static final Identifier idBadMethodException =
|
||||
Identifier.lookup("org.omg.CORBA.BAD_OPERATION");
|
||||
public static final Identifier idPortableUnknownException =
|
||||
Identifier.lookup("org.omg.CORBA.portable.UnknownException");
|
||||
public static final Identifier idApplicationException =
|
||||
Identifier.lookup("org.omg.CORBA.portable.ApplicationException");
|
||||
public static final Identifier idRemarshalException =
|
||||
Identifier.lookup("org.omg.CORBA.portable.RemarshalException");
|
||||
public static final Identifier idJavaIoExternalizable =
|
||||
Identifier.lookup("java.io.Externalizable");
|
||||
public static final Identifier idCorbaObject =
|
||||
Identifier.lookup("org.omg.CORBA.Object");
|
||||
public static final Identifier idCorbaORB =
|
||||
Identifier.lookup("org.omg.CORBA.ORB");
|
||||
public static final Identifier idClassDesc =
|
||||
Identifier.lookup("javax.rmi.CORBA.ClassDesc");
|
||||
public static final Identifier idJavaIoIOException =
|
||||
Identifier.lookup("java.io.IOException");
|
||||
public static final Identifier idIDLEntity =
|
||||
Identifier.lookup("org.omg.CORBA.portable.IDLEntity");
|
||||
public static final Identifier idValueBase =
|
||||
Identifier.lookup("org.omg.CORBA.portable.ValueBase");
|
||||
public static final Identifier idBoxedRMI =
|
||||
Identifier.lookup("org.omg.boxedRMI");
|
||||
public static final Identifier idBoxedIDL =
|
||||
Identifier.lookup("org.omg.boxedIDL");
|
||||
public static final Identifier idCorbaUserException =
|
||||
Identifier.lookup("org.omg.CORBA.UserException");
|
||||
|
||||
|
||||
// Identifiers for primitive types:
|
||||
|
||||
public static final Identifier idBoolean =
|
||||
Identifier.lookup("boolean");
|
||||
public static final Identifier idByte =
|
||||
Identifier.lookup("byte");
|
||||
public static final Identifier idChar =
|
||||
Identifier.lookup("char");
|
||||
public static final Identifier idShort =
|
||||
Identifier.lookup("short");
|
||||
public static final Identifier idInt =
|
||||
Identifier.lookup("int");
|
||||
public static final Identifier idLong =
|
||||
Identifier.lookup("long");
|
||||
public static final Identifier idFloat =
|
||||
Identifier.lookup("float");
|
||||
public static final Identifier idDouble =
|
||||
Identifier.lookup("double");
|
||||
public static final Identifier idVoid =
|
||||
Identifier.lookup("void");
|
||||
|
||||
// IndentingWriter constructor args:
|
||||
|
||||
public static final int INDENT_STEP = 4;
|
||||
public static final int TAB_SIZE = Integer.MAX_VALUE; // No tabs.
|
||||
|
||||
// Type status codes:
|
||||
|
||||
public static final int STATUS_PENDING = 0;
|
||||
public static final int STATUS_VALID = 1;
|
||||
public static final int STATUS_INVALID = 2;
|
||||
|
||||
// Java Names:
|
||||
|
||||
public static final String NAME_SEPARATOR = ".";
|
||||
public static final String SERIAL_VERSION_UID = "serialVersionUID";
|
||||
|
||||
// IDL Names:
|
||||
|
||||
public static final String[] IDL_KEYWORDS = {
|
||||
"abstract",
|
||||
"any",
|
||||
"attribute",
|
||||
"boolean",
|
||||
"case",
|
||||
"char",
|
||||
"const",
|
||||
"context",
|
||||
"custom",
|
||||
"default",
|
||||
"double",
|
||||
"enum",
|
||||
"exception",
|
||||
"factory",
|
||||
"FALSE",
|
||||
"fixed",
|
||||
"float",
|
||||
"in",
|
||||
"inout",
|
||||
"interface",
|
||||
"long",
|
||||
"module",
|
||||
"native",
|
||||
"Object",
|
||||
"octet",
|
||||
"oneway",
|
||||
"out",
|
||||
"private",
|
||||
"public",
|
||||
"raises",
|
||||
"readonly",
|
||||
"sequence",
|
||||
"short",
|
||||
"string",
|
||||
"struct",
|
||||
"supports",
|
||||
"switch",
|
||||
"TRUE",
|
||||
"truncatable",
|
||||
"typedef",
|
||||
"unsigned",
|
||||
"union",
|
||||
"ValueBase",
|
||||
"valuetype",
|
||||
"void",
|
||||
"wchar",
|
||||
"wstring",
|
||||
};
|
||||
|
||||
|
||||
public static final String EXCEPTION_SUFFIX = "Exception";
|
||||
public static final String ERROR_SUFFIX = "Error";
|
||||
public static final String EX_SUFFIX = "Ex";
|
||||
|
||||
public static final String IDL_REPOSITORY_ID_PREFIX = "IDL:";
|
||||
public static final String IDL_REPOSITORY_ID_VERSION = ":1.0";
|
||||
|
||||
public static final String[] IDL_CORBA_MODULE = {"CORBA"};
|
||||
public static final String[] IDL_SEQUENCE_MODULE = {"org","omg","boxedRMI"};
|
||||
public static final String[] IDL_BOXEDIDL_MODULE = {"org","omg","boxedIDL"};
|
||||
|
||||
public static final String IDL_CLASS = "ClassDesc";
|
||||
public static final String[] IDL_CLASS_MODULE = {"javax","rmi","CORBA"};
|
||||
|
||||
public static final String IDL_IDLENTITY = "IDLEntity";
|
||||
public static final String IDL_SERIALIZABLE = "Serializable";
|
||||
public static final String IDL_EXTERNALIZABLE = "Externalizable";
|
||||
public static final String[] IDL_JAVA_IO_MODULE = {"java","io"};
|
||||
public static final String[] IDL_ORG_OMG_CORBA_MODULE = {"org","omg","CORBA"};
|
||||
public static final String[] IDL_ORG_OMG_CORBA_PORTABLE_MODULE = {"org","omg","CORBA","portable"};
|
||||
|
||||
public static final String IDL_JAVA_LANG_OBJECT = "_Object";
|
||||
public static final String[] IDL_JAVA_LANG_MODULE = {"java","lang"};
|
||||
|
||||
public static final String IDL_JAVA_RMI_REMOTE = "Remote";
|
||||
public static final String[] IDL_JAVA_RMI_MODULE = {"java","rmi"};
|
||||
|
||||
public static final String IDL_SEQUENCE = "seq";
|
||||
|
||||
public static final String IDL_CONSTRUCTOR = "create";
|
||||
|
||||
public static final String IDL_NAME_SEPARATOR = "::";
|
||||
public static final String IDL_BOOLEAN = "boolean";
|
||||
public static final String IDL_BYTE = "octet";
|
||||
public static final String IDL_CHAR = "wchar";
|
||||
public static final String IDL_SHORT = "short";
|
||||
public static final String IDL_INT = "long";
|
||||
public static final String IDL_LONG = "long long";
|
||||
public static final String IDL_FLOAT = "float";
|
||||
public static final String IDL_DOUBLE = "double";
|
||||
public static final String IDL_VOID = "void";
|
||||
|
||||
public static final String IDL_STRING = "WStringValue";
|
||||
public static final String IDL_CONSTANT_STRING = "wstring";
|
||||
public static final String IDL_CORBA_OBJECT = "Object";
|
||||
public static final String IDL_ANY = "any";
|
||||
|
||||
// File names:
|
||||
|
||||
public static final String SOURCE_FILE_EXTENSION = ".java";
|
||||
public static final String IDL_FILE_EXTENSION = ".idl";
|
||||
|
||||
// Type Codes:
|
||||
|
||||
public static final int TYPE_VOID = 0x00000001; // In PrimitiveType
|
||||
public static final int TYPE_BOOLEAN = 0x00000002; // In PrimitiveType
|
||||
public static final int TYPE_BYTE = 0x00000004; // In PrimitiveType
|
||||
public static final int TYPE_CHAR = 0x00000008; // In PrimitiveType
|
||||
public static final int TYPE_SHORT = 0x00000010; // In PrimitiveType
|
||||
public static final int TYPE_INT = 0x00000020; // In PrimitiveType
|
||||
public static final int TYPE_LONG = 0x00000040; // In PrimitiveType
|
||||
public static final int TYPE_FLOAT = 0x00000080; // In PrimitiveType
|
||||
public static final int TYPE_DOUBLE = 0x00000100; // In PrimitiveType
|
||||
|
||||
public static final int TYPE_STRING = 0x00000200; // In SpecialClassType (String)
|
||||
public static final int TYPE_ANY = 0x00000400; // In SpecialInterfaceType (Serializable,Externalizable)
|
||||
public static final int TYPE_CORBA_OBJECT = 0x00000800; // In SpecialInterfaceType (CORBA.Object,Remote)
|
||||
|
||||
public static final int TYPE_REMOTE = 0x00001000; // In RemoteType
|
||||
public static final int TYPE_ABSTRACT = 0x00002000; // In AbstractType
|
||||
public static final int TYPE_NC_INTERFACE = 0x00004000; // In NCInterfaceType
|
||||
|
||||
public static final int TYPE_VALUE = 0x00008000; // In ValueType
|
||||
public static final int TYPE_IMPLEMENTATION = 0x00010000; // In ImplementationType
|
||||
public static final int TYPE_NC_CLASS = 0x00020000; // In NCClassType
|
||||
|
||||
public static final int TYPE_ARRAY = 0x00040000; // In ArrayType
|
||||
public static final int TYPE_JAVA_RMI_REMOTE = 0x00080000; // In SpecialInterfaceType
|
||||
|
||||
// Type code masks:
|
||||
|
||||
public static final int TYPE_NONE = 0x00000000;
|
||||
public static final int TYPE_ALL = 0xFFFFFFFF;
|
||||
public static final int TYPE_MASK = 0x00FFFFFF;
|
||||
public static final int TM_MASK = 0xFF000000;
|
||||
|
||||
// Type code modifiers:
|
||||
|
||||
public static final int TM_PRIMITIVE = 0x01000000;
|
||||
public static final int TM_COMPOUND = 0x02000000;
|
||||
public static final int TM_CLASS = 0x04000000;
|
||||
public static final int TM_INTERFACE = 0x08000000;
|
||||
public static final int TM_SPECIAL_CLASS = 0x10000000;
|
||||
public static final int TM_SPECIAL_INTERFACE= 0x20000000;
|
||||
public static final int TM_NON_CONFORMING = 0x40000000;
|
||||
public static final int TM_INNER = 0x80000000;
|
||||
|
||||
// Attribute kinds...
|
||||
|
||||
public static final int ATTRIBUTE_NONE = 0; // Not an attribute.
|
||||
public static final int ATTRIBUTE_IS = 1; // read-only, had "is" prefix.
|
||||
public static final int ATTRIBUTE_GET = 2; // read-only, had "get" prefix.
|
||||
public static final int ATTRIBUTE_IS_RW = 3; // read-write, had "is" prefix.
|
||||
public static final int ATTRIBUTE_GET_RW = 4; // read-write, had "get" prefix.
|
||||
public static final int ATTRIBUTE_SET = 5; // had "set" prefix.
|
||||
|
||||
public static final String[] ATTRIBUTE_WIRE_PREFIX = {
|
||||
"",
|
||||
"_get_",
|
||||
"_get_",
|
||||
"_get_",
|
||||
"_get_",
|
||||
"_set_",
|
||||
};
|
||||
}
|
||||
41
jdkSrc/jdk8/sun/rmi/rmic/iiop/ContextElement.java
Normal file
41
jdkSrc/jdk8/sun/rmi/rmic/iiop/ContextElement.java
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Licensed Materials - Property of IBM
|
||||
* RMI-IIOP v1.0
|
||||
* Copyright IBM Corp. 1998 1999 All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
package sun.rmi.rmic.iiop;
|
||||
|
||||
/**
|
||||
* ContextElement provides a common interface for elements of a ContextStack.
|
||||
* @author Bryan Atsatt
|
||||
*/
|
||||
public interface ContextElement {
|
||||
public String getElementName();
|
||||
}
|
||||
447
jdkSrc/jdk8/sun/rmi/rmic/iiop/ContextStack.java
Normal file
447
jdkSrc/jdk8/sun/rmi/rmic/iiop/ContextStack.java
Normal file
@@ -0,0 +1,447 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Licensed Materials - Property of IBM
|
||||
* RMI-IIOP v1.0
|
||||
* Copyright IBM Corp. 1998 1999 All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
package sun.rmi.rmic.iiop;
|
||||
|
||||
import sun.tools.java.CompilerError;
|
||||
|
||||
/**
|
||||
* ContextStack provides a mechanism to record parsing state.
|
||||
*
|
||||
* @author Bryan Atsatt
|
||||
*/
|
||||
public class ContextStack {
|
||||
|
||||
// Context codes.
|
||||
|
||||
public static final int TOP = 1;
|
||||
|
||||
public static final int METHOD = 2;
|
||||
public static final int METHOD_RETURN = 3;
|
||||
public static final int METHOD_ARGUMENT = 4;
|
||||
public static final int METHOD_EXCEPTION = 5;
|
||||
|
||||
public static final int MEMBER = 6;
|
||||
public static final int MEMBER_CONSTANT = 7;
|
||||
public static final int MEMBER_STATIC = 8;
|
||||
public static final int MEMBER_TRANSIENT = 9;
|
||||
|
||||
public static final int IMPLEMENTS = 10;
|
||||
public static final int EXTENDS = 11;
|
||||
|
||||
// String versions of context codes.
|
||||
|
||||
private static final String[] CODE_NAMES = {
|
||||
"UNKNOWN ",
|
||||
"Top level type ",
|
||||
"Method ",
|
||||
"Return parameter ",
|
||||
"Parameter ",
|
||||
"Exception ",
|
||||
"Member ",
|
||||
"Constant member ",
|
||||
"Static member ",
|
||||
"Transient member ",
|
||||
"Implements ",
|
||||
"Extends ",
|
||||
};
|
||||
// Member data.
|
||||
|
||||
private int currentIndex = -1;
|
||||
private int maxIndex = 100;
|
||||
private TypeContext[] stack = new TypeContext[maxIndex];
|
||||
private int newCode = TOP;
|
||||
private BatchEnvironment env = null;
|
||||
private boolean trace = false;
|
||||
private TypeContext tempContext = new TypeContext();
|
||||
|
||||
private static final String TRACE_INDENT = " ";
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public ContextStack (BatchEnvironment env) {
|
||||
this.env = env;
|
||||
env.contextStack = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if env.nerrors > 0.
|
||||
*/
|
||||
public boolean anyErrors () {
|
||||
return env.nerrors > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable/disable tracing.
|
||||
*/
|
||||
public void setTrace(boolean trace) {
|
||||
this.trace = trace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check trace flag.
|
||||
*/
|
||||
public boolean isTraceOn() {
|
||||
return trace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the environment.
|
||||
*/
|
||||
public BatchEnvironment getEnv() {
|
||||
return env;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the new context.
|
||||
*/
|
||||
public void setNewContextCode(int code) {
|
||||
newCode = code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current context code.
|
||||
*/
|
||||
public int getCurrentContextCode() {
|
||||
return newCode;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If tracing on, write the current call stack (not the context stack) to
|
||||
* System.out.
|
||||
*/
|
||||
final void traceCallStack () {
|
||||
if (trace) dumpCallStack();
|
||||
}
|
||||
|
||||
public final static void dumpCallStack() {
|
||||
new Error().printStackTrace(System.out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a line indented by stack depth.
|
||||
*/
|
||||
final private void tracePrint (String text, boolean line) {
|
||||
int length = text.length() + (currentIndex * TRACE_INDENT.length());
|
||||
StringBuffer buffer = new StringBuffer(length);
|
||||
for (int i = 0; i < currentIndex; i++) {
|
||||
buffer.append(TRACE_INDENT);
|
||||
}
|
||||
buffer.append(text);
|
||||
if (line) {
|
||||
buffer.append("\n");
|
||||
}
|
||||
System.out.print(buffer.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* If tracing on, print a line.
|
||||
*/
|
||||
final void trace (String text) {
|
||||
if (trace) {
|
||||
tracePrint(text,false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If tracing on, print a line followed by a '\n'.
|
||||
*/
|
||||
final void traceln (String text) {
|
||||
if (trace) {
|
||||
tracePrint(text,true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If tracing on, print a pre-mapped ContextElement.
|
||||
*/
|
||||
final void traceExistingType (Type type) {
|
||||
if (trace) {
|
||||
tempContext.set(newCode,type);
|
||||
traceln(toResultString(tempContext,true,true));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Push a new element on the stack.
|
||||
* @return the new element.
|
||||
*/
|
||||
public TypeContext push (ContextElement element) {
|
||||
|
||||
currentIndex++;
|
||||
|
||||
// Grow array if need to...
|
||||
|
||||
if (currentIndex == maxIndex) {
|
||||
int newMax = maxIndex * 2;
|
||||
TypeContext[] newStack = new TypeContext[newMax];
|
||||
System.arraycopy(stack,0,newStack,0,maxIndex);
|
||||
maxIndex = newMax;
|
||||
stack = newStack;
|
||||
}
|
||||
|
||||
// Make sure we have a context object to use at this position...
|
||||
|
||||
TypeContext it = stack[currentIndex];
|
||||
|
||||
if (it == null) {
|
||||
it = new TypeContext();
|
||||
stack[currentIndex] = it;
|
||||
}
|
||||
|
||||
// Set the context object...
|
||||
|
||||
it.set(newCode,element);
|
||||
|
||||
// Trace...
|
||||
|
||||
traceln(toTrialString(it));
|
||||
|
||||
// Return...
|
||||
|
||||
return it;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pop an element from the stack.
|
||||
* @return the new current element or null if top.
|
||||
*/
|
||||
public TypeContext pop (boolean wasValid) {
|
||||
|
||||
if (currentIndex < 0) {
|
||||
throw new CompilerError("Nothing on stack!");
|
||||
}
|
||||
|
||||
newCode = stack[currentIndex].getCode();
|
||||
traceln(toResultString(stack[currentIndex],wasValid,false));
|
||||
|
||||
Type last = stack[currentIndex].getCandidateType();
|
||||
if (last != null) {
|
||||
|
||||
// Set status...
|
||||
|
||||
if (wasValid) {
|
||||
last.setStatus(Constants.STATUS_VALID);
|
||||
} else {
|
||||
last.setStatus(Constants.STATUS_INVALID);
|
||||
}
|
||||
}
|
||||
|
||||
currentIndex--;
|
||||
|
||||
if (currentIndex < 0) {
|
||||
|
||||
// Done parsing, so update the invalid types
|
||||
// if this type was valid...
|
||||
|
||||
if (wasValid) {
|
||||
Type.updateAllInvalidTypes(this);
|
||||
}
|
||||
return null;
|
||||
} else {
|
||||
return stack[currentIndex];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current size.
|
||||
*/
|
||||
public int size () {
|
||||
return currentIndex + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a specific context.
|
||||
*/
|
||||
public TypeContext getContext (int index) {
|
||||
|
||||
if (currentIndex < index) {
|
||||
throw new Error("Index out of range");
|
||||
}
|
||||
return stack[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current top context.
|
||||
*/
|
||||
public TypeContext getContext () {
|
||||
|
||||
if (currentIndex < 0) {
|
||||
throw new Error("Nothing on stack!");
|
||||
}
|
||||
return stack[currentIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Is parent context a value type?
|
||||
*/
|
||||
public boolean isParentAValue () {
|
||||
|
||||
if (currentIndex > 0) {
|
||||
return stack[currentIndex - 1].isValue();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get parent context. Null if none.
|
||||
*/
|
||||
public TypeContext getParentContext () {
|
||||
|
||||
if (currentIndex > 0) {
|
||||
return stack[currentIndex - 1];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a string for the context name...
|
||||
*/
|
||||
public String getContextCodeString () {
|
||||
|
||||
if (currentIndex >= 0) {
|
||||
return CODE_NAMES[newCode];
|
||||
} else {
|
||||
return CODE_NAMES[0];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a string for the given context code...
|
||||
*/
|
||||
public static String getContextCodeString (int contextCode) {
|
||||
return CODE_NAMES[contextCode];
|
||||
}
|
||||
|
||||
private String toTrialString(TypeContext it) {
|
||||
int code = it.getCode();
|
||||
if (code != METHOD && code != MEMBER) {
|
||||
return it.toString() + " (trying " + it.getTypeDescription() + ")";
|
||||
} else {
|
||||
return it.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private String toResultString (TypeContext it, boolean result, boolean preExisting) {
|
||||
int code = it.getCode();
|
||||
if (code != METHOD && code != MEMBER) {
|
||||
if (result) {
|
||||
String str = it.toString() + " --> " + it.getTypeDescription();
|
||||
if (preExisting) {
|
||||
return str + " [Previously mapped]";
|
||||
} else {
|
||||
return str;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (result) {
|
||||
return it.toString() + " --> [Mapped]";
|
||||
}
|
||||
}
|
||||
return it.toString() + " [Did not map]";
|
||||
}
|
||||
|
||||
public void clear () {
|
||||
for (int i = 0; i < stack.length; i++) {
|
||||
if (stack[i] != null) stack[i].destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class TypeContext {
|
||||
|
||||
public void set(int code, ContextElement element) {
|
||||
this.code = code;
|
||||
this.element = element;
|
||||
if (element instanceof ValueType) {
|
||||
isValue = true;
|
||||
} else {
|
||||
isValue = false;
|
||||
}
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return element.getElementName();
|
||||
}
|
||||
|
||||
public Type getCandidateType() {
|
||||
if (element instanceof Type) {
|
||||
return (Type) element;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String getTypeDescription() {
|
||||
if (element instanceof Type) {
|
||||
return ((Type) element).getTypeDescription();
|
||||
} else {
|
||||
return "[unknown type]";
|
||||
}
|
||||
}
|
||||
|
||||
public String toString () {
|
||||
if (element != null) {
|
||||
return ContextStack.getContextCodeString(code) + element.getElementName();
|
||||
} else {
|
||||
return ContextStack.getContextCodeString(code) + "null";
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isValue () {
|
||||
return isValue;
|
||||
}
|
||||
|
||||
public boolean isConstant () {
|
||||
return code == ContextStack.MEMBER_CONSTANT;
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
if (element instanceof Type) {
|
||||
((Type)element).destroy();
|
||||
}
|
||||
element = null;
|
||||
}
|
||||
|
||||
private int code = 0;
|
||||
private ContextElement element = null;
|
||||
private boolean isValue = false;
|
||||
}
|
||||
160
jdkSrc/jdk8/sun/rmi/rmic/iiop/DirectoryLoader.java
Normal file
160
jdkSrc/jdk8/sun/rmi/rmic/iiop/DirectoryLoader.java
Normal file
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Licensed Materials - Property of IBM
|
||||
* RMI-IIOP v1.0
|
||||
* Copyright IBM Corp. 1998 1999 All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
package sun.rmi.rmic.iiop;
|
||||
|
||||
import java.util.Hashtable;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
|
||||
/**
|
||||
* DirectoryLoader is a simple ClassLoader which loads from a specified
|
||||
* file system directory.
|
||||
* @author Bryan Atsatt
|
||||
*/
|
||||
|
||||
public class DirectoryLoader extends ClassLoader {
|
||||
|
||||
private Hashtable cache;
|
||||
private File root;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public DirectoryLoader (File rootDir) {
|
||||
cache = new Hashtable();
|
||||
if (rootDir == null || !rootDir.isDirectory()) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
root = rootDir;
|
||||
}
|
||||
|
||||
private DirectoryLoader () {}
|
||||
|
||||
/**
|
||||
* Convenience version of loadClass which sets 'resolve' == true.
|
||||
*/
|
||||
public Class loadClass(String className) throws ClassNotFoundException {
|
||||
return loadClass(className, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the required version of loadClass which is called
|
||||
* both from loadClass above and from the internal function
|
||||
* FindClassFromClass.
|
||||
*/
|
||||
public synchronized Class loadClass(String className, boolean resolve)
|
||||
throws ClassNotFoundException {
|
||||
Class result;
|
||||
byte classData[];
|
||||
|
||||
// Do we already have it in the cache?
|
||||
|
||||
result = (Class) cache.get(className);
|
||||
|
||||
if (result == null) {
|
||||
|
||||
// Nope, can we get if from the system class loader?
|
||||
|
||||
try {
|
||||
|
||||
result = super.findSystemClass(className);
|
||||
|
||||
} catch (ClassNotFoundException e) {
|
||||
|
||||
// No, so try loading it...
|
||||
|
||||
classData = getClassFileData(className);
|
||||
|
||||
if (classData == null) {
|
||||
throw new ClassNotFoundException();
|
||||
}
|
||||
|
||||
// Parse the class file data...
|
||||
|
||||
result = defineClass(classData, 0, classData.length);
|
||||
|
||||
if (result == null) {
|
||||
throw new ClassFormatError();
|
||||
}
|
||||
|
||||
// Resolve it...
|
||||
|
||||
if (resolve) resolveClass(result);
|
||||
|
||||
// Add to cache...
|
||||
|
||||
cache.put(className, result);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reurn a byte array containing the contents of the class file. Returns null
|
||||
* if an exception occurs.
|
||||
*/
|
||||
private byte[] getClassFileData (String className) {
|
||||
|
||||
byte result[] = null;
|
||||
FileInputStream stream = null;
|
||||
|
||||
// Get the file...
|
||||
|
||||
File classFile = new File(root,className.replace('.',File.separatorChar) + ".class");
|
||||
|
||||
// Now get the bits...
|
||||
|
||||
try {
|
||||
stream = new FileInputStream(classFile);
|
||||
result = new byte[stream.available()];
|
||||
stream.read(result);
|
||||
} catch(ThreadDeath death) {
|
||||
throw death;
|
||||
} catch (Throwable e) {
|
||||
}
|
||||
|
||||
finally {
|
||||
if (stream != null) {
|
||||
try {
|
||||
stream.close();
|
||||
} catch(ThreadDeath death) {
|
||||
throw death;
|
||||
} catch (Throwable e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
436
jdkSrc/jdk8/sun/rmi/rmic/iiop/Generator.java
Normal file
436
jdkSrc/jdk8/sun/rmi/rmic/iiop/Generator.java
Normal file
@@ -0,0 +1,436 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Licensed Materials - Property of IBM
|
||||
* RMI-IIOP v1.0
|
||||
* Copyright IBM Corp. 1998 1999 All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
package sun.rmi.rmic.iiop;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.IOException;
|
||||
import sun.tools.java.Identifier;
|
||||
import sun.tools.java.ClassPath;
|
||||
import sun.tools.java.ClassFile;
|
||||
import sun.tools.java.ClassNotFound;
|
||||
import sun.tools.java.ClassDefinition;
|
||||
import sun.tools.java.ClassDeclaration;
|
||||
import sun.rmi.rmic.IndentingWriter;
|
||||
import sun.rmi.rmic.Main;
|
||||
import sun.rmi.rmic.iiop.Util;
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* Generator provides a small framework from which IIOP-specific
|
||||
* generators can inherit. Common logic is implemented here which uses
|
||||
* both abstract methods as well as concrete methods which subclasses may
|
||||
* want to override. The following methods must be present in any subclass:
|
||||
* <pre>
|
||||
* Default constructor
|
||||
* CompoundType getTopType(BatchEnvironment env, ClassDefinition cdef);
|
||||
* int parseArgs(String argv[], int currentIndex);
|
||||
* boolean requireNewInstance();
|
||||
* OutputType[] getOutputTypesFor(CompoundType topType,
|
||||
* HashSet alreadyChecked);
|
||||
* String getFileNameExtensionFor(OutputType outputType);
|
||||
* void writeOutputFor ( OutputType outputType,
|
||||
* HashSet alreadyChecked,
|
||||
* IndentingWriter writer) throws IOException;
|
||||
* </pre>
|
||||
* @author Bryan Atsatt
|
||||
*/
|
||||
public abstract class Generator implements sun.rmi.rmic.Generator,
|
||||
sun.rmi.rmic.iiop.Constants {
|
||||
|
||||
protected boolean alwaysGenerate = false;
|
||||
protected BatchEnvironment env = null;
|
||||
protected ContextStack contextStack = null;
|
||||
private boolean trace = false;
|
||||
protected boolean idl = false;
|
||||
|
||||
/**
|
||||
* Examine and consume command line arguments.
|
||||
* @param argv The command line arguments. Ignore null
|
||||
* and unknown arguments. Set each consumed argument to null.
|
||||
* @param error Report any errors using the main.error() methods.
|
||||
* @return true if no errors, false otherwise.
|
||||
*/
|
||||
public boolean parseArgs(String argv[], Main main) {
|
||||
for (int i = 0; i < argv.length; i++) {
|
||||
if (argv[i] != null) {
|
||||
if (argv[i].equalsIgnoreCase("-always") ||
|
||||
argv[i].equalsIgnoreCase("-alwaysGenerate")) {
|
||||
alwaysGenerate = true;
|
||||
argv[i] = null;
|
||||
} else if (argv[i].equalsIgnoreCase("-xtrace")) {
|
||||
trace = true;
|
||||
argv[i] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if non-conforming types should be parsed.
|
||||
* @param stack The context stack.
|
||||
*/
|
||||
protected abstract boolean parseNonConforming(ContextStack stack);
|
||||
|
||||
/**
|
||||
* Create and return a top-level type.
|
||||
* @param cdef The top-level class definition.
|
||||
* @param stack The context stack.
|
||||
* @return The compound type or null if is non-conforming.
|
||||
*/
|
||||
protected abstract CompoundType getTopType(ClassDefinition cdef, ContextStack stack);
|
||||
|
||||
/**
|
||||
* Return an array containing all the file names and types that need to be
|
||||
* generated for the given top-level type. The file names must NOT have an
|
||||
* extension (e.g. ".java").
|
||||
* @param topType The type returned by getTopType().
|
||||
* @param alreadyChecked A set of Types which have already been checked.
|
||||
* Intended to be passed to Type.collectMatching(filter,alreadyChecked).
|
||||
*/
|
||||
protected abstract OutputType[] getOutputTypesFor(CompoundType topType,
|
||||
HashSet alreadyChecked);
|
||||
|
||||
/**
|
||||
* Return the file name extension for the given file name (e.g. ".java").
|
||||
* All files generated with the ".java" extension will be compiled. To
|
||||
* change this behavior for ".java" files, override the compileJavaSourceFile
|
||||
* method to return false.
|
||||
* @param outputType One of the items returned by getOutputTypesFor(...)
|
||||
*/
|
||||
protected abstract String getFileNameExtensionFor(OutputType outputType);
|
||||
|
||||
/**
|
||||
* Write the output for the given OutputFileName into the output stream.
|
||||
* @param name One of the items returned by getOutputTypesFor(...)
|
||||
* @param alreadyChecked A set of Types which have already been checked.
|
||||
* Intended to be passed to Type.collectMatching(filter,alreadyChecked).
|
||||
* @param writer The output stream.
|
||||
*/
|
||||
protected abstract void writeOutputFor(OutputType outputType,
|
||||
HashSet alreadyChecked,
|
||||
IndentingWriter writer) throws IOException;
|
||||
|
||||
/**
|
||||
* Return true if a new instance should be created for each
|
||||
* class on the command line. Subclasses which return true
|
||||
* should override newInstance() to return an appropriately
|
||||
* constructed instance.
|
||||
*/
|
||||
protected abstract boolean requireNewInstance();
|
||||
|
||||
/**
|
||||
* Return true if the specified file needs generation.
|
||||
*/
|
||||
public boolean requiresGeneration (File target, Type theType) {
|
||||
|
||||
boolean result = alwaysGenerate;
|
||||
|
||||
if (!result) {
|
||||
|
||||
// Get a ClassFile instance for base source or class
|
||||
// file. We use ClassFile so that if the base is in
|
||||
// a zip file, we can still get at it's mod time...
|
||||
|
||||
ClassFile baseFile;
|
||||
ClassPath path = env.getClassPath();
|
||||
String className = theType.getQualifiedName().replace('.',File.separatorChar);
|
||||
|
||||
// First try the source file...
|
||||
|
||||
baseFile = path.getFile(className + ".source");
|
||||
|
||||
if (baseFile == null) {
|
||||
|
||||
// Then try class file...
|
||||
|
||||
baseFile = path.getFile(className + ".class");
|
||||
}
|
||||
|
||||
// Do we have a baseFile?
|
||||
|
||||
if (baseFile != null) {
|
||||
|
||||
// Yes, grab baseFile's mod time...
|
||||
|
||||
long baseFileMod = baseFile.lastModified();
|
||||
|
||||
// Get a File instance for the target. If it is a source
|
||||
// file, create a class file instead since the source file
|
||||
// will frequently be deleted...
|
||||
|
||||
String targetName = IDLNames.replace(target.getName(),".java",".class");
|
||||
String parentPath = target.getParent();
|
||||
File targetFile = new File(parentPath,targetName);
|
||||
|
||||
// Does the target file exist?
|
||||
|
||||
if (targetFile.exists()) {
|
||||
|
||||
// Yes, so grab it's mod time...
|
||||
|
||||
long targetFileMod = targetFile.lastModified();
|
||||
|
||||
// Set result...
|
||||
|
||||
result = targetFileMod < baseFileMod;
|
||||
|
||||
} else {
|
||||
|
||||
// No, so we must generate...
|
||||
|
||||
result = true;
|
||||
}
|
||||
} else {
|
||||
|
||||
// No, so we must generate...
|
||||
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and return a new instance of self. Subclasses
|
||||
* which need to do something other than default construction
|
||||
* must override this method.
|
||||
*/
|
||||
protected Generator newInstance() {
|
||||
Generator result = null;
|
||||
try {
|
||||
result = (Generator) getClass().newInstance();
|
||||
}
|
||||
catch (Exception e){} // Should ALWAYS work!
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default constructor for subclasses to use.
|
||||
*/
|
||||
protected Generator() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate output. Any source files created which need compilation should
|
||||
* be added to the compiler environment using the addGeneratedFile(File)
|
||||
* method.
|
||||
*
|
||||
* @param env The compiler environment
|
||||
* @param cdef The definition for the implementation class or interface from
|
||||
* which to generate output
|
||||
* @param destDir The directory for the root of the package hierarchy
|
||||
* for generated files. May be null.
|
||||
*/
|
||||
public void generate(sun.rmi.rmic.BatchEnvironment env, ClassDefinition cdef, File destDir) {
|
||||
|
||||
this.env = (BatchEnvironment) env;
|
||||
contextStack = new ContextStack(this.env);
|
||||
contextStack.setTrace(trace);
|
||||
|
||||
// Make sure the environment knows whether or not to parse
|
||||
// non-conforming types. This will clear out any previously
|
||||
// parsed types if necessary...
|
||||
|
||||
this.env.setParseNonConforming(parseNonConforming(contextStack));
|
||||
|
||||
// Get our top level type...
|
||||
|
||||
CompoundType topType = getTopType(cdef,contextStack);
|
||||
if (topType != null) {
|
||||
|
||||
Generator generator = this;
|
||||
|
||||
// Do we need to make a new instance?
|
||||
|
||||
if (requireNewInstance()) {
|
||||
|
||||
// Yes, so make one. 'this' instance is the one instantiated by Main
|
||||
// and which knows any needed command line args...
|
||||
|
||||
generator = newInstance();
|
||||
}
|
||||
|
||||
// Now generate all output files...
|
||||
|
||||
generator.generateOutputFiles(topType, this.env, destDir);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and return a new instance of self. Subclasses
|
||||
* which need to do something other than default construction
|
||||
* must override this method.
|
||||
*/
|
||||
protected void generateOutputFiles (CompoundType topType,
|
||||
BatchEnvironment env,
|
||||
File destDir) {
|
||||
|
||||
// Grab the 'alreadyChecked' HashSet from the environment...
|
||||
|
||||
HashSet alreadyChecked = env.alreadyChecked;
|
||||
|
||||
// Ask subclass for a list of output types...
|
||||
|
||||
OutputType[] types = getOutputTypesFor(topType,alreadyChecked);
|
||||
|
||||
// Process each file...
|
||||
|
||||
for (int i = 0; i < types.length; i++) {
|
||||
OutputType current = types[i];
|
||||
String className = current.getName();
|
||||
File file = getFileFor(current,destDir);
|
||||
boolean sourceFile = false;
|
||||
|
||||
// Do we need to generate this file?
|
||||
|
||||
if (requiresGeneration(file,current.getType())) {
|
||||
|
||||
// Yes. If java source file, add to environment so will be compiled...
|
||||
|
||||
if (file.getName().endsWith(".java")) {
|
||||
sourceFile = compileJavaSourceFile(current);
|
||||
|
||||
// Are we supposeded to compile this one?
|
||||
|
||||
if (sourceFile) {
|
||||
env.addGeneratedFile(file);
|
||||
}
|
||||
}
|
||||
|
||||
// Now create an output stream and ask subclass to fill it up...
|
||||
|
||||
try {
|
||||
IndentingWriter out = new IndentingWriter(
|
||||
new OutputStreamWriter(new FileOutputStream(file)),INDENT_STEP,TAB_SIZE);
|
||||
|
||||
long startTime = 0;
|
||||
if (env.verbose()) {
|
||||
startTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
writeOutputFor(types[i],alreadyChecked,out);
|
||||
out.close();
|
||||
|
||||
if (env.verbose()) {
|
||||
long duration = System.currentTimeMillis() - startTime;
|
||||
env.output(Main.getText("rmic.generated", file.getPath(), Long.toString(duration)));
|
||||
}
|
||||
if (sourceFile) {
|
||||
env.parseFile(new ClassFile(file));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
env.error(0, "cant.write", file.toString());
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
|
||||
// No, say so if we need to...
|
||||
|
||||
if (env.verbose()) {
|
||||
env.output(Main.getText("rmic.previously.generated", file.getPath()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the File object that should be used as the output file
|
||||
* for the given OutputType.
|
||||
* @param outputType The type to create a file for.
|
||||
* @param destinationDir The directory to use as the root of the
|
||||
* package heirarchy. May be null, in which case the current
|
||||
* classpath is searched to find the directory in which to create
|
||||
* the output file. If that search fails (most likely because the
|
||||
* package directory lives in a zip or jar file rather than the
|
||||
* file system), the current user directory is used.
|
||||
*/
|
||||
protected File getFileFor(OutputType outputType, File destinationDir) {
|
||||
// Calling this method does some crucial initialization
|
||||
// in a subclass implementation. Don't skip it.
|
||||
Identifier id = getOutputId(outputType);
|
||||
File packageDir = null;
|
||||
if(idl){
|
||||
packageDir = Util.getOutputDirectoryForIDL(id,destinationDir,env);
|
||||
} else {
|
||||
packageDir = Util.getOutputDirectoryForStub(id,destinationDir,env);
|
||||
}
|
||||
String classFileName = outputType.getName() + getFileNameExtensionFor(outputType);
|
||||
return new File(packageDir, classFileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an identifier to use for output.
|
||||
* @param outputType the type for which output is to be generated.
|
||||
* @return the new identifier. This implementation returns the input parameter.
|
||||
*/
|
||||
protected Identifier getOutputId (OutputType outputType) {
|
||||
return outputType.getType().getIdentifier();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the given file should be compiled.
|
||||
* @param outputType One of the items returned by getOutputTypesFor(...) for
|
||||
* which getFileNameExtensionFor(OutputType) returned ".java".
|
||||
*/
|
||||
protected boolean compileJavaSourceFile (OutputType outputType) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//_____________________________________________________________________
|
||||
// OutputType is a simple wrapper for a name and a Type
|
||||
//_____________________________________________________________________
|
||||
|
||||
public class OutputType {
|
||||
private String name;
|
||||
private Type type;
|
||||
|
||||
public OutputType (String name, Type type) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
}
|
||||
2084
jdkSrc/jdk8/sun/rmi/rmic/iiop/IDLGenerator.java
Normal file
2084
jdkSrc/jdk8/sun/rmi/rmic/iiop/IDLGenerator.java
Normal file
File diff suppressed because it is too large
Load Diff
1227
jdkSrc/jdk8/sun/rmi/rmic/iiop/IDLNames.java
Normal file
1227
jdkSrc/jdk8/sun/rmi/rmic/iiop/IDLNames.java
Normal file
File diff suppressed because it is too large
Load Diff
292
jdkSrc/jdk8/sun/rmi/rmic/iiop/ImplementationType.java
Normal file
292
jdkSrc/jdk8/sun/rmi/rmic/iiop/ImplementationType.java
Normal file
@@ -0,0 +1,292 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Licensed Materials - Property of IBM
|
||||
* RMI-IIOP v1.0
|
||||
* Copyright IBM Corp. 1998 1999 All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
package sun.rmi.rmic.iiop;
|
||||
|
||||
import java.util.Vector;
|
||||
import sun.tools.java.CompilerError;
|
||||
import sun.tools.java.ClassNotFound;
|
||||
import sun.tools.java.ClassDefinition;
|
||||
import sun.tools.java.MemberDefinition;
|
||||
|
||||
/**
|
||||
* ImplementationType represents any non-special class which implements
|
||||
* one or more interfaces which inherit from java.rmi.Remote.
|
||||
* <p>
|
||||
* The static forImplementation(...) method must be used to obtain an instance,
|
||||
* and will return null if the ClassDefinition is non-conforming.
|
||||
*
|
||||
* @author Bryan Atsatt
|
||||
*/
|
||||
public class ImplementationType extends ClassType {
|
||||
|
||||
//_____________________________________________________________________
|
||||
// Public Interfaces
|
||||
//_____________________________________________________________________
|
||||
|
||||
/**
|
||||
* Create an ImplementationType for the given class.
|
||||
*
|
||||
* If the class is not a properly formed or if some other error occurs, the
|
||||
* return value will be null, and errors will have been reported to the
|
||||
* supplied BatchEnvironment.
|
||||
*/
|
||||
public static ImplementationType forImplementation(ClassDefinition classDef,
|
||||
ContextStack stack,
|
||||
boolean quiet) {
|
||||
if (stack.anyErrors()) return null;
|
||||
|
||||
boolean doPop = false;
|
||||
ImplementationType result = null;
|
||||
|
||||
try {
|
||||
// Do we already have it?
|
||||
|
||||
sun.tools.java.Type theType = classDef.getType();
|
||||
Type existing = getType(theType,stack);
|
||||
|
||||
if (existing != null) {
|
||||
|
||||
if (!(existing instanceof ImplementationType)) return null; // False hit.
|
||||
|
||||
// Yep, so return it...
|
||||
|
||||
return (ImplementationType) existing;
|
||||
|
||||
}
|
||||
|
||||
// Could this be an implementation?
|
||||
|
||||
if (couldBeImplementation(quiet,stack,classDef)) {
|
||||
|
||||
// Yes, so check it...
|
||||
|
||||
ImplementationType it = new ImplementationType(stack, classDef);
|
||||
putType(theType,it,stack);
|
||||
stack.push(it);
|
||||
doPop = true;
|
||||
|
||||
if (it.initialize(stack,quiet)) {
|
||||
stack.pop(true);
|
||||
result = it;
|
||||
} else {
|
||||
removeType(theType,stack);
|
||||
stack.pop(false);
|
||||
}
|
||||
}
|
||||
} catch (CompilerError e) {
|
||||
if (doPop) stack.pop(false);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string describing this type.
|
||||
*/
|
||||
public String getTypeDescription () {
|
||||
return "Implementation";
|
||||
}
|
||||
|
||||
|
||||
//_____________________________________________________________________
|
||||
// Internal Interfaces
|
||||
//_____________________________________________________________________
|
||||
|
||||
/**
|
||||
* Create a ImplementationType instance for the given class. The resulting
|
||||
* object is not yet completely initialized.
|
||||
*/
|
||||
private ImplementationType(ContextStack stack, ClassDefinition classDef) {
|
||||
super(TYPE_IMPLEMENTATION | TM_CLASS | TM_COMPOUND,classDef,stack); // Use special constructor.
|
||||
}
|
||||
|
||||
|
||||
private static boolean couldBeImplementation(boolean quiet, ContextStack stack,
|
||||
ClassDefinition classDef) {
|
||||
boolean result = false;
|
||||
BatchEnvironment env = stack.getEnv();
|
||||
|
||||
try {
|
||||
if (!classDef.isClass()) {
|
||||
failedConstraint(17,quiet,stack,classDef.getName());
|
||||
} else {
|
||||
result = env.defRemote.implementedBy(env, classDef.getClassDeclaration());
|
||||
if (!result) failedConstraint(8,quiet,stack,classDef.getName());
|
||||
}
|
||||
} catch (ClassNotFound e) {
|
||||
classNotFound(stack,e);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize this instance.
|
||||
*/
|
||||
private boolean initialize (ContextStack stack, boolean quiet) {
|
||||
|
||||
boolean result = false;
|
||||
ClassDefinition theClass = getClassDefinition();
|
||||
|
||||
if (initParents(stack)) {
|
||||
|
||||
// Make up our collections...
|
||||
|
||||
Vector directInterfaces = new Vector();
|
||||
Vector directMethods = new Vector();
|
||||
|
||||
// Check interfaces...
|
||||
|
||||
try {
|
||||
if (addRemoteInterfaces(directInterfaces,true,stack) != null) {
|
||||
|
||||
boolean haveRemote = false;
|
||||
|
||||
// Get methods from all interfaces...
|
||||
|
||||
for (int i = 0; i < directInterfaces.size(); i++) {
|
||||
InterfaceType theInt = (InterfaceType) directInterfaces.elementAt(i);
|
||||
if (theInt.isType(TYPE_REMOTE) ||
|
||||
theInt.isType(TYPE_JAVA_RMI_REMOTE)) {
|
||||
haveRemote = true;
|
||||
}
|
||||
|
||||
copyRemoteMethods(theInt,directMethods);
|
||||
}
|
||||
|
||||
// Make sure we have at least one remote interface...
|
||||
|
||||
if (!haveRemote) {
|
||||
failedConstraint(8,quiet,stack,getQualifiedName());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now check the methods to ensure we have the
|
||||
// correct throws clauses...
|
||||
|
||||
if (checkMethods(theClass,directMethods,stack,quiet)) {
|
||||
|
||||
// We're ok, so pass 'em up...
|
||||
|
||||
result = initialize(directInterfaces,directMethods,null,stack,quiet);
|
||||
}
|
||||
}
|
||||
} catch (ClassNotFound e) {
|
||||
classNotFound(stack,e);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void copyRemoteMethods(InterfaceType type, Vector list) {
|
||||
|
||||
if (type.isType(TYPE_REMOTE)) {
|
||||
|
||||
// Copy all the unique methods from type...
|
||||
|
||||
Method[] allMethods = type.getMethods();
|
||||
|
||||
for (int i = 0; i < allMethods.length; i++) {
|
||||
Method theMethod = allMethods[i];
|
||||
|
||||
if (!list.contains(theMethod)) {
|
||||
list.addElement(theMethod);
|
||||
}
|
||||
}
|
||||
|
||||
// Now recurse thru all inherited interfaces...
|
||||
|
||||
InterfaceType[] allInterfaces = type.getInterfaces();
|
||||
|
||||
for (int i = 0; i < allInterfaces.length; i++) {
|
||||
copyRemoteMethods(allInterfaces[i],list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Walk all methods of the class, and for each that is already in
|
||||
// the list, call setImplExceptions()...
|
||||
|
||||
private boolean checkMethods(ClassDefinition theClass, Vector list,
|
||||
ContextStack stack, boolean quiet) {
|
||||
|
||||
// Convert vector to array...
|
||||
|
||||
Method[] methods = new Method[list.size()];
|
||||
list.copyInto(methods);
|
||||
|
||||
for (MemberDefinition member = theClass.getFirstMember();
|
||||
member != null;
|
||||
member = member.getNextMember()) {
|
||||
|
||||
if (member.isMethod() && !member.isConstructor()
|
||||
&& !member.isInitializer()) {
|
||||
|
||||
// It's a method...
|
||||
|
||||
if (!updateExceptions(member,methods,stack,quiet)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean updateExceptions (MemberDefinition implMethod, Method[] list,
|
||||
ContextStack stack, boolean quiet) {
|
||||
int length = list.length;
|
||||
String implMethodSig = implMethod.toString();
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
Method existingMethod = list[i];
|
||||
MemberDefinition existing = existingMethod.getMemberDefinition();
|
||||
|
||||
// Do we have a matching method?
|
||||
|
||||
if (implMethodSig.equals(existing.toString())) {
|
||||
|
||||
// Yes, so create exception list...
|
||||
|
||||
try {
|
||||
ValueType[] implExcept = getMethodExceptions(implMethod,quiet,stack);
|
||||
existingMethod.setImplExceptions(implExcept);
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
122
jdkSrc/jdk8/sun/rmi/rmic/iiop/InterfaceType.java
Normal file
122
jdkSrc/jdk8/sun/rmi/rmic/iiop/InterfaceType.java
Normal file
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Licensed Materials - Property of IBM
|
||||
* RMI-IIOP v1.0
|
||||
* Copyright IBM Corp. 1998 1999 All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
package sun.rmi.rmic.iiop;
|
||||
|
||||
import java.io.IOException;
|
||||
import sun.tools.java.CompilerError;
|
||||
import sun.tools.java.ClassDefinition;
|
||||
import sun.rmi.rmic.IndentingWriter;
|
||||
|
||||
/**
|
||||
* InterfaceType is an abstract base representing any non-special
|
||||
* interface type.
|
||||
*
|
||||
* @author Bryan Atsatt
|
||||
*/
|
||||
public abstract class InterfaceType extends CompoundType {
|
||||
|
||||
//_____________________________________________________________________
|
||||
// Public Interfaces
|
||||
//_____________________________________________________________________
|
||||
|
||||
/**
|
||||
* Print this type.
|
||||
* @param writer The stream to print to.
|
||||
* @param useQualifiedNames If true, print qualified names; otherwise, print unqualified names.
|
||||
* @param useIDLNames If true, print IDL names; otherwise, print java names.
|
||||
* @param globalIDLNames If true and useIDLNames true, prepends "::".
|
||||
*/
|
||||
public void print ( IndentingWriter writer,
|
||||
boolean useQualifiedNames,
|
||||
boolean useIDLNames,
|
||||
boolean globalIDLNames) throws IOException {
|
||||
|
||||
if (isInner()) {
|
||||
writer.p("// " + getTypeDescription() + " (INNER)");
|
||||
} else {
|
||||
writer.p("// " + getTypeDescription() + "");
|
||||
}
|
||||
writer.pln(" (" + getRepositoryID() + ")\n");
|
||||
printPackageOpen(writer,useIDLNames);
|
||||
|
||||
if (!useIDLNames) {
|
||||
writer.p("public ");
|
||||
}
|
||||
|
||||
writer.p("interface " + getTypeName(false,useIDLNames,false));
|
||||
printImplements(writer,"",useQualifiedNames,useIDLNames,globalIDLNames);
|
||||
writer.plnI(" {");
|
||||
printMembers(writer,useQualifiedNames,useIDLNames,globalIDLNames);
|
||||
writer.pln();
|
||||
printMethods(writer,useQualifiedNames,useIDLNames,globalIDLNames);
|
||||
writer.pln();
|
||||
|
||||
if (useIDLNames) {
|
||||
writer.pOln("};");
|
||||
} else {
|
||||
writer.pOln("}");
|
||||
}
|
||||
printPackageClose(writer,useIDLNames);
|
||||
}
|
||||
|
||||
//_____________________________________________________________________
|
||||
// Subclass/Internal Interfaces
|
||||
//_____________________________________________________________________
|
||||
|
||||
/**
|
||||
* Create a InterfaceType instance for the given class. NOTE: This constructor
|
||||
* is ONLY for SpecialInterfaceType.
|
||||
*/
|
||||
protected InterfaceType(ContextStack stack, int typeCode, ClassDefinition classDef) {
|
||||
super(stack,typeCode,classDef); // Call special parent constructor.
|
||||
|
||||
if ((typeCode & TM_INTERFACE) == 0 || ! classDef.isInterface()) {
|
||||
throw new CompilerError("Not an interface");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a InterfaceType instance for the given class. The resulting
|
||||
* object is not yet completely initialized. Subclasses must call
|
||||
* initialize(directInterfaces,directInterfaces,directConstants);
|
||||
*/
|
||||
protected InterfaceType(ContextStack stack,
|
||||
ClassDefinition classDef,
|
||||
int typeCode) {
|
||||
super(stack,classDef,typeCode);
|
||||
|
||||
if ((typeCode & TM_INTERFACE) == 0 || ! classDef.isInterface()) {
|
||||
throw new CompilerError("Not an interface");
|
||||
}
|
||||
}
|
||||
}
|
||||
172
jdkSrc/jdk8/sun/rmi/rmic/iiop/NCClassType.java
Normal file
172
jdkSrc/jdk8/sun/rmi/rmic/iiop/NCClassType.java
Normal file
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Licensed Materials - Property of IBM
|
||||
* RMI-IIOP v1.0
|
||||
* Copyright IBM Corp. 1998 1999 All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
package sun.rmi.rmic.iiop;
|
||||
|
||||
import java.util.Vector;
|
||||
import sun.tools.java.CompilerError;
|
||||
import sun.tools.java.ClassNotFound;
|
||||
import sun.tools.java.ClassDefinition;
|
||||
|
||||
/**
|
||||
* NCClassType represents any non-special class which does not
|
||||
* extends one or more interfaces which inherit from java.rmi.Remote.
|
||||
* <p>
|
||||
* The static forImplementation(...) method must be used to obtain an instance,
|
||||
* and will return null if the ClassDefinition is non-conforming.
|
||||
*
|
||||
* @author Bryan Atsatt
|
||||
*/
|
||||
public class NCClassType extends ClassType {
|
||||
|
||||
//_____________________________________________________________________
|
||||
// Public Interfaces
|
||||
//_____________________________________________________________________
|
||||
|
||||
/**
|
||||
* Create an NCClassType for the given class.
|
||||
*
|
||||
* If the class is not a properly formed or if some other error occurs, the
|
||||
* return value will be null, and errors will have been reported to the
|
||||
* supplied BatchEnvironment.
|
||||
*/
|
||||
public static NCClassType forNCClass(ClassDefinition classDef,
|
||||
ContextStack stack) {
|
||||
|
||||
if (stack.anyErrors()) return null;
|
||||
|
||||
boolean doPop = false;
|
||||
try {
|
||||
// Do we already have it?
|
||||
|
||||
sun.tools.java.Type theType = classDef.getType();
|
||||
Type existing = getType(theType,stack);
|
||||
|
||||
if (existing != null) {
|
||||
|
||||
if (!(existing instanceof NCClassType)) return null; // False hit.
|
||||
|
||||
// Yep, so return it...
|
||||
|
||||
return (NCClassType) existing;
|
||||
|
||||
}
|
||||
|
||||
NCClassType it = new NCClassType(stack, classDef);
|
||||
putType(theType,it,stack);
|
||||
stack.push(it);
|
||||
doPop = true;
|
||||
|
||||
if (it.initialize(stack)) {
|
||||
stack.pop(true);
|
||||
return it;
|
||||
} else {
|
||||
removeType(theType,stack);
|
||||
stack.pop(false);
|
||||
return null;
|
||||
}
|
||||
} catch (CompilerError e) {
|
||||
if (doPop) stack.pop(false);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string describing this type.
|
||||
*/
|
||||
public String getTypeDescription () {
|
||||
return addExceptionDescription("Non-conforming class");
|
||||
}
|
||||
|
||||
//_____________________________________________________________________
|
||||
// Internal/Subclass Interfaces
|
||||
//_____________________________________________________________________
|
||||
|
||||
/**
|
||||
* Create a NCClassType instance for the given class. The resulting
|
||||
* object is not yet completely initialized.
|
||||
*/
|
||||
private NCClassType(ContextStack stack, ClassDefinition classDef) {
|
||||
super(stack,classDef,TYPE_NC_CLASS | TM_CLASS | TM_COMPOUND);
|
||||
}
|
||||
|
||||
//_____________________________________________________________________
|
||||
// Internal Interfaces
|
||||
//_____________________________________________________________________
|
||||
|
||||
/**
|
||||
* Initialize this instance.
|
||||
*/
|
||||
private boolean initialize (ContextStack stack) {
|
||||
if (!initParents(stack)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stack.getEnv().getParseNonConforming()) {
|
||||
|
||||
Vector directInterfaces = new Vector();
|
||||
Vector directMethods = new Vector();
|
||||
Vector directMembers = new Vector();
|
||||
|
||||
try {
|
||||
|
||||
// Get methods...
|
||||
|
||||
if (addAllMethods(getClassDefinition(),directMethods,false,false,stack) != null) {
|
||||
|
||||
// Update parent class methods...
|
||||
|
||||
if (updateParentClassMethods(getClassDefinition(),directMethods,false,stack) != null) {
|
||||
|
||||
// Get conforming constants...
|
||||
|
||||
if (addConformingConstants(directMembers,false,stack)) {
|
||||
|
||||
// We're ok, so pass 'em up...
|
||||
|
||||
if (!initialize(directInterfaces,directMethods,directMembers,stack,false)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
} catch (ClassNotFound e) {
|
||||
classNotFound(stack,e);
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
return initialize(null,null,null,stack,false);
|
||||
}
|
||||
}
|
||||
}
|
||||
162
jdkSrc/jdk8/sun/rmi/rmic/iiop/NCInterfaceType.java
Normal file
162
jdkSrc/jdk8/sun/rmi/rmic/iiop/NCInterfaceType.java
Normal file
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Licensed Materials - Property of IBM
|
||||
* RMI-IIOP v1.0
|
||||
* Copyright IBM Corp. 1998 1999 All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
package sun.rmi.rmic.iiop;
|
||||
|
||||
import java.util.Vector;
|
||||
import sun.tools.java.CompilerError;
|
||||
import sun.tools.java.ClassNotFound;
|
||||
import sun.tools.java.ClassDefinition;
|
||||
|
||||
/**
|
||||
* NCInterfaceType represents any non-special, non-conforming interface.
|
||||
* <p>
|
||||
* The static forNCInterface(...) method must be used to obtain an instance.
|
||||
* @author Bryan Atsatt
|
||||
*/
|
||||
public class NCInterfaceType extends InterfaceType {
|
||||
|
||||
//_____________________________________________________________________
|
||||
// Public Interfaces
|
||||
//_____________________________________________________________________
|
||||
|
||||
/**
|
||||
* Create an NCInterfaceType for the given class.
|
||||
*
|
||||
* If the class is not a properly formed or if some other error occurs, the
|
||||
* return value will be null, and errors will have been reported to the
|
||||
* supplied BatchEnvironment.
|
||||
*/
|
||||
public static NCInterfaceType forNCInterface( ClassDefinition classDef,
|
||||
ContextStack stack) {
|
||||
if (stack.anyErrors()) return null;
|
||||
|
||||
boolean doPop = false;
|
||||
try {
|
||||
// Do we already have it?
|
||||
|
||||
sun.tools.java.Type theType = classDef.getType();
|
||||
Type existing = getType(theType,stack);
|
||||
|
||||
if (existing != null) {
|
||||
|
||||
if (!(existing instanceof NCInterfaceType)) return null; // False hit.
|
||||
|
||||
// Yep, so return it...
|
||||
|
||||
return (NCInterfaceType) existing;
|
||||
}
|
||||
|
||||
NCInterfaceType it = new NCInterfaceType(stack, classDef);
|
||||
putType(theType,it,stack);
|
||||
stack.push(it);
|
||||
doPop = true;
|
||||
|
||||
if (it.initialize(stack)) {
|
||||
stack.pop(true);
|
||||
return it;
|
||||
} else {
|
||||
removeType(theType,stack);
|
||||
stack.pop(false);
|
||||
return null;
|
||||
}
|
||||
} catch (CompilerError e) {
|
||||
if (doPop) stack.pop(false);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string describing this type.
|
||||
*/
|
||||
public String getTypeDescription () {
|
||||
return "Non-conforming interface";
|
||||
}
|
||||
|
||||
//_____________________________________________________________________
|
||||
// Internal/Subclass Interfaces
|
||||
//_____________________________________________________________________
|
||||
|
||||
/**
|
||||
* Create a NCInterfaceType instance for the given class. The resulting
|
||||
* object is not yet completely initialized.
|
||||
*/
|
||||
private NCInterfaceType(ContextStack stack, ClassDefinition classDef) {
|
||||
super(stack,classDef,TYPE_NC_INTERFACE | TM_INTERFACE | TM_COMPOUND);
|
||||
}
|
||||
|
||||
//_____________________________________________________________________
|
||||
// Internal Interfaces
|
||||
//_____________________________________________________________________
|
||||
|
||||
/**
|
||||
* Initialize this instance.
|
||||
*/
|
||||
private boolean initialize (ContextStack stack) {
|
||||
|
||||
if (stack.getEnv().getParseNonConforming()) {
|
||||
|
||||
Vector directInterfaces = new Vector();
|
||||
Vector directMethods = new Vector();
|
||||
Vector directMembers = new Vector();
|
||||
|
||||
try {
|
||||
|
||||
// need to include parent interfaces in IDL generation...
|
||||
addNonRemoteInterfaces( directInterfaces,stack );
|
||||
|
||||
// Get methods...
|
||||
|
||||
if (addAllMethods(getClassDefinition(),directMethods,false,false,stack) != null) {
|
||||
|
||||
// Get conforming constants...
|
||||
|
||||
if (addConformingConstants(directMembers,false,stack)) {
|
||||
|
||||
// We're ok, so pass 'em up...
|
||||
|
||||
if (!initialize(directInterfaces,directMethods,directMembers,stack,false)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
} catch (ClassNotFound e) {
|
||||
classNotFound(stack,e);
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
return initialize(null,null,null,stack,false);
|
||||
}
|
||||
}
|
||||
}
|
||||
232
jdkSrc/jdk8/sun/rmi/rmic/iiop/NameContext.java
Normal file
232
jdkSrc/jdk8/sun/rmi/rmic/iiop/NameContext.java
Normal file
@@ -0,0 +1,232 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Licensed Materials - Property of IBM
|
||||
* RMI-IIOP v1.0
|
||||
* Copyright IBM Corp. 1998 1999 All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
package sun.rmi.rmic.iiop;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
/**
|
||||
* A NameContext enables detection of strings which differ only
|
||||
* in case.
|
||||
*
|
||||
* @author Bryan Atsatt
|
||||
*/
|
||||
class NameContext {
|
||||
|
||||
private Hashtable table;
|
||||
private boolean allowCollisions;
|
||||
|
||||
/**
|
||||
* Get a context for the given name. Name may be null, in
|
||||
* which case this method will return the default context.
|
||||
*/
|
||||
public static synchronized NameContext forName (String name,
|
||||
boolean allowCollisions,
|
||||
BatchEnvironment env) {
|
||||
|
||||
NameContext result = null;
|
||||
|
||||
// Do we need to use the default context?
|
||||
|
||||
if (name == null) {
|
||||
|
||||
// Yes.
|
||||
|
||||
name = "null";
|
||||
}
|
||||
|
||||
// Have we initialized our hashtable?
|
||||
|
||||
if (env.nameContexts == null) {
|
||||
|
||||
// Nope, so do it...
|
||||
|
||||
env.nameContexts = new Hashtable();
|
||||
|
||||
} else {
|
||||
|
||||
// Yes, see if we already have the requested
|
||||
// context...
|
||||
|
||||
result = (NameContext) env.nameContexts.get(name);
|
||||
}
|
||||
|
||||
// Do we have the requested context?
|
||||
|
||||
if (result == null) {
|
||||
|
||||
// Nope, so create and add it...
|
||||
|
||||
result = new NameContext(allowCollisions);
|
||||
|
||||
env.nameContexts.put(name,result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a context.
|
||||
* @param allowCollisions true if case-sensitive name collisions
|
||||
* are allowed, false if not.
|
||||
*/
|
||||
public NameContext (boolean allowCollisions) {
|
||||
this.allowCollisions = allowCollisions;
|
||||
table = new Hashtable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a name to this context. If constructed with allowCollisions
|
||||
* false and a collision occurs, this method will throw an exception
|
||||
* in which the message contains the string: "name" and "collision".
|
||||
*/
|
||||
public void assertPut (String name) throws Exception {
|
||||
|
||||
String message = add(name);
|
||||
|
||||
if (message != null) {
|
||||
throw new Exception(message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a name to this context..
|
||||
*/
|
||||
public void put (String name) {
|
||||
|
||||
if (allowCollisions == false) {
|
||||
throw new Error("Must use assertPut(name)");
|
||||
}
|
||||
|
||||
add(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a name to this context. If constructed with allowCollisions
|
||||
* false and a collision occurs, this method will return a message
|
||||
* string, otherwise returns null.
|
||||
*/
|
||||
private String add (String name) {
|
||||
|
||||
// First, create a key by converting name to lowercase...
|
||||
|
||||
String key = name.toLowerCase();
|
||||
|
||||
// Does this key exist in the context?
|
||||
|
||||
Name value = (Name) table.get(key);
|
||||
|
||||
if (value != null) {
|
||||
|
||||
// Yes, so they match if we ignore case. Do they match if
|
||||
// we don't ignore case?
|
||||
|
||||
if (!name.equals(value.name)) {
|
||||
|
||||
// No, so this is a case-sensitive match. Are we
|
||||
// supposed to allow this?
|
||||
|
||||
if (allowCollisions) {
|
||||
|
||||
// Yes, make sure it knows that it collides...
|
||||
|
||||
value.collisions = true;
|
||||
|
||||
} else {
|
||||
|
||||
// No, so return a message string...
|
||||
|
||||
return new String("\"" + name + "\" and \"" + value.name + "\"");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
// No, so add it...
|
||||
|
||||
table.put(key,new Name(name,false));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a name from the context. If it has collisions, the name
|
||||
* will be converted as specified in section 5.2.7.
|
||||
*/
|
||||
public String get (String name) {
|
||||
|
||||
Name it = (Name) table.get(name.toLowerCase());
|
||||
String result = name;
|
||||
|
||||
// Do we need to mangle it?
|
||||
|
||||
if (it.collisions) {
|
||||
|
||||
// Yep, so do it...
|
||||
|
||||
int length = name.length();
|
||||
boolean allLower = true;
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
|
||||
if (Character.isUpperCase(name.charAt(i))) {
|
||||
result += "_";
|
||||
result += i;
|
||||
allLower = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (allLower) {
|
||||
result += "_";
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all entries.
|
||||
*/
|
||||
public void clear () {
|
||||
table.clear();
|
||||
}
|
||||
|
||||
public class Name {
|
||||
public String name;
|
||||
public boolean collisions;
|
||||
|
||||
public Name (String name, boolean collisions) {
|
||||
this.name = name;
|
||||
this.collisions = collisions;
|
||||
}
|
||||
}
|
||||
}
|
||||
195
jdkSrc/jdk8/sun/rmi/rmic/iiop/PrimitiveType.java
Normal file
195
jdkSrc/jdk8/sun/rmi/rmic/iiop/PrimitiveType.java
Normal file
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Licensed Materials - Property of IBM
|
||||
* RMI-IIOP v1.0
|
||||
* Copyright IBM Corp. 1998 1999 All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
package sun.rmi.rmic.iiop;
|
||||
|
||||
import sun.tools.java.CompilerError;
|
||||
import sun.tools.java.Identifier;
|
||||
import sun.tools.java.ClassDefinition;
|
||||
|
||||
/**
|
||||
* PrimitiveType wraps primitive types and void.
|
||||
* <p>
|
||||
* The static forPrimitive(...) method must be used to obtain an instance, and
|
||||
* will return null if the type is non-conforming.
|
||||
*
|
||||
* @author Bryan Atsatt
|
||||
*/
|
||||
public class PrimitiveType extends Type {
|
||||
|
||||
//_____________________________________________________________________
|
||||
// Public Interfaces
|
||||
//_____________________________________________________________________
|
||||
|
||||
/**
|
||||
* Create a PrimitiveType object for the given type.
|
||||
*
|
||||
* If the type is not a properly formed or if some other error occurs, the
|
||||
* return value will be null, and errors will have been reported to the
|
||||
* supplied BatchEnvironment.
|
||||
*/
|
||||
public static PrimitiveType forPrimitive(sun.tools.java.Type type,
|
||||
ContextStack stack) {
|
||||
|
||||
if (stack.anyErrors()) return null;
|
||||
|
||||
// Do we already have it?
|
||||
|
||||
Type existing = getType(type,stack);
|
||||
|
||||
if (existing != null) {
|
||||
|
||||
if (!(existing instanceof PrimitiveType)) return null; // False hit.
|
||||
|
||||
// Yep, so return it...
|
||||
|
||||
return (PrimitiveType) existing;
|
||||
}
|
||||
|
||||
int typeCode;
|
||||
|
||||
switch (type.getTypeCode()) {
|
||||
case TC_VOID: typeCode = TYPE_VOID; break;
|
||||
case TC_BOOLEAN: typeCode = TYPE_BOOLEAN; break;
|
||||
case TC_BYTE: typeCode = TYPE_BYTE; break;
|
||||
case TC_CHAR: typeCode = TYPE_CHAR; break;
|
||||
case TC_SHORT: typeCode = TYPE_SHORT; break;
|
||||
case TC_INT: typeCode = TYPE_INT; break;
|
||||
case TC_LONG: typeCode = TYPE_LONG; break;
|
||||
case TC_FLOAT: typeCode = TYPE_FLOAT; break;
|
||||
case TC_DOUBLE: typeCode = TYPE_DOUBLE; break;
|
||||
default: return null;
|
||||
}
|
||||
|
||||
PrimitiveType it = new PrimitiveType(stack,typeCode);
|
||||
|
||||
// Add it...
|
||||
|
||||
putType(type,it,stack);
|
||||
|
||||
// Do the stack thing in case tracing on...
|
||||
|
||||
stack.push(it);
|
||||
stack.pop(true);
|
||||
|
||||
return it;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return signature for this type (e.g. com.acme.Dynamite
|
||||
* would return "com.acme.Dynamite", byte = "B")
|
||||
*/
|
||||
public String getSignature() {
|
||||
switch (getTypeCode()) {
|
||||
case TYPE_VOID: return SIG_VOID;
|
||||
case TYPE_BOOLEAN: return SIG_BOOLEAN;
|
||||
case TYPE_BYTE: return SIG_BYTE;
|
||||
case TYPE_CHAR: return SIG_CHAR;
|
||||
case TYPE_SHORT: return SIG_SHORT;
|
||||
case TYPE_INT: return SIG_INT;
|
||||
case TYPE_LONG: return SIG_LONG;
|
||||
case TYPE_FLOAT: return SIG_FLOAT;
|
||||
case TYPE_DOUBLE: return SIG_DOUBLE;
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string describing this type.
|
||||
*/
|
||||
public String getTypeDescription () {
|
||||
return "Primitive";
|
||||
}
|
||||
|
||||
/**
|
||||
* IDL_Naming
|
||||
* Return the fully qualified IDL name for this type (e.g. com.acme.Dynamite would
|
||||
* return "com::acme::Dynamite").
|
||||
* @param global If true, prepends "::".
|
||||
*/
|
||||
public String getQualifiedIDLName(boolean global) {
|
||||
return super.getQualifiedIDLName(false);
|
||||
}
|
||||
|
||||
//_____________________________________________________________________
|
||||
// Subclass/Internal Interfaces
|
||||
//_____________________________________________________________________
|
||||
|
||||
/*
|
||||
* Load a Class instance. Return null if fail.
|
||||
*/
|
||||
protected Class loadClass() {
|
||||
switch (getTypeCode()) {
|
||||
case TYPE_VOID: return Null.class;
|
||||
case TYPE_BOOLEAN: return boolean.class;
|
||||
case TYPE_BYTE: return byte.class;
|
||||
case TYPE_CHAR: return char.class;
|
||||
case TYPE_SHORT: return short.class;
|
||||
case TYPE_INT: return int.class;
|
||||
case TYPE_LONG: return long.class;
|
||||
case TYPE_FLOAT: return float.class;
|
||||
case TYPE_DOUBLE: return double.class;
|
||||
default: throw new CompilerError("Not a primitive type");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* IDL_Naming
|
||||
* Create an PrimitiveType instance for the given class.
|
||||
*/
|
||||
private PrimitiveType(ContextStack stack, int typeCode) {
|
||||
super(stack,typeCode | TM_PRIMITIVE);
|
||||
|
||||
// Validate type and set names...
|
||||
|
||||
String idlName = IDLNames.getTypeName(typeCode,false);
|
||||
Identifier id = null;
|
||||
|
||||
switch (typeCode) {
|
||||
case TYPE_VOID: id = idVoid; break;
|
||||
case TYPE_BOOLEAN: id = idBoolean; break;
|
||||
case TYPE_BYTE: id = idByte; break;
|
||||
case TYPE_CHAR: id = idChar; break;
|
||||
case TYPE_SHORT: id = idShort; break;
|
||||
case TYPE_INT: id = idInt; break;
|
||||
case TYPE_LONG: id = idLong; break;
|
||||
case TYPE_FLOAT: id = idFloat; break;
|
||||
case TYPE_DOUBLE: id = idDouble; break;
|
||||
default: throw new CompilerError("Not a primitive type");
|
||||
}
|
||||
|
||||
setNames(id,null,idlName);
|
||||
setRepositoryID();
|
||||
}
|
||||
}
|
||||
|
||||
class Null {}
|
||||
171
jdkSrc/jdk8/sun/rmi/rmic/iiop/PrintGenerator.java
Normal file
171
jdkSrc/jdk8/sun/rmi/rmic/iiop/PrintGenerator.java
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* Licensed Materials - Property of IBM
|
||||
* RMI-IIOP v1.0
|
||||
* Copyright IBM Corp. 1998 1999 All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
package sun.rmi.rmic.iiop;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import sun.tools.java.CompilerError;
|
||||
import sun.tools.java.ClassDefinition;
|
||||
import sun.rmi.rmic.IndentingWriter;
|
||||
import sun.rmi.rmic.Main;
|
||||
|
||||
/**
|
||||
* An IDL generator for rmic.
|
||||
*
|
||||
* @author Bryan Atsatt
|
||||
*/
|
||||
public class PrintGenerator implements sun.rmi.rmic.Generator,
|
||||
sun.rmi.rmic.iiop.Constants {
|
||||
|
||||
private static final int JAVA = 0;
|
||||
private static final int IDL = 1;
|
||||
private static final int BOTH = 2;
|
||||
|
||||
private int whatToPrint; // Initialized in parseArgs.
|
||||
private boolean global = false;
|
||||
private boolean qualified = false;
|
||||
private boolean trace = false;
|
||||
private boolean valueMethods = false;
|
||||
|
||||
private IndentingWriter out;
|
||||
|
||||
/**
|
||||
* Default constructor for Main to use.
|
||||
*/
|
||||
public PrintGenerator() {
|
||||
OutputStreamWriter writer = new OutputStreamWriter(System.out);
|
||||
out = new IndentingWriter (writer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Examine and consume command line arguments.
|
||||
* @param argv The command line arguments. Ignore null
|
||||
* @param error Report any errors using the main.error() methods.
|
||||
* @return true if no errors, false otherwise.
|
||||
*/
|
||||
public boolean parseArgs(String argv[], Main main) {
|
||||
for (int i = 0; i < argv.length; i++) {
|
||||
if (argv[i] != null) {
|
||||
String arg = argv[i].toLowerCase();
|
||||
if (arg.equals("-xprint")) {
|
||||
whatToPrint = JAVA;
|
||||
argv[i] = null;
|
||||
if (i+1 < argv.length) {
|
||||
if (argv[i+1].equalsIgnoreCase("idl")) {
|
||||
argv[++i] = null;
|
||||
whatToPrint = IDL;
|
||||
} else if (argv[i+1].equalsIgnoreCase("both")) {
|
||||
argv[++i] = null;
|
||||
whatToPrint = BOTH;
|
||||
}
|
||||
}
|
||||
} else if (arg.equals("-xglobal")) {
|
||||
global = true;
|
||||
argv[i] = null;
|
||||
} else if (arg.equals("-xqualified")) {
|
||||
qualified = true;
|
||||
argv[i] = null;
|
||||
} else if (arg.equals("-xtrace")) {
|
||||
trace = true;
|
||||
argv[i] = null;
|
||||
} else if (arg.equals("-xvaluemethods")) {
|
||||
valueMethods = true;
|
||||
argv[i] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate output. Any source files created which need compilation should
|
||||
* be added to the compiler environment using the addGeneratedFile(File)
|
||||
* method.
|
||||
*
|
||||
* @param env The compiler environment
|
||||
* @param cdef The definition for the implementation class or interface from
|
||||
* which to generate output
|
||||
* @param destDir The directory for the root of the package hierarchy
|
||||
* for generated files. May be null.
|
||||
*/
|
||||
public void generate(sun.rmi.rmic.BatchEnvironment env, ClassDefinition cdef, File destDir) {
|
||||
|
||||
BatchEnvironment ourEnv = (BatchEnvironment) env;
|
||||
ContextStack stack = new ContextStack(ourEnv);
|
||||
stack.setTrace(trace);
|
||||
|
||||
if (valueMethods) {
|
||||
ourEnv.setParseNonConforming(true);
|
||||
}
|
||||
|
||||
// Get our top level type...
|
||||
|
||||
CompoundType topType = CompoundType.forCompound(cdef,stack);
|
||||
|
||||
if (topType != null) {
|
||||
|
||||
try {
|
||||
|
||||
// Collect up all the compound types...
|
||||
|
||||
Type[] theTypes = topType.collectMatching(TM_COMPOUND);
|
||||
|
||||
for (int i = 0; i < theTypes.length; i++) {
|
||||
|
||||
out.pln("\n-----------------------------------------------------------\n");
|
||||
|
||||
Type theType = theTypes[i];
|
||||
|
||||
switch (whatToPrint) {
|
||||
case JAVA: theType.println(out,qualified,false,false);
|
||||
break;
|
||||
|
||||
case IDL: theType.println(out,qualified,true,global);
|
||||
break;
|
||||
|
||||
case BOTH: theType.println(out,qualified,false,false);
|
||||
theType.println(out,qualified,true,global);
|
||||
break;
|
||||
|
||||
default: throw new CompilerError("Unknown type!");
|
||||
}
|
||||
}
|
||||
|
||||
out.flush();
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new CompilerError("PrintGenerator caught " + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
251
jdkSrc/jdk8/sun/rmi/rmic/iiop/RemoteType.java
Normal file
251
jdkSrc/jdk8/sun/rmi/rmic/iiop/RemoteType.java
Normal file
@@ -0,0 +1,251 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Licensed Materials - Property of IBM
|
||||
* RMI-IIOP v1.0
|
||||
* Copyright IBM Corp. 1998 1999 All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
package sun.rmi.rmic.iiop;
|
||||
|
||||
import java.util.Vector;
|
||||
import sun.tools.java.CompilerError;
|
||||
import sun.tools.java.ClassDefinition;
|
||||
import sun.tools.java.ClassNotFound;
|
||||
|
||||
/**
|
||||
* RemoteType represents any non-special interface which inherits
|
||||
* from java.rmi.Remote.
|
||||
* <p>
|
||||
* The static forRemote(...) method must be used to obtain an instance, and will
|
||||
* return null if the ClassDefinition is non-conforming.
|
||||
* @author Bryan Atsatt
|
||||
*/
|
||||
public class RemoteType extends InterfaceType {
|
||||
|
||||
//_____________________________________________________________________
|
||||
// Public Interfaces
|
||||
//_____________________________________________________________________
|
||||
|
||||
/**
|
||||
* Create an RemoteType for the given class.
|
||||
*
|
||||
* If the class is not a properly formed or if some other error occurs, the
|
||||
* return value will be null, and errors will have been reported to the
|
||||
* supplied BatchEnvironment.
|
||||
*/
|
||||
public static RemoteType forRemote(ClassDefinition classDef,
|
||||
ContextStack stack,
|
||||
boolean quiet) {
|
||||
|
||||
if (stack.anyErrors()) return null;
|
||||
|
||||
boolean doPop = false;
|
||||
RemoteType result = null;
|
||||
|
||||
try {
|
||||
// Do we already have it?
|
||||
|
||||
sun.tools.java.Type theType = classDef.getType();
|
||||
Type existing = getType(theType,stack);
|
||||
|
||||
if (existing != null) {
|
||||
|
||||
if (!(existing instanceof RemoteType)) return null; // False hit.
|
||||
|
||||
// Yep, so return it...
|
||||
|
||||
return (RemoteType) existing;
|
||||
}
|
||||
|
||||
// Could this be a remote type?
|
||||
|
||||
if (couldBeRemote(quiet,stack,classDef)) {
|
||||
|
||||
// Yes, so check it...
|
||||
|
||||
RemoteType it = new RemoteType(stack,classDef);
|
||||
putType(theType,it,stack);
|
||||
stack.push(it);
|
||||
doPop = true;
|
||||
|
||||
if (it.initialize(quiet,stack)) {
|
||||
stack.pop(true);
|
||||
result = it;
|
||||
} else {
|
||||
removeType(theType,stack);
|
||||
stack.pop(false);
|
||||
}
|
||||
}
|
||||
} catch (CompilerError e) {
|
||||
if (doPop) stack.pop(false);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string describing this type.
|
||||
*/
|
||||
public String getTypeDescription () {
|
||||
return "Remote interface";
|
||||
}
|
||||
|
||||
//_____________________________________________________________________
|
||||
// Internal/Subclass Interfaces
|
||||
//_____________________________________________________________________
|
||||
|
||||
/**
|
||||
* Create a RemoteType instance for the given class. The resulting
|
||||
* object is not yet completely initialized.
|
||||
*/
|
||||
protected RemoteType(ContextStack stack, ClassDefinition classDef) {
|
||||
super(stack,classDef,TYPE_REMOTE | TM_INTERFACE | TM_COMPOUND);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a RemoteType instance for the given class. The resulting
|
||||
* object is not yet completely initialized.
|
||||
*/
|
||||
protected RemoteType(ContextStack stack, ClassDefinition classDef, int typeCode) {
|
||||
super(stack,classDef,typeCode);
|
||||
}
|
||||
|
||||
//_____________________________________________________________________
|
||||
// Internal Interfaces
|
||||
//_____________________________________________________________________
|
||||
|
||||
|
||||
private static boolean couldBeRemote (boolean quiet, ContextStack stack,
|
||||
ClassDefinition classDef) {
|
||||
|
||||
boolean result = false;
|
||||
BatchEnvironment env = stack.getEnv();
|
||||
|
||||
try {
|
||||
if (!classDef.isInterface()) {
|
||||
failedConstraint(16,quiet,stack,classDef.getName());
|
||||
} else {
|
||||
result = env.defRemote.implementedBy(env,classDef.getClassDeclaration());
|
||||
if (!result) failedConstraint(1,quiet,stack,classDef.getName());
|
||||
}
|
||||
} catch (ClassNotFound e) {
|
||||
classNotFound(stack,e);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize this instance.
|
||||
*/
|
||||
private boolean initialize (boolean quiet,ContextStack stack) {
|
||||
|
||||
boolean result = false;
|
||||
|
||||
// Go check it out and gather up the info we need...
|
||||
|
||||
Vector directInterfaces = new Vector();
|
||||
Vector directMethods = new Vector();
|
||||
Vector directConstants = new Vector();
|
||||
|
||||
if (isConformingRemoteInterface(directInterfaces,
|
||||
directMethods,
|
||||
directConstants,
|
||||
quiet,
|
||||
stack)){
|
||||
|
||||
// We're ok, so pass 'em up...
|
||||
|
||||
result = initialize(directInterfaces,directMethods,directConstants,stack,quiet);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to ensure that the interface and all it's methods and arguments
|
||||
* conforms to the RMI/IDL java subset for remote interfaces as defined
|
||||
* by the "Java to IDL Mapping" specification, section 4.
|
||||
* @param directInterfaces All directly implmented interfaces will be
|
||||
* added to this list.
|
||||
* @param directMethods All directly implemented methods (other than
|
||||
* constructors and initializers) will be added to this list.
|
||||
* @param directConstants All constants defined by theInterface will be
|
||||
* added to this list.
|
||||
* @param quiet True if should not report constraint failures.
|
||||
* @return true if constraints satisfied, false otherwise.
|
||||
*/
|
||||
private boolean isConformingRemoteInterface ( Vector directInterfaces,
|
||||
Vector directMethods,
|
||||
Vector directConstants,
|
||||
boolean quiet,
|
||||
ContextStack stack) {
|
||||
|
||||
ClassDefinition theInterface = getClassDefinition();
|
||||
|
||||
try {
|
||||
|
||||
// Get all remote interfaces...
|
||||
|
||||
if (addRemoteInterfaces(directInterfaces,false,stack) == null ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make sure all constants are conforming...
|
||||
|
||||
if (!addAllMembers(directConstants,true,quiet,stack)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now, collect up all methods...
|
||||
|
||||
if (addAllMethods(theInterface,directMethods,true,quiet,stack) == null) {
|
||||
// Failed a constraint check...
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now walk 'em, ensuring each is a valid remote method...
|
||||
|
||||
boolean methodsConform = true;
|
||||
for (int i = 0; i < directMethods.size(); i++) {
|
||||
if (! isConformingRemoteMethod((Method) directMethods.elementAt(i),quiet)) {
|
||||
methodsConform = false;
|
||||
}
|
||||
}
|
||||
if (!methodsConform) {
|
||||
return false;
|
||||
}
|
||||
} catch (ClassNotFound e) {
|
||||
classNotFound(stack,e);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
171
jdkSrc/jdk8/sun/rmi/rmic/iiop/SpecialClassType.java
Normal file
171
jdkSrc/jdk8/sun/rmi/rmic/iiop/SpecialClassType.java
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Licensed Materials - Property of IBM
|
||||
* RMI-IIOP v1.0
|
||||
* Copyright IBM Corp. 1998 1999 All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
package sun.rmi.rmic.iiop;
|
||||
|
||||
import sun.tools.java.ClassNotFound;
|
||||
import sun.tools.java.CompilerError;
|
||||
import sun.tools.java.Identifier;
|
||||
import sun.tools.java.ClassDefinition;
|
||||
|
||||
/**
|
||||
* SpecialClassType represents any one of the following types:
|
||||
* <pre>
|
||||
* java.lang.Object
|
||||
* java.lang.String
|
||||
* </pre>
|
||||
* all of which are treated as special cases.
|
||||
* <p>
|
||||
* The static forSpecial(...) method must be used to obtain an instance, and
|
||||
* will return null if the type is non-conforming.
|
||||
*
|
||||
* @author Bryan Atsatt
|
||||
*/
|
||||
public class SpecialClassType extends ClassType {
|
||||
|
||||
//_____________________________________________________________________
|
||||
// Public Interfaces
|
||||
//_____________________________________________________________________
|
||||
|
||||
/**
|
||||
* Create a SpecialClassType object for the given class.
|
||||
*
|
||||
* If the class is not a properly formed or if some other error occurs, the
|
||||
* return value will be null, and errors will have been reported to the
|
||||
* supplied BatchEnvironment.
|
||||
*/
|
||||
public static SpecialClassType forSpecial (ClassDefinition theClass,
|
||||
ContextStack stack) {
|
||||
if (stack.anyErrors()) return null;
|
||||
|
||||
sun.tools.java.Type type = theClass.getType();
|
||||
|
||||
// Do we already have it?
|
||||
|
||||
String typeKey = type.toString() + stack.getContextCodeString();
|
||||
|
||||
Type existing = getType(typeKey,stack);
|
||||
|
||||
if (existing != null) {
|
||||
|
||||
if (!(existing instanceof SpecialClassType)) return null; // False hit.
|
||||
|
||||
// Yep, so return it...
|
||||
|
||||
return (SpecialClassType) existing;
|
||||
}
|
||||
|
||||
// Is it a special type?
|
||||
|
||||
int typeCode = getTypeCode(type,theClass,stack);
|
||||
|
||||
if (typeCode != TYPE_NONE) {
|
||||
|
||||
// Yes...
|
||||
|
||||
SpecialClassType result = new SpecialClassType(stack,typeCode,theClass);
|
||||
putType(typeKey,result,stack);
|
||||
stack.push(result);
|
||||
stack.pop(true);
|
||||
return result;
|
||||
|
||||
} else {
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string describing this type.
|
||||
*/
|
||||
public String getTypeDescription () {
|
||||
return "Special class";
|
||||
}
|
||||
|
||||
//_____________________________________________________________________
|
||||
// Subclass/Internal Interfaces
|
||||
//_____________________________________________________________________
|
||||
|
||||
/**
|
||||
* Create an SpecialClassType instance for the given class.
|
||||
*/
|
||||
private SpecialClassType(ContextStack stack, int typeCode,
|
||||
ClassDefinition theClass) {
|
||||
super(stack,typeCode | TM_SPECIAL_CLASS | TM_CLASS | TM_COMPOUND, theClass);
|
||||
Identifier id = theClass.getName();
|
||||
String idlName = null;
|
||||
String[] idlModuleName = null;
|
||||
boolean constant = stack.size() > 0 && stack.getContext().isConstant();
|
||||
|
||||
// Set names...
|
||||
|
||||
switch (typeCode) {
|
||||
case TYPE_STRING: {
|
||||
idlName = IDLNames.getTypeName(typeCode,constant);
|
||||
if (!constant) {
|
||||
idlModuleName = IDL_CORBA_MODULE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TYPE_ANY: {
|
||||
idlName = IDL_JAVA_LANG_OBJECT;
|
||||
idlModuleName = IDL_JAVA_LANG_MODULE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
setNames(id,idlModuleName,idlName);
|
||||
|
||||
// Init parents...
|
||||
|
||||
if (!initParents(stack)) {
|
||||
|
||||
// Should not be possible!
|
||||
|
||||
throw new CompilerError("SpecialClassType found invalid parent.");
|
||||
}
|
||||
|
||||
// Initialize CompoundType...
|
||||
|
||||
initialize(null,null,null,stack,false);
|
||||
}
|
||||
|
||||
private static int getTypeCode(sun.tools.java.Type type, ClassDefinition theClass, ContextStack stack) {
|
||||
if (type.isType(TC_CLASS)) {
|
||||
Identifier id = type.getClassName();
|
||||
if (id == idJavaLangString) return TYPE_STRING;
|
||||
if (id == idJavaLangObject) return TYPE_ANY;
|
||||
}
|
||||
return TYPE_NONE;
|
||||
}
|
||||
}
|
||||
233
jdkSrc/jdk8/sun/rmi/rmic/iiop/SpecialInterfaceType.java
Normal file
233
jdkSrc/jdk8/sun/rmi/rmic/iiop/SpecialInterfaceType.java
Normal file
@@ -0,0 +1,233 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Licensed Materials - Property of IBM
|
||||
* RMI-IIOP v1.0
|
||||
* Copyright IBM Corp. 1998 1999 All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
package sun.rmi.rmic.iiop;
|
||||
|
||||
import sun.tools.java.ClassNotFound;
|
||||
import sun.tools.java.CompilerError;
|
||||
import sun.tools.java.Identifier;
|
||||
import sun.tools.java.ClassDeclaration;
|
||||
import sun.tools.java.ClassDefinition;
|
||||
|
||||
/**
|
||||
* SpecialInterfaceType represents any one of the following types:
|
||||
* <pre>
|
||||
* java.rmi.Remote
|
||||
* java.io.Serializable
|
||||
* java.io.Externalizable
|
||||
* org.omg.CORBA.Object
|
||||
* org.omg.CORBA.portable.IDLEntity
|
||||
* </pre>
|
||||
* all of which are treated as special cases. For all but CORBA.Object,
|
||||
* the type must match exactly. For CORBA.Object, the type must either be
|
||||
* CORBA.Object or inherit from it.
|
||||
* <p>
|
||||
* The static forSpecial(...) method must be used to obtain an instance, and
|
||||
* will return null if the type is non-conforming.
|
||||
*
|
||||
* @author Bryan Atsatt
|
||||
*/
|
||||
public class SpecialInterfaceType extends InterfaceType {
|
||||
|
||||
//_____________________________________________________________________
|
||||
// Public Interfaces
|
||||
//_____________________________________________________________________
|
||||
|
||||
/**
|
||||
* Create a SpecialInterfaceType object for the given class.
|
||||
*
|
||||
* If the class is not a properly formed or if some other error occurs, the
|
||||
* return value will be null, and errors will have been reported to the
|
||||
* supplied BatchEnvironment.
|
||||
*/
|
||||
public static SpecialInterfaceType forSpecial ( ClassDefinition theClass,
|
||||
ContextStack stack) {
|
||||
|
||||
if (stack.anyErrors()) return null;
|
||||
|
||||
// Do we already have it?
|
||||
|
||||
sun.tools.java.Type type = theClass.getType();
|
||||
Type existing = getType(type,stack);
|
||||
|
||||
if (existing != null) {
|
||||
|
||||
if (!(existing instanceof SpecialInterfaceType)) return null; // False hit.
|
||||
|
||||
// Yep, so return it...
|
||||
|
||||
return (SpecialInterfaceType) existing;
|
||||
}
|
||||
|
||||
// Is it special?
|
||||
|
||||
if (isSpecial(type,theClass,stack)) {
|
||||
|
||||
// Yes...
|
||||
|
||||
SpecialInterfaceType result = new SpecialInterfaceType(stack,0,theClass);
|
||||
putType(type,result,stack);
|
||||
stack.push(result);
|
||||
|
||||
if (result.initialize(type,stack)) {
|
||||
stack.pop(true);
|
||||
return result;
|
||||
} else {
|
||||
removeType(type,stack);
|
||||
stack.pop(false);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string describing this type.
|
||||
*/
|
||||
public String getTypeDescription () {
|
||||
return "Special interface";
|
||||
}
|
||||
|
||||
//_____________________________________________________________________
|
||||
// Subclass/Internal Interfaces
|
||||
//_____________________________________________________________________
|
||||
|
||||
/**
|
||||
* Create an SpecialInterfaceType instance for the given class.
|
||||
*/
|
||||
private SpecialInterfaceType(ContextStack stack, int typeCode,
|
||||
ClassDefinition theClass) {
|
||||
super(stack,typeCode | TM_SPECIAL_INTERFACE | TM_INTERFACE | TM_COMPOUND, theClass);
|
||||
setNames(theClass.getName(),null,null); // Fixed in initialize.
|
||||
}
|
||||
|
||||
private static boolean isSpecial(sun.tools.java.Type type,
|
||||
ClassDefinition theClass,
|
||||
ContextStack stack) {
|
||||
if (type.isType(TC_CLASS)) {
|
||||
Identifier id = type.getClassName();
|
||||
|
||||
if (id.equals(idRemote)) return true;
|
||||
if (id == idJavaIoSerializable) return true;
|
||||
if (id == idJavaIoExternalizable) return true;
|
||||
if (id == idCorbaObject) return true;
|
||||
if (id == idIDLEntity) return true;
|
||||
BatchEnvironment env = stack.getEnv();
|
||||
try {
|
||||
if (env.defCorbaObject.implementedBy(env,theClass.getClassDeclaration())) return true;
|
||||
} catch (ClassNotFound e) {
|
||||
classNotFound(stack,e);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean initialize(sun.tools.java.Type type, ContextStack stack) {
|
||||
|
||||
int typeCode = TYPE_NONE;
|
||||
Identifier id = null;
|
||||
String idlName = null;
|
||||
String[] idlModuleName = null;
|
||||
boolean constant = stack.size() > 0 && stack.getContext().isConstant();
|
||||
|
||||
if (type.isType(TC_CLASS)) {
|
||||
id = type.getClassName();
|
||||
|
||||
if (id.equals(idRemote)) {
|
||||
typeCode = TYPE_JAVA_RMI_REMOTE;
|
||||
idlName = IDL_JAVA_RMI_REMOTE;
|
||||
idlModuleName = IDL_JAVA_RMI_MODULE;
|
||||
} else if (id == idJavaIoSerializable) {
|
||||
typeCode = TYPE_ANY;
|
||||
idlName = IDL_SERIALIZABLE;
|
||||
idlModuleName = IDL_JAVA_IO_MODULE;
|
||||
} else if (id == idJavaIoExternalizable) {
|
||||
typeCode = TYPE_ANY;
|
||||
idlName = IDL_EXTERNALIZABLE;
|
||||
idlModuleName = IDL_JAVA_IO_MODULE;
|
||||
} else if (id == idIDLEntity) {
|
||||
typeCode = TYPE_ANY;
|
||||
idlName = IDL_IDLENTITY;
|
||||
idlModuleName = IDL_ORG_OMG_CORBA_PORTABLE_MODULE;
|
||||
} else {
|
||||
|
||||
typeCode = TYPE_CORBA_OBJECT;
|
||||
|
||||
// Is it exactly org.omg.CORBA.Object?
|
||||
|
||||
if (id == idCorbaObject) {
|
||||
|
||||
// Yes, so special case...
|
||||
|
||||
idlName = IDLNames.getTypeName(typeCode,constant);
|
||||
idlModuleName = null;
|
||||
|
||||
} else {
|
||||
|
||||
// No, so get the correct names...
|
||||
|
||||
try {
|
||||
|
||||
// These can fail if we get case-sensitive name matches...
|
||||
|
||||
idlName = IDLNames.getClassOrInterfaceName(id,env);
|
||||
idlModuleName = IDLNames.getModuleNames(id,isBoxed(),env);
|
||||
|
||||
} catch (Exception e) {
|
||||
failedConstraint(7,false,stack,id.toString(),e.getMessage());
|
||||
throw new CompilerError("");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (typeCode == TYPE_NONE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Reset type code...
|
||||
|
||||
setTypeCode(typeCode | TM_SPECIAL_INTERFACE | TM_INTERFACE | TM_COMPOUND);
|
||||
|
||||
// Set names
|
||||
|
||||
if (idlName == null) {
|
||||
throw new CompilerError("Not a special type");
|
||||
}
|
||||
|
||||
setNames(id,idlModuleName,idlName);
|
||||
|
||||
// Initialize CompoundType...
|
||||
|
||||
return initialize(null,null,null,stack,false);
|
||||
}
|
||||
}
|
||||
372
jdkSrc/jdk8/sun/rmi/rmic/iiop/StaticStringsHash.java
Normal file
372
jdkSrc/jdk8/sun/rmi/rmic/iiop/StaticStringsHash.java
Normal file
@@ -0,0 +1,372 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* Licensed Materials - Property of IBM
|
||||
* RMI-IIOP v1.0
|
||||
* Copyright IBM Corp. 1998 1999 All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
package sun.rmi.rmic.iiop;
|
||||
|
||||
/**
|
||||
* StaticStringsHash takes an array of constant strings and
|
||||
* uses several different hash methods to try to find the
|
||||
* 'best' one for that set. The set of methods is currently
|
||||
* fixed, but with a little work could be made extensible thru
|
||||
* subclassing.
|
||||
* <p>
|
||||
* The current set of methods is:
|
||||
* <ol>
|
||||
* <li> length() - works well when all strings are different length.</li>
|
||||
* <li> charAt(n) - works well when one offset into all strings is different.</li>
|
||||
* <li> hashCode() - works well with larger arrays.</li>
|
||||
* </ol>
|
||||
* After constructing an instance over the set of strings, the
|
||||
* <code>getKey(String)</code> method can be used to use the selected hash
|
||||
* method to produce a key. The <code>method</code> string will contain
|
||||
* "length()", "charAt(n)", or "hashCode()", and is intended for use by
|
||||
* code generators.
|
||||
* <p>
|
||||
* The <code>keys</code> array will contain the full set of unique keys.
|
||||
* <p>
|
||||
* The <code>buckets</code> array will contain a set of arrays, one for
|
||||
* each key in the <code>keys</code>, where <code>buckets[x][y]</code>
|
||||
* is an index into the <code>strings</code> array.
|
||||
* @author Bryan Atsatt
|
||||
*/
|
||||
public class StaticStringsHash {
|
||||
|
||||
/** The set of strings upon which the hash info is created */
|
||||
public String[] strings = null;
|
||||
|
||||
/** Unique hash keys */
|
||||
public int[] keys = null;
|
||||
|
||||
/** Buckets for each key, where buckets[x][y] is an index
|
||||
* into the strings[] array. */
|
||||
public int[][] buckets = null;
|
||||
|
||||
/** The method to invoke on String to produce the hash key */
|
||||
public String method = null;
|
||||
|
||||
/** Get a key for the given string using the
|
||||
* selected hash method.
|
||||
* @param str the string to return a key for.
|
||||
* @return the key.
|
||||
*/
|
||||
public int getKey(String str) {
|
||||
switch (keyKind) {
|
||||
case LENGTH: return str.length();
|
||||
case CHAR_AT: return str.charAt(charAt);
|
||||
case HASH_CODE: return str.hashCode();
|
||||
}
|
||||
throw new Error("Bad keyKind");
|
||||
}
|
||||
|
||||
/** Constructor
|
||||
* @param strings the set of strings upon which to
|
||||
* find an optimal hash method. Must not contain
|
||||
* duplicates.
|
||||
*/
|
||||
public StaticStringsHash(String[] strings) {
|
||||
this.strings = strings;
|
||||
length = strings.length;
|
||||
tempKeys = new int[length];
|
||||
bucketSizes = new int[length];
|
||||
setMinStringLength();
|
||||
|
||||
// Decide on the best algorithm based on
|
||||
// which one has the smallest maximum
|
||||
// bucket depth. First, try length()...
|
||||
|
||||
int currentMaxDepth = getKeys(LENGTH);
|
||||
int useCharAt = -1;
|
||||
boolean useHashCode = false;
|
||||
|
||||
if (currentMaxDepth > 1) {
|
||||
|
||||
// At least one bucket had more than one
|
||||
// entry, so try charAt(i). If there
|
||||
// are a lot of strings in the array,
|
||||
// and minStringLength is large, limit
|
||||
// the search to a smaller number of
|
||||
// characters to avoid spending a lot
|
||||
// of time here that is most likely to
|
||||
// be pointless...
|
||||
|
||||
int minLength = minStringLength;
|
||||
if (length > CHAR_AT_MAX_LINES &&
|
||||
length * minLength > CHAR_AT_MAX_CHARS) {
|
||||
minLength = length/CHAR_AT_MAX_CHARS;
|
||||
}
|
||||
|
||||
charAt = 0;
|
||||
for (int i = 0; i < minLength; i++) {
|
||||
int charAtDepth = getKeys(CHAR_AT);
|
||||
if (charAtDepth < currentMaxDepth) {
|
||||
currentMaxDepth = charAtDepth;
|
||||
useCharAt = i;
|
||||
if (currentMaxDepth == 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
charAt++;
|
||||
}
|
||||
charAt = useCharAt;
|
||||
|
||||
|
||||
if (currentMaxDepth > 1) {
|
||||
|
||||
// At least one bucket had more than one
|
||||
// entry, try hashCode().
|
||||
//
|
||||
// Since the cost of computing a full hashCode
|
||||
// (for the runtime target string) is much higher
|
||||
// than the previous methods, use it only if it is
|
||||
// substantially better. The definition of 'substantial'
|
||||
// here is not very well founded, and could be improved
|
||||
// with some further analysis ;^)
|
||||
|
||||
int hashCodeDepth = getKeys(HASH_CODE);
|
||||
if (hashCodeDepth < currentMaxDepth-3) {
|
||||
|
||||
// Using the full hashCode results in at least
|
||||
// 3 fewer entries in the worst bucket, so will
|
||||
// therefore avoid at least 3 calls to equals()
|
||||
// in the worst case.
|
||||
//
|
||||
// Note that using a number smaller than 3 could
|
||||
// result in using a hashCode when there are only
|
||||
// 2 strings in the array, and that would surely
|
||||
// be a poor performance choice.
|
||||
|
||||
useHashCode = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Reset keys if needed...
|
||||
|
||||
if (!useHashCode) {
|
||||
if (useCharAt >= 0) {
|
||||
|
||||
// Use the charAt(i) method...
|
||||
|
||||
getKeys(CHAR_AT);
|
||||
|
||||
} else {
|
||||
|
||||
// Use length method...
|
||||
|
||||
getKeys(LENGTH);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now allocate and fill our real hashKeys array...
|
||||
|
||||
keys = new int[bucketCount];
|
||||
System.arraycopy(tempKeys,0,keys,0,bucketCount);
|
||||
|
||||
// Sort keys and bucketSizes arrays...
|
||||
|
||||
boolean didSwap;
|
||||
do {
|
||||
didSwap = false;
|
||||
for (int i = 0; i < bucketCount - 1; i++) {
|
||||
if (keys[i] > keys[i+1]) {
|
||||
int temp = keys[i];
|
||||
keys[i] = keys[i+1];
|
||||
keys[i+1] = temp;
|
||||
temp = bucketSizes[i];
|
||||
bucketSizes[i] = bucketSizes[i+1];
|
||||
bucketSizes[i+1] = temp;
|
||||
didSwap = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (didSwap == true);
|
||||
|
||||
// Allocate our buckets array. Fill the string
|
||||
// index slot with an unused key so we can
|
||||
// determine which are free...
|
||||
|
||||
int unused = findUnusedKey();
|
||||
buckets = new int[bucketCount][];
|
||||
for (int i = 0; i < bucketCount; i++) {
|
||||
buckets[i] = new int[bucketSizes[i]];
|
||||
for (int j = 0; j < bucketSizes[i]; j++) {
|
||||
buckets[i][j] = unused;
|
||||
}
|
||||
}
|
||||
|
||||
// And fill it in...
|
||||
|
||||
for(int i = 0; i < strings.length; i++) {
|
||||
int key = getKey(strings[i]);
|
||||
for (int j = 0; j < bucketCount; j++) {
|
||||
if (keys[j] == key) {
|
||||
int k = 0;
|
||||
while (buckets[j][k] != unused) {
|
||||
k++;
|
||||
}
|
||||
buckets[j][k] = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Print an optimized 'contains' method for the
|
||||
* argument strings
|
||||
*/
|
||||
public static void main (String[] args) {
|
||||
StaticStringsHash hash = new StaticStringsHash(args);
|
||||
System.out.println();
|
||||
System.out.println(" public boolean contains(String key) {");
|
||||
System.out.println(" switch (key."+hash.method+") {");
|
||||
for (int i = 0; i < hash.buckets.length; i++) {
|
||||
System.out.println(" case "+hash.keys[i]+": ");
|
||||
for (int j = 0; j < hash.buckets[i].length; j++) {
|
||||
if (j > 0) {
|
||||
System.out.print(" } else ");
|
||||
} else {
|
||||
System.out.print(" ");
|
||||
}
|
||||
System.out.println("if (key.equals(\""+ hash.strings[hash.buckets[i][j]] +"\")) {");
|
||||
System.out.println(" return true;");
|
||||
}
|
||||
System.out.println(" }");
|
||||
}
|
||||
System.out.println(" }");
|
||||
System.out.println(" return false;");
|
||||
System.out.println(" }");
|
||||
}
|
||||
|
||||
private int length;
|
||||
private int[] tempKeys;
|
||||
private int[] bucketSizes;
|
||||
private int bucketCount;
|
||||
private int maxDepth;
|
||||
private int minStringLength = Integer.MAX_VALUE;
|
||||
private int keyKind;
|
||||
private int charAt;
|
||||
|
||||
private static final int LENGTH = 0;
|
||||
private static final int CHAR_AT = 1;
|
||||
private static final int HASH_CODE = 2;
|
||||
|
||||
/* Determines the maximum number of charAt(i)
|
||||
* tests that will be done. The search is
|
||||
* limited because if the number of characters
|
||||
* is large enough, the likelyhood of finding
|
||||
* a good hash key based on this method is
|
||||
* low. The CHAR_AT_MAX_CHARS limit only
|
||||
* applies f there are more strings than
|
||||
* CHAR_AT_MAX_LINES.
|
||||
*/
|
||||
private static final int CHAR_AT_MAX_LINES = 50;
|
||||
private static final int CHAR_AT_MAX_CHARS = 1000;
|
||||
|
||||
private void resetKeys(int keyKind) {
|
||||
this.keyKind = keyKind;
|
||||
switch (keyKind) {
|
||||
case LENGTH: method = "length()"; break;
|
||||
case CHAR_AT: method = "charAt("+charAt+")"; break;
|
||||
case HASH_CODE: method = "hashCode()"; break;
|
||||
}
|
||||
maxDepth = 1;
|
||||
bucketCount = 0;
|
||||
for (int i = 0; i < length; i++) {
|
||||
tempKeys[i] = 0;
|
||||
bucketSizes[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void setMinStringLength() {
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (strings[i].length() < minStringLength) {
|
||||
minStringLength = strings[i].length();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int findUnusedKey() {
|
||||
int unused = 0;
|
||||
int keysLength = keys.length;
|
||||
|
||||
// Note that we just assume that resource
|
||||
// exhaustion will occur rather than an
|
||||
// infinite loop here if the set of keys
|
||||
// is very large.
|
||||
|
||||
while (true) {
|
||||
boolean match = false;
|
||||
for (int i = 0; i < keysLength; i++) {
|
||||
if (keys[i] == unused) {
|
||||
match = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (match) {
|
||||
unused--;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return unused;
|
||||
}
|
||||
|
||||
private int getKeys(int methodKind) {
|
||||
resetKeys(methodKind);
|
||||
for(int i = 0; i < strings.length; i++) {
|
||||
addKey(getKey(strings[i]));
|
||||
}
|
||||
return maxDepth;
|
||||
}
|
||||
|
||||
private void addKey(int key) {
|
||||
|
||||
// Have we seen this one before?
|
||||
|
||||
boolean addIt = true;
|
||||
for (int j = 0; j < bucketCount; j++) {
|
||||
if (tempKeys[j] == key) {
|
||||
addIt = false;
|
||||
bucketSizes[j]++;
|
||||
if (bucketSizes[j] > maxDepth) {
|
||||
maxDepth = bucketSizes[j];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (addIt) {
|
||||
tempKeys[bucketCount] = key;
|
||||
bucketSizes[bucketCount] = 1;
|
||||
bucketCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
2380
jdkSrc/jdk8/sun/rmi/rmic/iiop/StubGenerator.java
Normal file
2380
jdkSrc/jdk8/sun/rmi/rmic/iiop/StubGenerator.java
Normal file
File diff suppressed because it is too large
Load Diff
1009
jdkSrc/jdk8/sun/rmi/rmic/iiop/Type.java
Normal file
1009
jdkSrc/jdk8/sun/rmi/rmic/iiop/Type.java
Normal file
File diff suppressed because it is too large
Load Diff
174
jdkSrc/jdk8/sun/rmi/rmic/iiop/Util.java
Normal file
174
jdkSrc/jdk8/sun/rmi/rmic/iiop/Util.java
Normal file
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Licensed Materials - Property of IBM
|
||||
* RMI-IIOP v1.0
|
||||
* Copyright IBM Corp. 1998 1999 All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
package sun.rmi.rmic.iiop;
|
||||
|
||||
import java.io.File;
|
||||
import sun.tools.java.Identifier;
|
||||
|
||||
import com.sun.corba.se.impl.util.PackagePrefixChecker;
|
||||
|
||||
/**
|
||||
* Util provides static utility methods used by other rmic classes.
|
||||
* @author Bryan Atsatt
|
||||
*/
|
||||
|
||||
public final class Util implements sun.rmi.rmic.Constants {
|
||||
|
||||
|
||||
public static String packagePrefix(){ return PackagePrefixChecker.packagePrefix();}
|
||||
|
||||
|
||||
/**
|
||||
* Return the directory that should be used for output for a given
|
||||
* class.
|
||||
* @param theClass The fully qualified name of the class.
|
||||
* @param rootDir The directory to use as the root of the
|
||||
* package heirarchy. May be null, in which case the current
|
||||
* working directory is used as the root.
|
||||
*/
|
||||
private static File getOutputDirectoryFor(Identifier theClass,
|
||||
File rootDir,
|
||||
BatchEnvironment env,
|
||||
boolean idl ) {
|
||||
File outputDir = null;
|
||||
String className = theClass.getFlatName().toString().replace('.', SIGC_INNERCLASS);
|
||||
String qualifiedClassName = className;
|
||||
String packagePath = null;
|
||||
String packageName = theClass.getQualifier().toString();
|
||||
//Shift package names for stubs generated for interfaces.
|
||||
/*if(type.isInterface())*/
|
||||
packageName = correctPackageName(packageName, idl, env.getStandardPackage());
|
||||
//Done.
|
||||
if (packageName.length() > 0) {
|
||||
qualifiedClassName = packageName + "." + className;
|
||||
packagePath = packageName.replace('.', File.separatorChar);
|
||||
}
|
||||
|
||||
// Do we have a root directory?
|
||||
|
||||
if (rootDir != null) {
|
||||
|
||||
// Yes, do we have a package name?
|
||||
|
||||
if (packagePath != null) {
|
||||
|
||||
// Yes, so use it as the root. Open the directory...
|
||||
|
||||
outputDir = new File(rootDir, packagePath);
|
||||
|
||||
// Make sure the directory exists...
|
||||
|
||||
ensureDirectory(outputDir,env);
|
||||
|
||||
} else {
|
||||
|
||||
// Default package, so use root as output dir...
|
||||
|
||||
outputDir = rootDir;
|
||||
}
|
||||
} else {
|
||||
|
||||
// No root directory. Get the current working directory...
|
||||
|
||||
String workingDirPath = System.getProperty("user.dir");
|
||||
File workingDir = new File(workingDirPath);
|
||||
|
||||
// Do we have a package name?
|
||||
|
||||
if (packagePath == null) {
|
||||
|
||||
// No, so use working directory...
|
||||
|
||||
outputDir = workingDir;
|
||||
|
||||
} else {
|
||||
|
||||
// Yes, so use working directory as the root...
|
||||
|
||||
outputDir = new File(workingDir, packagePath);
|
||||
|
||||
// Make sure the directory exists...
|
||||
|
||||
ensureDirectory(outputDir,env);
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, return the directory...
|
||||
|
||||
return outputDir;
|
||||
}
|
||||
|
||||
public static File getOutputDirectoryForIDL(Identifier theClass,
|
||||
File rootDir,
|
||||
BatchEnvironment env) {
|
||||
return getOutputDirectoryFor(theClass, rootDir, env, true);
|
||||
}
|
||||
|
||||
public static File getOutputDirectoryForStub(Identifier theClass,
|
||||
File rootDir,
|
||||
BatchEnvironment env) {
|
||||
return getOutputDirectoryFor(theClass, rootDir, env, false);
|
||||
}
|
||||
|
||||
private static void ensureDirectory (File dir, BatchEnvironment env) {
|
||||
if (!dir.exists()) {
|
||||
dir.mkdirs();
|
||||
if (!dir.exists()) {
|
||||
env.error(0,"rmic.cannot.create.dir",dir.getAbsolutePath());
|
||||
throw new InternalError();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static String correctPackageName(
|
||||
String p, boolean idl, boolean standardPackage){
|
||||
if (idl){
|
||||
return p;
|
||||
} else {
|
||||
if (standardPackage) {
|
||||
return p;
|
||||
} else {
|
||||
return PackagePrefixChecker.correctPackageName(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isOffendingPackage(String p){
|
||||
return PackagePrefixChecker.isOffendingPackage(p);
|
||||
}
|
||||
|
||||
public static boolean hasOffendingPrefix(String p){
|
||||
return PackagePrefixChecker.hasOffendingPrefix(p);
|
||||
}
|
||||
|
||||
}
|
||||
488
jdkSrc/jdk8/sun/rmi/rmic/iiop/ValueType.java
Normal file
488
jdkSrc/jdk8/sun/rmi/rmic/iiop/ValueType.java
Normal file
@@ -0,0 +1,488 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* Licensed Materials - Property of IBM
|
||||
* RMI-IIOP v1.0
|
||||
* Copyright IBM Corp. 1998 1999 All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
package sun.rmi.rmic.iiop;
|
||||
|
||||
import java.util.Vector;
|
||||
import sun.tools.java.ClassNotFound;
|
||||
import sun.tools.java.ClassDeclaration;
|
||||
import sun.tools.java.ClassDefinition;
|
||||
import sun.tools.java.MemberDefinition;
|
||||
import java.util.Hashtable;
|
||||
import java.io.ObjectStreamClass;
|
||||
import java.io.ObjectStreamField;
|
||||
|
||||
|
||||
/**
|
||||
* ValueType represents any non-special class which does inherit from
|
||||
* java.io.Serializable and does not inherit from java.rmi.Remote.
|
||||
* <p>
|
||||
* The static forValue(...) method must be used to obtain an instance, and
|
||||
* will return null if the ClassDefinition is non-conforming.
|
||||
*
|
||||
* @author Bryan Atsatt
|
||||
*/
|
||||
public class ValueType extends ClassType {
|
||||
|
||||
private boolean isCustom;
|
||||
|
||||
//_____________________________________________________________________
|
||||
// Public Interfaces
|
||||
//_____________________________________________________________________
|
||||
|
||||
/**
|
||||
* Create an ValueType object for the given class.
|
||||
*
|
||||
* If the class is not a properly formed or if some other error occurs, the
|
||||
* return value will be null, and errors will have been reported to the
|
||||
* supplied BatchEnvironment.
|
||||
*/
|
||||
public static ValueType forValue(ClassDefinition classDef,
|
||||
ContextStack stack,
|
||||
boolean quiet) {
|
||||
|
||||
if (stack.anyErrors()) return null;
|
||||
|
||||
// Do we already have it?
|
||||
|
||||
sun.tools.java.Type theType = classDef.getType();
|
||||
String typeKey = theType.toString();
|
||||
Type existing = getType(typeKey,stack);
|
||||
|
||||
if (existing != null) {
|
||||
|
||||
if (!(existing instanceof ValueType)) return null; // False hit.
|
||||
|
||||
// Yep, so return it...
|
||||
|
||||
return (ValueType) existing;
|
||||
}
|
||||
|
||||
// Is this java.lang.Class?
|
||||
|
||||
boolean javaLangClass = false;
|
||||
|
||||
if (classDef.getClassDeclaration().getName() == idJavaLangClass) {
|
||||
|
||||
// Yes, so replace classDef with one for
|
||||
// javax.rmi.CORBA.ClassDesc...
|
||||
|
||||
javaLangClass = true;
|
||||
BatchEnvironment env = stack.getEnv();
|
||||
ClassDeclaration decl = env.getClassDeclaration(idClassDesc);
|
||||
ClassDefinition def = null;
|
||||
|
||||
try {
|
||||
def = decl.getClassDefinition(env);
|
||||
} catch (ClassNotFound ex) {
|
||||
classNotFound(stack,ex);
|
||||
return null;
|
||||
}
|
||||
|
||||
classDef = def;
|
||||
}
|
||||
|
||||
// Could this be a value?
|
||||
|
||||
if (couldBeValue(stack,classDef)) {
|
||||
|
||||
// Yes, so check it...
|
||||
|
||||
ValueType it = new ValueType(classDef,stack,javaLangClass);
|
||||
putType(typeKey,it,stack);
|
||||
stack.push(it);
|
||||
|
||||
if (it.initialize(stack,quiet)) {
|
||||
stack.pop(true);
|
||||
return it;
|
||||
} else {
|
||||
removeType(typeKey,stack);
|
||||
stack.pop(false);
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a string describing this type.
|
||||
*/
|
||||
public String getTypeDescription () {
|
||||
String result = addExceptionDescription("Value");
|
||||
if (isCustom) {
|
||||
result = "Custom " + result;
|
||||
}
|
||||
if (isIDLEntity) {
|
||||
result = result + " [IDLEntity]";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this type is a "custom" type (i.e.
|
||||
* it implements java.io.Externalizable or has a
|
||||
* method with the following signature:
|
||||
*
|
||||
* private void writeObject(java.io.ObjectOutputStream out);
|
||||
*
|
||||
*/
|
||||
public boolean isCustom () {
|
||||
return isCustom;
|
||||
}
|
||||
|
||||
|
||||
//_____________________________________________________________________
|
||||
// Subclass/Internal Interfaces
|
||||
//_____________________________________________________________________
|
||||
|
||||
/**
|
||||
* Create a ValueType instance for the given class. The resulting
|
||||
* object is not yet completely initialized.
|
||||
*/
|
||||
private ValueType(ClassDefinition classDef,
|
||||
ContextStack stack,
|
||||
boolean isMappedJavaLangClass) {
|
||||
super(stack,classDef,TYPE_VALUE | TM_CLASS | TM_COMPOUND);
|
||||
isCustom = false;
|
||||
|
||||
// If this is the mapped version of java.lang.Class,
|
||||
// set the non-IDL names back to java.lang.Class...
|
||||
|
||||
if (isMappedJavaLangClass) {
|
||||
setNames(idJavaLangClass,IDL_CLASS_MODULE,IDL_CLASS);
|
||||
}
|
||||
}
|
||||
|
||||
//_____________________________________________________________________
|
||||
// Internal Interfaces
|
||||
//_____________________________________________________________________
|
||||
|
||||
/**
|
||||
* Initialize this instance.
|
||||
*/
|
||||
|
||||
private static boolean couldBeValue(ContextStack stack, ClassDefinition classDef) {
|
||||
|
||||
boolean result = false;
|
||||
ClassDeclaration classDecl = classDef.getClassDeclaration();
|
||||
BatchEnvironment env = stack.getEnv();
|
||||
|
||||
try {
|
||||
// Make sure it's not remote...
|
||||
|
||||
if (env.defRemote.implementedBy(env, classDecl)) {
|
||||
failedConstraint(10,false,stack,classDef.getName());
|
||||
} else {
|
||||
|
||||
// Make sure it's Serializable...
|
||||
|
||||
if (!env.defSerializable.implementedBy(env, classDecl)) {
|
||||
failedConstraint(11,false,stack,classDef.getName());
|
||||
} else {
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
} catch (ClassNotFound e) {
|
||||
classNotFound(stack,e);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize this instance.
|
||||
*/
|
||||
private boolean initialize (ContextStack stack, boolean quiet) {
|
||||
|
||||
ClassDefinition ourDef = getClassDefinition();
|
||||
ClassDeclaration ourDecl = getClassDeclaration();
|
||||
|
||||
try {
|
||||
|
||||
// Make sure our parentage is ok...
|
||||
|
||||
if (!initParents(stack)) {
|
||||
failedConstraint(12,quiet,stack,getQualifiedName());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// We're ok, so make up our collections...
|
||||
|
||||
Vector directInterfaces = new Vector();
|
||||
Vector directMethods = new Vector();
|
||||
Vector directMembers = new Vector();
|
||||
|
||||
// Get interfaces...
|
||||
|
||||
if (addNonRemoteInterfaces(directInterfaces,stack) != null) {
|
||||
|
||||
// Get methods...
|
||||
|
||||
if (addAllMethods(ourDef,directMethods,false,false,stack) != null) {
|
||||
|
||||
// Update parent class methods
|
||||
if (updateParentClassMethods(ourDef,directMethods,false,stack) != null) {
|
||||
|
||||
// Get constants and members...
|
||||
|
||||
if (addAllMembers(directMembers,false,false,stack)) {
|
||||
|
||||
// We're ok, so pass 'em up...
|
||||
|
||||
if (!initialize(directInterfaces,directMethods,directMembers,stack,quiet)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Is this class Externalizable?
|
||||
|
||||
boolean externalizable = false;
|
||||
if (!env.defExternalizable.implementedBy(env, ourDecl)) {
|
||||
|
||||
// No, so check to see if we have a serialPersistentField
|
||||
// that will modify the members.
|
||||
|
||||
if (!checkPersistentFields(getClassInstance(),quiet)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
|
||||
// Yes.
|
||||
|
||||
externalizable = true;
|
||||
}
|
||||
|
||||
// Should this class be considered "custom"? It is if
|
||||
// it is Externalizable OR if it has a method with the
|
||||
// following signature:
|
||||
//
|
||||
// private void writeObject(java.io.ObjectOutputStream out);
|
||||
//
|
||||
|
||||
if (externalizable) {
|
||||
isCustom = true;
|
||||
} else {
|
||||
for (MemberDefinition member = ourDef.getFirstMember();
|
||||
member != null;
|
||||
member = member.getNextMember()) {
|
||||
|
||||
if (member.isMethod() &&
|
||||
!member.isInitializer() &&
|
||||
member.isPrivate() &&
|
||||
member.getName().toString().equals("writeObject")) {
|
||||
|
||||
// Check return type, arguments and exceptions...
|
||||
|
||||
sun.tools.java.Type methodType = member.getType();
|
||||
sun.tools.java.Type rtnType = methodType.getReturnType();
|
||||
|
||||
if (rtnType == sun.tools.java.Type.tVoid) {
|
||||
|
||||
// Return type is correct. How about arguments?
|
||||
|
||||
sun.tools.java.Type[] args = methodType.getArgumentTypes();
|
||||
if (args.length == 1 &&
|
||||
args[0].getTypeSignature().equals("Ljava/io/ObjectOutputStream;")) {
|
||||
|
||||
// Arguments are correct, so it is a custom
|
||||
// value type...
|
||||
|
||||
isCustom = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (ClassNotFound e) {
|
||||
classNotFound(stack,e);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private boolean checkPersistentFields (Class clz, boolean quiet) {
|
||||
|
||||
// Do we have a writeObject method?
|
||||
|
||||
for (int i = 0; i < methods.length; i++) {
|
||||
if (methods[i].getName().equals("writeObject") &&
|
||||
methods[i].getArguments().length == 1) {
|
||||
|
||||
Type returnType = methods[i].getReturnType();
|
||||
Type arg = methods[i].getArguments()[0];
|
||||
String id = arg.getQualifiedName();
|
||||
|
||||
if (returnType.isType(TYPE_VOID) &&
|
||||
id.equals("java.io.ObjectOutputStream")) {
|
||||
|
||||
// Got one, so there's nothing to do...
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Do we have a valid serialPersistentField array?
|
||||
|
||||
MemberDefinition spfDef = null;
|
||||
|
||||
for (int i = 0; i < members.length; i++) {
|
||||
if (members[i].getName().equals("serialPersistentFields")) {
|
||||
|
||||
Member member = members[i];
|
||||
Type type = member.getType();
|
||||
Type elementType = type.getElementType();
|
||||
|
||||
// We have a member with the correct name. Make sure
|
||||
// we have the correct signature...
|
||||
|
||||
if (elementType != null &&
|
||||
elementType.getQualifiedName().equals(
|
||||
"java.io.ObjectStreamField")
|
||||
) {
|
||||
|
||||
if (member.isStatic() &&
|
||||
member.isFinal() &&
|
||||
member.isPrivate()) {
|
||||
|
||||
// We have the correct signature
|
||||
|
||||
spfDef = member.getMemberDefinition();
|
||||
|
||||
} else {
|
||||
|
||||
// Bad signature...
|
||||
|
||||
failedConstraint(4,quiet,stack,getQualifiedName());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we do not have a serialPersistentField,
|
||||
// there's nothing to do, so return with no error...
|
||||
|
||||
if (spfDef == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Ok, now we must examine the contents of the array -
|
||||
// then validate them...
|
||||
|
||||
Hashtable fields = getPersistentFields(clz);
|
||||
boolean result = true;
|
||||
|
||||
for (int i = 0; i < members.length; i++) {
|
||||
String fieldName = members[i].getName();
|
||||
String fieldType = members[i].getType().getSignature();
|
||||
|
||||
// Is this field present in the array?
|
||||
|
||||
String type = (String) fields.get(fieldName);
|
||||
|
||||
if (type == null) {
|
||||
|
||||
// No, so mark it transient...
|
||||
|
||||
members[i].setTransient();
|
||||
|
||||
} else {
|
||||
|
||||
// Yes, does the type match?
|
||||
|
||||
if (type.equals(fieldType)) {
|
||||
|
||||
// Yes, so remove it from the fields table...
|
||||
|
||||
fields.remove(fieldName);
|
||||
|
||||
} else {
|
||||
|
||||
// No, so error...
|
||||
|
||||
result = false;
|
||||
failedConstraint(2,quiet,stack,fieldName,getQualifiedName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ok, we've checked all of our fields. Are there any left in the "array"?
|
||||
// If so, it's an error...
|
||||
|
||||
if (result && fields.size() > 0) {
|
||||
|
||||
result = false;
|
||||
failedConstraint(9,quiet,stack,getQualifiedName());
|
||||
}
|
||||
|
||||
// Return result...
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the names and types of all the persistent fields of a Class.
|
||||
*/
|
||||
private Hashtable getPersistentFields (Class clz) {
|
||||
Hashtable result = new Hashtable();
|
||||
ObjectStreamClass osc = ObjectStreamClass.lookup(clz);
|
||||
if (osc != null) {
|
||||
ObjectStreamField[] fields = osc.getFields();
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
String typeSig;
|
||||
String typePrefix = String.valueOf(fields[i].getTypeCode());
|
||||
if (fields[i].isPrimitive()) {
|
||||
typeSig = typePrefix;
|
||||
} else {
|
||||
if (fields[i].getTypeCode() == '[') {
|
||||
typePrefix = "";
|
||||
}
|
||||
typeSig = typePrefix + fields[i].getType().getName().replace('.','/');
|
||||
if (typeSig.endsWith(";")) {
|
||||
typeSig = typeSig.substring(0,typeSig.length()-1);
|
||||
}
|
||||
}
|
||||
result.put(fields[i].getName(),typeSig);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
145
jdkSrc/jdk8/sun/rmi/rmic/newrmic/BatchEnvironment.java
Normal file
145
jdkSrc/jdk8/sun/rmi/rmic/newrmic/BatchEnvironment.java
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.rmi.rmic.newrmic;
|
||||
|
||||
import com.sun.javadoc.ClassDoc;
|
||||
import com.sun.javadoc.RootDoc;
|
||||
import java.io.File;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static sun.rmi.rmic.newrmic.Constants.*;
|
||||
|
||||
/**
|
||||
* The environment for an rmic compilation batch.
|
||||
*
|
||||
* A BatchEnvironment contains a RootDoc, which is the entry point
|
||||
* into the doclet environment for the associated rmic compilation
|
||||
* batch. A BatchEnvironment collects the source files generated
|
||||
* during the batch's execution, for eventual source code compilation
|
||||
* and, possibly, deletion. Errors that occur during generation
|
||||
* activity should be reported through the BatchEnvironment's "error"
|
||||
* method.
|
||||
*
|
||||
* A protocol-specific generator class may require the use of a
|
||||
* particular BatchEnvironment subclass for enhanced environment
|
||||
* functionality. A BatchEnvironment subclass must declare a
|
||||
* public constructor with one parameter of type RootDoc.
|
||||
*
|
||||
* 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 BatchEnvironment {
|
||||
|
||||
private final RootDoc rootDoc;
|
||||
|
||||
/** cached ClassDoc for certain types used by rmic */
|
||||
private final ClassDoc docRemote;
|
||||
private final ClassDoc docException;
|
||||
private final ClassDoc docRemoteException;
|
||||
private final ClassDoc docRuntimeException;
|
||||
|
||||
private boolean verbose = false;
|
||||
private final List<File> generatedFiles = new ArrayList<File>();
|
||||
|
||||
/**
|
||||
* Creates a new BatchEnvironment with the specified RootDoc.
|
||||
**/
|
||||
public BatchEnvironment(RootDoc rootDoc) {
|
||||
this.rootDoc = rootDoc;
|
||||
|
||||
/*
|
||||
* Initialize cached ClassDoc for types used by rmic. Note
|
||||
* that any of these could be null if the boot class path is
|
||||
* incorrect, which could cause a NullPointerException later.
|
||||
*/
|
||||
docRemote = rootDoc().classNamed(REMOTE);
|
||||
docException = rootDoc().classNamed(EXCEPTION);
|
||||
docRemoteException = rootDoc().classNamed(REMOTE_EXCEPTION);
|
||||
docRuntimeException = rootDoc().classNamed(RUNTIME_EXCEPTION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the RootDoc for this environment.
|
||||
**/
|
||||
public RootDoc rootDoc() {
|
||||
return rootDoc;
|
||||
}
|
||||
|
||||
public ClassDoc docRemote() { return docRemote; }
|
||||
public ClassDoc docException() { return docException; }
|
||||
public ClassDoc docRemoteException() { return docRemoteException; }
|
||||
public ClassDoc docRuntimeException() { return docRuntimeException; }
|
||||
|
||||
/**
|
||||
* Sets this environment's verbosity status.
|
||||
**/
|
||||
public void setVerbose(boolean verbose) {
|
||||
this.verbose = verbose;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this environment's verbosity status.
|
||||
**/
|
||||
public boolean verbose() {
|
||||
return verbose;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the specified file to the list of source files generated
|
||||
* during this batch.
|
||||
**/
|
||||
public void addGeneratedFile(File file) {
|
||||
generatedFiles.add(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of files generated during this batch.
|
||||
**/
|
||||
public List<File> generatedFiles() {
|
||||
return Collections.unmodifiableList(generatedFiles);
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs the specified (non-error) message.
|
||||
**/
|
||||
public void output(String msg) {
|
||||
rootDoc.printNotice(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports an error using the specified resource key and text
|
||||
* formatting arguments.
|
||||
**/
|
||||
public void error(String key, String... args) {
|
||||
rootDoc.printError(Resources.getText(key, args));
|
||||
}
|
||||
}
|
||||
48
jdkSrc/jdk8/sun/rmi/rmic/newrmic/Constants.java
Normal file
48
jdkSrc/jdk8/sun/rmi/rmic/newrmic/Constants.java
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.rmi.rmic.newrmic;
|
||||
|
||||
/**
|
||||
* Constants potentially useful to all rmic generators.
|
||||
*
|
||||
* 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 final class Constants {
|
||||
|
||||
private Constants() { throw new AssertionError(); }
|
||||
|
||||
/*
|
||||
* fully-qualified names of types used by rmic
|
||||
*/
|
||||
public static final String REMOTE = "java.rmi.Remote";
|
||||
public static final String EXCEPTION = "java.lang.Exception";
|
||||
public static final String REMOTE_EXCEPTION = "java.rmi.RemoteException";
|
||||
public static final String RUNTIME_EXCEPTION = "java.lang.RuntimeException";
|
||||
}
|
||||
87
jdkSrc/jdk8/sun/rmi/rmic/newrmic/Generator.java
Normal file
87
jdkSrc/jdk8/sun/rmi/rmic/newrmic/Generator.java
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.rmi.rmic.newrmic;
|
||||
|
||||
import com.sun.javadoc.ClassDoc;
|
||||
import java.io.File;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* The interface to rmic back end implementations. Classes that
|
||||
* implement this interface correspond to the various generation modes
|
||||
* of rmic (JRMP, IIOP, IDL, etc.).
|
||||
*
|
||||
* A Generator instance corresponds to a particular rmic compilation
|
||||
* batch, and its instance state represents the generator-specific
|
||||
* command line options for that batch. Main will instantiate a
|
||||
* generator class when the command line arguments indicate selection
|
||||
* of the corresponding generation mode. Main will then invoke the
|
||||
* "parseArgs" method to allow the generator to process any
|
||||
* generator-specific command line options and set its instance state
|
||||
* accordingly.
|
||||
*
|
||||
* 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 interface Generator {
|
||||
|
||||
/**
|
||||
* Processes the command line options specific to this generator.
|
||||
* Processed options are set to null in the specified array.
|
||||
* Returns true if successful or false if an error occurs. Errors
|
||||
* are output to the specific Main instance.
|
||||
**/
|
||||
public boolean parseArgs(String[] args, Main main);
|
||||
|
||||
/**
|
||||
* Returns the most specific environment class required by this
|
||||
* generator.
|
||||
**/
|
||||
public Class<? extends BatchEnvironment> envClass();
|
||||
|
||||
/**
|
||||
* Returns the names of the classes that must be available through
|
||||
* the doclet API in order for this generator to function.
|
||||
**/
|
||||
public Set<String> bootstrapClassNames();
|
||||
|
||||
/**
|
||||
* Generates the protocol-specific rmic output files for the
|
||||
* specified remote class. This method is invoked once for each
|
||||
* class or interface specified on the command line for the rmic
|
||||
* compilation batch associated with this instance.
|
||||
*
|
||||
* Any generated source files (to be compiled with javac) are
|
||||
* passed to the addGeneratedFile method of the specified
|
||||
* BatchEnvironment.
|
||||
**/
|
||||
public void generate(BatchEnvironment env,
|
||||
ClassDoc inputClass,
|
||||
File destDir);
|
||||
}
|
||||
291
jdkSrc/jdk8/sun/rmi/rmic/newrmic/IndentingWriter.java
Normal file
291
jdkSrc/jdk8/sun/rmi/rmic/newrmic/IndentingWriter.java
Normal file
@@ -0,0 +1,291 @@
|
||||
/*
|
||||
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.rmi.rmic.newrmic;
|
||||
|
||||
import java.io.Writer;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* A BufferedWriter that supports automatic indentation of lines of
|
||||
* text written to the underlying Writer.
|
||||
*
|
||||
* Methods are provided for compact/convenient indenting in and out,
|
||||
* writing text, and writing lines of text in various combinations.
|
||||
*
|
||||
* 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 IndentingWriter extends BufferedWriter {
|
||||
|
||||
/** number of spaces to change indent when indenting in or out */
|
||||
private final int indentStep;
|
||||
|
||||
/** number of spaces to convert into tabs (use MAX_VALUE to disable) */
|
||||
private final int tabSize;
|
||||
|
||||
/** true if the next character written is the first on a line */
|
||||
private boolean beginningOfLine = true;
|
||||
|
||||
/** current number of spaces to prepend to lines */
|
||||
private int currentIndent = 0;
|
||||
|
||||
/**
|
||||
* Creates a new IndentingWriter that writes indented text to the
|
||||
* given Writer. Use the default indent step of four spaces.
|
||||
**/
|
||||
public IndentingWriter(Writer out) {
|
||||
this(out, 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new IndentingWriter that writes indented text to the
|
||||
* given Writer and uses the supplied indent step.
|
||||
**/
|
||||
public IndentingWriter(Writer out, int indentStep) {
|
||||
this(out, indentStep, 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new IndentingWriter that writes indented text to the
|
||||
* given Writer and uses the supplied indent step and tab size.
|
||||
**/
|
||||
public IndentingWriter(Writer out, int indentStep, int tabSize) {
|
||||
super(out);
|
||||
if (indentStep < 0) {
|
||||
throw new IllegalArgumentException("negative indent step");
|
||||
}
|
||||
if (tabSize < 0) {
|
||||
throw new IllegalArgumentException("negative tab size");
|
||||
}
|
||||
this.indentStep = indentStep;
|
||||
this.tabSize = tabSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a single character.
|
||||
**/
|
||||
public void write(int c) throws IOException {
|
||||
checkWrite();
|
||||
super.write(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a portion of an array of characters.
|
||||
**/
|
||||
public void write(char[] cbuf, int off, int len) throws IOException {
|
||||
if (len > 0) {
|
||||
checkWrite();
|
||||
}
|
||||
super.write(cbuf, off, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a portion of a String.
|
||||
**/
|
||||
public void write(String s, int off, int len) throws IOException {
|
||||
if (len > 0) {
|
||||
checkWrite();
|
||||
}
|
||||
super.write(s, off, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a line separator. The next character written will be
|
||||
* preceded by an indent.
|
||||
**/
|
||||
public void newLine() throws IOException {
|
||||
super.newLine();
|
||||
beginningOfLine = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an indent needs to be written before writing the next
|
||||
* character.
|
||||
*
|
||||
* The indent generation is optimized (and made consistent with
|
||||
* certain coding conventions) by condensing groups of eight
|
||||
* spaces into tab characters.
|
||||
**/
|
||||
protected void checkWrite() throws IOException {
|
||||
if (beginningOfLine) {
|
||||
beginningOfLine = false;
|
||||
int i = currentIndent;
|
||||
while (i >= tabSize) {
|
||||
super.write('\t');
|
||||
i -= tabSize;
|
||||
}
|
||||
while (i > 0) {
|
||||
super.write(' ');
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Increases the current indent by the indent step.
|
||||
**/
|
||||
protected void indentIn() {
|
||||
currentIndent += indentStep;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decreases the current indent by the indent step.
|
||||
**/
|
||||
protected void indentOut() {
|
||||
currentIndent -= indentStep;
|
||||
if (currentIndent < 0)
|
||||
currentIndent = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indents in.
|
||||
**/
|
||||
public void pI() {
|
||||
indentIn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indents out.
|
||||
**/
|
||||
public void pO() {
|
||||
indentOut();
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes string.
|
||||
**/
|
||||
public void p(String s) throws IOException {
|
||||
write(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends current line.
|
||||
**/
|
||||
public void pln() throws IOException {
|
||||
newLine();
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes string; ends current line.
|
||||
**/
|
||||
public void pln(String s) throws IOException {
|
||||
p(s);
|
||||
pln();
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes string; ends current line; indents in.
|
||||
**/
|
||||
public void plnI(String s) throws IOException {
|
||||
p(s);
|
||||
pln();
|
||||
pI();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indents out; writes string.
|
||||
**/
|
||||
public void pO(String s) throws IOException {
|
||||
pO();
|
||||
p(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indents out; writes string; ends current line.
|
||||
**/
|
||||
public void pOln(String s) throws IOException {
|
||||
pO(s);
|
||||
pln();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indents out; writes string; ends current line; indents in.
|
||||
*
|
||||
* This method is useful for generating lines of code that both
|
||||
* end and begin nested blocks, like "} else {".
|
||||
**/
|
||||
public void pOlnI(String s) throws IOException {
|
||||
pO(s);
|
||||
pln();
|
||||
pI();
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes object.
|
||||
**/
|
||||
public void p(Object o) throws IOException {
|
||||
write(o.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes object; ends current line.
|
||||
**/
|
||||
public void pln(Object o) throws IOException {
|
||||
p(o.toString());
|
||||
pln();
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes object; ends current line; indents in.
|
||||
**/
|
||||
public void plnI(Object o) throws IOException {
|
||||
p(o.toString());
|
||||
pln();
|
||||
pI();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indents out; writes object.
|
||||
**/
|
||||
public void pO(Object o) throws IOException {
|
||||
pO();
|
||||
p(o.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Indents out; writes object; ends current line.
|
||||
**/
|
||||
public void pOln(Object o) throws IOException {
|
||||
pO(o.toString());
|
||||
pln();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indents out; writes object; ends current line; indents in.
|
||||
*
|
||||
* This method is useful for generating lines of code that both
|
||||
* end and begin nested blocks, like "} else {".
|
||||
**/
|
||||
public void pOlnI(Object o) throws IOException {
|
||||
pO(o.toString());
|
||||
pln();
|
||||
pI();
|
||||
}
|
||||
}
|
||||
689
jdkSrc/jdk8/sun/rmi/rmic/newrmic/Main.java
Normal file
689
jdkSrc/jdk8/sun/rmi/rmic/newrmic/Main.java
Normal file
@@ -0,0 +1,689 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.rmi.rmic.newrmic;
|
||||
|
||||
import com.sun.javadoc.ClassDoc;
|
||||
import com.sun.javadoc.RootDoc;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import sun.rmi.rmic.newrmic.jrmp.JrmpGenerator;
|
||||
import sun.tools.util.CommandLine;
|
||||
|
||||
/**
|
||||
* The rmic front end. This class contains the "main" method for rmic
|
||||
* command line invocation.
|
||||
*
|
||||
* A Main instance contains the stream to output error messages and
|
||||
* other diagnostics to.
|
||||
*
|
||||
* An rmic compilation batch (for example, one rmic command line
|
||||
* invocation) is executed by invoking the "compile" method of a Main
|
||||
* instance.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* NOTE: If and when there is a J2SE API for invoking SDK tools, this
|
||||
* class should be updated to support that API.
|
||||
*
|
||||
* NOTE: This class is the front end for a "new" rmic implementation,
|
||||
* which uses javadoc and the doclet API for reading class files and
|
||||
* javac for compiling generated source files. This implementation is
|
||||
* incomplete: it lacks any CORBA-based back end implementations, and
|
||||
* thus the command line options "-idl", "-iiop", and their related
|
||||
* options are not yet supported. The front end for the "old",
|
||||
* oldjavac-based rmic implementation is sun.rmi.rmic.Main.
|
||||
*
|
||||
* @author Peter Jones
|
||||
**/
|
||||
public class Main {
|
||||
|
||||
/*
|
||||
* Implementation note:
|
||||
*
|
||||
* In order to use the doclet API to read class files, much of
|
||||
* this implementation of rmic executes as a doclet within an
|
||||
* invocation of javadoc. This class is used as the doclet class
|
||||
* for such javadoc invocations, via its static "start" and
|
||||
* "optionLength" methods. There is one javadoc invocation per
|
||||
* rmic compilation batch.
|
||||
*
|
||||
* The only guaranteed way to pass data to a doclet through a
|
||||
* javadoc invocation is through doclet-specific options on the
|
||||
* javadoc "command line". Rather than passing numerous pieces of
|
||||
* individual data in string form as javadoc options, we use a
|
||||
* single doclet-specific option ("-batchID") to pass a numeric
|
||||
* identifier that uniquely identifies the rmic compilation batch
|
||||
* that the javadoc invocation is for, and that identifier can
|
||||
* then be used as a key in a global table to retrieve an object
|
||||
* containing all of batch-specific data (rmic command line
|
||||
* arguments, etc.).
|
||||
*/
|
||||
|
||||
/** guards "batchCount" */
|
||||
private static final Object batchCountLock = new Object();
|
||||
|
||||
/** number of batches run; used to generated batch IDs */
|
||||
private static long batchCount = 0;
|
||||
|
||||
/** maps batch ID to batch data */
|
||||
private static final Map<Long,Batch> batchTable =
|
||||
Collections.synchronizedMap(new HashMap<Long,Batch>());
|
||||
|
||||
/** stream to output error messages and other diagnostics to */
|
||||
private final PrintStream out;
|
||||
|
||||
/** name of this program, to use in error messages */
|
||||
private final String program;
|
||||
|
||||
/**
|
||||
* Command line entry point.
|
||||
**/
|
||||
public static void main(String[] args) {
|
||||
Main rmic = new Main(System.err, "rmic");
|
||||
System.exit(rmic.compile(args) ? 0 : 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Main instance that writes output to the specified
|
||||
* stream. The specified program name is used in error messages.
|
||||
**/
|
||||
public Main(OutputStream out, String program) {
|
||||
this.out = out instanceof PrintStream ?
|
||||
(PrintStream) out : new PrintStream(out);
|
||||
this.program = program;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles a batch of input classes, as given by the specified
|
||||
* command line arguments. Protocol-specific generators are
|
||||
* determined by the choice options on the command line. Returns
|
||||
* true if successful, or false if an error occurred.
|
||||
*
|
||||
* NOTE: This method is retained for transitional consistency with
|
||||
* previous implementations.
|
||||
**/
|
||||
public boolean compile(String[] args) {
|
||||
long startTime = System.currentTimeMillis();
|
||||
|
||||
long batchID;
|
||||
synchronized (batchCountLock) {
|
||||
batchID = batchCount++; // assign batch ID
|
||||
}
|
||||
|
||||
// process command line
|
||||
Batch batch = parseArgs(args);
|
||||
if (batch == null) {
|
||||
return false; // terminate if error occurred
|
||||
}
|
||||
|
||||
/*
|
||||
* With the batch data retrievable in the global table, run
|
||||
* javadoc to continue the rest of the batch's compliation as
|
||||
* a doclet.
|
||||
*/
|
||||
boolean status;
|
||||
try {
|
||||
batchTable.put(batchID, batch);
|
||||
status = invokeJavadoc(batch, batchID);
|
||||
} finally {
|
||||
batchTable.remove(batchID);
|
||||
}
|
||||
|
||||
if (batch.verbose) {
|
||||
long deltaTime = System.currentTimeMillis() - startTime;
|
||||
output(Resources.getText("rmic.done_in",
|
||||
Long.toString(deltaTime)));
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the specified string to the output stream of this Main
|
||||
* instance.
|
||||
**/
|
||||
public void output(String msg) {
|
||||
out.println(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints an error message to the output stream of this Main
|
||||
* instance. The first argument is used as a key in rmic's
|
||||
* resource bundle, and the rest of the arguments are used as
|
||||
* arguments in the formatting of the resource string.
|
||||
**/
|
||||
public void error(String msg, String... args) {
|
||||
output(Resources.getText(msg, args));
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints rmic's usage message to the output stream of this Main
|
||||
* instance.
|
||||
*
|
||||
* This method is public so that it can be used by the "parseArgs"
|
||||
* methods of Generator implementations.
|
||||
**/
|
||||
public void usage() {
|
||||
error("rmic.usage", program);
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes rmic command line arguments. Returns a Batch object
|
||||
* representing the command line arguments if successful, or null
|
||||
* if an error occurred. Processed elements of the args array are
|
||||
* set to null.
|
||||
**/
|
||||
private Batch parseArgs(String[] args) {
|
||||
Batch batch = new Batch();
|
||||
|
||||
/*
|
||||
* Pre-process command line for @file arguments.
|
||||
*/
|
||||
try {
|
||||
args = CommandLine.parse(args);
|
||||
} catch (FileNotFoundException e) {
|
||||
error("rmic.cant.read", e.getMessage());
|
||||
return null;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace(out);
|
||||
return null;
|
||||
}
|
||||
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
|
||||
if (args[i] == null) {
|
||||
// already processed by a generator
|
||||
continue;
|
||||
|
||||
} else if (args[i].equals("-Xnew")) {
|
||||
// we're already using the "new" implementation
|
||||
args[i] = null;
|
||||
|
||||
} else if (args[i].equals("-show")) {
|
||||
// obselete: fail
|
||||
error("rmic.option.unsupported", args[i]);
|
||||
usage();
|
||||
return null;
|
||||
|
||||
} else if (args[i].equals("-O")) {
|
||||
// obselete: warn but tolerate
|
||||
error("rmic.option.unsupported", args[i]);
|
||||
args[i] = null;
|
||||
|
||||
} else if (args[i].equals("-debug")) {
|
||||
// obselete: warn but tolerate
|
||||
error("rmic.option.unsupported", args[i]);
|
||||
args[i] = null;
|
||||
|
||||
} else if (args[i].equals("-depend")) {
|
||||
// obselete: warn but tolerate
|
||||
// REMIND: should this fail instead?
|
||||
error("rmic.option.unsupported", args[i]);
|
||||
args[i] = null;
|
||||
|
||||
} else if (args[i].equals("-keep") ||
|
||||
args[i].equals("-keepgenerated"))
|
||||
{
|
||||
batch.keepGenerated = true;
|
||||
args[i] = null;
|
||||
|
||||
} else if (args[i].equals("-g")) {
|
||||
batch.debug = true;
|
||||
args[i] = null;
|
||||
|
||||
} else if (args[i].equals("-nowarn")) {
|
||||
batch.noWarn = true;
|
||||
args[i] = null;
|
||||
|
||||
} else if (args[i].equals("-nowrite")) {
|
||||
batch.noWrite = true;
|
||||
args[i] = null;
|
||||
|
||||
} else if (args[i].equals("-verbose")) {
|
||||
batch.verbose = true;
|
||||
args[i] = null;
|
||||
|
||||
} else if (args[i].equals("-Xnocompile")) {
|
||||
batch.noCompile = true;
|
||||
batch.keepGenerated = true;
|
||||
args[i] = null;
|
||||
|
||||
} else if (args[i].equals("-bootclasspath")) {
|
||||
if ((i + 1) >= args.length) {
|
||||
error("rmic.option.requires.argument", args[i]);
|
||||
usage();
|
||||
return null;
|
||||
}
|
||||
if (batch.bootClassPath != null) {
|
||||
error("rmic.option.already.seen", args[i]);
|
||||
usage();
|
||||
return null;
|
||||
}
|
||||
args[i] = null;
|
||||
batch.bootClassPath = args[++i];
|
||||
assert batch.bootClassPath != null;
|
||||
args[i] = null;
|
||||
|
||||
} else if (args[i].equals("-extdirs")) {
|
||||
if ((i + 1) >= args.length) {
|
||||
error("rmic.option.requires.argument", args[i]);
|
||||
usage();
|
||||
return null;
|
||||
}
|
||||
if (batch.extDirs != null) {
|
||||
error("rmic.option.already.seen", args[i]);
|
||||
usage();
|
||||
return null;
|
||||
}
|
||||
args[i] = null;
|
||||
batch.extDirs = args[++i];
|
||||
assert batch.extDirs != null;
|
||||
args[i] = null;
|
||||
|
||||
} else if (args[i].equals("-classpath")) {
|
||||
if ((i + 1) >= args.length) {
|
||||
error("rmic.option.requires.argument", args[i]);
|
||||
usage();
|
||||
return null;
|
||||
}
|
||||
if (batch.classPath != null) {
|
||||
error("rmic.option.already.seen", args[i]);
|
||||
usage();
|
||||
return null;
|
||||
}
|
||||
args[i] = null;
|
||||
batch.classPath = args[++i];
|
||||
assert batch.classPath != null;
|
||||
args[i] = null;
|
||||
|
||||
} else if (args[i].equals("-d")) {
|
||||
if ((i + 1) >= args.length) {
|
||||
error("rmic.option.requires.argument", args[i]);
|
||||
usage();
|
||||
return null;
|
||||
}
|
||||
if (batch.destDir != null) {
|
||||
error("rmic.option.already.seen", args[i]);
|
||||
usage();
|
||||
return null;
|
||||
}
|
||||
args[i] = null;
|
||||
batch.destDir = new File(args[++i]);
|
||||
assert batch.destDir != null;
|
||||
args[i] = null;
|
||||
if (!batch.destDir.exists()) {
|
||||
error("rmic.no.such.directory", batch.destDir.getPath());
|
||||
usage();
|
||||
return null;
|
||||
}
|
||||
|
||||
} else if (args[i].equals("-v1.1") ||
|
||||
args[i].equals("-vcompat") ||
|
||||
args[i].equals("-v1.2"))
|
||||
{
|
||||
Generator gen = new JrmpGenerator();
|
||||
batch.generators.add(gen);
|
||||
// JrmpGenerator only requires base BatchEnvironment class
|
||||
if (!gen.parseArgs(args, this)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
} else if (args[i].equalsIgnoreCase("-iiop")) {
|
||||
error("rmic.option.unimplemented", args[i]);
|
||||
return null;
|
||||
|
||||
// Generator gen = new IiopGenerator();
|
||||
// batch.generators.add(gen);
|
||||
// if (!batch.envClass.isAssignableFrom(gen.envClass())) {
|
||||
// error("rmic.cannot.use.both",
|
||||
// batch.envClass.getName(), gen.envClass().getName());
|
||||
// return null;
|
||||
// }
|
||||
// batch.envClass = gen.envClass();
|
||||
// if (!gen.parseArgs(args, this)) {
|
||||
// return null;
|
||||
// }
|
||||
|
||||
} else if (args[i].equalsIgnoreCase("-idl")) {
|
||||
error("rmic.option.unimplemented", args[i]);
|
||||
return null;
|
||||
|
||||
// see implementation sketch above
|
||||
|
||||
} else if (args[i].equalsIgnoreCase("-xprint")) {
|
||||
error("rmic.option.unimplemented", args[i]);
|
||||
return null;
|
||||
|
||||
// see implementation sketch above
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* At this point, all that remains non-null in the args
|
||||
* array are input class names or illegal options.
|
||||
*/
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if (args[i] != null) {
|
||||
if (args[i].startsWith("-")) {
|
||||
error("rmic.no.such.option", args[i]);
|
||||
usage();
|
||||
return null;
|
||||
} else {
|
||||
batch.classes.add(args[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (batch.classes.isEmpty()) {
|
||||
usage();
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* If options did not specify at least one protocol-specific
|
||||
* generator, then JRMP is the default.
|
||||
*/
|
||||
if (batch.generators.isEmpty()) {
|
||||
batch.generators.add(new JrmpGenerator());
|
||||
}
|
||||
return batch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Doclet class entry point.
|
||||
**/
|
||||
public static boolean start(RootDoc rootDoc) {
|
||||
|
||||
/*
|
||||
* Find batch ID among javadoc options, and retrieve
|
||||
* corresponding batch data from global table.
|
||||
*/
|
||||
long batchID = -1;
|
||||
for (String[] option : rootDoc.options()) {
|
||||
if (option[0].equals("-batchID")) {
|
||||
try {
|
||||
batchID = Long.parseLong(option[1]);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Batch batch = batchTable.get(batchID);
|
||||
assert batch != null;
|
||||
|
||||
/*
|
||||
* Construct batch environment using class agreed upon by
|
||||
* generator implementations.
|
||||
*/
|
||||
BatchEnvironment env;
|
||||
try {
|
||||
Constructor<? extends BatchEnvironment> cons =
|
||||
batch.envClass.getConstructor(new Class<?>[] { RootDoc.class });
|
||||
env = cons.newInstance(rootDoc);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new AssertionError(e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new AssertionError(e);
|
||||
} catch (InstantiationException e) {
|
||||
throw new AssertionError(e);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
|
||||
env.setVerbose(batch.verbose);
|
||||
|
||||
/*
|
||||
* Determine the destination directory (the top of the package
|
||||
* hierarchy) for the output of this batch; if no destination
|
||||
* directory was specified on the command line, then the
|
||||
* default is the current working directory.
|
||||
*/
|
||||
File destDir = batch.destDir;
|
||||
if (destDir == null) {
|
||||
destDir = new File(System.getProperty("user.dir"));
|
||||
}
|
||||
|
||||
/*
|
||||
* Run each input class through each generator.
|
||||
*/
|
||||
for (String inputClassName : batch.classes) {
|
||||
ClassDoc inputClass = rootDoc.classNamed(inputClassName);
|
||||
try {
|
||||
for (Generator gen : batch.generators) {
|
||||
gen.generate(env, inputClass, destDir);
|
||||
}
|
||||
} catch (NullPointerException e) {
|
||||
/*
|
||||
* We assume that this means that some class that was
|
||||
* needed (perhaps even a bootstrap class) was not
|
||||
* found, and that javadoc has already reported this
|
||||
* as an error. There is nothing for us to do here
|
||||
* but try to continue with the next input class.
|
||||
*
|
||||
* REMIND: More explicit error checking throughout
|
||||
* would be preferable, however.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Compile any generated source files, if configured to do so.
|
||||
*/
|
||||
boolean status = true;
|
||||
List<File> generatedFiles = env.generatedFiles();
|
||||
if (!batch.noCompile && !batch.noWrite && !generatedFiles.isEmpty()) {
|
||||
status = batch.enclosingMain().invokeJavac(batch, generatedFiles);
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete any generated source files, if configured to do so.
|
||||
*/
|
||||
if (!batch.keepGenerated) {
|
||||
for (File file : generatedFiles) {
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Doclet class method that indicates that this doclet class
|
||||
* recognizes (only) the "-batchID" option on the javadoc command
|
||||
* line, and that the "-batchID" option comprises two arguments on
|
||||
* the javadoc command line.
|
||||
**/
|
||||
public static int optionLength(String option) {
|
||||
if (option.equals("-batchID")) {
|
||||
return 2;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the javadoc tool to invoke this class as a doclet, passing
|
||||
* command line options derived from the specified batch data and
|
||||
* indicating the specified batch ID.
|
||||
*
|
||||
* NOTE: This method currently uses a J2SE-internal API to run
|
||||
* javadoc. If and when there is a J2SE API for invoking SDK
|
||||
* tools, this method should be updated to use that API instead.
|
||||
**/
|
||||
private boolean invokeJavadoc(Batch batch, long batchID) {
|
||||
List<String> javadocArgs = new ArrayList<String>();
|
||||
|
||||
// include all types, regardless of language-level access
|
||||
javadocArgs.add("-private");
|
||||
|
||||
// inputs are class names, not source files
|
||||
javadocArgs.add("-Xclasses");
|
||||
|
||||
// reproduce relevant options from rmic invocation
|
||||
if (batch.verbose) {
|
||||
javadocArgs.add("-verbose");
|
||||
}
|
||||
if (batch.bootClassPath != null) {
|
||||
javadocArgs.add("-bootclasspath");
|
||||
javadocArgs.add(batch.bootClassPath);
|
||||
}
|
||||
if (batch.extDirs != null) {
|
||||
javadocArgs.add("-extdirs");
|
||||
javadocArgs.add(batch.extDirs);
|
||||
}
|
||||
if (batch.classPath != null) {
|
||||
javadocArgs.add("-classpath");
|
||||
javadocArgs.add(batch.classPath);
|
||||
}
|
||||
|
||||
// specify batch ID
|
||||
javadocArgs.add("-batchID");
|
||||
javadocArgs.add(Long.toString(batchID));
|
||||
|
||||
/*
|
||||
* Run javadoc on union of rmic input classes and all
|
||||
* generators' bootstrap classes, so that they will all be
|
||||
* available to the doclet code.
|
||||
*/
|
||||
Set<String> classNames = new HashSet<String>();
|
||||
for (Generator gen : batch.generators) {
|
||||
classNames.addAll(gen.bootstrapClassNames());
|
||||
}
|
||||
classNames.addAll(batch.classes);
|
||||
for (String s : classNames) {
|
||||
javadocArgs.add(s);
|
||||
}
|
||||
|
||||
// run javadoc with our program name and output stream
|
||||
int status = com.sun.tools.javadoc.Main.execute(
|
||||
program,
|
||||
new PrintWriter(out, true),
|
||||
new PrintWriter(out, true),
|
||||
new PrintWriter(out, true),
|
||||
this.getClass().getName(), // doclet class is this class
|
||||
javadocArgs.toArray(new String[javadocArgs.size()]));
|
||||
return status == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the javac tool to compile the specified source files,
|
||||
* passing command line options derived from the specified batch
|
||||
* data.
|
||||
*
|
||||
* NOTE: This method currently uses a J2SE-internal API to run
|
||||
* javac. If and when there is a J2SE API for invoking SDK tools,
|
||||
* this method should be updated to use that API instead.
|
||||
**/
|
||||
private boolean invokeJavac(Batch batch, List<File> files) {
|
||||
List<String> javacArgs = new ArrayList<String>();
|
||||
|
||||
// rmic never wants to display javac warnings
|
||||
javacArgs.add("-nowarn");
|
||||
|
||||
// reproduce relevant options from rmic invocation
|
||||
if (batch.debug) {
|
||||
javacArgs.add("-g");
|
||||
}
|
||||
if (batch.verbose) {
|
||||
javacArgs.add("-verbose");
|
||||
}
|
||||
if (batch.bootClassPath != null) {
|
||||
javacArgs.add("-bootclasspath");
|
||||
javacArgs.add(batch.bootClassPath);
|
||||
}
|
||||
if (batch.extDirs != null) {
|
||||
javacArgs.add("-extdirs");
|
||||
javacArgs.add(batch.extDirs);
|
||||
}
|
||||
if (batch.classPath != null) {
|
||||
javacArgs.add("-classpath");
|
||||
javacArgs.add(batch.classPath);
|
||||
}
|
||||
|
||||
/*
|
||||
* For now, rmic still always produces class files that have a
|
||||
* class file format version compatible with JDK 1.1.
|
||||
*/
|
||||
javacArgs.add("-source");
|
||||
javacArgs.add("1.3");
|
||||
javacArgs.add("-target");
|
||||
javacArgs.add("1.1");
|
||||
|
||||
// add source files to compile
|
||||
for (File file : files) {
|
||||
javacArgs.add(file.getPath());
|
||||
}
|
||||
|
||||
// run javac with our output stream
|
||||
int status = com.sun.tools.javac.Main.compile(
|
||||
javacArgs.toArray(new String[javacArgs.size()]),
|
||||
new PrintWriter(out, true));
|
||||
return status == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* The data for an rmic compliation batch: the processed command
|
||||
* line arguments.
|
||||
**/
|
||||
private class Batch {
|
||||
boolean keepGenerated = false; // -keep or -keepgenerated
|
||||
boolean debug = false; // -g
|
||||
boolean noWarn = false; // -nowarn
|
||||
boolean noWrite = false; // -nowrite
|
||||
boolean verbose = false; // -verbose
|
||||
boolean noCompile = false; // -Xnocompile
|
||||
String bootClassPath = null; // -bootclasspath
|
||||
String extDirs = null; // -extdirs
|
||||
String classPath = null; // -classpath
|
||||
File destDir = null; // -d
|
||||
List<Generator> generators = new ArrayList<Generator>();
|
||||
Class<? extends BatchEnvironment> envClass = BatchEnvironment.class;
|
||||
List<String> classes = new ArrayList<String>();
|
||||
|
||||
Batch() { }
|
||||
|
||||
/**
|
||||
* Returns the Main instance for this batch.
|
||||
**/
|
||||
Main enclosingMain() {
|
||||
return Main.this;
|
||||
}
|
||||
}
|
||||
}
|
||||
95
jdkSrc/jdk8/sun/rmi/rmic/newrmic/Resources.java
Normal file
95
jdkSrc/jdk8/sun/rmi/rmic/newrmic/Resources.java
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.rmi.rmic.newrmic;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* Provides resource support for rmic.
|
||||
*
|
||||
* 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 final class Resources {
|
||||
|
||||
private static ResourceBundle resources = null;
|
||||
private static ResourceBundle resourcesExt = null;
|
||||
static {
|
||||
try {
|
||||
resources =
|
||||
ResourceBundle.getBundle("sun.rmi.rmic.resources.rmic");
|
||||
} catch (MissingResourceException e) {
|
||||
// gracefully handle this later
|
||||
}
|
||||
try {
|
||||
resourcesExt =
|
||||
ResourceBundle.getBundle("sun.rmi.rmic.resources.rmicext");
|
||||
} catch (MissingResourceException e) {
|
||||
// OK if this isn't found
|
||||
}
|
||||
}
|
||||
|
||||
private Resources() { throw new AssertionError(); }
|
||||
|
||||
/**
|
||||
* Returns the text of the rmic resource for the specified key
|
||||
* formatted with the specified arguments.
|
||||
**/
|
||||
public static String getText(String key, String... args) {
|
||||
String format = getString(key);
|
||||
if (format == null) {
|
||||
format = "missing resource key: key = \"" + key + "\", " +
|
||||
"arguments = \"{0}\", \"{1}\", \"{2}\"";
|
||||
}
|
||||
return MessageFormat.format(format, (Object[]) args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the rmic resource string for the specified key.
|
||||
**/
|
||||
private static String getString(String key) {
|
||||
if (resourcesExt != null) {
|
||||
try {
|
||||
return resourcesExt.getString(key);
|
||||
} catch (MissingResourceException e) {
|
||||
}
|
||||
}
|
||||
if (resources != null) {
|
||||
try {
|
||||
return resources.getString(key);
|
||||
} catch (MissingResourceException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return "missing resource bundle: key = \"" + key + "\", " +
|
||||
"arguments = \"{0}\", \"{1}\", \"{2}\"";
|
||||
}
|
||||
}
|
||||
70
jdkSrc/jdk8/sun/rmi/rmic/newrmic/jrmp/Constants.java
Normal file
70
jdkSrc/jdk8/sun/rmi/rmic/newrmic/jrmp/Constants.java
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.rmi.rmic.newrmic.jrmp;
|
||||
|
||||
/**
|
||||
* Constants specific to the JRMP rmic generator.
|
||||
*
|
||||
* 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
|
||||
**/
|
||||
final class Constants {
|
||||
|
||||
private Constants() { throw new AssertionError(); }
|
||||
|
||||
/*
|
||||
* fully-qualified names of types used by rmic
|
||||
*/
|
||||
static final String REMOTE_OBJECT = "java.rmi.server.RemoteObject";
|
||||
static final String REMOTE_STUB = "java.rmi.server.RemoteStub";
|
||||
static final String REMOTE_REF = "java.rmi.server.RemoteRef";
|
||||
static final String OPERATION = "java.rmi.server.Operation";
|
||||
static final String SKELETON = "java.rmi.server.Skeleton";
|
||||
static final String SKELETON_MISMATCH_EXCEPTION =
|
||||
"java.rmi.server.SkeletonMismatchException";
|
||||
static final String REMOTE_CALL = "java.rmi.server.RemoteCall";
|
||||
static final String MARSHAL_EXCEPTION = "java.rmi.MarshalException";
|
||||
static final String UNMARSHAL_EXCEPTION = "java.rmi.UnmarshalException";
|
||||
static final String UNEXPECTED_EXCEPTION = "java.rmi.UnexpectedException";
|
||||
|
||||
/*
|
||||
* stub protocol versions
|
||||
*/
|
||||
enum StubVersion { V1_1, VCOMPAT, V1_2 };
|
||||
|
||||
/*
|
||||
* serialVersionUID for all stubs that can use 1.2 protocol
|
||||
*/
|
||||
static final long STUB_SERIAL_VERSION_UID = 2;
|
||||
|
||||
/*
|
||||
* version number used to seed interface hash computation
|
||||
*/
|
||||
static final int INTERFACE_HASH_STUB_VERSION = 1;
|
||||
}
|
||||
226
jdkSrc/jdk8/sun/rmi/rmic/newrmic/jrmp/JrmpGenerator.java
Normal file
226
jdkSrc/jdk8/sun/rmi/rmic/newrmic/jrmp/JrmpGenerator.java
Normal file
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
710
jdkSrc/jdk8/sun/rmi/rmic/newrmic/jrmp/RemoteClass.java
Normal file
710
jdkSrc/jdk8/sun/rmi/rmic/newrmic/jrmp/RemoteClass.java
Normal file
@@ -0,0 +1,710 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.rmi.rmic.newrmic.jrmp;
|
||||
|
||||
import com.sun.javadoc.ClassDoc;
|
||||
import com.sun.javadoc.MethodDoc;
|
||||
import com.sun.javadoc.Parameter;
|
||||
import com.sun.javadoc.Type;
|
||||
import java.io.IOException;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.DigestOutputStream;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import sun.rmi.rmic.newrmic.BatchEnvironment;
|
||||
|
||||
import static sun.rmi.rmic.newrmic.Constants.*;
|
||||
import static sun.rmi.rmic.newrmic.jrmp.Constants.*;
|
||||
|
||||
/**
|
||||
* Encapsulates RMI-specific information about a remote implementation
|
||||
* class (a class that implements one or more remote interfaces).
|
||||
*
|
||||
* 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
|
||||
**/
|
||||
final class RemoteClass {
|
||||
|
||||
/** rmic environment for this object */
|
||||
private final BatchEnvironment env;
|
||||
|
||||
/** the remote implementation class this object represents */
|
||||
private final ClassDoc implClass;
|
||||
|
||||
/** remote interfaces implemented by this class */
|
||||
private ClassDoc[] remoteInterfaces;
|
||||
|
||||
/** the remote methods of this class */
|
||||
private Method[] remoteMethods;
|
||||
|
||||
/** stub/skeleton "interface hash" for this class */
|
||||
private long interfaceHash;
|
||||
|
||||
/**
|
||||
* Creates a RemoteClass instance that represents the RMI-specific
|
||||
* information about the specified remote implementation class.
|
||||
*
|
||||
* If the class is not a valid remote implementation class or if
|
||||
* some other error occurs, the return value will be null, and
|
||||
* errors will have been reported to the supplied
|
||||
* BatchEnvironment.
|
||||
**/
|
||||
static RemoteClass forClass(BatchEnvironment env, ClassDoc implClass) {
|
||||
RemoteClass remoteClass = new RemoteClass(env, implClass);
|
||||
if (remoteClass.init()) {
|
||||
return remoteClass;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a RemoteClass instance for the specified class. The
|
||||
* resulting object is not yet initialized.
|
||||
**/
|
||||
private RemoteClass(BatchEnvironment env, ClassDoc implClass) {
|
||||
this.env = env;
|
||||
this.implClass = implClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ClassDoc for this remote implementation class.
|
||||
**/
|
||||
ClassDoc classDoc() {
|
||||
return implClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the remote interfaces implemented by this remote
|
||||
* implementation class.
|
||||
*
|
||||
* A remote interface is an interface that is a subinterface of
|
||||
* java.rmi.Remote. The remote interfaces of a class are the
|
||||
* direct superinterfaces of the class and all of its superclasses
|
||||
* that are remote interfaces.
|
||||
*
|
||||
* The order of the array returned is arbitrary, and some elements
|
||||
* may be superfluous (i.e., superinterfaces of other interfaces
|
||||
* in the array).
|
||||
**/
|
||||
ClassDoc[] remoteInterfaces() {
|
||||
return remoteInterfaces.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of RemoteClass.Method objects representing all
|
||||
* of the remote methods of this remote implementation class (all
|
||||
* of the member methods of the class's remote interfaces).
|
||||
*
|
||||
* The methods in the array are ordered according to a comparison
|
||||
* of strings consisting of their name followed by their
|
||||
* descriptor, so each method's index in the array corresponds to
|
||||
* its "operation number" in the JDK 1.1 version of the JRMP
|
||||
* stub/skeleton protocol.
|
||||
**/
|
||||
Method[] remoteMethods() {
|
||||
return remoteMethods.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the "interface hash" used to match a stub/skeleton pair
|
||||
* for this remote implementation class in the JDK 1.1 version of
|
||||
* the JRMP stub/skeleton protocol.
|
||||
**/
|
||||
long interfaceHash() {
|
||||
return interfaceHash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates this remote implementation class and computes the
|
||||
* RMI-specific information. Returns true if successful, or false
|
||||
* if an error occurred.
|
||||
**/
|
||||
private boolean init() {
|
||||
/*
|
||||
* Verify that it is really a class, not an interface.
|
||||
*/
|
||||
if (implClass.isInterface()) {
|
||||
env.error("rmic.cant.make.stubs.for.interface",
|
||||
implClass.qualifiedName());
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find all of the remote interfaces of our remote
|
||||
* implementation class-- for each class up the superclass
|
||||
* chain, add each directly-implemented interface that somehow
|
||||
* extends Remote to a list.
|
||||
*/
|
||||
List<ClassDoc> remotesImplemented = new ArrayList<ClassDoc>();
|
||||
for (ClassDoc cl = implClass; cl != null; cl = cl.superclass()) {
|
||||
for (ClassDoc intf : cl.interfaces()) {
|
||||
/*
|
||||
* Add interface to the list if it extends Remote and
|
||||
* it is not already there.
|
||||
*/
|
||||
if (!remotesImplemented.contains(intf) &&
|
||||
intf.subclassOf(env.docRemote()))
|
||||
{
|
||||
remotesImplemented.add(intf);
|
||||
if (env.verbose()) {
|
||||
env.output("[found remote interface: " +
|
||||
intf.qualifiedName() + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify that the candidate remote implementation class
|
||||
* implements at least one remote interface directly.
|
||||
*/
|
||||
if (cl == implClass && remotesImplemented.isEmpty()) {
|
||||
if (implClass.subclassOf(env.docRemote())) {
|
||||
/*
|
||||
* This error message is used if the class does
|
||||
* implement a remote interface through one of its
|
||||
* superclasses, but not directly.
|
||||
*/
|
||||
env.error("rmic.must.implement.remote.directly",
|
||||
implClass.qualifiedName());
|
||||
} else {
|
||||
/*
|
||||
* This error message is used if the class does
|
||||
* not implement a remote interface at all.
|
||||
*/
|
||||
env.error("rmic.must.implement.remote",
|
||||
implClass.qualifiedName());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert list of remote interfaces to an array
|
||||
* (order is not important for this array).
|
||||
*/
|
||||
remoteInterfaces =
|
||||
remotesImplemented.toArray(
|
||||
new ClassDoc[remotesImplemented.size()]);
|
||||
|
||||
/*
|
||||
* Collect the methods from all of the remote interfaces into
|
||||
* a table, which maps from method name-and-descriptor string
|
||||
* to Method object.
|
||||
*/
|
||||
Map<String,Method> methods = new HashMap<String,Method>();
|
||||
boolean errors = false;
|
||||
for (ClassDoc intf : remotesImplemented) {
|
||||
if (!collectRemoteMethods(intf, methods)) {
|
||||
/*
|
||||
* Continue iterating despite errors in order to
|
||||
* generate more complete error report.
|
||||
*/
|
||||
errors = true;
|
||||
}
|
||||
}
|
||||
if (errors) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sort table of remote methods into an array. The elements
|
||||
* are sorted in ascending order of the string of the method's
|
||||
* name and descriptor, so that each elements index is equal
|
||||
* to its operation number in the JDK 1.1 version of the JRMP
|
||||
* stub/skeleton protocol.
|
||||
*/
|
||||
String[] orderedKeys =
|
||||
methods.keySet().toArray(new String[methods.size()]);
|
||||
Arrays.sort(orderedKeys);
|
||||
remoteMethods = new Method[methods.size()];
|
||||
for (int i = 0; i < remoteMethods.length; i++) {
|
||||
remoteMethods[i] = methods.get(orderedKeys[i]);
|
||||
if (env.verbose()) {
|
||||
String msg = "[found remote method <" + i + ">: " +
|
||||
remoteMethods[i].operationString();
|
||||
ClassDoc[] exceptions = remoteMethods[i].exceptionTypes();
|
||||
if (exceptions.length > 0) {
|
||||
msg += " throws ";
|
||||
for (int j = 0; j < exceptions.length; j++) {
|
||||
if (j > 0) {
|
||||
msg += ", ";
|
||||
}
|
||||
msg += exceptions[j].qualifiedName();
|
||||
}
|
||||
}
|
||||
msg += "\n\tname and descriptor = \"" +
|
||||
remoteMethods[i].nameAndDescriptor();
|
||||
msg += "\n\tmethod hash = " +
|
||||
remoteMethods[i].methodHash() + "]";
|
||||
env.output(msg);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Finally, pre-compute the interface hash to be used by
|
||||
* stubs/skeletons for this remote class in the JDK 1.1
|
||||
* version of the JRMP stub/skeleton protocol.
|
||||
*/
|
||||
interfaceHash = computeInterfaceHash();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects and validates all methods from the specified interface
|
||||
* and all of its superinterfaces as remote methods. Remote
|
||||
* methods are added to the supplied table. Returns true if
|
||||
* successful, or false if an error occurred.
|
||||
**/
|
||||
private boolean collectRemoteMethods(ClassDoc intf,
|
||||
Map<String,Method> table)
|
||||
{
|
||||
if (!intf.isInterface()) {
|
||||
throw new AssertionError(
|
||||
intf.qualifiedName() + " not an interface");
|
||||
}
|
||||
|
||||
boolean errors = false;
|
||||
|
||||
/*
|
||||
* Search interface's declared methods.
|
||||
*/
|
||||
nextMethod:
|
||||
for (MethodDoc method : intf.methods()) {
|
||||
|
||||
/*
|
||||
* Verify that each method throws RemoteException (or a
|
||||
* superclass of RemoteException).
|
||||
*/
|
||||
boolean hasRemoteException = false;
|
||||
for (ClassDoc ex : method.thrownExceptions()) {
|
||||
if (env.docRemoteException().subclassOf(ex)) {
|
||||
hasRemoteException = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If this method did not throw RemoteException as required,
|
||||
* generate the error but continue, so that multiple such
|
||||
* errors can be reported.
|
||||
*/
|
||||
if (!hasRemoteException) {
|
||||
env.error("rmic.must.throw.remoteexception",
|
||||
intf.qualifiedName(),
|
||||
method.name() + method.signature());
|
||||
errors = true;
|
||||
continue nextMethod;
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify that the implementation of this method throws only
|
||||
* java.lang.Exception or its subclasses (fix bugid 4092486).
|
||||
* JRMP does not support remote methods throwing
|
||||
* java.lang.Throwable or other subclasses.
|
||||
*/
|
||||
MethodDoc implMethod = findImplMethod(method);
|
||||
if (implMethod != null) { // should not be null
|
||||
for (ClassDoc ex : implMethod.thrownExceptions()) {
|
||||
if (!ex.subclassOf(env.docException())) {
|
||||
env.error("rmic.must.only.throw.exception",
|
||||
implMethod.name() + implMethod.signature(),
|
||||
ex.qualifiedName());
|
||||
errors = true;
|
||||
continue nextMethod;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Create RemoteClass.Method object to represent this method
|
||||
* found in a remote interface.
|
||||
*/
|
||||
Method newMethod = new Method(method);
|
||||
|
||||
/*
|
||||
* Store remote method's representation in the table of
|
||||
* remote methods found, keyed by its name and descriptor.
|
||||
*
|
||||
* If the table already contains an entry with the same
|
||||
* method name and descriptor, then we must replace the
|
||||
* old entry with a Method object that represents a legal
|
||||
* combination of the old and the new methods;
|
||||
* specifically, the combined method must have a throws
|
||||
* clause that contains (only) all of the checked
|
||||
* exceptions that can be thrown by both the old and the
|
||||
* new method (see bugid 4070653).
|
||||
*/
|
||||
String key = newMethod.nameAndDescriptor();
|
||||
Method oldMethod = table.get(key);
|
||||
if (oldMethod != null) {
|
||||
newMethod = newMethod.mergeWith(oldMethod);
|
||||
}
|
||||
table.put(key, newMethod);
|
||||
}
|
||||
|
||||
/*
|
||||
* Recursively collect methods for all superinterfaces.
|
||||
*/
|
||||
for (ClassDoc superintf : intf.interfaces()) {
|
||||
if (!collectRemoteMethods(superintf, table)) {
|
||||
errors = true;
|
||||
}
|
||||
}
|
||||
|
||||
return !errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the MethodDoc for the method of this remote
|
||||
* implementation class that implements the specified remote
|
||||
* method of a remote interface. Returns null if no matching
|
||||
* method was found in this remote implementation class.
|
||||
**/
|
||||
private MethodDoc findImplMethod(MethodDoc interfaceMethod) {
|
||||
String name = interfaceMethod.name();
|
||||
String desc = Util.methodDescriptorOf(interfaceMethod);
|
||||
for (MethodDoc implMethod : implClass.methods()) {
|
||||
if (name.equals(implMethod.name()) &&
|
||||
desc.equals(Util.methodDescriptorOf(implMethod)))
|
||||
{
|
||||
return implMethod;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the "interface hash" of the stub/skeleton pair for
|
||||
* this remote implementation class. This is the 64-bit value
|
||||
* used to enforce compatibility between a stub class and a
|
||||
* skeleton class in the JDK 1.1 version of the JRMP stub/skeleton
|
||||
* protocol.
|
||||
*
|
||||
* It is calculated using the first 64 bits of an SHA digest. The
|
||||
* digest is of a stream consisting of the following data:
|
||||
* (int) stub version number, always 1
|
||||
* for each remote method, in order of operation number:
|
||||
* (UTF-8) method name
|
||||
* (UTF-8) method descriptor
|
||||
* for each declared exception, in alphabetical name order:
|
||||
* (UTF-8) name of exception class
|
||||
* (where "UTF-8" includes a 16-bit length prefix as written by
|
||||
* java.io.DataOutput.writeUTF).
|
||||
**/
|
||||
private long computeInterfaceHash() {
|
||||
long hash = 0;
|
||||
ByteArrayOutputStream sink = new ByteArrayOutputStream(512);
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("SHA");
|
||||
DataOutputStream out = new DataOutputStream(
|
||||
new DigestOutputStream(sink, md));
|
||||
|
||||
out.writeInt(INTERFACE_HASH_STUB_VERSION);
|
||||
|
||||
for (Method method : remoteMethods) {
|
||||
MethodDoc methodDoc = method.methodDoc();
|
||||
|
||||
out.writeUTF(methodDoc.name());
|
||||
out.writeUTF(Util.methodDescriptorOf(methodDoc));
|
||||
// descriptors already use binary names
|
||||
|
||||
ClassDoc exceptions[] = methodDoc.thrownExceptions();
|
||||
Arrays.sort(exceptions, new ClassDocComparator());
|
||||
for (ClassDoc ex : exceptions) {
|
||||
out.writeUTF(Util.binaryNameOf(ex));
|
||||
}
|
||||
}
|
||||
out.flush();
|
||||
|
||||
// use only the first 64 bits of the digest for the hash
|
||||
byte hashArray[] = md.digest();
|
||||
for (int i = 0; i < Math.min(8, hashArray.length); i++) {
|
||||
hash += ((long) (hashArray[i] & 0xFF)) << (i * 8);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new AssertionError(e);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares ClassDoc instances according to the lexicographic
|
||||
* order of their binary names.
|
||||
**/
|
||||
private static class ClassDocComparator implements Comparator<ClassDoc> {
|
||||
public int compare(ClassDoc o1, ClassDoc o2) {
|
||||
return Util.binaryNameOf(o1).compareTo(Util.binaryNameOf(o2));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encapsulates RMI-specific information about a particular remote
|
||||
* method in the remote implementation class represented by the
|
||||
* enclosing RemoteClass.
|
||||
**/
|
||||
final class Method implements Cloneable {
|
||||
|
||||
/**
|
||||
* MethodDoc for this remove method, from one of the remote
|
||||
* interfaces that this method was found in.
|
||||
*
|
||||
* Note that this MethodDoc may be only one of multiple that
|
||||
* correspond to this remote method object, if multiple of
|
||||
* this class's remote interfaces contain methods with the
|
||||
* same name and descriptor. Therefore, this MethodDoc may
|
||||
* declare more exceptions thrown that this remote method
|
||||
* does.
|
||||
**/
|
||||
private final MethodDoc methodDoc;
|
||||
|
||||
/** java.rmi.server.Operation string for this remote method */
|
||||
private final String operationString;
|
||||
|
||||
/** name and descriptor of this remote method */
|
||||
private final String nameAndDescriptor;
|
||||
|
||||
/** JRMP "method hash" for this remote method */
|
||||
private final long methodHash;
|
||||
|
||||
/**
|
||||
* Exceptions declared to be thrown by this remote method.
|
||||
*
|
||||
* This list may include superfluous entries, such as
|
||||
* unchecked exceptions and subclasses of other entries.
|
||||
**/
|
||||
private ClassDoc[] exceptionTypes;
|
||||
|
||||
/**
|
||||
* Creates a new Method instance for the specified method.
|
||||
**/
|
||||
Method(MethodDoc methodDoc) {
|
||||
this.methodDoc = methodDoc;
|
||||
exceptionTypes = methodDoc.thrownExceptions();
|
||||
/*
|
||||
* Sort exception types to improve consistency with
|
||||
* previous implementations.
|
||||
*/
|
||||
Arrays.sort(exceptionTypes, new ClassDocComparator());
|
||||
operationString = computeOperationString();
|
||||
nameAndDescriptor =
|
||||
methodDoc.name() + Util.methodDescriptorOf(methodDoc);
|
||||
methodHash = computeMethodHash();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the MethodDoc object corresponding to this method
|
||||
* of a remote interface.
|
||||
**/
|
||||
MethodDoc methodDoc() {
|
||||
return methodDoc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the parameter types declared by this method.
|
||||
**/
|
||||
Type[] parameterTypes() {
|
||||
Parameter[] parameters = methodDoc.parameters();
|
||||
Type[] paramTypes = new Type[parameters.length];
|
||||
for (int i = 0; i < paramTypes.length; i++) {
|
||||
paramTypes[i] = parameters[i].type();
|
||||
}
|
||||
return paramTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the exception types declared to be thrown by this
|
||||
* remote method.
|
||||
*
|
||||
* For methods with the same name and descriptor inherited
|
||||
* from multiple remote interfaces, the array will contain the
|
||||
* set of exceptions declared in all of the interfaces'
|
||||
* methods that can be legally thrown by all of them.
|
||||
**/
|
||||
ClassDoc[] exceptionTypes() {
|
||||
return exceptionTypes.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the JRMP "method hash" used to identify this remote
|
||||
* method in the JDK 1.2 version of the stub protocol.
|
||||
**/
|
||||
long methodHash() {
|
||||
return methodHash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string representation of this method
|
||||
* appropriate for the construction of a
|
||||
* java.rmi.server.Operation object.
|
||||
**/
|
||||
String operationString() {
|
||||
return operationString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string consisting of this method's name followed
|
||||
* by its descriptor.
|
||||
**/
|
||||
String nameAndDescriptor() {
|
||||
return nameAndDescriptor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new Method object that is a legal combination of
|
||||
* this Method object and another one.
|
||||
*
|
||||
* Doing this requires determining the exceptions declared by
|
||||
* the combined method, which must be (only) all of the
|
||||
* exceptions declared in both old Methods that may thrown in
|
||||
* either of them.
|
||||
**/
|
||||
Method mergeWith(Method other) {
|
||||
if (!nameAndDescriptor().equals(other.nameAndDescriptor())) {
|
||||
throw new AssertionError(
|
||||
"attempt to merge method \"" +
|
||||
other.nameAndDescriptor() + "\" with \"" +
|
||||
nameAndDescriptor());
|
||||
}
|
||||
|
||||
List<ClassDoc> legalExceptions = new ArrayList<ClassDoc>();
|
||||
collectCompatibleExceptions(
|
||||
other.exceptionTypes, exceptionTypes, legalExceptions);
|
||||
collectCompatibleExceptions(
|
||||
exceptionTypes, other.exceptionTypes, legalExceptions);
|
||||
|
||||
Method merged = clone();
|
||||
merged.exceptionTypes =
|
||||
legalExceptions.toArray(new ClassDoc[legalExceptions.size()]);
|
||||
|
||||
return merged;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cloning is supported by returning a shallow copy of this
|
||||
* object.
|
||||
**/
|
||||
protected Method clone() {
|
||||
try {
|
||||
return (Method) super.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds to the supplied list all exceptions in the "froms"
|
||||
* array that are subclasses of an exception in the "withs"
|
||||
* array.
|
||||
**/
|
||||
private void collectCompatibleExceptions(ClassDoc[] froms,
|
||||
ClassDoc[] withs,
|
||||
List<ClassDoc> list)
|
||||
{
|
||||
for (ClassDoc from : froms) {
|
||||
if (!list.contains(from)) {
|
||||
for (ClassDoc with : withs) {
|
||||
if (from.subclassOf(with)) {
|
||||
list.add(from);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the JRMP "method hash" of this remote method. The
|
||||
* method hash is a long containing the first 64 bits of the
|
||||
* SHA digest from the UTF-8 encoded string of the method name
|
||||
* and descriptor.
|
||||
**/
|
||||
private long computeMethodHash() {
|
||||
long hash = 0;
|
||||
ByteArrayOutputStream sink = new ByteArrayOutputStream(512);
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("SHA");
|
||||
DataOutputStream out = new DataOutputStream(
|
||||
new DigestOutputStream(sink, md));
|
||||
|
||||
String methodString = nameAndDescriptor();
|
||||
out.writeUTF(methodString);
|
||||
|
||||
// use only the first 64 bits of the digest for the hash
|
||||
out.flush();
|
||||
byte hashArray[] = md.digest();
|
||||
for (int i = 0; i < Math.min(8, hashArray.length); i++) {
|
||||
hash += ((long) (hashArray[i] & 0xFF)) << (i * 8);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new AssertionError(e);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the string representation of this method
|
||||
* appropriate for the construction of a
|
||||
* java.rmi.server.Operation object.
|
||||
**/
|
||||
private String computeOperationString() {
|
||||
/*
|
||||
* To be consistent with previous implementations, we use
|
||||
* the deprecated style of placing the "[]" for the return
|
||||
* type (if any) after the parameter list.
|
||||
*/
|
||||
Type returnType = methodDoc.returnType();
|
||||
String op = returnType.qualifiedTypeName() + " " +
|
||||
methodDoc.name() + "(";
|
||||
Parameter[] parameters = methodDoc.parameters();
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
if (i > 0) {
|
||||
op += ", ";
|
||||
}
|
||||
op += parameters[i].type().toString();
|
||||
}
|
||||
op += ")" + returnType.dimension();
|
||||
return op;
|
||||
}
|
||||
}
|
||||
}
|
||||
1079
jdkSrc/jdk8/sun/rmi/rmic/newrmic/jrmp/StubSkeletonWriter.java
Normal file
1079
jdkSrc/jdk8/sun/rmi/rmic/newrmic/jrmp/StubSkeletonWriter.java
Normal file
File diff suppressed because it is too large
Load Diff
149
jdkSrc/jdk8/sun/rmi/rmic/newrmic/jrmp/Util.java
Normal file
149
jdkSrc/jdk8/sun/rmi/rmic/newrmic/jrmp/Util.java
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.rmi.rmic.newrmic.jrmp;
|
||||
|
||||
import com.sun.javadoc.ClassDoc;
|
||||
import com.sun.javadoc.MethodDoc;
|
||||
import com.sun.javadoc.Parameter;
|
||||
import com.sun.javadoc.Type;
|
||||
|
||||
/**
|
||||
* Provides static utility methods.
|
||||
*
|
||||
* 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
|
||||
**/
|
||||
final class Util {
|
||||
|
||||
private Util() { throw new AssertionError(); }
|
||||
|
||||
/**
|
||||
* Returns the binary name of the class or interface represented
|
||||
* by the specified ClassDoc.
|
||||
**/
|
||||
static String binaryNameOf(ClassDoc cl) {
|
||||
String flat = cl.name().replace('.', '$');
|
||||
String packageName = cl.containingPackage().name();
|
||||
return packageName.equals("") ? flat : packageName + "." + flat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the method descriptor for the specified method.
|
||||
*
|
||||
* See section 4.3.3 of The Java Virtual Machine Specification
|
||||
* Second Edition for the definition of a "method descriptor".
|
||||
**/
|
||||
static String methodDescriptorOf(MethodDoc method) {
|
||||
String desc = "(";
|
||||
Parameter[] parameters = method.parameters();
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
desc += typeDescriptorOf(parameters[i].type());
|
||||
}
|
||||
desc += ")" + typeDescriptorOf(method.returnType());
|
||||
return desc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the descriptor for the specified type, as appropriate
|
||||
* for either a parameter or return type in a method descriptor.
|
||||
**/
|
||||
private static String typeDescriptorOf(Type type) {
|
||||
String desc;
|
||||
ClassDoc classDoc = type.asClassDoc();
|
||||
if (classDoc == null) {
|
||||
/*
|
||||
* Handle primitive types.
|
||||
*/
|
||||
String name = type.typeName();
|
||||
if (name.equals("boolean")) {
|
||||
desc = "Z";
|
||||
} else if (name.equals("byte")) {
|
||||
desc = "B";
|
||||
} else if (name.equals("char")) {
|
||||
desc = "C";
|
||||
} else if (name.equals("short")) {
|
||||
desc = "S";
|
||||
} else if (name.equals("int")) {
|
||||
desc = "I";
|
||||
} else if (name.equals("long")) {
|
||||
desc = "J";
|
||||
} else if (name.equals("float")) {
|
||||
desc = "F";
|
||||
} else if (name.equals("double")) {
|
||||
desc = "D";
|
||||
} else if (name.equals("void")) {
|
||||
desc = "V";
|
||||
} else {
|
||||
throw new AssertionError(
|
||||
"unrecognized primitive type: " + name);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Handle non-array reference types.
|
||||
*/
|
||||
desc = "L" + binaryNameOf(classDoc).replace('.', '/') + ";";
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle array types.
|
||||
*/
|
||||
int dimensions = type.dimension().length() / 2;
|
||||
for (int i = 0; i < dimensions; i++) {
|
||||
desc = "[" + desc;
|
||||
}
|
||||
|
||||
return desc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reader-friendly string representation of the
|
||||
* specified method's signature. Names of reference types are not
|
||||
* package-qualified.
|
||||
**/
|
||||
static String getFriendlyUnqualifiedSignature(MethodDoc method) {
|
||||
String sig = method.name() + "(";
|
||||
Parameter[] parameters = method.parameters();
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
if (i > 0) {
|
||||
sig += ", ";
|
||||
}
|
||||
Type paramType = parameters[i].type();
|
||||
sig += paramType.typeName() + paramType.dimension();
|
||||
}
|
||||
sig += ")";
|
||||
return sig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the specified type is void.
|
||||
**/
|
||||
static boolean isVoid(Type type) {
|
||||
return type.asClassDoc() == null && type.typeName().equals("void");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user