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 = Math.max(
156 fileName.lastIndexOf("/com/"), fileName.lastIndexOf("/org/"));
157 int y = fileName.lastIndexOf(StringPool.SLASH);
158
159 String packagePath = fileName.substring(x + 1, y);
160
161 return StringUtil.replace(
162 packagePath, StringPool.SLASH, StringPool.PERIOD);
163 }
164
165 public static boolean isInsideQuotes(String s, int pos) {
166 int start = s.lastIndexOf(CharPool.NEW_LINE, pos);
167
168 if (start == -1) {
169 start = 0;
170 }
171
172 int end = s.indexOf(CharPool.NEW_LINE, pos);
173
174 if (end == -1) {
175 end = s.length();
176 }
177
178 String line = s.substring(start, end);
179
180 pos -= start;
181
182 char delimeter = CharPool.SPACE;
183 boolean insideQuotes = false;
184
185 for (int i = 0; i < line.length(); i++) {
186 char c = line.charAt(i);
187
188 if (insideQuotes) {
189 if (c == delimeter) {
190 int precedingBackSlashCount = 0;
191
192 for (int j = (i - 1); j >= 0; j--) {
193 if (line.charAt(j) == CharPool.BACK_SLASH) {
194 precedingBackSlashCount += 1;
195 }
196 else {
197 break;
198 }
199 }
200
201 if ((precedingBackSlashCount == 0) ||
202 ((precedingBackSlashCount % 2) == 0)) {
203
204 insideQuotes = false;
205 }
206 }
207 }
208 else if ((c == CharPool.APOSTROPHE) || (c == CharPool.QUOTE)) {
209 delimeter = c;
210 insideQuotes = true;
211 }
212
213 if (pos == i) {
214 return insideQuotes;
215 }
216 }
217
218 return false;
219 }
220
221 public static String stripFullyQualifiedClassNames(String content)
222 throws IOException {
223
224 String imports = JavaImportsFormatter.getImports(content);
225
226 return stripFullyQualifiedClassNames(content, imports);
227 }
228
229 public static String stripFullyQualifiedClassNames(
230 String content, String imports)
231 throws IOException {
232
233 if (Validator.isNull(content) || Validator.isNull(imports)) {
234 return content;
235 }
236
237 UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
238 new UnsyncStringReader(imports));
239
240 String line = null;
241
242 while ((line = unsyncBufferedReader.readLine()) != null) {
243 int x = line.indexOf("import ");
244
245 if (x == -1) {
246 continue;
247 }
248
249 String importPackageAndClassName = line.substring(
250 x + 7, line.lastIndexOf(StringPool.SEMICOLON));
251
252 x = -1;
253
254 while (true) {
255 x = content.indexOf(importPackageAndClassName, x + 1);
256
257 if (x == -1) {
258 break;
259 }
260
261 if (isInsideQuotes(content, x)) {
262 continue;
263 }
264
265 if (content.length() >
266 (x + importPackageAndClassName.length())) {
267
268 char nextChar = content.charAt(
269 x + importPackageAndClassName.length());
270
271 if (Character.isAlphabetic(nextChar) ||
272 Character.isDigit(nextChar) ||
273 (nextChar == CharPool.PERIOD) ||
274 (nextChar == CharPool.SEMICOLON) ||
275 (nextChar == CharPool.UNDERLINE)) {
276
277 continue;
278 }
279
280 if (x > 0) {
281 char previousChar = content.charAt(x - 1);
282
283 if ((previousChar == CharPool.QUOTE) &&
284 (nextChar == CharPool.QUOTE)) {
285
286 continue;
287 }
288 }
289 }
290
291 String importClassName = importPackageAndClassName.substring(
292 importPackageAndClassName.lastIndexOf(StringPool.PERIOD) +
293 1);
294
295 content = StringUtil.replaceFirst(
296 content, importPackageAndClassName, importClassName, x);
297 }
298 }
299
300 return content;
301 }
302
303 public static void writeFile(
304 File file, String content, Set<String> modifiedFileNames)
305 throws IOException {
306
307 writeFile(file, content, AUTHOR, modifiedFileNames);
308 }
309
310 public static void writeFile(
311 File file, String content, String author,
312 Map<String, Object> jalopySettings, Set<String> modifiedFileNames)
313 throws IOException {
314
315 String packagePath = getPackagePath(file);
316
317 String className = file.getName();
318
319 className = className.substring(0, className.length() - 5);
320
321 content = JavaImportsFormatter.stripJavaImports(
322 content, packagePath, className);
323
324 content = stripFullyQualifiedClassNames(content);
325
326 File tempFile = new File(_TMP_DIR, "ServiceBuilder.temp");
327
328 _write(tempFile, content);
329
330
331
332 StringBuffer sb = new StringBuffer();
333
334 Jalopy jalopy = new Jalopy();
335
336 jalopy.setFileFormat(FileFormat.UNIX);
337 jalopy.setInput(tempFile);
338 jalopy.setOutput(sb);
339
340 File jalopyXmlFile = new File("tools/jalopy.xml");
341
342 if (!jalopyXmlFile.exists()) {
343 jalopyXmlFile = new File("../tools/jalopy.xml");
344 }
345
346 if (!jalopyXmlFile.exists()) {
347 jalopyXmlFile = new File("misc/jalopy.xml");
348 }
349
350 if (!jalopyXmlFile.exists()) {
351 jalopyXmlFile = new File("../misc/jalopy.xml");
352 }
353
354 if (!jalopyXmlFile.exists()) {
355 jalopyXmlFile = new File("../../misc/jalopy.xml");
356 }
357
358 if (jalopyXmlFile.exists()) {
359 Jalopy.setConvention(jalopyXmlFile);
360 }
361 else {
362 URL url = _readJalopyXmlFromClassLoader();
363
364 Jalopy.setConvention(url);
365 }
366
367 if (jalopySettings == null) {
368 jalopySettings = new HashMap<>();
369 }
370
371 Environment env = Environment.getInstance();
372
373
374
375 author = GetterUtil.getString(
376 (String)jalopySettings.get("author"), author);
377
378 env.set("author", author);
379
380
381
382 env.set("fileName", file.getName());
383
384 Convention convention = Convention.getInstance();
385
386 String classMask = "";
387
388 convention.put(
389 ConventionKeys.COMMENT_JAVADOC_TEMPLATE_CLASS,
390 env.interpolate(classMask));
391
392 convention.put(
393 ConventionKeys.COMMENT_JAVADOC_TEMPLATE_INTERFACE,
394 env.interpolate(classMask));
395
396 jalopy.format();
397
398 String newContent = sb.toString();
399
400
401
402 newContent = newContent.replaceFirst(
403 "(?m)^[ \t]*((?:package|import) .*;)\\s*^[ \t]*/\\*\\*",
404 "$1\n\n