1 19 20 package org.openide.src.nodes; 21 22 import java.beans.PropertyChangeListener ; 23 import java.beans.PropertyChangeEvent ; 24 import java.util.*; 25 26 import org.openide.nodes.Children; 27 import org.openide.nodes.Node; 28 import org.openide.cookies.FilterCookie; 29 import org.openide.util.WeakListeners; 30 import org.openide.src.*; 31 32 36 public class ClassChildren extends Children.Keys implements FilterCookie { 37 38 39 private static int PPP_MASK = SourceElementFilter.PUBLIC + 40 SourceElementFilter.PRIVATE + 41 SourceElementFilter.PROTECTED; 42 43 protected static HashMap propToFilter; 44 45 46 private static Comparator comparator = new Comparator () { 47 public int compare (Object o1, Object o2) { 48 if (o1 instanceof MemberElement) 49 if (o2 instanceof MemberElement) 50 return ((MemberElement) o1).getName ().getName ().compareToIgnoreCase ( 51 ((MemberElement) o2).getName ().getName () 52 ); 53 else 54 return -1; 55 else 56 if (o2 instanceof MemberElement) 57 return 1; 58 else 59 return 0; 60 } 61 }; 62 63 static { 64 propToFilter = new HashMap (); 65 propToFilter.put (ElementProperties.PROP_CLASSES, new Integer (ClassElementFilter.CLASS | ClassElementFilter.INTERFACE)); 66 propToFilter.put (ElementProperties.PROP_METHODS, new Integer (ClassElementFilter.METHOD)); 67 propToFilter.put (ElementProperties.PROP_FIELDS, new Integer (ClassElementFilter.FIELD)); 68 propToFilter.put (ElementProperties.PROP_CONSTRUCTORS, new Integer (ClassElementFilter.CONSTRUCTOR)); 69 propToFilter.put (ElementProperties.PROP_INITIALIZERS, new Integer (ClassElementFilter.CONSTRUCTOR)); 70 } 71 72 73 protected ClassElement element; 74 75 protected ClassElementFilter filter; 76 77 protected ElementNodeFactory factory; 78 79 private PropertyChangeListener wPropL; 80 82 private ElementListener propL; 83 84 protected Collection[] cpl; 85 86 private boolean nodesInited = false; 87 88 89 91 95 public ClassChildren (final ClassElement element) { 96 this(DefaultFactory.READ_WRITE, element); 97 } 98 99 104 public ClassChildren (final ElementNodeFactory factory, 105 final ClassElement element) { 106 super(); 107 this.element = element; 108 this.factory = factory; 109 this.filter = null; 110 } 111 112 113 114 115 118 public Class getFilterClass () { 119 return ClassElementFilter.class; 120 } 121 122 124 public Object getFilter () { 125 return filter; 126 } 127 128 131 public void setFilter (final Object filter) { 132 if (!(filter instanceof ClassElementFilter)) 133 throw new IllegalArgumentException (); 134 135 this.filter = (ClassElementFilter)filter; 136 if (nodesInited) 138 refreshAllKeys (); 139 } 140 141 142 144 147 protected void addNotify () { 148 if (wPropL == null) { 150 propL = new ElementListener(this); 151 wPropL = WeakListeners.propertyChange (propL, element); 152 } 153 refreshAllKeys (); 154 element.addPropertyChangeListener (wPropL); 155 nodesInited = true; 156 } 157 158 protected void removeNotify () { 159 setKeys (java.util.Collections.EMPTY_SET); 160 nodesInited = false; 161 } 162 163 private Node hookNodeName(Node n) { 164 MemberElement el = (MemberElement)n.getCookie(MemberElement.class); 165 if (el != null) 166 el.addPropertyChangeListener(propL); 167 return n; 168 } 169 170 173 protected Node[] createNodes (final Object key) { 174 if (key instanceof MethodElement) { 175 return new Node[] { hookNodeName(factory.createMethodNode((MethodElement)key)) }; 176 } 177 if (key instanceof FieldElement) { 178 return new Node[] { hookNodeName(factory.createFieldNode((FieldElement)key)) }; 179 } 180 if (key instanceof ConstructorElement) { 181 return new Node[] { hookNodeName(factory.createConstructorNode((ConstructorElement)key)) }; 182 } 183 if (key instanceof ClassElement) { 184 return new Node[] { hookNodeName(factory.createClassNode((ClassElement)key)) }; 185 } 186 if (key instanceof InitializerElement) { 187 return new Node[] { hookNodeName(factory.createInitializerNode((InitializerElement)key)) }; 188 } 189 return new Node[0]; 191 } 192 193 194 195 196 199 protected void refreshAllKeys () { 200 cpl = new Collection [getOrder ().length]; 201 refreshKeys (ClassElementFilter.ALL); 202 } 203 204 206 protected void refreshKeys (int filter) { 207 int[] order = getOrder (); 208 LinkedList keys = new LinkedList(); 209 for (int i = 0; i < order.length; i++) { 211 if (((order[i] & filter) != 0) || (cpl [i] == null)) 212 keys.addAll (cpl [i] = getKeysOfType (order[i])); 213 else 214 keys.addAll (cpl [i]); 215 } 216 ElementListener l = propL; 218 if (l != null) 219 l.updateElements(keys); 220 setKeys(keys); 221 } 222 223 225 protected Collection getKeysOfType (final int elementType) { 226 LinkedList keys = new LinkedList(); 227 if ((elementType & ClassElementFilter.EXTENDS) != 0) { 228 keys.add (element.getSuperclass ()); 229 } 230 if ((elementType & ClassElementFilter.IMPLEMENTS) != 0) { 231 keys.addAll (Arrays.asList (element.getInterfaces ())); 232 } 233 if ((elementType & ClassElementFilter.FIELD) != 0) { 234 filterModifiers (element.getFields (), keys); 235 } 236 if ((elementType & ClassElementFilter.CONSTRUCTOR) != 0) { 237 filterModifiers (element.getConstructors (), keys); 238 keys.addAll (Arrays.asList (element.getInitializers ())); 239 } 240 if ((elementType & ClassElementFilter.METHOD) != 0) { 241 filterModifiers (element.getMethods (), keys); 242 } 243 if ((elementType & (ClassElementFilter.CLASS + ClassElementFilter.INTERFACE)) != 0) { 244 filterClassModifiers (element.getClasses (), keys, elementType); 245 } 246 if ((filter == null) || filter.isSorted ()) 247 Collections.sort (keys, comparator); 248 return keys; 249 } 250 251 253 protected int[] getOrder () { 254 return (filter == null || (filter.getOrder() == null)) 255 ? ClassElementFilter.DEFAULT_ORDER : filter.getOrder(); 256 } 257 258 260 private int getModifierFilter () { 261 if (filter == null) return ClassElementFilter.ALL_MODIFIERS; 262 return filter.getModifiers (); 263 } 264 265 267 private void filterModifiers (MemberElement[] elements, Collection keys) { 268 int ff = getModifierFilter (); 269 int i, k = elements.length; 270 for (i = 0; i < k; i ++) { 271 int f = elements [i].getModifiers (); 272 if ((f & PPP_MASK) == 0) f += ClassElementFilter.PACKAGE; 273 if ((f & ff) != 0) keys.add (elements [i]); 274 } 275 } 276 277 279 private void filterClassModifiers (ClassElement[] elements, Collection keys, int filter) { 280 int ff = getModifierFilter (); 281 int i, k = elements.length; 282 for (i = 0; i < k; i ++) { 283 int f = elements [i].getModifiers (); 284 if ((f & PPP_MASK) == 0) f += ClassElementFilter.PACKAGE; 285 if ((f & ff) == 0) continue; 286 if (elements [i].isClass ()) { 287 if ((filter & ClassElementFilter.CLASS) != 0) keys.add (elements [i]); 288 } else 289 if ((filter & ClassElementFilter.INTERFACE) != 0) keys.add (elements [i]); 290 } 291 } 292 293 294 296 298 private static final class ElementListener extends java.lang.ref.WeakReference implements Runnable , PropertyChangeListener { 299 Collection elements; 300 301 ElementListener(ClassChildren cc) { 302 super(cc, org.openide.util.Utilities.activeReferenceQueue()); 303 } 304 305 ClassChildren getClassChildren() { 306 Object o = get(); 307 return (ClassChildren)o; 308 } 309 310 315 public void propertyChange (PropertyChangeEvent evt) { 316 Object src = evt.getSource(); 317 String propName = evt.getPropertyName(); 318 int filter; 319 320 ClassChildren cc = getClassChildren(); 321 if (cc == null) 322 return; 323 324 if (src != cc.element) { 325 if (src instanceof MemberElement && 326 (propName == null || ElementProperties.PROP_NAME == propName)) { 327 if (src instanceof MethodElement) 328 filter = ClassElementFilter.METHOD; 329 else if (src instanceof ConstructorElement) 330 filter = ClassElementFilter.CONSTRUCTOR; 331 else if (src instanceof FieldElement) 332 filter = ClassElementFilter.FIELD; 333 else 334 filter = ClassElementFilter.CLASS | ClassElementFilter.INTERFACE; 335 } else 336 return; 337 } else { 338 Integer i = (Integer ) cc.propToFilter.get (propName); 339 if (i == null) 340 return; 341 filter = i.intValue(); 342 } 343 cc.refreshKeys (filter); 344 } 345 346 void updateElements(Collection c) { 347 this.elements = c; 348 } 349 350 public void run() { 351 for (Iterator it = elements.iterator(); it.hasNext(); ) { 353 Object o = it.next(); 354 if (!(o instanceof Element)) 355 continue; 356 Element el = (Element)o; 357 el.removePropertyChangeListener(this); 358 } 359 } 360 } } 362 | Popular Tags |