1 19 20 package org.netbeans.modules.form.palette; 21 22 import java.beans.PropertyChangeEvent ; 23 import java.beans.PropertyChangeListener ; 24 import java.lang.ref.WeakReference ; 25 import java.util.*; 26 import java.text.MessageFormat ; 27 import java.io.File ; 28 import java.io.IOException ; 29 30 import org.netbeans.spi.palette.*; 31 import org.openide.ErrorManager; 32 import org.openide.nodes.*; 33 import org.openide.loaders.DataFolder; 34 import org.openide.loaders.DataObject; 35 import org.openide.filesystems.*; 36 import org.openide.util.*; 37 import org.openide.util.lookup.*; 38 39 import org.netbeans.api.java.classpath.ClassPath; 40 import org.netbeans.api.project.libraries.Library; 41 import org.netbeans.api.project.libraries.LibraryManager; 42 import org.netbeans.api.project.Project; 43 import org.netbeans.api.project.FileOwnerQuery; 44 45 import org.netbeans.modules.form.project.ClassSource; 46 47 52 53 public final class PaletteUtils { 54 55 private static FileObject paletteFolder; 56 private static DataFolder paletteDataFolder; 57 58 private static FileObject context; 59 private static Map<Project, ProjectPaletteInfo> palettes = new WeakHashMap(); 60 61 private static class ProjectPaletteInfo { 62 PaletteLookup paletteLookup; 63 ClassPathFilter paletteFilter; 64 List<PropertyChangeListener > paletteListeners; 65 66 PaletteController getPalette() { 67 return paletteLookup.lookup(PaletteController.class); 68 } 69 } 70 71 private PaletteUtils() { 72 } 73 74 static String getItemComponentDescription(PaletteItem item) { 75 ClassSource classSource = item.getComponentClassSource(); 76 77 if (classSource == null || classSource.getCPRootCount() == 0) { 78 String className = classSource.getClassName(); 79 if (className != null) { 80 if (className.startsWith("javax.") || className.startsWith("java.")) return getBundleString("MSG_StandardJDKComponent"); if (className.startsWith("org.netbeans.")) return getBundleString("MSG_NetBeansComponent"); } 86 } 87 else { 88 String type = classSource.getCPRootType(0); 89 String name = classSource.getCPRootName(0); 90 91 if (ClassSource.JAR_SOURCE.equals(type)) { 92 return MessageFormat.format( 93 getBundleString("FMT_ComponentFromJar"), new Object [] { name }); 95 } 96 else if (ClassSource.LIBRARY_SOURCE.equals(type)) { 97 Library lib = LibraryManager.getDefault().getLibrary(name); 98 return MessageFormat.format( 99 getBundleString("FMT_ComponentFromLibrary"), new Object [] { lib != null ? lib.getDisplayName() : name }); 101 } 102 else if (ClassSource.PROJECT_SOURCE.equals(type)) { 103 try { 104 Project project = FileOwnerQuery.getOwner(new File (name).toURI()); 105 return MessageFormat.format( 106 getBundleString("FMT_ComponentFromProject"), new Object [] { project == null ? name : 108 FileUtil.getFileDisplayName(project.getProjectDirectory()) }); 109 } catch (Exception ex) { 110 } 112 } 113 } 114 115 return getBundleString("MSG_UnspecifiedComponent"); } 117 118 public static FileObject getPaletteFolder() { 119 if (paletteFolder != null) 120 return paletteFolder; 121 122 try { 123 paletteFolder = Repository.getDefault().getDefaultFileSystem() 124 .findResource("FormDesignerPalette"); if (paletteFolder == null) paletteFolder = Repository.getDefault().getDefaultFileSystem() 127 .getRoot().createFolder("FormDesignerPalette"); } 129 catch (java.io.IOException ex) { 130 throw new IllegalStateException ("Palette folder not found and cannot be created."); } 132 return paletteFolder; 133 } 134 135 public static Node getPaletteNode() { 136 return getPaletteDataFolder().getNodeDelegate(); 137 } 138 139 public static void showPaletteManager() { 140 try { 141 PaletteFactory.createPalette("FormDesignerPalette", new FormPaletteActions(), 143 new ClassPathFilter(null), null) 145 .showCustomizer(); 146 } 147 catch (IOException ex) { 148 ErrorManager.getDefault().notify(ex); 149 } 150 } 151 152 public static void setContext(FileObject fileInProject) { 153 context = fileInProject; 154 } 155 156 public static synchronized void addPaletteListener(PropertyChangeListener listener, 157 FileObject context) 158 { 159 ProjectPaletteInfo pInfo = preparePalette(context); 160 if (pInfo != null) { 161 if (pInfo.paletteListeners == null) { 162 pInfo.paletteListeners = new LinkedList(); 163 } 164 pInfo.paletteListeners.add(listener); 165 pInfo.getPalette().addPropertyChangeListener(listener); 166 } 167 } 168 169 public static synchronized void removePaletteListener(PropertyChangeListener listener, 170 FileObject context) 171 { 172 Project project = FileOwnerQuery.getOwner(context); 173 if (project != null) { 174 ProjectPaletteInfo pInfo = palettes.get(project); 175 if (pInfo != null && pInfo.paletteListeners != null) { 176 pInfo.paletteListeners.remove(listener); 177 pInfo.getPalette().removePropertyChangeListener(listener); 178 } 179 } 180 } 181 182 public static Lookup getPaletteLookup(FileObject context) { 183 ProjectPaletteInfo pInfo = preparePalette(context); 184 return pInfo != null ? pInfo.paletteLookup : Lookups.fixed(new Object [0]); 185 } 186 187 private static PaletteController getPalette() { 188 ProjectPaletteInfo pInfo = preparePalette(context); 189 return pInfo != null ? pInfo.getPalette() : null; 190 } 191 192 private static ClassPathFilter getPaletteFilter() { 193 if (context != null) { 194 Project project = FileOwnerQuery.getOwner(context); 195 if (project != null) { 196 ProjectPaletteInfo pInfo = palettes.get(project); 197 if (pInfo != null) 198 return pInfo.paletteFilter; 199 } 200 } 201 return null; 202 } 203 204 208 private static ProjectPaletteInfo preparePalette(FileObject context) { 209 if (context == null) 210 return null; 211 212 Project project = FileOwnerQuery.getOwner(context); 213 if (project == null) 214 return null; 215 216 ProjectPaletteInfo pInfo = palettes.get(project); 217 if (pInfo == null) { 218 ClassPath classPath = ClassPath.getClassPath(context, ClassPath.BOOT); 219 classPath.addPropertyChangeListener(new ClassPathListener(classPath, project)); 220 221 PaletteLookup lookup = new PaletteLookup(); 222 ClassPathFilter filter = new ClassPathFilter(classPath); 223 lookup.setPalette(createPalette(filter)); 224 225 pInfo = new ProjectPaletteInfo(); 226 pInfo.paletteLookup = lookup; 227 pInfo.paletteFilter = filter; 228 palettes.put(project, pInfo); 229 } 230 return pInfo; 231 } 232 233 236 private static PaletteController createPalette(ClassPathFilter filter) { 237 try { 238 return PaletteFactory.createPalette("FormDesignerPalette", new FormPaletteActions(), 240 filter, 241 null); 242 } 243 catch (IOException ex) { 244 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex); 245 return null; 246 } 247 } 248 249 255 private static synchronized void bootClassPathChanged(Project p, ClassPath cp) { 256 ProjectPaletteInfo pInfo = palettes.get(p); 257 if (pInfo != null) { 258 PaletteLookup lookup = pInfo.paletteLookup; 259 PaletteController oldPalette = pInfo.getPalette(); 260 oldPalette.clearSelection(); 261 ClassPathFilter newFilter = new ClassPathFilter(cp); 262 PaletteController newPalette = createPalette(newFilter); 263 if (pInfo.paletteListeners != null) { 264 for (PropertyChangeListener l : pInfo.paletteListeners) { 265 oldPalette.removePropertyChangeListener(l); 266 newPalette.addPropertyChangeListener(l); 267 } 268 } 269 lookup.setPalette(newPalette); 270 pInfo.paletteFilter = newFilter; 271 } 272 } 273 274 static DataFolder getPaletteDataFolder() { 275 if (paletteDataFolder == null) 276 paletteDataFolder = DataFolder.findFolder(getPaletteFolder()); 277 return paletteDataFolder; 278 } 279 280 public static void clearPaletteSelection() { 281 getPalette().clearSelection(); 282 } 283 284 public static PaletteItem getSelectedItem() { 285 PaletteController palette = getPalette(); 286 if( null == palette ) 287 return null; 288 Lookup lkp = palette.getSelectedItem(); 289 290 return (PaletteItem)lkp.lookup( PaletteItem.class ); 291 } 292 293 public static void selectItem( PaletteItem item ) { 294 if( null == item ) { 295 getPalette().clearSelection(); 296 } else { 297 Node paletteNode = (Node)getPalette().getRoot().lookup(Node.class); 299 Node[] categories = getCategoryNodes(paletteNode, true, true, true); 300 for( int i=0; i<categories.length; i++ ) { 301 Node[] items = getItemNodes( categories[i], true ); 302 for( int j=0; j<items.length; j++ ) { 303 PaletteItem formItem = (PaletteItem)items[j].getLookup().lookup( PaletteItem.class ); 304 if( item.equals( formItem ) ) { 305 getPalette().setSelectedItem( categories[i].getLookup(), items[j].getLookup() ); 306 } 307 } 308 } 309 } 310 } 311 312 public static PaletteItem[] getAllItems() { 313 HashSet uniqueItems = null; 314 Node[] categories = getCategoryNodes(getPaletteNode(), false, true, false); 316 for( int i=0; i<categories.length; i++ ) { 317 Node[] items = getItemNodes( categories[i], true ); 318 for( int j=0; j<items.length; j++ ) { 319 PaletteItem formItem = (PaletteItem)items[j].getLookup().lookup( PaletteItem.class ); 320 if( null != formItem ) { 321 if( null == uniqueItems ) { 322 uniqueItems = new HashSet(); 323 } 324 uniqueItems.add( formItem ); 325 } 326 } 327 } 328 PaletteItem[] res; 329 if( null != uniqueItems ) { 330 res = (PaletteItem[]) uniqueItems.toArray( new PaletteItem[uniqueItems.size()] ); 331 } else { 332 res = new PaletteItem[0]; 333 } 334 return res; 335 } 336 337 static String getBundleString(String key) { 338 return NbBundle.getBundle(PaletteUtils.class).getString(key); 339 } 340 341 348 public static Node[] getItemNodes( Node categoryNode, boolean mustBeValid ) { 349 Node[] nodes = categoryNode.getChildren().getNodes( true ); 350 if (!mustBeValid) 351 return nodes; 352 353 ClassPathFilter filter = getPaletteFilter(); 354 if (filter == null) 355 return nodes; 356 357 List validList = null; 358 for (int i=0; i < nodes.length; i++) { 359 PaletteItem item = (PaletteItem) nodes[i].getCookie(PaletteItem.class); 360 if (filter.isValidItem(item)) { 361 if (validList != null) 362 validList.add(nodes[i]); 363 } 364 else if (validList == null) { 365 validList = new ArrayList(nodes.length); 366 for (int j=0; j < i; j++) { 367 validList.add(nodes[j]); 368 } 369 } 370 } 371 if (validList != null) 372 nodes = (Node[]) validList.toArray(new Node[validList.size()]); 373 374 return nodes; 375 } 376 377 385 public static Node[] getCategoryNodes(Node paletteNode, boolean mustBeVisible) { 386 return getCategoryNodes(paletteNode, mustBeVisible, mustBeVisible, true); 387 } 388 389 401 private static Node[] getCategoryNodes(Node paletteNode, 402 boolean mustBeVisible, 403 boolean mustBeValid, 404 boolean mustBePaletteCategory) 405 { 406 if (mustBeVisible) 407 mustBeValid = mustBePaletteCategory = true; 408 409 Node[] nodes = paletteNode.getChildren().getNodes(true); 410 411 ClassPathFilter filter = mustBeValid ? getPaletteFilter() : null; 412 java.util.List list = null; for( int i=0; i<nodes.length; i++ ) { 414 if ((!mustBeVisible || isVisibleCategoryNode(nodes[i])) 415 && (!mustBeValid || filter == null || filter.isValidCategory(nodes[i])) 416 && (!mustBePaletteCategory || representsShowableCategory(nodes[i]))) 417 { if( list != null ) { 419 list.add(nodes[i]); 420 } 421 } else if( list == null ) { 422 list = new ArrayList( nodes.length ); 423 for( int j=0; j < i; j++ ) { 424 list.add(nodes[j]); 425 } 426 } 427 } 428 if( list != null ) { 429 nodes = new Node[list.size()]; 430 list.toArray(nodes); 431 } 432 return nodes; 433 } 434 435 438 private static boolean isVisibleCategoryNode(Node node) { 439 DataFolder df = (DataFolder) node.getCookie(DataFolder.class); 440 if (df != null) { 441 Object value = node.getValue("psa_" + PaletteController.ATTR_IS_VISIBLE); if (null == value || "null".equals(value)) { value = df.getPrimaryFile().getAttribute(PaletteController.ATTR_IS_VISIBLE); 444 } 445 if (value == null) { 446 value = Boolean.TRUE; 447 } 448 return Boolean.valueOf(value.toString()).booleanValue(); 449 } 450 return false; 451 } 452 453 private static boolean representsShowableCategory(Node node) { 454 DataFolder df = (DataFolder) node.getCookie(DataFolder.class); 455 return (df != null) && !Boolean.TRUE.equals(df.getPrimaryFile().getAttribute("isNoPaletteCategory")); } 457 458 460 466 private static class ClassPathFilter extends PaletteFilter { 467 private ClassPath classPath; 468 private Set<PaletteItem> validItems; 469 private Set<PaletteItem> invalidItems; 470 471 ClassPathFilter(ClassPath cp) { 472 if (cp != null) { 473 validItems = new WeakSet(); 474 invalidItems = new WeakSet(); 475 } 476 classPath = cp; 477 } 478 479 public boolean isValidCategory(Lookup lkp) { 480 Node categoryNode = lkp.lookup(Node.class); 481 if (!representsShowableCategory(categoryNode)) 482 return false; 484 return isValidCategory(categoryNode); 485 } 486 487 boolean isValidCategory(Node node) { 488 if (classPath == null) 489 return true; 490 491 DataFolder folder = (DataFolder) node.getCookie(DataFolder.class); 495 if (folder == null) 496 return false; 497 498 DataObject[] dobjs = folder.getChildren(); 499 for (int i=0; i < dobjs.length; i++) { 500 PaletteItem item = (PaletteItem) dobjs[i].getCookie(PaletteItem.class); 501 if (item == null || isValidItem(item)) 502 return true; 503 } 504 return dobjs.length == 0; 505 } 506 507 public boolean isValidItem(Lookup lkp) { 508 return isValidItem((PaletteItem) lkp.lookup(PaletteItem.class)); 509 } 510 511 boolean isValidItem(PaletteItem item) { 512 if (classPath == null) 513 return true; 514 515 if (item == null) return false; 517 518 if (item.getComponentClassSource().getCPRootCount() > 0 519 || "chooseBean".equals(item.getExplicitComponentType()) || "org.netbeans.modules.form.layoutsupport.delegates.NullLayoutSupport".equals(item.getComponentClassName())) return true; 523 if (validItems.contains(item)) { 524 return true; 525 } 526 else if (invalidItems.contains(item)) { 527 return false; 528 } 529 530 String resName = item.getComponentClassName().replace('.', '/').concat(".class"); if (classPath.findResource(resName) != null) { 533 validItems.add(item); 534 return true; 535 } 536 else { 537 invalidItems.add(item); 538 return false; 539 } 540 } 541 } 542 543 547 private static class ClassPathListener implements PropertyChangeListener { 548 private ClassPath classPath; 549 private WeakReference projRef; 550 551 ClassPathListener(ClassPath cp, Project p) { 552 classPath = cp; 553 projRef = new WeakReference (p); 554 } 555 556 public void propertyChange(PropertyChangeEvent evt) { 557 if (ClassPath.PROP_ROOTS.equals(evt.getPropertyName())) { 558 Project p = (Project) projRef.get(); 559 if (p != null) 560 PaletteUtils.bootClassPathChanged(p, classPath); 561 else 562 classPath.removePropertyChangeListener(this); 563 } 564 } 565 } 566 567 570 private static class PaletteLookup extends AbstractLookup { 571 private InstanceContent content; 572 573 PaletteLookup() { 574 this(new InstanceContent()); 575 } 576 577 private PaletteLookup(InstanceContent content) { 578 super(content); 579 this.content = content; 580 } 581 582 void setPalette(PaletteController palette) { 583 content.set(Arrays.asList(new PaletteController[] { palette }), null); 584 } 585 } 586 } 587 | Popular Tags |