Lines 26-31
Link Here
|
26 |
import javax.swing.event.ChangeEvent; |
26 |
import javax.swing.event.ChangeEvent; |
27 |
import javax.swing.event.ChangeListener; |
27 |
import javax.swing.event.ChangeListener; |
28 |
import javax.swing.event.EventListenerList; |
28 |
import javax.swing.event.EventListenerList; |
|
|
29 |
import org.openide.util.Lookup; |
30 |
import org.openide.util.lookup.AbstractLookup; |
31 |
import org.openide.util.lookup.InstanceContent; |
29 |
|
32 |
|
30 |
|
33 |
|
31 |
/** Support class for storing cookies and |
34 |
/** Support class for storing cookies and |
Lines 35-41
Link Here
|
35 |
* |
38 |
* |
36 |
* @author Jaroslav Tulach |
39 |
* @author Jaroslav Tulach |
37 |
*/ |
40 |
*/ |
38 |
public final class CookieSet extends Object { |
41 |
public final class CookieSet extends Object implements Lookup.Provider { |
39 |
/** variable to allow effecient communication with NodeLookup, Node.Cookie or Class or Set */ |
42 |
/** variable to allow effecient communication with NodeLookup, Node.Cookie or Class or Set */ |
40 |
private static ThreadLocal<Object> QUERY_MODE = new ThreadLocal<Object>(); |
43 |
private static ThreadLocal<Object> QUERY_MODE = new ThreadLocal<Object>(); |
41 |
|
44 |
|
Lines 44-54
Link Here
|
44 |
|
47 |
|
45 |
/** set of listeners */ |
48 |
/** set of listeners */ |
46 |
private EventListenerList listeners = new EventListenerList(); |
49 |
private EventListenerList listeners = new EventListenerList(); |
|
|
50 |
|
51 |
/** potential instance content */ |
52 |
private final CookieSetLkp ic; |
53 |
/** lookup to use return from the cookie set, if initialized */ |
54 |
private Lookup lookup; |
47 |
|
55 |
|
48 |
/** Default constructor. */ |
56 |
/** Default constructor. */ |
49 |
public CookieSet() { |
57 |
public CookieSet() { |
|
|
58 |
this(null, null); |
59 |
} |
60 |
|
61 |
private CookieSet(CookieSetLkp ic, Lookup lookup) { |
62 |
this.ic = ic; |
63 |
this.lookup = lookup; |
64 |
} |
65 |
|
66 |
/** Factory method to create new, general purpose cookie set. |
67 |
* The <q>general purpose</q> means that it is possible to store |
68 |
* any object, into the cookie set and then obtain it using {@link #getLookup} |
69 |
* and queries on the returned {@link Lookup}. The before object can |
70 |
* be passed in if one wants to do a lazy initialization of the {@link CookieSet} |
71 |
* content. |
72 |
* |
73 |
* @param before the interface to support lazy initialization |
74 |
* @return new cookie set that can contain not only {@link Node.Cookie} but also |
75 |
* any plain old java object |
76 |
* @see #assign |
77 |
* @since 7.0 |
78 |
*/ |
79 |
public static CookieSet createGeneric(Before before) { |
80 |
CookieSetLkp al = new CookieSetLkp(before); |
81 |
return new CookieSet(al, al); |
82 |
} |
83 |
|
84 |
/** The lookup associated with this cookie set. Keeps track of |
85 |
* the same things that are in the cookie set, but presents them |
86 |
* as being inside the lookup. |
87 |
* |
88 |
* @return the lookup representing this cookie set |
89 |
* @since 7.0 |
90 |
*/ |
91 |
public Lookup getLookup() { |
92 |
synchronized (QUERY_MODE) { |
93 |
if (lookup == null) { |
94 |
AbstractNode an = new AbstractNode(this); |
95 |
lookup = an.getLookup(); |
96 |
} |
97 |
} |
98 |
return lookup; |
50 |
} |
99 |
} |
51 |
|
100 |
|
|
|
101 |
|
52 |
/** Add a new cookie to the set. If a cookie of the same |
102 |
/** Add a new cookie to the set. If a cookie of the same |
53 |
* <em>actual</em> (not representation!) class is already there, |
103 |
* <em>actual</em> (not representation!) class is already there, |
54 |
* it is replaced. |
104 |
* it is replaced. |
Lines 59-81
Link Here
|
59 |
* @param cookie cookie to add |
109 |
* @param cookie cookie to add |
60 |
*/ |
110 |
*/ |
61 |
public void add(Node.Cookie cookie) { |
111 |
public void add(Node.Cookie cookie) { |
|
|
112 |
addImpl((Object)cookie); |
113 |
fireChangeEvent(); |
114 |
} |
115 |
|
116 |
private void addImpl(Object cookie) { |
62 |
synchronized (this) { |
117 |
synchronized (this) { |
63 |
registerCookie(cookie.getClass(), cookie); |
118 |
registerCookie(cookie.getClass(), cookie); |
64 |
} |
119 |
} |
65 |
|
120 |
if (ic != null) { |
66 |
fireChangeEvent(); |
121 |
ic.add(cookie); |
|
|
122 |
} |
67 |
} |
123 |
} |
68 |
|
124 |
|
69 |
/** Remove a cookie from the set. |
125 |
/** Remove a cookie from the set. |
70 |
* @param cookie the cookie to remove |
126 |
* @param cookie the cookie to remove |
71 |
*/ |
127 |
*/ |
72 |
public void remove(Node.Cookie cookie) { |
128 |
public void remove(Node.Cookie cookie) { |
|
|
129 |
removeImpl((Object)cookie); |
130 |
fireChangeEvent(); |
131 |
} |
132 |
|
133 |
void removeImpl(Object cookie) { |
73 |
synchronized (this) { |
134 |
synchronized (this) { |
74 |
unregisterCookie(cookie.getClass(), cookie); |
135 |
unregisterCookie(cookie.getClass(), cookie); |
75 |
} |
136 |
} |
76 |
|
137 |
if (ic != null) { |
77 |
fireChangeEvent(); |
138 |
ic.remove(cookie); |
|
|
139 |
} |
78 |
} |
140 |
} |
|
|
141 |
|
142 |
/** Associates a given set of instances with |
143 |
*/ |
144 |
|
79 |
|
145 |
|
80 |
/** Get a cookie. |
146 |
/** Get a cookie. |
81 |
* |
147 |
* |
Lines 83-88
Link Here
|
83 |
* @return a cookie assignable to the representation class, or <code>null</code> if there is none |
149 |
* @return a cookie assignable to the representation class, or <code>null</code> if there is none |
84 |
*/ |
150 |
*/ |
85 |
public <T extends Node.Cookie> T getCookie(Class<T> clazz) { |
151 |
public <T extends Node.Cookie> T getCookie(Class<T> clazz) { |
|
|
152 |
if (ic != null) { |
153 |
ic.beforeLookupImpl(clazz); |
154 |
} |
155 |
|
86 |
Node.Cookie ret = null; |
156 |
Node.Cookie ret = null; |
87 |
Object queryMode = QUERY_MODE.get(); |
157 |
Object queryMode = QUERY_MODE.get(); |
88 |
|
158 |
|
Lines 90-102
Link Here
|
90 |
R r = findR(clazz); |
160 |
R r = findR(clazz); |
91 |
|
161 |
|
92 |
if (r == null) { |
162 |
if (r == null) { |
93 |
return null; |
163 |
if (queryMode == null || ic == null) { |
94 |
} |
164 |
return null; |
95 |
|
165 |
} |
96 |
ret = r.cookie(); |
166 |
} else { |
|
|
167 |
ret = r.cookie(); |
97 |
|
168 |
|
98 |
if (queryMode instanceof Set) { |
169 |
if (queryMode instanceof Set) { |
99 |
((Set) queryMode).addAll(map.keySet()); |
170 |
@SuppressWarnings("unchecked") |
|
|
171 |
Set<Class> keys = (Set<Class>)queryMode; |
172 |
keys.addAll(map.keySet()); |
173 |
} |
100 |
} |
174 |
} |
101 |
} |
175 |
} |
102 |
|
176 |
|
Lines 110-119
Link Here
|
110 |
// unwrap the cookie |
184 |
// unwrap the cookie |
111 |
ret = ((CookieEntry) ret).getCookie(true); |
185 |
ret = ((CookieEntry) ret).getCookie(true); |
112 |
} |
186 |
} |
|
|
187 |
} else if (ret == null) { |
188 |
if (ic != null && |
189 |
(!Node.Cookie.class.isAssignableFrom(clazz) || clazz == Node.Cookie.class) |
190 |
) { |
191 |
enhancedQueryMode(lookup, clazz); |
192 |
ret = null; |
193 |
} |
113 |
} |
194 |
} |
114 |
|
195 |
|
115 |
return clazz.cast(ret); |
196 |
return clazz.cast(ret); |
116 |
} |
197 |
} |
|
|
198 |
|
199 |
static void enhancedQueryMode(Lookup lookup, Class<?> clazz) { |
200 |
Object type = QUERY_MODE.get(); |
201 |
if (type != clazz) { |
202 |
return; |
203 |
} |
204 |
Collection<? extends Lookup.Item<?>> items = lookup.lookupResult(clazz).allItems(); |
205 |
if (items.size() == 0) { |
206 |
return; |
207 |
} |
208 |
AbstractLookup.Pair[] arr = new AbstractLookup.Pair[items.size()]; |
209 |
Iterator<? extends Lookup.Item> it = items.iterator(); |
210 |
for (int i = 0; i < arr.length; i++) { |
211 |
arr[i] = new PairWrap(it.next()); |
212 |
} |
213 |
QUERY_MODE.set(arr); |
214 |
} |
117 |
|
215 |
|
118 |
/** Add a listener to changes in the cookie set. |
216 |
/** Add a listener to changes in the cookie set. |
119 |
* @param l the listener to add |
217 |
* @param l the listener to add |
Lines 128-134
Link Here
|
128 |
public void removeChangeListener(ChangeListener l) { |
226 |
public void removeChangeListener(ChangeListener l) { |
129 |
listeners.remove(ChangeListener.class, l); |
227 |
listeners.remove(ChangeListener.class, l); |
130 |
} |
228 |
} |
131 |
|
229 |
|
|
|
230 |
|
132 |
/** Node lookup starts its non-important query. |
231 |
/** Node lookup starts its non-important query. |
133 |
*/ |
232 |
*/ |
134 |
static Object entryQueryMode(Class c) { |
233 |
static Object entryQueryMode(Class c) { |
Lines 149-160
Link Here
|
149 |
|
248 |
|
150 |
/** Exits query mode. |
249 |
/** Exits query mode. |
151 |
*/ |
250 |
*/ |
152 |
static org.openide.util.lookup.AbstractLookup.Pair exitQueryMode(Object prev) { |
251 |
static Collection<AbstractLookup.Pair> exitQueryMode(Object prev) { |
153 |
Object cookie = QUERY_MODE.get(); |
252 |
Object cookie = QUERY_MODE.get(); |
154 |
QUERY_MODE.set(prev); |
253 |
QUERY_MODE.set(prev); |
155 |
|
254 |
|
156 |
if (cookie instanceof CookieSet.CookieEntry) { |
255 |
if (cookie instanceof CookieSet.CookieEntry) { |
157 |
return new CookieEntryPair((CookieSet.CookieEntry) cookie); |
256 |
return Collections.singleton((AbstractLookup.Pair)new CookieEntryPair((CookieSet.CookieEntry) cookie)); |
|
|
257 |
} else if (cookie instanceof AbstractLookup.Pair[]) { |
258 |
return Arrays.asList((AbstractLookup.Pair[])cookie); |
158 |
} else { |
259 |
} else { |
159 |
return null; |
260 |
return null; |
160 |
} |
261 |
} |
Lines 174-180
Link Here
|
174 |
|
275 |
|
175 |
/** Fires change event |
276 |
/** Fires change event |
176 |
*/ |
277 |
*/ |
177 |
private void fireChangeEvent() { |
278 |
final void fireChangeEvent() { |
178 |
Object[] arr = listeners.getListenerList(); |
279 |
Object[] arr = listeners.getListenerList(); |
179 |
|
280 |
|
180 |
if (arr.length > 0) { |
281 |
if (arr.length > 0) { |
Lines 200-206
Link Here
|
200 |
* @param c class or null |
301 |
* @param c class or null |
201 |
* @param cookie cookie to attach |
302 |
* @param cookie cookie to attach |
202 |
*/ |
303 |
*/ |
203 |
private void registerCookie(Class<?> c, Node.Cookie cookie) { |
304 |
private void registerCookie(Class<?> c, Object cookie) { |
204 |
if ((c == null) || !Node.Cookie.class.isAssignableFrom(c)) { |
305 |
if ((c == null) || !Node.Cookie.class.isAssignableFrom(c)) { |
205 |
return; |
306 |
return; |
206 |
} |
307 |
} |
Lines 213-219
Link Here
|
213 |
map.put(c, r); |
314 |
map.put(c, r); |
214 |
} |
315 |
} |
215 |
|
316 |
|
216 |
r.add(cookie); |
317 |
r.add((Node.Cookie)cookie); |
217 |
|
318 |
|
218 |
registerCookie(c.getSuperclass(), cookie); |
319 |
registerCookie(c.getSuperclass(), cookie); |
219 |
|
320 |
|
Lines 230-236
Link Here
|
230 |
* @param c class or null |
331 |
* @param c class or null |
231 |
* @param cookie cookie to attach |
332 |
* @param cookie cookie to attach |
232 |
*/ |
333 |
*/ |
233 |
private void unregisterCookie(Class<?> c, Node.Cookie cookie) { |
334 |
private void unregisterCookie(Class<?> c, Object cookie) { |
234 |
if ((c == null) || !Node.Cookie.class.isAssignableFrom(c)) { |
335 |
if ((c == null) || !Node.Cookie.class.isAssignableFrom(c)) { |
235 |
return; |
336 |
return; |
236 |
} |
337 |
} |
Lines 242-248
Link Here
|
242 |
|
343 |
|
243 |
if (r != null) { |
344 |
if (r != null) { |
244 |
// remove the cookie |
345 |
// remove the cookie |
245 |
r.remove(cookie); |
346 |
r.remove((Node.Cookie)cookie); |
246 |
} |
347 |
} |
247 |
|
348 |
|
248 |
unregisterCookie(c.getSuperclass(), cookie); |
349 |
unregisterCookie(c.getSuperclass(), cookie); |
Lines 263-269
Link Here
|
263 |
synchronized (this) { |
364 |
synchronized (this) { |
264 |
registerCookie(cookieClass, new CookieEntry(factory, cookieClass)); |
365 |
registerCookie(cookieClass, new CookieEntry(factory, cookieClass)); |
265 |
} |
366 |
} |
266 |
|
367 |
if (ic != null) { |
|
|
368 |
ic.add(new FactAndClass(cookieClass, factory), C.INSTANCE); |
369 |
} |
267 |
fireChangeEvent(); |
370 |
fireChangeEvent(); |
268 |
} |
371 |
} |
269 |
|
372 |
|
Lines 279-284
Link Here
|
279 |
} |
382 |
} |
280 |
} |
383 |
} |
281 |
|
384 |
|
|
|
385 |
if (ic != null) { |
386 |
for (Class<? extends Node.Cookie> c : cookieClass) { |
387 |
ic.add(new FactAndClass(c, factory), C.INSTANCE); |
388 |
} |
389 |
} |
282 |
fireChangeEvent(); |
390 |
fireChangeEvent(); |
283 |
} |
391 |
} |
284 |
|
392 |
|
Lines 306-311
Link Here
|
306 |
} |
414 |
} |
307 |
} |
415 |
} |
308 |
} |
416 |
} |
|
|
417 |
if (ic != null) { |
418 |
ic.remove(new FactAndClass(cookieClass, factory), C.INSTANCE); |
419 |
} |
309 |
|
420 |
|
310 |
fireChangeEvent(); |
421 |
fireChangeEvent(); |
311 |
} |
422 |
} |
Lines 336-345
Link Here
|
336 |
} |
447 |
} |
337 |
} |
448 |
} |
338 |
} |
449 |
} |
|
|
450 |
|
451 |
if (ic != null) { |
452 |
for (Class<? extends Node.Cookie> c : cookieClass) { |
453 |
ic.remove(new FactAndClass(c, factory), C.INSTANCE); |
454 |
} |
455 |
} |
339 |
|
456 |
|
340 |
fireChangeEvent(); |
457 |
fireChangeEvent(); |
341 |
} |
458 |
} |
342 |
|
459 |
|
|
|
460 |
/** Removes all instances of clazz from the set and replaces them |
461 |
* with newly provided instance(s). |
462 |
* |
463 |
* @param clazz the root clazz for cookies to remove |
464 |
* @param instances the one or more instances to put into the lookup |
465 |
* |
466 |
* @since 7.0 |
467 |
*/ |
468 |
public <T> void assign(Class<? extends T> clazz, T... instances) { |
469 |
if (Node.Cookie.class.isAssignableFrom(clazz)) { |
470 |
Class<? extends Node.Cookie> cookieClazz = clazz.asSubclass(Node.Cookie.class); |
471 |
for(;;) { |
472 |
Node.Cookie cookie = getCookie(cookieClazz); |
473 |
if (cookie != null) { |
474 |
removeImpl(cookie); |
475 |
} else { |
476 |
break; |
477 |
} |
478 |
} |
479 |
for (T t : instances) { |
480 |
addImpl(t); |
481 |
} |
482 |
|
483 |
fireChangeEvent(); |
484 |
} else if (ic != null) { |
485 |
synchronized (this) { |
486 |
for (T t : instances) { |
487 |
registerCookie(t.getClass(), t); |
488 |
} |
489 |
} |
490 |
ic.replaceInstances(clazz, instances, this); |
491 |
} |
492 |
} |
493 |
|
494 |
/** Assignes a trigger that gets called everytime given class is about |
495 |
* to be queried. Can be used only for cookie set created with |
496 |
* {@link CookieSet#create(true)} and for classes that are not |
497 |
* subclasses of Node.Cookie. |
498 |
* |
499 |
* @param clazz the trigger class (not subclass of Node.Cookie) |
500 |
* @param run runnable to run when the task is queried |
501 |
* |
502 |
public void beforeLookup(Class<?> clazz, Runnable run) { |
503 |
if (Node.Cookie.class.isAssignableFrom(clazz) || clazz == Object.class) { |
504 |
throw new IllegalArgumentException("Too generic class: " + clazz); // NOI18N |
505 |
} |
506 |
if (ic == null) { |
507 |
throw new IllegalStateException("Can be used only on CookieSet.create(true)"); // NOI18N |
508 |
} |
509 |
ic.registerBeforeLookup(clazz, run); |
510 |
} |
511 |
*/ |
512 |
|
343 |
/** Finds a result in a map. |
513 |
/** Finds a result in a map. |
344 |
*/ |
514 |
*/ |
345 |
private R findR(Class<? extends Node.Cookie> c) { |
515 |
private R findR(Class<? extends Node.Cookie> c) { |
Lines 365-370
Link Here
|
365 |
*/ |
535 |
*/ |
366 |
<T extends Node.Cookie> T createCookie(Class<T> klass); |
536 |
<T extends Node.Cookie> T createCookie(Class<T> klass); |
367 |
} |
537 |
} |
|
|
538 |
|
539 |
/** Allows to update content of the cookie set just before |
540 |
* a query for a given class is made. |
541 |
*/ |
542 |
public interface Before { |
543 |
public void beforeLookup(Class<?> clazz); |
544 |
} |
368 |
|
545 |
|
369 |
/** Entry for one Cookie */ |
546 |
/** Entry for one Cookie */ |
370 |
private static class CookieEntry implements Node.Cookie { |
547 |
private static class CookieEntry implements Node.Cookie { |
Lines 405-459
Link Here
|
405 |
|
582 |
|
406 |
return ret; |
583 |
return ret; |
407 |
} |
584 |
} |
408 |
} |
585 |
} // end of CookieEntry |
409 |
// end of CookieEntry |
|
|
410 |
|
411 |
/** Pair that represents an entry. |
412 |
*/ |
413 |
private static final class CookieEntryPair extends org.openide.util.lookup.AbstractLookup.Pair { |
414 |
private CookieEntry entry; |
415 |
|
416 |
public CookieEntryPair(CookieEntry e) { |
417 |
this.entry = e; |
418 |
} |
419 |
|
420 |
protected boolean creatorOf(Object obj) { |
421 |
return obj == entry.getCookie(false); |
422 |
} |
423 |
|
424 |
public String getDisplayName() { |
425 |
return getId(); |
426 |
} |
427 |
|
428 |
public String getId() { |
429 |
return entry.klass.getName(); |
430 |
} |
431 |
|
432 |
public Object getInstance() { |
433 |
return entry.getCookie(true); |
434 |
} |
435 |
|
436 |
public Class getType() { |
437 |
return entry.klass; |
438 |
} |
439 |
|
440 |
protected boolean instanceOf(Class c) { |
441 |
return c.isAssignableFrom(entry.klass); |
442 |
} |
443 |
|
444 |
public int hashCode() { |
445 |
return entry.hashCode() + 5; |
446 |
} |
447 |
|
448 |
public boolean equals(Object obj) { |
449 |
if (obj instanceof CookieEntryPair) { |
450 |
return ((CookieEntryPair) obj).entry == entry; |
451 |
} |
452 |
|
453 |
return false; |
454 |
} |
455 |
} |
456 |
// end of CookieEntryPair |
457 |
|
586 |
|
458 |
/** Implementation of the result. |
587 |
/** Implementation of the result. |
459 |
*/ |
588 |
*/ |
Lines 513-518
Link Here
|
513 |
*/ |
642 |
*/ |
514 |
public Node.Cookie cookie() { |
643 |
public Node.Cookie cookie() { |
515 |
return ((cookies == null) || cookies.isEmpty()) ? null : cookies.get(0); |
644 |
return ((cookies == null) || cookies.isEmpty()) ? null : cookies.get(0); |
|
|
645 |
} |
646 |
} |
647 |
|
648 |
/** Pair that wraps another Lookup.Item |
649 |
*/ |
650 |
private static final class PairWrap extends AbstractLookup.Pair { |
651 |
private Lookup.Item<?> item; |
652 |
private boolean created; |
653 |
|
654 |
public PairWrap(Lookup.Item<?> item) { |
655 |
this.item = item; |
656 |
} |
657 |
|
658 |
protected boolean instanceOf(Class c) { |
659 |
Class<?> k = c; |
660 |
return k.isAssignableFrom(getType()); |
661 |
} |
662 |
|
663 |
protected boolean creatorOf(Object obj) { |
664 |
return created && getInstance() == obj; |
665 |
} |
666 |
|
667 |
public Object getInstance() { |
668 |
created = true; |
669 |
return item.getInstance(); |
670 |
} |
671 |
|
672 |
public Class<? extends Object> getType() { |
673 |
return item.getType(); |
674 |
} |
675 |
|
676 |
public String getId() { |
677 |
return item.getId(); |
678 |
} |
679 |
|
680 |
public String getDisplayName() { |
681 |
return item.getDisplayName(); |
682 |
} |
683 |
|
684 |
public int hashCode() { |
685 |
return 777 + item.hashCode(); |
686 |
} |
687 |
|
688 |
public boolean equals(Object object) { |
689 |
if (object instanceof PairWrap) { |
690 |
PairWrap p = (PairWrap)object; |
691 |
return item.equals(p.item); |
692 |
} |
693 |
return false; |
694 |
} |
695 |
} // end of PairWrap |
696 |
|
697 |
/** Pair that represents an entry. |
698 |
*/ |
699 |
private static final class CookieEntryPair extends AbstractLookup.Pair { |
700 |
private CookieEntry entry; |
701 |
|
702 |
public CookieEntryPair(CookieEntry e) { |
703 |
this.entry = e; |
704 |
} |
705 |
|
706 |
protected boolean creatorOf(Object obj) { |
707 |
return obj == entry.getCookie(false); |
708 |
} |
709 |
|
710 |
public String getDisplayName() { |
711 |
return getId(); |
712 |
} |
713 |
|
714 |
public String getId() { |
715 |
return entry.klass.getName(); |
716 |
} |
717 |
|
718 |
public Object getInstance() { |
719 |
return entry.getCookie(true); |
720 |
} |
721 |
|
722 |
public Class getType() { |
723 |
return entry.klass; |
724 |
} |
725 |
|
726 |
protected boolean instanceOf(Class c) { |
727 |
Class<?> k = c; |
728 |
return k.isAssignableFrom(entry.klass); |
729 |
} |
730 |
|
731 |
public int hashCode() { |
732 |
return entry.hashCode() + 5; |
733 |
} |
734 |
|
735 |
public boolean equals(Object obj) { |
736 |
if (obj instanceof CookieEntryPair) { |
737 |
return ((CookieEntryPair) obj).entry == entry; |
738 |
} |
739 |
|
740 |
return false; |
741 |
} |
742 |
} // end of CookieEntryPair |
743 |
|
744 |
private static final class FactAndClass { |
745 |
final Class<? extends Node.Cookie> clazz; |
746 |
final Factory factory; |
747 |
|
748 |
public FactAndClass(Class<? extends Node.Cookie> clazz, Factory factory) { |
749 |
this.clazz = clazz; |
750 |
this.factory = factory; |
751 |
} |
752 |
|
753 |
public int hashCode() { |
754 |
return clazz.hashCode() + factory.hashCode(); |
755 |
} |
756 |
|
757 |
public boolean equals(Object o) { |
758 |
if (o instanceof FactAndClass) { |
759 |
FactAndClass f = (FactAndClass)o; |
760 |
return f.clazz.equals(clazz) && f.factory == factory; |
761 |
} |
762 |
return false; |
763 |
} |
764 |
} |
765 |
|
766 |
private static class C implements InstanceContent.Convertor<FactAndClass, Node.Cookie> { |
767 |
static final C INSTANCE = new C(); |
768 |
|
769 |
|
770 |
public Node.Cookie convert(CookieSet.FactAndClass obj) { |
771 |
return obj.factory.createCookie(obj.clazz); |
772 |
} |
773 |
|
774 |
public Class<? extends Node.Cookie> type(CookieSet.FactAndClass obj) { |
775 |
return obj.clazz; |
776 |
} |
777 |
|
778 |
public String id(CookieSet.FactAndClass obj) { |
779 |
return obj.clazz.getName(); |
780 |
} |
781 |
|
782 |
public String displayName(CookieSet.FactAndClass obj) { |
783 |
return obj.clazz.getName(); |
516 |
} |
784 |
} |
517 |
} |
785 |
} |
518 |
} |
786 |
} |