2 * Copyright 2005-2010 the original author or authors.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package org.wamblee.system.spring;
18 import junit.framework.TestCase;
20 import org.wamblee.io.ClassPathResource;
22 import org.wamblee.system.core.DefaultProvidedInterface;
23 import org.wamblee.system.core.DefaultRequiredInterface;
24 import org.wamblee.system.core.DefaultScope;
25 import org.wamblee.system.core.ProvidedInterface;
26 import org.wamblee.system.core.RequiredInterface;
27 import org.wamblee.system.core.Scope;
28 import org.wamblee.system.core.SystemAssemblyException;
30 import org.wamblee.test.EventTracker;
32 import java.io.IOException;
34 import java.util.HashMap;
35 import java.util.List;
37 import java.util.Properties;
44 public class SpringComponentTest extends TestCase {
45 private static final String HELLO_SERVICE_SPRING_XML = "test.org.wamblee.system.spring.xml";
47 private static final String HELLO_SERVICE_SPRING_WITH_REQS_XML = "test.org.wamblee.system.springWithRequirements.xml";
49 private static final String HELLO_SERVICE_SPRING_WITH_PROPERTIES_XML = "test.org.wamblee.system.springWithProperties.xml";
51 private static final String HELLO_SERVICE_SPRING_WITH_PROPERTIES_XML2 = "test.org.wamblee.system.springWithProperties2.xml";
53 private static final String PROPERTY_FILE = "test.org.wamblee.system.spring.properties";
55 private static EventTracker<String> EVENT_TRACKER;
57 private Scope externalScope;
59 public static EventTracker<String> getEventTracker() {
64 protected void setUp() throws Exception {
66 EVENT_TRACKER = new EventTracker<String>();
67 externalScope = new DefaultScope(new ProvidedInterface[0]);
70 public void testBlackboxSystem() {
71 SpringComponent system = new SpringComponent("system",
72 new String[] { HELLO_SERVICE_SPRING_XML },
73 new HashMap<String, ProvidedInterface>(),
74 new HashMap<RequiredInterface, String>());
76 Scope runtime = system.start(externalScope);
77 assertEquals(0, externalScope.getProvidedInterfaces().size());
82 public void testOneProvidedService() {
83 Map<String, ProvidedInterface> provided = new HashMap<String, ProvidedInterface>();
84 provided.put("helloService", new DefaultProvidedInterface("hello",
87 SpringComponent system = new SpringComponent("system",
88 new String[] { HELLO_SERVICE_SPRING_XML }, provided,
89 new HashMap<RequiredInterface, String>());
90 Scope runtime = system.start(externalScope);
91 List<ProvidedInterface> services = runtime.getProvidedInterfaces();
93 assertEquals(1, services.size());
95 Object service = runtime.getInterfaceImplementation(services.get(0),
97 assertTrue(service instanceof HelloService);
99 // BUG; Provided services should be made available in the external
101 Object service2 = externalScope.getInterfaceImplementation(provided
102 .get("helloService"), Object.class);
103 assertSame(service, service2);
105 assertEquals("Hello world!", ((HelloService) service).say());
106 system.stop(runtime);
109 public void testWithProperties() throws IOException {
110 Map<String, ProvidedInterface> provided = new HashMap<String, ProvidedInterface>();
111 provided.put("helloService", new DefaultProvidedInterface("hello",
112 HelloService.class));
114 SpringComponent system = new SpringComponent("system",
115 new String[] { HELLO_SERVICE_SPRING_WITH_PROPERTIES_XML },
116 provided, new HashMap<RequiredInterface, String>());
117 Properties props = new Properties();
118 props.load(new ClassPathResource(PROPERTY_FILE).getInputStream());
119 system.addProperties(props);
121 Scope scope = system.start(externalScope);
122 // BUG: Hello service was constructed multiple times. Once with the
123 // unprocessed property
124 // and another time with the processed property.
125 assertEquals(1, EVENT_TRACKER.getEventCount());
127 List<ProvidedInterface> services = scope.getProvidedInterfaces();
128 assertEquals("Property Value", scope.getInterfaceImplementation(
129 services.get(0), HelloService.class).say());
132 public void testWithPropertiesAsBean() throws IOException {
133 Map<String, ProvidedInterface> provided = new HashMap<String, ProvidedInterface>();
134 provided.put("helloService", new DefaultProvidedInterface("hello",
135 HelloService2.class));
137 SpringComponent system = new SpringComponent("system",
138 new String[] { HELLO_SERVICE_SPRING_WITH_PROPERTIES_XML2 },
139 provided, new HashMap<RequiredInterface, String>());
140 Properties props = new Properties();
141 props.load(new ClassPathResource(PROPERTY_FILE).getInputStream());
142 system.addProperties("properties", props);
144 Scope scope = system.start(externalScope);
146 List<ProvidedInterface> services = scope.getProvidedInterfaces();
148 Properties props2 = scope.getInterfaceImplementation(services.get(0),
149 HelloService2.class).getProperties();
150 assertEquals(props, props2);
153 public void testWithMissingRequirement() {
155 SpringComponent system = new SpringComponent("system",
156 new String[] { HELLO_SERVICE_SPRING_WITH_REQS_XML },
157 new HashMap<String, ProvidedInterface>(),
158 new HashMap<RequiredInterface, String>());
159 system.start(externalScope);
160 } catch (SystemAssemblyException e) {
161 // e.printStackTrace();
168 public void testWithRequirement() {
169 Map<RequiredInterface, String> required = new HashMap<RequiredInterface, String>();
170 required.put(new DefaultRequiredInterface("hello", HelloService.class),
173 SpringComponent system = new SpringComponent("system",
174 new String[] { HELLO_SERVICE_SPRING_WITH_REQS_XML },
175 new HashMap<String, ProvidedInterface>(), required);
177 HelloService helloObject = new HelloService("ladida");
178 ProvidedInterface helloService = new DefaultProvidedInterface("hello",
180 Scope scope = new DefaultScope(new ProvidedInterface[] { helloService });
181 scope.publishInterface(helloService, helloObject);
182 system.getRequiredInterfaces().get(0).setProvider(helloService);
184 Scope runtime = system.start(scope);
185 system.stop(runtime);
188 public void testWithRequirementAndProvidedService() {
189 Map<RequiredInterface, String> required = new HashMap<RequiredInterface, String>();
190 required.put(new DefaultRequiredInterface("hello", HelloService.class),
193 Map<String, ProvidedInterface> provided = new HashMap<String, ProvidedInterface>();
194 provided.put("blaService", new DefaultProvidedInterface("bla",
197 SpringComponent system = new SpringComponent("system",
198 new String[] { HELLO_SERVICE_SPRING_WITH_REQS_XML }, provided,
201 HelloService helloObject = new HelloService("ladida");
202 ProvidedInterface helloService = new DefaultProvidedInterface("hello",
204 Scope scope = new DefaultScope(new ProvidedInterface[] { helloService });
205 scope.publishInterface(helloService, helloObject);
206 system.getRequiredInterfaces().get(0).setProvider(helloService);
208 Scope runtime = system.start(scope);
209 ProvidedInterface started = runtime.getProvidedInterfaces().get(0);
211 Object impl = runtime.getInterfaceImplementation(started,
214 assertTrue(impl instanceof BlaService);
215 assertEquals("ladida", ((BlaService) impl).execute());
216 system.stop(runtime);
220 * Tests a scenario where a subclass of SpringComponent adds a new provided
221 * interface where the interface is provided by the subclass itself and not
222 * by the spring configs inside.
224 public void testWithProvidedFromSubClassNotFromConfig() {
225 Map<String, ProvidedInterface> provided = new HashMap<String, ProvidedInterface>();
226 provided.put("helloService", new DefaultProvidedInterface("hello",
227 HelloService.class));
229 SubSpringComponent system = new SubSpringComponent("system",
230 new String[] { HELLO_SERVICE_SPRING_XML }, provided,
231 new HashMap<RequiredInterface, String>());
233 Scope runtime = system.start(externalScope);
234 List<ProvidedInterface> services = runtime.getProvidedInterfaces();
236 assertEquals(2, services.size());
238 Object service = runtime.getInterfaceImplementation(services.get(0),
240 assertTrue(service instanceof HelloService);
242 // BUG; Provided services should be made available in the external
244 Object service2 = externalScope.getInterfaceImplementation(provided
245 .get("helloService"), Object.class);
246 assertSame(service, service2);
248 Object floatsvc = externalScope.getInterfaceImplementation(system
249 .getProvidedInterfaces().get(1), Object.class);
250 assertTrue(floatsvc instanceof Float);
251 assertTrue((((Float) floatsvc).floatValue() - 100.345f) < 0.00001);
253 assertEquals("Hello world!", ((HelloService) service).say());
254 system.stop(runtime);
258 * Tests the spring component with an additional requirement from the
259 * subclass which is not required by the spring config files inside.
261 public void testWithRequirementFromSubClass() {
262 Map<RequiredInterface, String> required = new HashMap<RequiredInterface, String>();
263 required.put(new DefaultRequiredInterface("hello", HelloService.class),
266 SpringComponent system = new SubSpringComponent2("system",
267 new String[] { HELLO_SERVICE_SPRING_WITH_REQS_XML },
268 new HashMap<String, ProvidedInterface>(), required);
270 HelloService helloObject = new HelloService("ladida");
271 ProvidedInterface helloService = new DefaultProvidedInterface("hello",
274 ProvidedInterface floatService = new DefaultProvidedInterface("float",
277 Scope scope = new DefaultScope(new ProvidedInterface[] { helloService });
278 scope.publishInterface(helloService, helloObject);
279 scope.publishInterface(floatService, 100.234f);
280 system.getRequiredInterfaces().get(0).setProvider(helloService);
281 system.getRequiredInterfaces().get(1).setProvider(floatService);
283 Scope runtime = system.start(scope);
284 system.stop(runtime);
286 assertEquals(100.234f,
287 ((Float) runtime.get("floatValue")).floatValue(), 0.0001f);