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.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    import com.liferay.portal.tools.servicebuilder.ServiceBuilder;
025    import com.liferay.portal.util.InitUtil;
026    
027    import com.thoughtworks.qdox.JavaDocBuilder;
028    import com.thoughtworks.qdox.model.DocletTag;
029    import com.thoughtworks.qdox.model.JavaClass;
030    import com.thoughtworks.qdox.model.JavaMethod;
031    import com.thoughtworks.qdox.model.JavaParameter;
032    import com.thoughtworks.qdox.model.Type;
033    import com.thoughtworks.qdox.model.TypeVariable;
034    
035    import java.io.File;
036    import java.io.IOException;
037    
038    import java.util.LinkedHashSet;
039    import java.util.List;
040    import java.util.Set;
041    
042    /**
043     * @author Brian Wing Shun Chan
044     */
045    public class InstanceWrapperBuilder {
046    
047            public static void main(String[] args) {
048                    InitUtil.initWithSpring();
049    
050                    if (args.length == 1) {
051                            new InstanceWrapperBuilder(args[0]);
052                    }
053                    else {
054                            throw new IllegalArgumentException();
055                    }
056            }
057    
058            public InstanceWrapperBuilder(String xml) {
059                    try {
060                            File file = new File(xml);
061    
062                            Document document = UnsecureSAXReaderUtil.read(file);
063    
064                            Element rootElement = document.getRootElement();
065    
066                            List<Element> instanceWrapperElements = rootElement.elements(
067                                    "instance-wrapper");
068    
069                            for (Element instanceWrapperElement : instanceWrapperElements) {
070                                    String parentDir = instanceWrapperElement.attributeValue(
071                                            "parent-dir");
072                                    String srcFile = instanceWrapperElement.attributeValue(
073                                            "src-file");
074    
075                                    _createIW(parentDir, srcFile);
076                            }
077                    }
078                    catch (Exception e) {
079                            e.printStackTrace();
080                    }
081            }
082    
083            private void _createIW(String parentDir, String srcFile)
084                    throws IOException {
085    
086                    JavaClass javaClass = _getJavaClass(parentDir, srcFile);
087    
088                    JavaMethod[] javaMethods = javaClass.getMethods();
089    
090                    StringBundler sb = new StringBundler();
091    
092                    // Package
093    
094                    sb.append("package ");
095                    sb.append(javaClass.getPackage().getName());
096                    sb.append(";");
097    
098                    // Class declaration
099    
100                    sb.append("public class ");
101                    sb.append(javaClass.getName());
102                    sb.append("_IW {");
103    
104                    // Methods
105    
106                    sb.append("public static ");
107                    sb.append(javaClass.getName());
108                    sb.append("_IW getInstance() {");
109                    sb.append("return _instance;");
110                    sb.append("}\n");
111    
112                    for (JavaMethod javaMethod : javaMethods) {
113                            String methodName = javaMethod.getName();
114    
115                            if (!javaMethod.isPublic() || !javaMethod.isStatic()) {
116                                    continue;
117                            }
118    
119                            if (methodName.equals("getInstance")) {
120                                    methodName = "getWrappedInstance";
121                            }
122    
123                            DocletTag[] docletTags = javaMethod.getTagsByName("deprecated");
124    
125                            if (ArrayUtil.isNotEmpty(docletTags)) {
126                                    sb.append("\t/**\n");
127                                    sb.append("\t * @deprecated\n");
128                                    sb.append("\t */\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.size() > 0) {
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    }