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.util.FileComparator;
018    import com.liferay.portal.kernel.util.GetterUtil;
019    import com.liferay.portal.kernel.util.ListUtil;
020    import com.liferay.portal.kernel.util.StringBundler;
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.kernel.xml.Document;
025    import com.liferay.portal.kernel.xml.Element;
026    import com.liferay.portal.util.FileImpl;
027    import com.liferay.portal.util.PropsValues;
028    import com.liferay.portal.xml.SAXReaderImpl;
029    
030    import java.io.File;
031    import java.io.FileInputStream;
032    import java.io.FilenameFilter;
033    
034    import java.util.ArrayList;
035    import java.util.Arrays;
036    import java.util.Collections;
037    import java.util.HashMap;
038    import java.util.LinkedHashSet;
039    import java.util.List;
040    import java.util.Map;
041    import java.util.Properties;
042    import java.util.Set;
043    import java.util.TreeSet;
044    
045    import org.apache.oro.io.GlobFilenameFilter;
046    import org.apache.tools.ant.DirectoryScanner;
047    
048    /**
049     * @author Alexander Chow
050     * @author Brian Wing Shun Chan
051     */
052    public class PluginsEnvironmentBuilder {
053    
054            public static void main(String[] args) throws Exception {
055                    try {
056                            File dir = new File(System.getProperty("plugins.env.dir"));
057    
058                            new PluginsEnvironmentBuilder(dir);
059                    }
060                    catch (Exception e) {
061                            e.printStackTrace();
062                    }
063            }
064    
065            public PluginsEnvironmentBuilder(File dir) throws Exception {
066                    DirectoryScanner directoryScanner = new DirectoryScanner();
067    
068                    directoryScanner.setBasedir(dir);
069                    directoryScanner.setIncludes(
070                            new String[] {"**\\liferay-plugin-package.properties"});
071    
072                    directoryScanner.scan();
073    
074                    String dirName = dir.getCanonicalPath();
075    
076                    for (String fileName : directoryScanner.getIncludedFiles()) {
077                            setupWarProject(dirName, fileName);
078                    }
079    
080                    directoryScanner = new DirectoryScanner();
081    
082                    directoryScanner.setBasedir(dir);
083                    directoryScanner.setIncludes(new String[] {"**\\build.xml"});
084    
085                    directoryScanner.scan();
086    
087                    for (String fileName : directoryScanner.getIncludedFiles()) {
088                            String content = _fileUtil.read(dirName + "/" + fileName);
089    
090                            boolean osgiProject = false;
091    
092                            if (content.contains(
093                                            "<import file=\"../../build-common-osgi-plugin.xml\" />") ||
094                                    content.contains(
095                                            "../tools/sdk/build-common-osgi-plugin.xml\" />")) {
096    
097                                    osgiProject = true;
098                            }
099    
100                            boolean sharedProject = false;
101    
102                            if (content.contains(
103                                            "<import file=\"../build-common-shared.xml\" />") ||
104                                    content.contains(
105                                            "../tools/sdk/build-common-shared.xml\" />")) {
106    
107                                    sharedProject = true;
108                            }
109    
110                            List<String> dependencyJars = Collections.emptyList();
111    
112                            if (osgiProject) {
113                                    int x = content.indexOf("osgi.ide.dependencies");
114    
115                                    if (x != -1) {
116                                            x = content.indexOf("value=\"", x);
117                                            x = content.indexOf("\"", x);
118    
119                                            int y = content.indexOf("\"", x + 1);
120    
121                                            dependencyJars = Arrays.asList(
122                                                    StringUtil.split(content.substring(x + 1, y)));
123                                    }
124                            }
125    
126                            if (osgiProject || sharedProject) {
127                                    setupJarProject(
128                                            dirName, fileName, dependencyJars, sharedProject);
129                            }
130                    }
131            }
132    
133            protected void addClasspathEntry(StringBundler sb, String jar) {
134                    addClasspathEntry(sb, jar, null);
135            }
136    
137            protected void addClasspathEntry(
138                    StringBundler sb, String jar, Map<String, String> attributes) {
139    
140                    sb.append("\t<classpathentry kind=\"lib\" path=\"");
141                    sb.append(jar);
142    
143                    if ((attributes == null) || attributes.isEmpty()) {
144                            sb.append("\" />\n");
145    
146                            return;
147                    }
148    
149                    sb.append("\">\n\t\t<attributes>\n");
150    
151                    for (Map.Entry<String, String> entry : attributes.entrySet()) {
152                            sb.append("\t\t\t<attribute name=\"");
153                            sb.append(entry.getKey());
154                            sb.append("\" value=\"");
155                            sb.append(entry.getValue());
156                            sb.append("\" />\n");
157                    }
158    
159                    sb.append("\t\t</attributes>\n\t</classpathentry>\n");
160            }
161    
162            protected void addIvyCacheJar(
163                            StringBundler sb, String ivyDirName, String dependencyName,
164                            String version)
165                    throws Exception {
166    
167                    System.out.println("Adding " + dependencyName + " " + version);
168    
169                    if (version.equals("latest.integration")) {
170                            File dir = new File(ivyDirName + "/cache/" + dependencyName);
171    
172                            File[] files = dir.listFiles();
173    
174                            Arrays.sort(files, new FileComparator());
175    
176                            for (int i = files.length - 1; i >= 0; i--) {
177                                    File file = files[i];
178    
179                                    if (!file.isFile()) {
180                                            continue;
181                                    }
182    
183                                    String fileName = file.getName();
184    
185                                    if (!fileName.endsWith(".xml")) {
186                                            continue;
187                                    }
188    
189                                    version = fileName.substring(4, fileName.length() - 4);
190    
191                                    System.out.println(
192                                            "Substituting " + version + " for latest.integration");
193                            }
194                    }
195    
196                    String ivyFileName =
197                            ivyDirName + "/cache/" + dependencyName + "/ivy-" + version +
198                                    ".xml";
199    
200                    if (_fileUtil.exists(ivyFileName)) {
201                            Document document = _saxReaderUtil.read(new File(ivyFileName));
202    
203                            Element rootElement = document.getRootElement();
204    
205                            Element dependenciesElement = rootElement.element("dependencies");
206    
207                            if (dependenciesElement != null) {
208                                    List<Element> dependencyElements = dependenciesElement.elements(
209                                            "dependency");
210    
211                                    for (Element dependencyElement : dependencyElements) {
212                                            String conf = GetterUtil.getString(
213                                                    dependencyElement.attributeValue("conf"));
214    
215                                            if (!conf.startsWith("compile")) {
216                                                    continue;
217                                            }
218    
219                                            String name = GetterUtil.getString(
220                                                    dependencyElement.attributeValue("name"));
221                                            String org = GetterUtil.getString(
222                                                    dependencyElement.attributeValue("org"));
223                                            String rev = GetterUtil.getString(
224                                                    dependencyElement.attributeValue("rev"));
225    
226                                            String string = sb.toString();
227    
228                                            if (string.contains(name)) {
229                                                    continue;
230                                            }
231    
232                                            addIvyCacheJar(sb, ivyDirName, org + "/" + name, rev);
233                                    }
234                            }
235                    }
236    
237                    String dirName = ivyDirName + "/cache/" + dependencyName + "/bundles";
238    
239                    if (!_fileUtil.exists(dirName)) {
240                            dirName = ivyDirName + "/cache/" + dependencyName + "/jars";
241    
242                            if (!_fileUtil.exists(dirName)) {
243                                    System.out.println("Unable to find jars in " + dirName);
244    
245                                    return;
246                            }
247                    }
248    
249                    File dir = new File(dirName);
250    
251                    File[] files = dir.listFiles();
252    
253                    for (File file : files) {
254                            if (!file.isFile()) {
255                                    continue;
256                            }
257    
258                            String fileName = file.getName();
259    
260                            if (!fileName.endsWith("-" + version + ".jar")) {
261                                    continue;
262                            }
263    
264                            addClasspathEntry(sb, dirName + "/" + fileName);
265    
266                            return;
267                    }
268    
269                    System.out.println(
270                            "Unable to find jars in " + dirName + " for " + version);
271            }
272    
273            protected void addIvyCacheJars(
274                            StringBundler sb, String content, String ivyDirName)
275                    throws Exception {
276    
277                    Document document = _saxReaderUtil.read(content);
278    
279                    Element rootElement = document.getRootElement();
280    
281                    Element dependenciesElement = rootElement.element("dependencies");
282    
283                    List<Element> dependencyElements = dependenciesElement.elements(
284                            "dependency");
285    
286                    for (Element dependencyElement : dependencyElements) {
287                            String conf = GetterUtil.getString(
288                                    dependencyElement.attributeValue("conf"));
289    
290                            if (!conf.equals("test->default")) {
291                                    continue;
292                            }
293    
294                            String name = GetterUtil.getString(
295                                    dependencyElement.attributeValue("name"));
296                            String org = GetterUtil.getString(
297                                    dependencyElement.attributeValue("org"));
298                            String rev = GetterUtil.getString(
299                                    dependencyElement.attributeValue("rev"));
300    
301                            addIvyCacheJar(sb, ivyDirName, org + "/" + name, rev);
302                    }
303            }
304    
305            protected List<String> getCommonJars() {
306                    List<String> jars = new ArrayList<String>();
307    
308                    jars.add("commons-logging.jar");
309                    jars.add("log4j.jar");
310                    jars.add("util-bridges.jar");
311                    jars.add("util-java.jar");
312                    jars.add("util-taglib.jar");
313    
314                    return jars;
315            }
316    
317            protected List<String> getImportSharedJars(File projectDir)
318                    throws Exception {
319    
320                    File buildXmlFile = new File(projectDir, "build.xml");
321    
322                    String content = _fileUtil.read(buildXmlFile);
323    
324                    int x = content.indexOf("import.shared");
325    
326                    if (x == -1) {
327                            return new ArrayList<String>();
328                    }
329    
330                    x = content.indexOf("value=\"", x);
331                    x = content.indexOf("\"", x);
332    
333                    int y = content.indexOf("\" />", x);
334    
335                    if ((x == -1) || (y == -1)) {
336                            return new ArrayList<String>();
337                    }
338    
339                    String[] importShared = StringUtil.split(content.substring(x + 1, y));
340    
341                    if (importShared.length == 0) {
342                            return new ArrayList<String>();
343                    }
344    
345                    List<String> jars = new ArrayList<String>();
346    
347                    for (String currentImportShared : importShared) {
348                            jars.add(currentImportShared + ".jar");
349    
350                            File currentImportSharedLibDir = new File(
351                                    projectDir, "../../shared/" + currentImportShared + "/lib");
352    
353                            if (!currentImportSharedLibDir.exists()) {
354                                    continue;
355                            }
356    
357                            for (File file : currentImportSharedLibDir.listFiles()) {
358                                    jars.add(file.getName());
359                            }
360                    }
361    
362                    return jars;
363            }
364    
365            protected List<String> getPortalDependencyJars(Properties properties) {
366                    String[] dependencyJars = StringUtil.split(
367                            properties.getProperty(
368                                    "portal-dependency-jars",
369                                    properties.getProperty("portal.dependency.jars")));
370    
371                    return ListUtil.toList(dependencyJars);
372            }
373    
374            protected List<String> getRequiredDeploymentContextsJars(
375                            File libDir, Properties properties)
376                    throws Exception {
377    
378                    List<String> jars = new ArrayList<String>();
379    
380                    String[] requiredDeploymentContexts = StringUtil.split(
381                            properties.getProperty("required-deployment-contexts"));
382    
383                    for (String requiredDeploymentContext : requiredDeploymentContexts) {
384                            if (_fileUtil.exists(
385                                            libDir.getCanonicalPath() + "/" +
386                                                    requiredDeploymentContext + "-service.jar")) {
387    
388                                    jars.add(requiredDeploymentContext + "-service.jar");
389                            }
390                    }
391    
392                    return jars;
393            }
394    
395            protected void setupJarProject(
396                            String dirName, String fileName, List<String> dependencyJars,
397                            boolean sharedProject)
398                    throws Exception {
399    
400                    File buildFile = new File(dirName + "/" + fileName);
401    
402                    File projectDir = new File(buildFile.getParent());
403    
404                    File libDir = new File(projectDir, "lib");
405    
406                    if (!libDir.exists()) {
407                            libDir = new File(projectDir, "docroot/WEB-INF/lib");
408                    }
409    
410                    writeEclipseFiles(libDir, projectDir, dependencyJars);
411    
412                    List<String> importSharedJars = getImportSharedJars(projectDir);
413    
414                    if (sharedProject) {
415                            if (!importSharedJars.contains("portal-compat-shared.jar")) {
416                                    importSharedJars.add("portal-compat-shared.jar");
417                            }
418                    }
419    
420                    File gitignoreFile = new File(
421                            projectDir.getCanonicalPath() + "/.gitignore");
422    
423                    String[] gitIgnores = importSharedJars.toArray(
424                            new String[importSharedJars.size()]);
425    
426                    for (int i = 0; i < gitIgnores.length; i++) {
427                            String gitIgnore = gitIgnores[i];
428    
429                            gitIgnore = "/lib/" + gitIgnore;
430    
431                            gitIgnores[i] = gitIgnore;
432                    }
433    
434                    if (gitIgnores.length > 0) {
435                            System.out.println("Updating " + gitignoreFile);
436    
437                            _fileUtil.write(gitignoreFile, StringUtil.merge(gitIgnores, "\n"));
438                    }
439            }
440    
441            protected void setupWarProject(String dirName, String fileName)
442                    throws Exception {
443    
444                    File propertiesFile = new File(dirName + "/" + fileName);
445    
446                    Properties properties = new Properties();
447    
448                    properties.load(new FileInputStream(propertiesFile));
449    
450                    Set<String> jars = new TreeSet<String>();
451    
452                    jars.addAll(getCommonJars());
453    
454                    List<String> dependencyJars = getPortalDependencyJars(properties);
455    
456                    jars.addAll(dependencyJars);
457    
458                    File projectDir = new File(propertiesFile.getParent() + "/../..");
459    
460                    jars.addAll(getImportSharedJars(projectDir));
461    
462                    File libDir = new File(propertiesFile.getParent() + "/lib");
463    
464                    jars.addAll(getRequiredDeploymentContextsJars(libDir, properties));
465    
466                    writeEclipseFiles(libDir, projectDir, dependencyJars);
467    
468                    String libDirPath = StringUtil.replace(
469                            libDir.getPath(), StringPool.BACK_SLASH, StringPool.SLASH);
470    
471                    List<String> ignores = ListUtil.fromFile(
472                            libDir.getCanonicalPath() + "/../.gitignore");
473    
474                    if (libDirPath.contains("/ext/") || ignores.contains("/lib")) {
475                            return;
476                    }
477    
478                    File gitignoreFile = new File(
479                            libDir.getCanonicalPath() + "/.gitignore");
480    
481                    System.out.println("Updating " + gitignoreFile);
482    
483                    String[] gitIgnores = jars.toArray(new String[jars.size()]);
484    
485                    for (int i = 0; i < gitIgnores.length; i++) {
486                            String gitIgnore = gitIgnores[i];
487    
488                            if (Validator.isNotNull(gitIgnore) && !gitIgnore.startsWith("/")) {
489                                    gitIgnores[i] = "/" + gitIgnore;
490                            }
491                    }
492    
493                    _fileUtil.write(gitignoreFile, StringUtil.merge(gitIgnores, "\n"));
494            }
495    
496            protected void writeClasspathFile(
497                            File libDir, List<String> dependencyJars, String projectDirName,
498                            String projectName, boolean javaProject)
499                    throws Exception {
500    
501                    File classpathFile = new File(projectDirName + "/.classpath");
502    
503                    if (!javaProject) {
504                            classpathFile.delete();
505    
506                            return;
507                    }
508    
509                    Set<String> globalJars = new LinkedHashSet<String>();
510                    List<String> portalJars = new ArrayList<String>();
511    
512                    Set<String> extGlobalJars = new LinkedHashSet<String>();
513                    Set<String> extPortalJars = new LinkedHashSet<String>();
514    
515                    String libDirPath = StringUtil.replace(
516                            libDir.getPath(), StringPool.BACK_SLASH, StringPool.SLASH);
517    
518                    if (libDirPath.contains("/ext/")) {
519                            FilenameFilter filenameFilter = new GlobFilenameFilter("*.jar");
520    
521                            for (String dirName : new String[] {"global", "portal"}) {
522                                    File file = new File(libDirPath + "/../ext-lib/" + dirName);
523    
524                                    List<String> jars = ListUtil.toList(file.list(filenameFilter));
525    
526                                    if (dirName.equals("global")) {
527                                            extGlobalJars.addAll(ListUtil.sort(jars));
528    
529                                            File dir = new File(PropsValues.LIFERAY_LIB_GLOBAL_DIR);
530    
531                                            String[] fileNames = dir.list(filenameFilter);
532    
533                                            globalJars.addAll(
534                                                    ListUtil.sort(ListUtil.toList(fileNames)));
535                                            globalJars.removeAll(extGlobalJars);
536                                    }
537                                    else if (dirName.equals("portal")) {
538                                            extPortalJars.addAll(ListUtil.sort(jars));
539    
540                                            File dir = new File(PropsValues.LIFERAY_LIB_PORTAL_DIR);
541    
542                                            String[] fileNames = dir.list(filenameFilter);
543    
544                                            portalJars.addAll(
545                                                    ListUtil.sort(ListUtil.toList(fileNames)));
546                                            portalJars.removeAll(extPortalJars);
547                                    }
548                            }
549                    }
550                    else {
551                            globalJars.add("portlet.jar");
552    
553                            portalJars.addAll(dependencyJars);
554                            portalJars.add("bnd.jar");
555                            portalJars.add("commons-logging.jar");
556                            portalJars.add("log4j.jar");
557    
558                            portalJars = ListUtil.unique(portalJars);
559    
560                            Collections.sort(portalJars);
561                    }
562    
563                    String[] customJarsArray = libDir.list(new GlobFilenameFilter("*.jar"));
564    
565                    List<String> customJars = null;
566    
567                    if (customJarsArray != null) {
568                            customJars = ListUtil.toList(customJarsArray);
569    
570                            for (String jar : portalJars) {
571                                    customJars.remove(jar);
572                            }
573    
574                            customJars.remove(projectName + "-service.jar");
575                            customJars.remove("util-bridges.jar");
576                            customJars.remove("util-java.jar");
577                            customJars.remove("util-taglib.jar");
578    
579                            Collections.sort(customJars);
580                    }
581                    else {
582                            customJars = new ArrayList<String>();
583                    }
584    
585                    StringBundler sb = new StringBundler();
586    
587                    sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n");
588                    sb.append("<classpath>\n");
589    
590                    for (String sourceDirName : _SOURCE_DIR_NAMES) {
591                            if (_fileUtil.exists(projectDirName + "/" + sourceDirName)) {
592                                    sb.append("\t<classpathentry excluding=\"**/.svn/**|.svn/\" ");
593                                    sb.append("kind=\"src\" path=\"");
594                                    sb.append(sourceDirName);
595                                    sb.append("\" />\n");
596                            }
597                    }
598    
599                    sb.append("\t<classpathentry kind=\"src\" path=\"/portal\" />\n");
600                    sb.append("\t<classpathentry kind=\"con\" ");
601                    sb.append("path=\"org.eclipse.jdt.launching.JRE_CONTAINER\" />\n");
602    
603                    boolean addJunitJars = false;
604    
605                    for (String testType : _TEST_TYPES) {
606                            String testFolder = "test/" + testType;
607    
608                            if (_fileUtil.exists(projectDirName + "/" + testFolder)) {
609                                    addJunitJars = true;
610    
611                                    sb.append("\t<classpathentry excluding=\"**/.svn/**|.svn/\" ");
612                                    sb.append("kind=\"src\" path=\"");
613                                    sb.append(testFolder);
614                                    sb.append("\" />\n");
615                            }
616                    }
617    
618                    if (addJunitJars) {
619                            addClasspathEntry(sb, "/portal/lib/development/junit.jar");
620                            addClasspathEntry(sb, "/portal/lib/development/mockito.jar");
621                            addClasspathEntry(
622                                    sb, "/portal/lib/development/powermock-api-mockito.jar");
623                            addClasspathEntry(
624                                    sb, "/portal/lib/development/powermock-api-support.jar");
625                            addClasspathEntry(
626                                    sb, "/portal/lib/development/powermock-module-junit4.jar");
627                            addClasspathEntry(
628                                    sb,
629                                    "/portal/lib/development/powermock-module-junit4-common.jar");
630                            addClasspathEntry(sb, "/portal/lib/development/spring-test.jar");
631    
632                            portalJars.add("commons-io.jar");
633                            portalJars.add("commons-lang.jar");
634                    }
635    
636                    addClasspathEntry(sb, "/portal/lib/development/activation.jar");
637                    addClasspathEntry(sb, "/portal/lib/development/annotations.jar");
638                    addClasspathEntry(sb, "/portal/lib/development/jsp-api.jar");
639                    addClasspathEntry(sb, "/portal/lib/development/mail.jar");
640                    addClasspathEntry(sb, "/portal/lib/development/servlet-api.jar");
641    
642                    Map<String, String> attributes = new HashMap<String, String>();
643    
644                    if (libDirPath.contains("/ext/")) {
645                            attributes.put("optional", "true");
646                    }
647    
648                    for (String jar : globalJars) {
649                            addClasspathEntry(sb, "/portal/lib/global/" + jar, attributes);
650                    }
651    
652                    portalJars = ListUtil.unique(portalJars);
653    
654                    Collections.sort(portalJars);
655    
656                    for (String jar : portalJars) {
657                            if (!jar.equals("util-slf4j.jar")) {
658                                    addClasspathEntry(sb, "/portal/lib/portal/" + jar, attributes);
659                            }
660                    }
661    
662                    addClasspathEntry(sb, "/portal/portal-service/portal-service.jar");
663                    addClasspathEntry(sb, "/portal/util-bridges/util-bridges.jar");
664                    addClasspathEntry(sb, "/portal/util-java/util-java.jar");
665    
666                    if (portalJars.contains("util-slf4j.jar")) {
667                            addClasspathEntry(sb, "/portal/util-slf4j/util-slf4j.jar");
668                    }
669    
670                    addClasspathEntry(sb, "/portal/util-taglib/util-taglib.jar");
671    
672                    for (String jar : extGlobalJars) {
673                            addClasspathEntry(sb, "docroot/WEB-INF/ext-lib/global/" + jar);
674                    }
675    
676                    for (String jar : extPortalJars) {
677                            addClasspathEntry(sb, "docroot/WEB-INF/ext-lib/portal/" + jar);
678                    }
679    
680                    for (String jar : customJars) {
681                            if (libDirPath.contains("/tmp/WEB-INF/lib")) {
682                                    addClasspathEntry(sb, "tmp/WEB-INF/lib/" + jar);
683                            }
684                            else if (libDirPath.contains("/docroot/WEB-INF/lib")) {
685                                    addClasspathEntry(sb, "docroot/WEB-INF/lib/" + jar);
686                            }
687                            else {
688                                    addClasspathEntry(sb, "lib/" + jar);
689                            }
690                    }
691    
692                    File ivyXmlFile = new File(projectDirName, "ivy.xml");
693    
694                    if (ivyXmlFile.exists()) {
695                            String content = _fileUtil.read(ivyXmlFile);
696    
697                            if (content.contains("test->default")) {
698                                    String ivyDirName = ".ivy";
699    
700                                    for (int i = 0; i < 10; i++) {
701                                            if (_fileUtil.exists(ivyDirName)) {
702                                                    break;
703                                            }
704    
705                                            ivyDirName = "../" + ivyDirName;
706                                    }
707    
708                                    addIvyCacheJars(sb, content, ivyDirName);
709                            }
710                    }
711    
712                    sb.append("\t<classpathentry kind=\"output\" path=\"bin\" />\n");
713                    sb.append("</classpath>");
714    
715                    System.out.println("Updating " + classpathFile);
716    
717                    String content = StringUtil.replace(
718                            sb.toString(), "\"/portal", "\"/portal-" + _BRANCH);
719    
720                    _fileUtil.write(classpathFile, content);
721            }
722    
723            protected void writeEclipseFiles(
724                            File libDir, File projectDir, List<String> dependencyJars)
725                    throws Exception {
726    
727                    String projectDirName = projectDir.getCanonicalPath();
728    
729                    String projectName = StringUtil.extractLast(
730                            projectDirName, File.separatorChar);
731    
732                    boolean javaProject = false;
733    
734                    for (String sourceDirName : _SOURCE_DIR_NAMES) {
735                            if (_fileUtil.exists(projectDirName + "/" + sourceDirName)) {
736                                    javaProject = true;
737    
738                                    break;
739                            }
740                    }
741    
742                    if (!javaProject) {
743                            System.out.println(
744                                    "Eclipse Java project will not be used because a source " +
745                                            "folder does not exist");
746                    }
747    
748                    writeProjectFile(projectDirName, projectName, javaProject);
749    
750                    writeClasspathFile(
751                            libDir, dependencyJars, projectDirName, projectName, javaProject);
752    
753                    for (String sourceDirName : _SOURCE_DIR_NAMES) {
754                            if (_fileUtil.exists(projectDirName + "/" + sourceDirName)) {
755                                    List<String> gitIgnores = new ArrayList<String>();
756    
757                                    if (sourceDirName.endsWith("ext-impl/src")) {
758                                            gitIgnores.add("/classes");
759                                            gitIgnores.add("/ext-impl.jar");
760                                    }
761                                    else if (sourceDirName.endsWith("ext-service/src")) {
762                                            gitIgnores.add("/classes");
763                                            gitIgnores.add("/ext-service.jar");
764                                    }
765                                    else if (sourceDirName.endsWith("ext-util-bridges/src")) {
766                                            gitIgnores.add("/classes");
767                                            gitIgnores.add("/ext-util-bridges.jar");
768                                    }
769                                    else if (sourceDirName.endsWith("ext-util-java/src")) {
770                                            gitIgnores.add("/classes");
771                                            gitIgnores.add("/ext-util-java.jar");
772                                    }
773                                    else if (sourceDirName.endsWith("ext-util-taglib/src")) {
774                                            gitIgnores.add("/classes");
775                                            gitIgnores.add("/ext-util-taglib.jar");
776                                    }
777                                    else {
778                                            continue;
779                                    }
780    
781                                    String dirName = projectDirName + "/" + sourceDirName + "/../";
782    
783                                    if (gitIgnores.isEmpty()) {
784                                            _fileUtil.delete(dirName + ".gitignore");
785                                    }
786                                    else {
787                                            String gitIgnoresString = StringUtil.merge(
788                                                    gitIgnores, "\n");
789    
790                                            _fileUtil.write(dirName + ".gitignore", gitIgnoresString);
791                                    }
792                            }
793                    }
794    
795                    if (_fileUtil.exists(projectDirName + "/test")) {
796                            _fileUtil.write(
797                                    projectDirName + "/.gitignore", "/test-classes\n/test-results");
798                    }
799                    else {
800                            _fileUtil.delete(projectDirName + "/.gitignore");
801                    }
802            }
803    
804            protected void writeProjectFile(
805                            String projectDirName, String projectName, boolean javaProject)
806                    throws Exception {
807    
808                    StringBundler sb = new StringBundler(17);
809    
810                    sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n");
811                    sb.append("<projectDescription>\n");
812                    sb.append("\t<name>");
813                    sb.append(projectName);
814                    sb.append("-");
815                    sb.append(_BRANCH);
816                    sb.append("</name>\n");
817                    sb.append("\t<comment></comment>\n");
818                    sb.append("\t<projects></projects>\n");
819                    sb.append("\t<buildSpec>\n");
820    
821                    if (javaProject) {
822                            sb.append("\t\t<buildCommand>\n");
823                            sb.append("\t\t\t<name>org.eclipse.jdt.core.javabuilder</name>\n");
824                            sb.append("\t\t\t<arguments></arguments>\n");
825                            sb.append("\t\t</buildCommand>\n");
826                    }
827    
828                    sb.append("\t</buildSpec>\n");
829                    sb.append("\t<natures>\n");
830    
831                    if (javaProject) {
832                            sb.append("\t\t<nature>org.eclipse.jdt.core.javanature</nature>\n");
833                    }
834    
835                    sb.append("\t</natures>\n");
836                    sb.append("</projectDescription>");
837    
838                    File projectFile = new File(projectDirName + "/.project");
839    
840                    System.out.println("Updating " + projectFile);
841    
842                    _fileUtil.write(projectFile, sb.toString());
843            }
844    
845            private static final String _BRANCH = "master";
846    
847            private static final String[] _SOURCE_DIR_NAMES = new String[] {
848                    "docroot/WEB-INF/ext-impl/src", "docroot/WEB-INF/ext-service/src",
849                    "docroot/WEB-INF/ext-util-bridges/src",
850                    "docroot/WEB-INF/ext-util-java/src",
851                    "docroot/WEB-INF/ext-util-taglib/src", "docroot/WEB-INF/service",
852                    "docroot/WEB-INF/src", "src"
853            };
854    
855            private static final String[] _TEST_TYPES = {"integration", "unit"};
856    
857            private static FileImpl _fileUtil = FileImpl.getInstance();
858            private static SAXReaderImpl _saxReaderUtil = SAXReaderImpl.getInstance();
859    
860    }