1 19 20 package org.netbeans.modules.apisupport.project.ui.customizer; 21 22 import java.io.File ; 23 import java.io.IOException ; 24 import java.util.ArrayList ; 25 import java.util.Arrays ; 26 import java.util.Collection ; 27 import java.util.HashSet ; 28 import java.util.Iterator ; 29 import java.util.List ; 30 import java.util.Set ; 31 import org.netbeans.api.project.Project; 32 import org.netbeans.api.project.ProjectManager; 33 import org.netbeans.api.project.ProjectUtils; 34 import org.netbeans.api.queries.CollocationQuery; 35 import org.netbeans.modules.apisupport.project.NbModuleProject; 36 import org.netbeans.modules.apisupport.project.NbModuleProjectGenerator; 37 import org.netbeans.modules.apisupport.project.spi.NbModuleProvider; 38 import org.netbeans.modules.apisupport.project.ProjectXMLManager; 39 import org.netbeans.modules.apisupport.project.SuiteProvider; 40 import org.netbeans.modules.apisupport.project.Util; 41 import org.netbeans.modules.apisupport.project.suite.SuiteProject; 42 import org.netbeans.spi.project.SubprojectProvider; 43 import org.netbeans.spi.project.support.ant.EditableProperties; 44 import org.netbeans.spi.project.support.ant.PropertyUtils; 45 import org.openide.ErrorManager; 46 import org.openide.filesystems.FileObject; 47 import org.openide.filesystems.FileSystem; 48 import org.openide.filesystems.FileUtil; 49 import org.openide.util.Mutex; 50 import org.openide.util.MutexException; 51 import org.openide.util.NbCollections; 52 53 63 public final class SuiteUtils { 64 65 private static final String ANT_PURE_PROPERTY_REFERENCE_REGEXP = "\\$\\{\\p{Graph}+\\}"; 68 private static final String PRIVATE_PLATFORM_PROPERTIES = "nbproject/private/platform-private.properties"; 70 static final String MODULES_PROPERTY = "modules"; 72 private final SuiteProperties suiteProps; 73 74 private SuiteUtils(final SuiteProperties suiteProps) { 75 this.suiteProps = suiteProps; 76 } 77 78 82 public static NbModuleProject[] getDependentModules(final NbModuleProject suiteComponent) throws IOException { 83 final String cnb = suiteComponent.getCodeNameBase(); 84 try { 85 return ProjectManager.mutex().readAccess(new Mutex.ExceptionAction<NbModuleProject[]>(){ 86 public NbModuleProject[] run() throws Exception { 87 Set <NbModuleProject> result = new HashSet <NbModuleProject>(); 88 SuiteProject suite = SuiteUtils.findSuite(suiteComponent); 89 if (suite == null) { Util.err.log(ErrorManager.WARNING, 91 "Cannot find suite for the given suitecomponent (" + suiteComponent + ')'); } else { 93 for (NbModuleProject p : SuiteUtils.getSubProjects(suite)) { 94 for (ModuleDependency dep : new ProjectXMLManager(p).getDirectDependencies()) { 95 if (dep.getModuleEntry().getCodeNameBase().equals(cnb)) { 96 result.add(p); 97 break; 98 } 99 } 100 } 101 } 102 return result.toArray(new NbModuleProject[result.size()]); 103 } 104 }); 105 } catch (MutexException e) { 106 throw (IOException ) e.getException(); 107 } 108 } 109 110 115 public static void replaceSubModules(final SuiteProperties suiteProps) throws IOException { 116 try { 117 ProjectManager.mutex().writeAccess(new Mutex.ExceptionAction<Void >() { 118 public Void run() throws Exception { 119 SuiteUtils utils = new SuiteUtils(suiteProps); 120 Set <NbModuleProject> currentModules = suiteProps.getSubModules(); 121 Set <NbModuleProject> origSubModules = suiteProps.getOrigSubModules(); 122 123 for (NbModuleProject origModule : origSubModules) { 125 if (!currentModules.contains(origModule)) { 126 Util.err.log("Removing module: " + origModule); removeModule(origModule, suiteProps); 128 } 129 } 130 131 for (NbModuleProject currentModule : currentModules) { 133 if (SuiteUtils.contains(suiteProps.getProject(), currentModule)) { 134 Util.err.log("Module \"" + currentModule + "\" or a module with the same CNB is already contained in the suite."); continue; 136 } 137 utils.addModule(currentModule); 138 } 139 return null; 140 } 141 }); 142 } catch (MutexException e) { 143 throw (IOException ) e.getException(); 144 } 145 } 146 147 154 public static void addModule(final SuiteProject suite, final NbModuleProject project) throws IOException { 155 try { 156 ProjectManager.mutex().writeAccess(new Mutex.ExceptionAction<Void >() { 157 public Void run() throws Exception { 158 final SuiteProperties suiteProps = new SuiteProperties(suite, suite.getHelper(), 159 suite.getEvaluator(), getSubProjects(suite)); 160 if (!SuiteUtils.contains(suite, project)) { 161 SuiteUtils utils = new SuiteUtils(suiteProps); 162 utils.addModule(project); 163 suiteProps.storeProperties(); 164 } else { 165 Util.err.log("Module \"" + project + "\" or a module with the same CNB is already contained in the suite."); } 167 ProjectManager.getDefault().saveProject(suite); 168 return null; 169 } 170 }); 171 } catch (MutexException e) { 172 throw (IOException ) e.getException(); 173 } 174 } 175 176 182 public static void removeModuleFromSuiteWithDependencies(final NbModuleProject suiteComponent) throws IOException { 183 try { 184 ProjectManager.mutex().writeAccess(new Mutex.ExceptionAction<Void >() { 185 public Void run() throws Exception { 186 NbModuleProject[] modules = SuiteUtils.getDependentModules(suiteComponent); 187 String cnb = suiteComponent.getCodeNameBase(); 189 for (int j = 0; j < modules.length; j++) { 190 ProjectXMLManager pxm = new ProjectXMLManager(modules[j]); 191 pxm.removeDependency(cnb); 192 ProjectManager.getDefault().saveProject(modules[j]); 193 } 194 SuiteUtils.removeModuleFromSuite(suiteComponent); 196 return null; 197 } 198 }); 199 } catch (MutexException e) { 200 throw (IOException ) e.getException(); 201 } 202 } 203 204 209 public static void removeModuleFromSuite(final NbModuleProject suiteComponent) throws IOException { 210 try { 211 ProjectManager.mutex().writeAccess(new Mutex.ExceptionAction<Void >() { 212 public Void run() throws Exception { 213 SuiteProject suite = SuiteUtils.findSuite(suiteComponent); 214 if (suite != null) { 215 SuiteProperties suiteProps = new SuiteProperties(suite, suite.getHelper(), 217 suite.getEvaluator(), getSubProjects(suite)); 218 SuiteUtils utils = new SuiteUtils(suiteProps); 219 removeModule(suiteComponent, suiteProps); 220 suiteProps.storeProperties(); 221 ProjectManager.getDefault().saveProject(suite); 222 } else if (Util.getModuleType(suiteComponent) == NbModuleProvider.SUITE_COMPONENT) { 223 removeModule(suiteComponent, null); 224 } 225 return null; 226 } 227 }); 228 } catch (MutexException e) { 229 throw (IOException ) e.getException(); 230 } 231 } 232 233 private void addModule(final NbModuleProject project) throws IOException , IllegalArgumentException { 234 SuiteUtils.removeModuleFromSuite(project); 235 attachSubModuleToSuite(project); 237 } 238 239 251 private static void removeModule(final NbModuleProject subModule, final SuiteProperties suiteProps) { 252 NbModuleProvider.NbModuleType type = Util.getModuleType(subModule); 253 assert type == NbModuleProvider.SUITE_COMPONENT : "Not a suite component: " + subModule; 254 try { 255 subModule.getProjectDirectory().getFileSystem().runAtomicAction(new FileSystem.AtomicAction() { 256 public void run() throws IOException { 257 subModule.setRunInAtomicAction(true); 258 try { 259 FileObject subModuleDir = subModule.getProjectDirectory(); 261 FileObject fo = subModuleDir.getFileObject( 262 "nbproject/suite.properties"); if (fo != null) { 264 fo.delete(); 268 } 269 fo = subModuleDir.getFileObject( 270 "nbproject/private/suite-private.properties"); if (fo != null) { 272 fo.delete(); 273 } 274 275 if (suiteProps != null) { 276 FileObject plafPropsFO = suiteProps.getProject().getProjectDirectory(). 278 getFileObject("nbproject/platform.properties"); FileObject subModuleNbProject = subModuleDir.getFileObject("nbproject"); if (subModuleNbProject.getFileObject("platform.properties") == null) { FileUtil.copyFile(plafPropsFO, subModuleNbProject, "platform"); } 283 } 284 EditableProperties props = subModule.getHelper().getProperties(PRIVATE_PLATFORM_PROPERTIES); 285 if (props.getProperty("user.properties.file") == null) { String nbuser = System.getProperty("netbeans.user"); if (nbuser != null) { 288 props.setProperty("user.properties.file", new File (nbuser, "build.properties").getAbsolutePath()); subModule.getHelper().putProperties(PRIVATE_PLATFORM_PROPERTIES, props); 290 } else { 291 Util.err.log("netbeans.user system property is not defined. Skipping " + PRIVATE_PLATFORM_PROPERTIES + " creation."); } 293 } 294 295 SuiteUtils.setNbModuleType(subModule, NbModuleProvider.STANDALONE); 296 ProjectManager.getDefault().saveProject(subModule); 298 } finally { 299 subModule.setRunInAtomicAction(false); 300 } 301 } 302 }); 303 304 if (suiteProps != null) { 306 removeFromProperties(subModule, suiteProps); 307 } 308 } catch (IOException ex) { 309 ErrorManager.getDefault().notify(ex); 310 } 311 } 312 313 320 private static boolean removeFromProperties(NbModuleProject moduleToRemove, SuiteProperties suiteProps) { 321 String modulesProp = suiteProps.getProperty(MODULES_PROPERTY); 322 boolean removed = false; 323 if (modulesProp != null) { 324 List <String > pieces = new ArrayList <String >(Arrays.asList(PropertyUtils.tokenizePath(modulesProp))); 325 for (Iterator <String > piecesIt = pieces.iterator(); piecesIt.hasNext(); ) { 326 String unevaluated = piecesIt.next(); 327 String evaluated = suiteProps.getEvaluator().evaluate(unevaluated); 328 if (evaluated == null) { 329 Util.err.log("Cannot evaluate " + unevaluated + " property."); continue; 331 } 332 if (moduleToRemove.getProjectDirectory() != 333 suiteProps.getHelper().resolveFileObject(evaluated)) { 334 continue; 335 } 336 piecesIt.remove(); 337 String [] newModulesProp = getAntProperty(pieces); 338 suiteProps.setProperty(MODULES_PROPERTY, newModulesProp); 339 removed = true; 340 if (unevaluated.matches(ANT_PURE_PROPERTY_REFERENCE_REGEXP)) { 343 String key = unevaluated.substring(2, unevaluated.length() - 1); 344 suiteProps.removeProperty(key); 345 suiteProps.removePrivateProperty(key); 346 } 347 break; 348 } 349 } 350 if (!removed) { 351 Util.err.log("Removing of " + moduleToRemove + " was unsuccessful."); } 353 return removed; 354 } 355 356 private void attachSubModuleToSuite(Project subModule) throws IOException { 357 File projectDirF = FileUtil.toFile(subModule.getProjectDirectory()); 359 File suiteDirF = suiteProps.getProjectDirectoryFile(); 360 String projectPropKey = generatePropertyKey(subModule); 361 if (CollocationQuery.areCollocated(projectDirF, suiteDirF)) { 362 suiteProps.setProperty(projectPropKey, 363 PropertyUtils.relativizeFile(suiteDirF, projectDirF)); 364 } else { 365 suiteProps.setPrivateProperty(projectPropKey, projectDirF.getAbsolutePath()); 366 } 367 String origModules = suiteProps.getProperty(MODULES_PROPERTY); 368 StringBuffer modules = new StringBuffer (origModules == null ? "" : origModules); 369 if (modules.length() > 0) { 370 modules.append(':'); 371 } 372 modules.append("${").append(projectPropKey).append('}'); suiteProps.setProperty(MODULES_PROPERTY, modules.toString().split("(?<=:)", -1)); 375 NbModuleProjectGenerator.createSuiteProperties(subModule.getProjectDirectory(), suiteDirF); 377 setNbModuleType(subModule, NbModuleProvider.SUITE_COMPONENT); 378 ProjectManager.getDefault().saveProject(subModule); 379 } 380 381 382 private String generatePropertyKey(final Project subModule) { 383 String key = "project." + ProjectUtils.getInformation(subModule).getName(); String [] keys = suiteProps.getProperty(MODULES_PROPERTY).split("(?<=:)", -1); int index = 0; 386 while (Arrays.binarySearch(keys, "${" + key + "}") >= 0) { key += "_" + ++index; } 389 return key; 390 } 391 392 private static void setNbModuleType(Project module, NbModuleProvider.NbModuleType type) throws IOException { 393 ProjectXMLManager pxm = new ProjectXMLManager(((NbModuleProject) module)); 394 pxm.setModuleType(type); 395 } 396 397 private static String [] getAntProperty(final Collection <String > pieces) { 398 List <String > l = new ArrayList <String >(); 399 for (Iterator <String > it = pieces.iterator(); it.hasNext();) { 400 String piece = it.next() + (it.hasNext() ? ":" : ""); l.add(piece); 402 } 403 return l.toArray(new String [l.size()]); 404 } 405 406 413 public static boolean isSuite(final File maybeSuiteDir) { 414 boolean isSuite = false; 415 try { 416 FileObject dirFO = FileUtil.toFileObject(maybeSuiteDir); 417 if (dirFO != null) { 418 Project maybeSuite = ProjectManager.getDefault().findProject(dirFO); 419 if (maybeSuite != null) { 420 isSuite = maybeSuiteDir.equals(getSuiteDirectory(maybeSuite)); 421 } 422 } 423 } catch (IOException e) { 424 } 426 return isSuite; 427 } 428 429 434 public static SuiteProject findSuite(final Project suiteComponent) throws IOException { 435 try { 436 return ProjectManager.mutex().readAccess(new Mutex.ExceptionAction<SuiteProject>(){ 437 public SuiteProject run() throws Exception { 438 Project suite = null; 439 File suiteDir = SuiteUtils.getSuiteDirectory(suiteComponent); 440 if (suiteDir != null) { 441 FileObject fo = FileUtil.toFileObject(suiteDir); 442 if (fo == null) { 443 Util.err.log(ErrorManager.WARNING, "Module in the \"" + FileUtil.toFile(suiteComponent.getProjectDirectory()).getAbsolutePath() + 445 "\" directory claims to be a subcomponent of a suite in the \"" + suiteDir.getAbsolutePath() + "\" which does not exist however."); } else { 448 suite = ProjectManager.getDefault().findProject(fo); 449 } 450 } 451 return suite instanceof SuiteProject ? (SuiteProject) suite : null; 452 } 453 }); 454 } catch (MutexException e) { 455 throw (IOException ) e.getException(); 456 } 457 } 458 459 463 public static boolean contains(final SuiteProject suite, final NbModuleProject project) { 464 Set <NbModuleProject> subModules = getSubProjects(suite); 465 if (subModules.contains(project)) { 466 return true; 467 } 468 for (Iterator it = subModules.iterator(); it.hasNext();) { 469 NbModuleProject p = (NbModuleProject) it.next(); 470 if (p.getCodeNameBase().equals(project.getCodeNameBase())) { 471 return true; 472 } 473 } 474 return false; 475 } 476 477 481 public static Set <NbModuleProject> getSubProjects(final Project suite) { 482 assert suite != null; 483 SubprojectProvider spp = suite.getLookup().lookup(SubprojectProvider.class); 484 return NbCollections.checkedSetByFilter(spp.getSubprojects(), NbModuleProject.class, true); 485 } 486 487 492 public static File getSuiteDirectory(final Project project) { 493 File suiteDir = null; 494 SuiteProvider sp = project.getLookup().lookup(SuiteProvider.class); 495 if (sp != null) { 496 suiteDir = sp.getSuiteDirectory(); 497 } 498 return suiteDir; 499 } 500 501 505 public static String getSuiteDirectoryPath(final Project project) { 506 File suiteDir = getSuiteDirectory(project); 507 return suiteDir != null ? suiteDir.getAbsolutePath() : null; 508 } 509 510 } 511 | Popular Tags |