/* * Copyright 2002-2005 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Sun designates this * particular file as subject to the "Classpath" exception as provided * by Sun in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ package com.sun.tools.javah; import java.io.OutputStream; import java.io.PrintWriter; import java.util.Vector; import java.util.Enumeration; import com.sun.javadoc.*; /** * Header file generator for JNI. * * @author Sucheta Dambalkar(Revised) */ public class JNI extends Gen { public JNI(RootDoc root){ super(root); } public String getIncludes() { return "#include <jni.h>"; } public void write(OutputStream o, ClassDoc clazz) throws ClassNotFoundException { String cname = Mangle.mangle(clazz.qualifiedName(), Mangle.Type.CLASS); PrintWriter pw = wrapWriter(o); pw.println(guardBegin(cname)); pw.println(cppGuardBegin()); /* Write statics. */ FieldDoc[] classfields = getAllFields(clazz); for (int i = 0; i < classfields.length; i++) { if (!classfields[i].isStatic()) continue; String s = null; s = defineForStatic(clazz, classfields[i]); if (s != null) { pw.println(s); } } /* Write methods. */ MethodDoc[] classmethods = clazz.methods(); for (int i = 0; i < classmethods.length; i++) { if(classmethods[i].isNative()){ MethodDoc md = classmethods[i]; Type mtr = classmethods[i].returnType(); String sig = md.signature(); TypeSignature newtypesig = new TypeSignature(root); String methodName = md.name(); boolean longName = false; for (int j = 0; j < classmethods.length; j++) { if ((classmethods[j] != md) && (methodName.equals(classmethods[j].name())) && (classmethods[j].isNative())) longName = true; } pw.println("/*"); pw.println(" * Class: " + cname); pw.println(" * Method: " + Mangle.mangle(methodName, Mangle.Type.FIELDSTUB)); pw.println(" * Signature: " + newtypesig.getTypeSignature(sig, mtr)); pw.println(" */"); pw.println("JNIEXPORT " + jniType(mtr) + " JNICALL " + Mangle.mangleMethod(md, root,clazz, (longName) ? Mangle.Type.METHOD_JNI_LONG : Mangle.Type.METHOD_JNI_SHORT)); pw.print(" (JNIEnv *, "); Parameter[] paramargs = md.parameters(); Type []args =new Type[ paramargs.length]; for(int p = 0; p < paramargs.length; p++){ args[p] = paramargs[p].type(); } if (md.isStatic()) pw.print("jclass"); else pw.print("jobject"); if (args.length > 0) pw.print(", "); for (int j = 0; j < args.length; j++) { pw.print(jniType(args[j])); if (j != (args.length - 1)) { pw.print(", "); } } pw.println(");" + lineSep); } } pw.println(cppGuardEnd()); pw.println(guardEnd(cname)); } protected final String jniType(Type t){ String elmT = t.typeName(); ClassDoc throwable = root.classNamed("java.lang.Throwable"); ClassDoc jClass = root.classNamed("java.lang.Class"); ClassDoc tclassDoc = t.asClassDoc(); if((t.dimension()).indexOf("[]") != -1){ if((t.dimension().indexOf("[][]") != -1) || (tclassDoc != null)) return "jobjectArray"; else if(elmT.equals("boolean"))return "jbooleanArray"; else if(elmT.equals("byte"))return "jbyteArray"; else if(elmT.equals("char"))return "jcharArray"; else if(elmT.equals("short"))return "jshortArray"; else if(elmT.equals("int"))return "jintArray"; else if(elmT.equals("long"))return "jlongArray"; else if(elmT.equals("float"))return "jfloatArray"; else if(elmT.equals("double"))return "jdoubleArray"; }else{ if(elmT.equals("void"))return "void"; else if(elmT.equals("String"))return "jstring"; else if(elmT.equals("boolean"))return "jboolean"; else if(elmT.equals("byte"))return "jbyte"; else if(elmT.equals("char"))return "jchar"; else if(elmT.equals("short"))return "jshort"; else if(elmT.equals("int"))return "jint"; else if(elmT.equals("long"))return "jlong"; else if(elmT.equals("float"))return "jfloat"; else if(elmT.equals("double"))return "jdouble"; else if(tclassDoc != null){ if(tclassDoc.subclassOf(throwable)) return "jthrowable"; else if(tclassDoc.subclassOf(jClass)) return "jclass"; else return "jobject"; } } Util.bug("jni.unknown.type"); return null; /* dead code. */ } }