1 package it.allproducts;
2
3 import com.atlassian.plugin.spring.scanner.annotation.export.ExportAsService;
4 import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport;
5 import com.google.common.base.Joiner;
6 import com.google.common.collect.ImmutableList;
7 import org.hamcrest.Description;
8 import org.hamcrest.Matcher;
9 import org.hamcrest.Matchers;
10 import org.hamcrest.TypeSafeMatcher;
11 import org.springframework.stereotype.Component;
12
13 import java.util.Collection;
14 import java.util.List;
15 import java.util.stream.Collectors;
16
17 import static java.util.Collections.emptyList;
18 import static org.hamcrest.Matchers.equalTo;
19
20
21
22
23
24
25
26
27 public class ComponentExpectations {
28
29 public static final ComponentExpectations COMMON = new ComponentExpectations();
30
31 public static final ComponentExpectations REFAPP = new ComponentExpectations(
32
33 component("com.atlassian.plugin.spring.scanner.test.product.refapp.RefappOnlyComponent"),
34
35 componentImport("com.atlassian.refapp.api.ConnectionProvider"),
36
37 ImmutableList.of(autoAddedComponent("org.springframework.context.event.internalEventListenerFactory"),
38 autoAddedComponent("org.springframework.context.event.internalEventListenerProcessor")));
39
40 public static final ComponentExpectations CONFLUENCE = new ComponentExpectations(
41
42 component("com.atlassian.plugin.spring.scanner.test.product.confluence.ConfluenceOnlyComponent"),
43
44 componentImport("com.atlassian.confluence.api.service.content.ContentService"),
45
46 ImmutableList.of(autoAddedComponent("org.springframework.context.event.internalEventListenerFactory"),
47 autoAddedComponent("org.springframework.context.event.internalEventListenerProcessor")));
48
49 public static final ComponentExpectations JIRA_CLOUD = new ComponentExpectations(
50
51 component("com.atlassian.plugin.spring.scanner.test.product.jira.JiraOnlyComponent"),
52
53 componentImport("com.atlassian.jira.bc.issue.comment.CommentService"),
54
55 ImmutableList.of(autoAddedComponent("org.springframework.context.event.internalEventListenerFactory"),
56 autoAddedComponent("org.springframework.context.event.internalEventListenerProcessor")));
57
58 public static final ComponentExpectations JIRA_BTF = new ComponentExpectations(
59
60 component("com.atlassian.plugin.spring.scanner.test.product.jira.JiraOnlyComponent"),
61
62 componentImport("com.atlassian.jira.bc.issue.comment.CommentService"));
63
64 public static final ComponentExpectations BAMBOO = new ComponentExpectations(
65
66 component("com.atlassian.plugin.spring.scanner.test.product.bamboo.BambooOnlyComponent"),
67
68 componentImport("com.atlassian.bamboo.build.BuildExecutionManager"));
69
70 public static final ComponentExpectations STASH = new ComponentExpectations(
71
72 component("com.atlassian.plugin.spring.scanner.test.product.stash.StashOnlyComponent"),
73
74 componentImport("com.atlassian.stash.repository.RepositoryService"));
75
76 public static final ComponentExpectations BITBUCKET = new ComponentExpectations(
77
78 component("com.atlassian.plugin.spring.scanner.test.product.bitbucket.BitbucketOnlyComponent"),
79
80 componentImport("com.atlassian.bitbucket.repository.RepositoryService"));
81
82 public static final ComponentExpectations FECRU = new ComponentExpectations(
83
84 component("com.atlassian.plugin.spring.scanner.test.product.fecru.FecruOnlyComponent"),
85
86 componentImport("com.atlassian.fisheye.spi.services.RepositoryService"));
87
88 private final List<ExpectedComponent> productSpecificScannerCreatedComponents;
89 private final List<ExpectedAutoAddedComponent> productSpecificAutoAddedComponents;
90 private final List<ExpectedComponentImport> productSpecificComponentImports;
91
92 private ComponentExpectations(ExpectedComponent productSpecificComponent,
93 ExpectedComponentImport productSpecificComponentImport,
94 List<ExpectedAutoAddedComponent> productSpecificAutoAddedComponents) {
95 this.productSpecificScannerCreatedComponents = ImmutableList.of(productSpecificComponent);
96 this.productSpecificComponentImports = ImmutableList.of(productSpecificComponentImport);
97 this.productSpecificAutoAddedComponents = productSpecificAutoAddedComponents;
98 }
99
100 private ComponentExpectations(ExpectedComponent productSpecificComponent,
101 ExpectedComponentImport productSpecificComponentImport) {
102 this(productSpecificComponent, productSpecificComponentImport, emptyList());
103 }
104
105 private ComponentExpectations() {
106 this.productSpecificScannerCreatedComponents = emptyList();
107 this.productSpecificComponentImports = emptyList();
108 this.productSpecificAutoAddedComponents = emptyList();
109 }
110
111
112
113
114 public List<ExpectedComponent> getExpectedScannerCreatedComponents() {
115 return ImmutableList.<ExpectedComponent>builder()
116
117 .add(component("com.atlassian.plugin.spring.scanner.test.ConsumingInternalOnlyComponent"))
118 .add(component("com.atlassian.plugin.spring.scanner.test.imported.ConsumingMixedComponents"))
119 .add(component("com.atlassian.plugin.spring.scanner.test.exported.ExposedAsAServiceComponent"))
120 .add(component("com.atlassian.plugin.spring.scanner.test.exported.ExposedAsAServiceComponentWithSpecifiedInterface"))
121 .add(component("com.atlassian.plugin.spring.scanner.test.exported.ExposedAsAServiceComponentWithMultipleSpecifiedInterfaces"))
122 .add(component("com.atlassian.plugin.spring.scanner.test.exported.ExposedAsADevServiceComponent"))
123 .add(component("com.atlassian.plugin.spring.scanner.test.exported.ExportExternalComponentsViaFields$ExternalServiceViaField"))
124 .add(component("com.atlassian.plugin.spring.scanner.test.exported.ExportExternalComponentsViaFields$ExternalDevServiceViaField"))
125 .add(component("com.atlassian.plugin.spring.scanner.test.InternalComponent"))
126 .add(component("com.atlassian.plugin.spring.scanner.test.InternalComponentTwo"))
127 .add(component("com.atlassian.plugin.spring.scanner.test.NamedComponent", "namedComponent"))
128 .add(component("com.atlassian.plugin.spring.scanner.test.imported.NamedConsumingMixedComponents", "namedMixed"))
129 .add(component("com.atlassian.plugin.spring.scanner.test.OuterClass$InnerClass$InnerComponent$EvenMoreInnerComponent"))
130 .add(component("com.atlassian.plugin.spring.scanner.test.OuterClass$InnerClass$InnerComponent"))
131 .add(component("com.atlassian.plugin.spring.scanner.test.OuterClass$OuterComponent"))
132 .add(component("com.atlassian.plugin.spring.scanner.test.primary.BaseImplementation"))
133 .add(component("com.atlassian.plugin.spring.scanner.test.primary.PrimaryImplementation"))
134 .add(component("com.atlassian.plugin.spring.scanner.test.primary.ConsumingPrimaryComponentByInterface"))
135
136 .add(component("com.atlassian.plugin.spring.scanner.test.fields.ComponentWithFields"))
137
138 .add(component("com.atlassian.plugin.spring.scanner.test.spring.ControllerComponent"))
139 .add(component("com.atlassian.plugin.spring.scanner.test.spring.RepositoryComponent"))
140 .add(component("com.atlassian.plugin.spring.scanner.test.spring.ServiceComponent"))
141
142 .add(component("com.atlassian.plugin.spring.scanner.test.jsr.JsrComponent"))
143
144 .add(component("com.atlassian.plugin.spring.scanner.external.component.ExternalJarComponentOne"))
145 .add(component("com.atlassian.plugin.spring.scanner.external.component.ExternalJarComponentTwo"))
146 .add(component("com.atlassian.plugin.spring.scanner.external.component.ExternalJarComponentComposite"))
147 .add(component("com.atlassian.plugin.spring.scanner.external.notannotated.NotAnnotatedExternalJarClass"))
148
149 .add(component("com.atlassian.plugin.spring.scanner.external.component.TransitiveJarComponent1"))
150 .add(component("com.atlassian.plugin.spring.scanner.external.component.TransitiveJarComponent2"))
151 .add(component("com.atlassian.plugin.spring.scanner.external.component.TransitiveJarComponentComposite"))
152
153 .add(component("com.atlassian.plugin.spring.scanner.test.imported.ConsumesExternalComponentsViaConstructor"))
154 .add(component("com.atlassian.plugin.spring.scanner.test.imported.ConsumesExternalComponentsViaFields"))
155
156
157 .add(component("com.atlassian.plugin.spring.scanner.test.dynamic.DynamicContextManager"))
158 .add(component("com.atlassian.plugin.spring.scanner.test.registry.BeanLister"))
159
160
161 .add(component("com.atlassian.plugin.spring.scanner.test.moduletype.BasicModuleTypeFactory"))
162
163 .add(component("com.atlassian.plugin.osgi.bridge.external.SpringHostContainer"))
164 .build();
165 }
166
167
168
169
170 public List<ExpectedAutoAddedComponent> getExpectedAutoAddedComponents() {
171 return ImmutableList.<ExpectedAutoAddedComponent>builder()
172
173 .add(autoAddedComponent("devModeBeanInitialisationLoggerBeanPostProcessor", "com.atlassian.plugin.spring.scanner.runtime.impl.DevModeBeanInitialisationLoggerBeanPostProcessor"))
174 .add(autoAddedComponent("serviceExportBeanPostProcessor", "com.atlassian.plugin.spring.scanner.runtime.impl.ServiceExporterBeanPostProcessor"))
175 .add(autoAddedComponent("componentImportBeanFactoryPostProcessor", "com.atlassian.plugin.spring.scanner.runtime.impl.ComponentImportBeanFactoryPostProcessor"))
176
177
178 .add(autoAddedComponent("org.springframework.context.annotation.internalAutowiredAnnotationProcessor", "org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"))
179 .add(autoAddedComponent("org.springframework.context.annotation.internalCommonAnnotationProcessor", "org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"))
180 .add(autoAddedComponent("org.springframework.context.annotation.internalConfigurationAnnotationProcessor", "org.springframework.context.annotation.ConfigurationClassPostProcessor"))
181 .add(autoAddedComponent("org.springframework.context.annotation.internalRequiredAnnotationProcessor", "org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"))
182 .build();
183 }
184
185
186
187
188 public List<ExpectedComponentImport> getExpectedScannerCreatedComponentImports() {
189 return ImmutableList.<ExpectedComponentImport>builder()
190 .add(componentImport("com.atlassian.event.api.EventPublisher"))
191 .add(componentImport("com.atlassian.plugin.PluginAccessor"))
192 .add(componentImport("com.atlassian.plugin.module.ModuleFactory"))
193 .add(componentImport("com.atlassian.plugin.spring.scanner.test.otherplugin.ServiceExportedFromAnotherPlugin"))
194
195 .add(componentImport("com.atlassian.plugin.spring.scanner.test.otherplugin.ServiceTwoExportedFromAnotherPlugin"))
196 .build();
197 }
198
199
200
201
202 public List<ExpectedServiceExport> getExpectedScannerCreatedExports() {
203 return ImmutableList.<ExpectedServiceExport>builder()
204
205 .add(serviceExport(
206 "com.atlassian.plugin.spring.scanner.test.exported.ExposedAsAServiceComponent",
207 ImmutableList.of(
208 "com.atlassian.plugin.spring.scanner.test.exported.ExposedAsAServiceComponentInterface")))
209 .add(serviceExport(
210 "com.atlassian.plugin.spring.scanner.test.exported.ExposedAsAServiceComponentWithSpecifiedInterface",
211 ImmutableList.of(
212 "com.atlassian.plugin.spring.scanner.test.exported.ExposedAsAServiceComponentInterfaceThree"),
213 ImmutableList.of(
214 "com.atlassian.plugin.spring.scanner.test.exported.ExposedAsAServiceComponentInterfaceThree")))
215 .add(serviceExport(
216 "com.atlassian.plugin.spring.scanner.test.exported.ExposedAsAServiceComponentWithMultipleSpecifiedInterfaces",
217 ImmutableList.of(
218 "com.atlassian.plugin.spring.scanner.test.exported.ExposedAsAServiceComponentInterface",
219 "com.atlassian.plugin.spring.scanner.test.exported.ExposedAsAServiceComponentInterfaceTwo"),
220 ImmutableList.of(
221 "com.atlassian.plugin.spring.scanner.test.exported.ExposedAsAServiceComponentInterface",
222 "com.atlassian.plugin.spring.scanner.test.exported.ExposedAsAServiceComponentInterfaceTwo")))
223 .add(serviceExport(
224 "com.atlassian.plugin.spring.scanner.test.exported.ExportExternalComponentsViaFields$ExternalServiceViaField",
225 ImmutableList.of(
226 "com.atlassian.plugin.spring.scanner.test.exported.ExportExternalComponentsViaFields$ExternalServiceViaField")))
227
228
229 .add(serviceExport("com.atlassian.plugin.spring.scanner.test.moduletype.BasicModuleTypeFactory",
230 ImmutableList.of(
231 "com.atlassian.plugin.osgi.external.ListableModuleDescriptorFactory"),
232 ImmutableList.of(
233 "com.atlassian.plugin.osgi.external.ListableModuleDescriptorFactory")))
234 .build();
235 }
236
237
238
239
240 public List<ExpectedServiceExport> getExpectedScannerCreatedDevExports() {
241 return ImmutableList.of(
242 serviceExport(
243 "com.atlassian.plugin.spring.scanner.test.exported.ExposedAsADevServiceComponent",
244 ImmutableList.of(
245 "com.atlassian.plugin.spring.scanner.test.exported.ExposedAsADevServiceComponent")),
246 serviceExport(
247 "com.atlassian.plugin.spring.scanner.test.exported.ExportExternalComponentsViaFields$ExternalDevServiceViaField",
248 ImmutableList.of(
249 "com.atlassian.plugin.spring.scanner.test.exported.ExportExternalComponentsViaFields$ExternalDevServiceViaField")));
250 }
251
252
253
254
255 public List<ExpectedServiceExport> getExpectedAutoAddedExports() {
256 return ImmutableList.of(
257
258 serviceExport(null,
259 ImmutableList.<String>builder()
260 .add("org.eclipse.gemini.blueprint.context.DelegatedExecutionOsgiBundleApplicationContext")
261 .add("org.eclipse.gemini.blueprint.context.ConfigurableOsgiBundleApplicationContext")
262 .add("org.springframework.context.ConfigurableApplicationContext")
263 .add("org.springframework.context.ApplicationContext")
264 .add("org.springframework.context.Lifecycle")
265 .add("java.io.Closeable")
266 .add("org.springframework.beans.factory.ListableBeanFactory")
267 .add("org.springframework.beans.factory.HierarchicalBeanFactory")
268 .add("org.springframework.context.MessageSource")
269 .add("org.springframework.context.ApplicationEventPublisher")
270 .add("org.springframework.core.io.support.ResourcePatternResolver")
271 .add("org.springframework.beans.factory.BeanFactory")
272 .add("org.springframework.core.io.ResourceLoader")
273 .add("java.lang.AutoCloseable")
274 .add("org.springframework.beans.factory.DisposableBean")
275 .build()));
276 }
277
278
279
280
281 public List<ExpectedComponent> getExpectedScannerCreatedDynamicComponents() {
282 return ImmutableList.of(component("com.atlassian.plugin.spring.scanner.test.dynamic.DynamicComponent"));
283 }
284
285
286
287
288 public List<ExpectedComponentImport> getExpectedScannerCreatedDynamicComponentImports() {
289 return ImmutableList.of(
290 componentImport("com.atlassian.plugin.spring.scanner.test.otherplugin.DynamicallyImportedServiceFromAnotherPlugin"));
291 }
292
293
294
295
296 public List<ExpectedComponent> getProductSpecificScannerCreatedComponents() {
297 return productSpecificScannerCreatedComponents;
298 }
299
300
301
302
303 public List<ExpectedComponentImport> getProductSpecificScannerCreatedComponentImports() {
304 return productSpecificComponentImports;
305 }
306
307
308
309
310 public List<ExpectedAutoAddedComponent> getProductSpecificAutoAddedComponents() {
311 return productSpecificAutoAddedComponents;
312 }
313
314 private static String toComponentName(String classNameWithPackage) {
315 final String simpleClassName = classNameWithPackage.replaceAll(".*\\.", "").replace('$', '.');
316 return simpleClassName.substring(0, 1).toLowerCase() + simpleClassName.substring(1);
317 }
318
319 private static ExpectedComponent component(String implClass) {
320 return new ExpectedComponent(implClass, null);
321 }
322
323 private static ExpectedComponent component(String implClass, String specifiedName) {
324 return new ExpectedComponent(implClass, specifiedName);
325 }
326
327 private static ExpectedComponentImport componentImport(String iface) {
328 return new ExpectedComponentImport(iface);
329 }
330
331 private static ExpectedAutoAddedComponent autoAddedComponent(String name) {
332 return new ExpectedAutoAddedComponent(name);
333 }
334
335 private static ExpectedAutoAddedComponent autoAddedComponent(String name, String implClass) {
336 return new ExpectedAutoAddedComponent(name, implClass);
337 }
338
339 private static ExpectedServiceExport serviceExport(String implClass, List<String> expectedExportedInterfaces) {
340 return new ExpectedServiceExport(implClass, expectedExportedInterfaces, null);
341 }
342
343 private static ExpectedServiceExport serviceExport(String implClass, List<String> expectedExportedInterfaces, List<String> specifiedInterfaces) {
344 return new ExpectedServiceExport(implClass, expectedExportedInterfaces, specifiedInterfaces);
345 }
346
347 public static abstract class AbstractExpectedComponent {
348
349
350
351
352
353 public abstract Matcher<String> getIndexLineMatcher();
354
355
356
357
358
359
360
361 public abstract Matcher<String> getRuntimeComponentEntryMatcher();
362 }
363
364 public static class ExpectedComponent extends AbstractExpectedComponent {
365 private final String implClass;
366 private final String specifiedName;
367
368 public ExpectedComponent(String implClass, String specifiedName) {
369 this.implClass = implClass;
370 this.specifiedName = specifiedName;
371 }
372
373 @Override
374 public Matcher<String> getIndexLineMatcher() {
375 return equalTo(implClass + ((specifiedName == null) ? "" : "#" + specifiedName));
376 }
377
378 @Override
379 public Matcher<String> getRuntimeComponentEntryMatcher() {
380 return equalTo(((specifiedName != null) ? specifiedName : toComponentName(implClass))
381 + " = " + implClass);
382 }
383 }
384
385 public static class ExpectedComponentImport extends AbstractExpectedComponent {
386 private final String iface;
387
388 private ExpectedComponentImport(String iface) {
389 this.iface = iface;
390 }
391
392 @Override
393 public Matcher<String> getIndexLineMatcher() {
394 return equalTo(iface);
395 }
396
397 @Override
398 public Matcher<String> getRuntimeComponentEntryMatcher() {
399
400 return new AnyImplClassComponentMatcher(toComponentName(iface));
401 }
402 }
403
404 public static class ExpectedAutoAddedComponent extends AbstractExpectedComponent {
405 private final String name;
406 private final String implClass;
407
408 private ExpectedAutoAddedComponent(String name) {
409 this.name = name;
410 this.implClass = null;
411 }
412
413 private ExpectedAutoAddedComponent(String name, String implClass) {
414 this.name = name;
415 this.implClass = implClass;
416 }
417
418 @Override
419 public Matcher<String> getIndexLineMatcher() {
420
421 return null;
422 }
423
424 @Override
425 public Matcher<String> getRuntimeComponentEntryMatcher() {
426 if (implClass == null) {
427
428 return new AnyImplClassComponentMatcher(name);
429 }
430 return equalTo(name + " = " + implClass);
431 }
432 }
433
434 public static class ExpectedServiceExport extends AbstractExpectedComponent {
435 private final String implClass;
436 private final List<String> expectedExportedInterfaces;
437 private final List<String> specifiedInterfaces;
438
439 private ExpectedServiceExport(String implClass,
440 List<String> expectedExportedInterfaces,
441 List<String> specifiedInterfaces) {
442 this.implClass = implClass;
443 this.expectedExportedInterfaces = expectedExportedInterfaces;
444 this.specifiedInterfaces = specifiedInterfaces;
445 }
446
447 @Override
448 public Matcher<String> getIndexLineMatcher() {
449 return equalTo(implClass +
450 ((specifiedInterfaces != null)
451 ? ("#" + Joiner.on(",").join(specifiedInterfaces))
452 : ""));
453 }
454
455 @Override
456 public Matcher<String> getRuntimeComponentEntryMatcher() {
457 if (expectedExportedInterfaces == null) {
458 return equalTo(implClass);
459 }
460 return new InterfaceMatcherInAnyOrder(expectedExportedInterfaces);
461 }
462 }
463
464 private static class InterfaceMatcherInAnyOrder extends TypeSafeMatcher<String> {
465 private final List<String> interfaces;
466
467 public InterfaceMatcherInAnyOrder(List<String> interfaces) {
468 this.interfaces = interfaces;
469 }
470
471 @Override
472 protected boolean matchesSafely(String item) {
473
474 Collection<Matcher<? super String>> expected = interfaces.stream()
475 .map(Matchers::equalTo)
476 .collect(Collectors.toList());
477 Iterable<? extends String> actual = ImmutableList.<String>builder().add(item.split(",")).build();
478 final Matcher<Iterable<? extends String>> iterableMatcher
479 = Matchers.containsInAnyOrder(expected);
480 return iterableMatcher.matches(actual);
481 }
482
483 @Override
484 public void describeTo(Description description) {
485 description.appendText("exported interfaces: '" + interfaces + "'");
486 }
487 }
488
489
490
491
492 private static class AnyImplClassComponentMatcher extends TypeSafeMatcher<String> {
493
494 private final String componentName;
495
496 public AnyImplClassComponentMatcher(String componentName) {
497 this.componentName = componentName;
498 }
499
500 @Override
501 protected boolean matchesSafely(String item) {
502
503
504
505 return item.startsWith(componentName + " = ");
506 }
507
508 @Override
509 public void describeTo(Description description) {
510 description.appendText("component named: '" + componentName + "' (any impl)");
511 }
512 }
513 }