001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portal.tools;
016    
017    import com.liferay.portal.kernel.util.ListUtil;
018    import com.liferay.portal.kernel.util.StringBundler;
019    import com.liferay.portal.kernel.util.StringPool;
020    import com.liferay.portal.kernel.util.StringUtil;
021    import com.liferay.portal.kernel.util.UniqueList;
022    import com.liferay.portal.kernel.util.Validator;
023    import com.liferay.portal.util.FileImpl;
024    import com.liferay.portal.util.PropsValues;
025    
026    import java.io.File;
027    import java.io.FileInputStream;
028    import java.io.FilenameFilter;
029    
030    import java.util.ArrayList;
031    import java.util.Collections;
032    import java.util.HashMap;
033    import java.util.Iterator;
034    import java.util.List;
035    import java.util.Map;
036    import java.util.Properties;
037    
038    import org.apache.oro.io.GlobFilenameFilter;
039    import org.apache.tools.ant.DirectoryScanner;
040    
041    /**
042     * @author Alexander Chow
043     * @author Brian Wing Shun Chan
044     */
045    public class PluginsEnvironmentBuilder {
046    
047            public static void main(String[] args) throws Exception {
048                    try {
049                            File dir = new File(System.getProperty("plugins.env.dir"));
050    
051                            new PluginsEnvironmentBuilder(dir);
052                    }
053                    catch (Exception e) {
054                            e.printStackTrace();
055                    }
056            }
057    
058            public PluginsEnvironmentBuilder(File dir) throws Exception {
059                    DirectoryScanner ds = new DirectoryScanner();
060    
061                    ds.setBasedir(dir);
062                    ds.setIncludes(new String[] {"**\\liferay-plugin-package.properties"});
063    
064                    ds.scan();
065    
066                    String dirName = dir.getCanonicalPath();
067    
068                    String[] fileNames = ds.getIncludedFiles();
069    
070                    for (String fileName : fileNames) {
071                            setupProject(dirName, fileName);
072                    }
073            }
074    
075            protected void addClasspathEntry(StringBundler sb, String jar) {
076                    addClasspathEntry(sb, jar, null);
077            }
078    
079            protected void addClasspathEntry(
080                    StringBundler sb, String jar, Map<String, String> attributes) {
081    
082                    sb.append("\t<classpathentry kind=\"lib\" path=\"");
083                    sb.append(jar);
084    
085                    if ((attributes == null) || attributes.isEmpty()) {
086                            sb.append("\" />\n");
087    
088                            return;
089                    }
090    
091                    sb.append("\">\n\t\t<attributes>\n");
092    
093                    Iterator<Map.Entry<String, String>> itr =
094                            attributes.entrySet().iterator();
095    
096                    while (itr.hasNext()) {
097                            Map.Entry<String, String> entry = itr.next();
098    
099                            sb.append("\t\t\t<attribute name=\"");
100                            sb.append(entry.getKey());
101                            sb.append("\" value=\"");
102                            sb.append(entry.getValue());
103                            sb.append("\" />\n");
104                    }
105    
106                    sb.append("\t\t</attributes>\n\t</classpathentry>\n");
107            }
108    
109            protected void setupProject(String dirName, String fileName)
110                    throws Exception {
111    
112                    File propertiesFile = new File(dirName + "/" + fileName);
113    
114                    File libDir = new File(propertiesFile.getParent() + "/lib");
115    
116                    File projectDir = new File(propertiesFile.getParent() + "/../..");
117    
118                    Properties properties = new Properties();
119    
120                    properties.load(new FileInputStream(propertiesFile));
121    
122                    String[] dependencyJars = StringUtil.split(
123                            properties.getProperty(
124                                    "portal-dependency-jars",
125                                    properties.getProperty("portal.dependency.jars")));
126    
127                    List<String> jars = ListUtil.toList(dependencyJars);
128    
129                    jars.add("commons-logging.jar");
130                    jars.add("log4j.jar");
131                    jars.add("util-bridges.jar");
132                    jars.add("util-java.jar");
133                    jars.add("util-taglib.jar");
134    
135                    Collections.sort(jars);
136    
137                    writeEclipseFiles(libDir, projectDir, dependencyJars);
138    
139                    String libDirPath = StringUtil.replace(
140                            libDir.getPath(), StringPool.BACK_SLASH, StringPool.SLASH);
141    
142                    List<String> ignores = ListUtil.fromFile(
143                            libDir.getCanonicalPath() + "/../.gitignore");
144    
145                    if (!libDirPath.contains("/ext/") && !ignores.contains("/lib")) {
146                            File gitignoreFile = new File(
147                                    libDir.getCanonicalPath() + "/.gitignore");
148    
149                            System.out.println("Updating " + gitignoreFile);
150    
151                            String[] gitIgnores = jars.toArray(new String[jars.size()]);
152    
153                            for (int i = 0; i < gitIgnores.length; i++) {
154                                    String gitIgnore = gitIgnores[i];
155    
156                                    if (Validator.isNotNull(gitIgnore) &&
157                                            !gitIgnore.startsWith("/")) {
158    
159                                            gitIgnores[i] = "/" + gitIgnore;
160                                    }
161                            }
162    
163                            _fileUtil.write(gitignoreFile, StringUtil.merge(gitIgnores, "\n"));
164                    }
165            }
166    
167            protected void writeClasspathFile(
168                            File libDir, String[] dependencyJars, String projectDirName,
169                            String projectName, boolean javaProject)
170                    throws Exception {
171    
172                    File classpathFile = new File(projectDirName + "/.classpath");
173    
174                    if (!javaProject) {
175                            classpathFile.delete();
176    
177                            return;
178                    }
179    
180                    List<String> globalJars = new UniqueList<String>();
181                    List<String> portalJars = new UniqueList<String>();
182    
183                    List<String> extGlobalJars = new UniqueList<String>();
184                    List<String> extPortalJars = new UniqueList<String>();
185    
186                    String libDirPath = StringUtil.replace(
187                            libDir.getPath(), StringPool.BACK_SLASH, StringPool.SLASH);
188    
189                    if (libDirPath.contains("/ext/")) {
190                            FilenameFilter filenameFilter = new GlobFilenameFilter("*.jar");
191    
192                            for (String dirName : new String[] {"global", "portal"}) {
193                                    File file = new File(libDirPath + "/../ext-lib/" + dirName);
194    
195                                    List<String> jars = ListUtil.toList(file.list(filenameFilter));
196    
197                                    if (dirName.equals("global")) {
198                                            extGlobalJars.addAll(ListUtil.sort(jars));
199    
200                                            File dir = new File(PropsValues.LIFERAY_LIB_GLOBAL_DIR);
201    
202                                            String[] fileNames = dir.list(filenameFilter);
203    
204                                            globalJars.addAll(
205                                                    ListUtil.sort(ListUtil.toList(fileNames)));
206                                            globalJars.removeAll(extGlobalJars);
207                                    }
208                                    else if (dirName.equals("portal")) {
209                                            extPortalJars.addAll(ListUtil.sort(jars));
210    
211                                            File dir = new File(PropsValues.LIFERAY_LIB_PORTAL_DIR);
212    
213                                            String[] fileNames = dir.list(filenameFilter);
214    
215                                            portalJars.addAll(
216                                                    ListUtil.sort(ListUtil.toList(fileNames)));
217                                            portalJars.removeAll(extPortalJars);
218                                    }
219                            }
220                    }
221                    else {
222                            globalJars.add("portlet.jar");
223    
224                            portalJars.addAll(ListUtil.toList(dependencyJars));
225                            portalJars.add("commons-logging.jar");
226                            portalJars.add("log4j.jar");
227    
228                            Collections.sort(portalJars);
229                    }
230    
231                    String[] customJarsArray = libDir.list(new GlobFilenameFilter("*.jar"));
232    
233                    List<String> customJars = null;
234    
235                    if (customJarsArray != null) {
236                            customJars = ListUtil.toList(customJarsArray);
237    
238                            for (String jar : portalJars) {
239                                    customJars.remove(jar);
240                            }
241    
242                            customJars.remove(projectName + "-service.jar");
243                            customJars.remove("util-bridges.jar");
244                            customJars.remove("util-java.jar");
245                            customJars.remove("util-taglib.jar");
246    
247                            Collections.sort(customJars);
248                    }
249                    else {
250                            customJars = new ArrayList<String>();
251                    }
252    
253                    StringBundler sb = new StringBundler();
254    
255                    sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n");
256                    sb.append("<classpath>\n");
257    
258                    for (String sourceDirName : _SOURCE_DIR_NAMES) {
259                            if (_fileUtil.exists(projectDirName + "/" + sourceDirName)) {
260                                    sb.append("\t<classpathentry excluding=\"**/.svn/**|.svn/\" ");
261                                    sb.append("kind=\"src\" path=\"" + sourceDirName + "\" />\n");
262                            }
263                    }
264    
265                    sb.append("\t<classpathentry kind=\"src\" path=\"/portal\" />\n");
266                    sb.append("\t<classpathentry kind=\"con\" ");
267                    sb.append("path=\"org.eclipse.jdt.launching.JRE_CONTAINER\" />\n");
268    
269                    boolean addJunitJars = false;
270    
271                    for (String testType :_TEST_TYPES) {
272                            String testFolder = "test/" + testType;
273    
274                            if (_fileUtil.exists(projectDirName + "/" + testFolder)) {
275                                    addJunitJars = true;
276    
277                                    sb.append("\t<classpathentry excluding=\"**/.svn/**|.svn/\" ");
278                                    sb.append("kind=\"src\" path=\""+ testFolder + "\" />\n");
279                            }
280                    }
281    
282                    if (addJunitJars) {
283                            addClasspathEntry(sb, "/portal/lib/development/junit.jar");
284                            addClasspathEntry(sb, "/portal/lib/portal/commons-io.jar");
285                    }
286    
287                    addClasspathEntry(sb, "/portal/lib/development/activation.jar");
288                    addClasspathEntry(sb, "/portal/lib/development/annotations.jar");
289                    addClasspathEntry(sb, "/portal/lib/development/jsp-api.jar");
290                    addClasspathEntry(sb, "/portal/lib/development/mail.jar");
291                    addClasspathEntry(sb, "/portal/lib/development/servlet-api.jar");
292    
293                    Map<String, String> attributes = new HashMap<String, String>();
294    
295                    if (libDirPath.contains("/ext/")) {
296                            attributes.put("optional", "true");
297                    }
298    
299                    for (String jar : globalJars) {
300                            addClasspathEntry(sb, "/portal/lib/global/" + jar, attributes);
301                    }
302    
303                    for (String jar : portalJars) {
304                            addClasspathEntry(sb, "/portal/lib/portal/" + jar, attributes);
305                    }
306    
307                    addClasspathEntry(sb, "/portal/portal-service/portal-service.jar");
308                    addClasspathEntry(sb, "/portal/util-bridges/util-bridges.jar");
309                    addClasspathEntry(sb, "/portal/util-java/util-java.jar");
310                    addClasspathEntry(sb, "/portal/util-taglib/util-taglib.jar");
311    
312                    for (String jar : extGlobalJars) {
313                            addClasspathEntry(sb, "docroot/WEB-INF/ext-lib/global/" + jar);
314                    }
315    
316                    for (String jar : extPortalJars) {
317                            addClasspathEntry(sb, "docroot/WEB-INF/ext-lib/portal/" + jar);
318                    }
319    
320                    for (String jar : customJars) {
321                            if (libDirPath.contains("/tmp/WEB-INF/lib")) {
322                                    addClasspathEntry(sb, "tmp/WEB-INF/lib/" + jar);
323                            }
324                            else {
325                                    addClasspathEntry(sb, "docroot/WEB-INF/lib/" + jar);
326                            }
327                    }
328    
329                    sb.append("\t<classpathentry kind=\"output\" path=\"bin\" />\n");
330                    sb.append("</classpath>");
331    
332                    System.out.println("Updating " + classpathFile);
333    
334                    String content = StringUtil.replace(
335                            sb.toString(), "\"/portal", "\"/portal-" + _BRANCH);
336    
337                    _fileUtil.write(classpathFile, content);
338            }
339    
340            protected void writeEclipseFiles(
341                            File libDir, File projectDir, String[] dependencyJars)
342                    throws Exception {
343    
344                    String projectDirName = projectDir.getCanonicalPath();
345    
346                    String projectName = StringUtil.extractLast(
347                            projectDirName, File.separatorChar);
348    
349                    boolean javaProject = false;
350    
351                    for (String sourceDirName : _SOURCE_DIR_NAMES) {
352                            if (_fileUtil.exists(projectDirName + "/" + sourceDirName)) {
353                                    javaProject = true;
354    
355                                    break;
356                            }
357                    }
358    
359                    if (!javaProject) {
360                            System.out.println(
361                                    "Eclipse Java project will not be used because a source " +
362                                            "folder does not exist");
363                    }
364    
365                    writeProjectFile(projectDirName, projectName, javaProject);
366    
367                    writeClasspathFile(
368                            libDir, dependencyJars, projectDirName, projectName, javaProject);
369    
370                    for (String sourceDirName : _SOURCE_DIR_NAMES) {
371                            if (_fileUtil.exists(projectDirName + "/" + sourceDirName)) {
372                                    List<String> gitIgnores = new ArrayList<String>();
373    
374                                    if (sourceDirName.endsWith("ext-impl/src")) {
375                                            gitIgnores.add("/classes");
376                                            gitIgnores.add("/ext-impl.jar");
377                                    }
378                                    else if (sourceDirName.endsWith("ext-service/src")) {
379                                            gitIgnores.add("/classes");
380                                            gitIgnores.add("/ext-service.jar");
381                                    }
382                                    else if (sourceDirName.endsWith("ext-util-bridges/src")) {
383                                            gitIgnores.add("/classes");
384                                            gitIgnores.add("/ext-util-bridges.jar");
385                                    }
386                                    else if (sourceDirName.endsWith("ext-util-java/src")) {
387                                            gitIgnores.add("/classes");
388                                            gitIgnores.add("/ext-util-java.jar");
389                                    }
390                                    else if (sourceDirName.endsWith("ext-util-taglib/src")) {
391                                            gitIgnores.add("/classes");
392                                            gitIgnores.add("/ext-util-taglib.jar");
393                                    }
394                                    else {
395                                            continue;
396                                    }
397    
398                                    String dirName = projectDirName + "/" + sourceDirName + "/../";
399    
400                                    if (gitIgnores.isEmpty()) {
401                                            _fileUtil.delete(dirName + ".gitignore");
402                                    }
403                                    else {
404                                            String gitIgnoresString = StringUtil.merge(
405                                                    gitIgnores, "\n");
406    
407                                            _fileUtil.write(dirName + ".gitignore", gitIgnoresString);
408                                    }
409                            }
410                    }
411    
412                    if (_fileUtil.exists(projectDirName + "/test")) {
413                            _fileUtil.write(
414                                    projectDirName + "/.gitignore", "/test-classes\n/test-results");
415                    }
416                    else {
417                            _fileUtil.delete(projectDirName + "/.gitignore");
418                    }
419            }
420    
421            protected void writeProjectFile(
422                            String projectDirName, String projectName, boolean javaProject)
423                    throws Exception {
424    
425                    StringBundler sb = new StringBundler(17);
426    
427                    sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n");
428                    sb.append("<projectDescription>\n");
429                    sb.append("\t<name>");
430                    sb.append(projectName);
431                    sb.append("-");
432                    sb.append(_BRANCH);
433                    sb.append("</name>\n");
434                    sb.append("\t<comment></comment>\n");
435                    sb.append("\t<projects></projects>\n");
436                    sb.append("\t<buildSpec>\n");
437    
438                    if (javaProject) {
439                            sb.append("\t\t<buildCommand>\n");
440                            sb.append("\t\t\t<name>org.eclipse.jdt.core.javabuilder</name>\n");
441                            sb.append("\t\t\t<arguments></arguments>\n");
442                            sb.append("\t\t</buildCommand>\n");
443                    }
444    
445                    sb.append("\t</buildSpec>\n");
446                    sb.append("\t<natures>\n");
447    
448                    if (javaProject) {
449                            sb.append("\t\t<nature>org.eclipse.jdt.core.javanature</nature>\n");
450                    }
451    
452                    sb.append("\t</natures>\n");
453                    sb.append("</projectDescription>");
454    
455                    File projectFile = new File(projectDirName + "/.project");
456    
457                    System.out.println("Updating " + projectFile);
458    
459                    _fileUtil.write(projectFile, sb.toString());
460            }
461    
462            private static final String _BRANCH = "6.1.x";
463    
464            private static final String[] _SOURCE_DIR_NAMES = new String[] {
465                    "docroot/WEB-INF/ext-impl/src", "docroot/WEB-INF/ext-service/src",
466                    "docroot/WEB-INF/ext-util-bridges/src",
467                    "docroot/WEB-INF/ext-util-java/src",
468                    "docroot/WEB-INF/ext-util-taglib/src", "docroot/WEB-INF/service",
469                    "docroot/WEB-INF/src"
470            };
471    
472            private static final String[] _TEST_TYPES = {"integration", "unit"};
473    
474            private static FileImpl _fileUtil = FileImpl.getInstance();
475    
476    }