001    /**
002     * Copyright (c) 2000-present 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.ArrayUtil;
018    import com.liferay.portal.kernel.util.StringBundler;
019    import com.liferay.portal.kernel.util.StringPool;
020    import com.liferay.portal.kernel.util.StringUtil;
021    import com.liferay.portal.kernel.xml.Document;
022    import com.liferay.portal.kernel.xml.Element;
023    import com.liferay.portal.kernel.xml.UnsecureSAXReaderUtil;
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.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                    ToolDependencies.wireBasic();
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 = UnsecureSAXReaderUtil.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                    StringBundler sb = new StringBundler();
089    
090                    // Package
091    
092                    sb.append("package ");
093                    sb.append(javaClass.getPackage().getName());
094                    sb.append(";");
095    
096                    // Class declaration
097    
098                    sb.append("public class ");
099                    sb.append(javaClass.getName());
100                    sb.append("_IW {");
101    
102                    // Methods
103    
104                    sb.append("public static ");
105                    sb.append(javaClass.getName());
106                    sb.append("_IW getInstance() {return _instance;}\n");
107    
108                    for (JavaMethod javaMethod : javaMethods) {
109                            String methodName = javaMethod.getName();
110    
111                            if (!javaMethod.isPublic() || !javaMethod.isStatic()) {
112                                    continue;
113                            }
114    
115                            if (methodName.equals("getInstance")) {
116                                    methodName = "getWrappedInstance";
117                            }
118    
119                            DocletTag[] docletTags = javaMethod.getTagsByName("deprecated");
120    
121                            if (ArrayUtil.isNotEmpty(docletTags)) {
122                                    sb.append("\t/**\n");
123                                    sb.append("\t * @deprecated\n");
124                                    sb.append("\t */\n");
125                                    sb.append("\t@Deprecated\n");
126                            }
127    
128                            sb.append("public ");
129    
130                            TypeVariable[] typeParameters = javaMethod.getTypeParameters();
131    
132                            if (typeParameters.length > 0) {
133                                    sb.append(" <");
134    
135                                    for (int i = 0; i < typeParameters.length; i++) {
136                                            TypeVariable typeParameter = typeParameters[i];
137    
138                                            sb.append(typeParameter.getName());
139                                            sb.append(", ");
140                                    }
141    
142                                    sb.setIndex(sb.index() - 1);
143    
144                                    sb.append("> ");
145                            }
146    
147                            sb.append(_getTypeGenericsName(javaMethod.getReturnType()));
148                            sb.append(" ");
149                            sb.append(methodName);
150                            sb.append(StringPool.OPEN_PARENTHESIS);
151    
152                            JavaParameter[] javaParameters = javaMethod.getParameters();
153    
154                            for (int i = 0; i < javaParameters.length; i++) {
155                                    JavaParameter javaParameter = javaParameters[i];
156    
157                                    sb.append(_getTypeGenericsName(javaParameter.getType()));
158    
159                                    if (javaParameter.isVarArgs()) {
160                                            sb.append("...");
161                                    }
162    
163                                    sb.append(" ");
164                                    sb.append(javaParameter.getName());
165                                    sb.append(", ");
166                            }
167    
168                            if (javaParameters.length > 0) {
169                                    sb.setIndex(sb.index() - 1);
170                            }
171    
172                            sb.append(StringPool.CLOSE_PARENTHESIS);
173    
174                            Type[] thrownExceptions = javaMethod.getExceptions();
175    
176                            Set<String> newExceptions = new LinkedHashSet<>();
177    
178                            for (int j = 0; j < thrownExceptions.length; j++) {
179                                    Type thrownException = thrownExceptions[j];
180    
181                                    newExceptions.add(thrownException.getValue());
182                            }
183    
184                            if (!newExceptions.isEmpty()) {
185                                    sb.append(" throws ");
186    
187                                    for (String newException : newExceptions) {
188                                            sb.append(newException);
189                                            sb.append(", ");
190                                    }
191    
192                                    sb.setIndex(sb.index() - 1);
193                            }
194    
195                            sb.append("{\n");
196    
197                            if (!javaMethod.getReturnType().getValue().equals("void")) {
198                                    sb.append("return ");
199                            }
200    
201                            sb.append(javaClass.getName());
202                            sb.append(".");
203                            sb.append(javaMethod.getName());
204                            sb.append("(");
205    
206                            for (int j = 0; j < javaParameters.length; j++) {
207                                    JavaParameter javaParameter = javaParameters[j];
208    
209                                    sb.append(javaParameter.getName());
210                                    sb.append(", ");
211                            }
212    
213                            if (javaParameters.length > 0) {
214                                    sb.setIndex(sb.index() - 1);
215                            }
216    
217                            sb.append(");}\n");
218                    }
219    
220                    // Private constructor
221    
222                    sb.append("private ");
223                    sb.append(javaClass.getName());
224                    sb.append("_IW() {}");
225    
226                    // Fields
227    
228                    sb.append("private static ");
229                    sb.append(javaClass.getName());
230                    sb.append("_IW _instance = new ");
231                    sb.append(javaClass.getName());
232                    sb.append("_IW();");
233    
234                    // Class close brace
235    
236                    sb.append("}");
237    
238                    // Write file
239    
240                    File file = new File(
241                            parentDir + "/" +
242                                    StringUtil.replace(javaClass.getPackage().getName(), '.', '/') +
243                                            "/" + javaClass.getName() + "_IW.java");
244    
245                    ToolsUtil.writeFile(file, sb.toString(), null);
246            }
247    
248            private String _getDimensions(Type type) {
249                    String dimensions = "";
250    
251                    for (int i = 0; i < type.getDimensions(); i++) {
252                            dimensions += "[]";
253                    }
254    
255                    return dimensions;
256            }
257    
258            private JavaClass _getJavaClass(String parentDir, String srcFile)
259                    throws IOException {
260    
261                    String className = StringUtil.replace(
262                            srcFile.substring(0, srcFile.length() - 5), '/', '.');
263    
264                    JavaDocBuilder builder = new JavaDocBuilder();
265    
266                    builder.addSource(new File(parentDir + "/" + srcFile));
267    
268                    return builder.getClassByName(className);
269            }
270    
271            private String _getTypeGenericsName(Type type) {
272                    Type[] actualTypeArguments = type.getActualTypeArguments();
273    
274                    if (actualTypeArguments == null) {
275                            String value = type.getValue();
276    
277                            return value.concat(_getDimensions(type));
278                    }
279    
280                    StringBundler sb = new StringBundler(
281                            actualTypeArguments.length * 2 + 3);
282    
283                    sb.append(type.getValue());
284                    sb.append("<");
285    
286                    for (int i = 0; i < actualTypeArguments.length; i++) {
287                            sb.append(_getTypeGenericsName(actualTypeArguments[i]));
288                            sb.append(", ");
289                    }
290    
291                    if (actualTypeArguments.length > 0) {
292                            sb.setIndex(sb.index() - 1);
293                    }
294    
295                    sb.append(">");
296                    sb.append(_getDimensions(type));
297    
298                    return sb.toString();
299            }
300    
301    }