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 *******************************************************************************/
011package org.fusesource.hawtjni.generator;
012
013import java.lang.reflect.Modifier;
014import java.util.List;
015import java.util.regex.Matcher;
016import java.util.regex.Pattern;
017
018import org.fusesource.hawtjni.generator.model.JNIClass;
019import org.fusesource.hawtjni.generator.model.JNIMethod;
020import org.fusesource.hawtjni.generator.model.JNIType;
021import org.fusesource.hawtjni.generator.model.ReflectClass;
022import org.fusesource.hawtjni.generator.model.ReflectType;
023
024/**
025 * 
026 * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
027 */
028public 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}