blob: 6892b1b18341f401ec8c4f22591b31b26a6bb10d [file] [log] [blame]
Pierre De Ropfaca2892016-01-31 23:27:05 +00001package org.apache.felix.dm.lambda.impl;
2
3import java.util.Dictionary;
4import java.util.function.BiFunction;
5import java.util.function.Function;
6
7import org.apache.felix.dm.Component;
8import org.apache.felix.dm.DependencyManager;
9import org.apache.felix.dm.ServiceDependency;
10import org.apache.felix.dm.lambda.ServiceDependencyBuilder;
11import org.osgi.framework.ServiceReference;
12
13public class ServiceDependencyBuilderImpl<S> extends ServiceCallbacksBuilderImpl<S, ServiceDependencyBuilder<S>> implements ServiceDependencyBuilder<S> {
14 private final Class<S> m_serviceIface;
15 private final Component m_component;
16 private String m_filter;
17 private ServiceReference<S> m_ref;
18 private boolean m_required = true;
19 private String m_debug;
20 private boolean m_propagate;
21 private Object m_propagateInstance;
22 private String m_propagateMethod;
23 private Object m_defaultImpl;
24 private long m_timeout = -1;
25
26 public ServiceDependencyBuilderImpl(Component component, Class<S> service) {
27 super(service);
28 m_serviceIface = service;
29 m_component = component;
30 }
31
32 public ServiceDependencyBuilder<S> filter(String filter) {
33 m_filter = filter;
34 return this;
35 }
36
37 public ServiceDependencyBuilder<S> ref(ServiceReference<S> ref) {
38 m_ref = ref;
39 return this;
40 }
41
42 public ServiceDependencyBuilder<S> optional() {
43 return required(false);
44 }
45
46 public ServiceDependencyBuilder<S> required() {
47 return required(true);
48 }
49
50 public ServiceDependencyBuilder<S> required(boolean required) {
51 m_required = required;
52 return this;
53 }
54
55 public ServiceDependencyBuilder<S> debug(String label) {
56 m_debug = label;
57 return this;
58 }
59
60 public ServiceDependencyBuilder<S> propagate() {
61 return propagate(true);
62 }
63
64 public ServiceDependencyBuilder<S> propagate(boolean propagate) {
65 m_propagate = propagate;
66 return this;
67 }
68
69 public ServiceDependencyBuilder<S> propagate(Object instance, String method) {
70 m_propagateInstance = instance;
71 m_propagateMethod = method;
72 return this;
73 }
74
75 public ServiceDependencyBuilder<S> propagate(Function<ServiceReference<S>, Dictionary<String, Object>> propagate) {
76 Object wrappedCallback = new Object() {
77 @SuppressWarnings("unused")
78 Dictionary<String, Object> propagate(ServiceReference<S> ref) {
79 return propagate.apply(ref);
80 }
81 };
82 propagate(wrappedCallback, "propagate");
83 return this;
84 }
85
86 public ServiceDependencyBuilder<S> propagate(BiFunction<ServiceReference<S>, S, Dictionary<String, Object>> propagate) {
87 Object wrappedCallback = new Object() {
88 @SuppressWarnings("unused")
89 Dictionary<String, Object> propagate(ServiceReference<S> ref, S service) {
90 return propagate.apply(ref, service);
91 }
92 };
93 propagate(wrappedCallback, "propagate");
94 return this;
95 }
96
97 public ServiceDependencyBuilder<S> defImpl(Object defaultImpl) {
98 m_defaultImpl = defaultImpl;
99 return this;
100 }
101
102 public ServiceDependencyBuilder<S> timeout(long timeout) {
103 m_timeout = timeout;
104 return this;
105 }
106
107 // Build final ServiceDependency object.
108 @Override
109 public ServiceDependency build() {
110 DependencyManager dm = m_component.getDependencyManager();
111 if (m_ref != null && m_filter != null) {
112 throw new IllegalArgumentException("Can not set ref and filter at the same time");
113 }
114 ServiceDependency sd = m_timeout > -1 ? dm.createTemporalServiceDependency(m_timeout) : dm.createServiceDependency();
115 if (m_ref != null) {
116 sd.setService(m_serviceIface, m_ref);
117 } else {
118 sd.setService(m_serviceIface, m_filter);
119 }
120 sd.setRequired(m_required);
121 sd.setDefaultImplementation(m_defaultImpl);
122 if (m_debug != null) {
123 sd.setDebug(m_debug);
124 }
125 if (m_propagate) {
126 sd.setPropagate(true);
127 } else if (m_propagateInstance != null) {
128 if (m_propagateMethod == null) {
129 throw new IllegalArgumentException("propagate instance can't be null");
130 }
131 sd.setPropagate(m_propagateInstance, m_propagateMethod);
132 }
133 if (hasCallbacks()) {
134 sd.setCallbacks(m_callbackInstance, m_added, m_changed, m_removed, m_swapped);
135 } else if (hasRefs()) {
136 Object cb = createCallbackInstance();
137 sd.setCallbacks(cb, "add", "change", "remove", m_swapRefs.size() > 0 ? "swap" : null);
138 }
139
140 if (m_autoConfigField != null) {
141 sd.setAutoConfig(m_autoConfigField);
142 } else {
143 sd.setAutoConfig(m_autoConfig);
144 }
145 return sd;
146 }
147
148}