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.StringBundler;
018    import com.liferay.portal.kernel.util.StringPool;
019    import com.liferay.portal.kernel.util.StringUtil;
020    import com.liferay.portal.kernel.xml.Document;
021    import com.liferay.portal.kernel.xml.Element;
022    import com.liferay.portal.kernel.xml.SAXReaderUtil;
023    import com.liferay.portal.tools.servicebuilder.ServiceBuilder;
024    import com.liferay.portal.util.InitUtil;
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                    InitUtil.initWithSpring();
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 ((docletTags != null) && (docletTags.length > 0)) {
125                                    sb.append("\t/**\n");
126                                    sb.append("\t * @deprecated\n");
127                                    sb.append("\t */\n");
128                            }
129    
130                            sb.append("public ");
131    
132                            TypeVariable[] typeParameters = javaMethod.getTypeParameters();
133    
134                            if (typeParameters.length > 0) {
135                                    sb.append(" <");
136    
137                                    for (int i = 0; i < typeParameters.length; i++) {
138                                            TypeVariable typeParameter = typeParameters[i];
139    
140                                            sb.append(typeParameter.getName());
141                                            sb.append(", ");
142                                    }
143    
144                                    sb.setIndex(sb.index() - 1);
145    
146                                    sb.append("> ");
147                            }
148    
149                            sb.append(_getTypeGenericsName(javaMethod.getReturns()));
150                            sb.append(" ");
151                            sb.append(methodName);
152                            sb.append(StringPool.OPEN_PARENTHESIS);
153    
154                            JavaParameter[] javaParameters = javaMethod.getParameters();
155    
156                            for (int i = 0; i < javaParameters.length; i++) {
157                                    JavaParameter javaParameter = javaParameters[i];
158    
159                                    sb.append(_getTypeGenericsName(javaParameter.getType()));
160    
161                                    if (javaParameter.isVarArgs()) {
162                                            sb.append("...");
163                                    }
164    
165                                    sb.append(" ");
166                                    sb.append(javaParameter.getName());
167                                    sb.append(", ");
168                            }
169    
170                            if (javaParameters.length > 0) {
171                                    sb.setIndex(sb.index() - 1);
172                            }
173    
174                            sb.append(StringPool.CLOSE_PARENTHESIS);
175    
176                            Type[] thrownExceptions = javaMethod.getExceptions();
177    
178                            Set<String> newExceptions = new LinkedHashSet<String>();
179    
180                            for (int j = 0; j < thrownExceptions.length; j++) {
181                                    Type thrownException = thrownExceptions[j];
182    
183                                    newExceptions.add(thrownException.getValue());
184                            }
185    
186                            if (newExceptions.size() > 0) {
187                                    sb.append(" throws ");
188    
189                                    for (String newException : newExceptions) {
190                                            sb.append(newException);
191                                            sb.append(", ");
192                                    }
193    
194                                    sb.setIndex(sb.index() - 1);
195                            }
196    
197                            sb.append("{\n");
198    
199                            if (!javaMethod.getReturns().getValue().equals("void")) {
200                                    sb.append("return ");
201                            }
202    
203                            sb.append(javaClass.getName() + "." + javaMethod.getName() + "(");
204    
205                            for (int j = 0; j < javaParameters.length; j++) {
206                                    JavaParameter javaParameter = javaParameters[j];
207    
208                                    sb.append(javaParameter.getName());
209                                    sb.append(", ");
210                            }
211    
212                            if (javaParameters.length > 0) {
213                                    sb.setIndex(sb.index() - 1);
214                            }
215    
216                            sb.append(");");
217                            sb.append("}\n");
218                    }
219    
220                    // Private constructor
221    
222                    sb.append("private ");
223                    sb.append(javaClass.getName());
224                    sb.append("_IW() {");
225                    sb.append("}");
226    
227                    // Fields
228    
229                    sb.append("private static ");
230                    sb.append(javaClass.getName());
231                    sb.append("_IW _instance = new ");
232                    sb.append(javaClass.getName());
233                    sb.append("_IW();");
234    
235                    // Class close brace
236    
237                    sb.append("}");
238    
239                    // Write file
240    
241                    File file = new File(
242                            parentDir + "/" +
243                                    StringUtil.replace(javaClass.getPackage().getName(), ".", "/") +
244                                            "/" + javaClass.getName() + "_IW.java");
245    
246                    ServiceBuilder.writeFile(file, sb.toString());
247            }
248    
249            private String _getDimensions(Type type) {
250                    String dimensions = "";
251    
252                    for (int i = 0; i < type.getDimensions(); i++) {
253                            dimensions += "[]";
254                    }
255    
256                    return dimensions;
257            }
258    
259            private JavaClass _getJavaClass(String parentDir, String srcFile)
260                    throws IOException {
261    
262                    String className = StringUtil.replace(
263                            srcFile.substring(0, srcFile.length() - 5), "/", ".");
264    
265                    JavaDocBuilder builder = new JavaDocBuilder();
266    
267                    builder.addSource(new File(parentDir + "/" + srcFile));
268    
269                    return builder.getClassByName(className);
270            }
271    
272            private String _getTypeGenericsName(Type type) {
273                    Type[] actualTypeArguments = type.getActualTypeArguments();
274    
275                    if (actualTypeArguments == null) {
276                            String value = type.getValue();
277    
278                            return value.concat(_getDimensions(type));
279                    }
280                    else {
281                            StringBundler sb = new StringBundler(
282                                    actualTypeArguments.length * 2 + 3);
283    
284                            sb.append(type.getValue());
285                            sb.append("<");
286    
287                            for (int i = 0; i < actualTypeArguments.length; i++) {
288                                    sb.append(_getTypeGenericsName(actualTypeArguments[i]));
289                                    sb.append(", ");
290                            }
291    
292                            if (actualTypeArguments.length > 0) {
293                                    sb.setIndex(sb.index() - 1);
294                            }
295    
296                            sb.append(">");
297                            sb.append(_getDimensions(type));
298    
299                            return sb.toString();
300                    }
301            }
302    
303    }