1 19 20 package org.netbeans.modules.j2ee.earproject; 21 22 import java.beans.PropertyChangeListener ; 23 import java.beans.PropertyChangeSupport ; 24 import java.io.File ; 25 import java.io.IOException ; 26 import java.util.Iterator ; 27 import java.util.List ; 28 import javax.swing.Icon ; 29 import javax.swing.ImageIcon ; 30 import org.netbeans.api.java.classpath.ClassPath; 31 import org.netbeans.api.java.classpath.GlobalPathRegistry; 32 import org.netbeans.api.project.FileOwnerQuery; 33 import org.netbeans.api.project.Project; 34 import org.netbeans.api.project.ProjectInformation; 35 import org.netbeans.api.project.ProjectManager; 36 import org.netbeans.api.project.ant.AntArtifact; 37 import org.netbeans.modules.j2ee.api.ejbjar.Ear; 38 import org.netbeans.modules.j2ee.deployment.devmodules.spi.J2eeModuleProvider; 39 import org.netbeans.modules.j2ee.earproject.classpath.ClassPathProviderImpl; 40 import org.netbeans.modules.j2ee.earproject.ui.EarCustomizerProvider; 41 import org.netbeans.modules.j2ee.earproject.ui.IconBaseProvider; 42 import org.netbeans.modules.j2ee.earproject.ui.J2eeArchiveLogicalViewProvider; 43 import org.netbeans.modules.j2ee.earproject.ui.LogicalViewProvider; 44 import org.netbeans.modules.j2ee.earproject.ui.customizer.EarProjectProperties; 45 import org.netbeans.modules.j2ee.earproject.ui.customizer.VisualClassPathItem; 46 import org.netbeans.modules.j2ee.spi.ejbjar.EjbJarFactory; 47 import org.netbeans.spi.java.project.support.ui.BrokenReferencesSupport; 48 import org.netbeans.spi.project.AuxiliaryConfiguration; 49 import org.netbeans.spi.project.SubprojectProvider; 50 import org.netbeans.spi.project.ant.AntArtifactProvider; 51 import org.netbeans.spi.project.support.LookupProviderSupport; 52 import org.netbeans.spi.project.support.ant.AntBasedProjectType; 53 import org.netbeans.spi.project.support.ant.AntProjectEvent; 54 import org.netbeans.spi.project.support.ant.AntProjectHelper; 55 import org.netbeans.spi.project.support.ant.AntProjectListener; 56 import org.netbeans.spi.project.support.ant.EditableProperties; 57 import org.netbeans.spi.project.support.ant.GeneratedFilesHelper; 58 import org.netbeans.spi.project.support.ant.ProjectXmlSavedHook; 59 import org.netbeans.spi.project.support.ant.PropertyEvaluator; 60 import org.netbeans.spi.project.support.ant.PropertyUtils; 61 import org.netbeans.spi.project.support.ant.ReferenceHelper; 62 import org.netbeans.spi.project.support.ant.SourcesHelper; 63 import org.netbeans.spi.project.ui.PrivilegedTemplates; 64 import org.netbeans.spi.project.ui.ProjectOpenedHook; 65 import org.netbeans.spi.project.ui.RecommendedTemplates; 66 import org.netbeans.spi.project.ui.support.UILookupMergerSupport; 67 import org.openide.ErrorManager; 68 import org.openide.filesystems.FileAttributeEvent; 69 import org.openide.filesystems.FileChangeListener; 70 import org.openide.filesystems.FileEvent; 71 import org.openide.filesystems.FileObject; 72 import org.openide.filesystems.FileRenameEvent; 73 import org.openide.filesystems.FileUtil; 74 import org.openide.util.Lookup; 75 import org.openide.util.Mutex; 76 import org.openide.util.NbBundle; 77 import org.openide.util.Utilities; 78 import org.openide.util.lookup.Lookups; 79 import org.w3c.dom.Element ; 80 import org.w3c.dom.Node ; 81 import org.w3c.dom.NodeList ; 82 import org.w3c.dom.Text ; 83 84 91 public final class EarProject implements Project, AntProjectListener, FileChangeListener, ProjectPropertyProvider { 92 93 private static final Icon EAR_PROJECT_ICON = new ImageIcon (Utilities.loadImage("org/netbeans/modules/j2ee/earproject/ui/resources/projectIcon.gif")); public static final String ARTIFACT_TYPE_EAR = "ear"; 95 96 private final AntProjectHelper helper; 97 private final PropertyEvaluator eval; 98 private final ReferenceHelper refHelper; 99 private final GeneratedFilesHelper genFilesHelper; 100 private final Lookup lookup; 101 private final ProjectEar appModule; 102 private final Ear ear; 103 private final AntBasedProjectType abpt; 104 private final UpdateHelper updateHelper; 105 private final BrokenProjectSupport brokenProjectSupport; 106 107 EarProject(final AntProjectHelper helper, AntBasedProjectType abpt) throws IOException { 108 this.helper = helper; 109 this.abpt = abpt; 110 eval = createEvaluator(); 111 AuxiliaryConfiguration aux = helper.createAuxiliaryConfiguration(); 112 refHelper = new ReferenceHelper(helper, aux, helper.getStandardPropertyEvaluator()); 113 genFilesHelper = new GeneratedFilesHelper(helper); 114 appModule = new ProjectEar(this); 115 ear = EjbJarFactory.createEar(appModule); 116 updateHelper = new UpdateHelper(this, this.helper, aux, this.genFilesHelper, UpdateHelper.createDefaultNotifier()); 117 brokenProjectSupport = new BrokenProjectSupport(this); 118 lookup = createLookup(aux); 119 } 120 121 public UpdateHelper getUpdateHelper() { 122 return updateHelper; 123 } 124 125 public FileObject getProjectDirectory() { 126 return helper.getProjectDirectory(); 127 } 128 129 public String toString() { 130 return "EarProject[" + getProjectDirectory() + "]"; } 132 133 private PropertyEvaluator createEvaluator() { 134 return helper.getStandardPropertyEvaluator(); 136 } 137 138 PropertyEvaluator evaluator() { 139 return eval; 140 } 141 142 public Lookup getLookup() { 143 return lookup; 144 } 145 146 public AntProjectHelper getAntProjectHelper() { 147 return helper; 148 } 149 150 private Lookup createLookup(AuxiliaryConfiguration aux) { 151 SubprojectProvider spp = refHelper.createSubprojectProvider(); 152 153 final SourcesHelper sourcesHelper = new SourcesHelper(helper, evaluator()); 156 String configFilesLabel = NbBundle.getMessage(EarProject.class, "LBL_Node_ConfigBase"); 158 sourcesHelper.addPrincipalSourceRoot("${"+EarProjectProperties.META_INF+"}", configFilesLabel, null, null); ProjectManager.mutex().postWriteRequest(new Runnable () { 160 public void run() { 161 sourcesHelper.registerExternalRoots(FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT); 162 } 163 }); 164 Lookup base = Lookups.fixed(new Object [] { 165 new Info(), 166 aux, 167 spp, 168 new ProjectEarProvider(), 169 appModule, new EarActionProvider(this, updateHelper), 171 new LogicalViewProvider(this, updateHelper, evaluator(), refHelper, abpt), 172 new MyIconBaseProvider(), 173 new EarCustomizerProvider( this, helper, refHelper, abpt ), 174 new ClassPathProviderImpl(helper, evaluator()), 175 new ProjectXmlSavedHookImpl(), 176 new ProjectOpenedHookImpl(), 177 new EarSources(helper, evaluator()), 178 new RecommendedTemplatesImpl(), 179 helper.createSharabilityQuery(evaluator(), 180 new String [] {"${"+EarProjectProperties.SOURCE_ROOT+"}"}, new String [] { 182 "${"+EarProjectProperties.BUILD_DIR+"}", "${"+EarProjectProperties.DIST_DIR+"}"} ), 185 this, 186 new EarProjectOperations(this), 187 brokenProjectSupport, 188 new AntArtifactProviderImpl(), 189 UILookupMergerSupport.createPrivilegedTemplatesMerger(), 190 UILookupMergerSupport.createRecommendedTemplatesMerger(), 191 LookupProviderSupport.createSourcesMerger() 192 }); 193 return LookupProviderSupport.createCompositeLookup(base, "Projects/org-netbeans-modules-j2ee-earproject/Lookup"); } 195 196 public void configurationXmlChanged(AntProjectEvent ev) { 197 } 198 199 public void propertiesChanged(AntProjectEvent ev) { 200 } 203 204 public String getBuildXmlName() { 205 String storedName = helper.getStandardPropertyEvaluator().getProperty(EarProjectProperties.BUILD_FILE); 206 return storedName == null ? GeneratedFilesHelper.BUILD_XML_PATH : storedName; 207 } 208 209 211 public ProjectEar getAppModule() { 212 return appModule; 213 } 214 215 public Ear getEar() { 216 return ear; 217 } 218 219 public void fileAttributeChanged(FileAttributeEvent fe) { 220 } 221 222 public void fileChanged(FileEvent fe) { 223 } 224 225 public void fileDataCreated(FileEvent fe) { 226 } 227 228 public void fileDeleted(FileEvent fe) { 229 } 230 231 public void fileFolderCreated(FileEvent fe) { 232 } 233 234 public void fileRenamed(FileRenameEvent fe) { 235 } 236 237 238 public String getName() { 239 return (String ) ProjectManager.mutex().readAccess(new Mutex.Action() { 240 public Object run() { 241 Element data = updateHelper.getPrimaryConfigurationData(true); 242 NodeList nl = data.getElementsByTagNameNS(EarProjectType.PROJECT_CONFIGURATION_NAMESPACE, "name"); if (nl.getLength() == 1) { 245 nl = nl.item(0).getChildNodes(); 246 if (nl.getLength() == 1 && nl.item(0).getNodeType() == Node.TEXT_NODE) { 247 return ((Text ) nl.item(0)).getNodeValue(); 248 } 249 } 250 return "EAR????"; } 252 }); 253 } 254 255 256 public void setName(final String name) { 257 ProjectManager.mutex().writeAccess(new Mutex.Action() { 258 public Object run() { 259 Element data = helper.getPrimaryConfigurationData(true); 260 NodeList nl = data.getElementsByTagNameNS(EarProjectType.PROJECT_CONFIGURATION_NAMESPACE, "name"); Element nameEl; 263 if (nl.getLength() == 1) { 264 nameEl = (Element ) nl.item(0); 265 NodeList deadKids = nameEl.getChildNodes(); 266 while (deadKids.getLength() > 0) { 267 nameEl.removeChild(deadKids.item(0)); 268 } 269 } else { 270 nameEl = data.getOwnerDocument().createElementNS(EarProjectType.PROJECT_CONFIGURATION_NAMESPACE, "name"); data.insertBefore(nameEl, data.getChildNodes().item(0)); 272 } 273 nameEl.appendChild(data.getOwnerDocument().createTextNode(name)); 274 helper.putPrimaryConfigurationData(data, true); 275 return null; 276 } 277 }); 278 } 279 280 282 private final class Info implements ProjectInformation { 283 284 private final PropertyChangeSupport pcs = new PropertyChangeSupport (this); 285 286 Info() {} 287 288 void firePropertyChange(String prop) { 289 pcs.firePropertyChange(prop, null, null); 290 } 291 292 public String getName() { 293 return EarProject.this.getName(); 294 } 295 296 public String getDisplayName() { 297 return EarProject.this.getName(); 298 } 299 300 public Icon getIcon() { 301 return EAR_PROJECT_ICON; 302 } 303 304 public Project getProject() { 305 return EarProject.this; 306 } 307 308 public void addPropertyChangeListener(PropertyChangeListener listener) { 309 pcs.addPropertyChangeListener(listener); 310 } 311 312 public void removePropertyChangeListener(PropertyChangeListener listener) { 313 pcs.removePropertyChangeListener(listener); 314 } 315 316 } 317 318 private final class ProjectXmlSavedHookImpl extends ProjectXmlSavedHook { 319 320 ProjectXmlSavedHookImpl() {} 321 322 protected void projectXmlSaved() throws IOException { 323 genFilesHelper.refreshBuildScript( 324 GeneratedFilesHelper.BUILD_IMPL_XML_PATH, 325 EarProject.class.getResource("resources/build-impl.xsl"), 326 false); 327 genFilesHelper.refreshBuildScript( 328 getBuildXmlName(), 329 EarProject.class.getResource("resources/build.xsl"), 330 false); 331 } 332 333 } 334 335 private boolean addLibrary(List <VisualClassPathItem> cpItems, FileObject lib) { 336 boolean needsAdding = true; 337 for (Iterator vcpsIter = cpItems.iterator(); vcpsIter.hasNext();) { 338 VisualClassPathItem vcpi = (VisualClassPathItem) vcpsIter.next(); 339 340 if (vcpi.getType() != VisualClassPathItem.Type.JAR) { 341 continue; 342 } 343 FileObject fo = FileUtil.toFileObject(new File (helper.getStandardPropertyEvaluator().evaluate(vcpi.getEvaluated()))); 344 if (lib.equals(fo)) { 345 needsAdding = false; 346 break; 347 } 348 } 349 if (needsAdding) { 350 String file = "${"+EarProjectProperties.LIBRARIES_DIR+"}/"+lib.getNameExt(); VisualClassPathItem cpItem = VisualClassPathItem.createClassPath( 352 file, VisualClassPathItem.PATH_IN_WAR_LIB); 353 cpItems.add(cpItem); 354 } 355 return needsAdding; 356 } 357 358 359 final class ProjectOpenedHookImpl extends ProjectOpenedHook { 360 361 ProjectOpenedHookImpl() {} 362 363 protected void projectOpened() { 364 try { 365 String libFolderName = helper.getStandardPropertyEvaluator().getProperty(EarProjectProperties.LIBRARIES_DIR); 367 EarProjectProperties epp = new EarProjectProperties(EarProject.this, refHelper, abpt); 368 getAppModule().setModules(epp.getModuleMap()); 369 if (libFolderName != null && new File (libFolderName).isDirectory()) { 370 @SuppressWarnings ("unchecked") 371 List <VisualClassPathItem> cpItems = (List <VisualClassPathItem>) epp.get(EarProjectProperties.JAVAC_CLASSPATH); 372 FileObject libFolder = FileUtil.toFileObject(new File (libFolderName)); 373 FileObject libs [] = libFolder.getChildren(); 374 boolean anyChanged = false; 375 for (int i = 0; i < libs.length; i++) { 376 anyChanged = addLibrary(cpItems, libs [i]) || anyChanged; 377 } 378 if (anyChanged) { 379 epp.put(EarProjectProperties.JAVAC_CLASSPATH, cpItems); 380 epp.store(); 381 ProjectManager.getDefault().saveProject(EarProject.this); 382 } 383 libFolder.addFileChangeListener(EarProject.this); 384 } 385 genFilesHelper.refreshBuildScript( 387 GeneratedFilesHelper.BUILD_IMPL_XML_PATH, 388 EarProject.class.getResource("resources/build-impl.xsl"), 389 true); 390 genFilesHelper.refreshBuildScript( 391 getBuildXmlName(), 392 EarProject.class.getResource("resources/build.xsl"), 393 true); 394 395 epp.ensurePlatformIsSet(true); 396 } catch (IOException e) { 397 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 398 } 399 400 ClassPathProviderImpl cpProvider = (ClassPathProviderImpl)lookup.lookup(ClassPathProviderImpl.class); 402 GlobalPathRegistry.getDefault().register(ClassPath.BOOT, cpProvider.getProjectClassPaths(ClassPath.BOOT)); 403 GlobalPathRegistry.getDefault().register(ClassPath.COMPILE, cpProvider.getProjectClassPaths(ClassPath.COMPILE)); 404 405 J2eeModuleProvider pwm = (J2eeModuleProvider) EarProject.this.getLookup().lookup(J2eeModuleProvider.class); 406 pwm.getConfigSupport().ensureConfigurationReady(); 407 408 ProjectManager.mutex().writeAccess(new Mutex.Action() { 410 public Object run() { 411 EditableProperties ep = helper.getProperties(AntProjectHelper.PRIVATE_PROPERTIES_PATH); 412 ep.setProperty("netbeans.user", System.getProperty("netbeans.user")); 413 helper.putProperties(AntProjectHelper.PRIVATE_PROPERTIES_PATH, ep); 414 try { 415 ProjectManager.getDefault().saveProject(EarProject.this); 416 } catch (IOException e) { 417 ErrorManager.getDefault().notify(e); 418 } 419 return null; 420 } 421 }); 422 if (J2eeArchiveLogicalViewProvider.hasBrokenLinks(helper, refHelper)) { 423 BrokenReferencesSupport.showAlert(); 424 } 425 426 } 427 428 protected void projectClosed() { 429 try { 431 ProjectManager.getDefault().saveProject(EarProject.this); 432 } catch (IOException e) { 433 ErrorManager.getDefault().notify(e); 434 } 435 436 brokenProjectSupport.cleanUp(); 437 438 ClassPathProviderImpl cpProvider = (ClassPathProviderImpl)lookup.lookup(ClassPathProviderImpl.class); 440 GlobalPathRegistry.getDefault().unregister(ClassPath.BOOT, cpProvider.getProjectClassPaths(ClassPath.BOOT)); 441 GlobalPathRegistry.getDefault().unregister(ClassPath.COMPILE, cpProvider.getProjectClassPaths(ClassPath.COMPILE)); 442 } 443 444 } 445 446 private static final class RecommendedTemplatesImpl implements RecommendedTemplates, PrivilegedTemplates { 447 448 450 private static final String [] TYPES = new String [] { 451 "XML", "ear-types", "wsdl", "simple-files", "ant-script", "ant-task", }; 458 459 private static final String [] PRIVILEGED_NAMES = new String [] { 460 "Templates/XML/XMLWizard", "Templates/Other/Folder" }; 463 public String [] getRecommendedTypes() { 464 return TYPES; 465 } 466 public String [] getPrivilegedTemplates() { 467 return PRIVILEGED_NAMES; 468 } 469 } 470 471 class MyIconBaseProvider implements IconBaseProvider { 472 public String getIconBase() { 473 return "org/netbeans/modules/j2ee/earproject/ui/resources/"; } 475 } 476 477 478 FileObject getOrCreateMetaInfDir() { 479 String metaInfProp = helper.getStandardPropertyEvaluator(). 480 getProperty(EarProjectProperties.META_INF); 481 if (metaInfProp == null) { 482 File projectProperties = helper.resolveFile(AntProjectHelper.PROJECT_PROPERTIES_PATH); 485 if (projectProperties.exists()) { 486 ErrorManager.getDefault().log(ErrorManager.WARNING, 488 "Cannot resolve " + EarProjectProperties.META_INF + " property for " + this); } 491 return null; 492 } 493 FileObject metaInfFO = null; 494 try { 495 File prjDirF = FileUtil.toFile(getProjectDirectory()); 496 File rootF = prjDirF; 497 while (rootF.getParentFile() != null) { 498 rootF = rootF.getParentFile(); 499 } 500 File metaInfF = PropertyUtils.resolveFile(prjDirF, metaInfProp); 501 String metaInfPropRel = PropertyUtils.relativizeFile(rootF, metaInfF); 502 assert metaInfPropRel != null; 503 metaInfFO = FileUtil.createFolder(FileUtil.toFileObject(rootF), metaInfPropRel); 504 } catch (IOException ex) { 505 assert false : ex; 506 } 507 return metaInfFO; 508 } 509 510 FileObject getFileObject(String propname) { 511 String prop = helper.getStandardPropertyEvaluator().getProperty(propname); 512 if (prop != null) { 513 return helper.resolveFileObject(prop); 514 } else { 515 return null; 516 } 517 } 518 519 File getFile(String propname) { 520 String prop = helper.getStandardPropertyEvaluator().getProperty(propname); 521 if (prop != null) { 522 return helper.resolveFile(prop); 523 } else { 524 return null; 525 } 526 } 527 528 public String getServerID() { 529 return helper.getStandardPropertyEvaluator().getProperty(EarProjectProperties.J2EE_SERVER_TYPE); 530 } 531 532 public String getServerInstanceID() { 533 return helper.getStandardPropertyEvaluator().getProperty(EarProjectProperties.J2EE_SERVER_INSTANCE); 534 } 535 536 public String getJ2eePlatformVersion() { 537 return helper.getStandardPropertyEvaluator().getProperty(EarProjectProperties.J2EE_PLATFORM); 538 } 539 540 public EarProjectProperties getProjectProperties() { 541 return new EarProjectProperties(this, refHelper, abpt); 542 } 543 544 public GeneratedFilesHelper getGeneratedFilesHelper() { 545 return genFilesHelper; 546 } 547 548 private final class AntArtifactProviderImpl implements AntArtifactProvider{ 549 public AntArtifact[] getBuildArtifacts() { 550 return new AntArtifact[] { 551 helper.createSimpleAntArtifact(ARTIFACT_TYPE_EAR, "dist.jar", evaluator(), "dist", "clean"), }; 553 } 554 555 } 556 557 } 558 | Popular Tags |