1 19 20 package org.netbeans.modules.apisupport.project.ui; 21 22 import java.awt.Image ; 23 import java.util.ArrayList ; 24 import java.util.Collections ; 25 import java.util.HashSet ; 26 import java.util.Iterator ; 27 import java.util.LinkedHashMap ; 28 import java.util.List ; 29 import java.util.Set ; 30 import javax.swing.event.ChangeListener ; 31 import org.netbeans.api.project.Project; 32 import org.netbeans.modules.apisupport.project.NbModuleProject; 33 import org.netbeans.modules.apisupport.project.layers.LayerNode; 34 import org.netbeans.modules.apisupport.project.layers.LayerUtils; 35 import org.netbeans.modules.apisupport.project.metainf.ServiceNodeHandler; 36 import org.netbeans.modules.apisupport.project.suite.SuiteProject; 37 import org.netbeans.spi.project.ui.support.NodeFactory; 38 import org.netbeans.spi.project.ui.support.NodeList; 39 import org.openide.ErrorManager; 40 import org.openide.filesystems.FileChangeAdapter; 41 import org.openide.filesystems.FileChangeListener; 42 import org.openide.filesystems.FileEvent; 43 import org.openide.filesystems.FileObject; 44 import org.openide.filesystems.FileStateInvalidException; 45 import org.openide.filesystems.FileSystem; 46 import org.openide.loaders.DataObject; 47 import org.openide.loaders.DataObjectNotFoundException; 48 import org.openide.nodes.Children; 49 import org.openide.nodes.FilterNode; 50 import org.openide.nodes.Node; 51 import org.openide.util.NbBundle; 52 import org.openide.util.RequestProcessor; 53 import org.openide.util.Utilities; 54 55 59 public class ImportantFilesNodeFactory implements NodeFactory { 60 61 static final String IMPORTANT_FILES_NAME = "important.files"; 63 static final RequestProcessor RP = new RequestProcessor(); 64 65 66 public ImportantFilesNodeFactory() { 67 } 68 69 public NodeList createNodes(Project p) { 70 return new ImpFilesNL(p); 71 } 72 73 private static class ImpFilesNL implements NodeList<String > { 74 private Project project; 75 76 public ImpFilesNL(Project p) { 77 project = p; 78 } 79 80 public List <String > keys() { 81 return Collections.singletonList(IMPORTANT_FILES_NAME); 82 } 83 84 public void addChangeListener(ChangeListener l) { 85 } 87 88 public void removeChangeListener(ChangeListener l) { 89 } 91 92 public Node node(String key) { 93 assert key == IMPORTANT_FILES_NAME; 94 if (project instanceof NbModuleProject) { 95 return new ImportantFilesNode((NbModuleProject)project); 96 } 97 if (project instanceof SuiteProject) { 98 return new ImportantFilesNode(new SuiteImportantFilesChildren((SuiteProject)project)); 99 } 100 return null; 101 } 102 103 public void addNotify() { 104 } 105 106 public void removeNotify() { 107 } 108 } 109 112 static final class ImportantFilesNode extends AnnotatedNode { 113 114 public ImportantFilesNode(NbModuleProject project) { 115 super(new ImportantFilesChildren(project)); 116 } 117 118 ImportantFilesNode(Children ch) { 119 super(ch); 120 } 121 122 public String getName() { 123 return IMPORTANT_FILES_NAME; 124 } 125 126 private Image getIcon(boolean opened) { 127 Image badge = Utilities.loadImage("org/netbeans/modules/apisupport/project/resources/config-badge.gif", true); 128 return Utilities.mergeImages(UIUtil.getTreeFolderIcon(opened), badge, 8, 8); 129 } 130 131 private static final String DISPLAY_NAME = NbBundle.getMessage(ModuleLogicalView.class, "LBL_important_files"); 132 133 public String getDisplayName() { 134 return annotateName(DISPLAY_NAME); 135 } 136 137 public String getHtmlDisplayName() { 138 return computeAnnotatedHtmlDisplayName(DISPLAY_NAME, getFiles()); 139 } 140 141 public Image getIcon(int type) { 142 return annotateIcon(getIcon(false), type); 143 } 144 145 public Image getOpenedIcon(int type) { 146 return annotateIcon(getIcon(true), type); 147 } 148 149 } 150 151 154 private static final class ImportantFilesChildren extends Children.Keys { 155 156 private List visibleFiles = new ArrayList (); 157 private FileChangeListener fcl; 158 159 160 private static final java.util.Map <String ,String > FILES = new LinkedHashMap (); 161 static { 162 FILES.put("${manifest.mf}", NbBundle.getMessage(ModuleLogicalView.class, "LBL_module_manifest")); 163 FILES.put("${javadoc.arch}", NbBundle.getMessage(ModuleLogicalView.class, "LBL_arch_desc")); 164 FILES.put("${javadoc.apichanges}", NbBundle.getMessage(ModuleLogicalView.class, "LBL_api_changes")); 165 FILES.put("${javadoc.overview}", NbBundle.getMessage(ModuleLogicalView.class, "LBL_javadoc_overview")); 166 FILES.put("build.xml", NbBundle.getMessage(ModuleLogicalView.class, "LBL_build.xml")); 167 FILES.put("nbproject/project.xml", NbBundle.getMessage(ModuleLogicalView.class, "LBL_project.xml")); 168 FILES.put("nbproject/project.properties", NbBundle.getMessage(ModuleLogicalView.class, "LBL_project.properties")); 169 FILES.put("nbproject/private/private.properties", NbBundle.getMessage(ModuleLogicalView.class, "LBL_private.properties")); 170 FILES.put("nbproject/suite.properties", NbBundle.getMessage(ModuleLogicalView.class, "LBL_suite.properties")); 171 FILES.put("nbproject/private/suite-private.properties", NbBundle.getMessage(ModuleLogicalView.class, "LBL_suite-private.properties")); 172 FILES.put("nbproject/platform.properties", NbBundle.getMessage(ModuleLogicalView.class, "LBL_platform.properties")); 173 FILES.put("nbproject/private/platform-private.properties", NbBundle.getMessage(ModuleLogicalView.class, "LBL_platform-private.properties")); 174 } 175 176 private final NbModuleProject project; 177 178 public ImportantFilesChildren(NbModuleProject project) { 179 this.project = project; 180 } 181 182 protected void addNotify() { 183 super.addNotify(); 184 attachListeners(); 185 refreshKeys(); 186 } 187 188 protected void removeNotify() { 189 setKeys(Collections.EMPTY_SET); 190 removeListeners(); 191 super.removeNotify(); 192 } 193 194 protected Node[] createNodes(Object key) { 195 if (key instanceof String ) { 196 String loc = (String ) key; 197 String locEval = project.evaluator().evaluate(loc); 198 FileObject file = project.getHelper().resolveFileObject(locEval); 199 try { 200 Node orig = DataObject.find(file).getNodeDelegate(); 201 return new Node[] {new SpecialFileNode(orig, (String ) FILES.get(loc))}; 202 } catch (DataObjectNotFoundException e) { 203 throw new AssertionError (e); 204 } 205 } else if (key instanceof LayerUtils.LayerHandle) { 206 return new Node[] { new SpecialFileNode(new LayerNode((LayerUtils.LayerHandle) key), null)}; 207 } else if (key instanceof ServiceNodeHandler) { 208 return new Node[]{((ServiceNodeHandler)key).createServiceRootNode()}; 209 } else { 210 throw new AssertionError (key); 211 } 212 } 213 214 private void refreshKeys() { 215 Set <FileObject> files = new HashSet (); 216 List newVisibleFiles = new ArrayList (); 217 LayerUtils.LayerHandle handle = LayerUtils.layerForProject(project); 218 FileObject layerFile = handle.getLayerFile(); 219 if (layerFile != null) { 220 newVisibleFiles.add(handle); 221 files.add(layerFile); 222 } 223 Iterator it = FILES.keySet().iterator(); 224 while (it.hasNext()) { 225 String loc = (String ) it.next(); 226 String locEval = project.evaluator().evaluate(loc); 227 if (locEval == null) { 228 newVisibleFiles.remove(loc); continue; 230 } 231 FileObject file = project.getHelper().resolveFileObject(locEval); 232 if (file != null) { 233 newVisibleFiles.add(loc); 234 files.add(file); 235 } 236 } 237 if (!isInitialized() || !newVisibleFiles.equals(visibleFiles)) { 238 visibleFiles = newVisibleFiles; 239 visibleFiles.add(project.getLookup().lookup(ServiceNodeHandler.class)); 240 RP.post(new Runnable () { public void run() { 242 setKeys(visibleFiles); 243 } 244 }); 245 ((ImportantFilesNode) getNode()).setFiles(files); 246 } 247 } 248 249 private void attachListeners() { 250 try { 251 if (fcl == null) { 252 fcl = new FileChangeAdapter() { 253 public void fileDataCreated(FileEvent fe) { 254 refreshKeys(); 255 } 256 public void fileDeleted(FileEvent fe) { 257 refreshKeys(); 258 } 259 }; 260 project.getProjectDirectory().getFileSystem().addFileChangeListener(fcl); 261 } 262 } catch (FileStateInvalidException e) { 263 assert false : e; 264 } 265 } 266 267 private void removeListeners() { 268 if (fcl != null) { 269 try { 270 project.getProjectDirectory().getFileSystem().removeFileChangeListener(fcl); 271 } catch (FileStateInvalidException e) { 272 assert false : e; 273 } 274 fcl = null; 275 } 276 } 277 278 } 279 283 static final class SpecialFileNode extends FilterNode { 284 285 private final String displayName; 286 287 public SpecialFileNode(Node orig, String displayName) { 288 super(orig); 289 this.displayName = displayName; 290 } 291 292 public String getDisplayName() { 293 if (displayName != null) { 294 return displayName; 295 } else { 296 return super.getDisplayName(); 297 } 298 } 299 300 public boolean canRename() { 301 return false; 302 } 303 304 public boolean canDestroy() { 305 return false; 306 } 307 308 public boolean canCut() { 309 return false; 310 } 311 312 public String getHtmlDisplayName() { 313 String result = null; 314 DataObject dob = (DataObject) getLookup().lookup(DataObject.class); 315 if (dob != null) { 316 Set files = dob.files(); 317 result = computeAnnotatedHtmlDisplayName(getDisplayName(), files); 318 } 319 return result; 320 } 321 322 } 323 324 328 private static String computeAnnotatedHtmlDisplayName( 329 final String htmlDisplayName, final Set files) { 330 331 String result = null; 332 if (files != null && files.iterator().hasNext()) { 333 try { 334 FileObject fo = (FileObject) files.iterator().next(); 335 FileSystem.Status stat = fo.getFileSystem().getStatus(); 336 if (stat instanceof FileSystem.HtmlStatus) { 337 FileSystem.HtmlStatus hstat = (FileSystem.HtmlStatus) stat; 338 339 String annotated = hstat.annotateNameHtml(htmlDisplayName, files); 340 341 if (!htmlDisplayName.equals(annotated)) { 343 result = annotated; 344 } 345 } 346 } catch (FileStateInvalidException e) { 347 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 348 } 349 } 350 return result; 351 } 352 353 356 private static final class SuiteImportantFilesChildren extends Children.Keys<String > { 357 358 private List <String > visibleFiles = new ArrayList (); 359 private FileChangeListener fcl; 360 361 362 private static final java.util.Map <String ,String > FILES = new LinkedHashMap (); 363 static { 364 FILES.put("master.jnlp", NbBundle.getMessage(SuiteLogicalView.class,"LBL_jnlp_master")); 365 FILES.put("build.xml", NbBundle.getMessage(SuiteLogicalView.class,"LBL_build.xml")); 366 FILES.put("nbproject/project.properties", NbBundle.getMessage(SuiteLogicalView.class,"LBL_project.properties")); 367 FILES.put("nbproject/private/private.properties", NbBundle.getMessage(SuiteLogicalView.class,"LBL_private.properties")); 368 FILES.put("nbproject/platform.properties", NbBundle.getMessage(SuiteLogicalView.class,"LBL_platform.properties")); 369 FILES.put("nbproject/private/platform-private.properties", NbBundle.getMessage(SuiteLogicalView.class,"LBL_platform-private.properties")); 370 } 371 372 private final SuiteProject project; 373 374 public SuiteImportantFilesChildren(SuiteProject project) { 375 this.project = project; 376 } 377 378 protected void addNotify() { 379 super.addNotify(); 380 attachListeners(); 381 refreshKeys(); 382 } 383 384 protected void removeNotify() { 385 setKeys(Collections.EMPTY_SET); 386 removeListeners(); 387 super.removeNotify(); 388 } 389 390 protected Node[] createNodes(String loc) { 391 String locEval = project.getEvaluator().evaluate(loc); 392 FileObject file = project.getHelper().resolveFileObject(locEval); 393 394 try { 395 Node orig = DataObject.find(file).getNodeDelegate(); 396 return new Node[] {new SpecialFileNode(orig, (String ) FILES.get(loc))}; 397 } catch (DataObjectNotFoundException e) { 398 throw new AssertionError (e); 399 } 400 } 401 402 private void refreshKeys() { 403 List <String > newVisibleFiles = new ArrayList (); 404 Iterator it = FILES.keySet().iterator(); 405 Set files = new HashSet (); 406 while (it.hasNext()) { 407 String loc = (String ) it.next(); 408 String locEval = project.getEvaluator().evaluate(loc); 409 if (locEval == null) { 410 continue; 411 } 412 FileObject file = project.getHelper().resolveFileObject(locEval); 413 if (file != null) { 414 newVisibleFiles.add(loc); 415 files.add(file); 416 } 417 } 418 if (!isInitialized() || !newVisibleFiles.equals(visibleFiles)) { 419 visibleFiles = newVisibleFiles; 420 RP.post(new Runnable () { public void run() { 422 setKeys(visibleFiles); 423 } 424 }); 425 ((ImportantFilesNode) getNode()).setFiles(files); } 427 } 428 429 private void attachListeners() { 430 try { 431 if (fcl == null) { 432 fcl = new FileChangeAdapter() { 433 public void fileDataCreated(FileEvent fe) { 434 refreshKeys(); 435 } 436 public void fileDeleted(FileEvent fe) { 437 refreshKeys(); 438 } 439 }; 440 project.getProjectDirectory().getFileSystem().addFileChangeListener(fcl); 441 } 442 } catch (FileStateInvalidException e) { 443 assert false : e; 444 } 445 } 446 447 private void removeListeners() { 448 if (fcl != null) { 449 try { 450 project.getProjectDirectory().getFileSystem().removeFileChangeListener(fcl); 451 } catch (FileStateInvalidException e) { 452 assert false : e; 453 } 454 fcl = null; 455 } 456 } 457 458 } 459 460 } 461 | Popular Tags |