001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portal.tools;
016    
017    import com.liferay.portal.kernel.util.StringUtil;
018    import com.liferay.portal.kernel.xml.Document;
019    import com.liferay.portal.kernel.xml.DocumentException;
020    import com.liferay.portal.kernel.xml.Element;
021    import com.liferay.portal.kernel.xml.SAXReaderUtil;
022    import com.liferay.portal.tools.servicebuilder.ServiceBuilder;
023    import com.liferay.portal.util.InitUtil;
024    
025    import com.thoughtworks.qdox.JavaDocBuilder;
026    import com.thoughtworks.qdox.model.DocletTag;
027    import com.thoughtworks.qdox.model.JavaClass;
028    import com.thoughtworks.qdox.model.JavaMethod;
029    import com.thoughtworks.qdox.model.JavaParameter;
030    import com.thoughtworks.qdox.model.Type;
031    import com.thoughtworks.qdox.model.TypeVariable;
032    
033    import java.io.File;
034    import java.io.IOException;
035    
036    import java.util.Iterator;
037    import java.util.LinkedHashSet;
038    import java.util.Set;
039    
040    /**
041     * @author Brian Wing Shun Chan
042     */
043    public class InstanceWrapperBuilder {
044    
045            public static void main(String[] args) {
046                    InitUtil.initWithSpring();
047    
048                    if (args.length == 1) {
049                            new InstanceWrapperBuilder(args[0]);
050                    }
051                    else {
052                            throw new IllegalArgumentException();
053                    }
054            }
055    
056            public InstanceWrapperBuilder(String xml) {
057                    try {
058                            File file = new File(xml);
059    
060                            Document doc = null;
061    
062                            try {
063                                    doc = SAXReaderUtil.read(file);
064                            }
065                            catch (DocumentException de) {
066                                    de.printStackTrace();
067                            }
068    
069                            Element root = doc.getRootElement();
070    
071                            Iterator<Element> itr = root.elements(
072                                    "instance-wrapper").iterator();
073    
074                            while (itr.hasNext()) {
075                                    Element instanceWrapper = itr.next();
076    
077                                    String parentDir = instanceWrapper.attributeValue("parent-dir");
078                                    String srcFile = instanceWrapper.attributeValue("src-file");
079    
080                                    _createIW(parentDir, srcFile);
081                            }
082                    }
083                    catch (Exception e) {
084                            e.printStackTrace();
085                    }
086            }
087    
088            private void _createIW(String parentDir, String srcFile)
089                    throws IOException {
090    
091                    JavaClass javaClass = _getJavaClass(parentDir, srcFile);
092    
093                    JavaMethod[] methods = javaClass.getMethods();
094    
095                    StringBuilder sb = new StringBuilder();
096    
097                    // Package
098    
099                    sb.append("package " + javaClass.getPackage().getName() + ";");
100    
101                    // Class declaration
102    
103                    sb.append("public class " + javaClass.getName() + "_IW {");
104    
105                    // Methods
106    
107                    sb.append("public static " + javaClass.getName() + "_IW getInstance() {");
108                    sb.append("return _instance;");
109                    sb.append("}\n");
110    
111                    for (int i = 0; i < methods.length; i++) {
112                            JavaMethod javaMethod = methods[i];
113    
114                            String methodName = javaMethod.getName();
115    
116                            if (!javaMethod.isPublic() || !javaMethod.isStatic()) {
117                                    continue;
118                            }
119    
120                            if (methodName.equals("getInstance")) {
121                                    methodName = "getWrappedInstance";
122                            }
123    
124                            DocletTag[] docletTags = javaMethod.getTagsByName("deprecated");
125    
126                            if ((docletTags != null) && (docletTags.length > 0)) {
127                                    sb.append("\t/**\n");
128                                    sb.append("\t * @deprecated\n");
129                                    sb.append("\t */\n");
130                            }
131    
132                            sb.append("public ");
133    
134                            TypeVariable[] typeParameters = javaMethod.getTypeParameters();
135    
136                            if (typeParameters.length > 0) {
137                                    sb.append(" " + typeParameters[0].getGenericValue() + " ");
138                            }
139    
140                            sb.append(_getTypeGenericsName(javaMethod.getReturns()) + " " + methodName + "(");
141    
142                            JavaParameter[] parameters = javaMethod.getParameters();
143    
144                            for (int j = 0; j < parameters.length; j++) {
145                                    JavaParameter javaParameter = parameters[j];
146    
147                                    sb.append(_getTypeGenericsName(javaParameter.getType()));
148    
149                                    if (javaParameter.isVarArgs()) {
150                                            sb.append("...");
151                                    }
152    
153                                    sb.append(" " + javaParameter.getName());
154    
155                                    if ((j + 1) != parameters.length) {
156                                            sb.append(", ");
157                                    }
158                            }
159    
160                            sb.append(")");
161    
162                            Type[] thrownExceptions = javaMethod.getExceptions();
163    
164                            Set<String> newExceptions = new LinkedHashSet<String>();
165    
166                            for (int j = 0; j < thrownExceptions.length; j++) {
167                                    Type thrownException = thrownExceptions[j];
168    
169                                    newExceptions.add(thrownException.getValue());
170                            }
171    
172                            if (newExceptions.size() > 0) {
173                                    sb.append(" throws ");
174    
175                                    Iterator<String> itr = newExceptions.iterator();
176    
177                                    while (itr.hasNext()) {
178                                            sb.append(itr.next());
179    
180                                            if (itr.hasNext()) {
181                                                    sb.append(", ");
182                                            }
183                                    }
184                            }
185    
186                            sb.append("{\n");
187    
188                            if (!javaMethod.getReturns().getValue().equals("void")) {
189                                    sb.append("return ");
190                            }
191    
192                            sb.append(javaClass.getName() + "." + javaMethod.getName() + "(");
193    
194                            for (int j = 0; j < parameters.length; j++) {
195                                    JavaParameter javaParameter = parameters[j];
196    
197                                    sb.append(javaParameter.getName());
198    
199                                    if ((j + 1) != parameters.length) {
200                                            sb.append(", ");
201                                    }
202                            }
203    
204                            sb.append(");");
205                            sb.append("}\n");
206                    }
207    
208                    // Private constructor
209    
210                    sb.append("private " + javaClass.getName() + "_IW() {");
211                    sb.append("}");
212    
213                    // Fields
214    
215                    sb.append("private static " + javaClass.getName() + "_IW _instance = new " + javaClass.getName() + "_IW();");
216    
217                    // Class close brace
218    
219                    sb.append("}");
220    
221                    // Write file
222    
223                    File file = new File(parentDir + "/" + StringUtil.replace(javaClass.getPackage().getName(), ".", "/") + "/" + javaClass.getName() + "_IW.java");
224    
225                    ServiceBuilder.writeFile(file, sb.toString());
226            }
227    
228            private String _getDimensions(Type type) {
229                    String dimensions = "";
230    
231                    for (int i = 0; i < type.getDimensions(); i++) {
232                            dimensions += "[]";
233                    }
234    
235                    return dimensions;
236            }
237    
238            private JavaClass _getJavaClass(String parentDir, String srcFile)
239                    throws IOException {
240    
241                    String className = StringUtil.replace(
242                            srcFile.substring(0, srcFile.length() - 5), "/", ".");
243    
244                    JavaDocBuilder builder = new JavaDocBuilder();
245    
246                    builder.addSource(new File(parentDir + "/" + srcFile));
247    
248                    return builder.getClassByName(className);
249            }
250    
251            private String _getTypeGenericsName(Type type) {
252                    StringBuilder sb = new StringBuilder();
253    
254                    sb.append(type.getValue());
255    
256                    Type[] actualTypeArguments = type.getActualTypeArguments();
257    
258                    if (actualTypeArguments != null) {
259                            sb.append("<");
260    
261                            for (int i = 0; i < actualTypeArguments.length; i++) {
262                                    if (i > 0) {
263                                            sb.append(", ");
264                                    }
265    
266                                    sb.append(_getTypeGenericsName(actualTypeArguments[i]));
267                            }
268    
269                            sb.append(">");
270                    }
271    
272                    sb.append(_getDimensions(type));
273    
274                    return sb.toString();
275            }
276    
277    }