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.SAXReaderUtil;
024    import com.liferay.portal.tools.servicebuilder.ServiceBuilder;
025    
026    import com.thoughtworks.qdox.JavaDocBuilder;
027    import com.thoughtworks.qdox.model.DocletTag;
028    import com.thoughtworks.qdox.model.JavaClass;
029    import com.thoughtworks.qdox.model.JavaMethod;
030    import com.thoughtworks.qdox.model.JavaParameter;
031    import com.thoughtworks.qdox.model.Type;
032    import com.thoughtworks.qdox.model.TypeVariable;
033    
034    import java.io.File;
035    import java.io.IOException;
036    
037    import java.util.LinkedHashSet;
038    import java.util.List;
039    import java.util.Set;
040    
041    /**
042     * @author Brian Wing Shun Chan
043     */
044    public class InstanceWrapperBuilder {
045    
046            public static void main(String[] args) {
047                    ToolDependencies.wireBasic();
048    
049                    if (args.length == 1) {
050                            new InstanceWrapperBuilder(args[0]);
051                    }
052                    else {
053                            throw new IllegalArgumentException();
054                    }
055            }
056    
057            public InstanceWrapperBuilder(String xml) {
058                    try {
059                            File file = new File(xml);
060    
061                            Document document = SAXReaderUtil.read(file);
062    
063                            Element rootElement = document.getRootElement();
064    
065                            List<Element> instanceWrapperElements = rootElement.elements(
066                                    "instance-wrapper");
067    
068                            for (Element instanceWrapperElement : instanceWrapperElements) {
069                                    String parentDir = instanceWrapperElement.attributeValue(
070                                            "parent-dir");
071                                    String srcFile = instanceWrapperElement.attributeValue(
072                                            "src-file");
073    
074                                    _createIW(parentDir, srcFile);
075                            }
076                    }
077                    catch (Exception e) {
078                            e.printStackTrace();
079                    }
080            }
081    
082            private void _createIW(String parentDir, String srcFile)
083                    throws IOException {
084    
085                    JavaClass javaClass = _getJavaClass(parentDir, srcFile);
086    
087                    JavaMethod[] javaMethods = javaClass.getMethods();
088    
089                    StringBundler sb = new StringBundler();
090    
091                    // Package
092    
093                    sb.append("package ");
094                    sb.append(javaClass.getPackage().getName());
095                    sb.append(";");
096    
097                    // Class declaration
098    
099                    sb.append("public class ");
100                    sb.append(javaClass.getName());
101                    sb.append("_IW {");
102    
103                    // Methods
104    
105                    sb.append("public static ");
106                    sb.append(javaClass.getName());
107                    sb.append("_IW getInstance() {");
108                    sb.append("return _instance;");
109                    sb.append("}\n");
110    
111                    for (JavaMethod javaMethod : javaMethods) {
112                            String methodName = javaMethod.getName();
113    
114                            if (!javaMethod.isPublic() || !javaMethod.isStatic()) {
115                                    continue;
116                            }
117    
118                            if (methodName.equals("getInstance")) {
119                                    methodName = "getWrappedInstance";
120                            }
121    
122                            DocletTag[] docletTags = javaMethod.getTagsByName("deprecated");
123    
124                            if (ArrayUtil.isNotEmpty(docletTags)) {
125                                    sb.append("\t/**\n");
126                                    sb.append("\t * @deprecated\n");
127                                    sb.append("\t */\n");
128                                    sb.append("\t@Deprecated\n");
129                            }
130    
131                            sb.append("public ");
132    
133                            TypeVariable[] typeParameters = javaMethod.getTypeParameters();
134    
135                            if (typeParameters.length > 0) {
136                                    sb.append(" <");
137    
138                                    for (int i = 0; i < typeParameters.length; i++) {
139                                            TypeVariable typeParameter = typeParameters[i];
140    
141                                            sb.append(typeParameter.getName());
142                                            sb.append(", ");
143                                    }
144    
145                                    sb.setIndex(sb.index() - 1);
146    
147                                    sb.append("> ");
148                            }
149    
150                            sb.append(_getTypeGenericsName(javaMethod.getReturns()));
151                            sb.append(" ");
152                            sb.append(methodName);
153                            sb.append(StringPool.OPEN_PARENTHESIS);
154    
155                            JavaParameter[] javaParameters = javaMethod.getParameters();
156    
157                            for (int i = 0; i < javaParameters.length; i++) {
158                                    JavaParameter javaParameter = javaParameters[i];
159    
160                                    sb.append(_getTypeGenericsName(javaParameter.getType()));
161    
162                                    if (javaParameter.isVarArgs()) {
163                                            sb.append("...");
164                                    }
165    
166                                    sb.append(" ");
167                                    sb.append(javaParameter.getName());
168                                    sb.append(", ");
169                            }
170    
171                            if (javaParameters.length > 0) {
172                                    sb.setIndex(sb.index() - 1);
173                            }
174    
175                            sb.append(StringPool.CLOSE_PARENTHESIS);
176    
177                            Type[] thrownExceptions = javaMethod.getExceptions();
178    
179                            Set<String> newExceptions = new LinkedHashSet<String>();
180    
181                            for (int j = 0; j < thrownExceptions.length; j++) {
182                                    Type thrownException = thrownExceptions[j];
183    
184                                    newExceptions.add(thrownException.getValue());
185                            }
186    
187                            if (!newExceptions.isEmpty()) {
188                                    sb.append(" throws ");
189    
190                                    for (String newException : newExceptions) {
191                                            sb.append(newException);
192                                            sb.append(", ");
193                                    }
194    
195                                    sb.setIndex(sb.index() - 1);
196                            }
197    
198                            sb.append("{\n");
199    
200                            if (!javaMethod.getReturns().getValue().equals("void")) {
201                                    sb.append("return ");
202                            }
203    
204                            sb.append(javaClass.getName());
205                            sb.append(".");
206                            sb.append(javaMethod.getName());
207                            sb.append("(");
208    
209                            for (int j = 0; j < javaParameters.length; j++) {
210                                    JavaParameter javaParameter = javaParameters[j];
211    
212                                    sb.append(javaParameter.getName());
213                                    sb.append(", ");
214                            }
215    
216                            if (javaParameters.length > 0) {
217                                    sb.setIndex(sb.index() - 1);
218                            }
219    
220                            sb.append(");");
221                            sb.append("}\n");
222                    }
223    
224                    // Private constructor
225    
226                    sb.append("private ");
227                    sb.append(javaClass.getName());
228                    sb.append("_IW() {");
229                    sb.append("}");
230    
231                    // Fields
232    
233                    sb.append("private static ");
234                    sb.append(javaClass.getName());
235                    sb.append("_IW _instance = new ");
236                    sb.append(javaClass.getName());
237                    sb.append("_IW();");
238    
239                    // Class close brace
240    
241                    sb.append("}");
242    
243                    // Write file
244    
245                    File file = new File(
246                            parentDir + "/" +
247                                    StringUtil.replace(javaClass.getPackage().getName(), ".", "/") +
248                                            "/" + javaClass.getName() + "_IW.java");
249    
250                    ServiceBuilder.writeFile(file, sb.toString());
251            }
252    
253            private String _getDimensions(Type type) {
254                    String dimensions = "";
255    
256                    for (int i = 0; i < type.getDimensions(); i++) {
257                            dimensions += "[]";
258                    }
259    
260                    return dimensions;
261            }
262    
263            private JavaClass _getJavaClass(String parentDir, String srcFile)
264                    throws IOException {
265    
266                    String className = StringUtil.replace(
267                            srcFile.substring(0, srcFile.length() - 5), "/", ".");
268    
269                    JavaDocBuilder builder = new JavaDocBuilder();
270    
271                    builder.addSource(new File(parentDir + "/" + srcFile));
272    
273                    return builder.getClassByName(className);
274            }
275    
276            private String _getTypeGenericsName(Type type) {
277                    Type[] actualTypeArguments = type.getActualTypeArguments();
278    
279                    if (actualTypeArguments == null) {
280                            String value = type.getValue();
281    
282                            return value.concat(_getDimensions(type));
283                    }
284    
285                    StringBundler sb = new StringBundler(
286                            actualTypeArguments.length * 2 + 3);
287    
288                    sb.append(type.getValue());
289                    sb.append("<");
290    
291                    for (int i = 0; i < actualTypeArguments.length; i++) {
292                            sb.append(_getTypeGenericsName(actualTypeArguments[i]));
293                            sb.append(", ");
294                    }
295    
296                    if (actualTypeArguments.length > 0) {
297                            sb.setIndex(sb.index() - 1);
298                    }
299    
300                    sb.append(">");
301                    sb.append(_getDimensions(type));
302    
303                    return sb.toString();
304            }
305    
306    }