1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package edu.internet2.middleware.shibboleth.common.attribute.resolver.provider.dataConnector;
19
20 import java.io.StringWriter;
21 import java.util.ArrayList;
22 import java.util.List;
23 import java.util.Map;
24
25 import org.apache.velocity.Template;
26 import org.apache.velocity.VelocityContext;
27 import org.apache.velocity.app.VelocityEngine;
28 import org.apache.velocity.runtime.resource.util.StringResourceRepository;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32 import edu.internet2.middleware.shibboleth.common.attribute.BaseAttribute;
33 import edu.internet2.middleware.shibboleth.common.attribute.resolver.AttributeResolutionException;
34 import edu.internet2.middleware.shibboleth.common.attribute.resolver.provider.ResolutionPlugIn;
35 import edu.internet2.middleware.shibboleth.common.attribute.resolver.provider.ShibbolethResolutionContext;
36 import edu.internet2.middleware.shibboleth.common.attribute.resolver.provider.attributeDefinition.AttributeDefinition;
37 import edu.internet2.middleware.shibboleth.common.util.StringResourceLoader;
38
39
40
41
42 public class TemplateEngine {
43
44
45 private final Logger log = LoggerFactory.getLogger(TemplateEngine.class);
46
47
48 private VelocityEngine velocity;
49
50
51
52
53
54
55 public TemplateEngine(VelocityEngine engine) {
56 velocity = engine;
57 }
58
59
60
61
62
63
64
65 public void registerTemplate(String templateName, String template) {
66 StringResourceRepository repository = StringResourceLoader.getRepository();
67 repository.putStringResource(templateName, template);
68 }
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83 public String createStatement(String templateName, ShibbolethResolutionContext resolutionContext,
84 List<String> dependencies, CharacterEscapingStrategy escapingStrategy) throws AttributeResolutionException {
85 VelocityContext vContext = createVelocityContext(resolutionContext, dependencies, escapingStrategy);
86
87 try {
88 log.trace("Populating the following {} template", templateName);
89
90 StringWriter output = new StringWriter();
91 Template template = velocity.getTemplate(templateName);
92 template.merge(vContext, output);
93 return output.toString();
94 } catch (Exception e) {
95 log.error("Unable to populate " + templateName + " template", e);
96 throw new AttributeResolutionException("Unable to evaluate template", e);
97 }
98 }
99
100
101
102
103
104
105
106
107
108
109
110
111 @SuppressWarnings("unchecked")
112 protected VelocityContext createVelocityContext(ShibbolethResolutionContext resolutionContext,
113 List<String> dependencies, CharacterEscapingStrategy escapingStrategy) throws AttributeResolutionException {
114 log.trace("Populating velocity context");
115 VelocityContext vCtx = new VelocityContext();
116 vCtx.put("requestContext", resolutionContext.getAttributeRequestContext());
117
118 ResolutionPlugIn plugin;
119 Map<String, BaseAttribute> attributes;
120 BaseAttribute attribute;
121 for (String dependencyId : dependencies) {
122 plugin = resolutionContext.getResolvedPlugins().get(dependencyId);
123 if (plugin instanceof DataConnector) {
124 log.trace("Resolving attributes from data connector {}", dependencyId);
125 attributes = ((DataConnector) plugin).resolve(resolutionContext);
126
127 for (String attributeId : attributes.keySet()) {
128 vCtx.put(attributeId, prepareAttributeValues(attributes.get(attributeId), escapingStrategy));
129 }
130 } else if (plugin instanceof AttributeDefinition) {
131 log.trace("Resolving attributes from attribute definition {}", dependencyId);
132 attribute = ((AttributeDefinition) plugin).resolve(resolutionContext);
133 if (!vCtx.containsKey(attribute.getId())) {
134 vCtx.put(attribute.getId(), new ArrayList<String>());
135 }
136 ((List<String>) vCtx.get(attribute.getId())).addAll(attribute.getValues());
137 } else {
138 log.trace("Unable to locate resolution plugin {}", dependencyId);
139 }
140 }
141
142 return vCtx;
143 }
144
145
146
147
148
149
150
151
152
153 protected List<Object> prepareAttributeValues(BaseAttribute attribute, CharacterEscapingStrategy escapingStrategy) {
154 ArrayList<Object> preparedValues = new ArrayList<Object>();
155
156 if (attribute == null || attribute.getValues() == null || attribute.getValues().isEmpty()) {
157 return preparedValues;
158 }
159
160 if (escapingStrategy == null) {
161 preparedValues.addAll(attribute.getValues());
162 } else {
163 for (Object value : attribute.getValues()) {
164 if(value instanceof String){
165 preparedValues.add(escapingStrategy.escape(value.toString()));
166 }else{
167 preparedValues.add(value);
168 }
169 }
170 }
171
172 return preparedValues;
173 }
174
175
176
177
178 public interface CharacterEscapingStrategy {
179
180
181
182
183
184
185
186
187 public String escape(String value);
188 }
189 }