001: /*
002: * Copyright 2002-2005 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package com.sun.tools.javah;
027:
028: import java.io.OutputStream;
029: import java.io.PrintWriter;
030: import java.util.Vector;
031: import java.util.Enumeration;
032: import com.sun.javadoc.*;
033:
034: /**
035: * Header file generator for JNI.
036: *
037: * @author Sucheta Dambalkar(Revised)
038: */
039:
040: public class JNI extends Gen {
041:
042: public JNI(RootDoc root) {
043: super (root);
044: }
045:
046: public String getIncludes() {
047: return "#include <jni.h>";
048: }
049:
050: public void write(OutputStream o, ClassDoc clazz)
051: throws ClassNotFoundException {
052:
053: String cname = Mangle.mangle(clazz.qualifiedName(),
054: Mangle.Type.CLASS);
055: PrintWriter pw = wrapWriter(o);
056: pw.println(guardBegin(cname));
057: pw.println(cppGuardBegin());
058:
059: /* Write statics. */
060: FieldDoc[] classfields = getAllFields(clazz);
061:
062: for (int i = 0; i < classfields.length; i++) {
063: if (!classfields[i].isStatic())
064: continue;
065: String s = null;
066: s = defineForStatic(clazz, classfields[i]);
067: if (s != null) {
068: pw.println(s);
069: }
070: }
071:
072: /* Write methods. */
073: MethodDoc[] classmethods = clazz.methods();
074: for (int i = 0; i < classmethods.length; i++) {
075: if (classmethods[i].isNative()) {
076: MethodDoc md = classmethods[i];
077: Type mtr = classmethods[i].returnType();
078: String sig = md.signature();
079: TypeSignature newtypesig = new TypeSignature(root);
080: String methodName = md.name();
081: boolean longName = false;
082: for (int j = 0; j < classmethods.length; j++) {
083: if ((classmethods[j] != md)
084: && (methodName.equals(classmethods[j]
085: .name()))
086: && (classmethods[j].isNative()))
087: longName = true;
088:
089: }
090: pw.println("/*");
091: pw.println(" * Class: " + cname);
092: pw.println(" * Method: "
093: + Mangle.mangle(methodName,
094: Mangle.Type.FIELDSTUB));
095: pw.println(" * Signature: "
096: + newtypesig.getTypeSignature(sig, mtr));
097: pw.println(" */");
098: pw
099: .println("JNIEXPORT "
100: + jniType(mtr)
101: + " JNICALL "
102: + Mangle
103: .mangleMethod(
104: md,
105: root,
106: clazz,
107: (longName) ? Mangle.Type.METHOD_JNI_LONG
108: : Mangle.Type.METHOD_JNI_SHORT));
109: pw.print(" (JNIEnv *, ");
110: Parameter[] paramargs = md.parameters();
111: Type[] args = new Type[paramargs.length];
112: for (int p = 0; p < paramargs.length; p++) {
113: args[p] = paramargs[p].type();
114: }
115: if (md.isStatic())
116: pw.print("jclass");
117: else
118: pw.print("jobject");
119: if (args.length > 0)
120: pw.print(", ");
121:
122: for (int j = 0; j < args.length; j++) {
123: pw.print(jniType(args[j]));
124: if (j != (args.length - 1)) {
125: pw.print(", ");
126: }
127: }
128: pw.println(");" + lineSep);
129: }
130: }
131: pw.println(cppGuardEnd());
132: pw.println(guardEnd(cname));
133: }
134:
135: protected final String jniType(Type t) {
136:
137: String elmT = t.typeName();
138: ClassDoc throwable = root.classNamed("java.lang.Throwable");
139: ClassDoc jClass = root.classNamed("java.lang.Class");
140: ClassDoc tclassDoc = t.asClassDoc();
141:
142: if ((t.dimension()).indexOf("[]") != -1) {
143: if ((t.dimension().indexOf("[][]") != -1)
144: || (tclassDoc != null))
145: return "jobjectArray";
146: else if (elmT.equals("boolean"))
147: return "jbooleanArray";
148: else if (elmT.equals("byte"))
149: return "jbyteArray";
150: else if (elmT.equals("char"))
151: return "jcharArray";
152: else if (elmT.equals("short"))
153: return "jshortArray";
154: else if (elmT.equals("int"))
155: return "jintArray";
156: else if (elmT.equals("long"))
157: return "jlongArray";
158: else if (elmT.equals("float"))
159: return "jfloatArray";
160: else if (elmT.equals("double"))
161: return "jdoubleArray";
162: } else {
163: if (elmT.equals("void"))
164: return "void";
165: else if (elmT.equals("String"))
166: return "jstring";
167: else if (elmT.equals("boolean"))
168: return "jboolean";
169: else if (elmT.equals("byte"))
170: return "jbyte";
171: else if (elmT.equals("char"))
172: return "jchar";
173: else if (elmT.equals("short"))
174: return "jshort";
175: else if (elmT.equals("int"))
176: return "jint";
177: else if (elmT.equals("long"))
178: return "jlong";
179: else if (elmT.equals("float"))
180: return "jfloat";
181: else if (elmT.equals("double"))
182: return "jdouble";
183: else if (tclassDoc != null) {
184: if (tclassDoc.subclassOf(throwable))
185: return "jthrowable";
186: else if (tclassDoc.subclassOf(jClass))
187: return "jclass";
188: else
189: return "jobject";
190: }
191: }
192: Util.bug("jni.unknown.type");
193: return null; /* dead code. */
194: }
195: }
|