001    /**
002     * Copyright (c) 2000-present 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.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.ClassUtil;
021    import com.liferay.portal.kernel.util.StringBundler;
022    import com.liferay.portal.kernel.util.Validator;
023    
024    import java.io.IOException;
025    
026    import java.util.Set;
027    import java.util.TreeSet;
028    import java.util.regex.Matcher;
029    import java.util.regex.Pattern;
030    
031    /**
032     * @author Andr?? de Oliveira
033     * @author Hugo Huijser
034     */
035    public abstract class BaseImportsFormatter implements ImportsFormatter {
036    
037            @Override
038            public String format(String content, Pattern importPattern)
039                    throws IOException {
040    
041                    return doFormat(content, importPattern, null, null);
042            }
043    
044            @Override
045            public String format(String content, String packagePath, String className)
046                    throws IOException {
047    
048                    return doFormat(content, null, packagePath, className);
049            }
050    
051            protected abstract ImportPackage createImportPackage(String line);
052    
053            protected ImportPackage createJavaImportPackage(String line) {
054                    Matcher matcher = _javaImportPattern.matcher(line);
055    
056                    if (!matcher.find()) {
057                            return null;
058                    }
059    
060                    boolean isStatic = false;
061    
062                    if (Validator.isNotNull(matcher.group(1))) {
063                            isStatic = true;
064                    }
065    
066                    String importString = matcher.group(2);
067    
068                    return new ImportPackage(importString, isStatic, line);
069            }
070    
071            protected abstract String doFormat(
072                            String content, Pattern importPattern, String packagePath,
073                            String className)
074                    throws IOException;
075    
076            protected String sortAndGroupImports(String imports) throws IOException {
077                    if (imports.contains("/*") || imports.contains("*/") ||
078                            imports.contains("\n//")) {
079    
080                            return imports + "\n";
081                    }
082    
083                    Set<ImportPackage> importPackages = new TreeSet<>();
084    
085                    UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
086                            new UnsyncStringReader(imports));
087    
088                    String line = null;
089    
090                    while ((line = unsyncBufferedReader.readLine()) != null) {
091                            ImportPackage importPackage = createImportPackage(line);
092    
093                            if (importPackage != null) {
094                                    importPackages.add(importPackage);
095                            }
096                    }
097    
098                    StringBundler sb = new StringBundler(3 * importPackages.size());
099    
100                    ImportPackage previousImportPackage = null;
101    
102                    for (ImportPackage importPackage : importPackages) {
103                            if ((previousImportPackage != null) &&
104                                    !importPackage.isGroupedWith(previousImportPackage)) {
105    
106                                    sb.append("\n");
107                            }
108    
109                            sb.append(importPackage.getLine());
110                            sb.append("\n");
111    
112                            previousImportPackage = importPackage;
113                    }
114    
115                    return sb.toString();
116            }
117    
118            protected String stripUnusedImports(
119                            String imports, String content, String packagePath,
120                            String className, String classNameExceptionRegex)
121                    throws IOException {
122    
123                    Set<String> classes = ClassUtil.getClasses(
124                            new UnsyncStringReader(content), className);
125    
126                    StringBundler sb = new StringBundler();
127    
128                    UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
129                            new UnsyncStringReader(imports));
130    
131                    String line = null;
132    
133                    while ((line = unsyncBufferedReader.readLine()) != null) {
134                            int x = line.indexOf("import ");
135    
136                            if (x == -1) {
137                                    continue;
138                            }
139    
140                            int y = line.lastIndexOf(CharPool.PERIOD);
141    
142                            String importPackage = line.substring(x + 7, y);
143    
144                            if (importPackage.equals(packagePath) ||
145                                    importPackage.equals("java.lang")) {
146    
147                                    continue;
148                            }
149    
150                            String importClass = line.substring(y + 1, line.length() - 1);
151    
152                            if (importClass.matches(classNameExceptionRegex) ||
153                                    classes.contains(importClass)) {
154    
155                                    sb.append(line);
156                                    sb.append("\n");
157                            }
158                    }
159    
160                    return sb.toString();
161            }
162    
163            private static final Pattern _javaImportPattern = Pattern.compile(
164                    "import( static)? ([^;]+);");
165    
166    }