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