@Override
public TagScript createTagScript(final String tagName, Attributes attributes) throws JellyException {
return new TagScript() {
private Object evalAttribute(String name, JellyContext context) {
ExpressionAttribute e = attributes.get(name);
if (e==null) return null;
return e.exp.evaluate(context);
}
private Collection<?> getExclusions(JellyContext context) {
Object exclusion = evalAttribute(EXCEPT_ATTRIBUTES,context);
if (exclusion==null)
return Collections.emptySet();
if (exclusion instanceof String)
return Arrays.asList(exclusion.toString().split("\\s+")); // split by whitespace
if (exclusion instanceof Collection)
return (Collection)exclusion;
throw new IllegalArgumentException("Expected collection for exclusion but found :"+exclusion);
}
@Override
public void run(JellyContext context, XMLOutput output) throws JellyTagException {
AttributesImpl actual = new AttributesImpl();
Collection<?> exclusions = getExclusions(context);
Map<String,?> meta = (Map)evalAttribute(META_ATTRIBUTES,context);
if (meta!=null) {
for (Map.Entry<String,?> e : meta.entrySet()) {
String key = e.getKey();
// @see jelly.impl.DynamicTag.setAttribute() -- ${attrs} has duplicates with "Attr" suffix
if (key.endsWith("Attr") && meta.containsKey(key.substring(0, key.length()-4))) continue;
// @see http://github.com/jenkinsci/jelly/commit/4ae67d15957b5b4d32751619997a3cb2a6ad56ed
if (key.equals("ownerTag")) continue;
if (!exclusions.contains(key)) {
Object v = e.getValue();
if (v!=null)
actual.addAttribute("", key, key,"CDATA", v.toString());
}
}
} else {
meta = Collections.emptyMap();
}
for (Map.Entry<String,ExpressionAttribute> e : attributes.entrySet()) {
String name = e.getKey();
if (name.equals(META_ATTRIBUTES) || name.equals(EXCEPT_ATTRIBUTES)) continue; // already handled
if (meta.containsKey(name)) {
// if the explicit value is also generated by a map, delete it first.
// this is O(N) operation, but we don't expect there to be a lot of collisions.
int idx = actual.getIndex(name);
if(idx>=0) actual.removeAttribute(idx);
}
Expression expression = e.getValue().exp;
actual.addAttribute("",name,name,"CDATA",expression.evaluateAsString(context));
}
try {
output.startElement(tagName,actual);