You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ar...@apache.org on 2008/09/29 14:02:56 UTC
svn commit: r700077 [3/4] - in /incubator/qpid/trunk/qpid/java:
client/src/main/java/org/apache/qpid/management/
client/src/main/java/org/apache/qpid/management/configuration/
client/src/main/java/org/apache/qpid/management/domain/
client/src/main/java...
Added: incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/management/domain/model/QpidClass.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/management/domain/model/QpidClass.java?rev=700077&view=auto
==============================================================================
--- incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/management/domain/model/QpidClass.java (added)
+++ incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/management/domain/model/QpidClass.java Mon Sep 29 05:02:54 2008
@@ -0,0 +1,855 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.domain.model;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.management.Attribute;
+import javax.management.AttributeList;
+import javax.management.AttributeNotFoundException;
+import javax.management.DynamicMBean;
+import javax.management.InvalidAttributeValueException;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanException;
+import javax.management.MBeanInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanRegistration;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+import javax.management.RuntimeOperationsException;
+
+import org.apache.qpid.management.Protocol;
+import org.apache.qpid.management.domain.handler.impl.MethodOrEventDataTransferObject;
+import org.apache.qpid.management.domain.model.type.Binary;
+import org.apache.qpid.management.domain.services.QpidService;
+import org.apache.qpid.transport.codec.ManagementDecoder;
+import org.apache.qpid.transport.codec.ManagementEncoder;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * Qpid Class definition.
+ * A type definition for a manageable object.
+ * This class is also responsible to manage incoming obejct instance data (configuration & instrumentation).
+ * How can we handle data before schema is injected into this class? simply we must retain that data in raw format.
+ * This class has 2 states :
+ * 1) first state is when schema is not yet injected. In this case the incoming object data is retained as is (in raw format);
+ * 2) second state is when schema is injected. In this case each injection of data will result in an update / create / delete of
+ * the corresponding object instance. In addition, the first time the state change, the old retained raw data is cnverted in
+ * object instance(s).
+ *
+ * @author Andrea Gazzarini
+ */
+class QpidClass
+{
+ /**
+ * State interface for this class definition.
+ * Each state is responsible to handle the injection of the object data.
+ *
+ * @author Andrea Gazzarini
+ */
+ interface State
+ {
+ /**
+ * Adds configuration data for the object instance associated to the given object identifier.
+ *
+ * @param objectId the object identifier.
+ * @param rawData the raw configuration data.
+ */
+ void addInstrumentationData (Binary objectId, byte[] rawData);
+
+ /**
+ * Adds instrumentation data for the object instance associated to the given object identifier.
+ *
+ * @param objectId the object identifier.
+ * @param rawData the raw instrumentation data.
+ */
+ void addConfigurationData (Binary objectId, byte[] rawData);
+
+ /**
+ * Inject the schema into this class definition.
+ *
+ * @param propertyDefinitions
+ * @param statisticDefinitions
+ * @param methodDefinitions
+ * @param eventDefinitions
+ * @throws UnableToBuildFeatureException when it's not possibile to parse schema and build the class definition.
+ */
+ public void setSchema (
+ List<Map<String, Object>> propertyDefinitions,
+ List<Map<String, Object>> statisticDefinitions,
+ List<MethodOrEventDataTransferObject> methodDefinitions,
+ List<MethodOrEventDataTransferObject> eventDefinitions) throws UnableToBuildFeatureException;
+ };
+
+ /**
+ * This is the initial state of every qpid class.
+ * The class definition instance is created but its schema has not been injected.
+ * Incoming configuration & instrumentation data will be stored in raw format because we don't know how to
+ * parse it until the schema arrives.
+ * In addition, this state is responsible (when data arrives) to request its schema.
+ */
+ final State _schemaNotRequested = new State() {
+
+ /**
+ * Stores the incoming data in raw format and request the schema for this class.
+ * After that a transition to the next state is made.
+ *
+ * @param objectId the object instance identifier.
+ * @param rawData incoming configuration data.
+ */
+ public synchronized void addConfigurationData (Binary objectId, byte[] rawData)
+ {
+ schemaRequest();
+ QpidManagedObject instance = getObjectInstance(objectId,false);
+ instance._rawConfigurationData.add(rawData);
+ _state = _schemaRequestedButNotYetInjected;
+ }
+
+ /**
+ * Stores the incoming data in raw format and request the schema for this class.
+ * After that a transition to the next state is made.
+ *
+ * @param objectId the object instance identifier.
+ * @param rawData incoming instrumentation data.
+ */
+ public synchronized void addInstrumentationData (Binary objectId, byte[] rawData)
+ {
+ schemaRequest();
+ QpidManagedObject instance = getObjectInstance(objectId,false);
+ instance._rawConfigurationData.add(rawData);
+ _state = _schemaRequestedButNotYetInjected;
+ }
+
+ /**
+ * This method only throws an illegal state exception because when a schema arrives
+ * this state is no longer valid.
+ */
+ public void setSchema (
+ List<Map<String, Object>> propertyDefinitions,
+ List<Map<String, Object>> statisticDefinitions,
+ List<MethodOrEventDataTransferObject> methodDefinitions,
+ List<MethodOrEventDataTransferObject> eventDefinitions) throws UnableToBuildFeatureException
+ {
+ throw new IllegalStateException("When a schema arrives it's not possible for this class to be in this state.");
+ }
+ };
+
+ /**
+ * This is the first state of this class definition : the schema is not yet injected so each injection of object data will be
+ * retained in raw format.
+ */
+ final State _schemaRequestedButNotYetInjected = new State()
+ {
+ /**
+ * Stores the incoming data in raw format.
+ *
+ * @param objectId the object instance identifier.
+ * @param rawData incoming configuration data.
+ */
+ public void addConfigurationData (Binary objectId, byte[] rawData)
+ {
+ QpidManagedObject instance = getObjectInstance(objectId,false);
+ instance._rawConfigurationData.add(rawData);
+ }
+
+ /**
+ * Stores the incoming data in raw format.
+ *
+ * @param objectId the object instance identifier.
+ * @param rawData incoming instrumentation data.
+ */
+ public void addInstrumentationData (Binary objectId, byte[] rawData)
+ {
+ QpidManagedObject instance = getObjectInstance(objectId,false);
+ instance._rawInstrumentationData.add(rawData);
+ }
+
+ /**
+ * When a schema is injected into this defintiion the following should happen :
+ * 1) the incoming schema is parsed and the class definition is built;
+ * 2) the retained raw data is converted into object instance(s)
+ * 3) the internal state of this class changes;
+ *
+ * If someting is wrong during that process the schema is not built and the state don't change.
+ */
+ public synchronized void setSchema (
+ List<Map<String, Object>> propertyDefinitions,
+ List<Map<String, Object>> statisticDefinitions,
+ List<MethodOrEventDataTransferObject> methodDefinitions,
+ List<MethodOrEventDataTransferObject> eventDefinitions) throws UnableToBuildFeatureException
+ {
+
+ MBeanAttributeInfo [] attributesMetadata = new MBeanAttributeInfo[propertyDefinitions.size()+statisticDefinitions.size()];
+ MBeanOperationInfo [] operationsMetadata = new MBeanOperationInfo[methodDefinitions.size()];
+
+ buildAttributes(propertyDefinitions,statisticDefinitions,attributesMetadata);
+ buildMethods(methodDefinitions,operationsMetadata);
+ buildEvents(eventDefinitions);
+
+ _metadata = new MBeanInfo(_name,_name,attributesMetadata,null,operationsMetadata,null);
+
+ // Converting stored object instances into JMX MBean and removing raw instance data.
+ for (Entry<Binary, QpidManagedObject> instanceEntry : _objectInstances.entrySet())
+ {
+ Binary objectId = instanceEntry.getKey();
+ QpidManagedObject instance = instanceEntry.getValue();
+
+ for (Iterator<byte[]> iterator = instance._rawInstrumentationData.iterator(); iterator.hasNext();)
+ {
+ updateInstanceWithInstrumentationData(instance,iterator.next());
+ iterator.remove();
+ }
+
+ for (Iterator<byte[]> iterator = instance._rawConfigurationData.iterator(); iterator.hasNext();)
+ {
+ updateInstanceWithConfigurationData(instance, iterator.next());
+ iterator.remove();
+ }
+
+ JMX_SERVICE.registerObjectInstance(instance,_parent.getOwnerId(),_parent.getName(),_name,objectId);
+ }
+ _state = _schemaInjected;
+ }
+ };
+
+ /**
+ * After a schema is built into this definition this is the current state of the class.
+ */
+ final State _schemaInjected = new State()
+ {
+ /**
+ * Updates the configuration state of the object instance associates with the given object identifier.
+ *
+ * @param objectId the object identifier.
+ * @param rawData the configuration data (raw format).
+ */
+ public void addConfigurationData (Binary objectId, byte[] rawData)
+ {
+ QpidManagedObject instance = getObjectInstance(objectId,true);
+ updateInstanceWithConfigurationData(instance, rawData);
+ }
+
+ /**
+ * Updates the instrumentation state of the object instance associates with the given object identifier.
+ *
+ * @param objectId the object identifier.
+ * @param rawData the instrumentation data (raw format).
+ */
+ public void addInstrumentationData (Binary objectId, byte[] rawData)
+ {
+ QpidManagedObject instance = getObjectInstance(objectId,true);
+ updateInstanceWithInstrumentationData(instance, rawData);
+ }
+
+ /**
+ * Never called when the class definition has this state.
+ */
+ public void setSchema (
+ List<Map<String, Object>> propertyDefinitions,
+ List<Map<String, Object>> statisticDefinitions,
+ List<MethodOrEventDataTransferObject> methodDefinitions,
+ List<MethodOrEventDataTransferObject> eventDefinitions) throws UnableToBuildFeatureException
+ {
+ throw new IllegalStateException("When a schema arrives it's not possible for this class to be in this state.");
+ }
+ };
+
+ /**
+ * MBean used for representing remote broker object instances.
+ * This is the core component of the QMan domain model
+ *
+ * @author Andrea Gazzarini
+ */
+ class QpidManagedObject implements DynamicMBean,MBeanRegistration
+ {
+ // After this mbean is registered with the MBean server this collection holds the mbean attributes
+ private Map<String,Object> _attributes = new HashMap<String, Object>();
+ private Binary _objectId;
+
+ // Arrays used for storing raw data before this mbean is registered to mbean server.
+ List<byte[]> _rawInstrumentationData = new ArrayList<byte[]>();
+ List<byte[]> _rawConfigurationData = new ArrayList<byte[]>();
+
+ /**
+ * Builds a new managed object with the given object identifier.
+ *
+ * @param objectId the object identifier.
+ */
+ QpidManagedObject(Binary objectId)
+ {
+ this._objectId = objectId;
+ }
+
+ /**
+ * Creates or replace the given attribute.
+ * Note that this is not part of the management interface of this object instance and therefore will be accessible only
+ * from within this class.
+ * It is used to update directly the object attributes.
+ *
+ * @param attributeName the name of the attribute.
+ * @param property newValue the new value of the attribute.
+ */
+ void createOrReplaceAttributeValue(String attributeName, Object newValue)
+ {
+ _attributes.put(attributeName, newValue);
+ }
+
+ /**
+ * Returns the value of the given attribute.s
+ *
+ * @throws AttributeNotFoundException when no attribute is found with the given name.
+ */
+ public Object getAttribute (String attributeName) throws AttributeNotFoundException, MBeanException, ReflectionException
+ {
+ if (attributeName == null)
+ {
+ throw new RuntimeOperationsException(new IllegalArgumentException("attribute name must not be null"));
+ }
+
+ if (_properties.containsKey(attributeName) || _statistics.containsKey(attributeName))
+ {
+ return _attributes.get(attributeName);
+ } else
+ {
+ throw new AttributeNotFoundException(attributeName);
+ }
+ }
+
+ /**
+ * Get the values of several attributes of the Dynamic MBean.
+ *
+ * @param attributes A list of the attributes to be retrieved.
+ *
+ * @return The list of attributes retrieved.
+ */
+ public AttributeList getAttributes (String[] attributes)
+ {
+ if (attributes == null)
+ {
+ throw new RuntimeOperationsException(new IllegalArgumentException("attributes array must not be null"));
+ }
+
+ AttributeList result = new AttributeList(attributes.length);
+ for (int i = 0; i < attributes.length; i++)
+ {
+ String attributeName = attributes[i];
+ try
+ {
+ result.add(new Attribute(attributeName,getAttribute(attributeName)));
+ } catch(Exception exception)
+ {
+ // Already logged.
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Returns metadata for this object instance.
+ */
+ // Developer Note : note that this metadata is a member of the outer class definition : in that way we create
+ // that metadata only once and then it will be shared between all object instances (it's a readonly object)
+ public MBeanInfo getMBeanInfo ()
+ {
+ return _metadata;
+ }
+
+ /**
+ * Executes an operation on this object instance.
+ *
+ * @param actionName the name of the method.
+ * @param params the method parameters
+ * @param signature the method signature.
+ */
+ public Object invoke (String actionName, Object[] params, String[] signature) throws MBeanException,ReflectionException
+ {
+ // TODO : Overloaded methods
+ QpidMethod method = _methods.get(actionName);
+ if (method != null)
+ {
+ try
+ {
+ methodRequest(_objectId, method, params);
+ return null;
+ } catch (ValidationException exception)
+ {
+ throw new MBeanException(exception);
+ }
+ } else {
+ throw new ReflectionException(new NoSuchMethodException(actionName));
+ }
+ }
+
+ /**
+ * Sets the value of the given attribute on this object instance.
+ *
+ * @param attribute contains the new value of the attribute.
+ * @throws AttributeNotFoundException when the given attribute is not found on this object instance.
+ * @throws InvalidAttributeValueException when the given value is violating one attribute invariant.
+ */
+ public void setAttribute (Attribute attribute) throws AttributeNotFoundException,
+ InvalidAttributeValueException, MBeanException, ReflectionException
+ {
+ QpidProperty property = _properties.get(attribute.getName());
+ try
+ {
+ property.validate(attribute.getValue());
+ } catch(ValidationException exception)
+ {
+ throw new InvalidAttributeValueException(exception.getMessage());
+ }
+ throw new RuntimeException("Not yet implemented.");
+ }
+
+ /**
+ * Sets the values of several attributes of this MBean.
+ *
+ * @param attributes a list of attributes: The identification of the attributes to be set and the values they are to be set to.
+ * @return The list of attributes that were set, with their new values.
+ */
+ public AttributeList setAttributes (AttributeList attributes)
+ {
+ throw new RuntimeException("Not yet implemented.");
+ }
+
+ /**
+ * MBean server callback after deregistration.
+ */
+ public void postDeregister ()
+ {
+ }
+
+ /**
+ * After the object is registered the raw data is set to null.
+ * This is done because we no longer need this data : it has already been
+ * injected into this object instance.
+ *
+ * @param registrationDone a flag indicating if the instance has been registered to mbean server.
+ */
+ public void postRegister (Boolean registrationDone)
+ {
+ if (registrationDone)
+ {
+ _rawConfigurationData = null;
+ _rawInstrumentationData = null;
+ }
+ }
+
+ /**
+ * MBean server callback before deregistration.
+ */
+ public void preDeregister () throws Exception
+ {
+ }
+
+ /**
+ * MBean server callback before registration.
+ */
+ public ObjectName preRegister (MBeanServer server, ObjectName name) throws Exception
+ {
+ return name;
+ }
+ }
+
+ private final static Logger LOGGER = Logger.get(QpidClass.class);
+ private final static JmxService JMX_SERVICE = new JmxService();
+
+ private final String _name;
+ private final Binary _hash;
+
+ private final QpidPackage _parent;
+
+ Map<String, QpidProperty> _properties = new HashMap<String, QpidProperty>();
+ Map<String, QpidStatistic> _statistics = new HashMap<String, QpidStatistic>();
+ private Map<String, QpidMethod> _methods = new HashMap<String, QpidMethod>();
+
+ private List<QpidProperty> _schemaOrderedProperties = new ArrayList<QpidProperty>();
+ private List<QpidStatistic> _schemaOrderedStatistics= new ArrayList<QpidStatistic>();
+ private MBeanInfo _metadata;
+
+ private final QpidService _service;
+
+ private int _howManyPresenceBitMasks;
+
+ Map<Binary, QpidManagedObject> _objectInstances = new HashMap<Binary, QpidManagedObject>();
+ State _state = _schemaNotRequested;;
+
+ /**
+ * Builds a new class with the given name and package as parent.
+ *
+ * @param className the name of the class.
+ * @param hash the class schema hash.
+ * @param parentPackage the parent of this class.
+ */
+ QpidClass(String className, Binary hash, QpidPackage parentPackage)
+ {
+ this._name = className;
+ this._parent = parentPackage;
+ this._hash = hash;
+ this._service = new QpidService(_parent.getOwnerId());
+ LOGGER.debug(
+ "<QMAN-200017> : Class definition has been built (without schema) for %s::%s.%s",
+ _parent.getOwnerId(),
+ _parent.getName(),
+ _name);
+ }
+
+ /**
+ * Adds the configuration data for the object instance associated to the given object identifier.
+ *
+ * @param objectId the object identifier.
+ * @param rawData the raw configuration data.
+ */
+ void addInstrumentationData (Binary objectId, byte[] rawData)
+ {
+ LOGGER.debug("<QMAN-200015> : Incoming instrumentation data for %s::%s.%s.%s",
+ _parent.getOwnerId(),
+ _parent.getName(),
+ _name,
+ objectId);
+ _state.addInstrumentationData(objectId, rawData);
+ }
+
+ /**
+ * Adds the instrumentation data for the object instance associated to the given object identifier.
+ *
+ * @param objectId the object identifier.
+ * @param rawData the raw instrumentation data.
+ */
+ void addConfigurationData (Binary objectId, byte[] rawData)
+ {
+ LOGGER.debug("<QMAN-200016> : Incoming configuration data for %s::%s.%s.%s",
+ _parent.getOwnerId(),
+ _parent.getName(),
+ _name,
+ objectId);
+ _state.addConfigurationData(objectId, rawData);
+ }
+
+ /**
+ * Sets the schema for this class definition.
+ * A schema is basically a metadata description of all properties, statistics, methods and events of this class.
+ *
+ * @param propertyDefinitions properties metadata.
+ * @param statisticDefinitions statistics metadata.
+ * @param methodDefinitions methods metadata.
+ * @param eventDefinitions events metadata.
+ * @throws UnableToBuildFeatureException when some error occurs while parsing the incoming schema.
+ */
+ void setSchema (
+ List<Map<String, Object>> propertyDefinitions,
+ List<Map<String, Object>> statisticDefinitions,
+ List<MethodOrEventDataTransferObject> methodDefinitions,
+ List<MethodOrEventDataTransferObject> eventDefinitions) throws UnableToBuildFeatureException
+ {
+ LOGGER.info("<QMAN-000012> : Incoming schema for %s::%s.%s",_parent.getOwnerId(),_parent.getName(),_name);
+ _state.setSchema(propertyDefinitions, statisticDefinitions, methodDefinitions, eventDefinitions);
+ }
+
+ /**
+ * Internal method used for building attributes definitions.
+ *
+ * @param props the map contained in the properties schema.
+ * @param stats the map contained in the statistics schema.
+ * @param attributes the management metadata for attributes.
+ * @throws UnableToBuildFeatureException when it's not possibile to build one attribute definition.
+ */
+ void buildAttributes (
+ List<Map<String, Object>> props,
+ List<Map<String, Object>> stats,
+ MBeanAttributeInfo[] attributes) throws UnableToBuildFeatureException
+ {
+ int index = 0;
+ int howManyOptionalProperties = 0;
+
+ for (Map<String, Object> propertyDefinition : props)
+ {
+ QpidFeatureBuilder builder = QpidFeatureBuilder.createPropertyBuilder(propertyDefinition);
+ builder.build();
+
+ QpidProperty property = (QpidProperty) builder.getQpidFeature();
+
+ howManyOptionalProperties += (property.isOptional()) ? 1 : 0;
+
+ _properties.put(property.getName(),property);
+ _schemaOrderedProperties.add(property);
+ attributes[index++]=(MBeanAttributeInfo) builder.getManagementFeature();
+
+ LOGGER.debug(
+ "<QMAN-200017> : Property definition for %s::%s.%s has been built.",
+ _parent.getName(),
+ _name,
+ property);
+ }
+
+ _howManyPresenceBitMasks = (int)Math.ceil((double)howManyOptionalProperties / 8);
+
+ LOGGER.debug(
+ "<QMAN-200018> : Class %s::%s.%s has %s optional properties.",
+ _parent.getOwnerId(),
+ _parent.getName(),
+ _name,
+ _howManyPresenceBitMasks);
+
+ for (Map<String, Object> statisticDefinition : stats)
+ {
+ QpidFeatureBuilder builder = QpidFeatureBuilder.createStatisticBuilder(statisticDefinition);
+ builder.build();
+ QpidStatistic statistic = (QpidStatistic) builder.getQpidFeature();
+
+ _statistics.put(statistic.getName(),statistic);
+ _schemaOrderedStatistics.add(statistic);
+ attributes[index++]=(MBeanAttributeInfo) builder.getManagementFeature();
+
+ LOGGER.debug(
+ "<QMAN-200019> : Statistic definition for %s::%s.%s has been built.",
+ _parent.getName(),
+ _name,
+ statistic);
+ }
+ }
+
+ /**
+ * Returns the object instance associated to the given identifier.
+ * Note that if the identifier is not associated to any obejct instance, a new one will be created.
+ *
+ * @param objectId the object identifier.
+ * @param registration a flag indicating whenever the (new ) instance must be registered with MBean server.
+ * @return the object instance associated to the given identifier.
+ */
+ QpidManagedObject getObjectInstance(Binary objectId, boolean registration)
+ {
+ QpidManagedObject objectInstance = _objectInstances.get(objectId);
+ if (objectInstance == null)
+ {
+ objectInstance = new QpidManagedObject(objectId);
+ _objectInstances.put(objectId, objectInstance);
+ if (registration)
+ {
+ JMX_SERVICE.registerObjectInstance(objectInstance,_parent.getOwnerId(),_parent.getName(),_name,objectId);
+ }
+ }
+ return objectInstance;
+ }
+
+ /**
+ * Internal method used for building event statistics defintions.
+ *
+ * @param definitions the properties map contained in the incoming schema.
+ * @throws UnableToBuildFeatureException when it's not possibile to build one or more definitions.
+ */
+ void buildEvents (List<MethodOrEventDataTransferObject> eventDefinitions)
+ {
+ // TODO
+ }
+
+ /**
+ * Internal method used for building method defintiions.
+ *
+ * @param definitions the properties map contained in the incoming schema.
+ * @param operationsMetadata
+ * @throws UnableToBuildFeatureException when it's not possibile to build one or more definitions.
+ */
+ void buildMethods (List<MethodOrEventDataTransferObject> definitions, MBeanOperationInfo[] operationsMetadata) throws UnableToBuildFeatureException
+ {
+ int index = 0;
+ for (MethodOrEventDataTransferObject definition: definitions)
+ {
+ QpidFeatureBuilder builder = QpidFeatureBuilder.createMethodBuilder(definition);
+ builder.build();
+ operationsMetadata [index++]= (MBeanOperationInfo) builder.getManagementFeature();
+ QpidMethod method = (QpidMethod) builder.getQpidFeature();
+ _methods.put(method.getName(),method);
+ }
+ }
+
+ private void schemaRequest()
+ {
+ ByteBuffer buffer = ByteBuffer.allocate(100);
+ ManagementEncoder encoder = new ManagementEncoder(buffer);
+ buffer.put(Protocol.SCHEMA_REQUEST_FIRST_FOUR_BYTES);
+
+ // TODO
+ encoder.writeSequenceNo(1000);
+ encoder.writeStr8(_parent.getName());
+ encoder.writeStr8(_name);
+ _hash.encode(encoder);
+ buffer.rewind();
+ try
+ {
+ _service.connect();
+ _service.sendCommandMessage(buffer);
+ _service.sync();
+ } catch (Exception exception)
+ {
+ exception.printStackTrace();
+ // TODO
+ // Log.logSchemaRequestNotSent(exception,
+ // _parent.getOwnerId(),_parent.getName(), _name);
+ } finally
+ {
+ _service.close();
+ }
+ }
+
+ /**
+ * Header (opcode='M')
+ * ObjectId of target object (128 bits)
+ * Package name (str8)
+ * Class name (str8)
+ * Class hash (bin128)
+ * Method name (str8) [as defined in the schema]
+ * Now encode all input ("I") and i/o (IO) arguments in the order in which they are defined in the schema.
+ * (i.e. make one pass over the argument list and encode arguments that are either input or inptu/output).
+
+ * @param objectId
+ * @param method
+ * @param parameters
+ * @throws ValidationException
+ */
+ private void methodRequest(Binary objectId,QpidMethod method,Object [] parameters) throws ValidationException
+ {
+ ByteBuffer buffer = ByteBuffer.allocate(1000);
+ ManagementEncoder encoder = new ManagementEncoder(buffer);
+ buffer.put(Protocol.METHOD_REQUEST_FIRST_FOUR_BYTES);
+ encoder.writeSequenceNo(0);
+ objectId.encode(encoder);
+ encoder.writeStr8(_parent.getName());
+ encoder.writeStr8(_name);
+ _hash.encode(encoder);
+ encoder.writeStr8(method.getName());
+ method.encodeParameters(parameters,encoder);
+
+ buffer.rewind();
+ try
+ {
+ _service.connect();
+ _service.sendCommandMessage(buffer);
+ //_service.sync();
+ } catch (Exception exception)
+ {
+ exception.printStackTrace();
+ // TODO
+ // Log.logSchemaRequestNotSent(exception,
+ // _parent.getOwnerId(),_parent.getName(), _name);
+ } finally
+ {
+ _service.close();
+ }
+ }
+
+ /**
+ * Updates the given obejct instance with the given incoming configuration data.
+ *
+ * @param instance the managed object instance.
+ * @param rawData the incoming configuration data which contains new values for instance properties.
+ */
+ private void updateInstanceWithConfigurationData(QpidManagedObject instance,byte [] rawData)
+ {
+ ManagementDecoder decoder = new ManagementDecoder();
+ decoder.init(ByteBuffer.wrap(rawData));
+
+ byte [] presenceBitMasks = decoder.readBytes(_howManyPresenceBitMasks);
+ for (QpidProperty property : _schemaOrderedProperties)
+ {
+ try {
+ Object value = property.decodeValue(decoder,presenceBitMasks);
+ instance.createOrReplaceAttributeValue(property.getName(),value);
+ } catch(Exception ignore) {
+ LOGGER.error("Unable to decode value for %s::%s::%s", _parent.getName(),_name,property.getName());
+ }
+ }
+ }
+
+ /**
+ * Updates the given object instance with the given incoming instrumentation data.
+ *
+ * @param instance the managed object instance.
+ * @param rawData the incoming instrumentation data which contains new values for instance properties.
+ */
+ private void updateInstanceWithInstrumentationData(QpidManagedObject instance,byte [] rawData)
+ {
+ ManagementDecoder decoder = new ManagementDecoder();
+ decoder.init(ByteBuffer.wrap(rawData));
+
+ for (QpidStatistic statistic : _schemaOrderedStatistics)
+ {
+ try {
+ Object value = statistic.decodeValue(decoder);
+ instance.createOrReplaceAttributeValue(statistic.getName(),value);
+ } catch(Exception ignore) {
+ LOGGER.error("Unable to decode value for %s::%s::%s", _parent.getName(),_name,statistic.getName());
+ }
+ }
+ }
+
+ @Override
+ public String toString ()
+ {
+ return new StringBuilder()
+ .append(_parent.getOwnerId())
+ .append("::")
+ .append(_parent.getName())
+ .append("::")
+ .append(_name)
+ .toString();
+ }
+
+ /**
+ * Removes the object instance associated to the given identifier.
+ *
+ * @param objectId the object identifier.
+ */
+ void removeObjectInstance (Binary objectId)
+ {
+ QpidManagedObject toBeRemoved = _objectInstances.remove(objectId);
+ if (toBeRemoved != null)
+ {
+ JMX_SERVICE.unregisterObjectInstance(_parent.getOwnerId(),_parent.getName(),_name,toBeRemoved._objectId);
+ }
+ }
+
+ /**
+ * Deregisters all the object instances and release all previously acquired resources.
+ */
+ void releaseResources ()
+ {
+ for (Iterator<Binary> iterator = _objectInstances.keySet().iterator(); iterator.hasNext();)
+ {
+ Binary objectId = iterator.next();
+ JMX_SERVICE.unregisterObjectInstance(_parent.getOwnerId(),_parent.getName(),_name,objectId);
+ iterator.remove();
+ LOGGER.debug(
+ "%s.%s.%s object instance has been removed from broker %s",
+ _parent.getName(),
+ _name,objectId,
+ _parent.getOwnerId());
+ }
+ _service.close();
+ }
+}
\ No newline at end of file
Added: incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/management/domain/model/QpidEvent.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/management/domain/model/QpidEvent.java?rev=700077&view=auto
==============================================================================
--- incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/management/domain/model/QpidEvent.java (added)
+++ incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/management/domain/model/QpidEvent.java Mon Sep 29 05:02:54 2008
@@ -0,0 +1,26 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.domain.model;
+
+class QpidEvent extends QpidFeature
+{
+ // NOT YET IMPLEMENTED
+}
Added: incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeature.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeature.java?rev=700077&view=auto
==============================================================================
--- incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeature.java (added)
+++ incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeature.java Mon Sep 29 05:02:54 2008
@@ -0,0 +1,88 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.domain.model;
+
+/**
+ * Layer Supertype for all qpid management features.
+ *
+ * @author Andrea Gazzarini
+ */
+abstract class QpidFeature
+{
+ /** The name of the feature. */
+ protected String _name;
+
+ /**
+ * The description of the feature.
+ */
+ protected String _description;
+
+ /**
+ * Returns the description of this feature.
+ *
+ * @return the description of this feature.
+ */
+ String getDescription ()
+ {
+ return _description;
+ }
+
+ /**
+ * Sets the description for this feature.
+ *
+ * @param description the description for this feature.
+ */
+ void setDescription (String description)
+ {
+ this._description = description;
+ }
+
+ /**
+ * Returns the name of the feature.
+ *
+ * @return the name of the feature.
+ */
+ String getName ()
+ {
+ return _name;
+ }
+
+ /**
+ * Sets the name for this feature.
+ *
+ * @param name the name of this feature.
+ */
+ void setName (String name)
+ {
+ this._name = name;
+ }
+
+ /**
+ * Returns the name of the feature.
+ *
+ * @return the name of the feature.
+ */
+ @Override
+ public String toString ()
+ {
+ return _name;
+ }
+}
\ No newline at end of file
Added: incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeatureBuilder.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeatureBuilder.java?rev=700077&view=auto
==============================================================================
--- incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeatureBuilder.java (added)
+++ incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeatureBuilder.java Mon Sep 29 05:02:54 2008
@@ -0,0 +1,444 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.domain.model;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanFeatureInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanParameterInfo;
+
+import org.apache.qpid.management.configuration.Configuration;
+import org.apache.qpid.management.configuration.UnknownTypeCodeException;
+import org.apache.qpid.management.domain.handler.impl.MethodOrEventDataTransferObject;
+
+/**
+ * A builder used to parse incoming schema message and therefore to build a feature (property, statistic, method, event)
+ * definition.
+ * In order to set up the correct state for this builder, clients must create an instance of this class
+ * The product of the builder will be a QpidFeature and a JMX Managemtn feature used for describing that feature in a
+ * JMX environment. So, for example, for building a property definition client code should be :
+ *
+ * <br>- QpidFeatureBuilder builder = QpidFeature.createPropertyBuilder(...);
+ * <br>- builder.build();
+ * <br>- QpidProperty property = (QpidProperty) builder.getQpidFeature();
+ * <br>- MBeanAttributeInfo managementAttributeInfo = (MBeanAttributeInfo)builder.getManagementFeature();
+ *
+ * <br>N.B.: a builder instance is not supposed to be reused. One instance for one feature!
+ *
+ * @author Andrea Gazzarini
+ */
+class QpidFeatureBuilder
+{
+
+ static enum Attribute {
+ name,type,access,index,optional,unit,min,max,maxlen,desc,dir,argCount;
+ };
+
+ private List<Attribute> _mandatoryAttributes = new ArrayList<Attribute>();
+
+ /**
+ * Builder state for this class.
+ * Each concrete implementor is a builder for a specific feature.
+ * using the appropriate factory method.
+ *
+ * @author Andrea Gazzarini
+ */
+ interface State {
+ void build() throws UnableToBuildFeatureException;
+ }
+
+ /**
+ * Builder used for building property definition.
+ */
+ final State _propertyBuilder = new State() {
+
+ /**
+ * Builds a property definition as well a management attribute feature.
+ */
+ public void build () throws UnableToBuildFeatureException
+ {
+ QpidProperty property = new QpidProperty();
+ try {
+ int optionalIndex = 0;
+ for (Entry<String, Object> propertyAttribute : _featureDefinition.entrySet())
+ {
+ Attribute attribute = Attribute.valueOf(propertyAttribute.getKey());
+ switch(attribute)
+ {
+ case name :
+ {
+ property.setName(String.valueOf(propertyAttribute.getValue()));
+ break;
+ }
+ case access :
+ {
+ int code = (Integer)propertyAttribute.getValue();
+ property.setAccessMode(Configuration.getInstance().getAccessMode(code));
+ break;
+ }
+ case unit :
+ {
+ property.setUnit(String.valueOf(propertyAttribute.getValue()));
+ break;
+ }
+ case min :
+ {
+ property.setMinValue((Integer)propertyAttribute.getValue());
+ break;
+ }
+ case max :
+ {
+ property.setMaxValue((Integer)propertyAttribute.getValue());
+ break;
+ }
+ case maxlen :
+ {
+ property.setMaxLength((Integer)propertyAttribute.getValue());
+ break;
+ }
+ case desc :
+ {
+ property.setDescription(String.valueOf(propertyAttribute.getValue()));
+ break;
+ }
+ case type :
+ {
+ int code = (Integer) propertyAttribute.getValue();
+ property.setType(Configuration.getInstance().getType(code));
+ break;
+ }
+ case index :
+ {
+ break;
+ }
+ case optional :
+ {
+ int code = (Integer) propertyAttribute.getValue();
+ if (code == 1)
+ {
+ property.markAsOptional(optionalIndex);
+ optionalIndex++;
+ }
+ break;
+ }
+ }
+ _mandatoryAttributes.remove(attribute);
+ }
+ } catch(Exception exception)
+ {
+ throw new UnableToBuildFeatureException(exception,property.getName());
+ }
+
+ if (!_mandatoryAttributes.isEmpty())
+ {
+ throw new MissingFeatureAttributesException(_mandatoryAttributes);
+ }
+
+ _managementFeatureInfo = new MBeanAttributeInfo(
+ property.getName(),
+ property.getJavaType().getName(),
+ property.getDescription(),
+ true,
+ property.getAccessMode()==AccessMode.RW,
+ false);
+ _qpidFeature = property;
+ }
+ };
+
+ final State _statisticBuilder = new State()
+ {
+ public void build () throws UnableToBuildFeatureException
+ {
+ QpidStatistic statistic = new QpidStatistic();
+ try
+ {
+ for (Entry<String, Object> statisticAttribute : _featureDefinition.entrySet())
+ {
+ Attribute attribute = Attribute.valueOf(statisticAttribute.getKey());
+ switch(attribute)
+ {
+ case name :
+ {
+ statistic.setName(String.valueOf(statisticAttribute.getValue()));
+ break;
+ }
+ case unit :
+ {
+ statistic.setUnit(String.valueOf(statisticAttribute.getValue()));
+ break;
+ }
+ case desc :
+ {
+ statistic.setDescription(String.valueOf(statisticAttribute.getValue()));
+ break;
+ }
+ case type :
+ {
+ int code = (Integer) statisticAttribute.getValue();
+ statistic.setType(Configuration.getInstance().getType(code));
+ break;
+ }
+ }
+ _mandatoryAttributes.remove(attribute);
+ }
+ } catch(Exception exception)
+ {
+ throw new UnableToBuildFeatureException(exception,statistic.getName());
+ }
+
+ if (!_mandatoryAttributes.isEmpty())
+ {
+ throw new MissingFeatureAttributesException(_mandatoryAttributes);
+ }
+
+ _managementFeatureInfo = new MBeanAttributeInfo(
+ statistic.getName(),
+ statistic.getJavaType().getName(),
+ statistic.getDescription(),
+ true,
+ false,
+ false);
+ _qpidFeature = statistic;
+ }
+ };
+
+ /**
+ * Builder used for building a statistic definition.
+ */
+ final State _argumentBuilder = new State()
+ {
+ /**
+ * Builds a property definition as well a management attribute feature.
+ */
+ public void build () throws UnableToBuildFeatureException
+ {
+ QpidArgument argument = new QpidArgument();
+ for (Entry<String, Object> argumentAttribute : _featureDefinition.entrySet())
+ {
+ String key = argumentAttribute.getKey();
+ if ("default".equals(key))
+ {
+ argument.setDefaultValue(argumentAttribute.getValue());
+ } else {
+ Attribute attribute = Attribute.valueOf(key);
+ switch (attribute)
+ {
+ case name :
+ {
+ argument.setName((String)argumentAttribute.getValue());
+ break;
+ }
+ case desc :
+ {
+ argument.setDescription((String)argumentAttribute.getValue());
+ break;
+ }
+ case type :
+ {
+ try
+ {
+ argument.setType(Configuration.getInstance().getType((Integer)argumentAttribute.getValue()));
+ break;
+ } catch(UnknownTypeCodeException exception)
+ {
+ throw new UnableToBuildFeatureException(exception,argument.getName());
+ }
+ }
+ case dir :
+ {
+ argument.setDirection((String)argumentAttribute.getValue());
+ break;
+ }
+ case unit :
+ {
+ argument.setUnit((String)argumentAttribute.getValue());
+ break;
+
+ }
+ }
+ }
+ }
+
+ if (!_mandatoryAttributes.isEmpty())
+ {
+ throw new MissingFeatureAttributesException(_mandatoryAttributes);
+ }
+
+ _qpidFeature = argument;
+ _managementFeatureInfo = new MBeanParameterInfo(
+ argument.getName(),
+ argument.getJavaType().getName(),
+ argument.getDescription());
+ }
+ };
+
+ final State _methodBuilder = new State()
+ {
+ public void build () throws UnableToBuildFeatureException
+ {
+ Map<String,Object> definition = _methodOrEventDefinition.getDefinition();
+ String name = (String)definition.get(Attribute.name.name());
+ if (name == null)
+ {
+ throw new MissingFeatureAttributesException(_mandatoryAttributes);
+ }
+
+ QpidMethod method = new QpidMethod((String)definition.get("name"),(String) definition.get("desc"));
+
+ List<Map<String,Object>> args = _methodOrEventDefinition.getArgumentsDefinitions();
+
+ List<MBeanParameterInfo> signature = new LinkedList<MBeanParameterInfo>();
+
+ for (Map<String,Object> argumentDefinition : args)
+ {
+ QpidFeatureBuilder builder = QpidFeatureBuilder.createArgumentBuilder(argumentDefinition);
+ builder.build();
+
+ QpidArgument argument = (QpidArgument) builder.getQpidFeature();
+ method.addArgument(argument);
+ if (argument.isInput())
+ {
+ signature.add((MBeanParameterInfo) builder.getManagementFeature());
+ }
+ }
+
+ _qpidFeature = method;
+ _managementFeatureInfo = new MBeanOperationInfo(
+ method.getName(),
+ method.getDescription(),
+ (MBeanParameterInfo[])signature.toArray(new MBeanParameterInfo[signature.size()]),
+ void.class.getName(),
+ MBeanOperationInfo.ACTION);
+ }
+ };
+
+ final State _eventBuilder = new State()
+ {
+ public void build () throws UnableToBuildFeatureException
+ {
+ }
+ };
+
+ private MBeanFeatureInfo _managementFeatureInfo;
+ private QpidFeature _qpidFeature;
+ private final Map <String, Object> _featureDefinition;
+ private final MethodOrEventDataTransferObject _methodOrEventDefinition;
+ private State _state;
+
+ static QpidFeatureBuilder createPropertyBuilder(Map<String, Object> propertyDefinition)
+ {
+ QpidFeatureBuilder result = new QpidFeatureBuilder(propertyDefinition);
+ result._state = result._propertyBuilder;
+ result._mandatoryAttributes.add(Attribute.name);
+ result._mandatoryAttributes.add(Attribute.access);
+ result._mandatoryAttributes.add(Attribute.type);
+ result._mandatoryAttributes.add(Attribute.optional);
+ result._mandatoryAttributes.add(Attribute.index);
+ return result;
+ }
+
+ static QpidFeatureBuilder createStatisticBuilder(Map<String, Object> statisticDefinition)
+ {
+ QpidFeatureBuilder result = new QpidFeatureBuilder(statisticDefinition);
+ result._state = result._statisticBuilder;
+ result._mandatoryAttributes.add(Attribute.name);
+ result._mandatoryAttributes.add(Attribute.type);
+ return result;
+ }
+
+ static QpidFeatureBuilder createEventBuilder(Map<String, Object> eventDefinition)
+ {
+ QpidFeatureBuilder result = new QpidFeatureBuilder(eventDefinition);
+ result._state = result._eventBuilder;
+ return result;
+ }
+
+ static QpidFeatureBuilder createMethodBuilder(MethodOrEventDataTransferObject methodDefinition)
+ {
+ QpidFeatureBuilder result = new QpidFeatureBuilder(methodDefinition);
+ result._state = result._methodBuilder;
+ result._mandatoryAttributes.add(Attribute.name);
+ return result;
+ }
+
+ private static QpidFeatureBuilder createArgumentBuilder(Map<String, Object> argumentDefinition)
+ {
+ QpidFeatureBuilder result = new QpidFeatureBuilder(argumentDefinition);
+ result._state = result._argumentBuilder;
+ return result;
+ }
+
+
+ /**
+ * Builds new builder with the given data.
+ * This constructor is used for building properties, statistics and arguments.
+ *
+ * @param definition the feature definition data.
+ */
+ private QpidFeatureBuilder(Map<String, Object> definition)
+ {
+ this._featureDefinition = definition;
+ this._methodOrEventDefinition = null;
+ }
+
+ /**
+ * Builds new builder with the given data.
+ * This constructor is used for building properties, statistics and arguments.
+ *
+ * @param definition the feature definition data.
+ */
+ private QpidFeatureBuilder(MethodOrEventDataTransferObject definition)
+ {
+ this._featureDefinition = null;
+ this._methodOrEventDefinition = definition;
+ }
+
+ /**
+ * Returns the just built qpid feature.
+ *
+ * @return the qpid feature.
+ */
+ QpidFeature getQpidFeature()
+ {
+ return _qpidFeature;
+ }
+
+ /**
+ * Return the jmx metadata for the built feature.
+ *
+ * @return the jmx metadata for the built feature.
+ */
+ MBeanFeatureInfo getManagementFeature()
+ {
+ return _managementFeatureInfo;
+ }
+
+ void build() throws UnableToBuildFeatureException
+ {
+ _state.build();
+ }
+}
\ No newline at end of file
Added: incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/management/domain/model/QpidMethod.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/management/domain/model/QpidMethod.java?rev=700077&view=auto
==============================================================================
--- incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/management/domain/model/QpidMethod.java (added)
+++ incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/management/domain/model/QpidMethod.java Mon Sep 29 05:02:54 2008
@@ -0,0 +1,103 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.domain.model;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.qpid.transport.codec.ManagementEncoder;
+
+/**
+ * Qpid method definition.
+ * An entity describing an invocation that can be made on a managed object instance.
+ *
+ * @author Andrea Gazzarini
+ */
+class QpidMethod extends QpidFeature
+{
+ /** Argument list */
+ List<QpidArgument> arguments = new LinkedList<QpidArgument>();
+
+ /**
+ * Builds a new qpid method definition with the given name and description.
+ *
+ * @param name the method name.
+ * @param description the method description.
+ */
+ QpidMethod(String name, String description)
+ {
+ this._name = name;
+ this._description = description;
+ }
+
+ /**
+ * Adds an argument to this method.
+ *
+ * @param argument the new argument to be added.
+ */
+ void addArgument(QpidArgument argument)
+ {
+ arguments.add(argument);
+ }
+
+ /**
+ * Returns a string representation of this method.
+ * The result format is <method name>(argType1 argName1 (Direction), argType2 argName2 (Direction), etc...)
+ *
+ * @return a string representation of this method.
+ */
+ @Override
+ public String toString ()
+ {
+ StringBuilder builder = new StringBuilder()
+ .append(_name)
+ .append('(');
+
+ for (QpidArgument argument : arguments)
+ {
+ builder.append(argument).append(',');
+ }
+
+ builder.append(')');
+ return builder.toString();
+ }
+
+ /**
+ * Encodes the given parameter values according to this method arguments definitions.
+ * Also provide a validation of the given values according to the invariants defined for each argument.
+ * Note that only Input/Output and Output parameters are encoded.
+ *
+ * @param parameters the parameters values.
+ * @param encoder the encoder used for encoding.
+ * @throws ValidationException when one of the given values is violating an argument invariant.
+ */
+ void encodeParameters (Object[] parameters, ManagementEncoder encoder) throws ValidationException
+ {
+ int index = 0;
+ for (QpidArgument argument : arguments)
+ {
+ if (argument.getDirection() != Direction.O)
+ {
+ argument.validateAndEncode(parameters[index++],encoder);
+ }
+ }
+ }
+}
\ No newline at end of file
Added: incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/management/domain/model/QpidPackage.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/management/domain/model/QpidPackage.java?rev=700077&view=auto
==============================================================================
--- incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/management/domain/model/QpidPackage.java (added)
+++ incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/management/domain/model/QpidPackage.java Mon Sep 29 05:02:54 2008
@@ -0,0 +1,227 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.domain.model;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.qpid.management.domain.handler.impl.MethodOrEventDataTransferObject;
+import org.apache.qpid.management.domain.model.type.Binary;
+
+/**
+ * Qpid package definition.
+ * A grouping of class definitions that are related to a single software component.
+ * The package concept is used to extend the management schema beyond just the QPID software components.
+ * The name is prefixed with "Qpid" for avoiding name conficts with java.lang.Package.
+ *
+ * @author Andrea Gazzarini
+ */
+final class QpidPackage
+{
+ /**
+ * Qpid class identity.
+ * Each qpid class is uniquely identifier by its name and schema-hash.
+ * The schema hash is an MD5 checksum of the schema for a class.
+ * It is there so we can support the case where two different versions of the same class are present at the same time.
+ *
+ * @author Andrea Gazzarini
+ */
+ class QpidClassIdentity {
+ final String name;
+ final Binary hash;
+
+ /**
+ * Builds a new class identity with the given name and hash.
+ *
+ * @param name the class name.
+ * @param hash is an MD5 checksum of the schema of this outer class.
+ */
+ QpidClassIdentity(String name,Binary hash) {
+ this.name = name;
+ this.hash = hash;
+ }
+
+ @Override
+ public int hashCode ()
+ {
+ return name.hashCode()+hash.hashCode();
+ }
+
+ @Override
+ public boolean equals (Object obj)
+ {
+ QpidClassIdentity identity = (QpidClassIdentity) obj;
+ return name.equals(identity.name) && hash.equals(identity.hash);
+ }
+ }
+
+ private String _name;
+ private DomainModel _parent;
+ private Map<QpidClassIdentity, QpidClass> _classes = new HashMap<QpidClassIdentity, QpidClass>();
+
+ /**
+ * Builds a new package with the supplied name.
+ *
+ * @param name the name of the package.
+ */
+ QpidPackage(String name, DomainModel parent)
+ {
+ this._name = name;
+ this._parent = parent;
+ }
+
+ /**
+ * Returns the identifier of the broker which contains this package.
+ * @return
+ */
+ UUID getOwnerId()
+ {
+ return _parent.getBrokerId();
+ }
+
+ /**
+ * Returns the name of this package.
+ *
+ * @return the name of this package.
+ */
+ String getName ()
+ {
+ return _name;
+ }
+
+ /**
+ * Adds a class definition to this package.
+ * The class will be added only if its definition doesn't already exists.
+ *
+ * @param className the name of the class.
+ * @param classHash the class schema hash.
+ * @param properties the properties of the class.
+ * @param statistics the statistics of the class.
+ * @param methods the methods of the class.
+ * @param events the events of the class.
+ *
+ * @throws UnableToBuildFeatureException when the class definition cannot be built due to a feature build failure.
+ */
+ void addClassDefinition (
+ String className,
+ Binary classHash,
+ List<Map<String, Object>> properties,
+ List<Map<String, Object>> statistics,
+ List<MethodOrEventDataTransferObject> methods,
+ List<MethodOrEventDataTransferObject> events) throws UnableToBuildFeatureException
+ {
+ getQpidClass(className,classHash,true).setSchema(properties,statistics,methods, events);
+ }
+
+ /**
+ * Returns true if this package contains the given class definition.
+ *
+ * @param className the name of the class.
+ * @return true if this package contains the class definition, false otherwise.
+ */
+ boolean alreadyContainsClassDefinition (String className, Binary hash)
+ {
+ return _classes.containsKey(new QpidClassIdentity(className,hash));
+ }
+
+ /**
+ * Injects into a class the given object instance instrumentation data.
+ *
+ * @param className the of the class the injected object data belongs to.
+ * @param objectId the object identifier.
+ * @param rawData the instrumentation data (in raw format).
+ */
+ void setObjectInstanceInstrumentationRawData (String className, Binary classHash,Binary objectId, byte[] rawData)
+ {
+ getQpidClass(className, classHash,true).addInstrumentationData(objectId,rawData);
+ }
+
+ /**
+ * Injects into a class the given object instance configuration data.
+ *
+ * @param className the of the class the injected object data belongs to.
+ * @param objectId the object identifier.
+ * @param rawData the configuration data (in raw format).
+ */
+ void setObjectInstanceConfigurationRawData (String className,Binary classHash, Binary objectId, byte[] rawData)
+ {
+ getQpidClass(className,classHash,true).addConfigurationData(objectId,rawData);
+ }
+
+ /**
+ * Returns the definition of the class with given name.
+ *
+ * @param className the name of the class.
+ * @param hash the class hash.
+ * @param store a flag indicating if a just created class must be stored or not.
+ * @return the definition of the class with given name.
+ */
+ QpidClass getQpidClass(String className, Binary hash, boolean store)
+ {
+ QpidClassIdentity identity = new QpidClassIdentity(className,hash);
+ QpidClass classDefinition = _classes.get(identity);
+ if (classDefinition == null)
+ {
+ classDefinition = new QpidClass(className, hash,this);
+ if (store)
+ {
+ _classes.put(identity,classDefinition);
+ }
+ }
+ return classDefinition;
+ }
+
+ /**
+ * Returns a string representation of this class.
+ * That is, this method returns the simple name (not FQN) of this class.
+ */
+ @Override
+ public String toString ()
+ {
+ return _name;
+ }
+
+ /**
+ * Removes the object instance associated to the given parameters.
+ *
+ * @param className the class definition of the object instance.
+ * @param classHash the class hash
+ * @param objectId the object identifier.
+ */
+ void removeObjectInstance (String className, Binary classHash, Binary objectId)
+ {
+ QpidClass qpidClass = getQpidClass(className,classHash,false);
+ qpidClass.removeObjectInstance(objectId);
+ }
+
+ /**
+ * Releases all previously acquired resources of this package.
+ */
+ void releaseResources ()
+ {
+ for (QpidClass qpidClass : _classes.values())
+ {
+ qpidClass.releaseResources();
+ }
+ }
+}
\ No newline at end of file
Added: incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/management/domain/model/QpidProperty.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/management/domain/model/QpidProperty.java?rev=700077&view=auto
==============================================================================
--- incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/management/domain/model/QpidProperty.java (added)
+++ incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/management/domain/model/QpidProperty.java Mon Sep 29 05:02:54 2008
@@ -0,0 +1,295 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.domain.model;
+
+import java.lang.reflect.Constructor;
+
+import org.apache.qpid.management.configuration.Configuration;
+import org.apache.qpid.management.domain.model.type.Type;
+import org.apache.qpid.transport.codec.ManagementDecoder;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * Qpid property definition.
+ *
+ * @author Andrea Gazzarini
+ */
+class QpidProperty extends QpidAttribute
+{
+ private final static Logger LOGGER = Logger.get(QpidProperty.class);
+
+ private final static int [] MASKS = {1,2,4,8,16,32,64,128};
+
+ /**
+ * Decoder interface used for decoding incomng values for this property.
+ *
+ * @author Andrea Gazzarini
+ */
+ interface Decoder
+ {
+ Object decodeValue(ManagementDecoder decoder,byte [] presenceBitMasks);
+ }
+
+ /**
+ * Decoder used for decoding incoming values for this optional property.
+ */
+ final Decoder _optionalPropertyDecoder = new Decoder() {
+
+ public Object decodeValue (ManagementDecoder decoder, byte[] presenceBitMasks)
+ {
+ return ((presenceBitMasks[_optionalIndex/8] & MASKS[_maskIndex]) != 0)
+ ? QpidProperty.this.decodeValue(decoder)
+ : null;
+ }
+ };
+
+ /**
+ * Decoder used for decoding incoming values for this mandatory property.
+ */
+ final Decoder _mandatoryPropertyDecoder = new Decoder() {
+
+ public Object decodeValue (ManagementDecoder decoder, byte[] presenceBitMasks)
+ {
+ return QpidProperty.this.decodeValue(decoder);
+ }
+ };
+
+
+ /**
+ * Null object used to perform a dummy validation.
+ * This is the default validator installed at creation time.
+ */
+ final static IValidator EMPTY_VALIDATOR = new IValidator()
+ {
+ public void validate (Object value) throws ValidationException
+ {
+ // Nothing to do here.
+ }
+ };
+
+ /**
+ * Validator responsible for validating strings.
+ * At the moment the only constraint that should be applied to a string feature is the "max length"
+ */
+ class StringValidator implements IValidator
+ {
+ public void validate (Object value) throws ValidationException
+ {
+ if ((_maxLength != Integer.MIN_VALUE) && (value != null)){
+ int length = value.toString().length();
+ if (length > _maxLength) {
+ throw new ValidationException(
+ ValidationException.MAX_LENGTH,
+ _maxLength,
+ _name,
+ length);
+ }
+ }
+ }
+ };
+
+ /**
+ * Validator responsible for validating numbers.
+ */
+ class NumberValidator implements IValidator
+ {
+ public void validate (Object value) throws ValidationException
+ {
+ if (value != null) {
+ double numericValue = ((Number)value).doubleValue();
+ if (_minValue != Integer.MIN_VALUE && numericValue < _minValue) {
+ throw new ValidationException(
+ ValidationException.MIN_VALUE,
+ _minValue,
+ _name,
+ numericValue);
+ }
+
+ if (_maxValue != Integer.MIN_VALUE && numericValue > _maxValue) {
+ throw new ValidationException(
+ ValidationException.MAX_VALUE,
+ _maxValue,
+ _name,
+ numericValue);
+ }
+ }
+ }
+ };
+
+ private AccessMode _accessMode;
+ private int _minValue = Integer.MIN_VALUE;
+ private int _maxValue = Integer.MIN_VALUE;
+ private int _maxLength = Integer.MIN_VALUE;
+
+ private int _optionalIndex;
+ private int _maskIndex;
+
+ Decoder _decoder = _mandatoryPropertyDecoder;
+
+ private IValidator _validator = EMPTY_VALIDATOR;
+
+ /**
+ * Validates the given value according to the current validator.
+ * It delegates the validation to the current installed validator.
+ *
+ * @param value the value of this qpid property.
+ * @throws ValidationException when the given value is violating the current validator constraints.
+ */
+ void validate(Object value) throws ValidationException {
+ _validator.validate(value);
+ }
+
+ /**
+ * Sets the type of this property.
+ * In addition this method tries to detect if a validator has been associated with the type.
+ * If no validator is found then the default validator will be used; that is : no validator will be performed on this
+ * property.
+ *
+ * @param type the type of this property.
+ */
+ void setType (Type type)
+ {
+ super.setType(type);
+ try {
+ Class<?> validatorClass = Class.forName(Configuration.getInstance().getValidatorClassName(type));
+ Constructor<?> validatorConstructor = validatorClass.getDeclaredConstructor(QpidProperty.class);
+ _validator = (IValidator) validatorConstructor.newInstance(this);
+ LOGGER.debug("Validator %s for type %s successfully installed." ,validatorClass.getName(), type);
+ } catch(Exception exception) {
+ _validator = EMPTY_VALIDATOR;
+ LOGGER.debug("No validator was found for type %s. The default (empty) validator will be used." , type);
+ }
+ }
+
+ /**
+ * Gets the value of this property according to its type definition.
+ *
+ * @param decoder the decoder used to extract the value.
+ * @return the value of this feature according to its type definition
+ */
+ Object decodeValue(ManagementDecoder decoder,byte [] presenceBitMasks)
+ {
+ return _decoder.decodeValue(decoder, presenceBitMasks);
+ }
+
+ /**
+ * Sets access mode for this property.
+ *
+ * @param accessMode the access mode for this property.
+ */
+ void setAccessMode (AccessMode accessMode)
+ {
+ this._accessMode = accessMode;
+ }
+
+ /**
+ * Gets the minimum allowed value for this property.
+ *
+ * @return the minimum allowed value for this property.
+ */
+ int getMinValue ()
+ {
+ return _minValue;
+ }
+
+ /**
+ * Sets the minimum allowed value for this property.
+ *
+ * @param minValue the minimum allowed value for this property.
+ */
+ void setMinValue (int minValue)
+ {
+ this._minValue = minValue;
+ }
+
+ /**
+ * Gets the maximum allowed value for this property.
+ *
+ * @return the maximum allowed value for this property.
+ */
+ int getMaxValue ()
+ {
+ return _maxValue;
+ }
+
+ /**
+ * Sets the masimum allowed value for this property.
+ *
+ * @param maxValue the maximum allowed value for this property.
+ */
+ void setMaxValue (int maxValue)
+ {
+ this._maxValue = maxValue;
+ }
+
+ /**
+ * Gets the max length value for this property.
+ *
+ * @return the max length value for this property.
+ */
+ int getMaxLength ()
+ {
+ return _maxLength;
+ }
+
+ /**
+ * Sets the max length value for this property.
+ *
+ * @param maxLength the max length value for this property.
+ */
+ void setMaxLength (int maxLength)
+ {
+ this._maxLength = maxLength;
+ }
+
+ /**
+ * Gets the description of this property.
+ *
+ * @return the description of this property.
+ */
+ AccessMode getAccessMode ()
+ {
+ return _accessMode;
+ }
+
+ /**
+ * Marks this property as optional.
+ *
+ * @param optional the optional attribute value for this property.
+ * @param index the index of this optional property
+ */
+ void markAsOptional (int index)
+ {
+ this._optionalIndex = index;
+ this._maskIndex = (_optionalIndex >= 8) ? _optionalIndex-8 : _optionalIndex;
+ _decoder = _optionalPropertyDecoder;
+ }
+
+ /**
+ * Returns true if this property is marked as optional.
+ *
+ * @return true if this property is marked as optional, false otherwise.
+ */
+ boolean isOptional ()
+ {
+ return _decoder == _optionalPropertyDecoder;
+ }
+}
\ No newline at end of file
Added: incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/management/domain/model/QpidStatistic.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/management/domain/model/QpidStatistic.java?rev=700077&view=auto
==============================================================================
--- incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/management/domain/model/QpidStatistic.java (added)
+++ incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/management/domain/model/QpidStatistic.java Mon Sep 29 05:02:54 2008
@@ -0,0 +1,34 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.domain.model;
+
+/**
+ * Qpid statistic definition.
+ *
+ * A statistic is a typed member of a class which represents an instrumentation attribute of the class.
+ * Statistics are always read-only in nature and tend to change rapidly.
+ *
+ * @author Andrea Gazzarini
+ */
+class QpidStatistic extends QpidAttribute
+{
+ // EMPTY CLASS : Statistic metadata are all defined in superclasses.
+}
\ No newline at end of file
Added: incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/management/domain/model/UnableToBuildFeatureException.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/management/domain/model/UnableToBuildFeatureException.java?rev=700077&view=auto
==============================================================================
--- incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/management/domain/model/UnableToBuildFeatureException.java (added)
+++ incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/management/domain/model/UnableToBuildFeatureException.java Mon Sep 29 05:02:54 2008
@@ -0,0 +1,51 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.domain.model;
+
+/**
+ * Thrown when a feature (property, statistic, method or event) definition cannot be built due to schema parsing errors.
+ *
+ * @author Andrea Gazzarini
+ */
+public class UnableToBuildFeatureException extends Exception
+{
+ private static final long serialVersionUID = 5180111828887602836L;
+
+ /**
+ * Builds a new UnableToBuildFeatureException with the specified cause.
+ *
+ * @param exception the exception cause.
+ */
+ UnableToBuildFeatureException(Exception exception, String featureName)
+ {
+ super( (featureName != null) ? featureName : "Not available" ,exception);
+ }
+
+ /**
+ * Builds a new UnableToBuildFeatureException with the specified message.
+ *
+ * @param message the detail message.
+ */
+ UnableToBuildFeatureException(String message)
+ {
+ super(message);
+ }
+}
\ No newline at end of file
Added: incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/management/domain/model/ValidationException.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/management/domain/model/ValidationException.java?rev=700077&view=auto
==============================================================================
--- incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/management/domain/model/ValidationException.java (added)
+++ incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/management/domain/model/ValidationException.java Mon Sep 29 05:02:54 2008
@@ -0,0 +1,105 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.domain.model;
+
+/**
+ * Thrown when an attempt is made in order to update / change the state of an object and a constraint on that state
+ * is violated.
+ *
+ * @author Andrea Gazzarini
+ */
+public class ValidationException extends Exception
+{
+ private static final long serialVersionUID = -5218828669655586205L;
+
+ public final static String MAX_LENGTH = "Max Length";
+ public final static String MAX_VALUE = "Max Value";
+ public final static String MIN_VALUE = "Min Value";
+
+ private final String _featureName;
+ private final Object _featureValue;
+
+ private final Number _constraintValue;
+ private final String _constraintName;
+
+ /**
+ * Builds a new validation exception with the specified parameters.
+ *
+ * @param constraintName the name of the violated constraint.
+ * @param constraintValue the value of the violated constraint.
+ * @param featureName the name of the violating feature.
+ * @param featureValue the value of the violating feature.
+ */
+ ValidationException(String constraintName,Number constraintValue, String featureName,Object featureValue)
+ {
+ super(String.format(
+ "Property constraint violation : " +
+ "%s allowed for property %s is %s but received value was %s",
+ constraintName,
+ featureName,
+ constraintValue,
+ featureValue));
+ this._constraintName = constraintName;
+ this._constraintValue = constraintValue;
+ this._featureName = featureName;
+ this._featureValue = featureValue;
+ }
+
+ /**
+ * Returns the value of the violating feature.
+ *
+ * @return the value of the violating feature.
+ */
+ public Object getFeatureValue ()
+ {
+ return _featureValue;
+ }
+
+ /**
+ * Returns the name of the violating feature.
+ *
+ * @return the name of the violating feature.
+ */
+ public String getFeatureName()
+ {
+ return _featureName;
+ }
+
+ /**
+ * Returns the value of the violated constraint.
+ *
+ * @return the value of the violated constraint.
+ */
+ public Number getConstraintValue ()
+ {
+ return _constraintValue;
+ }
+
+ /**
+ * Returns the name of the violated constraint.
+ *
+ * @return the name of the violated constraint.
+ */
+ public String getConstraintName ()
+ {
+ return _constraintName;
+ }
+}
\ No newline at end of file