1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17   * SOFTWARE.
18   */
19  
20  package com.liferay.portal.tools;
21  
22  import com.liferay.portal.kernel.util.FileUtil;
23  import com.liferay.portal.kernel.util.GetterUtil;
24  import com.liferay.portal.kernel.util.ListUtil;
25  import com.liferay.portal.kernel.util.StringUtil;
26  import com.liferay.portal.kernel.util.Validator;
27  import com.liferay.portal.util.InitUtil;
28  
29  import java.io.BufferedReader;
30  import java.io.File;
31  import java.io.FileInputStream;
32  import java.io.IOException;
33  import java.io.InputStream;
34  import java.io.InputStreamReader;
35  
36  import java.util.ArrayList;
37  import java.util.Arrays;
38  import java.util.List;
39  import java.util.Properties;
40  
41  import org.apache.oro.io.GlobFilenameFilter;
42  import org.apache.tools.ant.DirectoryScanner;
43  
44  /**
45   * <a href="PluginsEnvironmentBuilder.java.html"><b><i>View Source</i></b></a>
46   *
47   * @author Alexander Chow
48   * @author Brian Wing Shun Chan
49   *
50   */
51  public class PluginsEnvironmentBuilder {
52  
53      public static void main(String[] args) throws Exception {
54          InitUtil.initWithSpring();
55  
56          File dir = new File(System.getProperty("plugins.env.dir"));
57          boolean svn = GetterUtil.getBoolean(
58              System.getProperty("plugins.env.svn"));
59          boolean eclipse = GetterUtil.getBoolean(
60              System.getProperty("plugins.env.eclipse"));
61  
62          new PluginsEnvironmentBuilder(dir, svn, eclipse);
63      }
64  
65      public PluginsEnvironmentBuilder(File dir, boolean svn, boolean eclipse) {
66          try {
67              _svn = svn;
68  
69              DirectoryScanner ds = new DirectoryScanner();
70  
71              ds.setBasedir(dir);
72              ds.setIncludes(
73                  new String[] {
74                      "**\\liferay-plugin-package.properties",
75                  });
76  
77              ds.scan();
78  
79              String dirName = dir.getCanonicalPath();
80  
81              String[] fileNames = ds.getIncludedFiles();
82  
83              for (String fileName : fileNames) {
84                  File propertiesFile = new File(dirName + "/" + fileName);
85                  File libDir = new File(propertiesFile.getParent() + "/lib");
86                  File projectDir = new File(
87                      propertiesFile.getParent() + "/../..");
88  
89                  Properties properties = new Properties();
90  
91                  properties.load(new FileInputStream(propertiesFile));
92  
93                  List<String> dependencyJars = ListUtil.toList(StringUtil.split(
94                      properties.getProperty(
95                          "portal-dependency-jars",
96                          properties.getProperty("portal.dependency.jars"))));
97  
98                  if (svn) {
99                      List<String> jars = new ArrayList<String>(dependencyJars);
100 
101                     jars.add("commons-logging.jar");
102                     jars.add("log4j.jar");
103                     jars.add("util-bridges.jar");
104                     jars.add("util-java.jar");
105                     jars.add("util-taglib.jar");
106 
107                     jars = ListUtil.sort(jars);
108 
109                     updateLibIgnores(
110                         libDir, jars.toArray(new String[jars.size()]));
111                 }
112 
113                 if (eclipse) {
114                     updateEclipseFiles(libDir, projectDir, dependencyJars);
115                 }
116             }
117         }
118         catch (Exception e) {
119             e.printStackTrace();
120         }
121     }
122 
123     public void updateEclipseFiles(
124             File libDir, File projectDir, List<String> dependencyJars)
125         throws Exception {
126 
127         String projectDirName = projectDir.getCanonicalPath();
128         String projectName = StringUtil.extractLast(
129             projectDirName, File.separator);
130 
131         // .project
132 
133         StringBuilder sb = new StringBuilder();
134 
135         sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n");
136         sb.append("<projectDescription>\n");
137         sb.append("\t<name>" + projectName + "</name>\n");
138         sb.append("\t<comment></comment>\n");
139         sb.append("\t<projects></projects>\n");
140         sb.append("\t<buildSpec>\n");
141         sb.append("\t\t<buildCommand>\n");
142         sb.append("\t\t\t<name>org.eclipse.jdt.core.javabuilder</name>\n");
143         sb.append("\t\t\t<arguments></arguments>\n");
144         sb.append("\t\t</buildCommand>\n");
145         sb.append("\t</buildSpec>\n");
146         sb.append("\t<natures>\n");
147         sb.append("\t\t<nature>org.eclipse.jdt.core.javanature</nature>\n");
148         sb.append("\t</natures>\n");
149         sb.append("</projectDescription>");
150 
151         File projectFile = new File(projectDirName + "/.project");
152 
153         System.out.println("Updating " + projectFile);
154 
155         FileUtil.write(projectFile, sb.toString());
156 
157         // .classpath
158 
159         List<String> portalJars = new ArrayList<String>(dependencyJars);
160 
161         portalJars.add("commons-logging.jar");
162         portalJars.add("log4j.jar");
163 
164         portalJars = ListUtil.sort(portalJars);
165 
166         String[] customJarsArray = libDir.list(new GlobFilenameFilter("*.jar"));
167 
168         List<String> customJars = null;
169 
170         if (customJarsArray != null) {
171             customJars = ListUtil.toList(customJarsArray);
172 
173             customJars = ListUtil.sort(customJars);
174 
175             for (String jar : portalJars) {
176                 customJars.remove(jar);
177             }
178 
179             customJars.remove(projectName + "-service.jar");
180             customJars.remove("util-bridges.jar");
181             customJars.remove("util-java.jar");
182             customJars.remove("util-taglib.jar");
183         }
184         else {
185             customJars = new ArrayList<String>();
186         }
187 
188         sb = new StringBuilder();
189 
190         sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n");
191         sb.append("<classpath>\n");
192 
193         if (FileUtil.exists(projectDirName + "/docroot/WEB-INF/service")) {
194             sb.append("\t<classpathentry excluding=\"**/.svn/**|.svn/\" ");
195             sb.append("kind=\"src\" path=\"docroot/WEB-INF/service\" />\n");
196         }
197 
198         sb.append("\t<classpathentry excluding=\"**/.svn/**|.svn/\" ");
199         sb.append("kind=\"src\" path=\"docroot/WEB-INF/src\" />\n");
200         sb.append("\t<classpathentry kind=\"src\" path=\"/portal\" />\n");
201         sb.append("\t<classpathentry kind=\"con\" ");
202         sb.append("path=\"org.eclipse.jdt.launching.JRE_CONTAINER\" />\n");
203 
204         if (FileUtil.exists(projectDirName + "/docroot/WEB-INF/test")) {
205             sb.append("\t<classpathentry excluding=\"**/.svn/**|.svn/\" ");
206             sb.append("kind=\"src\" path=\"docroot/WEB-INF/test\" />\n");
207         }
208 
209         _addClasspathEntry(sb, "/portal/lib/development/activation.jar");
210         _addClasspathEntry(sb, "/portal/lib/development/jsp-api.jar");
211         _addClasspathEntry(sb, "/portal/lib/development/mail.jar");
212         _addClasspathEntry(sb, "/portal/lib/development/servlet-api.jar");
213         _addClasspathEntry(sb, "/portal/lib/global/annotations.jar");
214         _addClasspathEntry(sb, "/portal/lib/global/container.jar");
215         _addClasspathEntry(sb, "/portal/lib/global/portlet-container.jar");
216         _addClasspathEntry(sb, "/portal/lib/global/portlet.jar");
217 
218         for (String jar : portalJars) {
219             _addClasspathEntry(sb, "/portal/lib/portal/" + jar);
220         }
221 
222         _addClasspathEntry(sb, "/portal/portal-kernel/portal-kernel.jar");
223         _addClasspathEntry(sb, "/portal/portal-service/portal-service.jar");
224         _addClasspathEntry(sb, "/portal/util-bridges/util-bridges.jar");
225         _addClasspathEntry(sb, "/portal/util-java/util-java.jar");
226         _addClasspathEntry(sb, "/portal/util-taglib/util-taglib.jar");
227 
228         for (String jar : customJars) {
229             _addClasspathEntry(sb, "docroot/WEB-INF/lib/" + jar);
230         }
231 
232         sb.append("\t<classpathentry kind=\"output\" path=\"bin\" />\n");
233         sb.append("</classpath>");
234 
235         File classpathFile = new File(projectDirName + "/.classpath");
236 
237         System.out.println("Updating " + classpathFile);
238 
239         FileUtil.write(classpathFile, sb.toString());
240 
241         // SVN
242 
243         if (_svn) {
244             String projectFileName = "\"" + projectFile + "\"";
245 
246             try {
247                 _exec(_SVN_INFO + projectFileName);
248             }
249             catch (Exception e) {
250                 _exec(_SVN_ADD + projectFileName);
251             }
252 
253             String classpathFileName = "\"" + classpathFile + "\"";
254 
255             try {
256                 _exec(_SVN_INFO + classpathFileName);
257             }
258             catch (Exception e) {
259                 _exec(_SVN_ADD + classpathFileName);
260             }
261 
262             File tempFile = File.createTempFile("svn-ignores-", null, null);
263 
264             try {
265                 FileUtil.write(tempFile, "bin\ntmp");
266 
267                 _exec(
268                     _SVN_SET_IGNORES + "-F \"" + tempFile.getCanonicalPath() +
269                         "\" \"" + projectDirName + "\"");
270             }
271             finally {
272                 FileUtil.delete(tempFile);
273             }
274         }
275     }
276 
277     public void updateLibIgnores(File libDir, String[] jars) throws Exception {
278         if (!_isSVNDir(libDir)) {
279             return;
280         }
281 
282         File tempFile = null;
283 
284         try {
285             String libDirName = "\"" + libDir.getCanonicalPath() + "\"";
286 
287             String[] oldIgnores = _exec(_SVN_GET_IGNORES + libDirName);
288 
289             Arrays.sort(oldIgnores);
290 
291             if (Arrays.equals(oldIgnores, jars)) {
292                 return;
293             }
294 
295             tempFile = File.createTempFile("svn-ignores-", null, null);
296 
297             _exec(_SVN_DEL_IGNORES + libDirName);
298 
299             StringBuilder sb = new StringBuilder();
300 
301             for (String jar : jars) {
302                 sb.append(jar + "\n");
303             }
304 
305             FileUtil.write(tempFile, sb.toString());
306 
307             _exec(
308                 _SVN_SET_IGNORES + "-F \"" + tempFile.getCanonicalPath() +
309                     "\" \"" + libDirName + "\"");
310 
311             String[] newIgnores = _exec(
312                 _SVN_GET_IGNORES + "\"" + libDirName + "\"");
313 
314             if (newIgnores.length > 0) {
315                 Arrays.sort(newIgnores);
316             }
317         }
318         finally {
319             if (tempFile != null) {
320                 FileUtil.delete(tempFile);
321             }
322         }
323     }
324 
325     private void _addClasspathEntry(StringBuilder sb, String jar)
326         throws Exception {
327 
328         sb.append("\t<classpathentry kind=\"lib\" path=\"");
329         sb.append(jar);
330         sb.append("\" />\n");
331     }
332 
333     private String[] _exec(String cmd) throws Exception {
334         Process process = Runtime.getRuntime().exec(cmd);
335 
336         String[] stdout = _getExecOutput(process.getInputStream());
337         String[] stderr = _getExecOutput(process.getErrorStream());
338 
339         if (stderr.length > 0) {
340             StringBuilder sb = new StringBuilder();
341 
342             sb.append("Received errors in executing '" + cmd + "'\n");
343 
344             for (String err : stderr) {
345                 sb.append("\t" + err + "\n");
346             }
347 
348             throw new Exception(sb.toString());
349         }
350 
351         return stdout;
352     }
353 
354     private String[] _getExecOutput(InputStream is) throws IOException {
355         List<String> list = new ArrayList<String>();
356 
357         BufferedReader br = null;
358 
359         try {
360             br = new BufferedReader(new InputStreamReader(is));
361 
362             String line = br.readLine();
363 
364             while (line != null) {
365                 line = line.trim();
366 
367                 if (Validator.isNotNull(line)) {
368                     list.add(line);
369                 }
370 
371                 line = br.readLine();
372             }
373         }
374         finally {
375             if (br != null) {
376                 try {
377                     br.close();
378                 }
379                 catch (Exception e) {
380                 }
381             }
382         }
383 
384         return list.toArray(new String[] {});
385     }
386 
387     private boolean _isSVNDir(File libDir) {
388         if (!libDir.exists()) {
389             return false;
390         }
391 
392         try {
393             _exec(_SVN_INFO + "\"" + libDir + "\"");
394         }
395         catch (Exception e) {
396             return false;
397         }
398 
399         return true;
400     }
401 
402     private static final String _SVN_ADD = "svn add ";
403 
404     private static final String _SVN_DEL_IGNORES = "svn propdel svn:ignore ";
405 
406     private static final String _SVN_GET_IGNORES = "svn propget svn:ignore ";
407 
408     private static final String _SVN_INFO = "svn info ";
409 
410     private static final String _SVN_SET_IGNORES = "svn propset svn:ignore ";
411 
412     private boolean _svn;
413 
414 }