1 11 package org.eclipse.swt.tools.internal; 12 13 import java.io.*; 14 import java.lang.reflect.*; 15 import java.util.*; 16 17 import org.eclipse.swt.SWT; 18 19 public abstract class JNIGenerator { 20 21 Class mainClass; 22 Class [] classes; 23 MetaData metaData; 24 boolean isCPP; 25 String delimiter; 26 PrintStream output; 27 ProgressMonitor progress; 28 29 public JNIGenerator() { 30 delimiter = System.getProperty("line.separator"); 31 output = System.out; 32 metaData = new MetaData(new Properties()); 33 } 34 35 String fixDelimiter(String str) { 36 if (delimiter.equals("\n")) return str; 37 int index = 0, length = str.length(); 38 StringBuffer buffer = new StringBuffer (); 39 while (index != -1) { 40 int start = index; 41 index = str.indexOf('\n', start); 42 if (index == -1) { 43 buffer.append(str.substring(start, length)); 44 } else { 45 buffer.append(str.substring(start, index)); 46 buffer.append(delimiter); 47 index++; 48 } 49 } 50 return buffer.toString(); 51 } 52 53 static String getClassName(Class clazz) { 54 String name = clazz.getName(); 55 int index = name.lastIndexOf('.') + 1; 56 return name.substring(index, name.length()); 57 } 58 59 static String getFunctionName(Method method) { 60 return getFunctionName(method, method.getParameterTypes()); 61 } 62 63 static String getFunctionName(Method method, Class [] paramTypes) { 64 if ((method.getModifiers() & Modifier.NATIVE) == 0) return method.getName(); 65 String function = toC(method.getName()); 66 if (!isNativeUnique(method)) { 67 StringBuffer buffer = new StringBuffer (); 68 buffer.append(function); 69 buffer.append("__"); 70 if (paramTypes.length > 0) { 71 for (int i = 0; i < paramTypes.length; i++) { 72 Class paramType = paramTypes[i]; 73 buffer.append(toC(getTypeSignature(paramType))); 74 } 75 } 76 return buffer.toString(); 77 } 78 return function; 79 } 80 81 static int getByteCount(Class clazz) { 82 if (clazz == Integer.TYPE) return 4; 83 if (clazz == Boolean.TYPE) return 4; 84 if (clazz == Long.TYPE) return 8; 85 if (clazz == Short.TYPE) return 2; 86 if (clazz == Character.TYPE) return 2; 87 if (clazz == Byte.TYPE) return 1; 88 if (clazz == Float.TYPE) return 4; 89 if (clazz == Double.TYPE) return 8; 90 return 4; 91 } 92 93 static String getTypeSignature(Class clazz) { 94 if (clazz == Void.TYPE) return "V"; 95 if (clazz == Integer.TYPE) return "I"; 96 if (clazz == Boolean.TYPE) return "Z"; 97 if (clazz == Long.TYPE) return "J"; 98 if (clazz == Short.TYPE) return "S"; 99 if (clazz == Character.TYPE) return "C"; 100 if (clazz == Byte.TYPE) return "B"; 101 if (clazz == Float.TYPE) return "F"; 102 if (clazz == Double.TYPE) return "D"; 103 if (clazz == String .class) return "Ljava/lang/String;"; 104 if (clazz.isArray()) { 105 Class componentType = clazz.getComponentType(); 106 return "[" + getTypeSignature(componentType); 107 } 108 return "L" + clazz.getName().replace('.', '/') + ";"; 109 } 110 111 static String getTypeSignature1(Class clazz) { 112 if (clazz == Void.TYPE) return "Void"; 113 if (clazz == Integer.TYPE) return "Int"; 114 if (clazz == Boolean.TYPE) return "Boolean"; 115 if (clazz == Long.TYPE) return "Long"; 116 if (clazz == Short.TYPE) return "Short"; 117 if (clazz == Character.TYPE) return "Char"; 118 if (clazz == Byte.TYPE) return "Byte"; 119 if (clazz == Float.TYPE) return "Float"; 120 if (clazz == Double.TYPE) return "Double"; 121 if (clazz == String .class) return "String"; 122 return "Object"; 123 } 124 125 static String getTypeSignature2(Class clazz) { 126 if (clazz == Void.TYPE) return "void"; 127 if (clazz == Integer.TYPE) return "jint"; 128 if (clazz == Boolean.TYPE) return "jboolean"; 129 if (clazz == Long.TYPE) return "jlong"; 130 if (clazz == Short.TYPE) return "jshort"; 131 if (clazz == Character.TYPE) return "jchar"; 132 if (clazz == Byte.TYPE) return "jbyte"; 133 if (clazz == Float.TYPE) return "jfloat"; 134 if (clazz == Double.TYPE) return "jdouble"; 135 if (clazz == String .class) return "jstring"; 136 if (clazz == Class .class) return "jclass"; 137 if (clazz.isArray()) { 138 Class componentType = clazz.getComponentType(); 139 return getTypeSignature2(componentType) + "Array"; 140 } 141 return "jobject"; 142 } 143 144 static String getTypeSignature3(Class clazz) { 145 if (clazz == Void.TYPE) return "void"; 146 if (clazz == Integer.TYPE) return "int"; 147 if (clazz == Boolean.TYPE) return "boolean"; 148 if (clazz == Long.TYPE) return "long"; 149 if (clazz == Short.TYPE) return "short"; 150 if (clazz == Character.TYPE) return "char"; 151 if (clazz == Byte.TYPE) return "byte"; 152 if (clazz == Float.TYPE) return "float"; 153 if (clazz == Double.TYPE) return "double"; 154 if (clazz == String .class) return "String"; 155 if (clazz.isArray()) { 156 Class componentType = clazz.getComponentType(); 157 return getTypeSignature3(componentType) + "[]"; 158 } 159 return clazz.getName(); 160 } 161 162 static String getTypeSignature4(Class clazz) { 163 if (clazz == Void.TYPE) return "void"; 164 if (clazz == Integer.TYPE) return "jint"; 165 if (clazz == Boolean.TYPE) return "jboolean"; 166 if (clazz == Long.TYPE) return "jlong"; 167 if (clazz == Short.TYPE) return "jshort"; 168 if (clazz == Character.TYPE) return "jchar"; 169 if (clazz == Byte.TYPE) return "jbyte"; 170 if (clazz == Float.TYPE) return "jfloat"; 171 if (clazz == Double.TYPE) return "jdouble"; 172 if (clazz == String .class) return "jstring"; 173 if (clazz.isArray()) { 174 Class componentType = clazz.getComponentType(); 175 return getTypeSignature4(componentType) + " *"; 176 } 177 return getClassName(clazz) + " *"; 178 } 179 180 static HashMap uniqueCache = new HashMap(); 181 static Class uniqueClassCache; 182 static Method[] uniqueMethodsCache; 183 static synchronized boolean isNativeUnique(Method method) { 184 if ((method.getModifiers() & Modifier.NATIVE) == 0) return false; 185 Object unique = uniqueCache.get(method); 186 if (unique != null) return ((Boolean )unique).booleanValue(); 187 boolean result = true; 188 Method[] methods; 189 String name = method.getName(); 190 Class clazz = method.getDeclaringClass(); 191 if (clazz.equals(uniqueClassCache)) { 192 methods = uniqueMethodsCache; 193 } else { 194 methods = clazz.getDeclaredMethods(); 195 uniqueClassCache = clazz; 196 uniqueMethodsCache = methods; 197 } 198 for (int i = 0; i < methods.length; i++) { 199 Method mth = methods[i]; 200 if ((mth.getModifiers() & Modifier.NATIVE) != 0 && 201 method != mth && !method.equals(mth) && 202 name.equals(mth.getName())) 203 { 204 result = false; 205 break; 206 } 207 } 208 uniqueCache.put(method, new Boolean (result)); 209 return result; 210 } 211 212 static void sort(Method[] methods) { 213 Arrays.sort(methods, new Comparator() { 214 public int compare(Object a, Object b) { 215 Method mth1 = (Method)a; 216 Method mth2 = (Method)b; 217 int result = mth1.getName().compareTo(mth2.getName()); 218 return result != 0 ? result : getFunctionName(mth1).compareTo(getFunctionName(mth2)); 219 } 220 }); 221 } 222 223 static void sort(Field[] fields) { 224 Arrays.sort(fields, new Comparator() { 225 public int compare(Object a, Object b) { 226 return ((Field)a).getName().compareTo(((Field)b).getName()); 227 } 228 }); 229 } 230 231 static void sort(Class [] classes) { 232 Arrays.sort(classes, new Comparator() { 233 public int compare(Object a, Object b) { 234 return ((Class )a).getName().compareTo(((Class )b).getName()); 235 } 236 }); 237 } 238 239 static String toC(String str) { 240 int length = str.length(); 241 StringBuffer buffer = new StringBuffer (length * 2); 242 for (int i = 0; i < length; i++) { 243 char c = str.charAt(i); 244 switch (c) { 245 case '_': buffer.append("_1"); break; 246 case ';': buffer.append("_2"); break; 247 case '[': buffer.append("_3"); break; 248 case '.': buffer.append("_"); break; 249 case '/': buffer.append("_"); break; 250 default: buffer.append(c); 251 } 252 } 253 return buffer.toString(); 254 } 255 256 public abstract void generate(Class clazz); 257 258 public void generateCopyright() { 259 } 260 261 public void generateIncludes() { 262 } 263 264 public void generate() { 265 if (classes == null) return; 266 generateCopyright(); 267 generateIncludes(); 268 sort(classes); 269 for (int i = 0; i < classes.length; i++) { 270 Class clazz = classes[i]; 271 ClassData data = getMetaData().getMetaData(clazz); 272 if (data.getFlag("cpp")) { 273 isCPP = true; 274 break; 275 } 276 } 277 for (int i = 0; i < classes.length; i++) { 278 Class clazz = classes[i]; 279 if (getGenerate(clazz)) generate(clazz); 280 if (progress != null) progress.step(); 281 } 282 output.flush(); 283 } 284 285 public void generateMetaData(String key) { 286 MetaData mt = getMetaData(); 287 String data = mt.getMetaData(key, null); 288 if (data == null) return; 289 if (data.length() == 0) return; 290 outputln(fixDelimiter(data)); 291 } 292 293 public Class [] getClasses() { 294 return classes; 295 } 296 297 protected boolean getGenerate(Class clazz) { 298 ClassData data = getMetaData().getMetaData(clazz); 299 return !data.getFlag("no_gen"); 300 } 301 302 public boolean getCPP() { 303 return isCPP; 304 } 305 306 public String getDelimiter() { 307 return delimiter; 308 } 309 310 public String getExtension() { 311 return getCPP() ? ".cpp" : ".c"; 312 } 313 314 public String getFileName() { 315 return getOutputName() + getSuffix() + getExtension(); 316 } 317 318 public PrintStream getOutput() { 319 return output; 320 } 321 322 public String getOutputName() { 323 return getClassName(getMainClass()).toLowerCase(); 324 } 325 326 public Class getMainClass() { 327 return mainClass; 328 } 329 330 public MetaData getMetaData() { 331 return metaData; 332 } 333 334 public String getPlatform() { 335 return SWT.getPlatform(); 336 } 337 338 public ProgressMonitor getProgressMonitor() { 339 return progress; 340 } 341 342 public String getSuffix() { 343 return ""; 344 } 345 346 public void output(String str) { 347 output.print(str); 348 } 349 350 public void outputln() { 351 output(getDelimiter()); 352 } 353 354 public void outputln(String str) { 355 output(str); 356 output(getDelimiter()); 357 } 358 359 public void setClasses(Class [] classes) { 360 this.classes = classes; 361 } 362 363 public void setDelimiter(String delimiter) { 364 this.delimiter = delimiter; 365 } 366 367 public void setMainClass(Class mainClass) { 368 this.mainClass = mainClass; 369 } 370 371 public void setMetaData(MetaData data) { 372 metaData = data; 373 } 374 375 public void setOutput(PrintStream output) { 376 this.output = output; 377 } 378 379 public void setProgressMonitor(ProgressMonitor progress) { 380 this.progress = progress; 381 } 382 383 } 384 | Popular Tags |