You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by rg...@apache.org on 2016/02/05 12:16:59 UTC

svn commit: r1728639 - in /qpid/java/trunk/broker-core/src: main/java/org/apache/qpid/server/model/ test/java/org/apache/qpid/server/model/testmodels/hierarchy/

Author: rgodfrey
Date: Fri Feb  5 11:16:59 2016
New Revision: 1728639

URL: http://svn.apache.org/viewvc?rev=1728639&view=rev
Log:
QPID-7049 : Allow injected derived attributes/statistics/operations to be constructed from methods with an initial set of fixed parameters

Modified:
    qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredDerivedInjectedAttribute.java
    qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectInjectedOperation.java
    qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectInjectedStatistic.java
    qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/InjectedAttributeTest.java

Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredDerivedInjectedAttribute.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredDerivedInjectedAttribute.java?rev=1728639&r1=1728638&r2=1728639&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredDerivedInjectedAttribute.java (original)
+++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredDerivedInjectedAttribute.java Fri Feb  5 11:16:59 2016
@@ -43,9 +43,11 @@ public class ConfiguredDerivedInjectedAt
     private final String _oversizedAltText;
     private final String _description;
     private final Method _method;
+    private final Object[] _staticParams;
 
     public ConfiguredDerivedInjectedAttribute(final String name,
                                               final Method method,
+                                              final Object[] staticParams,
                                               final boolean secure,
                                               final boolean persisted,
                                               final String secureValueFilter,
@@ -57,14 +59,31 @@ public class ConfiguredDerivedInjectedAt
         super(name, (Class<T>) AttributeValueConverter.getTypeFromMethod(method),
               method.getGenericReturnType(), typeValidator);
 
-        if(!(method.getParameterTypes().length == 1
+        _staticParams = staticParams == null ? new Object[0] : staticParams;
+
+        if(!(method.getParameterTypes().length == 1 + _staticParams.length
              && ConfiguredObject.class.isAssignableFrom(method.getParameterTypes()[0])
              && Modifier.isStatic(method.getModifiers())))
         {
-            throw new IllegalArgumentException("Injected derived attribute method must be static, and have a single argument which inherits from ConfiguredObject");
+            throw new IllegalArgumentException("Injected derived attribute method must be static, and have an initial argument which inherits from ConfiguredObject");
         }
         _method = method;
         method.setAccessible(true);
+
+        final Class<?>[] methodParamTypes = method.getParameterTypes();
+        for(int i = 0; i < _staticParams.length; i++)
+        {
+            if(methodParamTypes[i+1].isPrimitive() && _staticParams[i] == null)
+            {
+                throw new IllegalArgumentException("Static parameter has null value, but the " + methodParamTypes[i+1].getSimpleName() + " type is a primitive");
+            }
+            if(!AttributeValueConverter.convertPrimitiveToBoxed(methodParamTypes[i+1]).isAssignableFrom(_staticParams[i].getClass()))
+            {
+                throw new IllegalArgumentException("Static parameter cannot be assigned value as it is of incompatible type");
+            }
+        }
+
+
         _secure = secure;
         _persisted = persisted;
         _oversized = oversized;
@@ -144,7 +163,14 @@ public class ConfiguredDerivedInjectedAt
     {
         try
         {
-            return (T) _method.invoke(null, configuredObject);
+            Object[] params = new Object[1+_staticParams.length];
+            params[0] = configuredObject;
+            for(int i = 0; i < _staticParams.length; i++)
+            {
+                params[i+1] = _staticParams[i];
+            }
+
+            return (T) _method.invoke(null, params);
         }
         catch (IllegalAccessException e)
         {

Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectInjectedOperation.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectInjectedOperation.java?rev=1728639&r1=1728638&r2=1728639&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectInjectedOperation.java (original)
+++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectInjectedOperation.java Fri Feb  5 11:16:59 2016
@@ -43,12 +43,14 @@ public class ConfiguredObjectInjectedOpe
     private final String _name;
     private final String _description;
     private final boolean _nonModifying;
+    private final Object[] _staticParams;
 
     public ConfiguredObjectInjectedOperation(final String name,
                                              final String description,
                                              final boolean nonModifying,
                                              final OperationParameter[] parameters,
                                              final Method operation,
+                                             final Object[] staticParams,
                                              final TypeValidator validator)
     {
         _operation = operation;
@@ -56,6 +58,7 @@ public class ConfiguredObjectInjectedOpe
         _description = description;
         _nonModifying = nonModifying;
         _validator = validator;
+        _staticParams = staticParams == null ? new Object[0] : staticParams;
 
         _params = parameters == null ? Collections.<OperationParameter>emptyList() : Arrays.asList(parameters);
 
@@ -67,16 +70,29 @@ public class ConfiguredObjectInjectedOpe
 
         _validNames = Collections.unmodifiableSet(validNames);
 
-        Class<?>[] opParameterTypes = operation.getParameterTypes();
+        final Class<?>[] opParameterTypes = operation.getParameterTypes();
+
         if(!(Modifier.isStatic(operation.getModifiers())
              && Modifier.isPublic(operation.getModifiers())
-             && opParameterTypes.length == _params.size() + 1
+             && opParameterTypes.length == _params.size() + _staticParams.length + 1
              && ConfiguredObject.class.isAssignableFrom(opParameterTypes[0])))
         {
             throw new IllegalArgumentException("Passed method must be public and static.  The first parameter must derive from ConfiguredObject, and the rest of the parameters must match the passed in specifications");
         }
 
-        int paramId = 1;
+        for(int i = 0; i < _staticParams.length; i++)
+        {
+            if(opParameterTypes[i+1].isPrimitive() && _staticParams[i] == null)
+            {
+                throw new IllegalArgumentException("Static parameter has null value, but the " + opParameterTypes[i+1].getSimpleName() + " type is a primitive");
+            }
+            if(!AttributeValueConverter.convertPrimitiveToBoxed(opParameterTypes[i+1]).isAssignableFrom(_staticParams[i].getClass()))
+            {
+                throw new IllegalArgumentException("Static parameter cannot be assigned value as it is of incompatible type");
+            }
+        }
+
+        int paramId = 1+_staticParams.length;
         for(OperationParameter parameter : _params)
         {
             if(!opParameterTypes[paramId].isAssignableFrom(parameter.getType()))
@@ -119,8 +135,15 @@ public class ConfiguredObjectInjectedOpe
             {
                 throw new IllegalArgumentException("Parameters " + providedNames + " are not accepted by " + getName());
             }
-            Object[] paramValues = new Object[1+_params.size()];
+            Object[] paramValues = new Object[1+_staticParams.length+_params.size()];
             paramValues[0] = subject;
+
+
+            for(int i = 0; i < _staticParams.length; i++)
+            {
+                paramValues[i+1] = _staticParams[i];
+            }
+
             for (int i = 0; i < _params.size(); i++)
             {
                 OperationParameter param = _params.get(i);
@@ -143,7 +166,7 @@ public class ConfiguredObjectInjectedOpe
                 try
                 {
                     final Object convertedVal = converter.convert(providedVal, subject);
-                    paramValues[i+1] = convertedVal;
+                    paramValues[i+1+_staticParams.length] = convertedVal;
                 }
                 catch (IllegalArgumentException e)
                 {

Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectInjectedStatistic.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectInjectedStatistic.java?rev=1728639&r1=1728638&r2=1728639&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectInjectedStatistic.java (original)
+++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectInjectedStatistic.java Fri Feb  5 11:16:59 2016
@@ -40,27 +40,43 @@ final public class ConfiguredObjectInjec
     private final StatisticUnit _units;
     private final StatisticType _type;
     private final String _label;
+    private final Object[] _staticParams;
 
     public ConfiguredObjectInjectedStatistic(final String name,
-                                      final Method method,
-                                      final String description,
-                                      final TypeValidator typeValidator,
-                                      final StatisticUnit units,
-                                      final StatisticType type,
-                                      final String label)
+                                             final Method method,
+                                             final Object[] staticParams,
+                                             final String description,
+                                             final TypeValidator typeValidator,
+                                             final StatisticUnit units,
+                                             final StatisticType type,
+                                             final String label)
     {
         super(name,
               (Class<T>) AttributeValueConverter.getTypeFromMethod(method), method.getGenericReturnType(), typeValidator);
         _units = units;
         _type = type;
         _label = label;
-        if(!(method.getParameterTypes().length == 1
+        _staticParams = staticParams == null ? new Object[0] : staticParams;
+        if(!(method.getParameterTypes().length == 1 + _staticParams.length
              && ConfiguredObject.class.isAssignableFrom(method.getParameterTypes()[0])
              && Modifier.isStatic(method.getModifiers())
              && Number.class.isAssignableFrom(AttributeValueConverter.getTypeFromMethod(method))))
         {
-            throw new IllegalArgumentException("Injected statistic method must be static, have a single argument which inherits from ConfiguredObject, and return a Number");
+            throw new IllegalArgumentException("Injected statistic method must be static, have first argument which inherits from ConfiguredObject, and return a Number");
         }
+        final Class<?>[] methodParamTypes = method.getParameterTypes();
+        for(int i = 0; i < _staticParams.length; i++)
+        {
+            if(methodParamTypes[i+1].isPrimitive() && _staticParams[i] == null)
+            {
+                throw new IllegalArgumentException("Static parameter has null value, but the " + methodParamTypes[i+1].getSimpleName() + " type is a primitive");
+            }
+            if(!AttributeValueConverter.convertPrimitiveToBoxed(methodParamTypes[i+1]).isAssignableFrom(_staticParams[i].getClass()))
+            {
+                throw new IllegalArgumentException("Static parameter cannot be assigned value as it is of incompatible type");
+            }
+        }
+
         _method = method;
         method.setAccessible(true);
         _description = description;
@@ -95,7 +111,13 @@ final public class ConfiguredObjectInjec
     {
         try
         {
-            return (T) _method.invoke(null, configuredObject);
+            Object[] params = new Object[1+_staticParams.length];
+            params[0] = configuredObject;
+            for(int i = 0; i < _staticParams.length; i++)
+            {
+                params[i+1] = _staticParams[i];
+            }
+            return (T) _method.invoke(null, params);
         }
         catch (IllegalAccessException e)
         {

Modified: qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/InjectedAttributeTest.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/InjectedAttributeTest.java?rev=1728639&r1=1728638&r2=1728639&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/InjectedAttributeTest.java (original)
+++ qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/InjectedAttributeTest.java Fri Feb  5 11:16:59 2016
@@ -21,9 +21,12 @@
 package org.apache.qpid.server.model.testmodels.hierarchy;
 
 import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 import org.apache.qpid.server.configuration.IllegalConfigurationException;
@@ -41,26 +44,25 @@ public class InjectedAttributeTest exten
         private Collection<ConfiguredObjectInjectedStatistic<?, ?>> _injectedStatistics;
         private Collection<ConfiguredObjectInjectedOperation<?>> _injectedOperations;
 
-        private TestInjector(ConfiguredObjectInjectedAttribute<?, ?> attribute)
+        private TestInjector(ConfiguredObjectInjectedAttribute<?, ?>... attributes)
         {
-            this(Collections.<ConfiguredObjectInjectedAttribute<?, ?>>singletonList(attribute),
+            this(Arrays.asList(attributes),
                  Collections.<ConfiguredObjectInjectedStatistic<?, ?>>emptyList(),
                  Collections.<ConfiguredObjectInjectedOperation<?>>emptyList());
         }
 
-        private TestInjector(ConfiguredObjectInjectedStatistic<?, ?> statistic)
+        private TestInjector(ConfiguredObjectInjectedStatistic<?, ?>... statistics)
         {
             this(Collections.<ConfiguredObjectInjectedAttribute<?, ?>>emptyList(),
-                 Collections.<ConfiguredObjectInjectedStatistic<?, ?>>singletonList(statistic),
+                 Arrays.asList(statistics),
                  Collections.<ConfiguredObjectInjectedOperation<?>>emptyList());
         }
 
-
-        private TestInjector(ConfiguredObjectInjectedOperation<?> operation)
+        private TestInjector(ConfiguredObjectInjectedOperation<?>... operations)
         {
             this(Collections.<ConfiguredObjectInjectedAttribute<?, ?>>emptyList(),
                  Collections.<ConfiguredObjectInjectedStatistic<?, ?>>emptyList(),
-                 Collections.<ConfiguredObjectInjectedOperation<?>>singletonList(operation));
+                 Arrays.asList(operations));
         }
 
         private TestInjector(final Collection<ConfiguredObjectInjectedAttribute<?, ?>> injectedAttributes,
@@ -212,7 +214,7 @@ public class InjectedAttributeTest exten
         final ConfiguredDerivedInjectedAttribute<?, ?> attrInjector =
                 new ConfiguredDerivedInjectedAttribute<TestCar<?>, Integer>("meaningOfLife",
                                                                             method,
-                                                                            false,
+                                                                            null, false,
                                                                             false,
                                                                             "",
                                                                             false,
@@ -247,7 +249,7 @@ public class InjectedAttributeTest exten
         final ConfiguredObjectInjectedStatistic<?, ?> statInjector =
                 new ConfiguredObjectInjectedStatistic<TestCar<?>, Integer>("meaningOfLife",
                                                                            method,
-                                                                           "",
+                                                                           null, "",
                                                                            validator,
                                                                            StatisticUnit.COUNT,
                                                                            StatisticType.POINT_IN_TIME,
@@ -263,6 +265,47 @@ public class InjectedAttributeTest exten
     }
 
 
+    public void testInjectedStatisticWithParameters() throws Exception
+    {
+
+        Method method = InjectedAttributeTest.class.getDeclaredMethod("getWhatISent", TestCar.class, Integer.TYPE);
+        InjectedAttributeOrStatistic.TypeValidator validator =
+                new InjectedAttributeOrStatistic.TypeValidator()
+                {
+                    @Override
+                    public boolean appliesToType(final Class<? extends ConfiguredObject<?>> type)
+                    {
+                        return TestCar.class.isAssignableFrom(type);
+                    }
+                };
+
+        final ConfiguredObjectInjectedStatistic<?, ?> statInjector1 =
+                new ConfiguredObjectInjectedStatistic<TestCar<?>, Integer>("whatISent1",
+                                                                           method,
+                                                                           new Object[] { 1 }, "",
+                                                                           validator,
+                                                                           StatisticUnit.COUNT,
+                                                                           StatisticType.POINT_IN_TIME,
+                                                                           "One");
+        final ConfiguredObjectInjectedStatistic<?, ?> statInjector2 =
+                new ConfiguredObjectInjectedStatistic<TestCar<?>, Integer>("whatISent2",
+                                                                           method,
+                                                                           new Object[] { 2 }, "",
+                                                                           validator,
+                                                                           StatisticUnit.COUNT,
+                                                                           StatisticType.POINT_IN_TIME,
+                                                                           "Two");
+        TestModel model = new TestModel(null, new TestInjector(statInjector1, statInjector2));
+
+        TestCar<?> testCar = new TestStandardCarImpl(Collections.<String,Object>singletonMap("name", "Arthur"), model);
+
+        final Map<String, Number> statistics = testCar.getStatistics();
+        assertEquals("incorrect number of statistics", 2, statistics.size());
+        assertEquals("incorrect statistic value", 1, statistics.get("whatISent1"));
+        assertEquals("incorrect statistic value", 2, statistics.get("whatISent2"));
+    }
+
+
     public void testInjectedOperation() throws Exception
     {
 
@@ -280,7 +323,7 @@ public class InjectedAttributeTest exten
         final OperationParameter[] params = new OperationParameter[1];
         params[0] = new OperationParameterFromInjection("height", Integer.TYPE, Integer.TYPE, "", "", new String[0]);
         final ConfiguredObjectInjectedOperation<?> operationInjector =
-                new ConfiguredObjectInjectedOperation<TestCar<?>>("fly", "", true, params, method, validator);
+                new ConfiguredObjectInjectedOperation<TestCar<?>>("fly", "", true, params, method, null, validator);
 
         TestModel model = new TestModel(null, new TestInjector(operationInjector));
 
@@ -302,6 +345,49 @@ public class InjectedAttributeTest exten
         assertEquals("Car should not be able to fly at 5000m", Boolean.FALSE, result);
     }
 
+    public void testInjectedOperationWithStaticParams() throws Exception
+    {
+
+        Method method = InjectedAttributeTest.class.getDeclaredMethod("saySomething", TestCar.class, String.class, Integer.TYPE);
+        InjectedAttributeOrStatistic.TypeValidator validator =
+                new InjectedAttributeOrStatistic.TypeValidator()
+                {
+                    @Override
+                    public boolean appliesToType(final Class<? extends ConfiguredObject<?>> type)
+                    {
+                        return TestCar.class.isAssignableFrom(type);
+                    }
+                };
+
+        final OperationParameter[] params = new OperationParameter[1];
+        params[0] = new OperationParameterFromInjection("count", Integer.TYPE, Integer.TYPE, "", "", new String[0]);
+
+        final ConfiguredObjectInjectedOperation<?> hello =
+                new ConfiguredObjectInjectedOperation<TestCar<?>>("sayHello", "", true, params, method, new String[] { "Hello"}, validator);
+        final ConfiguredObjectInjectedOperation<?> goodbye =
+                new ConfiguredObjectInjectedOperation<TestCar<?>>("sayGoodbye", "", true, params, method, new String[] { "Goodbye"}, validator);
+
+        TestModel model = new TestModel(null, new TestInjector(hello, goodbye));
+
+        TestCar testCar = new TestStandardCarImpl(Collections.<String,Object>singletonMap("name", "Arthur"), model);
+
+        final Map<String, ConfiguredObjectOperation<?>> allOperations =
+                model.getTypeRegistry().getOperations(testCar.getClass());
+
+        assertTrue("Operation sayHello(int count) is missing", allOperations.containsKey("sayHello"));
+        assertTrue("Operation sayGoodbye(int count) is missing", allOperations.containsKey("sayGoodbye"));
+
+        final ConfiguredObjectOperation helloOperation = allOperations.get("sayHello");
+        final ConfiguredObjectOperation goodbyeOperation = allOperations.get("sayGoodbye");
+
+        Object result = helloOperation.perform(testCar, Collections.<String, Object>singletonMap("count", 3));
+
+        assertEquals("Car should say 'Hello' 3 times", Arrays.asList("Hello", "Hello", "Hello"), result);
+
+        result = goodbyeOperation.perform(testCar, Collections.<String, Object>singletonMap("count", 1));
+
+        assertEquals("Car say 'Goodbye' once", Collections.singletonList("Goodbye"), result);
+    }
 
 
     public static int getMeaningOfLife(TestCar<?> car)
@@ -309,8 +395,24 @@ public class InjectedAttributeTest exten
         return 42;
     }
 
+
+    public static int getWhatISent(TestCar<?> car, int whatIsent)
+    {
+        return whatIsent;
+    }
+
     public static boolean fly(TestCar<?> car, int height)
     {
         return height == 0;
     }
+
+    public static List<String> saySomething(TestCar<?> car, String whatToSay, int count)
+    {
+        List<String> list = new ArrayList<>();
+        for(int i = 0; i < count; i++)
+        {
+            list.add(whatToSay);
+        }
+        return list;
+    }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org