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 private static ComponentLocator componentLocator;
13
14 /**
15 * Sets the component locator to use. Should only be called once.
16 *
17 * @param loc The implementation to use
18 */
19 public static void setComponentLocator(ComponentLocator loc) {
20 ComponentLocator.componentLocator = loc;
21 }
22
23 /**
24 * @return True if intialized with a locator subclass
25 */
26 public static boolean isInitialized() {
27 return ComponentLocator.componentLocator != null;
28 }
29
30 /**
31 * Gets a component by its interface. Applications that don't support interface-based components will need to
32 * convert the interface name into a String
33 *
34 * @param iface The interface to find an implementation for
35 * @return The implementation
36 */
37 public static <T> T getComponent(Class<T> iface) {
38 return componentLocator.getComponentInternal(iface);
39 }
40
41 /**
42 * Gets a component by its interface and its Id.
43 *
44 * @param iface The interface to find an implementation for
45 * @param componentKey id of the component
46 * @return The implementation
47 */
48 public static <T> T getComponent(Class<T> iface, String componentKey) {
49 return componentLocator.getComponentInternal(iface, componentKey);
50 }
51
52 /**
53 * Gets the requested component, to be overridden for each application
54 *
55 * @param iface The interface to lookup
56 * @return The implementation
57 */
58 protected abstract <T> T getComponentInternal(Class<T> iface);
59
60 /**
61 * Gets the requested component, to be overridden for each application
62 *
63 * @param iface The interface to lookup
64 * @param componentKey key of the component
65 * @return The implementation
66 */
67 protected abstract <T> T getComponentInternal(Class<T> iface, String componentKey);
68
69 /**
70 * Gets a components by interface. Applications that don't support interface-based components will need to
71 * covert the interface name into a String
72 *
73 * @param iface The interface to find an implementation for
74 * @return The implementation
75 */
76 public static <T> Collection<T> getComponents(Class<T> iface) {
77 return componentLocator.getComponentsInternal(iface);
78 }
79
80 protected abstract <T> Collection<T> getComponentsInternal(Class<T> iface);
81
82 /**
83 * Converts the interface name into a String key
84 *
85 * @param iface The interface to convert
86 * @return The String key to use to find the implementation
87 */
88 protected String convertClassToName(Class iface) {
89 return Character.toLowerCase(iface.getSimpleName().charAt(0)) + iface.getSimpleName()
90 .substring(1);
91 }
92
93 }