001 /******************************************************************************* 002 * Copyright (C) 2009-2011 FuseSource Corp. 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 }