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