1 package com.atlassian.sal.api.component;
2
3 import java.util.Collection;
4
5 /**
6 * Unified interface to access components via their interface. Calling {@link #getComponent(Class)} will work the
7 * same in any application, regardless of underlying dependency injection system used.
8 *
9 * @since 2.0
10 */
11 public abstract class ComponentLocator
12 {
13 private static ComponentLocator componentLocator;
14
15 /**
16 * Sets the component locator to use. Should only be called once.
17 *
18 * @param loc The implementation to use
19 */
20 public static void setComponentLocator(ComponentLocator loc)
21 {
22 ComponentLocator.componentLocator = loc;
23 }
24
25 /**
26 * @return True if intialized with a locator subclass
27 */
28 public static boolean isInitialized()
29 {
30 return ComponentLocator.componentLocator != null;
31 }
32
33 /**
34 * Gets a component by its interface. Applications that don't support interface-based components will need to
35 * convert the interface name into a String
36 *
37 * @param iface The interface to find an implementation for
38 * @return The implementation
39 */
40 public static <T> T getComponent(Class<T> iface)
41 {
42 return componentLocator.getComponentInternal(iface);
43 }
44
45 /**
46 * Gets a component by its interface and its Id.
47 *
48 * @param iface The interface to find an implementation for
49 * @param componentKey id of the component
50 * @return The implementation
51 */
52 public static <T> T getComponent(Class<T> iface, String componentKey)
53 {
54 return componentLocator.getComponentInternal(iface, componentKey);
55 }
56
57 /**
58 * Gets the requested component, to be overridden for each application
59 *
60 * @param iface The interface to lookup
61 * @return The implementation
62 */
63 protected abstract <T> T getComponentInternal(Class<T> iface);
64
65 /**
66 * Gets the requested component, to be overridden for each application
67 *
68 * @param iface The interface to lookup
69 * @param componentKey key of the component
70 * @return The implementation
71 */
72 protected abstract <T> T getComponentInternal(Class<T> iface, String componentKey);
73
74 /**
75 * Gets a components by interface. Applications that don't support interface-based components will need to
76 * covert the interface name into a String
77 *
78 * @param iface The interface to find an implementation for
79 * @return The implementation
80 */
81 public static <T> Collection<T> getComponents(Class<T> iface)
82 {
83 return componentLocator.getComponentsInternal(iface);
84 }
85
86 protected abstract <T> Collection<T> getComponentsInternal(Class<T> iface);
87
88 /**
89 * Converts the interface name into a String key
90 *
91 * @param iface The interface to convert
92 * @return The String key to use to find the implementation
93 */
94 protected String convertClassToName(Class iface)
95 {
96 return Character.toLowerCase(iface.getSimpleName().charAt(0)) + iface.getSimpleName()
97 .substring(1);
98 }
99
100 }