1
1
package org .zalando .sprocwrapper .globalvaluetransformer ;
2
2
3
- import java .lang .reflect .InvocationTargetException ;
4
- import java .util .Set ;
5
-
3
+ import com .google .common .base .Strings ;
6
4
import org .reflections .Reflections ;
7
-
8
5
import org .reflections .scanners .SubTypesScanner ;
9
6
import org .reflections .scanners .TypeAnnotationsScanner ;
10
-
11
7
import org .reflections .util .ClasspathHelper ;
12
8
import org .reflections .util .ConfigurationBuilder ;
13
9
import org .reflections .util .FilterBuilder ;
14
-
15
10
import org .slf4j .Logger ;
16
11
import org .slf4j .LoggerFactory ;
17
-
18
- import com .google .common .base .Predicate ;
19
- import com .google .common .base .Strings ;
20
-
21
12
import org .zalando .sprocwrapper .globalvaluetransformer .annotation .GlobalValueTransformer ;
22
-
23
13
import org .zalando .typemapper .core .ValueTransformer ;
24
14
import org .zalando .typemapper .core .fieldMapper .GlobalValueTransformerRegistry ;
25
15
16
+ import java .lang .reflect .InvocationTargetException ;
17
+ import java .util .Arrays ;
18
+ import java .util .HashSet ;
19
+ import java .util .Set ;
20
+ import java .util .function .Predicate ;
21
+ import java .util .stream .Collectors ;
22
+
26
23
public class GlobalValueTransformerLoader {
27
24
25
+ private static final Logger LOG = LoggerFactory .getLogger (GlobalValueTransformerLoader .class );
28
26
private static final String GLOBAL_VALUE_TRANSFORMER_SEARCH_NAMESPACE = "global.value.transformer.search.namespace" ;
29
-
30
- // you need to set the namespace to a valid value like: org.doodlejump
27
+ private static final String NAMESPACE_SEPARATOR = ";" ;
31
28
private static String namespaceToScan = "org.zalando" ;
32
-
33
- private static final Logger LOG = LoggerFactory .getLogger (GlobalValueTransformerLoader .class );
34
29
private static boolean scannedClasspath = false ;
35
30
36
31
public static synchronized ValueTransformer <?, ?> getValueTransformerForClass (final Class <?> genericType )
37
- throws InstantiationException , IllegalAccessException , InvocationTargetException , NoSuchMethodException {
32
+ throws InstantiationException , IllegalAccessException , InvocationTargetException , NoSuchMethodException {
38
33
39
34
// did we already scanned the classpath for global value transformers?
40
- if (scannedClasspath == false ) {
41
- final Predicate <String > filter = new Predicate <String >() {
42
- @ Override
43
- public boolean apply (final String input ) {
44
- return GlobalValueTransformer .class .getCanonicalName ().equals (input );
45
- }
46
- };
35
+ if (!scannedClasspath ) {
47
36
48
37
// last to get the namespace from the system environment
49
38
String myNameSpaceToScan = null ;
@@ -59,29 +48,33 @@ public boolean apply(final String input) {
59
48
myNameSpaceToScan = namespaceToScan ;
60
49
}
61
50
62
- if (!Strings .isNullOrEmpty (myNameSpaceToScan )) {
63
- final Reflections reflections = new Reflections (new ConfigurationBuilder ().filterInputsBy (
64
- new FilterBuilder .Include (FilterBuilder .prefix (myNameSpaceToScan ))).setUrls (
65
- ClasspathHelper .forPackage (myNameSpaceToScan )).setScanners (new TypeAnnotationsScanner ()
66
- .filterResultsBy (filter ), new SubTypesScanner ()));
67
- final Set <Class <?>> typesAnnotatedWith = reflections .getTypesAnnotatedWith (
68
- GlobalValueTransformer .class );
69
- for (final Class <?> foundGlobalValueTransformer : typesAnnotatedWith ) {
70
- final Class <?> valueTransformerReturnType ;
71
- try {
72
- valueTransformerReturnType = ValueTransformerUtils .getUnmarshalFromDbClass (
73
- foundGlobalValueTransformer );
74
- GlobalValueTransformerRegistry .register (valueTransformerReturnType ,
75
- (ValueTransformer <?, ?>) foundGlobalValueTransformer .getDeclaredConstructor ().newInstance ());
76
- } catch (final RuntimeException e ) {
77
- LOG .error ("Failed to add global transformer [{}] to global registry." ,
51
+ final Set <String > namespaces =
52
+ Arrays .stream (myNameSpaceToScan .split (NAMESPACE_SEPARATOR ))
53
+ .map (String ::trim )
54
+ .filter (Strings ::isNullOrEmpty )
55
+ .collect (Collectors .toSet ());
56
+
57
+ namespaces .add (namespaceToScan );
58
+ LOG .debug ("Scan the following packages for {}: {}" , GlobalValueTransformer .class .getSimpleName (),
59
+ namespaces );
60
+ final Set <Class <?>> typesAnnotatedWith = loadAnnotatedTypes (namespaces );
61
+
62
+ for (final Class <?> foundGlobalValueTransformer : typesAnnotatedWith ) {
63
+ final Class <?> valueTransformerReturnType ;
64
+ try {
65
+ valueTransformerReturnType = ValueTransformerUtils .getUnmarshalFromDbClass (
66
+ foundGlobalValueTransformer );
67
+ GlobalValueTransformerRegistry .register (valueTransformerReturnType ,
68
+ (ValueTransformer <?, ?>) foundGlobalValueTransformer .getDeclaredConstructor ()
69
+ .newInstance ());
70
+ } catch (final RuntimeException e ) {
71
+ LOG .error ("Failed to add global transformer [{}] to global registry." ,
78
72
foundGlobalValueTransformer , e );
79
- continue ;
80
- }
73
+ continue ;
74
+ }
81
75
82
- LOG .debug ("Global Value Transformer [{}] for type [{}] registered. " ,
76
+ LOG .debug ("Global Value Transformer [{}] for type [{}] registered." ,
83
77
foundGlobalValueTransformer .getSimpleName (), valueTransformerReturnType .getSimpleName ());
84
- }
85
78
}
86
79
87
80
scannedClasspath = true ;
@@ -90,10 +83,26 @@ public boolean apply(final String input) {
90
83
return GlobalValueTransformerRegistry .getValueTransformerForClass (genericType );
91
84
}
92
85
86
+ private static Set <Class <?>> loadAnnotatedTypes (Set <String > namespacesToScan ) {
87
+ final Predicate <String > filter = input -> GlobalValueTransformer .class .getCanonicalName ().equals (input );
88
+ final Set <Class <?>> result = new HashSet <>();
89
+ for (String namespace : namespacesToScan ) {
90
+ final Reflections reflections = new Reflections (
91
+ new ConfigurationBuilder ()
92
+ .filterInputsBy (new FilterBuilder .Include (FilterBuilder .prefix (namespace )))
93
+ .setUrls (ClasspathHelper .forPackage (namespace ))
94
+ .setScanners (new TypeAnnotationsScanner ().filterResultsBy (filter ),
95
+ new SubTypesScanner ())
96
+ );
97
+ result .addAll (reflections .getTypesAnnotatedWith (GlobalValueTransformer .class ));
98
+ }
99
+ return result ;
100
+ }
101
+
93
102
/**
94
103
* Use this static function to set the namespace to scan.
95
104
*
96
- * @param newNamespace the new namespace to be searched for {@link GlobalValueTransformer}
105
+ * @param newNamespace the new namespace to be searched for {@link org.zalando.sprocwrapper.globalvaluetransformer.annotation. GlobalValueTransformer}
97
106
*/
98
107
public static void changeNamespaceToScan (final String newNamespace ) {
99
108
namespaceToScan = newNamespace ;
0 commit comments