1 19 20 package org.netbeans.modules.java.freeform.ui; 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.LinkedHashSet ; 30 import java.util.List ; 31 import java.util.Set ; 32 import javax.swing.event.ChangeEvent ; 33 import javax.swing.event.ChangeListener ; 34 import org.netbeans.api.java.platform.JavaPlatform; 35 import org.netbeans.api.project.ProjectManager; 36 import org.netbeans.modules.ant.freeform.spi.ProjectConstants; 37 import org.netbeans.modules.ant.freeform.spi.support.Util; 38 import org.netbeans.modules.java.freeform.JavaProjectGenerator; 39 import org.netbeans.modules.java.freeform.JavaProjectNature; 40 import org.netbeans.spi.project.AuxiliaryConfiguration; 41 import org.netbeans.spi.project.support.ant.AntProjectHelper; 42 import org.netbeans.spi.project.support.ant.PropertyEvaluator; 43 import org.netbeans.spi.project.support.ant.PropertyUtils; 44 import org.openide.modules.SpecificationVersion; 45 import org.openide.util.Mutex; 46 47 52 public class ProjectModel { 53 54 55 private File baseFolder; 56 57 58 private File nbProjectFolder; 59 60 private PropertyEvaluator evaluator; 61 62 private String sourceLevel; 63 64 65 private List <JavaProjectGenerator.SourceFolder> sourceFolders; 66 67 public List <JavaProjectGenerator.JavaCompilationUnit> javaCompilationUnitsList; 68 69 private Set <String > addedSourceFolders; 70 private Set <String > removedSourceFolders; 71 72 public static final String TYPE_JAVA = "java"; public static final String CLASSPATH_MODE_COMPILE = "compile"; private static final SpecificationVersion JDK_MAX_SUPPORTED_VERSION = new SpecificationVersion ("1.5"); 77 private ProjectModel(File baseFolder, File nbProjectFolder, PropertyEvaluator evaluator, 78 List <JavaProjectGenerator.SourceFolder> sourceFolders, List <JavaProjectGenerator.JavaCompilationUnit> compUnits) { 79 this.baseFolder = baseFolder; 80 this.nbProjectFolder = nbProjectFolder; 81 this.evaluator = evaluator; 82 this.sourceFolders = sourceFolders; 83 this.javaCompilationUnitsList = compUnits; 84 if (javaCompilationUnitsList.size() > 0) { 85 sourceLevel = javaCompilationUnitsList.get(0).sourceLevel; 86 } 87 if (sourceLevel == null) { 88 setSourceLevel(getDefaultSourceLevel()); 89 } 90 resetState(); 91 } 92 93 private final Set <ChangeListener > listeners = new HashSet <ChangeListener >(1); 94 public final void addChangeListener(ChangeListener l) { 95 synchronized (listeners) { 96 listeners.add(l); 97 } 98 } 99 100 public final void removeChangeListener(ChangeListener l) { 101 synchronized (listeners) { 102 listeners.remove(l); 103 } 104 } 105 106 109 protected final void fireChangeEvent() { 110 Collection <ChangeListener > ls; 111 synchronized (listeners) { 112 ls = new HashSet <ChangeListener >(listeners); 113 } 114 ChangeEvent ev = new ChangeEvent (this); 115 for (ChangeListener l : ls) { 116 l.stateChanged(ev); 117 } 118 } 119 120 private void resetState() { 121 addedSourceFolders = new HashSet <String >(); 122 removedSourceFolders = new HashSet <String >(); 123 } 124 125 126 public static ProjectModel createEmptyModel(File baseFolder, File nbProjectFolder, PropertyEvaluator evaluator) { 127 return new ProjectModel(baseFolder, nbProjectFolder, evaluator, 128 new ArrayList <JavaProjectGenerator.SourceFolder>(), 129 new ArrayList <JavaProjectGenerator.JavaCompilationUnit>()); 130 } 131 132 133 public static ProjectModel createModel(final File baseFolder, final File nbProjectFolder, final PropertyEvaluator evaluator, final AntProjectHelper helper) { 134 return ProjectManager.mutex().readAccess(new Mutex.Action<ProjectModel>() { 135 public ProjectModel run() { 136 ProjectModel pm = new ProjectModel( 137 baseFolder, 138 nbProjectFolder, 139 evaluator, 140 JavaProjectGenerator.getSourceFolders(helper, TYPE_JAVA), 142 JavaProjectGenerator.getJavaCompilationUnits(helper, 143 Util.getAuxiliaryConfiguration(helper)) 144 ); 145 updateStyle(pm.sourceFolders); 147 return pm; 148 } 149 }); 150 } 151 152 153 public static void instantiateJavaProject(AntProjectHelper helper, ProjectModel model) throws IOException { 154 List <JavaProjectGenerator.SourceFolder> sourceFolders = model.updatePrincipalSourceFolders(model.sourceFolders, true); 155 156 if (sourceFolders.size() > 0) { 157 JavaProjectGenerator.putSourceFolders(helper, sourceFolders, null); 158 } 159 if (sourceFolders.size() > 0) { 160 JavaProjectGenerator.putSourceViews(helper, sourceFolders, null); 161 } 162 JavaProjectGenerator.putJavaCompilationUnits(helper, Util.getAuxiliaryConfiguration(helper), model.javaCompilationUnitsList); 163 List <JavaProjectGenerator.Export> exports = JavaProjectGenerator.guessExports( 164 model.evaluator, model.baseFolder, JavaProjectGenerator.getTargetMappings(helper), model.javaCompilationUnitsList); 165 if (exports.size() > 0) { 166 JavaProjectGenerator.putExports(helper, exports); 167 } 168 List <String > subprojects = JavaProjectGenerator.guessSubprojects(model.evaluator, model.javaCompilationUnitsList, model.baseFolder, model.nbProjectFolder); 169 if (subprojects.size() > 0) { 170 JavaProjectGenerator.putSubprojects(helper, subprojects); 171 } 172 173 model.resetState(); 174 } 175 176 177 public static void saveProject(final AntProjectHelper helper, final ProjectModel model) { 178 ProjectManager.mutex().writeAccess(new Mutex.Action<Void >() { 179 public Void run() { 180 JavaProjectGenerator.putSourceFolders(helper, model.sourceFolders, TYPE_JAVA); 182 JavaProjectGenerator.putSourceViews(helper, model.sourceFolders, JavaProjectNature.STYLE_PACKAGES); 183 184 List <JavaProjectGenerator.SourceFolder> sourceFolders = JavaProjectGenerator.getSourceFolders(helper, null); 185 sourceFolders = model.updatePrincipalSourceFolders(sourceFolders, false); 186 JavaProjectGenerator.putSourceFolders(helper, sourceFolders, null); 187 188 AuxiliaryConfiguration aux = Util.getAuxiliaryConfiguration(helper); 189 JavaProjectGenerator.putJavaCompilationUnits(helper, aux, model.javaCompilationUnitsList); 190 model.resetState(); 191 192 List <JavaProjectGenerator.Export> exports = JavaProjectGenerator.guessExports(model.getEvaluator(), model.baseFolder, 193 JavaProjectGenerator.getTargetMappings(helper), model.javaCompilationUnitsList); 194 JavaProjectGenerator.putExports(helper, exports); 195 196 List <String > subprojects = JavaProjectGenerator.guessSubprojects(model.getEvaluator(), 197 model.javaCompilationUnitsList, model.baseFolder, model.nbProjectFolder); 198 JavaProjectGenerator.putSubprojects(helper, subprojects); 199 200 List <String > buildFolders = JavaProjectGenerator.guessBuildFolders(model.getEvaluator(), 201 model.javaCompilationUnitsList, model.baseFolder, model.nbProjectFolder); 202 JavaProjectGenerator.putBuildFolders(helper, buildFolders); 203 204 return null; 205 } 206 }); 207 } 208 209 225 List <JavaProjectGenerator.SourceFolder> updatePrincipalSourceFolders( 226 List <JavaProjectGenerator.SourceFolder> allSourceFolders, boolean checkProjectDir) { 227 List <JavaProjectGenerator.SourceFolder> allSF = new ArrayList <JavaProjectGenerator.SourceFolder>(allSourceFolders); 228 for (String location : addedSourceFolders) { 229 230 if (!isExternalSourceRoot(location)) { 231 continue; 232 } 233 234 boolean exist = false; 235 String label = ""; String includes = null, excludes = null; 237 for (JavaProjectGenerator.SourceFolder _sf : allSF) { 238 if (_sf.location.equals(location) && _sf.type == null) { 239 exist = true; 240 break; 241 } 242 if (_sf.location.equals(location) && _sf.type != null) { 243 label = _sf.label; 245 includes = _sf.includes; 246 excludes = _sf.excludes; 247 } 248 } 249 250 if (!exist) { 251 JavaProjectGenerator.SourceFolder _sf = new JavaProjectGenerator.SourceFolder(); 252 _sf.location = location; 253 _sf.label = label; 254 _sf.includes = includes; 255 _sf.excludes = excludes; 256 allSF.add(_sf); 257 } 258 } 259 260 for (String location : removedSourceFolders) { 261 262 if (!isExternalSourceRoot(location)) { 263 continue; 264 } 265 266 Iterator <JavaProjectGenerator.SourceFolder> it = allSF.iterator(); 267 while (it.hasNext()) { 268 JavaProjectGenerator.SourceFolder _sf = it.next(); 269 if (_sf.location.equals(location) && _sf.type == null) { 270 it.remove(); 271 } 272 } 273 } 274 275 if (checkProjectDir && !baseFolder.equals(nbProjectFolder)) { 276 JavaProjectGenerator.SourceFolder gen = new JavaProjectGenerator.SourceFolder(); 277 gen.location = "${"+ProjectConstants.PROP_PROJECT_LOCATION+"}"; gen.label = baseFolder.getName(); 280 allSF.add(gen); 281 } 282 283 return allSF; 284 } 285 286 private boolean isExternalSourceRoot(String location) { 287 String baseFolder_ = baseFolder.getAbsolutePath(); 288 if (!baseFolder_.endsWith(File.separator)) { 289 baseFolder_ += File.separatorChar; 290 } 291 String nbProjectFolder_ = nbProjectFolder.getAbsolutePath(); 292 if (!nbProjectFolder_.endsWith(File.separator)) { 293 nbProjectFolder_ += File.separatorChar; 294 } 295 File f = Util.resolveFile(evaluator, baseFolder, location); 296 if (f == null) { 297 return false; 298 } 299 location = f.getAbsolutePath(); 300 return (!location.startsWith(baseFolder_) && 301 !location.startsWith(nbProjectFolder_)); 302 } 303 304 305 public File getBaseFolder() { 306 return baseFolder; 307 } 308 309 310 public File getNBProjectFolder() { 311 return nbProjectFolder; 312 } 313 314 public PropertyEvaluator getEvaluator() { 315 return evaluator; 316 } 317 318 public int getSourceFoldersCount() { 319 return sourceFolders.size(); 320 } 321 322 public JavaProjectGenerator.SourceFolder getSourceFolder(int index) { 323 return sourceFolders.get(index); 324 } 325 326 public void moveSourceFolder(int fromIndex, int toIndex) { 327 JavaProjectGenerator.SourceFolder sf = sourceFolders.remove(fromIndex); 328 sourceFolders.add(toIndex, sf); 329 } 330 331 public void addSourceFolder(JavaProjectGenerator.SourceFolder sf, boolean isTests) { 332 List <CompilationUnitKey> keys = createCompilationUnitKeys(); 333 boolean singleCU = isSingleCompilationUnit(keys); 334 if (singleCU) { 335 JavaProjectGenerator.JavaCompilationUnit cu = javaCompilationUnitsList.get(0); 338 if (cu.isTests != isTests) { 339 updateCompilationUnits(true); 340 singleCU = false; 341 } 342 } 343 sourceFolders.add(sf); 344 if (singleCU) { 345 if (TYPE_JAVA.equals(sf.type)) { 346 JavaProjectGenerator.JavaCompilationUnit cu = javaCompilationUnitsList.get(0); 348 cu.packageRoots.add(sf.location); 349 } 350 } else { 351 for (CompilationUnitKey key : createCompilationUnitKeys()) { 353 getCompilationUnit(key, isTests); 354 } 355 } 356 if (removedSourceFolders.contains(sf.location)) { 358 removedSourceFolders.remove(sf.location); 359 } else { 360 addedSourceFolders.add(sf.location); 361 } 362 fireChangeEvent(); 363 } 364 365 public void removeSourceFolder(int index) { 366 JavaProjectGenerator.SourceFolder sf = sourceFolders.get(index); 367 if (TYPE_JAVA.equals(sf.type)) { 368 removeSourceLocation(sf.location); 369 } 370 sourceFolders.remove(index); 371 if (addedSourceFolders.contains(sf.location)) { 373 addedSourceFolders.remove(sf.location); 374 } else { 375 removedSourceFolders.add(sf.location); 376 } 377 fireChangeEvent(); 378 } 379 380 public void clearSourceFolders() { 381 sourceFolders.clear(); 382 javaCompilationUnitsList.clear(); 383 fireChangeEvent(); 384 } 385 386 public String getSourceLevel() { 387 return sourceLevel; 388 } 389 390 public void setSourceLevel(String sourceLevel) { 391 if ((this.sourceLevel == null && sourceLevel == null) || 392 (this.sourceLevel != null && this.sourceLevel.equals(sourceLevel))) { 393 return; 394 } 395 this.sourceLevel = sourceLevel; 396 for (JavaProjectGenerator.JavaCompilationUnit cu : javaCompilationUnitsList) { 397 cu.sourceLevel = sourceLevel; 398 } 399 } 400 401 public boolean canHaveSeparateClasspath() { 402 return (sourceFolders.size() > 1 || javaCompilationUnitsList.size() > 1); 405 } 406 407 public boolean canCreateSingleCompilationUnit() { 408 boolean testCU = false; 411 boolean sourceCU = false; 412 for (JavaProjectGenerator.JavaCompilationUnit cu : javaCompilationUnitsList) { 413 if (cu.isTests) { 414 testCU = true; 415 } else { 416 sourceCU = true; 417 } 418 } 419 return !(testCU && sourceCU); 420 } 421 422 public static boolean isSingleCompilationUnit(List <ProjectModel.CompilationUnitKey> compilationUnitKeys) { 423 return compilationUnitKeys.size() == 1 && compilationUnitKeys.get(0).label == null; 424 } 425 426 435 public List <CompilationUnitKey> createCompilationUnitKeys() { 436 List <CompilationUnitKey> l = new ArrayList <CompilationUnitKey>(); 438 for (JavaProjectGenerator.JavaCompilationUnit cu : javaCompilationUnitsList) { 439 CompilationUnitKey cul = new CompilationUnitKey(); 440 cul.locations = cu.packageRoots; 441 cul.label = null; 442 l.add(cul); 443 } 444 for (JavaProjectGenerator.SourceFolder sf : sourceFolders) { 445 if (!TYPE_JAVA.equals(sf.type)) { 446 continue; 447 } 448 CompilationUnitKey cul = new CompilationUnitKey(); 449 cul.locations = new ArrayList <String >(); 450 cul.locations.add(sf.location); 451 cul.label = sf.label; 452 int index = l.indexOf(cul); 454 if (index != -1) { 455 CompilationUnitKey cul_ = l.get(index); 457 cul_.label = sf.label; 458 continue; 459 } 460 boolean found = false; 462 for (JavaProjectGenerator.JavaCompilationUnit cu_ : javaCompilationUnitsList) { 463 if (cu_.packageRoots.contains(sf.location)) { 464 found = true; 466 break; 467 } 468 } 469 if (found) { 470 continue; 471 } 472 l.add(cul); 474 } 475 return l; 476 } 477 478 484 public void updateCompilationUnits(boolean separateClasspath) { 485 if (separateClasspath) { 486 String classpath = null; 489 List <String > output = null; 490 if (javaCompilationUnitsList.size() > 0) { 493 List <JavaProjectGenerator.JavaCompilationUnit.CP> classpaths = javaCompilationUnitsList.get(0).classpath; 494 if (classpaths != null) { 495 for (JavaProjectGenerator.JavaCompilationUnit.CP cp : classpaths) { 497 if (cp.mode.equals(CLASSPATH_MODE_COMPILE)) { 498 classpath = cp.classpath; 499 break; 500 } 501 } 502 } 503 output = javaCompilationUnitsList.get(0).output; 504 } 505 javaCompilationUnitsList.clear(); 506 for (JavaProjectGenerator.SourceFolder sf : sourceFolders) { 507 JavaProjectGenerator.JavaCompilationUnit cu = new JavaProjectGenerator.JavaCompilationUnit(); 508 cu.packageRoots = new ArrayList <String >(); 509 cu.packageRoots.add(sf.location); 510 if (classpath != null) { 511 JavaProjectGenerator.JavaCompilationUnit.CP cp = new JavaProjectGenerator.JavaCompilationUnit.CP(); 512 cp.mode = CLASSPATH_MODE_COMPILE; 513 cp.classpath = classpath; 514 cu.classpath = new ArrayList <JavaProjectGenerator.JavaCompilationUnit.CP>(); 515 cu.classpath.add(cp); 516 } 517 if (output != null) { 518 cu.output = new ArrayList <String >(); 519 cu.output.addAll(output); 520 } 521 cu.sourceLevel = sourceLevel; 522 javaCompilationUnitsList.add(cu); 523 } 524 } else { 525 List <String > packageRoots = new ArrayList <String >(); 528 for (JavaProjectGenerator.SourceFolder sf : sourceFolders) { 530 packageRoots.add(sf.location); 531 } 532 Set <String > classpath = new LinkedHashSet <String >(); 534 Set <String > output = new LinkedHashSet <String >(); 535 for (JavaProjectGenerator.JavaCompilationUnit cu : javaCompilationUnitsList) { 536 if (cu.output != null) { 537 output.addAll(cu.output); 538 } 539 if (cu.classpath != null) { 540 for (JavaProjectGenerator.JavaCompilationUnit.CP cp : cu.classpath) { 541 if (cp.mode.equals(CLASSPATH_MODE_COMPILE)) { 542 classpath.addAll(Arrays.asList(PropertyUtils.tokenizePath(cp.classpath))); 543 } 544 } 545 } 546 } 547 javaCompilationUnitsList.clear(); 548 JavaProjectGenerator.JavaCompilationUnit cu = new JavaProjectGenerator.JavaCompilationUnit(); 549 cu.packageRoots = packageRoots; 550 JavaProjectGenerator.JavaCompilationUnit.CP cp = new JavaProjectGenerator.JavaCompilationUnit.CP(); 551 if (classpath.size() > 0) { 552 StringBuffer cp_ = new StringBuffer (); 553 Iterator <String > it = classpath.iterator(); 554 while (it.hasNext()) { 555 cp_.append(it.next()); 556 if (it.hasNext()) { 557 cp_.append(File.pathSeparatorChar); 558 } 559 } 560 cp.classpath = cp_.toString(); 561 cp.mode = CLASSPATH_MODE_COMPILE; 562 cu.classpath = new ArrayList <JavaProjectGenerator.JavaCompilationUnit.CP>(); 563 cu.classpath.add(cp); 564 } 565 cu.output = new ArrayList <String >(output); 566 cu.sourceLevel = sourceLevel; 567 javaCompilationUnitsList.add(cu); 568 } 569 fireChangeEvent(); 570 } 571 572 576 public JavaProjectGenerator.JavaCompilationUnit getCompilationUnit(CompilationUnitKey key, boolean isTests) { 577 for (JavaProjectGenerator.JavaCompilationUnit cu : javaCompilationUnitsList) { 578 if (cu.packageRoots.equals(key.locations)) { 579 return cu; 580 } 581 } 582 JavaProjectGenerator.JavaCompilationUnit cu = new JavaProjectGenerator.JavaCompilationUnit(); 583 cu.packageRoots = key.locations; 584 cu.sourceLevel = sourceLevel; 585 cu.isTests = isTests; 586 javaCompilationUnitsList.add(cu); 587 return cu; 588 } 589 590 private void removeSourceLocation(String location) { 591 Iterator <JavaProjectGenerator.JavaCompilationUnit> it = javaCompilationUnitsList.iterator(); 592 while (it.hasNext()) { 593 JavaProjectGenerator.JavaCompilationUnit cu = it.next(); 594 if (cu.packageRoots.contains(location)) { 595 cu.packageRoots.remove(location); 596 } 597 if (cu.packageRoots.size() == 0) { 598 it.remove(); 599 } 600 } 601 } 602 603 604 private static void updateStyle(List <JavaProjectGenerator.SourceFolder> sources) { 605 for (JavaProjectGenerator.SourceFolder sf : sources) { 606 assert sf.type.equals(TYPE_JAVA); 607 sf.style = JavaProjectNature.STYLE_PACKAGES; 608 } 609 } 610 611 void setSourceFolders(List <JavaProjectGenerator.SourceFolder> list) { 613 sourceFolders = list; 614 } 615 616 List <JavaProjectGenerator.SourceFolder> getSourceFolders() { 618 return sourceFolders; 619 } 620 621 void setJavaCompilationUnits(List <JavaProjectGenerator.JavaCompilationUnit> list) { 623 javaCompilationUnitsList = list; 624 } 625 626 List <JavaProjectGenerator.JavaCompilationUnit> getJavaCompilationUnits() { 628 return javaCompilationUnitsList; 629 } 630 631 632 635 public static String getDefaultSourceLevel() { 636 JavaPlatform platform = JavaPlatform.getDefault(); 637 SpecificationVersion sv = platform.getSpecification().getVersion(); 638 if (sv.compareTo(JDK_MAX_SUPPORTED_VERSION)>0) { 639 sv = JDK_MAX_SUPPORTED_VERSION; 640 } 641 return sv.toString(); 642 } 643 644 public boolean isTestSourceFolder(int index) { 645 return isTestSourceFolder(getSourceFolder(index)); 646 } 647 648 public boolean isTestSourceFolder(JavaProjectGenerator.SourceFolder sf) { 649 for (JavaProjectGenerator.JavaCompilationUnit cu : javaCompilationUnitsList) { 650 if (cu.packageRoots.contains(sf.location)) { 651 return cu.isTests; 652 } 653 } 654 return false; 655 } 656 657 public static class CompilationUnitKey { 658 public List <String > locations; 659 public String label; 660 661 public boolean equals(Object o) { 662 if (o == this) { 663 return true; 664 } 665 if (!(o instanceof CompilationUnitKey)) { 666 return false; 667 } 668 CompilationUnitKey cul = (CompilationUnitKey)o; 669 return this.locations.equals(cul.locations); 670 } 671 672 public int hashCode() { 673 return locations.hashCode()*7; 674 } 675 676 public String toString() { 677 return "PM.CUK:[label="+label+", locations="+locations+", this="+super.toString()+"]"; } 679 } 680 681 } 682 | Popular Tags |