001 /*******************************************************************************
002 * Copyright (c) 2009 Progress Software, Inc.
003 * Copyright (c) 2004, 2007 IBM Corporation and others.
004 *
005 * All rights reserved. This program and the accompanying materials
006 * are made available under the terms of the Eclipse Public License v1.0
007 * which accompanies this distribution, and is available at
008 * http://www.eclipse.org/legal/epl-v10.html
009 *
010 *******************************************************************************/
011 package org.fusesource.hawtjni.generator;
012
013 import java.lang.reflect.Modifier;
014 import java.util.List;
015 import java.util.regex.Matcher;
016 import java.util.regex.Pattern;
017
018 import org.fusesource.hawtjni.generator.model.JNIClass;
019 import org.fusesource.hawtjni.generator.model.JNIMethod;
020 import org.fusesource.hawtjni.generator.model.JNIType;
021 import org.fusesource.hawtjni.generator.model.ReflectClass;
022 import org.fusesource.hawtjni.generator.model.ReflectType;
023
024 /**
025 *
026 * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
027 */
028 public class LockGenerator extends CleanupClass {
029
030 public LockGenerator() {
031 }
032
033 String getParams(JNIMethod method) {
034 int n_args = method.getParameters().size();
035 if (n_args == 0)
036 return "";
037 String name = method.getName();
038 String params = "";
039 int index = 0;
040 while (true) {
041 index = classSource.indexOf(name, index + 1);
042 if (!Character.isWhitespace(classSource.charAt(index - 1)))
043 continue;
044 if (index == -1)
045 return null;
046 int parantesesStart = classSource.indexOf("(", index);
047 if (classSource.substring(index + name.length(), parantesesStart).trim().length() == 0) {
048 int parantesesEnd = classSource.indexOf(")", parantesesStart);
049 params = classSource.substring(parantesesStart + 1, parantesesEnd);
050 break;
051 }
052 }
053 return params;
054 }
055
056 String getReturn(JNIMethod method) {
057 JNIType returnType = method.getReturnType32();
058 if (!returnType.isType("int"))
059 return returnType.getTypeSignature3(false);
060 String modifierStr = Modifier.toString(method.getModifiers());
061 String name = method.getName();
062 Pattern p = Pattern.compile(modifierStr + ".*" + name + ".*(.*)");
063 Matcher m = p.matcher(classSource);
064 if (m.find()) {
065 String methodStr = classSource.substring(m.start(), m.end());
066 int index = methodStr.indexOf("/*long*/");
067 if (index != -1 && index < methodStr.indexOf(name)) {
068 return new ReflectType(Integer.TYPE).getTypeSignature3(false) + " /*long*/";
069 }
070 }
071 return new ReflectType(Integer.TYPE).getTypeSignature3(false);
072 }
073
074 public void generate(JNIClass clazz) {
075 super.generate(clazz);
076 generate(clazz.getDeclaredMethods());
077 }
078
079 public void generate(List<JNIMethod> methods) {
080 sortMethods(methods);
081 for (JNIMethod method : methods) {
082 if ((method.getModifiers() & Modifier.NATIVE) == 0)
083 continue;
084 generate(method);
085 }
086 }
087
088 public void generate(JNIMethod method) {
089 int modifiers = method.getModifiers();
090 boolean lock = (modifiers & Modifier.SYNCHRONIZED) != 0;
091 String returnStr = getReturn(method);
092 String paramsStr = getParams(method);
093 if (lock) {
094 String modifiersStr = Modifier.toString(modifiers & ~Modifier.SYNCHRONIZED);
095 output(modifiersStr);
096 if (modifiersStr.length() > 0)
097 output(" ");
098 output(returnStr);
099 output(" _");
100 output(method.getName());
101 output("(");
102 output(paramsStr);
103 outputln(");");
104 }
105 String modifiersStr = Modifier.toString(modifiers & ~(Modifier.SYNCHRONIZED | (lock ? Modifier.NATIVE : 0)));
106 output(modifiersStr);
107 if (modifiersStr.length() > 0)
108 output(" ");
109 output(returnStr);
110 output(" ");
111 output(method.getName());
112 output("(");
113 output(paramsStr);
114 output(")");
115 if (lock) {
116 outputln(" {");
117 outputln("\tlock.lock();");
118 outputln("\ttry {");
119 output("\t\t");
120 if (!method.getReturnType32().isType("void")) {
121 output("return ");
122 }
123 output("_");
124 output(method.getName());
125 output("(");
126 String[] paramNames = getArgNames(method);
127 for (int i = 0; i < paramNames.length; i++) {
128 if (i != 0)
129 output(", ");
130 output(paramNames[i]);
131 }
132 outputln(");");
133 outputln("\t} finally {");
134 outputln("\t\tlock.unlock();");
135 outputln("\t}");
136 outputln("}");
137 } else {
138 outputln(";");
139 }
140 }
141
142 public static void main(String[] args) {
143 if (args.length < 2) {
144 System.out.println("Usage: java LockGenerator <OS className> <OS class source>");
145 return;
146 }
147 try {
148 LockGenerator gen = new LockGenerator();
149 String clazzName = args[0];
150 String classSource = args[1];
151 Class<?> clazz = Class.forName(clazzName);
152 gen.setClassSourcePath(classSource);
153 gen.generate(new ReflectClass(clazz));
154 } catch (Exception e) {
155 System.out.println("Problem");
156 e.printStackTrace(System.out);
157 }
158 }
159
160 }