1
1
/**
2
- * Copyright 2012-2018 the original author or authors.
2
+ * Copyright 2012-2019 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
17
17
18
18
import java .io .StringReader ;
19
19
import java .io .StringWriter ;
20
- import java .util .Collections ;
21
20
import java .util .HashMap ;
22
21
import java .util .Map ;
23
22
import java .util .Properties ;
23
+ import java .util .stream .Collectors ;
24
24
25
- import org .apache .commons .lang3 .StringUtils ;
26
25
import org .apache .ibatis .builder .BuilderException ;
26
+ import org .apache .ibatis .io .Resources ;
27
+ import org .apache .ibatis .scripting .ScriptingException ;
27
28
import org .apache .velocity .Template ;
28
29
import org .apache .velocity .VelocityContext ;
30
+ import org .apache .velocity .runtime .RuntimeConstants ;
29
31
import org .apache .velocity .runtime .RuntimeInstance ;
30
32
import org .apache .velocity .runtime .parser .node .SimpleNode ;
31
33
32
34
public class VelocityFacade {
33
35
34
- private static final String ADDITIONAL_CTX_ATTRIBUTES_KEY = "additional.context.attributes" ;
35
- private static final String EXTERNAL_PROPERTIES = "mybatis-velocity.properties" ;
36
- private static final String DIRECTIVES = TrimDirective .class .getName () + "," + WhereDirective .class .getName () + ","
37
- + SetDirective .class .getName () + "," + InDirective .class .getName () + "," + RepeatDirective .class .getName ();
36
+ private static final RuntimeInstance engine = new RuntimeInstance ();
37
+ private static final Map <String , Object > additionalCtxAttributes = new HashMap <>();
38
38
39
- private static final RuntimeInstance engine ;
40
-
41
- /** Contains thread safe objects to be set in the velocity context. */
42
- private static final Map <String , Object > additionalCtxAttributes ;
43
- private static final Properties settings ;
44
-
45
- static {
39
+ private VelocityFacade () {
40
+ // Prevent instantiation
41
+ }
46
42
47
- settings = loadProperties ();
48
- additionalCtxAttributes = Collections .unmodifiableMap (loadAdditionalCtxAttributes ());
49
- engine = new RuntimeInstance ();
50
- engine .init (settings );
43
+ /**
44
+ * Initialize a template engine.
45
+ *
46
+ * @param driverConfig
47
+ * a language driver configuration
48
+ * @since 2.1.0
49
+ */
50
+ public static void initialize (VelocityLanguageDriverConfig driverConfig ) {
51
+ Properties properties = new Properties ();
52
+ driverConfig .getVelocitySettings ().forEach (properties ::setProperty );
53
+ properties .setProperty (RuntimeConstants .CUSTOM_DIRECTIVES , driverConfig .generateCustomDirectivesString ());
54
+ engine .init (properties );
55
+ additionalCtxAttributes .putAll (driverConfig .getAdditionalContextAttributes ().entrySet ().stream ()
56
+ .collect (Collectors .toMap (Map .Entry ::getKey , v -> {
57
+ try {
58
+ return Resources .classForName (v .getValue ()).getConstructor ().newInstance ();
59
+ } catch (Exception e ) {
60
+ throw new ScriptingException ("Cannot load additional context attribute class." , e );
61
+ }
62
+ })));
51
63
}
52
64
53
- private VelocityFacade () {
54
- // Prevent instantiation
65
+ /**
66
+ * Destroy a template engine.
67
+ *
68
+ * @since 2.1.0
69
+ */
70
+ public static void destroy () {
71
+ engine .reset ();
72
+ additionalCtxAttributes .clear ();
55
73
}
56
74
57
75
public static Object compile (String script , String name ) {
@@ -76,48 +94,4 @@ public static String apply(Object template, Map<String, Object> context) {
76
94
return out .toString ();
77
95
}
78
96
79
- private static Properties loadProperties () {
80
- final Properties props = new Properties ();
81
- // Defaults
82
- props .setProperty ("resource.loader" , "class" );
83
- props .setProperty ("class.resource.loader.class" ,
84
- "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader" );
85
-
86
- try {
87
- // External properties
88
- ClassLoader cl = Thread .currentThread ().getContextClassLoader ();
89
- props .load (cl .getResourceAsStream (EXTERNAL_PROPERTIES ));
90
- } catch (Exception ex ) {
91
- // No custom properties
92
- }
93
-
94
- // Append the user defined directives if provided
95
- String userDirective = StringUtils .trim (props .getProperty ("userdirective" ));
96
- if (userDirective == null ) {
97
- userDirective = DIRECTIVES ;
98
- } else {
99
- userDirective += "," + DIRECTIVES ;
100
- }
101
- props .setProperty ("userdirective" , userDirective );
102
- return props ;
103
- }
104
-
105
- private static Map <String , Object > loadAdditionalCtxAttributes () {
106
- Map <String , Object > attributes = new HashMap <>();
107
- String additionalContextAttributes = settings .getProperty (ADDITIONAL_CTX_ATTRIBUTES_KEY );
108
- if (additionalContextAttributes == null ) {
109
- return attributes ;
110
- }
111
-
112
- try {
113
- String [] entries = additionalContextAttributes .split ("," );
114
- for (String str : entries ) {
115
- String [] entry = str .trim ().split (":" );
116
- attributes .put (entry [0 ].trim (), Class .forName (entry [1 ].trim ()).newInstance ());
117
- }
118
- } catch (Exception ex ) {
119
- throw new BuilderException ("Error parsing velocity property '" + ADDITIONAL_CTX_ATTRIBUTES_KEY + "'" , ex );
120
- }
121
- return attributes ;
122
- }
123
97
}
0 commit comments