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 /**
036 * Header file generator for JNI.
037 *
038 * @author Sucheta Dambalkar(Revised)
039 */
040
041 public class JNI extends Gen {
042
043 public JNI(RootDoc root){
044 super(root);
045 }
046
047 public String getIncludes() {
048 return "#include <jni.h>";
049 }
050
051 public void write(OutputStream o, ClassDoc clazz)
052 throws ClassNotFoundException {
053
054 String cname = Mangle.mangle(clazz.qualifiedName(), 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].name()))
085 && (classmethods[j].isNative()))
086 longName = true;
087
088 }
089 pw.println("/*");
090 pw.println(" * Class: " + cname);
091 pw.println(" * Method: " +
092 Mangle.mangle(methodName, Mangle.Type.FIELDSTUB));
093 pw.println(" * Signature: " + newtypesig.getTypeSignature(sig, mtr));
094 pw.println(" */");
095 pw.println("JNIEXPORT " + jniType(mtr) +
096 " JNICALL " +
097 Mangle.mangleMethod(md, root,clazz,
098 (longName) ?
099 Mangle.Type.METHOD_JNI_LONG :
100 Mangle.Type.METHOD_JNI_SHORT));
101 pw.print(" (JNIEnv *, ");
102 Parameter[] paramargs = md.parameters();
103 Type []args =new Type[ paramargs.length];
104 for(int p = 0; p < paramargs.length; p++){
105 args[p] = paramargs[p].type();
106 }
107 if (md.isStatic())
108 pw.print("jclass");
109 else
110 pw.print("jobject");
111 if (args.length > 0)
112 pw.print(", ");
113
114 for (int j = 0; j < args.length; j++) {
115 pw.print(jniType(args[j]));
116 if (j != (args.length - 1)) {
117 pw.print(", ");
118 }
119 }
120 pw.println(");" + lineSep);
121 }
122 }
123 pw.println(cppGuardEnd());
124 pw.println(guardEnd(cname));
125 }
126
127
128 protected final String jniType(Type t){
129
130 String elmT = t.typeName();
131 ClassDoc throwable = root.classNamed("java.lang.Throwable");
132 ClassDoc jClass = root.classNamed("java.lang.Class");
133 ClassDoc tclassDoc = t.asClassDoc();
134
135 if((t.dimension()).indexOf("[]") != -1){
136 if((t.dimension().indexOf("[][]") != -1)
137 || (tclassDoc != null)) return "jobjectArray";
138 else if(elmT.equals("boolean"))return "jbooleanArray";
139 else if(elmT.equals("byte"))return "jbyteArray";
140 else if(elmT.equals("char"))return "jcharArray";
141 else if(elmT.equals("short"))return "jshortArray";
142 else if(elmT.equals("int"))return "jintArray";
143 else if(elmT.equals("long"))return "jlongArray";
144 else if(elmT.equals("float"))return "jfloatArray";
145 else if(elmT.equals("double"))return "jdoubleArray";
146 }else{
147 if(elmT.equals("void"))return "void";
148 else if(elmT.equals("String"))return "jstring";
149 else if(elmT.equals("boolean"))return "jboolean";
150 else if(elmT.equals("byte"))return "jbyte";
151 else if(elmT.equals("char"))return "jchar";
152 else if(elmT.equals("short"))return "jshort";
153 else if(elmT.equals("int"))return "jint";
154 else if(elmT.equals("long"))return "jlong";
155 else if(elmT.equals("float"))return "jfloat";
156 else if(elmT.equals("double"))return "jdouble";
157 else if(tclassDoc != null){
158 if(tclassDoc.subclassOf(throwable)) return "jthrowable";
159 else if(tclassDoc.subclassOf(jClass)) return "jclass";
160 else return "jobject";
161 }
162 }
163 Util.bug("jni.unknown.type");
164 return null; /* dead code. */
165 }
166 }