You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by tr...@apache.org on 2009/06/16 23:03:25 UTC

svn commit: r785400 [2/2] - in /qpid/trunk/qpid/java: ./ agent/ management/agent/ management/agent/src/ management/agent/src/main/ management/agent/src/main/java/ management/agent/src/main/java/org/ management/agent/src/main/java/org/apache/ management...

Added: qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ClassBinding.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ClassBinding.java?rev=785400&view=auto
==============================================================================
--- qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ClassBinding.java (added)
+++ qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ClassBinding.java Tue Jun 16 21:03:24 2009
@@ -0,0 +1,602 @@
+/*
+ *
+ * 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.agent.binding;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.qpid.agent.annotations.QMFEvent;
+import org.apache.qpid.agent.annotations.QMFObject;
+import org.apache.qpid.agent.annotations.QMFProperty;
+import org.apache.qpid.agent.annotations.QMFSeeAlso;
+import org.apache.qpid.agent.annotations.QMFType;
+import org.apache.qpid.agent.annotations.QMFHide;
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+/**
+ * Binding information from a custom java class to a QMF schema
+ */
+public class ClassBinding implements TypeBinding
+{
+    private static Log log = LogFactory.getLog(ClassBinding.class);
+
+    private static enum MethodType
+    {
+        READ_ONLY, READ_WRITE, METHOD, IGNORE
+    }
+
+    protected boolean exposeBehaviour = true;
+    protected String pkg;
+    protected BindingContext bctx;
+    protected String name;
+    protected ArrayList<PropertyBinding> properties = new ArrayList<PropertyBinding>();
+    protected ArrayList<MethodBinding> methods = new ArrayList<MethodBinding>();
+    protected Map<String, MethodBinding> methodsByName = new HashMap<String, MethodBinding>();
+    protected Class javaClass;
+    protected short kind = 1;
+    protected byte hash[] = null;
+    protected ClassBinding superType = null;
+
+    public ClassBinding(String pkg, String name, Class cls,
+            boolean exposeBehaviour, BindingContext bctx)
+    {
+        this.pkg = pkg;
+        this.name = name;
+        this.bctx = bctx;
+        this.javaClass = cls;
+        this.exposeBehaviour = exposeBehaviour;
+    }
+
+    protected MethodType classify(Class<?> cls, Method m)
+    {
+        String name = m.getName();
+        MethodType returnValue = MethodType.METHOD;
+        String propPrefixes[] =
+        { "get", "is" };
+        for (String prefix : propPrefixes)
+        {
+            if (name.startsWith(prefix) && m.getParameterTypes().length == 0)
+            {
+                try
+                {
+                    Class<?> type = m.getReturnType();
+                    Method setter = cls.getMethod("set"
+                            + name.substring(prefix.length()), type);
+                    returnValue = MethodType.READ_WRITE;
+                } catch (NoSuchMethodException e)
+                {
+                    returnValue = MethodType.READ_ONLY;
+                }
+                break;
+            }
+        }
+        return returnValue;
+    }
+
+    protected String property(Method m)
+    {
+        String name = m.getName();
+        String propPrefixes[] =
+        { "get", "is" };
+        for (String prefix : propPrefixes)
+        {
+            if (name.startsWith(prefix) && m.getParameterTypes().length == 0)
+            {
+                String sfx = name.substring(prefix.length());
+                return Character.toLowerCase(sfx.charAt(0)) + sfx.substring(1);
+            }
+        }
+        // If we got here, it is n invalid property
+        throw new IllegalArgumentException("" + m);
+    }
+
+    protected ArrayList<Method> getMethods(Class cls)
+    {
+        ArrayList returnValue = new ArrayList();
+        ArrayList nameList = new ArrayList();
+        if ((cls != null) && (!cls.equals(Object.class)))
+        {
+            for (Method m : cls.getDeclaredMethods())
+            {
+                if (m.getAnnotation(QMFHide.class) == null)
+                // && (!Modifier.isAbstract(m.getModifiers())))
+                {
+                    returnValue.add(m);
+                    nameList.add(m.getName());
+                }
+            }
+            // Look at the superclass, if it is also a
+            // QMF object then stop.
+            Class superType = cls.getSuperclass();
+            if (!this.hasQMFSupertype(cls))
+            {
+                for (Method m : this.getMethods(cls.getSuperclass()))
+                {
+                    if (!nameList.contains(m.getName()))
+                    {
+                        returnValue.add(m);
+                        nameList.add(m.getName());
+                    }
+                }
+            }
+        }
+        return returnValue;
+    }
+
+    protected boolean hasQMFSupertype(Class cls)
+    {
+        boolean returnValue = false;
+        Class superType = cls.getSuperclass();
+        if (superType != null)
+        {
+            if ((superType.getAnnotation(QMFObject.class) != null)
+                    || (superType.getAnnotation(QMFType.class) != null)
+                    || (superType.getAnnotation(QMFSeeAlso.class) != null)
+                    || (superType.getAnnotation(QMFEvent.class) != null))
+            {
+                returnValue = true;
+            }
+        }
+        return returnValue;
+    }
+
+    protected boolean isOptional(Method m, TypeBinding type)
+    {
+        boolean returnValue = false;
+        // Look for the annotaiton first
+        QMFProperty ann = m.getAnnotation(QMFProperty.class);
+        if (ann != null)
+        {
+            returnValue = ann.optional();
+        } else
+        {
+            returnValue = type.optionalDefault();
+        }
+        return returnValue;
+    }
+
+    public ClassBinding parse()
+    {
+        log.debug(String.format(
+                "Parsing class binding '%s' for package '%s' from class %s",
+                name, pkg, javaClass.getName()));
+        for (Method m : this.getMethods(javaClass))
+        {
+            String mname = m.getName();
+            Class<?> type = m.getReturnType();
+            switch (classify(javaClass, m))
+            {
+            case READ_ONLY:
+                TypeBinding tb = bctx.getTypeBinding(type);
+                boolean optional = isOptional(m, tb);
+                properties.add(new PropertyBinding(property(m), tb,
+                        PropertyBinding.READ_ONLY, optional));
+                break;
+            case READ_WRITE:
+                TypeBinding tbnd = bctx.getTypeBinding(type);
+                boolean opt = isOptional(m, tbnd);
+                properties.add(new PropertyBinding(property(m), tbnd,
+                        PropertyBinding.READ_WRITE, opt));
+                break;
+            case METHOD:
+                // Only expose methods if told to
+                if (exposeBehaviour)
+                {
+                    List<ParameterBinding> params = new ArrayList<ParameterBinding>();
+                    int arg = 0;
+                    for (Class pcls : m.getParameterTypes())
+                    {
+                        params.add(new ParameterBinding("arg" + arg++, bctx
+                                .getTypeBinding(pcls), true, false));
+                    }
+                    if (type != void.class)
+                    {
+                        params.add(new ParameterBinding("result", bctx
+                                .getTypeBinding(type), false, true));
+                    }
+                    methods.add(new MethodBinding(mname, params));
+                }
+                break;
+            case IGNORE:
+                break;
+            }
+        }
+        for (MethodBinding m : methods)
+        {
+            methodsByName.put(m.getName(), m);
+        }
+        QMFEvent eventAnnotation = (QMFEvent) javaClass
+                .getAnnotation(QMFEvent.class);
+        if (eventAnnotation != null)
+        {
+            kind = 2; // Event Type
+        }
+        // if (this.hasQMFSupertype(javaClass)) {
+        if ((javaClass.getSuperclass() != Object.class)
+                && (javaClass.getSuperclass() != null))
+        {
+            superType = bctx.register(javaClass.getSuperclass());
+        }
+        return this;
+    }
+
+    public String getPackage()
+    {
+        return pkg;
+    }
+
+    public String getName()
+    {
+        return name;
+    }
+
+    public List<PropertyBinding> getProperties()
+    {
+        return properties;
+    }
+
+    public List<PropertyBinding> getAllProperties()
+    {
+        if (this.superType == null)
+        {
+            return properties;
+        } else
+        {
+            List<PropertyBinding> newList = new ArrayList<PropertyBinding>(
+                    properties);
+            for (PropertyBinding p : superType.getAllProperties())
+            {
+                if (!newList.contains(p))
+                {
+                    newList.add(p);
+                }
+            }
+            return newList;
+        }
+    }
+
+    public List<MethodBinding> getMethods()
+    {
+        return methods;
+    }
+
+    public MethodBinding getMethod(String name)
+    {
+        return methodsByName.get(name);
+    }
+
+    // Use this format
+    // bytes value
+    // 0-3 package name
+    // 4-7 class name
+    // 8-11 property signature hash
+    // 12-15 method signature hash
+    // FIXME: Hash codes seem to mess things up
+    public byte[] getSchemaHash()
+    {
+        if (null == hash)
+        {
+            hash = new byte[16];
+            StringBuilder blder = new StringBuilder();
+            int packageHash = pkg.hashCode();
+            int classHash = name.hashCode();
+            int propertyHash = 0;
+            int methodHash = 0;
+            for (PropertyBinding p : properties)
+            {
+                blder.append(p.getName()).append(":").append(
+                        p.getType().getCode()).append(":")
+                        .append(p.getAccess()).append(":").append(
+                                p.isOptional());
+            }
+            propertyHash = blder.toString().hashCode();
+            blder = new StringBuilder();
+            for (MethodBinding m : methods)
+            {
+                blder.append(m.getName());
+                for (ParameterBinding p : m.getParameters())
+                {
+                    String direction = p.isIn() ? "in" : "out";
+                    blder.append(":").append(p.getName()).append(":").append(
+                            direction).append(":")
+                            .append(p.getType().getCode());
+                }
+            }
+            methodHash = blder.toString().hashCode();
+            hash[0] = (byte) (packageHash >> 24);
+            hash[1] = (byte) (packageHash >> 16);
+            hash[2] = (byte) (packageHash >> 8);
+            hash[3] = (byte) (packageHash);
+            hash[4] = (byte) (classHash >> 24);
+            hash[5] = (byte) (classHash >> 16);
+            hash[6] = (byte) (classHash >> 8);
+            hash[7] = (byte) (classHash);
+            hash[8] = (byte) (propertyHash >> 24);
+            hash[9] = (byte) (propertyHash >> 16);
+            hash[10] = (byte) (propertyHash >> 8);
+            hash[11] = (byte) (propertyHash);
+            hash[12] = (byte) (methodHash >> 24);
+            hash[13] = (byte) (methodHash >> 16);
+            hash[14] = (byte) (methodHash >> 8);
+            hash[15] = (byte) (methodHash);
+        }
+        return hash;
+    }
+
+    public void encode(Encoder enc)
+    {
+        log.debug(String.format("encoding %s %s with superclass %s", this
+                .getRefClass(), this.getRefPackage(), superType));
+        enc.writeUint8(kind); // kind
+        enc.writeStr8(pkg);
+        enc.writeStr8(name);
+        enc.writeBin128(this.getSchemaHash()); // schema hash
+        // Send true (1) if we have a super-type
+        if (superType == null)
+        {
+            enc.writeUint8((short) 0);
+        } else
+        {
+            enc.writeUint8((short) 1);
+        }
+        enc.writeUint16(properties.size());
+        // Events do not have the method size sent
+        if (kind == 1)
+        {
+            enc.writeUint16(0);
+            enc.writeUint16(methods.size());
+        }
+        // Add the super type information if we have it
+        if (superType != null)
+        {
+            enc.writeStr8(superType.pkg);
+            enc.writeStr8(superType.name);
+            enc.writeBin128(superType.getSchemaHash()); // schema hash
+        }
+        for (PropertyBinding p : properties)
+        {
+            log.trace("encoding property " + p.getName());
+            p.encode(enc);
+        }
+        for (MethodBinding m : methods)
+        {
+            m.encode(enc);
+        }
+    }
+
+    // Type Binding functions
+    public short getCode()
+    {
+        return (short) 20;
+    }
+
+    public Class<?> getJavaClass()
+    {
+        return javaClass;
+    }
+
+    public Object decode(Decoder dec)
+    {
+        // FIXME This only works with POJOs
+        short typeCode = dec.readUint8();
+        log.trace("Type code: " + typeCode);
+        if (typeCode == 20)
+        {
+            String packageName = dec.readStr8();
+            String className = dec.readStr8();
+            log
+                    .debug(String
+                            .format(
+                                    "Decoding an object for package %s class %s with bindings for %s %s",
+                                    packageName, className, this.pkg, this.name));
+            byte schemaHash[] = dec.readBin128();
+            // Check to see that this is me, and not a subclass
+            if (packageName.equals(this.pkg) && className.equals(this.name))
+            {
+                return decodeWithNoHeaders(dec);
+            } else
+            {
+                ClassBinding mcls = bctx
+                        .getClassBinding(packageName, className);
+                return mcls.decodeWithNoHeaders(dec);
+            }
+        } else
+        {
+            TypeBinding tb = QMFTypeBinding.getType(typeCode);
+            return tb.decode(dec);
+        }
+    }
+
+    protected Object decodeWithNoHeaders(Decoder dec)
+    {
+        Object instance = null;
+        try
+        {
+            log.trace("Creating a new instance of " + this.javaClass.getName());
+            instance = this.javaClass.newInstance();
+        } catch (Exception e)
+        {
+            log.error("Could not instantiate object of class"
+                    + this.javaClass.getName());
+            throw new BindingException(e);
+        }
+        List<String> excludes = this.processPresenceMasks(dec);
+        for (PropertyBinding p : getAllProperties())
+        {
+            if (!excludes.contains(p.getName()))
+            {
+                Object value = p.getType().decode(dec);
+                BindingUtils.set(p, value, instance);
+            }
+        }
+        return instance;
+    }
+
+    protected List<String> processPresenceMasks(Decoder dec)
+    {
+        List<String> excludes = new ArrayList<String>();
+        short bit = 0;
+        short mask = 0;
+        for (PropertyBinding prop : properties)
+        {
+            if (prop.isOptional())
+            {
+                if (bit == 0)
+                {
+                    mask = dec.readUint8();
+                    bit = 1;
+                }
+                if ((mask & bit) == 0)
+                {
+                    log.trace("Going in exlude " + prop.getName());
+                    excludes.add(prop.getName());
+                }
+                bit *= 2;
+                if (bit == 256)
+                {
+                    bit = 0;
+                }
+            }
+        }
+        return excludes;
+    }
+
+    public void encode(Encoder enc, Object value)
+    {
+        // if the object is null, assume this is the
+        // correct class
+        if (value == null || (value.getClass().equals(this.javaClass)))
+        {
+            String pkg = getPackage();
+            String cls = getName();
+            log.debug(String.format("Encoding class %s:%s", pkg, cls));
+            enc.writeUint8(this.getCode());
+            enc.writeStr8(pkg);
+            enc.writeStr8(cls);
+            enc.writeBin128(this.getSchemaHash());
+            short bit = 0;
+            short mask = 0;
+            if (value != null)
+            {
+                // Encode the property presence masks first.
+                // if this is not an event
+                if (!isEvent())
+                {
+                    for (PropertyBinding p : getAllProperties())
+                    {
+                        if (p.isOptional())
+                        {
+                            Object pValue = BindingUtils.get(p, value);
+                            if (bit == 0)
+                                bit = 1;
+                            if (pValue != null)
+                            {
+                                mask |= bit;
+                            }
+                            if (bit == 128)
+                            {
+                                enc.writeUint8(mask);
+                                bit = 0;
+                                mask = 0;
+                            } else
+                            {
+                                bit = (short) (bit << 1);
+                            }
+                        }
+                    }
+                    if (bit != 0)
+                    {
+                        enc.writeUint8(mask);
+                    }
+                }
+                // Now put the actual properties
+                for (PropertyBinding p : getAllProperties())
+                {
+                    Object pValue = BindingUtils.get(p, value);
+                    if (!p.isOptional() || !(pValue == null))
+                    {
+                        log.trace(String.format("Encoding property %s", p
+                                .getName()));
+                        p.getType().encode(enc, pValue);
+                    }
+                }
+            }
+            log.debug(String.format("Done with %s:%s", pkg, cls));
+        } else
+        {
+            TypeBinding tb = bctx.getTypeBinding(value.getClass());
+            if (tb == null)
+            {
+                throw new BindingException(String.format(
+                        "No class named %s defined for this context ", value
+                                .getClass()));
+            } else
+            {
+                if (tb.isNative())
+                {
+                    enc.writeUint8(tb.getCode());
+                }
+                tb.encode(enc, value);
+            }
+        }
+    }
+
+    public boolean isNative()
+    {
+        return false;
+    }
+
+    public boolean optionalDefault()
+    {
+        return true;
+    }
+
+    public String getRefClass()
+    {
+        return this.name;
+    }
+
+    public String getRefPackage()
+    {
+        return this.pkg;
+    }
+
+    public short getKind()
+    {
+        return kind;
+    }
+
+    public boolean isEvent()
+    {
+        return kind == 2;
+    }
+
+    public void setKind(short kind)
+    {
+        this.kind = kind;
+    }
+}

Added: qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/EnumBinding.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/EnumBinding.java?rev=785400&view=auto
==============================================================================
--- qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/EnumBinding.java (added)
+++ qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/EnumBinding.java Tue Jun 16 21:03:24 2009
@@ -0,0 +1,102 @@
+/*
+ *
+ * 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.agent.binding;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+/**
+ * Binding information from a java enum to a QMF schema
+ */
+public class EnumBinding extends ClassBinding
+{
+    private static Log log = LogFactory.getLog(EnumBinding.class);
+
+    public EnumBinding(String pkg, String name, Class cls,
+            boolean exposeBehaviour, BindingContext bctx)
+    {
+        super(pkg, name, cls, exposeBehaviour, bctx);
+    }
+
+    @Override
+    public void encode(Encoder enc)
+    {
+        enc.writeUint8((short) 1); // kind
+        enc.writeStr8(pkg);
+        enc.writeStr8(name);
+        enc.writeBin128(new byte[16]); // schema hash
+        // FIXME Is there a way to send the valid types?
+    }
+
+    @Override
+    public void encode(Encoder enc, Object value)
+    {
+        if (value != null)
+        {
+            enc.writeStr16(value.toString());
+        } else
+        {
+            enc.writeStr16("");
+        }
+    }
+
+    @Override
+    public Object decode(Decoder dec)
+    {
+        // FIXME This only works with POJOs
+        Object instance = null;
+        try
+        {
+            String value = dec.readStr16();
+            instance = Enum.valueOf((Class<Enum>) this.getJavaClass(), value);
+        } catch (Exception e)
+        {
+            log.error("Could not create an enum of type "
+                    + this.javaClass.getName());
+            throw new BindingException(e);
+        }
+        return instance;
+    }
+
+    // Make this look like a String
+    @Override
+    public short getCode()
+    {
+        return (short) 7;
+    }
+
+    @Override
+    public EnumBinding parse()
+    {
+        log.debug(String.format(
+                "Parsing enum binding '%s' for package '%s' from class %s",
+                name, pkg, javaClass.getName()));
+        return this;
+    }
+
+    @Override
+    public boolean optionalDefault()
+    {
+        return false;
+    }
+}

Added: qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ListBinding.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ListBinding.java?rev=785400&view=auto
==============================================================================
--- qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ListBinding.java (added)
+++ qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ListBinding.java Tue Jun 16 21:03:24 2009
@@ -0,0 +1,130 @@
+/*
+ *
+ * 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.agent.binding;
+
+import java.nio.ByteBuffer;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.qpid.transport.codec.BBDecoder;
+import org.apache.qpid.transport.codec.BBEncoder;
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+/**
+ * Binding information from a java list to a QMF schema.
+ */
+public class ListBinding implements TypeBinding
+{
+    private static Log log = LogFactory.getLog(ListBinding.class);
+    protected BindingContext bctx;
+    protected Class javaClass;
+
+    public ListBinding(BindingContext bctx, Class javaClass)
+    {
+        this.bctx = bctx;
+        this.javaClass = javaClass;
+    }
+
+    public void encode(Encoder enc, Object value)
+    {
+        List list = (List) value;
+        BBEncoder newEncoder = new BBEncoder(10);
+        if (list != null) {
+            newEncoder.writeUint32(list.size());
+            for (Object obj : list)
+            {
+                TypeBinding type = bctx.getTypeBinding(obj.getClass());
+                newEncoder.writeUint8(type.getCode());
+                type.encode(newEncoder, obj);
+            }
+        }
+        else {
+            newEncoder.writeUint32(0) ;
+        }
+        enc.writeVbin32(newEncoder.buffer().array());
+    }
+
+    public Object decode(Decoder dec)
+    {
+        List list = null;
+        try
+        {
+            list = (List) javaClass.newInstance();
+        } catch (Exception e)
+        {
+            throw new BindingException(
+                    "Could not create a List implementation for "
+                            + javaClass.getName(), e);
+        }
+        BBDecoder newDecoder = new BBDecoder();
+        newDecoder.init(ByteBuffer.wrap(dec.readVbin32()));
+        long count = newDecoder.readUint32();
+        while (count > 0)
+        {
+            short typeCode = newDecoder.readUint8();
+            TypeBinding type = QMFTypeBinding.getType(typeCode);
+            if (type == null)
+            {
+                type = bctx.getTypeBinding(Object.class);
+            }
+            list.add(type.decode(newDecoder));
+            count -= 1;
+        }
+        return list;
+    }
+
+    // QMF List Type
+    public short getCode()
+    {
+        return (short) 21;
+    }
+
+    @Override
+    public Class<?> getJavaClass()
+    {
+        return javaClass;
+    }
+
+    @Override
+    public String getRefClass()
+    {
+        return null;
+    }
+
+    @Override
+    public String getRefPackage()
+    {
+        return null;
+    }
+
+    @Override
+    public boolean isNative()
+    {
+        return true;
+    }
+
+    public boolean optionalDefault()
+    {
+        return false;
+    }
+}

Added: qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/MapBinding.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/MapBinding.java?rev=785400&view=auto
==============================================================================
--- qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/MapBinding.java (added)
+++ qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/MapBinding.java Tue Jun 16 21:03:24 2009
@@ -0,0 +1,136 @@
+/*
+ *
+ * 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.agent.binding;
+
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.qpid.transport.codec.BBDecoder;
+import org.apache.qpid.transport.codec.BBEncoder;
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+/**
+ * Binding information from a java Map to a QMF schema.
+ */
+public class MapBinding implements TypeBinding
+{
+    private static Log log = LogFactory.getLog(MapBinding.class);
+    protected BindingContext bctx;
+    protected Class javaClass;
+
+    public MapBinding(BindingContext bctx, Class javaClass)
+    {
+        this.bctx = bctx;
+        this.javaClass = javaClass;
+    }
+
+    @SuppressWarnings("unchecked")
+    public void encode(Encoder enc, Object value)
+    {
+        Map map = (Map) value;
+        BBEncoder newEncoder = new BBEncoder(10);
+        newEncoder.writeUint32(map.size());
+        for (Object key : map.keySet())
+        {
+            String keyString = key.toString();
+            Object mapValue = map.get(key);
+            TypeBinding binding = bctx.getTypeBinding(mapValue.getClass());
+            newEncoder.writeStr8(keyString);
+            newEncoder.writeUint8(binding.getCode());
+            binding.encode(newEncoder, mapValue);
+        }
+        enc.writeVbin32(newEncoder.buffer().array());
+    }
+
+    public Object decode(Decoder dec)
+    {
+        Map map = null;
+        try
+        {
+            if (javaClass.isInterface())
+            {
+                map = new HashMap();
+            } else
+            {
+                map = (Map) javaClass.newInstance();
+            }
+        } catch (Exception e)
+        {
+            throw new BindingException(
+                    "Could not create a Map implementation for "
+                            + javaClass.getName(), e);
+        }
+        BBDecoder newDecoder = new BBDecoder();
+        newDecoder.init(ByteBuffer.wrap(dec.readVbin32()));
+        long count = newDecoder.readUint32();
+        while (count > 0)
+        {
+            String key = newDecoder.readStr8();
+            short typeCode = newDecoder.readUint8();
+            TypeBinding type = QMFTypeBinding.getType(typeCode);
+            if (type == null)
+            {
+                type = bctx.getTypeBinding(Object.class);
+            }
+            map.put(key, type.decode(newDecoder));
+            count -= 1;
+        }
+        return map;
+    }
+
+    // QMF List Type
+    public short getCode()
+    {
+        return (short) 15;
+    }
+
+    @Override
+    public Class<?> getJavaClass()
+    {
+        return javaClass;
+    }
+
+    @Override
+    public String getRefClass()
+    {
+        return null;
+    }
+
+    @Override
+    public String getRefPackage()
+    {
+        return null;
+    }
+
+    @Override
+    public boolean isNative()
+    {
+        return true;
+    }
+
+    public boolean optionalDefault()
+    {
+        return false;
+    }
+}

Added: qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/MethodBinding.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/MethodBinding.java?rev=785400&view=auto
==============================================================================
--- qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/MethodBinding.java (added)
+++ qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/MethodBinding.java Tue Jun 16 21:03:24 2009
@@ -0,0 +1,91 @@
+/*
+ *
+ * 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.agent.binding;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.qpid.transport.codec.Encoder;
+
+/**
+ * Metadata for mapping a method to a QMF schema
+ */
+public class MethodBinding
+{
+    private final String name;
+    private final List<ParameterBinding> parameters;
+    private final List<ParameterBinding> inParameters = new ArrayList<ParameterBinding>();
+    private final List<ParameterBinding> outParameters = new ArrayList<ParameterBinding>();
+    private Log log = LogFactory.getLog(MethodBinding.class);
+
+    public MethodBinding(String name, List<ParameterBinding> parameters)
+    {
+        this.name = name;
+        this.parameters = parameters;
+        for (ParameterBinding p : parameters)
+        {
+            if (p.isIn())
+            {
+                inParameters.add(p);
+            }
+            if (p.isOut())
+            {
+                outParameters.add(p);
+            }
+        }
+    }
+
+    public String getName()
+    {
+        return name;
+    }
+
+    public List<ParameterBinding> getParameters()
+    {
+        return parameters;
+    }
+
+    public List<ParameterBinding> getInParameters()
+    {
+        return inParameters;
+    }
+
+    public List<ParameterBinding> getOutParameters()
+    {
+        return outParameters;
+    }
+
+    void encode(Encoder enc)
+    {
+        Map map = new HashMap();
+        map.put("name", name);
+        map.put("argCount", parameters.size());
+        enc.writeMap(map);
+        for (ParameterBinding p : parameters)
+        {
+            p.encode(enc);
+        }
+    }
+}

Added: qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ParameterBinding.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ParameterBinding.java?rev=785400&view=auto
==============================================================================
--- qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ParameterBinding.java (added)
+++ qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ParameterBinding.java Tue Jun 16 21:03:24 2009
@@ -0,0 +1,121 @@
+/*
+ *
+ * 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.agent.binding;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.qpid.transport.codec.Encoder;
+
+/**
+ * Metadata for mapping a method argument to a QMF schema
+ */
+public class ParameterBinding
+{
+    private final String name;
+    private final TypeBinding type;
+    private final boolean in;
+    private final boolean out;
+
+    public ParameterBinding(String name, TypeBinding type, boolean in,
+            boolean out)
+    {
+        this.name = name;
+        this.type = type;
+        this.in = in;
+        this.out = out;
+    }
+
+    public String getName()
+    {
+        return name;
+    }
+
+    public TypeBinding getType()
+    {
+        return type;
+    }
+
+    public boolean isIn()
+    {
+        return in;
+    }
+
+    public boolean isOut()
+    {
+        return out;
+    }
+
+    void encode(Encoder enc)
+    {
+        Map map = new HashMap();
+        map.put("name", name);
+        map.put("type", type.getCode());
+        map.put("dir", (in ? "I" : "") + (out ? "O" : ""));
+        if (!type.isNative())
+        {
+            map.put("refClass", type.getRefClass());
+            map.put("refPackage", type.getRefPackage());
+        }
+        enc.writeMap(map);
+    }
+
+    @Override
+    public int hashCode()
+    {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + (in ? 1231 : 1237);
+        result = prime * result + ((name == null) ? 0 : name.hashCode());
+        result = prime * result + (out ? 1231 : 1237);
+        result = prime * result + ((type == null) ? 0 : type.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj)
+    {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        ParameterBinding other = (ParameterBinding) obj;
+        if (in != other.in)
+            return false;
+        if (name == null)
+        {
+            if (other.name != null)
+                return false;
+        } else if (!name.equals(other.name))
+            return false;
+        if (out != other.out)
+            return false;
+        if (type == null)
+        {
+            if (other.type != null)
+                return false;
+        } else if (!type.equals(other.type))
+            return false;
+        return true;
+    }
+}

Added: qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/PropertyBinding.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/PropertyBinding.java?rev=785400&view=auto
==============================================================================
--- qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/PropertyBinding.java (added)
+++ qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/PropertyBinding.java Tue Jun 16 21:03:24 2009
@@ -0,0 +1,132 @@
+/*
+ *
+ * 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.agent.binding;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.qpid.transport.codec.Encoder;
+
+
+/**
+ * Metadata for mapping a java property (getter/setter) to a QMF schema
+ */
+public class PropertyBinding
+{
+    private static Log log = LogFactory.getLog(PropertyBinding.class);
+    public final static int READ_CREATE = 1;
+    public final static int READ_WRITE = 2;
+    public final static int READ_ONLY = 3;
+    private String name;
+    private TypeBinding type;
+    private int accessType;
+    private boolean optional;
+
+    public PropertyBinding(String name, TypeBinding type, int accessType,
+            boolean optional)
+    {
+        this.name = name;
+        this.type = type;
+        this.accessType = accessType;
+        this.optional = optional;
+    }
+
+    @Override
+    public int hashCode()
+    {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + accessType;
+        result = prime * result + ((name == null) ? 0 : name.hashCode());
+        result = prime * result + ((type == null) ? 0 : type.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj)
+    {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        PropertyBinding other = (PropertyBinding) obj;
+        if (accessType != other.accessType)
+            return false;
+        if (name == null)
+        {
+            if (other.name != null)
+                return false;
+        } else if (!name.equals(other.name))
+            return false;
+        if (type == null)
+        {
+            if (other.type != null)
+                return false;
+        } else if (!type.equals(other.type))
+            return false;
+        return true;
+    }
+
+    public String getName()
+    {
+        return name;
+    }
+
+    public TypeBinding getType()
+    {
+        return type;
+    }
+
+    public int getAccess()
+    {
+        return accessType;
+    }
+
+    public boolean isIndex()
+    {
+        return false;
+    }
+
+    public boolean isOptional()
+    {
+        return optional;
+    }
+
+    void encode(Encoder enc)
+    {
+        Map map = new HashMap();
+        map.put("name", name);
+        map.put("type", type.getCode());
+        map.put("access", getAccess());
+        map.put("index", isIndex() ? 1 : 0);
+        map.put("optional", isOptional() ? 1 : 0);
+        if (!type.isNative())
+        {
+            map.put("refClass", type.getRefClass());
+            map.put("refPackage", type.getRefPackage());
+        }
+        enc.writeMap(map);
+    }
+}

Added: qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/QMFTypeBinding.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/QMFTypeBinding.java?rev=785400&view=auto
==============================================================================
--- qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/QMFTypeBinding.java (added)
+++ qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/QMFTypeBinding.java Tue Jun 16 21:03:24 2009
@@ -0,0 +1,465 @@
+/*
+ *
+ * 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.agent.binding;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+/**
+ * Basic type mappings for QMF schema
+ */
+public abstract class QMFTypeBinding implements TypeBinding
+{
+    private static final Map<Class<?>, QMFTypeBinding> TYPES = new HashMap<Class<?>, QMFTypeBinding>();
+    private static final Map<Short, QMFTypeBinding> TYPES_BY_CODE = new HashMap<Short, QMFTypeBinding>();
+    static
+    {
+        new QMFTypeBinding(null, (short) 1)
+        {
+            @Override
+            public Object decode(Decoder dec)
+            {
+                return Short.valueOf(dec.readUint8());
+            }
+
+            @Override
+            public void encode(Encoder enc, Object value)
+            {
+                enc.writeUint8(((Number) value).shortValue());
+            }
+        };
+        new QMFTypeBinding(null, (short) 2)
+        {
+            @Override
+            public Object decode(Decoder dec)
+            {
+                return Integer.valueOf(dec.readUint16());
+            }
+
+            @Override
+            public void encode(Encoder enc, Object value)
+            {
+                enc.writeUint16(((Number) value).intValue());
+            }
+        };
+        new QMFTypeBinding(null, (short) 3)
+        {
+            @Override
+            public Object decode(Decoder dec)
+            {
+                return Long.valueOf(dec.readUint32());
+            }
+
+            @Override
+            public void encode(Encoder enc, Object value)
+            {
+                enc.writeUint32(((Number) value).longValue());
+            }
+        };
+        new QMFTypeBinding(null, (short) 4)
+        {
+            @Override
+            public Object decode(Decoder dec)
+            {
+                return Long.valueOf(dec.readUint64());
+            }
+
+            @Override
+            public void encode(Encoder enc, Object value)
+            {
+                enc.writeUint64(((Number) value).longValue());
+            }
+        };
+        new QMFTypeBinding(null, (short) 6) // short string
+        {
+            @Override
+            public Object decode(Decoder dec)
+            {
+                return dec.readStr8();
+            }
+
+            @Override
+            public void encode(Encoder enc, Object value)
+            {
+                if (null == value)
+                    value = "";
+                enc.writeStr8((String) value);
+            }
+        };
+        new QMFTypeBinding(String.class, (short) 7) // long string
+        {
+            @Override
+            public Object decode(Decoder dec)
+            {
+                return dec.readStr16();
+            }
+
+            @Override
+            public void encode(Encoder enc, Object value)
+            {
+                if (null == value)
+                    value = "";
+                enc.writeStr16((String) value);
+            }
+        };
+        new QMFTypeBinding(Date.class, (short) 8)
+        {
+            @Override
+            public Object decode(Decoder dec)
+            {
+                return new Date(dec.readDatetime());
+            }
+
+            @Override
+            public void encode(Encoder enc, Object value)
+            {
+                enc.writeDatetime(((Date) value).getTime());
+            }
+        };
+        new QMFTypeBinding(Boolean.class, (short) 11)
+        {
+            @Override
+            public Object decode(Decoder dec)
+            {
+                return Boolean.valueOf(dec.readUint8() != 0);
+            }
+
+            @Override
+            public void encode(Encoder enc, Object value)
+            {
+                if (((Boolean) value).booleanValue())
+                {
+                    enc.writeUint8((short) 1);
+                } else
+                {
+                    enc.writeUint8((short) 0);
+                }
+            }
+
+            @Override
+            public short[] alternateTypes()
+            {
+                short[] types =
+                { 5 };
+                return types;
+            }
+        };
+        new QMFTypeBinding(boolean.class, (short) 11)
+        {
+            @Override
+            public Object decode(Decoder dec)
+            {
+                return dec.readUint8() != 0;
+            }
+
+            @Override
+            public void encode(Encoder enc, Object value)
+            {
+                if (((Boolean) value).booleanValue())
+                {
+                    enc.writeUint8((short) 1);
+                } else
+                {
+                    enc.writeUint8((short) 0);
+                }
+            }
+        };
+        new QMFTypeBinding(Float.class, (short) 12)
+        {
+            @Override
+            public Object decode(Decoder dec)
+            {
+                return Float.valueOf(dec.readFloat());
+            }
+
+            @Override
+            public void encode(Encoder enc, Object value)
+            {
+                enc.writeFloat(((Number) value).floatValue());
+            }
+        };
+        new QMFTypeBinding(float.class, (short) 12)
+        {
+            @Override
+            public Object decode(Decoder dec)
+            {
+                return dec.readFloat();
+            }
+
+            @Override
+            public void encode(Encoder enc, Object value)
+            {
+                enc.writeFloat(((Number) value).floatValue());
+            }
+        };
+        new QMFTypeBinding(Double.class, (short) 13)
+        {
+            @Override
+            public Object decode(Decoder dec)
+            {
+                return Double.valueOf(dec.readDouble());
+            }
+
+            @Override
+            public void encode(Encoder enc, Object value)
+            {
+                enc.writeDouble(((Number) value).doubleValue());
+            }
+        };
+        new QMFTypeBinding(double.class, (short) 13)
+        {
+            @Override
+            public Object decode(Decoder dec)
+            {
+                return dec.readDouble();
+            }
+
+            @Override
+            public void encode(Encoder enc, Object value)
+            {
+                enc.writeDouble(((Number) value).doubleValue());
+            }
+        };
+        new QMFTypeBinding(UUID.class, (short) 14)
+        {
+            @Override
+            public Object decode(Decoder dec)
+            {
+                return dec.readUuid();
+            }
+
+            @Override
+            public void encode(Encoder enc, Object value)
+            {
+                enc.writeUuid((UUID) value);
+            }
+        };
+        new QMFTypeBinding(byte.class, (short) 16)
+        {
+            @Override
+            public Object decode(Decoder dec)
+            {
+                return dec.readInt8();
+            }
+
+            @Override
+            public void encode(Encoder enc, Object value)
+            {
+                enc.writeInt8(((Number) value).byteValue());
+            }
+        };
+        new QMFTypeBinding(Short.class, (short) 17)
+        {
+            @Override
+            public Object decode(Decoder dec)
+            {
+                return Short.valueOf(dec.readInt16());
+            }
+
+            @Override
+            public void encode(Encoder enc, Object value)
+            {
+                enc.writeInt16(((Number) value).shortValue());
+            }
+        };
+        new QMFTypeBinding(short.class, (short) 17)
+        {
+            @Override
+            public Object decode(Decoder dec)
+            {
+                return dec.readInt16();
+            }
+
+            @Override
+            public void encode(Encoder enc, Object value)
+            {
+                enc.writeInt16(((Number) value).shortValue());
+            }
+        };
+        new QMFTypeBinding(Integer.class, (short) 18)
+        {
+            @Override
+            public Object decode(Decoder dec)
+            {
+                return Integer.valueOf(dec.readInt32());
+            }
+
+            @Override
+            public void encode(Encoder enc, Object value)
+            {
+                enc.writeInt32(((Number) value).intValue());
+            }
+        };
+        new QMFTypeBinding(int.class, (short) 18)
+        {
+            @Override
+            public Object decode(Decoder dec)
+            {
+                return dec.readInt32();
+            }
+
+            @Override
+            public void encode(Encoder enc, Object value)
+            {
+                enc.writeInt32(((Number) value).intValue());
+            }
+        };
+        new QMFTypeBinding(Long.class, (short) 19)
+        {
+            @Override
+            public Object decode(Decoder dec)
+            {
+                return Long.valueOf(dec.readInt64());
+            }
+
+            @Override
+            public void encode(Encoder enc, Object value)
+            {
+                enc.writeInt64(((Number) value).longValue());
+            }
+        };
+        new QMFTypeBinding(long.class, (short) 19)
+        {
+            @Override
+            public Object decode(Decoder dec)
+            {
+                return dec.readInt64();
+            }
+
+            @Override
+            public void encode(Encoder enc, Object value)
+            {
+                enc.writeInt64(((Number) value).longValue());
+            }
+        };
+    }
+
+    public static final QMFTypeBinding forClass(Class<?> cls)
+    {
+        QMFTypeBinding t = TYPES.get(cls);
+        return t;
+    }
+
+    public static final boolean isBound(Class<?> cls)
+    {
+        return TYPES.containsKey(cls);
+    }
+
+    public static QMFTypeBinding getType(short code)
+    {
+        return TYPES_BY_CODE.get(code);
+    }
+
+    private final Class<?> cls;
+    private final short code;
+
+    private QMFTypeBinding(Class<?> cls, short code)
+    {
+        this.cls = cls;
+        this.code = code;
+        if (cls != null)
+        {
+            TYPES.put(cls, this);
+        }
+        TYPES_BY_CODE.put(code, this);
+        for (short type : this.alternateTypes())
+        {
+            TYPES_BY_CODE.put(type, this);
+        }
+    }
+
+    public Class<?> getJavaClass()
+    {
+        return cls;
+    }
+
+    public short getCode()
+    {
+        return code;
+    }
+
+    public boolean isNative()
+    {
+        return true;
+    }
+
+    public boolean optionalDefault()
+    {
+        return false;
+    }
+
+    public String getRefClass()
+    {
+        return null;
+    }
+
+    public String getRefPackage()
+    {
+        return null;
+    }
+
+    public abstract Object decode(Decoder dec);
+
+    public abstract void encode(Encoder enc, Object value);
+
+    public short[] alternateTypes()
+    {
+        short[] types =
+        {};
+        return types;
+    }
+
+    @Override
+    public int hashCode()
+    {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((cls == null) ? 0 : cls.hashCode());
+        result = prime * result + code;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj)
+    {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        QMFTypeBinding other = (QMFTypeBinding) obj;
+        if (cls == null)
+        {
+            if (other.cls != null)
+                return false;
+        } else if (!cls.equals(other.cls))
+            return false;
+        if (code != other.code)
+            return false;
+        return true;
+    }
+}

Added: qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/TypeBinding.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/TypeBinding.java?rev=785400&view=auto
==============================================================================
--- qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/TypeBinding.java (added)
+++ qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/TypeBinding.java Tue Jun 16 21:03:24 2009
@@ -0,0 +1,46 @@
+/*
+ *
+ * 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.agent.binding;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+/**
+ * Binding between Java Type and QMF type
+ */
+public interface TypeBinding
+{
+    public Object decode(Decoder dec);
+
+    public void encode(Encoder enc, Object value);
+
+    public Class<?> getJavaClass();
+
+    public short getCode();
+
+    public boolean isNative();
+
+    public String getRefClass();
+
+    public String getRefPackage();
+
+    public boolean optionalDefault();
+}

Added: qpid/trunk/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Crumpet.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Crumpet.java?rev=785400&view=auto
==============================================================================
--- qpid/trunk/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Crumpet.java (added)
+++ qpid/trunk/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Crumpet.java Tue Jun 16 21:03:24 2009
@@ -0,0 +1,70 @@
+/*
+ *
+ * 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.agent;
+
+import java.util.ArrayList;
+
+import org.apache.qpid.agent.annotations.QMFSeeAlso;
+import org.apache.qpid.agent.annotations.QMFType;
+
+/**
+ * Crumpet
+ * 
+ */
+@QMFType(className = "Crumpet", packageName = "org.apache.test")
+@QMFSeeAlso(
+{ Pikelet.class })
+public class Crumpet
+{
+    private String foo = "fooValue";
+    private String bar = "barValue";
+    private ArrayList<String> ingredients = new ArrayList<String>();
+
+    public String getFoo()
+    {
+        return foo;
+    }
+
+    public void setFoo(String foo)
+    {
+        this.foo = foo;
+    }
+
+    public String getBar()
+    {
+        return bar;
+    }
+
+    public void setBar(String bar)
+    {
+        this.bar = bar;
+    }
+
+    public ArrayList<String> getIngredients()
+    {
+        return ingredients;
+    }
+
+    public void setIngredients(ArrayList<String> ingredients)
+    {
+        this.ingredients = ingredients;
+    }
+}

Added: qpid/trunk/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Muppet.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Muppet.java?rev=785400&view=auto
==============================================================================
--- qpid/trunk/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Muppet.java (added)
+++ qpid/trunk/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Muppet.java Tue Jun 16 21:03:24 2009
@@ -0,0 +1,113 @@
+/*
+ *
+ * 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.agent;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.qpid.agent.annotations.QMFObject;
+
+@QMFObject(className = "Muppet", packageName = "org.apache.test")
+public class Muppet extends Puppet
+{
+    private Log log = LogFactory.getLog(Muppet.class);
+
+    public String getSomething()
+    {
+        return "something";
+    }
+
+    public void doSomething(String str)
+    {
+        log.debug(String.format("doSomething: %s", str));
+    }
+
+    public String returnSomething()
+    {
+        log.debug("returning something");
+        return "asdf";
+    }
+
+    public Crumpet gimmieCrumpet(String asdf, int n, float f, Map foo)
+    {
+        log.debug(String
+                .format("mmm, crumpet: %s, %s, %s, %s", asdf, n, f, foo));
+        Crumpet crumpet = new Crumpet();
+        crumpet.getIngredients().add("Butter");
+        crumpet.getIngredients().add("Salt");
+        crumpet.getIngredients().add("Flour");
+        return crumpet;
+    }
+
+    public Crumpet gimmieCrumpet2()
+    {
+        Pikelet pik = new Pikelet();
+        pik.getIngredients().add("Butter");
+        pik.getIngredients().add("Salt");
+        pik.getIngredients().add("Eggs");
+        pik.getCrumpets().put("Crumpet1",
+                this.gimmieCrumpet("2121", 1, 1, null));
+        return pik;
+    }
+
+    public List gimmeLotsOfCrumpets()
+    {
+        log.debug("Asking for lots of Crumpets");
+        ArrayList<Crumpet> returnValue = new ArrayList<Crumpet>();
+        Crumpet crumpet = new Crumpet();
+        crumpet.getIngredients().add("Chocolate");
+        returnValue.add(crumpet);
+        crumpet = new Crumpet();
+        crumpet.getIngredients().add("Pecans");
+        returnValue.add(crumpet);
+        crumpet = new Pikelet();
+        crumpet.getIngredients().add("Poached Eggs");
+        returnValue.add(crumpet);
+        return returnValue;
+    }
+
+    public int divideByZero()
+    {
+        return 1 / 0;
+    }
+
+    public Crumpet takeCrumpet(Crumpet newCrumpet)
+    {
+        log.debug(String.format("I gots me a crumpet: foo: '%s' bar: '%s'",
+                newCrumpet.getFoo(), newCrumpet.getBar()));
+        log.debug("My crumpet's class is " + newCrumpet.getClass().getName());
+        for (String ingredient : newCrumpet.getIngredients())
+        {
+            log.debug("My crumpet is made of " + ingredient);
+        }
+        return newCrumpet;
+    }
+
+    public Object takeSomething(Object obj)
+    {
+        log.debug(String.format("I gots me a something: '%s'", obj.getClass()
+                .getName()));
+        return obj;
+    }
+}

Added: qpid/trunk/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Pikelet.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Pikelet.java?rev=785400&view=auto
==============================================================================
--- qpid/trunk/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Pikelet.java (added)
+++ qpid/trunk/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Pikelet.java Tue Jun 16 21:03:24 2009
@@ -0,0 +1,52 @@
+/*
+ *
+ * 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.agent;
+
+import java.util.HashMap;
+
+import org.apache.qpid.agent.annotations.QMFType;
+
+@QMFType(className = "Pikelet", packageName = "org.apache.test")
+public class Pikelet extends Crumpet
+{
+    protected String shape;
+    HashMap<String, Crumpet> crumpets = new HashMap<String, Crumpet>();
+
+    public String getShape()
+    {
+        return shape;
+    }
+
+    public void setShape(String shape)
+    {
+        this.shape = shape;
+    }
+
+    public HashMap<String, Crumpet> getCrumpets()
+    {
+        return crumpets;
+    }
+
+    public void setCrumpets(HashMap<String, Crumpet> crumpets)
+    {
+        this.crumpets = crumpets;
+    }
+}

Added: qpid/trunk/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Puppet.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Puppet.java?rev=785400&view=auto
==============================================================================
--- qpid/trunk/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Puppet.java (added)
+++ qpid/trunk/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Puppet.java Tue Jun 16 21:03:24 2009
@@ -0,0 +1,29 @@
+/*
+ *
+ * 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.agent;
+
+public class Puppet
+{
+    public int countStrings()
+    {
+        return 4;
+    }
+}



---------------------------------------------------------------------
Apache Qpid - AMQP Messaging Implementation
Project:      http://qpid.apache.org
Use/Interact: mailto:commits-subscribe@qpid.apache.org