comparison src/org/tmatesoft/hg/util/Adaptable.java @ 356:91d75e1bac9f

Consistent approach to deal with adaptable objects. Give adaptable precedence over instanceof to allow conditional response when classes do implement desired interface
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Tue, 06 Dec 2011 14:25:52 +0100
parents 1a7a9a20e1f9
children
comparison
equal deleted inserted replaced
355:f2c11fe7f3e9 356:91d75e1bac9f
23 * @author TMate Software Ltd. 23 * @author TMate Software Ltd.
24 */ 24 */
25 public interface Adaptable { 25 public interface Adaptable {
26 26
27 <T> T getAdapter(Class<T> adapterClass); 27 <T> T getAdapter(Class<T> adapterClass);
28
29 class Factory<T> {
30
31 private final Class<T> adapterClass;
32
33 public Factory(Class<T> adapterClass) {
34 assert adapterClass != null;
35 this.adapterClass = adapterClass;
36 }
37
38 public T get(Object target) {
39 return getAdapter(target, adapterClass, null);
40 }
41
42 public T get(Object target, T defaultValue) {
43 return getAdapter(target, adapterClass, defaultValue);
44 }
45
46 /**
47 * Try to adapt target to specified class, resort to defaultValue when not possible.
48 * Instance lookup order is as follows: first, target is checked for being {@link Adaptable} and, if yes,
49 * consulted for adapter. Then, plain {@link Class#isInstance(Object) instanceof} checks if target itself is
50 * of desired type. {@link Adaptable} check comes first to allow classed that are in fact <code>instanceof</code>
51 * desired type to respond to the demand conditionally
52 *
53 * @param target object to adapt, <code>null</code> value, although meaningless, is tolerable.
54 * @param adapterClass desired target class
55 * @param defaultValue value to use if target cannot be adapted to desired class, may be <code>null</code>
56 * @return instance of the desired class
57 */
58 public static <C> C getAdapter(Object target, Class<C> adapterClass, C defaultValue) {
59 if (target instanceof Adaptable) {
60 return ((Adaptable) target).getAdapter(adapterClass);
61 }
62 if (adapterClass.isInstance(target)) {
63 return adapterClass.cast(target);
64 }
65 return defaultValue;
66 }
67 }
28 } 68 }