/******************************************************************************* * Copyright (c) 2004, 2007 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.swt.tools.internal; import java.lang.reflect.Modifier; import java.util.regex.Matcher; import java.util.regex.Pattern; public class LockGenerator extends CleanupClass { public LockGenerator() { } String getParams(JNIMethod method) { int n_args = method.getParameters().length; if (n_args == 0) return ""; String name = method.getName(); String params = ""; int index = 0; while (true) { index = classSource.indexOf(name, index + 1); if (!Character.isWhitespace(classSource.charAt(index - 1))) continue; if (index == -1) return null; int parantesesStart = classSource.indexOf("(", index); if (classSource.substring(index + name.length(), parantesesStart).trim().length() == 0) { int parantesesEnd = classSource.indexOf(")", parantesesStart); params = classSource.substring(parantesesStart + 1, parantesesEnd); break; } } return params; } String getReturn(JNIMethod method) { JNIType returnType = method.getReturnType(); if (!returnType.isType("int")) return returnType.getTypeSignature3(false); String modifierStr = Modifier.toString(method.getModifiers()); String name = method.getName(); Pattern p = Pattern.compile(modifierStr + ".*" + name + ".*(.*)"); Matcher m = p.matcher(classSource); if (m.find()) { String methodStr = classSource.substring(m.start(), m.end()); int index = methodStr.indexOf("/*long*/"); if (index != -1 && index < methodStr.indexOf(name)) { return new ReflectType(Integer.TYPE).getTypeSignature3(false) + " /*long*/"; } } return new ReflectType(Integer.TYPE).getTypeSignature3(false); } @Override public void generate(JNIClass clazz) { super.generate(clazz); JNIMethod[] methods = clazz.getDeclaredMethods(); generate(methods); } public void generate(JNIMethod[] methods) { sort(methods); for (int i = 0; i < methods.length; i++) { JNIMethod method = methods[i]; if ((method.getModifiers() & Modifier.NATIVE) == 0) continue; generate(method); } } public void generate(JNIMethod method) { int modifiers = method.getModifiers(); boolean lock = (modifiers & Modifier.SYNCHRONIZED) != 0; String returnStr = getReturn(method); String paramsStr = getParams(method); if (lock) { String modifiersStr = Modifier.toString(modifiers & ~Modifier.SYNCHRONIZED); output(modifiersStr); if (modifiersStr.length() > 0) output(" "); output(returnStr); output(" _"); output(method.getName()); output("("); output(paramsStr); outputln(");"); } String modifiersStr = Modifier.toString(modifiers & ~(Modifier.SYNCHRONIZED | (lock ? Modifier.NATIVE : 0))); output(modifiersStr); if (modifiersStr.length() > 0) output(" "); output(returnStr); output(" "); output(method.getName()); output("("); output(paramsStr); output(")"); if (lock) { outputln(" {"); outputln("\tlock.lock();"); outputln("\ttry {"); output("\t\t"); if (!method.getReturnType().isType("void")) { output("return "); } output("_"); output(method.getName()); output("("); String[] paramNames = getArgNames(method); for (int i = 0; i < paramNames.length; i++) { if (i != 0) output(", "); output(paramNames[i]); } outputln(");"); outputln("\t} finally {"); outputln("\t\tlock.unlock();"); outputln("\t}"); outputln("}"); } else { outputln(";"); } } public static void main(String[] args) { if (args.length < 2) { System.out.println("Usage: java LockGenerator <OS className> <OS class source>"); return; } try { LockGenerator gen = new LockGenerator(); String clazzName = args[0]; String classSource = args[1]; Class<?> clazz = Class.forName(clazzName); gen.setClassSourcePath(classSource); gen.generate(new ReflectClass(clazz)); } catch (Exception e) { System.out.println("Problem"); e.printStackTrace(System.out); } } }