001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
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.Element;
020    import com.liferay.portal.kernel.xml.SAXReaderUtil;
021    import com.liferay.portal.tools.servicebuilder.ServiceBuilder;
022    import com.liferay.portal.util.InitUtil;
023    
024    import com.thoughtworks.qdox.JavaDocBuilder;
025    import com.thoughtworks.qdox.model.DocletTag;
026    import com.thoughtworks.qdox.model.JavaClass;
027    import com.thoughtworks.qdox.model.JavaMethod;
028    import com.thoughtworks.qdox.model.JavaParameter;
029    import com.thoughtworks.qdox.model.Type;
030    import com.thoughtworks.qdox.model.TypeVariable;
031    
032    import java.io.File;
033    import java.io.IOException;
034    
035    import java.util.Iterator;
036    import java.util.LinkedHashSet;
037    import java.util.List;
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 document = SAXReaderUtil.read(file);
061    
062                            Element rootElement = document.getRootElement();
063    
064                            List<Element> instanceWrapperElements = rootElement.elements(
065                                    "instance-wrapper");
066    
067                            for (Element instanceWrapperElement : instanceWrapperElements) {
068                                    String parentDir = instanceWrapperElement.attributeValue(
069                                            "parent-dir");
070                                    String srcFile = instanceWrapperElement.attributeValue(
071                                            "src-file");
072    
073                                    _createIW(parentDir, srcFile);
074                            }
075                    }
076                    catch (Exception e) {
077                            e.printStackTrace();
078                    }
079            }
080    
081            private void _createIW(String parentDir, String srcFile)
082                    throws IOException {
083    
084                    JavaClass javaClass = _getJavaClass(parentDir, srcFile);
085    
086                    JavaMethod[] javaMethods = javaClass.getMethods();
087    
088                    StringBuilder sb = new StringBuilder();
089    
090                    // Package
091    
092                    sb.append("package " + javaClass.getPackage().getName() + ";");
093    
094                    // Class declaration
095    
096                    sb.append("public class " + javaClass.getName() + "_IW {");
097    
098                    // Methods
099    
100                    sb.append(
101                            "public static " + javaClass.getName() + "_IW getInstance() {");
102                    sb.append("return _instance;");
103                    sb.append("}\n");
104    
105                    for (JavaMethod javaMethod : javaMethods) {
106                            String methodName = javaMethod.getName();
107    
108                            if (!javaMethod.isPublic() || !javaMethod.isStatic()) {
109                                    continue;
110                            }
111    
112                            if (methodName.equals("getInstance")) {
113                                    methodName = "getWrappedInstance";
114                            }
115    
116                            DocletTag[] docletTags = javaMethod.getTagsByName("deprecated");
117    
118                            if ((docletTags != null) && (docletTags.length > 0)) {
119                                    sb.append("\t/**\n");
120                                    sb.append("\t * @deprecated\n");
121                                    sb.append("\t */\n");
122                            }
123    
124                            sb.append("public ");
125    
126                            TypeVariable[] typeParameters = javaMethod.getTypeParameters();
127    
128                            if (typeParameters.length > 0) {
129                                    sb.append(" <");
130    
131                                    for (int i = 0; i < typeParameters.length; i++) {
132                                            TypeVariable typeParameter = typeParameters[i];
133    
134                                            sb.append(typeParameter.getName());
135    
136                                            if ((i + 1) != typeParameters.length) {
137                                                    sb.append(", ");
138                                            }
139                                    }
140    
141                                    sb.append("> ");
142                            }
143    
144                            sb.append(
145                                    _getTypeGenericsName(
146                                            javaMethod.getReturns()) + " " + methodName + "(");
147    
148                            JavaParameter[] javaParameters = javaMethod.getParameters();
149    
150                            for (int i = 0; i < javaParameters.length; i++) {
151                                    JavaParameter javaParameter = javaParameters[i];
152    
153                                    sb.append(_getTypeGenericsName(javaParameter.getType()));
154    
155                                    if (javaParameter.isVarArgs()) {
156                                            sb.append("...");
157                                    }
158    
159                                    sb.append(" " + javaParameter.getName());
160    
161                                    if ((i + 1) != javaParameters.length) {
162                                            sb.append(", ");
163                                    }
164                            }
165    
166                            sb.append(")");
167    
168                            Type[] thrownExceptions = javaMethod.getExceptions();
169    
170                            Set<String> newExceptions = new LinkedHashSet<String>();
171    
172                            for (int j = 0; j < thrownExceptions.length; j++) {
173                                    Type thrownException = thrownExceptions[j];
174    
175                                    newExceptions.add(thrownException.getValue());
176                            }
177    
178                            if (newExceptions.size() > 0) {
179                                    sb.append(" throws ");
180    
181                                    Iterator<String> itr = newExceptions.iterator();
182    
183                                    while (itr.hasNext()) {
184                                            sb.append(itr.next());
185    
186                                            if (itr.hasNext()) {
187                                                    sb.append(", ");
188                                            }
189                                    }
190                            }
191    
192                            sb.append("{\n");
193    
194                            if (!javaMethod.getReturns().getValue().equals("void")) {
195                                    sb.append("return ");
196                            }
197    
198                            sb.append(javaClass.getName() + "." + javaMethod.getName() + "(");
199    
200                            for (int j = 0; j < javaParameters.length; j++) {
201                                    JavaParameter javaParameter = javaParameters[j];
202    
203                                    sb.append(javaParameter.getName());
204    
205                                    if ((j + 1) != javaParameters.length) {
206                                            sb.append(", ");
207                                    }
208                            }
209    
210                            sb.append(");");
211                            sb.append("}\n");
212                    }
213    
214                    // Private constructor
215    
216                    sb.append("private " + javaClass.getName() + "_IW() {");
217                    sb.append("}");
218    
219                    // Fields
220    
221                    sb.append(
222                            "private static " + javaClass.getName() + "_IW _instance = new " +
223                                    javaClass.getName() + "_IW();");
224    
225                    // Class close brace
226    
227                    sb.append("}");
228    
229                    // Write file
230    
231                    File file = new File(
232                            parentDir + "/" +
233                                    StringUtil.replace(javaClass.getPackage().getName(), ".", "/") +
234                                            "/" + javaClass.getName() + "_IW.java");
235    
236                    ServiceBuilder.writeFile(file, sb.toString());
237            }
238    
239            private String _getDimensions(Type type) {
240                    String dimensions = "";
241    
242                    for (int i = 0; i < type.getDimensions(); i++) {
243                            dimensions += "[]";
244                    }
245    
246                    return dimensions;
247            }
248    
249            private JavaClass _getJavaClass(String parentDir, String srcFile)
250                    throws IOException {
251    
252                    String className = StringUtil.replace(
253                            srcFile.substring(0, srcFile.length() - 5), "/", ".");
254    
255                    JavaDocBuilder builder = new JavaDocBuilder();
256    
257                    builder.addSource(new File(parentDir + "/" + srcFile));
258    
259                    return builder.getClassByName(className);
260            }
261    
262            private String _getTypeGenericsName(Type type) {
263                    StringBuilder sb = new StringBuilder();
264    
265                    sb.append(type.getValue());
266    
267                    Type[] actualTypeArguments = type.getActualTypeArguments();
268    
269                    if (actualTypeArguments != null) {
270                            sb.append("<");
271    
272                            for (int i = 0; i < actualTypeArguments.length; i++) {
273                                    if (i > 0) {
274                                            sb.append(", ");
275                                    }
276    
277                                    sb.append(_getTypeGenericsName(actualTypeArguments[i]));
278                            }
279    
280                            sb.append(">");
281                    }
282    
283                    sb.append(_getDimensions(type));
284    
285                    return sb.toString();
286            }
287    
288    }