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.attributeDefinition;
19
20 import java.io.StringWriter;
21 import java.util.ArrayList;
22 import java.util.Collection;
23 import java.util.HashMap;
24 import java.util.Iterator;
25 import java.util.List;
26 import java.util.Map;
27
28 import org.apache.velocity.Template;
29 import org.apache.velocity.VelocityContext;
30 import org.apache.velocity.app.VelocityEngine;
31 import org.apache.velocity.runtime.resource.util.StringResourceRepository;
32 import org.opensaml.xml.util.DatatypeHelper;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35
36 import edu.internet2.middleware.shibboleth.common.attribute.BaseAttribute;
37 import edu.internet2.middleware.shibboleth.common.attribute.provider.BasicAttribute;
38 import edu.internet2.middleware.shibboleth.common.attribute.resolver.AttributeResolutionException;
39 import edu.internet2.middleware.shibboleth.common.attribute.resolver.provider.ShibbolethResolutionContext;
40 import edu.internet2.middleware.shibboleth.common.util.StringResourceLoader;
41
42
43
44
45
46
47
48 public class TemplateAttributeDefinition extends BaseAttributeDefinition {
49
50
51 private final Logger log = LoggerFactory.getLogger(TemplateAttributeDefinition.class);
52
53
54 private VelocityEngine velocity;
55
56
57 private String templateName;
58
59
60 private String attributeTemplate;
61
62
63
64
65 private List<String> sourceAttributes;
66
67
68
69
70
71
72 public TemplateAttributeDefinition(VelocityEngine newVelocityEngine) {
73 velocity = newVelocityEngine;
74 sourceAttributes = new ArrayList<String>();
75 }
76
77
78 protected BaseAttribute doResolve(ShibbolethResolutionContext resolutionContext)
79 throws AttributeResolutionException {
80 Map<String, Iterator> sourceValues = new HashMap<String, Iterator>();
81 BasicAttribute<Object> attribute = new BasicAttribute<Object>();
82 attribute.setId(getId());
83
84 int valueCount = -1;
85
86
87 for (String attributeId : sourceAttributes) {
88 Collection values = getValuesFromAllDependencies(resolutionContext, attributeId);
89
90 if (valueCount == -1) {
91 valueCount = values.size();
92 } else if (valueCount != values.size()) {
93 log.error("All attributes used in TemplateAttributeDefinition " + getId()
94 + " must have the same number of values.");
95 throw new AttributeResolutionException("All attributes used in TemplateAttributeDefinition " + getId()
96 + " must have the same number of values.");
97 }
98
99 sourceValues.put(attributeId, values.iterator());
100 }
101
102
103 VelocityContext vCtx = new VelocityContext();
104 vCtx.put("requestContext", resolutionContext.getAttributeRequestContext());
105 for (int i = 0; i < valueCount; i++) {
106 for (String attributeId : sourceValues.keySet()) {
107 vCtx.put(attributeId, sourceValues.get(attributeId).next());
108 }
109
110 try {
111 log.debug("Populating the following {} template", templateName);
112
113 StringWriter output = new StringWriter();
114 Template template = velocity.getTemplate(templateName);
115 template.merge(vCtx, output);
116 attribute.getValues().add(output.toString());
117 } catch (Exception e) {
118 log.error("Unable to populate " + templateName + " template", e);
119 throw new AttributeResolutionException("Unable to evaluate template", e);
120 }
121 }
122
123 return attribute;
124 }
125
126
127
128
129
130
131 public void initialize() throws Exception {
132 if (DatatypeHelper.isEmpty(attributeTemplate)) {
133 StringBuffer defaultTemplate = new StringBuffer();
134 for (String id : sourceAttributes) {
135 defaultTemplate.append("${").append(id).append("} ");
136 }
137 attributeTemplate = defaultTemplate.toString();
138 }
139
140 registerTemplate();
141 }
142
143
144
145
146 protected void registerTemplate() {
147 StringResourceRepository repository = StringResourceLoader.getRepository();
148 templateName = "shibboleth.resolver.ad." + getId();
149 repository.putStringResource(templateName, attributeTemplate.trim());
150 }
151
152
153 public void validate() throws AttributeResolutionException {
154
155 }
156
157
158
159
160
161
162 public String getAttributeTemplate() {
163 return attributeTemplate;
164 }
165
166
167
168
169
170
171 public void setAttributeTemplate(String newAttributeTemplate) {
172 attributeTemplate = newAttributeTemplate;
173 }
174
175
176
177
178
179
180 public List<String> getSourceAttributes() {
181 return sourceAttributes;
182 }
183
184
185
186
187
188
189 public void setSourceAttributes(List<String> newSourceAttributes) {
190 sourceAttributes = newSourceAttributes;
191 }
192 }