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