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