1 19 20 package org.netbeans.modules.java.ui.nodes; 21 22 import java.beans.*; 23 import java.util.*; 24 25 import org.openide.cookies.SourceCookie; 26 27 import org.openide.loaders.DataObject; 28 29 import org.openide.nodes.AbstractNode; 30 import org.openide.nodes.Children; 31 import org.openide.nodes.Node; 32 33 import org.openide.src.*; 34 import org.openide.src.nodes.ClassElementNode; 35 36 import org.openide.util.Task; 37 import org.openide.util.TaskListener; 38 import org.openide.util.WeakListeners; 39 40 import org.netbeans.api.java.comparators.JavaElementComparator; 41 import org.netbeans.modules.java.tools.MultiDataContainer; 42 43 57 public final class PackageNode extends AbstractNode { 58 61 private static final String PACKAGE_ICON_BASE = "org/netbeans/modules/java/resources/package"; 63 66 private static final ElementFormat CLASS_ELEMENT_FORMAT = new ElementFormat("{C}"); 68 71 private static final Comparator CLASS_NAME_COMPARATOR = 72 JavaElementComparator.createClassComparator( 73 false, new int[] { 74 JavaElementComparator.NAME 75 }); 76 79 public PackageNode(String packName, MultiDataContainer container) { 80 super(new PackageChildren(container)); 81 setName(packName); 82 setIconBase(PACKAGE_ICON_BASE); 83 } 84 85 89 private static class PackageChildren extends Children.Keys implements 90 PropertyChangeListener { 91 94 MultiDataContainer container; 95 96 99 Collection classElements; 100 101 104 Collection parsingSources; 105 106 110 PropertyChangeListener weakListener; 111 112 PackageChildren(MultiDataContainer cont) { 113 this.container = cont; 114 this.classElements = new TreeSet(CLASS_NAME_COMPARATOR); 115 this.parsingSources = new LinkedList(); 116 weakListener = WeakListeners.propertyChange(this, null); 117 cont.addPropertyChangeListener(weakListener); 118 } 119 120 public void addNotify() { 121 refreshData(); 122 } 123 124 128 protected Node[] createNodes(Object key) { 129 if (key instanceof ClassElement) { 130 Node n = createClassNode((ClassElement)key); 131 if (n != null) 132 return new Node[] { n }; 133 } else if (key instanceof String ) { 134 String name = (String )key; 135 MultiDataContainer cont = getPackageContainer(name); 136 if (cont != null) { 137 return new Node[] { 138 createPackageNode((String )key, cont) 139 }; 140 } 141 } 142 return new Node[0]; 143 } 144 145 149 private void sortInClasses(ClassElement[] cls) { 150 synchronized (this) { 151 classElements.addAll(Arrays.asList(cls)); 152 } 153 refreshKeys(); 154 } 155 156 159 private void refreshKeys() { 160 Collection containers = container.getContainers().keySet(); 161 Collection keys = new ArrayList(containers.size() + classElements.size()); 162 keys.addAll(containers); 163 synchronized (this) { 164 keys.addAll(classElements); 165 } 166 setKeys(keys); 167 } 168 169 172 protected final Node createClassNode(ClassElement c) { 173 ClassElementNode node = new ClassElementNode(c, Children.LEAF, true); 174 node.setElementFormat(CLASS_ELEMENT_FORMAT); 175 return node; 176 } 177 178 182 protected final Node createPackageNode(String name, MultiDataContainer data) { 183 return new PackageNode(name, data); 184 } 185 186 private MultiDataContainer getPackageContainer(String name) { 187 return (MultiDataContainer)this.container.getContainers().get(name); 188 } 189 190 198 private void refreshData() { 199 DataObject[] contents = container.getChildren(); 200 Collection myChildren = new ArrayList(contents.length); 201 Collection newClassElements = new ArrayList(contents.length); 202 203 for (int i = 0; i < contents.length; i++) { 204 DataObject d = contents[i]; 205 206 SourceCookie ck = (SourceCookie)d.getCookie(SourceCookie.class); 207 if (ck != null) { 208 SourceElement src = ck.getSource(); 209 if (parsingSources.add(src)) { 210 src.addPropertyChangeListener(weakListener); 211 if (src.getStatus() == SourceElement.STATUS_NOT) { 212 TaskListener l = new PrepareL(d, src); 213 src.prepare().addTaskListener(l); 214 } else { 215 synchronized (this) { 216 newClassElements.addAll(Arrays.asList(src.getAllClasses())); 217 } 218 } 219 } 220 } 221 } 222 synchronized (this) { 223 classElements = newClassElements; 224 } 225 refreshKeys(); 226 } 227 228 public void propertyChange(PropertyChangeEvent evt) { 229 Object source = evt.getSource(); 230 String propName = evt.getPropertyName(); 231 232 if (source == container) { 233 if (MultiDataContainer.PROP_CONTAINERS.equals(propName) || 234 MultiDataContainer.PROP_CHILDREN.equals(propName)) { 235 refreshData(); 236 } 237 } else { 238 if (ElementProperties.PROP_ALL_CLASSES.equals(evt.getPropertyName())) { 239 refreshData(); 240 } 241 } 242 } 243 244 248 private class PrepareL implements TaskListener { 249 DataObject sourceDO; 250 SourceElement srcElement; 251 252 PrepareL(DataObject source, SourceElement src) { 253 this.sourceDO = source; 254 this.srcElement = src; 255 } 256 257 public void taskFinished(Task t) { 258 t.removeTaskListener(this); 259 sortInClasses(srcElement.getAllClasses()); 260 } 261 } 262 } 263 } 264 | Popular Tags |