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 [1/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...

Author: tross
Date: Tue Jun 16 21:03:24 2009
New Revision: 785400

URL: http://svn.apache.org/viewvc?rev=785400&view=rev
Log:
QPID-1905 - Moved qmf agent code to java/management/agent where it belongs.

Added:
    qpid/trunk/qpid/java/management/agent/
    qpid/trunk/qpid/java/management/agent/build.xml
    qpid/trunk/qpid/java/management/agent/src/
    qpid/trunk/qpid/java/management/agent/src/main/
    qpid/trunk/qpid/java/management/agent/src/main/java/
    qpid/trunk/qpid/java/management/agent/src/main/java/org/
    qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/
    qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/
    qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/
    qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/Agent.java
    qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/AgentException.java
    qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/EventSeverity.java
    qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedEJB.java
    qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedObject.java
    qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedObjectBase.java
    qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedPOJO.java
    qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/
    qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFEvent.java
    qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFHide.java
    qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFObject.java
    qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFProperty.java
    qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFSeeAlso.java
    qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFType.java
    qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/
    qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingContext.java
    qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingException.java
    qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingUtils.java
    qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ClassBinding.java
    qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/EnumBinding.java
    qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ListBinding.java
    qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/MapBinding.java
    qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/MethodBinding.java
    qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ParameterBinding.java
    qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/PropertyBinding.java
    qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/QMFTypeBinding.java
    qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/TypeBinding.java
    qpid/trunk/qpid/java/management/agent/src/test/
    qpid/trunk/qpid/java/management/agent/src/test/java/
    qpid/trunk/qpid/java/management/agent/src/test/java/org/
    qpid/trunk/qpid/java/management/agent/src/test/java/org/apache/
    qpid/trunk/qpid/java/management/agent/src/test/java/org/apache/qpid/
    qpid/trunk/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/
    qpid/trunk/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Crumpet.java
    qpid/trunk/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Muppet.java
    qpid/trunk/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Pikelet.java
    qpid/trunk/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Puppet.java
Removed:
    qpid/trunk/qpid/java/agent/
Modified:
    qpid/trunk/qpid/java/build.deps
    qpid/trunk/qpid/java/build.xml

Modified: qpid/trunk/qpid/java/build.deps
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/build.deps?rev=785400&r1=785399&r2=785400&view=diff
==============================================================================
--- qpid/trunk/qpid/java/build.deps (original)
+++ qpid/trunk/qpid/java/build.deps Tue Jun 16 21:03:24 2009
@@ -86,7 +86,7 @@
 broker-plugins.libs=${common.libs} ${felix.libs} 
 management-client.libs=${jsp.libs} ${log4j} ${slf4j-log4j} ${slf4j-api} ${commons-pool} ${geronimo-servlet} ${muse.libs} ${javassist} ${xalan} ${mina-core} ${mina-filter-ssl}
 
-agent.libs=${client.libs} ${commons-logging}
+management-agent.libs=${client.libs} ${commons-logging} ${geronimo-jms}
 
 junit-toolkit.libs=${log4j} ${junit} ${slf4j-api}
 test.libs=${slf4j-log4j} ${junit-toolkit.libs}

Modified: qpid/trunk/qpid/java/build.xml
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/build.xml?rev=785400&r1=785399&r2=785400&view=diff
==============================================================================
--- qpid/trunk/qpid/java/build.xml (original)
+++ qpid/trunk/qpid/java/build.xml Tue Jun 16 21:03:24 2009
@@ -22,10 +22,10 @@
 
   <import file="common.xml"/>
 
-  <property name="modules.core"       value="junit-toolkit common broker client tools agent"/>
+  <property name="modules.core"       value="junit-toolkit common broker client tools"/>
   <property name="modules.examples"   value="client/example"/>
   <property name="modules.tests"      value="systests perftests integrationtests testkit"/>
-  <property name="modules.management" value="management/common management/client management/eclipse-plugin"/>
+  <property name="modules.management" value="management/common management/client management/eclipse-plugin management/agent"/>
   <property name="modules.plugin"     value="broker-plugins"/>
   <property name="modules.management.tools" value="management/tools/qpid-cli"/>
   <property name="modules"            value="${modules.core}

Added: qpid/trunk/qpid/java/management/agent/build.xml
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/management/agent/build.xml?rev=785400&view=auto
==============================================================================
--- qpid/trunk/qpid/java/management/agent/build.xml (added)
+++ qpid/trunk/qpid/java/management/agent/build.xml Tue Jun 16 21:03:24 2009
@@ -0,0 +1,27 @@
+<!--
+ -
+ - 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.
+ -
+ -->
+<project name="QMF Agent" default="build">
+
+    <property name="module.depends" value="common client"/>
+
+    <import file="../../module.xml"/>
+
+</project>

Added: qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/Agent.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/Agent.java?rev=785400&view=auto
==============================================================================
--- qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/Agent.java (added)
+++ qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/Agent.java Tue Jun 16 21:03:24 2009
@@ -0,0 +1,659 @@
+/*
+ *
+ * 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.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import javax.jms.BytesMessage;
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageListener;
+import javax.jms.MessageProducer;
+import javax.jms.Queue;
+import javax.jms.Session;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.qpid.agent.binding.BindingContext;
+import org.apache.qpid.agent.binding.BindingUtils;
+import org.apache.qpid.agent.binding.ClassBinding;
+import org.apache.qpid.agent.binding.BindingException;
+import org.apache.qpid.agent.binding.MethodBinding;
+import org.apache.qpid.agent.binding.ParameterBinding;
+import org.apache.qpid.agent.binding.PropertyBinding;
+import org.apache.qpid.agent.binding.TypeBinding;
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.transport.codec.BBDecoder;
+import org.apache.qpid.transport.codec.BBEncoder;
+import org.apache.qpid.transport.codec.Decoder;
+
+/**
+ * The main class for interacting with the QMF bus. Objects which are
+ * to be managed can be registered with the agent, as can classes
+ * to be exposed via the schema.
+ */
+public class Agent implements MessageListener
+{
+    // The following are settings to configure the Agent
+    private AMQConnection connection;
+    private boolean sessionTransacted = false;
+    private int acknowledgeMode = Session.AUTO_ACKNOWLEDGE;
+    private String label;
+    private UUID systemId;
+    // this list holds the objects until the agent is started
+    private List managedObjects = new ArrayList();
+    private List registeredClasses = new ArrayList();
+    // The following instance variables are not
+    // able to be set by the end user.
+    private Session session;
+    private MessageProducer prod;
+    private MessageConsumer cons;
+    private Queue reply;
+    private BindingContext bctx = new BindingContext();
+    private Map<Long, ManagedObject> objects = new Hashtable<Long, ManagedObject>();
+    private long bbank;
+    private long abank;
+    private static Log log = LogFactory.getLog(Agent.class);
+    private volatile boolean inside = false;
+
+    public Agent()
+    {
+        systemId = UUID.randomUUID();
+        log.debug(String.format("Agent with uid %s created", systemId
+                .toString()));
+    }
+
+    public Agent(String label, UUID systemId)
+    {
+        this.systemId = systemId;
+        this.label = label;
+        log.debug(String.format("Agent with name %s and uid %s created", label,
+                systemId.toString()));
+    }
+
+
+    public void register(ManagedObject managedObject)
+    {
+        Class managedClass = managedObject.getObjectClass();
+        long id = managedObject.getId();
+        ClassBinding cb = bctx.register(managedClass);
+        managedObject.setManagedClassName(cb.getName());
+        managedObject.setManagedPackageName(cb.getPackage());
+        log.debug(String.format(
+                "Added managed object id '%d' for package '%s' class '%s'", id,
+                managedObject.getManagedPackageName(), managedObject
+                        .getManagedClassName()));
+        objects.put(id, managedObject);
+        managedObjects.add(managedObject);
+    }
+
+    public void registerClass(Class cls)
+    {
+        bctx.register(cls);
+        if (!registeredClasses.contains(cls))
+        {
+            registeredClasses.add(cls);
+        }
+    }
+
+    /**
+     * Starts up the agent. Many bean containers may call this by
+     * default which aids in deployment
+     */
+    public void start()
+    {
+        log.debug(String.format("Agent with uid %s and name %s starting",
+                systemId.toString(), label));
+        for (Object clsName : registeredClasses.toArray())
+        {
+            try
+            {
+                Class cls = Class.forName(clsName.toString());
+                this.registerClass(cls);
+            } catch (Exception e)
+            {
+                log.error("Could not register class " + clsName);
+            }
+        }
+        for (Object obj : managedObjects.toArray())
+        {
+            this.register((ManagedObject) obj);
+        }
+        try
+        {
+            session = connection.createSession(sessionTransacted,
+                    acknowledgeMode);
+            reply = session.createQueue("direct://amq.direct//" + label);
+            cons = session.createConsumer(reply);
+            cons.setMessageListener(this);
+            prod = session.createProducer(null);
+        } catch (JMSException e)
+        {
+            throw new AgentException(e);
+        }
+        attachRequest(label, systemId);
+        try
+        {
+            connection.start();
+        } catch (JMSException e)
+        {
+            throw new AgentException(e);
+        }
+    }
+
+    /**
+     * Send an event object to the bus
+     */
+    public void raiseEvent(Object value, EventSeverity sev)
+    {
+        log.debug(String.format("Sending event of class %s with Severity %s",
+                value.getClass(), sev.ordinal()));
+        BBEncoder enc = this.init('e');
+        ClassBinding cb = bctx.getClassBinding(value.getClass());
+        String pkg = cb.getPackage();
+        String cls = cb.getName();
+        enc.writeStr8(pkg);
+        enc.writeStr8(cls);
+        enc.writeBin128(cb.getSchemaHash());
+        long now = System.currentTimeMillis() * 1000000;
+        enc.writeInt64(now);
+        enc.writeUint8((short) sev.ordinal());
+        for (PropertyBinding p : cb.getProperties())
+        {
+            p.getType().encode(enc, BindingUtils.get(p, value));
+        }
+        send(
+                String.format("console.event.%d.%d.%s.%s", bbank, abank, pkg,
+                        cls), enc);
+    }
+
+    public void onMessage(Message message)
+    {
+        if (inside)
+        {
+            new Throwable().printStackTrace();
+        }
+        inside = true;
+        Decoder dec = readBody(message);
+        Destination replyTo;
+        try
+        {
+            replyTo = message.getJMSReplyTo();
+        } catch (JMSException e)
+        {
+            throw new AgentException(e);
+        }
+        byte[] magic = dec.readBytes(3);
+        if (magic[0] != 'A' || magic[1] != 'M' || magic[2] != '3')
+        {
+            throw new AgentException("bad magic: " + new String(magic));
+        }
+        short op = dec.readUint8();
+        long seq = dec.readUint32();
+        log.debug("Message recieved: " + (char) op);
+        switch (op)
+        {
+        case 'a':
+            this.handleAgentAttach(seq, replyTo, dec);
+            break;
+        case 'G':
+            this.handleGetQuery(seq, replyTo, dec);
+            break;
+        case 'M':
+            this.handleMethodRequest(seq, replyTo, dec);
+            break;
+        case 'S':
+            this.handleSchemaRequest(seq, replyTo, dec);
+            break;
+        case 'x':
+            // TODO
+            break;
+        default:
+            throw new IllegalArgumentException("opcode: " + ((char) op));
+        }
+        inside = false;
+    }
+
+    protected ClassBinding getClassBinding(ManagedObject mobj)
+    {
+        return bctx.getClassBinding(mobj.getObjectClass());
+    }
+
+    private byte[] ensure(int capacity, byte[] body, int size)
+    {
+        if (capacity > body.length)
+        {
+            byte[] copy = new byte[capacity];
+            System.arraycopy(body, 0, copy, 0, size);
+            body = copy;
+        }
+        return body;
+    }
+
+    private Decoder readBody(Message message)
+    {
+        BytesMessage msg = (BytesMessage) message;
+        BBDecoder dec = new BBDecoder();
+        byte[] buf = new byte[1024];
+        byte[] body = new byte[1024];
+        int size = 0;
+        int n;
+        try
+        {
+            while ((n = msg.readBytes(buf)) > 0)
+            {
+                body = ensure(size + n, body, size);
+                System.arraycopy(buf, 0, body, size, n);
+                size += n;
+            }
+        } catch (JMSException e)
+        {
+            throw new AgentException(e);
+        }
+        dec.init(ByteBuffer.wrap(body, 0, size));
+        return dec;
+    }
+
+    protected void handleAgentAttach(long seq, Destination replyTo, Decoder dec)
+    {
+        log.debug("Agent Attach Message");
+        bbank = dec.readUint32();
+        abank = dec.readUint32();
+        try
+        {
+            MessageConsumer mc = session
+                    .createConsumer(session
+                            .createQueue(String
+                                    .format(
+                                            "management://qpid.management//%s?routingkey='agent.%d.%d'",
+                                            label, bbank, abank)));
+            mc.setMessageListener(this);
+        } catch (JMSException e)
+        {
+            throw new AgentException(e);
+        }
+        for (String packageName : bctx.getPackages())
+        {
+            packageIndication(packageName);
+        }
+        for (ClassBinding cb : bctx.getAllBindings())
+        {
+            classIndication(cb);
+        }
+        for (ManagedObject mo : objects.values())
+        {
+            content('i', seq, null, mo);
+        }
+    }
+
+    protected void handleMethodRequest(long seq, Destination replyTo,
+            Decoder dec)
+    {
+        dec.readUint64(); // first part of object-id
+        long id = dec.readUint64();
+        ManagedObject mo = objects.get(id);
+        if (mo == null)
+        {
+            methodResponse(seq, replyTo, 1, String.format(
+                    "no such object: 0x%x", id));
+        } else
+        {
+            dec.readStr8(); // pkg
+            dec.readStr8(); // cls
+            dec.readBin128(); // hash
+            String mname = dec.readStr8();
+            ClassBinding cls = getClassBinding(mo);
+            MethodBinding method = cls.getMethod(mname);
+            if (method == null)
+            {
+                methodResponse(seq, replyTo, 2, String.format(
+                        "no such method: %s", mname));
+            } else
+            {
+                log.trace("Handle method: " + method.getName());
+                List<ParameterBinding> params = method.getInParameters();
+                Object[] args = new Object[params.size()];
+                int idx = 0;
+                for (ParameterBinding p : params)
+                {
+                    TypeBinding typeBinding = p.getType();
+                    log
+                            .trace(String
+                                    .format(
+                                            "Decoding parameter with type %s ref package %s ref class %s ",
+                                            typeBinding.getCode(), typeBinding
+                                                    .getRefPackage(),
+                                            typeBinding.getRefClass()));
+                    args[idx++] = typeBinding.decode(dec);
+                    log.trace("Done");
+                }
+                try
+                {
+                    Object[] result = mo.invoke(method, args);
+                    methodResponse(seq, replyTo, 0, null, method, result);
+                } catch (BindingException ex)
+                {
+                    log
+                            .error(String
+                                    .format(
+                                            "An exception occured invoking method %s. Stack trace sent to console.",
+                                            method.getName()));
+                    StringWriter str = new StringWriter();
+                    PrintWriter writer = new PrintWriter(str);
+                    ex.printStackTrace(writer);
+                    writer.flush();
+                    methodResponse(seq, replyTo, 7, str.toString());
+                }
+                log.trace("Done with method: " + method.getName());
+            }
+        }
+    }
+
+    protected void handleGetQuery(long seq, Destination replyTo, Decoder dec)
+    {
+        Map<String, Object> data = dec.readMap();
+        if (data.containsKey("_objectid"))
+        {
+            long objId = (Long) data.get("_objectid");
+            log.debug("Get Request message for object id " + objId);
+            ManagedObject mo = objects.get(objId);
+            if (mo == null)
+            {
+                methodResponse(seq, replyTo, 1, String.format(
+                        "no such object: 0x%x", objId));
+            } else
+            {
+                content('g', seq, replyTo, mo);
+            }
+        } else if (data.containsKey("_class"))
+        {
+            String className = (String) data.get("_class");
+            String packageName = (String) data.get("_package");
+            log.debug(String.format(
+                    "Get Request message for package '%s' class '%s'",
+                    packageName, className));
+            for (ManagedObject mo : objects.values())
+            {
+                if (mo.getManagedClassName().equals(className))
+                {
+                    if ((packageName == null) || packageName.equals("")
+                            || packageName.equals(mo.getManagedPackageName()))
+                    {
+                        content('g', seq, replyTo, mo);
+                    }
+                }
+            }
+        } else
+        {
+            for (ManagedObject mo : objects.values())
+            {
+                content('g', seq, replyTo, mo);
+            }
+        }
+        complete(seq, replyTo);
+    }
+
+    protected void handleSchemaRequest(long seq, Destination replyTo,
+            Decoder dec)
+    {
+        String pkg = dec.readStr8();
+        String cls = dec.readStr8();
+        log.debug(String.format(
+                "SchemaRequest message for package '%s' class '%s'", pkg, cls));
+        ClassBinding cb = bctx.getClassBinding(pkg, cls);
+        if (cb == null)
+        {
+            throw new AgentException("no such class: " + pkg + ", " + cls);
+        }
+        schemaResponse(seq, cb);
+    }
+
+    protected BBEncoder init(char opcode)
+    {
+        return init(opcode, 0);
+    }
+
+    protected BBEncoder init(char opcode, long sequence)
+    {
+        BBEncoder enc = new BBEncoder(1024);
+        enc.init();
+        enc.writeUint8((short) 'A');
+        enc.writeUint8((short) 'M');
+        enc.writeUint8((short) '3');
+        enc.writeUint8((short) opcode);
+        enc.writeUint32(sequence);
+        return enc;
+    }
+
+    protected void send(BBEncoder enc)
+    {
+        send("broker", enc);
+    }
+
+    protected void send(Destination dest, BBEncoder enc)
+    {
+        try
+        {
+            byte[] buf = new byte[1024];
+            byte[] body = new byte[1024];
+            BytesMessage msg = session.createBytesMessage();
+            ByteBuffer slice = enc.segment();
+            while (slice.hasRemaining())
+            {
+                int n = Math.min(buf.length, slice.remaining());
+                slice.get(buf, 0, n);
+                msg.writeBytes(buf, 0, n);
+            }
+            msg.setJMSReplyTo(reply);
+            // ???: I assume this is thread safe.
+            prod.send(dest, msg);
+        } catch (JMSException e)
+        {
+            throw new AgentException(e);
+        }
+    }
+
+    protected void send(String routingKey, BBEncoder enc)
+    {
+        try
+        {
+            send(session
+                    .createQueue("management://qpid.management//?routingkey='"
+                            + routingKey + "'"), enc);
+        } catch (JMSException e)
+        {
+            throw new AgentException(e);
+        }
+    }
+
+    private void attachRequest(String label, UUID systemId)
+    {
+        BBEncoder enc = init('A');
+        enc.writeStr8(label);
+        enc.writeUuid(systemId);
+        enc.writeUint32(0);
+        enc.writeUint32(0);
+        send(enc);
+    }
+
+    private void packageIndication(String pkg)
+    {
+        BBEncoder enc = init('p');
+        enc.writeStr8(pkg);
+        send(enc);
+    }
+
+    private void classIndication(ClassBinding cb)
+    {
+        BBEncoder enc = init('q');
+        enc.writeUint8(cb.getKind());
+        enc.writeStr8(cb.getPackage());
+        enc.writeStr8(cb.getName());
+        enc.writeBin128(cb.getSchemaHash()); // schema hash?
+        send(enc);
+    }
+
+    private void schemaResponse(long seq, ClassBinding cb)
+    {
+        BBEncoder enc = init('s', seq);
+        cb.encode(enc);
+        send(enc);
+    }
+
+    private void content(char c, long seq, Destination dest, ManagedObject mo)
+    {
+        BBEncoder enc = init(c, seq);
+        ClassBinding cb = getClassBinding(mo);
+        String pkg = cb.getPackage();
+        String cls = cb.getName();
+        enc.writeStr8(pkg);
+        enc.writeStr8(cls);
+        enc.writeBin128(cb.getSchemaHash());
+        long now = System.currentTimeMillis() * 1000000;
+        enc.writeUint64(now);
+        enc.writeUint64(now);
+        enc.writeUint64(0);
+        enc.writeUint64(0x0000FFFFFFFFFFFFL & ((bbank << 28) | abank));
+        enc.writeUint64(mo.getId());
+        for (PropertyBinding p : cb.getProperties())
+        {
+            p.getType().encode(enc, mo.get(p));
+        }
+        if (dest == null)
+        {
+            send(String.format("console.obj.%d.%d.%s.%s", bbank, abank, pkg,
+                    cls), enc);
+        } else
+        {
+            send(dest, enc);
+        }
+    }
+
+    private void complete(long seq, Destination dest)
+    {
+        BBEncoder enc = init('z', seq);
+        enc.writeUint32(0);
+        enc.writeStr8("");
+        send(dest, enc);
+    }
+
+    private void methodResponse(long seq, Destination dest, int status,
+            String text)
+    {
+        methodResponse(seq, dest, status, text, null, null);
+    }
+
+    private void methodResponse(long seq, Destination dest, int status,
+            String text, MethodBinding method, Object[] result)
+    {
+        BBEncoder enc = init('m', seq);
+        enc.writeUint32(status);
+        enc.writeStr16(text == null ? "" : text);
+        if (method != null)
+        {
+            int idx = 0;
+            for (ParameterBinding p : method.getOutParameters())
+            {
+                p.getType().encode(enc, result[idx++]);
+            }
+        }
+        send(dest, enc);
+    }
+
+    public String getLabel()
+    {
+        return label;
+    }
+
+    public void setLabel(String label)
+    {
+        this.label = label;
+    }
+
+    public AMQConnection getConnection()
+    {
+        return connection;
+    }
+
+    public void setConnection(AMQConnection connection)
+    {
+        this.connection = connection;
+    }
+
+    public boolean isSessionTransacted()
+    {
+        return sessionTransacted;
+    }
+
+    public void setSessionTransacted(boolean sessionTransacted)
+    {
+        this.sessionTransacted = sessionTransacted;
+    }
+
+    public void setManagedObjects(List objectList)
+    {
+        this.managedObjects = objectList;
+    }
+
+    public List getManagedObjects()
+    {
+        return managedObjects;
+    }
+
+    public void setRegisteredClasses(List objectList)
+    {
+        this.registeredClasses = objectList;
+    }
+
+    public List getRegisteredClasses()
+    {
+        return this.registeredClasses;
+    }
+
+    public static void main(String[] args) throws Exception
+    {
+        String broker = args[0];
+        String name = args[1];
+        String url = String.format(
+                "amqp://guest:guest@/?brokerlist='tcp://%s'", broker);
+        AMQConnection conn = new AMQConnection(url);
+        Agent agent = new Agent(name, UUID.randomUUID());
+        agent.setConnection(conn);
+        for (int i = 2; i < args.length; i++)
+        {
+            Class<?> cls = Class.forName(args[i]);
+            agent.register(new ManagedPOJO(cls.newInstance()));
+        }
+        agent.start();
+        while (true)
+        {
+            Thread.sleep(1000);
+        }
+    }
+}

Added: qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/AgentException.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/AgentException.java?rev=785400&view=auto
==============================================================================
--- qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/AgentException.java (added)
+++ qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/AgentException.java Tue Jun 16 21:03:24 2009
@@ -0,0 +1,43 @@
+/*
+ *
+ * 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;
+
+/**
+ * AgentException
+ * 
+ */
+public class AgentException extends RuntimeException
+{
+    public AgentException(String msg)
+    {
+        super(msg);
+    }
+
+    public AgentException(Throwable t)
+    {
+        super(t);
+    }
+
+    public AgentException(String msg, Throwable t)
+    {
+        super(msg, t);
+    }
+}

Added: qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/EventSeverity.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/EventSeverity.java?rev=785400&view=auto
==============================================================================
--- qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/EventSeverity.java (added)
+++ qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/EventSeverity.java Tue Jun 16 21:03:24 2009
@@ -0,0 +1,6 @@
+package org.apache.qpid.agent;
+
+public enum EventSeverity
+{
+    EMERGENCY, ALERT, CRIT, ERROR, WARN, NOTICE, INFO, DEBUG
+}

Added: qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedEJB.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedEJB.java?rev=785400&view=auto
==============================================================================
--- qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedEJB.java (added)
+++ qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedEJB.java Tue Jun 16 21:03:24 2009
@@ -0,0 +1,109 @@
+/*
+ *
+ * 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 javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+import org.apache.qpid.agent.binding.BindingUtils;
+import org.apache.qpid.agent.binding.MethodBinding;
+import org.apache.qpid.agent.binding.PropertyBinding;
+
+/**
+ * Wrapper classe for adding EJBS which are to be 
+ * managed by the QMF Agent. The jndi location and the
+ * public interface to exposed are used to generate the schema.
+ */
+public class ManagedEJB extends ManagedObjectBase
+{
+    protected String className;
+    protected String jndiLocation;
+
+    protected Object getEJB()
+    {
+        try
+        {
+            InitialContext ctx = new InitialContext();
+            return ctx.lookup(jndiLocation);
+        } catch (NamingException e)
+        {
+            throw new AgentException("Error looking up EJB at " + jndiLocation,
+                    e);
+        }
+    }
+
+    @Override
+    public Object get(PropertyBinding property)
+    {
+        return BindingUtils.get(property, this.getEJB());
+    }
+
+    @Override
+    public long getId()
+    {
+        return System.identityHashCode(this);
+    }
+
+    @Override
+    public Class getObjectClass()
+    {
+        try
+        {
+            return Class.forName(className);
+        } catch (ClassNotFoundException e)
+        {
+            throw new AgentException(String.format(
+                    "No class named %s was found", className), e);
+        }
+    }
+
+    @Override
+    public Object[] invoke(MethodBinding method, Object... args)
+    {
+        return BindingUtils.invoke(method, this.getEJB(), args);
+    }
+
+    @Override
+    public void set(PropertyBinding property, Object value)
+    {
+        BindingUtils.set(property, value, this.getEJB());
+    }
+
+    public String getClassName()
+    {
+        return className;
+    }
+
+    public void setClassName(String className)
+    {
+        this.className = className;
+    }
+
+    public String getJndiLocation()
+    {
+        return jndiLocation;
+    }
+
+    public void setJndiLocation(String jndiLocation)
+    {
+        this.jndiLocation = jndiLocation;
+    }
+}

Added: qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedObject.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedObject.java?rev=785400&view=auto
==============================================================================
--- qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedObject.java (added)
+++ qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedObject.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 org.apache.qpid.agent.binding.MethodBinding;
+import org.apache.qpid.agent.binding.PropertyBinding;
+
+/**
+ * Objects which are to be managed and controlled by the QMF Agent.
+ */
+public interface ManagedObject
+{
+    public abstract long getId();
+
+    public abstract Class getObjectClass();
+
+    public abstract Object get(PropertyBinding property);
+
+    public abstract void set(PropertyBinding property, Object value);
+
+    public abstract Object[] invoke(MethodBinding method, Object... args);
+
+    public abstract String getName();
+
+    public abstract void setName(String name);
+
+    public String getManagedClassName();
+
+    public String getManagedPackageName();
+
+    public void setManagedClassName(String aName);
+
+    public void setManagedPackageName(String aName);
+}

Added: qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedObjectBase.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedObjectBase.java?rev=785400&view=auto
==============================================================================
--- qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedObjectBase.java (added)
+++ qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedObjectBase.java Tue Jun 16 21:03:24 2009
@@ -0,0 +1,72 @@
+/*
+ *
+ * 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 org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.qpid.agent.binding.MethodBinding;
+import org.apache.qpid.agent.binding.PropertyBinding;
+
+public abstract class ManagedObjectBase implements ManagedObject
+{
+    private static Log log = LogFactory.getLog(ManagedObjectBase.class);
+    protected String name;
+    protected String managedClassName;
+    protected String managedPackageName;
+
+    public abstract long getId();
+
+    public abstract Object get(PropertyBinding property);
+
+    public abstract void set(PropertyBinding property, Object value);
+
+    public abstract Object[] invoke(MethodBinding method, Object... args);
+
+    public String getName()
+    {
+        return name;
+    }
+
+    public void setName(String name)
+    {
+        this.name = name;
+    }
+
+    public String getManagedClassName()
+    {
+        return managedClassName;
+    }
+
+    public void setManagedClassName(String managedClassName)
+    {
+        this.managedClassName = managedClassName;
+    }
+
+    public String getManagedPackageName()
+    {
+        return managedPackageName;
+    }
+
+    public void setManagedPackageName(String managedPackageName)
+    {
+        this.managedPackageName = managedPackageName;
+    }
+}

Added: qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedPOJO.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedPOJO.java?rev=785400&view=auto
==============================================================================
--- qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedPOJO.java (added)
+++ qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedPOJO.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;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.qpid.agent.binding.BindingUtils;
+import org.apache.qpid.agent.binding.MethodBinding;
+import org.apache.qpid.agent.binding.PropertyBinding;
+
+/**
+ * Wrapper classe for adding POJOS which are to be 
+ * managed by the QMF Agent. 
+ */
+public class ManagedPOJO extends ManagedObjectBase implements ManagedObject
+{
+    private Log log = LogFactory.getLog(ManagedPOJO.class);
+    private Object managed;
+
+    public ManagedPOJO()
+    {
+        super();
+    }
+
+    public ManagedPOJO(Object managed)
+    {
+        super();
+        this.setManaged(managed);
+    }
+
+    @Override
+    public long getId()
+    {
+        if (managed == null)
+        {
+            throw new AgentException("The managed object is null");
+        }
+        return System.identityHashCode(managed);
+    }
+
+    public Class getObjectClass()
+    {
+        return managed.getClass();
+    }
+
+    public Object getManaged()
+    {
+        return managed;
+    }
+
+    public void setManaged(Object managed)
+    {
+        this.managed = managed;
+    }
+
+    @Override
+    public Object get(PropertyBinding property)
+    {
+        return BindingUtils.get(property, managed);
+    }
+
+    @Override
+    public Object[] invoke(MethodBinding method, Object... args)
+    {
+        return BindingUtils.invoke(method, managed, args);
+    }
+
+    @Override
+    public void set(PropertyBinding property, Object value)
+    {
+        BindingUtils.set(property, value, managed);
+    }
+}

Added: qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFEvent.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFEvent.java?rev=785400&view=auto
==============================================================================
--- qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFEvent.java (added)
+++ qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFEvent.java Tue Jun 16 21:03:24 2009
@@ -0,0 +1,43 @@
+/*
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Tells the QMF Agent that this object will be passed as a
+ * QMF event. This will cause only properties to be sent across
+ * the wire.
+ */
+@Target(TYPE)
+@Retention(RUNTIME)
+@Documented
+public @interface QMFEvent
+{
+    String eventName();
+
+    String packageName();
+}

Added: qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFHide.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFHide.java?rev=785400&view=auto
==============================================================================
--- qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFHide.java (added)
+++ qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFHide.java Tue Jun 16 21:03:24 2009
@@ -0,0 +1,39 @@
+/*
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Causes the property which is annotated to not be added to the
+ * QMF schema when it is built.
+ */
+@Target(ElementType.METHOD)
+@Retention(RUNTIME)
+@Documented
+public @interface QMFHide
+{
+}

Added: qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFObject.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFObject.java?rev=785400&view=auto
==============================================================================
--- qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFObject.java (added)
+++ qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFObject.java Tue Jun 16 21:03:24 2009
@@ -0,0 +1,43 @@
+/*
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Tells the QMF Agent that this object will be a managed 
+ * object. This will allow users to query for it, as well as
+ * invoke methods on it.
+ */
+@Target(TYPE)
+@Retention(RUNTIME)
+@Documented
+public @interface QMFObject
+{
+    String className();
+
+    String packageName();
+}

Added: qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFProperty.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFProperty.java?rev=785400&view=auto
==============================================================================
--- qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFProperty.java (added)
+++ qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFProperty.java Tue Jun 16 21:03:24 2009
@@ -0,0 +1,39 @@
+/*
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Controls the QMF schema which is generated for this property.
+ */
+@Target(ElementType.FIELD)
+@Retention(RUNTIME)
+@Documented
+public @interface QMFProperty
+{
+    boolean optional() default false;
+}

Added: qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFSeeAlso.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFSeeAlso.java?rev=785400&view=auto
==============================================================================
--- qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFSeeAlso.java (added)
+++ qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFSeeAlso.java Tue Jun 16 21:03:24 2009
@@ -0,0 +1,40 @@
+/*
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Augements the schema generation process to look for known
+ * subclasses of a type. Modeled after the JAXB @XMLSeeAlso.
+ */
+@Target(TYPE)
+@Retention(RUNTIME)
+@Documented
+public @interface QMFSeeAlso
+{
+    Class[] value();
+}

Added: qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFType.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFType.java?rev=785400&view=auto
==============================================================================
--- qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFType.java (added)
+++ qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFType.java Tue Jun 16 21:03:24 2009
@@ -0,0 +1,43 @@
+/*
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Tells the QMF Agent that this object will be a type only
+ * This will cause only properties to be sent across
+ * the wire.
+ */
+@Target(TYPE)
+@Retention(RUNTIME)
+@Documented
+public @interface QMFType
+{
+    String className();
+
+    String packageName();
+}

Added: qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingContext.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingContext.java?rev=785400&view=auto
==============================================================================
--- qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingContext.java (added)
+++ qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingContext.java Tue Jun 16 21:03:24 2009
@@ -0,0 +1,213 @@
+/*
+ *
+ * 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.Collection;
+import java.util.Hashtable;
+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.QMFSeeAlso;
+import org.apache.qpid.agent.annotations.QMFType;
+
+/**
+ * Contains the mappings from java classes to QMF schema and back.
+ * There is one context per agent, and it contains all the metadata.
+ */
+public class BindingContext
+{
+    private static Log log = LogFactory.getLog(BindingContext.class);
+    private Map<Key, ClassBinding> classes = new Hashtable<Key, ClassBinding>();
+    private ArrayList<String> packages = new ArrayList<String>();
+
+    static class Key
+    {
+        String packageName = "";
+        String className = "";
+        boolean object = false;
+
+        @Override
+        public int hashCode()
+        {
+            return (packageName + "." + className).hashCode();
+        }
+
+        @Override
+        public boolean equals(Object obj)
+        {
+            return ((obj.getClass() == Key.class)
+                    && (((Key) obj).packageName.equals(packageName)) && (((Key) obj).className
+                    .equals(className)));
+        }
+    }
+
+    public BindingContext()
+    {
+        Key key = new Key();
+        key.className = "Object";
+        key.packageName = "org.apache.qmf";
+        key.object = false;
+        ClassBinding cb = new ClassBinding("org.apache.qmf", "Object",
+                Object.class, false, this);
+        classes.put(key, cb);
+        packages.add("org.apache.qmf");
+    }
+
+    public ClassBinding getClassBinding(Class clazz)
+    {
+        return classes.get(getClassKey(clazz));
+    }
+
+    public ClassBinding getClassBinding(String packageName, String className)
+    {
+        Key key = new Key();
+        key.packageName = packageName;
+        key.className = className;
+        return classes.get(key);
+    }
+
+    public ClassBinding register(Class cls)
+    {
+        String name = cls.getName();
+        ClassBinding cb = getClassBinding(cls);
+        if (cb == null)
+        {
+            Key key = getClassKey(cls);
+            // Create and store the internal representations
+            if (cls.isEnum())
+            {
+                cb = new EnumBinding(key.packageName, key.className, cls,
+                        key.object, this);
+            } else
+            {
+                cb = new ClassBinding(key.packageName, key.className, cls,
+                        key.object, this);
+            }
+            log.debug(String.format(
+                    "Added class binding '%s' in package %s for class %s'",
+                    key.className, key.packageName, cls.getCanonicalName()));
+            classes.put(key, cb);
+            if (!packages.contains(key.packageName))
+            {
+                packages.add(key.packageName);
+            }
+            // Parse the methods after adding the class to avoid recursion
+            cb.parse();
+            // See if there are other classes which should be looked at
+            QMFSeeAlso seeAlso = (QMFSeeAlso) cls
+                    .getAnnotation(QMFSeeAlso.class);
+            if (seeAlso != null)
+            {
+                for (Class seeAlsoCls : seeAlso.value())
+                {
+                    this.register(seeAlsoCls);
+                }
+            }
+        }
+        return cb;
+    }
+
+    public TypeBinding getTypeBinding(Class cls)
+    {
+        // Look for a built in type
+        TypeBinding type = QMFTypeBinding.forClass(cls);
+        // Have we seen it before?
+        if (type == null)
+        {
+            type = this.getClassBinding(cls);
+        }
+        if ((type == null) && List.class.isAssignableFrom(cls))
+        {
+            type = new ListBinding(this, cls);
+        }
+        if ((type == null) && Map.class.isAssignableFrom(cls))
+        {
+            type = new MapBinding(this, cls);
+        }
+        // Add it, but since we have not seen it before do not expose methods
+        if (type == null)
+        {
+            type = this.register(cls);
+        }
+        return type;
+    }
+
+    // FIXME: Need to store these keys off so we dont create alot of objects
+    protected Key getClassKey(Class cls)
+    {
+        Key key = new Key();
+        QMFObject objAnnotation = (QMFObject) cls
+                .getAnnotation(QMFObject.class);
+        if (objAnnotation != null)
+        {
+            key.className = objAnnotation.className();
+            key.packageName = objAnnotation.packageName();
+            key.object = true;
+        } else
+        {
+            QMFType typeAnnotation = (QMFType) cls.getAnnotation(QMFType.class);
+            if (typeAnnotation != null)
+            {
+                key.className = typeAnnotation.className();
+                key.packageName = typeAnnotation.packageName();
+            } else
+            {
+                QMFEvent eventAnnotation = (QMFEvent) cls
+                        .getAnnotation(QMFEvent.class);
+                if (eventAnnotation != null)
+                {
+                    key.className = eventAnnotation.eventName();
+                    key.packageName = eventAnnotation.packageName();
+                } else
+                {
+                    // If this is Object, we return the fake
+                    // object value
+                    if (cls == Object.class)
+                    {
+                        key.className = "Object";
+                        key.packageName = "org.apache.qmf";
+                    } else
+                    {
+                        String name = cls.getName();
+                        int lastDot = name.lastIndexOf('.');
+                        key.className = name.substring(lastDot + 1);
+                        key.packageName = name.substring(0, lastDot);
+                    }
+                }
+            }
+        }
+        return key;
+    }
+
+    public ArrayList<String> getPackages()
+    {
+        return packages;
+    }
+
+    public Collection<ClassBinding> getAllBindings()
+    {
+        return classes.values();
+    }
+}

Added: qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingException.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingException.java?rev=785400&view=auto
==============================================================================
--- qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingException.java (added)
+++ qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingException.java Tue Jun 16 21:03:24 2009
@@ -0,0 +1,50 @@
+/*
+ *
+ * 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;
+
+/**
+ * ManagedException
+ * 
+ */
+public class BindingException extends RuntimeException
+{
+    private static final long serialVersionUID = -7350845525748113340L;
+
+    public BindingException(Throwable t)
+    {
+        super(t);
+    }
+
+    public BindingException()
+    {
+        super();
+    }
+
+    public BindingException(String message, Throwable cause)
+    {
+        super(message, cause);
+    }
+
+    public BindingException(String message)
+    {
+        super(message);
+    }
+}

Added: qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingUtils.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingUtils.java?rev=785400&view=auto
==============================================================================
--- qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingUtils.java (added)
+++ qpid/trunk/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingUtils.java Tue Jun 16 21:03:24 2009
@@ -0,0 +1,137 @@
+/*
+ *
+ * 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.beans.BeanInfo;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public class BindingUtils
+{
+    private static Log log = LogFactory.getLog(BindingUtils.class);
+
+    public static Object get(PropertyBinding property, Object managed)
+    {
+        String name = property.getName();
+        return get(name, managed);
+    }
+
+    public static void set(PropertyBinding property, Object value,
+            Object managed)
+    {
+        String name = property.getName();
+        TypeBinding type = property.getType();
+        try
+        {
+            Method meth = managed.getClass().getMethod(accessor("set", name),
+                    type.getJavaClass());
+            meth.invoke(managed, value);
+        } catch (NoSuchMethodException e)
+        {
+            throw new BindingException(e);
+        } catch (IllegalAccessException e)
+        {
+            throw new BindingException(e);
+        } catch (InvocationTargetException e)
+        {
+            throw new BindingException(e.getTargetException());
+        }
+    }
+
+    public static Object[] invoke(MethodBinding method, Object managed,
+            Object... args)
+    {
+        log.debug(String.format("Invoking %s on %s", method.getName(), managed
+                .getClass()));
+        List<ParameterBinding> in = method.getInParameters();
+        List<ParameterBinding> out = method.getOutParameters();
+        Class<?>[] classes = new Class<?>[in.size()];
+        int idx = 0;
+        for (ParameterBinding p : in)
+        {
+            classes[idx++] = p.getType().getJavaClass();
+        }
+        Object result;
+        try
+        {
+            Method meth = managed.getClass().getMethod(method.getName(),
+                    classes);
+            result = meth.invoke(managed, args);
+        } catch (NoSuchMethodException e)
+        {
+            throw new BindingException(e);
+        } catch (IllegalAccessException e)
+        {
+            throw new BindingException(e);
+        } catch (InvocationTargetException e)
+        {
+            throw new BindingException(e.getTargetException());
+        }
+        Object[] results = new Object[out.size()];
+        // XXX: need better way to distinguish this case
+        if (out.size() == 1 && out.get(0).getName().equals("result"))
+        {
+            results[0] = result;
+        } else
+        {
+            for (int i = 0; i < results.length; i++)
+            {
+                results[i] = get(out.get(i).getName(), result);
+            }
+        }
+        return results;
+    }
+
+    public static String accessor(String pfx, String property)
+    {
+        return pfx + Character.toUpperCase(property.charAt(0))
+                + property.substring(1);
+    }
+
+    public static Object get(String name, Object obj)
+    {
+        Object returnValue = null;
+        try
+        {
+            BeanInfo info = Introspector.getBeanInfo(obj.getClass());
+            PropertyDescriptor[] pds = info.getPropertyDescriptors();
+            for (PropertyDescriptor pd : pds)
+            {
+                if (pd.getName().equals(name))
+                {
+                    Method getMethod = pd.getReadMethod();
+                    returnValue = getMethod.invoke(obj);
+                    break;
+                }
+            }
+        } catch (Exception e)
+        {
+            throw new BindingException(e);
+        }
+        return returnValue;
+    }
+}



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