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 import java.util.regex.Matcher;
047 import java.util.regex.Pattern;
048
049 import org.dom4j.Document;
050 import org.dom4j.Element;
051 import org.dom4j.io.SAXReader;
052
053
069 public class ToolsUtil {
070
071 public static final String AUTHOR = "Brian Wing Shun Chan";
072
073 public static String getContent(String fileName) throws Exception {
074 Document document = _getContentDocument(fileName);
075
076 Element rootElement = document.getRootElement();
077
078 Element authorElement = null;
079 Element namespaceElement = null;
080 Map<String, Element> entityElements = new TreeMap<>();
081 Map<String, Element> exceptionElements = new TreeMap<>();
082
083 List<Element> elements = rootElement.elements();
084
085 for (Element element : elements) {
086 String elementName = element.getName();
087
088 if (elementName.equals("author")) {
089 element.detach();
090
091 if (authorElement != null) {
092 throw new IllegalArgumentException(
093 "There can only be one author element");
094 }
095
096 authorElement = element;
097 }
098 else if (elementName.equals("namespace")) {
099 element.detach();
100
101 if (namespaceElement != null) {
102 throw new IllegalArgumentException(
103 "There can only be one namespace element");
104 }
105
106 namespaceElement = element;
107 }
108 else if (elementName.equals("entity")) {
109 element.detach();
110
111 String name = element.attributeValue("name");
112
113 entityElements.put(StringUtil.toLowerCase(name), element);
114 }
115 else if (elementName.equals("exceptions")) {
116 element.detach();
117
118 List<Element> exceptionElementsList = element.elements(
119 "exception");
120
121 for (Element exceptionElement : exceptionElementsList) {
122 exceptionElement.detach();
123
124 exceptionElements.put(
125 exceptionElement.getText(), exceptionElement);
126 }
127 }
128 }
129
130 if (authorElement != null) {
131 rootElement.add(authorElement);
132 }
133
134 if (namespaceElement == null) {
135 throw new IllegalArgumentException(
136 "The namespace element is required");
137 }
138 else {
139 rootElement.add(namespaceElement);
140 }
141
142 _addElements(rootElement, entityElements);
143
144 if (!exceptionElements.isEmpty()) {
145 Element exceptionsElement = rootElement.addElement("exceptions");
146
147 _addElements(exceptionsElement, exceptionElements);
148 }
149
150 return document.asXML();
151 }
152
153 public static String getPackagePath(File file) {
154 String fileName = StringUtil.replace(
155 file.toString(), CharPool.BACK_SLASH, CharPool.SLASH);
156
157 return getPackagePath(fileName);
158 }
159
160 public static String getPackagePath(String fileName) {
161 int x = Math.max(
162 fileName.lastIndexOf("/com/"), fileName.lastIndexOf("/org/"));
163 int y = fileName.lastIndexOf(CharPool.SLASH);
164
165 String packagePath = fileName.substring(x + 1, y);
166
167 return StringUtil.replace(packagePath, CharPool.SLASH, CharPool.PERIOD);
168 }
169
170 public static boolean isInsideQuotes(String s, int pos) {
171 int start = s.lastIndexOf(CharPool.NEW_LINE, pos);
172
173 if (start == -1) {
174 start = 0;
175 }
176
177 int end = s.indexOf(CharPool.NEW_LINE, pos);
178
179 if (end == -1) {
180 end = s.length();
181 }
182
183 String line = s.substring(start, end);
184
185 pos -= start;
186
187 char delimeter = CharPool.SPACE;
188 boolean insideQuotes = false;
189
190 for (int i = 0; i < line.length(); i++) {
191 char c = line.charAt(i);
192
193 if (insideQuotes) {
194 if (c == delimeter) {
195 int precedingBackSlashCount = 0;
196
197 for (int j = (i - 1); j >= 0; j--) {
198 if (line.charAt(j) == CharPool.BACK_SLASH) {
199 precedingBackSlashCount += 1;
200 }
201 else {
202 break;
203 }
204 }
205
206 if ((precedingBackSlashCount == 0) ||
207 ((precedingBackSlashCount % 2) == 0)) {
208
209 insideQuotes = false;
210 }
211 }
212 }
213 else if ((c == CharPool.APOSTROPHE) || (c == CharPool.QUOTE)) {
214 delimeter = c;
215 insideQuotes = true;
216 }
217
218 if (pos == i) {
219 return insideQuotes;
220 }
221 }
222
223 return false;
224 }
225
226
230 @Deprecated
231 public static String stripFullyQualifiedClassNames(String content)
232 throws IOException {
233
234 return stripFullyQualifiedClassNames(content, null);
235 }
236
237 public static String stripFullyQualifiedClassNames(
238 String content, String packagePath)
239 throws IOException {
240
241 String imports = JavaImportsFormatter.getImports(content);
242
243 return stripFullyQualifiedClassNames(content, imports, packagePath);
244 }
245
246 public static String stripFullyQualifiedClassNames(
247 String content, String imports, String packagePath)
248 throws IOException {
249
250 if (Validator.isNull(content) || Validator.isNull(imports)) {
251 return content;
252 }
253
254 Pattern pattern1 = Pattern.compile(
255 "\n(.*)" + StringUtil.replace(packagePath, CharPool.PERIOD, "\\.") +
256 "\\.([A-Z]\\w+)\\W");
257
258 outerLoop:
259 while (true) {
260 Matcher matcher1 = pattern1.matcher(content);
261
262 while (matcher1.find()) {
263 String lineStart = StringUtil.trimLeading(matcher1.group(1));
264
265 if (lineStart.startsWith("import ") ||
266 lineStart.contains("
267 isInsideQuotes(content, matcher1.start(2))) {
268
269 continue;
270 }
271
272 String className = matcher1.group(2);
273
274 Pattern pattern2 = Pattern.compile(
275 "import [\\w.]+\\." + className + ";");
276
277 Matcher matcher2 = pattern2.matcher(imports);
278
279 if (matcher2.find()) {
280 continue;
281 }
282
283 content = StringUtil.replaceFirst(
284 content, packagePath + ".", StringPool.BLANK,
285 matcher1.start());
286
287 continue outerLoop;
288 }
289
290 break;
291 }
292
293 UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
294 new UnsyncStringReader(imports));
295
296 String line = null;
297
298 while ((line = unsyncBufferedReader.readLine()) != null) {
299 int x = line.indexOf("import ");
300
301 if (x == -1) {
302 continue;
303 }
304
305 String importPackageAndClassName = line.substring(
306 x + 7, line.lastIndexOf(StringPool.SEMICOLON));
307
308 if (importPackageAndClassName.contains(StringPool.STAR)) {
309 continue;
310 }
311
312 Pattern pattern3 = Pattern.compile(
313 "\n(.*)(" +
314 StringUtil.replace(importPackageAndClassName, ".", "\\.") +
315 ")\\W");
316
317 outerLoop:
318 while (true) {
319 Matcher matcher3 = pattern3.matcher(content);
320
321 while (matcher3.find()) {
322 String lineStart = StringUtil.trimLeading(
323 matcher3.group(1));
324
325 if (lineStart.startsWith("import ") ||
326 lineStart.contains("
327 isInsideQuotes(content, matcher3.start(2))) {
328
329 continue;
330 }
331
332 String importClassName =
333 importPackageAndClassName.substring(
334 importPackageAndClassName.lastIndexOf(
335 StringPool.PERIOD) + 1);
336
337 content = StringUtil.replaceFirst(
338 content, importPackageAndClassName, importClassName,
339 matcher3.start());
340
341 continue outerLoop;
342 }
343
344 break;
345 }
346 }
347
348 return content;
349 }
350
351 public static void writeFile(
352 File file, String content, Set<String> modifiedFileNames)
353 throws IOException {
354
355 writeFile(file, content, AUTHOR, modifiedFileNames);
356 }
357
358 public static void writeFile(
359 File file, String content, String author,
360 Map<String, Object> jalopySettings, Set<String> modifiedFileNames)
361 throws IOException {
362
363 String packagePath = getPackagePath(file);
364
365 String className = file.getName();
366
367 className = className.substring(0, className.length() - 5);
368
369 ImportsFormatter importsFormatter = new JavaImportsFormatter();
370
371 content = importsFormatter.format(content, packagePath, className);
372
373 File tempFile = new File(_TMP_DIR, "ServiceBuilder.temp");
374
375 _write(tempFile, content);
376
377
378
379 StringBuffer sb = new StringBuffer();
380
381 Jalopy jalopy = new Jalopy();
382
383 jalopy.setFileFormat(FileFormat.UNIX);
384 jalopy.setInput(tempFile);
385 jalopy.setOutput(sb);
386
387 File jalopyXmlFile = new File("tools/jalopy.xml");
388
389 if (!jalopyXmlFile.exists()) {
390 jalopyXmlFile = new File("../tools/jalopy.xml");
391 }
392
393 if (!jalopyXmlFile.exists()) {
394 jalopyXmlFile = new File("misc/jalopy.xml");
395 }
396
397 if (!jalopyXmlFile.exists()) {
398 jalopyXmlFile = new File("../misc/jalopy.xml");
399 }
400
401 if (!jalopyXmlFile.exists()) {
402 jalopyXmlFile = new File("../../misc/jalopy.xml");
403 }
404
405 if (jalopyXmlFile.exists()) {
406 Jalopy.setConvention(jalopyXmlFile);
407 }
408 else {
409 URL url = _readJalopyXmlFromClassLoader();
410
411 Jalopy.setConvention(url);
412 }
413
414 if (jalopySettings == null) {
415 jalopySettings = new HashMap<>();
416 }
417
418 Environment env = Environment.getInstance();
419
420
421
422 author = GetterUtil.getString(
423 (String)jalopySettings.get("author"), author);
424
425 env.set("author", author);
426
427
428
429 env.set("fileName", file.getName());
430
431 Convention convention = Convention.getInstance();
432
433 String classMask = "";
434
435 convention.put(
436 ConventionKeys.COMMENT_JAVADOC_TEMPLATE_CLASS,
437 env.interpolate(classMask));
438
439 convention.put(
440 ConventionKeys.COMMENT_JAVADOC_TEMPLATE_INTERFACE,
441 env.interpolate(classMask));
442
443 jalopy.format();
444
445 String newContent = sb.toString();
446
447
448
449 newContent = newContent.replaceFirst(
450 "(?m)^[ \t]*((?:package|import) .*;)\\s*^[ \t]*/\\*\\*",
451 "$1\n\n