1
14
15 package com.liferay.portal.tools;
16
17 import com.liferay.portal.kernel.io.unsync.UnsyncBufferedReader;
18 import com.liferay.portal.kernel.util.FileUtil;
19 import com.liferay.portal.kernel.util.GetterUtil;
20 import com.liferay.portal.kernel.util.ListUtil;
21 import com.liferay.portal.kernel.util.StringBundler;
22 import com.liferay.portal.kernel.util.StringPool;
23 import com.liferay.portal.kernel.util.StringUtil;
24 import com.liferay.portal.kernel.util.Validator;
25 import com.liferay.portal.util.InitUtil;
26
27 import java.io.File;
28 import java.io.FileInputStream;
29 import java.io.IOException;
30 import java.io.InputStream;
31 import java.io.InputStreamReader;
32
33 import java.util.ArrayList;
34 import java.util.Arrays;
35 import java.util.List;
36 import java.util.Properties;
37
38 import org.apache.oro.io.GlobFilenameFilter;
39 import org.apache.tools.ant.DirectoryScanner;
40
41
47 public class PluginsEnvironmentBuilder {
48
49 public static void main(String[] args) throws Exception {
50 InitUtil.initWithSpring();
51
52 File dir = new File(System.getProperty("plugins.env.dir"));
53 boolean svn = GetterUtil.getBoolean(
54 System.getProperty("plugins.env.svn"));
55 boolean eclipse = GetterUtil.getBoolean(
56 System.getProperty("plugins.env.eclipse"));
57
58 new PluginsEnvironmentBuilder(dir, svn, eclipse);
59 }
60
61 public PluginsEnvironmentBuilder(File dir, boolean svn, boolean eclipse) {
62 try {
63 _svn = svn;
64
65 DirectoryScanner ds = new DirectoryScanner();
66
67 ds.setBasedir(dir);
68 ds.setIncludes(
69 new String[] {
70 "**\\liferay-plugin-package.properties",
71 });
72
73 ds.scan();
74
75 String dirName = dir.getCanonicalPath();
76
77 String[] fileNames = ds.getIncludedFiles();
78
79 for (String fileName : fileNames) {
80 File propertiesFile = new File(dirName + "/" + fileName);
81 File libDir = new File(propertiesFile.getParent() + "/lib");
82 File projectDir = new File(
83 propertiesFile.getParent() + "/../..");
84
85 Properties properties = new Properties();
86
87 properties.load(new FileInputStream(propertiesFile));
88
89 String[] dependencyJars = StringUtil.split(
90 properties.getProperty(
91 "portal-dependency-jars",
92 properties.getProperty("portal.dependency.jars")));
93
94 if (svn) {
95 List<String> jars = ListUtil.toList(dependencyJars);
96
97 jars.add("commons-logging.jar");
98 jars.add("log4j.jar");
99 jars.add("util-bridges.jar");
100 jars.add("util-java.jar");
101 jars.add("util-taglib.jar");
102
103 jars = ListUtil.sort(jars);
104
105 updateLibIgnores(
106 libDir, jars.toArray(new String[jars.size()]));
107 }
108
109 if (eclipse) {
110 updateEclipseFiles(libDir, projectDir, dependencyJars);
111 }
112 }
113 }
114 catch (Exception e) {
115 e.printStackTrace();
116 }
117 }
118
119 public void updateEclipseFiles(
120 File libDir, File projectDir, String[] dependencyJars)
121 throws Exception {
122
123 String libDirPath = libDir.getPath();
124
125 libDirPath = StringUtil.replace(
126 libDirPath, StringPool.BACK_SLASH, StringPool.SLASH);
127
128 String projectDirName = projectDir.getCanonicalPath();
129 String projectName = StringUtil.extractLast(
130 projectDirName, File.separator);
131
132 boolean javaProject = false;
133
134 if (FileUtil.exists(projectDirName + "/docroot/WEB-INF/src")) {
135 javaProject = true;
136 }
137 else {
138 System.out.println(
139 "Eclipse Java project will not be used because " +
140 projectDirName + "/docroot/WEB-INF/src does not exist");
141 }
142
143
145 StringBundler sb = new StringBundler(17);
146
147 sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n");
148 sb.append("<projectDescription>\n");
149 sb.append("\t<name>");
150 sb.append(projectName);
151 sb.append("</name>\n");
152 sb.append("\t<comment></comment>\n");
153 sb.append("\t<projects></projects>\n");
154 sb.append("\t<buildSpec>\n");
155
156 if (javaProject) {
157 sb.append("\t\t<buildCommand>\n");
158 sb.append("\t\t\t<name>org.eclipse.jdt.core.javabuilder</name>\n");
159 sb.append("\t\t\t<arguments></arguments>\n");
160 sb.append("\t\t</buildCommand>\n");
161 }
162
163 sb.append("\t</buildSpec>\n");
164 sb.append("\t<natures>\n");
165
166 if (javaProject) {
167 sb.append("\t\t<nature>org.eclipse.jdt.core.javanature</nature>\n");
168 }
169
170 sb.append("\t</natures>\n");
171 sb.append("</projectDescription>");
172
173 File projectFile = new File(projectDirName + "/.project");
174
175 System.out.println("Updating " + projectFile);
176
177 FileUtil.write(projectFile, sb.toString());
178
179
181 File classpathFile = new File(projectDirName + "/.classpath");
182
183 if (javaProject) {
184 List<String> portalJars = ListUtil.toList(dependencyJars);
185
186 portalJars.add("commons-logging.jar");
187 portalJars.add("log4j.jar");
188
189 portalJars = ListUtil.sort(portalJars);
190
191 String[] customJarsArray = libDir.list(
192 new GlobFilenameFilter("*.jar"));
193
194 List<String> customJars = null;
195
196 if (customJarsArray != null) {
197 customJars = ListUtil.toList(customJarsArray);
198
199 customJars = ListUtil.sort(customJars);
200
201 for (String jar : portalJars) {
202 customJars.remove(jar);
203 }
204
205 customJars.remove(projectName + "-service.jar");
206 customJars.remove("util-bridges.jar");
207 customJars.remove("util-java.jar");
208 customJars.remove("util-taglib.jar");
209 }
210 else {
211 customJars = new ArrayList<String>();
212 }
213
214 sb = new StringBundler();
215
216 sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n");
217 sb.append("<classpath>\n");
218
219 if (FileUtil.exists(projectDirName + "/docroot/WEB-INF/service")) {
220 sb.append("\t<classpathentry excluding=\"**/.svn/**|.svn/\" ");
221 sb.append("kind=\"src\" path=\"docroot/WEB-INF/service\" />\n");
222 }
223
224 sb.append("\t<classpathentry excluding=\"**/.svn/**|.svn/\" ");
225 sb.append("kind=\"src\" path=\"docroot/WEB-INF/src\" />\n");
226 sb.append("\t<classpathentry kind=\"src\" path=\"/portal\" />\n");
227 sb.append("\t<classpathentry kind=\"con\" ");
228 sb.append("path=\"org.eclipse.jdt.launching.JRE_CONTAINER\" />\n");
229
230 if (FileUtil.exists(projectDirName + "/test")) {
231 sb.append("\t<classpathentry excluding=\"**/.svn/**|.svn/\" ");
232 sb.append("kind=\"src\" path=\"test\" />\n");
233
234 _addClasspathEntry(sb, "/portal/lib/development/junit.jar");
235 _addClasspathEntry(sb, "/portal/lib/portal/commons-io.jar");
236 }
237
238 _addClasspathEntry(sb, "/portal/lib/development/activation.jar");
239 _addClasspathEntry(sb, "/portal/lib/development/jsp-api.jar");
240 _addClasspathEntry(sb, "/portal/lib/development/mail.jar");
241 _addClasspathEntry(sb, "/portal/lib/development/servlet-api.jar");
242 _addClasspathEntry(sb, "/portal/lib/global/annotations.jar");
243 _addClasspathEntry(sb, "/portal/lib/global/portlet.jar");
244
245 for (String jar : portalJars) {
246 _addClasspathEntry(sb, "/portal/lib/portal/" + jar);
247 }
248
249 _addClasspathEntry(sb, "/portal/portal-kernel/portal-kernel.jar");
250 _addClasspathEntry(sb, "/portal/portal-service/portal-service.jar");
251 _addClasspathEntry(sb, "/portal/util-bridges/util-bridges.jar");
252 _addClasspathEntry(sb, "/portal/util-java/util-java.jar");
253 _addClasspathEntry(sb, "/portal/util-taglib/util-taglib.jar");
254
255 for (String jar : customJars) {
256 if (libDirPath.contains("/tmp/WEB-INF/lib")) {
257 _addClasspathEntry(sb, "tmp/WEB-INF/lib/" + jar);
258 }
259 else {
260 _addClasspathEntry(sb, "docroot/WEB-INF/lib/" + jar);
261 }
262 }
263
264 sb.append("\t<classpathentry kind=\"output\" path=\"bin\" />\n");
265 sb.append("</classpath>");
266
267 System.out.println("Updating " + classpathFile);
268
269 String content = sb.toString();
270
271 content = StringUtil.replace(
272 content, "\"/portal", "\"/portal-5.2.x");
273
274 FileUtil.write(classpathFile, content);
275 }
276 else {
277 classpathFile.delete();
278 }
279
280
282 if (_svn) {
283 String projectFileName = "\"" + projectFile + "\"";
284
285 try {
286 _exec(_SVN_INFO + projectFileName);
287 }
288 catch (Exception e) {
289 _exec(_SVN_ADD + projectFileName);
290 }
291
292 if (javaProject) {
293 String classpathFileName = "\"" + classpathFile + "\"";
294
295 try {
296 _exec(_SVN_INFO + classpathFileName);
297 }
298 catch (Exception e) {
299 _exec(_SVN_ADD + classpathFileName);
300 }
301 }
302
303 File tempFile = File.createTempFile("svn-ignores-", null, null);
304
305 try {
306 if (FileUtil.exists(projectDirName + "/test")) {
307 FileUtil.write(
308 tempFile, "bin\ntest-classes\ntest-results\ntmp");
309 }
310 else {
311 FileUtil.write(tempFile, "bin\ntmp");
312 }
313
314 _exec(
315 _SVN_SET_IGNORES + "-F \"" + tempFile.getCanonicalPath() +
316 "\" \"" + projectDirName + "\"");
317 }
318 finally {
319 FileUtil.delete(tempFile);
320 }
321 }
322 }
323
324 public void updateLibIgnores(File libDir, String[] jars) throws Exception {
325 if (!_isSVNDir(libDir)) {
326 return;
327 }
328
329 File tempFile = null;
330
331 try {
332 String libDirName = "\"" + libDir.getCanonicalPath() + "\"";
333
334 String[] oldIgnores = _exec(_SVN_GET_IGNORES + libDirName);
335
336 Arrays.sort(oldIgnores);
337
338 if (Arrays.equals(oldIgnores, jars)) {
339 return;
340 }
341
342 tempFile = File.createTempFile("svn-ignores-", null, null);
343
344 _exec(_SVN_DEL_IGNORES + libDirName);
345
346 if (jars.length == 0) {
347 FileUtil.write(tempFile, StringPool.BLANK);
348 }
349 else {
350 StringBundler sb = new StringBundler(jars.length * 2);
351
352 for (String jar : jars) {
353 sb.append(jar);
354 sb.append("\n");
355 }
356
357 FileUtil.write(tempFile, sb.toString());
358 }
359
360 _exec(
361 _SVN_SET_IGNORES + "-F \"" + tempFile.getCanonicalPath() +
362 "\" \"" + libDirName + "\"");
363
364 String[] newIgnores = _exec(
365 _SVN_GET_IGNORES + "\"" + libDirName + "\"");
366
367 if (newIgnores.length > 0) {
368 Arrays.sort(newIgnores);
369 }
370 }
371 finally {
372 if (tempFile != null) {
373 FileUtil.delete(tempFile);
374 }
375 }
376 }
377
378 private void _addClasspathEntry(StringBundler sb, String jar)
379 throws Exception {
380
381 sb.append("\t<classpathentry kind=\"lib\" path=\"");
382 sb.append(jar);
383 sb.append("\" />\n");
384 }
385
386 private String[] _exec(String cmd) throws Exception {
387 Process process = Runtime.getRuntime().exec(cmd);
388
389 String[] stdout = _getExecOutput(process.getInputStream());
390 String[] stderr = _getExecOutput(process.getErrorStream());
391
392 if (stderr.length > 0) {
393 StringBundler sb = new StringBundler(stderr.length * 3 + 3);
394
395 sb.append("Received errors in executing '");
396 sb.append(cmd);
397 sb.append("'\n");
398
399 for (String err : stderr) {
400 sb.append("\t");
401 sb.append(err);
402 sb.append("\n");
403 }
404
405 throw new Exception(sb.toString());
406 }
407
408 return stdout;
409 }
410
411 private String[] _getExecOutput(InputStream is) throws IOException {
412 List<String> list = new ArrayList<String>();
413
414 UnsyncBufferedReader unsyncBufferedReader = null;
415
416 try {
417 unsyncBufferedReader = new UnsyncBufferedReader(
418 new InputStreamReader(is));
419
420 String line = unsyncBufferedReader.readLine();
421
422 while (line != null) {
423 line = line.trim();
424
425 if (Validator.isNotNull(line)) {
426 list.add(line);
427 }
428
429 line = unsyncBufferedReader.readLine();
430 }
431 }
432 finally {
433 if (unsyncBufferedReader != null) {
434 try {
435 unsyncBufferedReader.close();
436 }
437 catch (Exception e) {
438 }
439 }
440 }
441
442 return list.toArray(new String[] {});
443 }
444
445 private boolean _isSVNDir(File libDir) {
446 if (!libDir.exists()) {
447 return false;
448 }
449
450 try {
451 _exec(_SVN_INFO + "\"" + libDir + "\"");
452 }
453 catch (Exception e) {
454 return false;
455 }
456
457 return true;
458 }
459
460 private static final String _SVN_ADD = "svn add ";
461
462 private static final String _SVN_DEL_IGNORES = "svn propdel svn:ignore ";
463
464 private static final String _SVN_GET_IGNORES = "svn propget svn:ignore ";
465
466 private static final String _SVN_INFO = "svn info ";
467
468 private static final String _SVN_SET_IGNORES = "svn propset svn:ignore ";
469
470 private boolean _svn;
471
472 }