use of com.sun.javadoc.MethodDoc in project jdk8u_jdk by JetBrains.
the class StubSkeletonWriter method writeStubMethod.
/**
* Writes the stub method for the remote method with the given
* operation number.
**/
private void writeStubMethod(IndentingWriter p, int opnum) throws IOException {
RemoteClass.Method method = remoteMethods[opnum];
MethodDoc methodDoc = method.methodDoc();
String methodName = methodDoc.name();
Type[] paramTypes = method.parameterTypes();
String[] paramNames = nameParameters(paramTypes);
Type returnType = methodDoc.returnType();
ClassDoc[] exceptions = method.exceptionTypes();
/*
* Declare stub method; throw exceptions declared in remote
* interface(s).
*/
p.pln("// implementation of " + Util.getFriendlyUnqualifiedSignature(methodDoc));
p.p("public " + returnType.toString() + " " + methodName + "(");
for (int i = 0; i < paramTypes.length; i++) {
if (i > 0) {
p.p(", ");
}
p.p(paramTypes[i].toString() + " " + paramNames[i]);
}
p.plnI(")");
if (exceptions.length > 0) {
p.p("throws ");
for (int i = 0; i < exceptions.length; i++) {
if (i > 0) {
p.p(", ");
}
p.p(exceptions[i].qualifiedName());
}
p.pln();
}
p.pOlnI("{");
/*
* The RemoteRef.invoke methods throw Exception, but unless
* this stub method throws Exception as well, we must catch
* Exceptions thrown from the invocation. So we must catch
* Exception and rethrow something we can throw:
* UnexpectedException, which is a subclass of
* RemoteException. But for any subclasses of Exception that
* we can throw, like RemoteException, RuntimeException, and
* any of the exceptions declared by this stub method, we want
* them to pass through unmodified, so first we must catch any
* such exceptions and rethrow them directly.
*
* We have to be careful generating the rethrowing catch
* blocks here, because javac will flag an error if there are
* any unreachable catch blocks, i.e. if the catch of an
* exception class follows a previous catch of it or of one of
* its superclasses. The following method invocation takes
* care of these details.
*/
List<ClassDoc> catchList = computeUniqueCatchList(exceptions);
/*
* If we need to catch any particular exceptions (i.e. this method
* does not declare java.lang.Exception), put the entire stub
* method in a try block.
*/
if (catchList.size() > 0) {
p.plnI("try {");
}
if (version == StubVersion.VCOMPAT) {
p.plnI("if (useNewInvoke) {");
}
if (version == StubVersion.VCOMPAT || version == StubVersion.V1_2) {
if (!Util.isVoid(returnType)) {
// REMIND: why $?
p.p("Object $result = ");
}
p.p("ref.invoke(this, " + methodFieldNames[opnum] + ", ");
if (paramTypes.length > 0) {
p.p("new java.lang.Object[] {");
for (int i = 0; i < paramTypes.length; i++) {
if (i > 0)
p.p(", ");
p.p(wrapArgumentCode(paramTypes[i], paramNames[i]));
}
p.p("}");
} else {
p.p("null");
}
p.pln(", " + method.methodHash() + "L);");
if (!Util.isVoid(returnType)) {
p.pln("return " + unwrapArgumentCode(returnType, "$result") + ";");
}
}
if (version == StubVersion.VCOMPAT) {
p.pOlnI("} else {");
}
if (version == StubVersion.V1_1 || version == StubVersion.VCOMPAT) {
p.pln(REMOTE_CALL + " call = ref.newCall((" + REMOTE_OBJECT + ") this, operations, " + opnum + ", interfaceHash);");
if (paramTypes.length > 0) {
p.plnI("try {");
p.pln("java.io.ObjectOutput out = call.getOutputStream();");
writeMarshalArguments(p, "out", paramTypes, paramNames);
p.pOlnI("} catch (java.io.IOException e) {");
p.pln("throw new " + MARSHAL_EXCEPTION + "(\"error marshalling arguments\", e);");
p.pOln("}");
}
p.pln("ref.invoke(call);");
if (Util.isVoid(returnType)) {
p.pln("ref.done(call);");
} else {
p.pln(returnType.toString() + " $result;");
// REMIND: why $?
p.plnI("try {");
p.pln("java.io.ObjectInput in = call.getInputStream();");
boolean objectRead = writeUnmarshalArgument(p, "in", returnType, "$result");
p.pln(";");
p.pOlnI("} catch (java.io.IOException e) {");
p.pln("throw new " + UNMARSHAL_EXCEPTION + "(\"error unmarshalling return\", e);");
/*
* If any only if readObject has been invoked, we must catch
* ClassNotFoundException as well as IOException.
*/
if (objectRead) {
p.pOlnI("} catch (java.lang.ClassNotFoundException e) {");
p.pln("throw new " + UNMARSHAL_EXCEPTION + "(\"error unmarshalling return\", e);");
}
p.pOlnI("} finally {");
p.pln("ref.done(call);");
p.pOln("}");
p.pln("return $result;");
}
}
if (version == StubVersion.VCOMPAT) {
// end if/else (useNewInvoke) block
p.pOln("}");
}
/*
* If we need to catch any particular exceptions, finally write
* the catch blocks for them, rethrow any other Exceptions with an
* UnexpectedException, and end the try block.
*/
if (catchList.size() > 0) {
for (ClassDoc catchClass : catchList) {
p.pOlnI("} catch (" + catchClass.qualifiedName() + " e) {");
p.pln("throw e;");
}
p.pOlnI("} catch (java.lang.Exception e) {");
p.pln("throw new " + UNEXPECTED_EXCEPTION + "(\"undeclared checked exception\", e);");
// end try/catch block
p.pOln("}");
}
// end stub method
p.pOln("}");
}
use of com.sun.javadoc.MethodDoc in project jdk8u_jdk by JetBrains.
the class StubSkeletonWriter method writeMethodFieldInitializers.
/**
* Writes code to initialize the static fields for each method
* using the Java Reflection API.
**/
private void writeMethodFieldInitializers(IndentingWriter p) throws IOException {
for (int i = 0; i < methodFieldNames.length; i++) {
p.p(methodFieldNames[i] + " = ");
/*
* Look up the Method object in the somewhat arbitrary
* interface that we find in the Method object.
*/
RemoteClass.Method method = remoteMethods[i];
MethodDoc methodDoc = method.methodDoc();
String methodName = methodDoc.name();
Type[] paramTypes = method.parameterTypes();
p.p(methodDoc.containingClass().qualifiedName() + ".class.getMethod(\"" + methodName + "\", new java.lang.Class[] {");
for (int j = 0; j < paramTypes.length; j++) {
if (j > 0)
p.p(", ");
p.p(paramTypes[j].toString() + ".class");
}
p.pln("});");
}
}
use of com.sun.javadoc.MethodDoc in project jdk8u_jdk by JetBrains.
the class RemoteClass method computeInterfaceHash.
/**
* 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;
}
use of com.sun.javadoc.MethodDoc in project jdk8u_jdk by JetBrains.
the class GenDocletBeanInfo method start.
/** @beaninfo
* bound:true
* constrained:false
* expert:true
* hidden:true
* preferred:false
* description: the description of this method can
* do all sorts of funky things. if it \n
* is indented like this, we have to remove
* all char spaces greater than 2 and also any hard-coded \n
* newline characters and all newlines
* displayname: theString
* propertyeditorclass: foo.bar.MyPropertyEditorClass
* customizerclass: foo.bar.MyCustomizerClass
* attribute:key1 value1
* attribute: key2 value2
*
*/
public static boolean start(RootDoc doc) {
readOptions(doc.options());
if (templateDir.length() == 0) {
System.err.println("-t option not specified");
return false;
}
if (fileDir.length() == 0) {
System.err.println("-d option not specified");
return false;
}
GenSwingBeanInfo generator = new GenSwingBeanInfo(fileDir, templateDir, DEBUG);
Hashtable dochash = new Hashtable();
DocBeanInfo dbi;
/* "javadoc Foo.java Bar.java" will return:
* "Foo Foo.I1 Foo.I2 Bar Bar.I1 Bar.I2"
* i.e., with all the innerclasses of classes specified in the command
* line. We don't want to generate BeanInfo for any of these inner
* classes, so we ignore these by remembering what the last outer
* class was. A hack, I admit, but makes the build faster.
*/
String previousClass = null;
ClassDoc[] classes = doc.classes();
for (int cnt = 0; cnt < classes.length; cnt++) {
String className = classes[cnt].qualifiedName();
if (previousClass != null && className.startsWith(previousClass) && className.charAt(previousClass.length()) == '.') {
continue;
}
previousClass = className;
// XXX - debug
System.out.println("\n>>> Generating beaninfo for " + className + "...");
// Examine the javadoc tags and look for the the @beaninfo tag
// This first block looks at the javadoc for the class
Tag[] tags = classes[cnt].tags();
for (int i = 0; i < tags.length; i++) {
if (tags[i].kind().equalsIgnoreCase("@beaninfo")) {
if (DEBUG)
System.out.println("GenDocletBeanInfo: found @beaninfo tagged Class: " + tags[i].text());
dbi = genDocletInfo(tags[i].text(), classes[cnt].name());
dochash.put(dbi.name, dbi);
break;
}
}
// This block looks at the javadoc for the class methods.
int startPos = -1;
MethodDoc[] methods = classes[cnt].methods();
for (int j = 0; j < methods.length; j++) {
// actually don't "introspect" - look for all
// methods with a @beaninfo tag
tags = methods[j].tags();
for (int x = 0; x < tags.length; x++) {
if (tags[x].kind().equalsIgnoreCase("@beaninfo")) {
if ((methods[j].name().startsWith("get")) || (methods[j].name().startsWith("set")))
startPos = 3;
else if (methods[j].name().startsWith("is"))
startPos = 2;
else
startPos = 0;
String propDesc = Introspector.decapitalize((methods[j].name()).substring(startPos));
if (DEBUG)
System.out.println("GenDocletBeanInfo: found @beaninfo tagged Method: " + tags[x].text());
dbi = genDocletInfo(tags[x].text(), propDesc);
dochash.put(dbi.name, dbi);
break;
}
}
}
if (DEBUG) {
// dump our classes doc beaninfo
System.out.println(">>>>DocletBeanInfo for class: " + classes[cnt].name());
Enumeration e = dochash.elements();
while (e.hasMoreElements()) {
DocBeanInfo db = (DocBeanInfo) e.nextElement();
System.out.println(db.toString());
}
}
// Use the generator to create the beaninfo code for the class.
generator.genBeanInfo(classes[cnt].containingPackage().name(), classes[cnt].name(), dochash);
// reset the values!
dochash.clear();
}
// end for loop
return true;
}
Aggregations