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 }