1 19 20 package org.openide.nodes; 21 22 import java.util.ArrayList ; 23 import java.util.Collection ; 24 import java.util.Collections ; 25 import java.util.Iterator ; 26 import org.openide.util.Lookup.Template; 27 import org.openide.util.lookup.AbstractLookup; 28 import org.openide.util.lookup.AbstractLookup.Pair; 29 30 35 final class NodeLookup extends AbstractLookup { 36 41 static final ThreadLocal <Node> NO_COOKIE_CHANGE = new ThreadLocal <Node>(); 42 43 44 private java.util.Collection <Class > queriedCookieClasses = new ArrayList <Class >(); 45 46 48 private Node node; 49 50 52 public NodeLookup(Node n) { 53 super(); 54 55 this.node = n; 56 addPair(new LookupItem(n)); 57 } 58 59 66 private static void addCookie(Node node, Class <?> c, 67 Collection <AbstractLookup.Pair> collection, 68 java.util.Map <AbstractLookup.Pair, Class > fromPairToClass) { 69 Object res; 70 Collection <AbstractLookup.Pair> pairs; 71 Object prev = CookieSet.entryQueryMode(c); 72 73 try { 74 @SuppressWarnings ("unchecked") 75 Class <? extends Node.Cookie> fake = (Class <? extends Node.Cookie>)c; 76 res = node.getCookie(fake); 77 } finally { 78 pairs = CookieSet.exitQueryMode(prev); 79 } 80 81 if (pairs == null) { 82 if (res == null) { 83 return; 84 } 85 86 pairs = Collections.singleton((AbstractLookup.Pair)new LookupItem(res)); 87 } 88 89 collection.addAll(pairs); 90 for (AbstractLookup.Pair p : pairs) { 91 Class <?> oldClazz = fromPairToClass.get(p); 92 if (oldClazz == null || c.isAssignableFrom(oldClazz)) { 93 fromPairToClass.put(p, c); 94 } 95 } 96 } 97 98 101 protected final void beforeLookup(Template template) { 102 Class type = template.getType(); 103 104 if (type == Object .class) { 105 java.util.Set all; 107 Object prev = null; 108 109 try { 110 prev = CookieSet.entryAllClassesMode(); 111 112 Object ignoreResult = node.getCookie(Node.Cookie.class); 113 } finally { 114 all = CookieSet.exitAllClassesMode(prev); 115 } 116 117 Iterator it = all.iterator(); 118 119 while (it.hasNext()) { 120 Class c = (Class ) it.next(); 121 updateLookupAsCookiesAreChanged(c); 122 } 123 124 if (!queriedCookieClasses.contains(Node.Cookie.class)) { 126 updateLookupAsCookiesAreChanged(Node.Cookie.class); 127 } 128 } 129 130 if (!queriedCookieClasses.contains(type)) { 131 updateLookupAsCookiesAreChanged(type); 132 } 133 } 134 135 public void updateLookupAsCookiesAreChanged(Class toAdd) { 136 java.util.Collection <AbstractLookup.Pair> instances; 137 java.util.Map <AbstractLookup.Pair, Class > fromPairToQueryClass; 138 139 synchronized (this) { 141 if (toAdd != null) { 142 if (queriedCookieClasses.contains(toAdd)) { 143 return; 145 } 146 147 queriedCookieClasses.add(toAdd); 148 } 149 150 instances = new java.util.LinkedHashSet <AbstractLookup.Pair>(queriedCookieClasses.size()); 151 fromPairToQueryClass = new java.util.LinkedHashMap <AbstractLookup.Pair, Class >(); 152 153 java.util.Iterator <Class > it = new ArrayList <Class >(queriedCookieClasses).iterator(); 154 LookupItem nodePair = new LookupItem(node); 155 instances.add(nodePair); 156 fromPairToQueryClass.put(nodePair, Node.class); 157 158 while (it.hasNext()) { 159 Class c = it.next(); 160 addCookie(node, c, instances, fromPairToQueryClass); 161 } 162 } 163 164 final java.util.Map <AbstractLookup.Pair, Class > m = fromPairToQueryClass; 165 166 class Cmp implements java.util.Comparator <AbstractLookup.Pair> { 167 public int compare(AbstractLookup.Pair p1, AbstractLookup.Pair p2) { 168 Class <?> c1 = m.get(p1); 169 Class <?> c2 = m.get(p2); 170 171 if (c1 == c2) { 172 return 0; 173 } 174 175 if (c1.isAssignableFrom(c2)) { 176 return -1; 177 } 178 179 if (c2.isAssignableFrom(c1)) { 180 return 1; 181 } 182 183 if (c1.isAssignableFrom(p2.getType())) { 184 return -1; 185 } 186 187 if (c2.isAssignableFrom(p1.getType())) { 188 return 1; 189 } 190 191 return 0; 192 } 193 } 194 195 java.util.ArrayList <AbstractLookup.Pair> list = new java.util.ArrayList <AbstractLookup.Pair>(instances); 196 java.util.Collections.sort(list, new Cmp()); 197 198 if (toAdd == null) { 199 setPairs(list); 200 } else { 201 Node prev = NO_COOKIE_CHANGE.get(); 202 203 try { 204 NO_COOKIE_CHANGE.set(node); 205 206 setPairs(list); 209 } finally { 210 NO_COOKIE_CHANGE.set(prev); 211 } 212 } 213 } 214 215 216 private static class LookupItem extends AbstractLookup.Pair { 217 private Object instance; 218 219 public LookupItem(Object instance) { 220 this.instance = instance; 221 } 222 223 public String getDisplayName() { 224 return getId(); 225 } 226 227 public String getId() { 228 return instance.toString(); 229 } 230 231 public Object getInstance() { 232 return instance; 233 } 234 235 public Class getType() { 236 return instance.getClass(); 237 } 238 239 public boolean equals(Object object) { 240 if (object instanceof LookupItem) { 241 return instance == ((LookupItem) object).getInstance(); 242 } 243 244 return false; 245 } 246 247 public int hashCode() { 248 return instance.hashCode(); 249 } 250 251 protected boolean creatorOf(Object obj) { 252 return instance == obj; 253 } 254 255 protected boolean instanceOf(Class c) { 256 return c.isInstance(instance); 257 } 258 } 259 } 261 | Popular Tags |