001
014
015 package com.liferay.portal.tools;
016
017 import com.liferay.portal.kernel.io.unsync.UnsyncBufferedReader;
018 import com.liferay.portal.kernel.io.unsync.UnsyncStringReader;
019 import com.liferay.portal.kernel.util.CharPool;
020 import com.liferay.portal.kernel.util.GetterUtil;
021 import com.liferay.portal.kernel.util.StringPool;
022 import com.liferay.portal.kernel.util.StringUtil;
023 import com.liferay.portal.kernel.util.Validator;
024 import com.liferay.portal.xml.SAXReaderFactory;
025
026 import de.hunsicker.io.FileFormat;
027 import de.hunsicker.jalopy.Jalopy;
028 import de.hunsicker.jalopy.storage.Convention;
029 import de.hunsicker.jalopy.storage.ConventionKeys;
030 import de.hunsicker.jalopy.storage.Environment;
031
032 import java.io.File;
033 import java.io.IOException;
034
035 import java.net.URL;
036
037 import java.nio.charset.StandardCharsets;
038 import java.nio.file.Files;
039 import java.nio.file.Path;
040
041 import java.util.HashMap;
042 import java.util.List;
043 import java.util.Map;
044 import java.util.Set;
045 import java.util.TreeMap;
046
047 import org.dom4j.Document;
048 import org.dom4j.Element;
049 import org.dom4j.io.SAXReader;
050
051
067 public class ToolsUtil {
068
069 public static final String AUTHOR = "Brian Wing Shun Chan";
070
071 public static String getContent(String fileName) throws Exception {
072 Document document = _getContentDocument(fileName);
073
074 Element rootElement = document.getRootElement();
075
076 Element authorElement = null;
077 Element namespaceElement = null;
078 Map<String, Element> entityElements = new TreeMap<>();
079 Map<String, Element> exceptionElements = new TreeMap<>();
080
081 List<Element> elements = rootElement.elements();
082
083 for (Element element : elements) {
084 String elementName = element.getName();
085
086 if (elementName.equals("author")) {
087 element.detach();
088
089 if (authorElement != null) {
090 throw new IllegalArgumentException(
091 "There can only be one author element");
092 }
093
094 authorElement = element;
095 }
096 else if (elementName.equals("namespace")) {
097 element.detach();
098
099 if (namespaceElement != null) {
100 throw new IllegalArgumentException(
101 "There can only be one namespace element");
102 }
103
104 namespaceElement = element;
105 }
106 else if (elementName.equals("entity")) {
107 element.detach();
108
109 String name = element.attributeValue("name");
110
111 entityElements.put(StringUtil.toLowerCase(name), element);
112 }
113 else if (elementName.equals("exceptions")) {
114 element.detach();
115
116 List<Element> exceptionElementsList = element.elements(
117 "exception");
118
119 for (Element exceptionElement : exceptionElementsList) {
120 exceptionElement.detach();
121
122 exceptionElements.put(
123 exceptionElement.getText(), exceptionElement);
124 }
125 }
126 }
127
128 if (authorElement != null) {
129 rootElement.add(authorElement);
130 }
131
132 if (namespaceElement == null) {
133 throw new IllegalArgumentException(
134 "The namespace element is required");
135 }
136 else {
137 rootElement.add(namespaceElement);
138 }
139
140 _addElements(rootElement, entityElements);
141
142 if (!exceptionElements.isEmpty()) {
143 Element exceptionsElement = rootElement.addElement("exceptions");
144
145 _addElements(exceptionsElement, exceptionElements);
146 }
147
148 return document.asXML();
149 }
150
151 public static String getPackagePath(File file) {
152 String fileName = StringUtil.replace(
153 file.toString(), StringPool.BACK_SLASH, StringPool.SLASH);
154
155 int x = fileName.lastIndexOf("/com/liferay/");
156 int y = fileName.lastIndexOf(StringPool.SLASH);
157
158 String packagePath = fileName.substring(x + 1, y);
159
160 return StringUtil.replace(
161 packagePath, StringPool.SLASH, StringPool.PERIOD);
162 }
163
164 public static boolean isInsideQuotes(String s, int pos) {
165 boolean insideQuotes = false;
166
167 for (int i = 0; i < s.length(); i++) {
168 char c = s.charAt(i);
169
170 if (insideQuotes) {
171 if ((c == CharPool.QUOTE) &&
172 ((c <= 1) || (s.charAt(i - 1) != CharPool.BACK_SLASH) ||
173 (s.charAt(i - 2) == CharPool.BACK_SLASH))) {
174
175 insideQuotes = false;
176 }
177 }
178 else if (c == CharPool.QUOTE) {
179 insideQuotes = true;
180 }
181
182 if (pos == i) {
183 return insideQuotes;
184 }
185 }
186
187 return false;
188 }
189
190 public static String stripFullyQualifiedClassNames(String content)
191 throws IOException {
192
193 String imports = JavaImportsFormatter.getImports(content);
194
195 return stripFullyQualifiedClassNames(content, imports);
196 }
197
198 public static String stripFullyQualifiedClassNames(
199 String content, String imports)
200 throws IOException {
201
202 if (Validator.isNull(content) || Validator.isNull(imports)) {
203 return content;
204 }
205
206 UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
207 new UnsyncStringReader(imports));
208
209 String line = null;
210
211 while ((line = unsyncBufferedReader.readLine()) != null) {
212 int x = line.indexOf("import ");
213
214 if (x == -1) {
215 continue;
216 }
217
218 String importPackageAndClassName = line.substring(
219 x + 7, line.lastIndexOf(StringPool.SEMICOLON));
220
221 x = -1;
222
223 while (true) {
224 x = content.indexOf(importPackageAndClassName, x + 1);
225
226 if (x == -1) {
227 break;
228 }
229
230 if (isInsideQuotes(content, x)) {
231 continue;
232 }
233
234 if (content.length() >
235 (x + importPackageAndClassName.length())) {
236
237 char nextChar = content.charAt(
238 x + importPackageAndClassName.length());
239
240 if (Character.isAlphabetic(nextChar) ||
241 Character.isDigit(nextChar) ||
242 (nextChar == CharPool.PERIOD) ||
243 (nextChar == CharPool.SEMICOLON) ||
244 (nextChar == CharPool.UNDERLINE)) {
245
246 continue;
247 }
248
249 if (x > 0) {
250 char previousChar = content.charAt(x - 1);
251
252 if ((previousChar == CharPool.QUOTE) &&
253 (nextChar == CharPool.QUOTE)) {
254
255 continue;
256 }
257 }
258 }
259
260 String importClassName = importPackageAndClassName.substring(
261 importPackageAndClassName.lastIndexOf(StringPool.PERIOD) +
262 1);
263
264 content = StringUtil.replaceFirst(
265 content, importPackageAndClassName, importClassName, x);
266 }
267 }
268
269 return content;
270 }
271
272 public static void writeFile(
273 File file, String content, Set<String> modifiedFileNames)
274 throws IOException {
275
276 writeFile(file, content, AUTHOR, modifiedFileNames);
277 }
278
279 public static void writeFile(
280 File file, String content, String author,
281 Map<String, Object> jalopySettings, Set<String> modifiedFileNames)
282 throws IOException {
283
284 String packagePath = getPackagePath(file);
285
286 String className = file.getName();
287
288 className = className.substring(0, className.length() - 5);
289
290 content = JavaImportsFormatter.stripJavaImports(
291 content, packagePath, className);
292
293 content = stripFullyQualifiedClassNames(content);
294
295 File tempFile = new File(_TMP_DIR, "ServiceBuilder.temp");
296
297 _write(tempFile, content);
298
299
300
301 StringBuffer sb = new StringBuffer();
302
303 Jalopy jalopy = new Jalopy();
304
305 jalopy.setFileFormat(FileFormat.UNIX);
306 jalopy.setInput(tempFile);
307 jalopy.setOutput(sb);
308
309 File jalopyXmlFile = new File("tools/jalopy.xml");
310
311 if (!jalopyXmlFile.exists()) {
312 jalopyXmlFile = new File("../tools/jalopy.xml");
313 }
314
315 if (!jalopyXmlFile.exists()) {
316 jalopyXmlFile = new File("misc/jalopy.xml");
317 }
318
319 if (!jalopyXmlFile.exists()) {
320 jalopyXmlFile = new File("../misc/jalopy.xml");
321 }
322
323 if (!jalopyXmlFile.exists()) {
324 jalopyXmlFile = new File("../../misc/jalopy.xml");
325 }
326
327 if (jalopyXmlFile.exists()) {
328 Jalopy.setConvention(jalopyXmlFile);
329 }
330 else {
331 URL url = _readJalopyXmlFromClassLoader();
332
333 Jalopy.setConvention(url);
334 }
335
336 if (jalopySettings == null) {
337 jalopySettings = new HashMap<>();
338 }
339
340 Environment env = Environment.getInstance();
341
342
343
344 author = GetterUtil.getString(
345 (String)jalopySettings.get("author"), author);
346
347 env.set("author", author);
348
349
350
351 env.set("fileName", file.getName());
352
353 Convention convention = Convention.getInstance();
354
355 String classMask = "";
356
357 convention.put(
358 ConventionKeys.COMMENT_JAVADOC_TEMPLATE_CLASS,
359 env.interpolate(classMask));
360
361 convention.put(
362 ConventionKeys.COMMENT_JAVADOC_TEMPLATE_INTERFACE,
363 env.interpolate(classMask));
364
365 jalopy.format();
366
367 String newContent = sb.toString();
368
369
370
371 newContent = newContent.replaceFirst(
372 "(?m)^[ \t]*((?:package|import) .*;)\\s*^[ \t]*/\\*\\*",
373 "$1\n\n