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    }