diff options
| author | Robert Godfrey <rgodfrey@apache.org> | 2014-04-28 11:20:44 +0000 |
|---|---|---|
| committer | Robert Godfrey <rgodfrey@apache.org> | 2014-04-28 11:20:44 +0000 |
| commit | ad2f94b4caabb7e222d136bc15b1cee528a73e31 (patch) | |
| tree | 367dd5c48b3b4f1d310bd5ccb12fed8e7c7368f0 | |
| parent | 7505243f188a9b978a472090f582baea9d96a318 (diff) | |
| download | qpid-python-ad2f94b4caabb7e222d136bc15b1cee528a73e31.tar.gz | |
QPID-5721 : Allow interpolation to include the values of attributes of the object on which the value is being iterpolated
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1590603 13f79535-47bb-0310-9956-ffa450edef68
| -rw-r--r-- | qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java index 95bd2f582d..73fc59e057 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java @@ -20,6 +20,8 @@ */ package org.apache.qpid.server.model; +import java.io.IOException; +import java.io.StringWriter; import java.lang.reflect.Field; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; @@ -49,6 +51,15 @@ import java.util.concurrent.atomic.AtomicBoolean; import javax.security.auth.Subject; +import org.codehaus.jackson.JsonGenerator; +import org.codehaus.jackson.JsonProcessingException; +import org.codehaus.jackson.Version; +import org.codehaus.jackson.map.JsonSerializer; +import org.codehaus.jackson.map.Module; +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.map.SerializerProvider; +import org.codehaus.jackson.map.module.SimpleModule; + import org.apache.qpid.server.configuration.IllegalConfigurationException; import org.apache.qpid.server.configuration.updater.Task; import org.apache.qpid.server.configuration.updater.TaskExecutor; @@ -156,6 +167,8 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im @ManagedAttributeField private String _type; + private final OwnAttributeResolver _attributeResolver = new OwnAttributeResolver(this); + protected static Map<Class<? extends ConfiguredObject>, ConfiguredObject<?>> parentsMap(ConfiguredObject<?>... parents) { final Map<Class<? extends ConfiguredObject>, ConfiguredObject<?>> parentsMap = @@ -1144,6 +1157,11 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im return converter.convert("${"+propertyName+"}", this); } + private OwnAttributeResolver getOwnAttributeResolver() + { + return _attributeResolver; + } + //========================================================================================= static String interpolate(ConfiguredObject<?> object, String value) @@ -1151,12 +1169,20 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im Map<String,String> inheritedContext = new HashMap<String, String>(); generateInheritedContext(object.getModel(), object, inheritedContext); return Strings.expand(value, false, + getOwnAttributeResolver(object), new Strings.MapResolver(inheritedContext), Strings.JAVA_SYS_PROPS_RESOLVER, Strings.ENV_VARS_RESOLVER, new Strings.MapResolver(_defaultContext)); } + private static OwnAttributeResolver getOwnAttributeResolver(final ConfiguredObject<?> object) + { + return object instanceof AbstractConfiguredObject + ? ((AbstractConfiguredObject)object).getOwnAttributeResolver() + : new OwnAttributeResolver(object); + } + static void generateInheritedContext(final Model model, final ConfiguredObject<?> object, final Map<String, String> inheritedContext) { @@ -1623,6 +1649,115 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im return allDescendants.contains(descendantClass); } + private static class OwnAttributeResolver implements Strings.Resolver + { + private static final Module _module; + static + { + SimpleModule module= new SimpleModule("ConfiguredObjectSerializer", new Version(1,0,0,null)); + + final JsonSerializer<ConfiguredObject> serializer = new JsonSerializer<ConfiguredObject>() + { + @Override + public void serialize(final ConfiguredObject value, + final JsonGenerator jgen, + final SerializerProvider provider) + throws IOException, JsonProcessingException + { + jgen.writeString(value.getId().toString()); + } + }; + module.addSerializer(ConfiguredObject.class, serializer); + + _module = module; + } + + + public static final String PREFIX = "this:"; + private final ThreadLocal<Set<String>> _stack = new ThreadLocal<>(); + private final ConfiguredObject<?> _object; + private final ObjectMapper _objectMapper; + + public OwnAttributeResolver(final ConfiguredObject<?> object) + { + _object = object; + _objectMapper = new ObjectMapper(); + _objectMapper.registerModule(_module); + } + + @Override + public String resolve(final String variable) + { + boolean clearStack = false; + Set<String> currentStack = _stack.get(); + if(currentStack == null) + { + currentStack = new HashSet<>(); + _stack.set(currentStack); + clearStack = true; + } + + try + { + if(variable.startsWith(PREFIX)) + { + String attrName = variable.substring(PREFIX.length()); + if(currentStack.contains(attrName)) + { + throw new IllegalArgumentException("The value of attribute " + attrName + " is defined recursively"); + } + else + { + currentStack.add(attrName); + Object returnVal = _object.getAttribute(attrName); + String returnString; + if(returnVal == null) + { + returnString = null; + } + else if(returnVal instanceof Map || returnVal instanceof Collection) + { + try + { + StringWriter writer = new StringWriter(); + + _objectMapper.writeValue(writer, returnVal); + + returnString = writer.toString(); + } + catch (IOException e) + { + throw new IllegalArgumentException(e); + } + } + else if(returnVal instanceof ConfiguredObject) + { + returnString = ((ConfiguredObject)returnVal).getId().toString(); + } + else + { + returnString = returnVal.toString(); + } + + return returnString; + } + } + else + { + return null; + } + } + finally + { + if(clearStack) + { + _stack.remove(); + } + + } + } + } + private class AttributeGettingHandler implements InvocationHandler { |
