001 /** 002 * Copyright (c) 2000-2010 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.io.unsync.UnsyncBufferedReader; 018 import com.liferay.portal.kernel.util.FileUtil; 019 import com.liferay.portal.kernel.util.GetterUtil; 020 import com.liferay.portal.kernel.util.ListUtil; 021 import com.liferay.portal.kernel.util.StringBundler; 022 import com.liferay.portal.kernel.util.StringPool; 023 import com.liferay.portal.kernel.util.StringUtil; 024 import com.liferay.portal.kernel.util.Validator; 025 import com.liferay.portal.util.InitUtil; 026 027 import java.io.File; 028 import java.io.FileInputStream; 029 import java.io.IOException; 030 import java.io.InputStream; 031 import java.io.InputStreamReader; 032 033 import java.util.ArrayList; 034 import java.util.Arrays; 035 import java.util.List; 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 InitUtil.initWithSpring(); 049 050 File dir = new File(System.getProperty("plugins.env.dir")); 051 boolean svn = GetterUtil.getBoolean( 052 System.getProperty("plugins.env.svn")); 053 boolean eclipse = GetterUtil.getBoolean( 054 System.getProperty("plugins.env.eclipse")); 055 056 new PluginsEnvironmentBuilder(dir, svn, eclipse); 057 } 058 059 public PluginsEnvironmentBuilder(File dir, boolean svn, boolean eclipse) { 060 try { 061 _svn = svn; 062 063 DirectoryScanner ds = new DirectoryScanner(); 064 065 ds.setBasedir(dir); 066 ds.setIncludes( 067 new String[] { 068 "**\\liferay-plugin-package.properties", 069 }); 070 071 ds.scan(); 072 073 String dirName = dir.getCanonicalPath(); 074 075 String[] fileNames = ds.getIncludedFiles(); 076 077 for (String fileName : fileNames) { 078 File propertiesFile = new File(dirName + "/" + fileName); 079 File libDir = new File(propertiesFile.getParent() + "/lib"); 080 File projectDir = new File( 081 propertiesFile.getParent() + "/../.."); 082 083 Properties properties = new Properties(); 084 085 properties.load(new FileInputStream(propertiesFile)); 086 087 String[] dependencyJars = StringUtil.split( 088 properties.getProperty( 089 "portal-dependency-jars", 090 properties.getProperty("portal.dependency.jars"))); 091 092 if (svn) { 093 List<String> jars = ListUtil.toList(dependencyJars); 094 095 jars.add("commons-logging.jar"); 096 jars.add("log4j.jar"); 097 jars.add("util-bridges.jar"); 098 jars.add("util-java.jar"); 099 jars.add("util-taglib.jar"); 100 101 jars = ListUtil.sort(jars); 102 103 updateLibIgnores( 104 libDir, jars.toArray(new String[jars.size()])); 105 } 106 107 if (eclipse) { 108 updateEclipseFiles(libDir, projectDir, dependencyJars); 109 } 110 } 111 } 112 catch (Exception e) { 113 e.printStackTrace(); 114 } 115 } 116 117 public void updateEclipseFiles( 118 File libDir, File projectDir, String[] dependencyJars) 119 throws Exception { 120 121 String libDirPath = libDir.getPath(); 122 123 libDirPath = StringUtil.replace( 124 libDirPath, StringPool.BACK_SLASH, StringPool.SLASH); 125 126 String projectDirName = projectDir.getCanonicalPath(); 127 String projectName = StringUtil.extractLast( 128 projectDirName, File.separator); 129 130 boolean javaProject = false; 131 132 if (FileUtil.exists(projectDirName + "/docroot/WEB-INF/src")) { 133 javaProject = true; 134 } 135 136 // .project 137 138 StringBundler sb = new StringBundler(17); 139 140 sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n"); 141 sb.append("<projectDescription>\n"); 142 sb.append("\t<name>"); 143 sb.append(projectName); 144 sb.append("</name>\n"); 145 sb.append("\t<comment></comment>\n"); 146 sb.append("\t<projects></projects>\n"); 147 sb.append("\t<buildSpec>\n"); 148 149 if (javaProject) { 150 sb.append("\t\t<buildCommand>\n"); 151 sb.append("\t\t\t<name>org.eclipse.jdt.core.javabuilder</name>\n"); 152 sb.append("\t\t\t<arguments></arguments>\n"); 153 sb.append("\t\t</buildCommand>\n"); 154 } 155 156 sb.append("\t</buildSpec>\n"); 157 sb.append("\t<natures>\n"); 158 159 if (javaProject) { 160 sb.append("\t\t<nature>org.eclipse.jdt.core.javanature</nature>\n"); 161 } 162 163 sb.append("\t</natures>\n"); 164 sb.append("</projectDescription>"); 165 166 File projectFile = new File(projectDirName + "/.project"); 167 168 System.out.println("Updating " + projectFile); 169 170 FileUtil.write(projectFile, sb.toString()); 171 172 // .classpath 173 174 File classpathFile = null; 175 176 if (javaProject) { 177 List<String> portalJars = ListUtil.toList(dependencyJars); 178 179 portalJars.add("commons-logging.jar"); 180 portalJars.add("log4j.jar"); 181 182 portalJars = ListUtil.sort(portalJars); 183 184 String[] customJarsArray = libDir.list( 185 new GlobFilenameFilter("*.jar")); 186 187 List<String> customJars = null; 188 189 if (customJarsArray != null) { 190 customJars = ListUtil.toList(customJarsArray); 191 192 customJars = ListUtil.sort(customJars); 193 194 for (String jar : portalJars) { 195 customJars.remove(jar); 196 } 197 198 customJars.remove(projectName + "-service.jar"); 199 customJars.remove("util-bridges.jar"); 200 customJars.remove("util-java.jar"); 201 customJars.remove("util-taglib.jar"); 202 } 203 else { 204 customJars = new ArrayList<String>(); 205 } 206 207 sb = new StringBundler(); 208 209 sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n"); 210 sb.append("<classpath>\n"); 211 212 if (FileUtil.exists(projectDirName + "/docroot/WEB-INF/service")) { 213 sb.append("\t<classpathentry excluding=\"**/.svn/**|.svn/\" "); 214 sb.append("kind=\"src\" path=\"docroot/WEB-INF/service\" />\n"); 215 } 216 217 sb.append("\t<classpathentry excluding=\"**/.svn/**|.svn/\" "); 218 sb.append("kind=\"src\" path=\"docroot/WEB-INF/src\" />\n"); 219 sb.append("\t<classpathentry kind=\"src\" path=\"/portal\" />\n"); 220 sb.append("\t<classpathentry kind=\"con\" "); 221 sb.append("path=\"org.eclipse.jdt.launching.JRE_CONTAINER\" />\n"); 222 223 if (FileUtil.exists(projectDirName + "/docroot/WEB-INF/test")) { 224 sb.append("\t<classpathentry excluding=\"**/.svn/**|.svn/\" "); 225 sb.append("kind=\"src\" path=\"docroot/WEB-INF/test\" />\n"); 226 } 227 228 _addClasspathEntry(sb, "/portal/lib/development/activation.jar"); 229 _addClasspathEntry(sb, "/portal/lib/development/annotations.jar"); 230 _addClasspathEntry(sb, "/portal/lib/development/jsp-api.jar"); 231 _addClasspathEntry(sb, "/portal/lib/development/mail.jar"); 232 _addClasspathEntry(sb, "/portal/lib/development/servlet-api.jar"); 233 _addClasspathEntry(sb, "/portal/lib/global/portlet.jar"); 234 235 for (String jar : portalJars) { 236 _addClasspathEntry(sb, "/portal/lib/portal/" + jar); 237 } 238 239 _addClasspathEntry(sb, "/portal/portal-service/portal-service.jar"); 240 _addClasspathEntry(sb, "/portal/util-bridges/util-bridges.jar"); 241 _addClasspathEntry(sb, "/portal/util-java/util-java.jar"); 242 _addClasspathEntry(sb, "/portal/util-taglib/util-taglib.jar"); 243 244 for (String jar : customJars) { 245 if (libDirPath.contains("/tmp/WEB-INF/lib")) { 246 _addClasspathEntry(sb, "tmp/WEB-INF/lib/" + jar); 247 } 248 else { 249 _addClasspathEntry(sb, "docroot/WEB-INF/lib/" + jar); 250 } 251 } 252 253 sb.append("\t<classpathentry kind=\"output\" path=\"bin\" />\n"); 254 sb.append("</classpath>"); 255 256 classpathFile = new File(projectDirName + "/.classpath"); 257 258 System.out.println("Updating " + classpathFile); 259 260 String content = sb.toString(); 261 262 content = StringUtil.replace( 263 content, "\"/portal", "\"/portal-trunk"); 264 265 FileUtil.write(classpathFile, content); 266 } 267 268 // SVN 269 270 if (_svn) { 271 String projectFileName = "\"" + projectFile + "\""; 272 273 try { 274 _exec(_SVN_INFO + projectFileName); 275 } 276 catch (Exception e) { 277 _exec(_SVN_ADD + projectFileName); 278 } 279 280 if (javaProject) { 281 String classpathFileName = "\"" + classpathFile + "\""; 282 283 try { 284 _exec(_SVN_INFO + classpathFileName); 285 } 286 catch (Exception e) { 287 _exec(_SVN_ADD + classpathFileName); 288 } 289 } 290 291 File tempFile = File.createTempFile("svn-ignores-", null, null); 292 293 try { 294 FileUtil.write(tempFile, "bin\ntmp"); 295 296 _exec( 297 _SVN_SET_IGNORES + "-F \"" + tempFile.getCanonicalPath() + 298 "\" \"" + projectDirName + "\""); 299 } 300 finally { 301 FileUtil.delete(tempFile); 302 } 303 } 304 } 305 306 public void updateLibIgnores(File libDir, String[] jars) throws Exception { 307 if (!_isSVNDir(libDir)) { 308 return; 309 } 310 311 File tempFile = null; 312 313 try { 314 String libDirName = "\"" + libDir.getCanonicalPath() + "\""; 315 316 String[] oldIgnores = _exec(_SVN_GET_IGNORES + libDirName); 317 318 Arrays.sort(oldIgnores); 319 320 if (Arrays.equals(oldIgnores, jars)) { 321 return; 322 } 323 324 tempFile = File.createTempFile("svn-ignores-", null, null); 325 326 _exec(_SVN_DEL_IGNORES + libDirName); 327 328 if (jars.length == 0) { 329 FileUtil.write(tempFile, StringPool.BLANK); 330 } 331 else { 332 StringBundler sb = new StringBundler(jars.length * 2); 333 334 for (String jar : jars) { 335 sb.append(jar); 336 sb.append("\n"); 337 } 338 339 FileUtil.write(tempFile, sb.toString()); 340 } 341 342 _exec( 343 _SVN_SET_IGNORES + "-F \"" + tempFile.getCanonicalPath() + 344 "\" \"" + libDirName + "\""); 345 346 String[] newIgnores = _exec( 347 _SVN_GET_IGNORES + "\"" + libDirName + "\""); 348 349 if (newIgnores.length > 0) { 350 Arrays.sort(newIgnores); 351 } 352 } 353 finally { 354 if (tempFile != null) { 355 FileUtil.delete(tempFile); 356 } 357 } 358 } 359 360 private void _addClasspathEntry(StringBundler sb, String jar) 361 throws Exception { 362 363 sb.append("\t<classpathentry kind=\"lib\" path=\""); 364 sb.append(jar); 365 sb.append("\" />\n"); 366 } 367 368 private String[] _exec(String cmd) throws Exception { 369 Process process = Runtime.getRuntime().exec(cmd); 370 371 String[] stdout = _getExecOutput(process.getInputStream()); 372 String[] stderr = _getExecOutput(process.getErrorStream()); 373 374 if (stderr.length > 0) { 375 StringBundler sb = new StringBundler(stderr.length * 3 + 3); 376 377 sb.append("Received errors in executing '"); 378 sb.append(cmd); 379 sb.append("'\n"); 380 381 for (String err : stderr) { 382 sb.append("\t"); 383 sb.append(err); 384 sb.append("\n"); 385 } 386 387 throw new Exception(sb.toString()); 388 } 389 390 return stdout; 391 } 392 393 private String[] _getExecOutput(InputStream is) throws IOException { 394 List<String> list = new ArrayList<String>(); 395 396 UnsyncBufferedReader unsyncBufferedReader = null; 397 398 try { 399 unsyncBufferedReader = new UnsyncBufferedReader( 400 new InputStreamReader(is)); 401 402 String line = unsyncBufferedReader.readLine(); 403 404 while (line != null) { 405 line = line.trim(); 406 407 if (Validator.isNotNull(line)) { 408 list.add(line); 409 } 410 411 line = unsyncBufferedReader.readLine(); 412 } 413 } 414 finally { 415 if (unsyncBufferedReader != null) { 416 try { 417 unsyncBufferedReader.close(); 418 } 419 catch (Exception e) { 420 } 421 } 422 } 423 424 return list.toArray(new String[] {}); 425 } 426 427 private boolean _isSVNDir(File libDir) { 428 if (!libDir.exists()) { 429 return false; 430 } 431 432 try { 433 _exec(_SVN_INFO + "\"" + libDir + "\""); 434 } 435 catch (Exception e) { 436 return false; 437 } 438 439 return true; 440 } 441 442 private static final String _SVN_ADD = "svn add "; 443 444 private static final String _SVN_DEL_IGNORES = "svn propdel svn:ignore "; 445 446 private static final String _SVN_GET_IGNORES = "svn propget svn:ignore "; 447 448 private static final String _SVN_INFO = "svn info "; 449 450 private static final String _SVN_SET_IGNORES = "svn propset svn:ignore "; 451 452 private boolean _svn; 453 454 }