You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by fa...@apache.org on 2013/04/08 17:19:09 UTC

svn commit: r1465662 [10/26] - in /qpid/trunk/qpid/tools/src/java: ./ bin/ bin/qpid-web/ bin/qpid-web/authentication/ bin/qpid-web/web/ bin/qpid-web/web/itablet/ bin/qpid-web/web/itablet/css/ bin/qpid-web/web/itablet/images/ bin/qpid-web/web/itablet/im...

Added: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/QmfAgentData.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/QmfAgentData.java?rev=1465662&view=auto
==============================================================================
--- qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/QmfAgentData.java (added)
+++ qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/QmfAgentData.java Mon Apr  8 15:19:04 2013
@@ -0,0 +1,364 @@
+/*
+ *
+ * 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.qmf2.agent;
+
+// Misc Imports
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+// QMF2 Imports
+import org.apache.qpid.qmf2.common.ObjectId;
+import org.apache.qpid.qmf2.common.QmfException;
+import org.apache.qpid.qmf2.common.QmfManaged;
+import org.apache.qpid.qmf2.common.SchemaObjectClass;
+
+/**
+ * The Agent manages the data it represents by the QmfAgentData class - a derivative of the QmfData class.
+ * <p>
+ * The Agent is responsible for managing the values of the properties within the object, as well as servicing
+ * the object's method calls. Unlike the Console, the Agent has full control of the state of the object.
+ * <p>
+ * In most cases, for efficiency, it is expected that Agents would <i>actually</i> manage objects that are subclasses of 
+ * QmfAgentData and maintain subclass specific properties as primitives, only actually explicitly setting the
+ * underlying Map properties via setValue() etc. when the object needs to be "serialised". This would most
+ * obviously be done by extending the mapEncode() method (noting that it's important to call QmfAgentData's mapEncode()
+ * first via super.mapEncode(); as this will set the state of the underlying QmfData).
+ * <p>
+ * This class provides a number of methods aren't in the QMF2 API per se, but they are used to manage the association
+ * between a managed object and any subscriptions that might be interested in it.
+ * <p>
+ * The diagram below shows the relationship between the Subscription and QmfAgentData.
+ * <p>
+ * <img src="doc-files/Subscriptions.png"/>
+ * <p>
+ * In particular the QmfAgentData maintains references to active subscriptions to allow agents to asynchronously
+ * push data to subscribing Consoles immediately that data becomes available.
+ * <p>
+ * The update() method indicates that the object's state has changed and the publish() method <b>immediately</b> sends
+ * the new state to any subscription.
+ * <p>
+ * The original intention was to "auto update" by calling these from the setValue() method. Upon reflection this
+ * seems a bad idea, as in many cases there may be several properties that an Agent may wish to change which would
+ * lead to unnecessary calls to currentTimeMillis(), but also as theSubscription update is run via a TimerTask it is
+ * possible that an update indication could get sent part way through setting an object's overall state.
+ * Similarly calling the publish() method directly from setValue() would force an update indication on partial changes
+ * of state, which is generally not the desired behaviour.
+ * @author Fraser Adams
+ */
+public class QmfAgentData extends QmfManaged implements Comparable<QmfAgentData>
+{
+    private long _updateTimestamp;
+    private long _createTimestamp;
+    private long _deleteTimestamp;
+    private String _compareKey = null;
+
+    /**
+     * This Map is used to look up Subscriptions that are interested in this data by SubscriptionId
+     */
+    private Map<String, Subscription> _subscriptions = new ConcurrentHashMap<String, Subscription>();
+
+    /**
+     * Construct a QmfAgentData object of the type described by the given SchemaObjectClass.
+     *
+     * @param schema the schema describing the type of this QmfAgentData object.
+     */
+    public QmfAgentData(final SchemaObjectClass schema)
+    {
+        long currentTime = System.currentTimeMillis()*1000000l;
+        _updateTimestamp = currentTime;
+        _createTimestamp = currentTime;
+        _deleteTimestamp = 0;
+        setSchemaClassId(schema.getClassId());
+    }
+
+    /**
+     * Return the creation timestamp.
+     * @return the creation timestamp. Timestamps are recorded in nanoseconds since the epoch
+     */
+    public final long getCreateTime()
+    {
+        return _createTimestamp;
+    }
+
+    /**
+     * Return the update timestamp.
+     * @return the update timestamp. Timestamps are recorded in nanoseconds since the epoch
+     */
+    public final long getUpdateTime()
+    {
+        return _updateTimestamp;
+    }
+
+    /**
+     * Return the deletion timestamp.
+     * @return the deletion timestamp, or zero if not deleted. Timestamps are recorded in nanoseconds since the epoch
+     */
+    public final long getDeleteTime()
+    {
+        return _deleteTimestamp;
+    }
+
+    /**
+     * Return true if deletion timestamp not zero.
+     * @return true if deletion timestamp not zero.
+     */
+    public final boolean isDeleted()
+    {
+        return getDeleteTime() != 0;
+    }
+
+    /**
+     * Mark the object as deleted by setting the deletion timestamp to the current time.
+     * <p>
+     * This method alse publishes the deleted object to any listening Subscription then removes references to the
+     * Subscription.
+     * <p>
+     * When this method returns the object should be ready for reaping.
+     */
+    public final void destroy()
+    {
+        _deleteTimestamp = System.currentTimeMillis()*1000000l;
+        _updateTimestamp = System.currentTimeMillis()*1000000l;
+        publish();
+        _subscriptions.clear();
+    }
+
+    /**
+     * Add the delta to the property.
+     *
+     * @param name the name of the property being modified.
+     * @param delta the value being added to the property.
+     */
+    public final synchronized void incValue(final String name, final long delta)
+    {
+        long value = getLongValue(name);
+        value += delta;
+        setValue(name, value);
+    }
+
+    /**
+     * Add the delta to the property.
+     *
+     * @param name the name of the property being modified.
+     * @param delta the value being added to the property.
+     */
+    public final synchronized void incValue(final String name, final double delta)
+    {
+        double value = getDoubleValue(name);
+        value += delta;
+        setValue(name, value);
+    }
+
+    /**
+     * Subtract the delta from the property.
+     *
+     * @param name the name of the property being modified.
+     * @param delta the value being subtracted from the property.
+     */
+    public final synchronized void decValue(final String name, final long delta)
+    {
+        long value = getLongValue(name);
+        value -= delta;
+        setValue(name, value);
+    }
+
+    /**
+     * Subtract the delta from the property.
+     *
+     * @param name the name of the property being modified.
+     * @param delta the value being subtracted from the property.
+     */
+    public final synchronized void decValue(final String name, final double delta)
+    {
+        double value = getDoubleValue(name);
+        value -= delta;
+        setValue(name, value);
+    }
+
+    // The following methods aren't in the QMF2 API per se, but they are used to manage the association between
+    // a managed object and any subscriptions that might be interested in it.
+
+    /**
+     * Return the Subscription with the specified ID.
+     * @return the Subscription with the specified ID.
+     */
+    public final Subscription getSubscription(final String subscriptionId)
+    {
+        return _subscriptions.get(subscriptionId);
+    }
+
+    /**
+     * Add a new Subscription reference.
+     * @param subscriptionId the ID of the Subscription being added.
+     * @param subscription the Subscription being added.
+     */
+    public final void addSubscription(final String subscriptionId, final Subscription subscription)
+    {
+        _subscriptions.put(subscriptionId, subscription);
+    }
+
+    /**
+     * Remove a Subscription reference.
+     * @param subscriptionId the ID of the Subscription being removed.
+     */
+    public final void removeSubscription(final String subscriptionId)
+    {
+        _subscriptions.remove(subscriptionId);
+    }
+
+
+    /**
+     * Set the _updateTimestamp to indicate (particularly to subscriptions) that the managed object has changed.
+     * <p>
+     * The update() method indicates that the object's state has changed and the publish() method <b>immediately</b> sends
+     * the new state to any subscription.
+     * <p>
+     * The original intention was to "auto update" by calling these from the setValue() method. Upon reflection this
+     * seems a bad idea, as in many cases there may be several properties that an Agent may wish to change which would
+     * lead to unnecessary calls to currentTimeMillis(), but also as the Subscription update is run via a TimerTask it
+     * is possible that an update indication could get sent part way through setting an object's overall state.
+     * Similarly calling the publish() method directly from setValue() would force an update indication on partial
+     * changes of state, which is generally not the desired behaviour.
+     */
+    public final void update()
+    {
+        _updateTimestamp = System.currentTimeMillis()*1000000l;
+    }
+
+    /**
+     * Iterate through any Subscriptions associated with this Object and force them to republish the Object's new state.
+     * <p>
+     * The update() method indicates that the object's state has changed and the publish() method <b>immediately</b> sends
+     * the new state to any subscription.
+     * <p>
+     * The original intention was to "auto update" by calling these from the setValue() method. Upon reflection this
+     * seems a bad idea, as in many cases there may be several properties that an Agent may wish to change which would
+     * lead to unnecessary calls to currentTimeMillis(), but also as the Subscription update is run via a TimerTask it
+     * is possible that an update indication could get sent part way through setting an object's overall state.
+     * Similarly calling the publish() method directly from setValue() would force an update indication on partial
+     * changes of state, which is generally not the desired behaviour.
+     */
+    public final void publish()
+    {
+        update();
+        if (getObjectId() == null)
+        { // If ObjectId is null the Object isn't yet Managed to we can't publish
+            return;
+        }
+
+        List<Map> results = new ArrayList<Map>();
+        results.add(mapEncode());
+        for (Map.Entry<String, Subscription> entry : _subscriptions.entrySet())
+        {
+            Subscription subscription = entry.getValue();
+            subscription.publish(results);
+        }
+    }
+
+    /**
+     * Return the underlying map.
+     * <p>
+     * In most cases, for efficiency, it is expected that Agents would <i>actually</i> manage objects that are
+     * subclasses of QmfAgentData and maintain subclass specific properties as primitives, only actually explicitly
+     * setting the underlying Map properties via setValue() etc. when the object needs to be "serialised". This would
+     * most obviously be done by extending the mapEncode() method (noting that it's important to call QmfAgentData's
+     * mapEncode() first via super.mapEncode(); as this will set the state of the underlying QmfData).
+     *
+     * @return the underlying map. 
+     */
+    @Override
+    public Map<String, Object> mapEncode()
+    {
+        Map<String, Object> map = new HashMap<String, Object>();
+        map.put("_values", super.mapEncode());
+        if (_subtypes != null)
+        {
+            map.put("_subtypes", _subtypes);
+        }
+        map.put("_schema_id", getSchemaClassId().mapEncode());
+        map.put("_object_id", getObjectId().mapEncode());
+        map.put("_update_ts", _updateTimestamp);
+        map.put("_create_ts", _createTimestamp);
+        map.put("_delete_ts", _deleteTimestamp);
+        return map;
+    }
+
+    /**
+     * Helper/debug method to list the QMF Object properties and their type.
+     */
+    @Override
+    public void listValues()
+    {
+        super.listValues();
+        System.out.println("QmfAgentData:");
+        System.out.println("create timestamp: " + new Date(getCreateTime()/1000000l));
+        System.out.println("update timestamp: " + new Date(getUpdateTime()/1000000l));
+        System.out.println("delete timestamp: " + new Date(getDeleteTime()/1000000l));
+    }
+
+    // The following methods allow instances of QmfAgentData to be compared with each other and sorted.
+    // N.B. This behaviour is not part of the specified QmfAgentData, but it's quite useful for some Agents.
+
+    /**
+     * Set the key String to be used for comparing two QmfAgentData instances. This is primarily used by the Agent
+     * to allow it to order Query results (e.g. for getObjects()).
+     * @param compareKey the String that we wish to use as a compare key.
+     */
+    public void setCompareKey(String compareKey)
+    {
+        _compareKey = compareKey;
+    }
+
+    /**
+     * If a compare key has been set then the QmfAgentData is sortable.
+     * @return true if a compare key has been set and the QmfAgentData is sortable otherwise return false.
+     */
+    public boolean isSortable()
+    {
+        return _compareKey != null;
+    }
+
+    /**
+     * Compare the compare key of this QmfAgentData with the specified other QmfAgentData.
+     * Compares the compare keys (which are Strings) lexicographically. The comparison is based on the Unicode
+     * value of each character in the strings.
+     * @param rhs the String to be compared.
+     * @return the value 0 if the argument string is equal to this string; a value less than 0 if this string is 
+     * lexicographically less than the string argument; and a value greater than 0 if this string is lexicographically 
+     * greater than the string argument.
+     */
+    public int compareTo(QmfAgentData rhs)
+    { 
+        if (_compareKey == null)
+        {
+            return 0;
+        }
+        else
+        {
+            return this._compareKey.compareTo(rhs._compareKey);
+        }
+    }
+}
+

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/QmfAgentData.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/QmfAgentData.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/QueryWorkItem.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/QueryWorkItem.java?rev=1465662&view=auto
==============================================================================
--- qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/QueryWorkItem.java (added)
+++ qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/QueryWorkItem.java Mon Apr  8 15:19:04 2013
@@ -0,0 +1,85 @@
+/*
+ *
+ * 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.qmf2.agent;
+
+import java.util.Map;
+
+// QMF2 Imports
+import org.apache.qpid.qmf2.common.Handle;
+import org.apache.qpid.qmf2.common.QmfQuery;
+import org.apache.qpid.qmf2.common.WorkItem;
+
+/**
+ * Descriptions below are taken from <a href=https://cwiki.apache.org/qpid/qmfv2-api-proposal.html>QMF2 API Proposal</a> 
+ * <pre>
+ * QUERY: The QUERY WorkItem describes a query that the application must service. The application should call the 
+ *        queryResponse() method for each object that satisfies the query. When complete, the application must call the 
+ *        queryComplete() method. If a failure occurs, the application should indicate the error to the agent by calling
+ *        the query_complete() method with a description of the error.
+ *
+ *        The getParams() method of a QUERY WorkItem will return an instance of the QmfQuery class.
+ *
+ *        The getHandle() WorkItem method returns the reply handle which should be passed to the Agent's queryResponse()
+ *        and queryComplete() methods.
+ * </pre>
+ * Note that the API is a bit sketchy on the description of the QUERY WorkItem and whereas most WorkItems seem to return
+ * defined classes for their getParams() it's not so obvious here. There's an implication that getParams() just returns
+ * QmfQuery, but it's not clear where the uset_id bit fits.
+ * <p>
+ * As the API doesn't define a "QueryParams" class I've not included one, but I've added a getUserId() method to 
+ * QueryWorkItem, this is a bit inconsistent with the approach for the other WorkItems though.
+ *
+ * @author Fraser Adams
+ */
+
+public final class QueryWorkItem extends WorkItem
+{
+    /**
+     * Construct a QueryWorkItem. Convenience constructor not in API.
+     *
+     * @param handle the reply handle.
+     * @param params the QmfQuery used to populate the WorkItem's param.
+     */
+    public QueryWorkItem(final Handle handle, final QmfQuery params)
+    {
+        super(WorkItemType.QUERY, handle, params);
+    }
+
+    /**
+     * Return the QmfQuery stored in the params Map.
+     * @return the QmfQuery stored in the params Map.
+     */
+    public QmfQuery getQmfQuery()
+    {
+        return (QmfQuery)getParams();
+    }
+
+    /**
+     * Return authenticated user id of caller if present, else null.
+     * @return authenticated user id of caller if present, else null.
+     */
+    public String getUserId()
+    {
+        Map map = getQmfQuery().mapEncode();
+        return (String)map.get("_user_id");
+    }
+}
+

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/QueryWorkItem.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/QueryWorkItem.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/ResubscribeParams.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/ResubscribeParams.java?rev=1465662&view=auto
==============================================================================
--- qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/ResubscribeParams.java (added)
+++ qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/ResubscribeParams.java Mon Apr  8 15:19:04 2013
@@ -0,0 +1,78 @@
+/*
+ *
+ * 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.qmf2.agent;
+
+import java.util.Map;
+
+// QMF2 Imports
+import org.apache.qpid.qmf2.common.QmfData;
+
+/**
+ * Holds the information contained in a resubscription request made by a Console to an Agent
+ *
+ * @author Fraser Adams
+ */
+public final class ResubscribeParams extends QmfData
+{
+    /**
+     * Construct ResubscribeParams.
+     *
+     * @param m the Map used to populate the ResubscribeParams state.
+     */
+    public ResubscribeParams(final Map m)
+    {
+        super(m);
+    }
+
+    /**
+     * Return a SubscriptionId object.
+     * @return a SubscriptionId object.
+     */
+    public String getSubscriptionId()
+    {
+        if (hasValue("_subscription_id"))
+        {
+            return getStringValue("_subscription_id");
+        }
+        return null;
+    }
+
+    /**
+     * Return the requested lifetime for the subscription.
+     * @return the requested lifetime for the subscription. Zero if the previous interval should be used.
+     */
+    public long getLifetime()
+    {
+        return getLongValue("_duration");
+    }
+
+    /**
+     * Return authenticated user id of caller if present, else null.
+     * @return authenticated user id of caller if present, else null.
+     */
+    public String getUserId()
+    {
+        return getStringValue("_user_id");
+    }
+}
+
+
+

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/ResubscribeParams.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/ResubscribeParams.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/ResubscribeRequestWorkItem.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/ResubscribeRequestWorkItem.java?rev=1465662&view=auto
==============================================================================
--- qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/ResubscribeRequestWorkItem.java (added)
+++ qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/ResubscribeRequestWorkItem.java Mon Apr  8 15:19:04 2013
@@ -0,0 +1,66 @@
+/*
+ *
+ * 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.qmf2.agent;
+
+import java.util.Map;
+
+// QMF2 Imports
+import org.apache.qpid.qmf2.common.Handle;
+import org.apache.qpid.qmf2.common.WorkItem;
+
+/**
+ * Descriptions below are taken from <a href=https://cwiki.apache.org/qpid/qmfv2-api-proposal.html>QMF2 API Proposal</a> 
+ * <pre>
+ * RESUBSCRIBE_REQUEST: The RESUBSCRIBE_REQUEST is sent by a Console to renew an existing subscription.  The Console may 
+ *                      request a new duration for the subscription, otherwise the previous lifetime interval is repeated.
+ *
+ *                      The getParams() method of a RESUBSCRIBE_REQUEST WorkItem will return an instance of the 
+ *                      ResubscribeParams class.
+ *
+ *                      The getHandle() WorkItem method returns the reply handle which should be passed to the Agent's 
+ *                      subscriptionResponse() method.
+ * </pre>
+ * @author Fraser Adams
+ */
+
+public final class ResubscribeRequestWorkItem extends WorkItem
+{
+    /**
+     * Construct a ResubscribeRequestWorkItem. Convenience constructor not in API.
+     *
+     * @param handle the reply handle.
+     * @param params the ResubscribeParams used to populate the WorkItem's param.
+     */
+    public ResubscribeRequestWorkItem(final Handle handle, final ResubscribeParams params)
+    {
+        super(WorkItemType.RESUBSCRIBE_REQUEST, handle, params);
+    }
+
+    /**
+     * Return the ResubscribeParams stored in the params Map.
+     * @return the ResubscribeParams stored in the params Map.
+     */
+    public ResubscribeParams getResubscribeParams()
+    {
+        return (ResubscribeParams)getParams();
+    }
+}
+

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/ResubscribeRequestWorkItem.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/ResubscribeRequestWorkItem.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/SubscribableAgent.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/SubscribableAgent.java?rev=1465662&view=auto
==============================================================================
--- qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/SubscribableAgent.java (added)
+++ qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/SubscribableAgent.java Mon Apr  8 15:19:04 2013
@@ -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.qmf2.agent;
+
+// Misc Imports
+import java.util.List;
+import java.util.Map;
+
+// QMF2 Imports
+import org.apache.qpid.qmf2.common.Handle;
+import org.apache.qpid.qmf2.common.QmfQuery;
+
+/**
+ * This interface provides a number of methods that are called by a Subscription in order to interact with an
+ * Agent or an Agent's managed data.
+ * <p>
+ * The purpose of this interface is primarily about removing a circular dependency between Subscription and Agent
+ * so the Subscription doesn't invoke these methods on an Agent instance, rather it invokes them on a
+ * SubscribeableAgent instance.
+ * <p>
+ * The following diagram illustrates the interactions between the Agent, Subscription and SubscribableAgent.
+ * <p>
+ * <img src="doc-files/Subscriptions.png"/>
+ *
+ * @author Fraser Adams
+ */
+public interface SubscribableAgent
+{
+    /**
+     * Send a list of updated subscribed data to the Console.
+     *
+     * @param handle the console reply handle
+     * @param results a list of subscribed data in Map encoded form
+     */
+    public void sendSubscriptionIndicate(Handle handle, List<Map> results);
+
+    /**
+     * This method evaluates a QmfQuery over the Agent's data on behalf of a Subscription
+     *
+     * @param query the QmfQuery that the Subscription wants to be evaluated over the Agent's data
+     * @return a List of QmfAgentData objects that match the specified QmfQuery
+     */
+    public List<QmfAgentData> evaluateQuery(QmfQuery query);
+
+    /**
+     * This method is called by the Subscription to tell the SubscriberProxy that the Subscription has been cancelled.
+     *
+     * @param subscription the Subscription that has been cancelled and is requesting removal.
+     */
+    public void removeSubscription(Subscription subscription);
+}
+

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/SubscribableAgent.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/SubscribableAgent.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/SubscribeRequestWorkItem.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/SubscribeRequestWorkItem.java?rev=1465662&view=auto
==============================================================================
--- qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/SubscribeRequestWorkItem.java (added)
+++ qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/SubscribeRequestWorkItem.java Mon Apr  8 15:19:04 2013
@@ -0,0 +1,69 @@
+/*
+ *
+ * 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.qmf2.agent;
+
+import java.util.Map;
+
+// QMF2 Imports
+import org.apache.qpid.qmf2.common.Handle;
+import org.apache.qpid.qmf2.common.WorkItem;
+
+/**
+ * Descriptions below are taken from <a href=https://cwiki.apache.org/qpid/qmfv2-api-proposal.html>QMF2 API Proposal</a> 
+ * <pre>
+ * SUBSCRIBE_REQUEST: The SUBSCRIBE_REQUEST WorkItem provides a query that the agent application must periodically
+ *                    publish until the subscription is cancelled or expires. On receipt of this WorkItem, the
+ *                    application should call the Agent subscriptionResponse() method to acknowledge the request.
+ *                    On each publish interval, the application should call Agent subscriptionIndicate(), passing a
+ *                    list of the objects that satisfy the query. The subscription remains in effect until an   
+ *                    UNSUBSCRIBE_REQUEST WorkItem for the subscription is received, or the subscription expires.
+ *
+ *                    The getParams() method of a QUERY WorkItem will return an instance of the SubscriptionParams class.
+ *
+ *                    The getHandle() WorkItem method returns the reply handle which should be passed to the Agent's 
+ *                    subscriptionResponse() method.
+ * </pre>
+ * @author Fraser Adams
+ */
+
+public final class SubscribeRequestWorkItem extends WorkItem
+{
+    /**
+     * Construct a SubscribeRequestWorkItem. Convenience constructor not in API
+     *
+     * @param handle the reply handle
+     * @param params the SubscriptionParams used to populate the WorkItem's param
+     */
+    public SubscribeRequestWorkItem(final Handle handle, final SubscriptionParams params)
+    {
+        super(WorkItemType.SUBSCRIBE_REQUEST, handle, params);
+    }
+
+    /**
+     * Return the SubscriptionParams stored in the params Map.
+     * @return the SubscriptionParams stored in the params Map.
+     */
+    public SubscriptionParams getSubscriptionParams()
+    {
+        return (SubscriptionParams)getParams();
+    }
+}
+

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/SubscribeRequestWorkItem.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/SubscribeRequestWorkItem.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/Subscription.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/Subscription.java?rev=1465662&view=auto
==============================================================================
--- qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/Subscription.java (added)
+++ qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/Subscription.java Mon Apr  8 15:19:04 2013
@@ -0,0 +1,280 @@
+/*
+ *
+ * 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.qmf2.agent;
+
+// Simple Logging Facade 4 Java
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.TimerTask;
+import java.util.UUID;
+
+// QMF2 Imports
+import org.apache.qpid.qmf2.common.Handle;
+import org.apache.qpid.qmf2.common.QmfException;
+import org.apache.qpid.qmf2.common.QmfQuery;
+import org.apache.qpid.qmf2.common.QmfQueryTarget;
+
+/** 
+ * This TimerTask represents a running Subscription on the Agent.
+ * <p>
+ * The main reason we have Subscriptions as TimerTasks is to enable proper cleanup of the references stored in
+ * the _subscriptions Map when the Subscription expires. The timer also causes QmfAgenData that have been updated
+ * since the last interval to be published.
+ * <p>
+ * The following diagram illustrates the Subscription relationships with the Agent and QmfAgentData.
+ * <p>
+ * <img src="doc-files/Subscriptions.png"/>
+ * @author Fraser Adams
+ */
+public final class Subscription extends TimerTask
+{
+    private static final Logger _log = LoggerFactory.getLogger(Subscription.class);
+
+    // Duration is the time (in seconds) the Subscription is active before it automatically expires unless refreshed
+    private static final int DEFAULT_DURATION = 300;
+    private static final int MAX_DURATION = 3600;
+    private static final int MIN_DURATION = 10;
+
+    // Interval is the period (in milliseconds) between subscription ubdates.
+    private static final int DEFAULT_INTERVAL = 30000;
+    private static final int MIN_INTERVAL = 1000;
+
+    private SubscribableAgent _agent;
+    private long _startTime = System.currentTimeMillis();
+    private long _lastUpdate = _startTime*1000000l;
+    private String _subscriptionId;
+    private Handle _consoleHandle;
+    private QmfQuery _query;
+    private long _duration = 0;
+    private long _interval = 0;
+
+    /**
+     * Tells the SubscribableAgent to send the results to the Console via a subscription indicate message.
+     *
+     * @param results the list of mapEncoded QmfAgentData that currently match the query associated with this
+     * Subscription.
+     */
+    protected void publish(List<Map> results)
+    {
+        _agent.sendSubscriptionIndicate(_consoleHandle, results);
+        _lastUpdate = System.currentTimeMillis()*1000000l;
+    }
+
+    /**
+     * Construct a new Subscription.
+     * @param agent the SubscribableAgent to which this Subscription is associated.
+     * @param params the SubscriptionParams object that contains the information needed to create a Subscription.
+     */
+    public Subscription(SubscribableAgent agent, SubscriptionParams params) throws QmfException
+    {
+        _agent = agent;
+        _subscriptionId = UUID.randomUUID().toString();
+        _consoleHandle = params.getConsoleHandle();
+        _query = params.getQuery();
+        setDuration(params.getLifetime());
+        setInterval(params.getPublishInterval());
+
+        _log.debug("Creating Subscription {}, duration = {}, interval = {}", new Object[] {_subscriptionId, _duration, _interval});
+    }
+
+    /**
+     * This method gets called periodically by the Timer scheduling this TimerTask.
+     * <p>
+     * First a check is made to see if the Subscription has expired, if it has then it is cancelled.
+     * <p>
+     * If the Subscription isn't cancelled the Query gets evaluated against all registered objects and any that match
+     * which are new to the Subscription or have changed since the last update get published.
+     */
+    public void run()
+    {
+        long elapsed = (long)Math.round((System.currentTimeMillis() - _startTime)/1000.0f);
+        if (elapsed >= _duration)
+        {
+            _log.debug("Subscription {} has expired, removing", _subscriptionId);
+            // The Subscription has expired so cancel it
+            cancel();
+        }
+        else
+        {
+            List<QmfAgentData> objects = _agent.evaluateQuery(_query);
+            List<Map> results = new ArrayList<Map>(objects.size());
+            for (QmfAgentData object : objects)
+            {
+                if (object.getSubscription(_subscriptionId) == null)
+                {
+                    // The object is new to this Subscription so publish it
+                    object.addSubscription(_subscriptionId, this);
+                    results.add(object.mapEncode());
+                }
+                else
+                {
+                    // If the object has had update() called since last Subscription update publish it.
+                    // Note that in many cases an Agent might call publish() on a managed object rather than
+                    // update() which immediately forces a data indication to be sent to the subscriber on
+                    // the Console.
+                    if (object.getUpdateTime() > _lastUpdate)
+                    {
+                        results.add(object.mapEncode());
+                    }
+                }
+            }
+
+            if (results.size() > 0)
+            {
+                publish(results);
+            }
+        }
+    }
+
+    /**
+     * Refresh the subscription by zeroing its elapsed time.
+     *
+     * @param resubscribeParams the ResubscribeParams passed by the Console potentially containing new duration
+     * information.
+     */
+    public void refresh(ResubscribeParams resubscribeParams)
+    {
+        _log.debug("Refreshing Subscription {}", _subscriptionId);
+        _startTime = System.currentTimeMillis();
+        setDuration(resubscribeParams.getLifetime());
+    }
+
+    /**
+     * Cancel the Subscription, tidying references up and cancelling the TimerTask.
+     */
+    @Override
+    public boolean cancel()
+    {
+        _log.debug("Cancelling Subscription {}", _subscriptionId);
+        // This Subscription is about to be deleted, remove it from any Objects that may be referencing it.
+        List<QmfAgentData> objects = _agent.evaluateQuery(_query);
+        for (QmfAgentData object : objects)
+        {
+            object.removeSubscription(_subscriptionId);
+        }
+
+        _agent.removeSubscription(this);
+        return super.cancel(); // Cancel the TimerTask
+    }
+
+    /**
+     * Return the SubscriptionId of this subscription.
+     * @return the SubscriptionId of this subscription.
+     */
+    public String getSubscriptionId()
+    {
+        return _subscriptionId;
+    }
+
+    /**
+     * Return the consoleHandle of this subscription.
+     * @return the consoleHandle of this subscription.
+     */
+    public Handle getConsoleHandle()
+    {
+        return _consoleHandle;
+    }
+
+    /**
+     * Set the Subscription lifetime in seconds. If the value passed to this method is zero the duration gets
+     * set to the Agent's DEFAULT_DURATION is the duration has not already been set, if the duration has already
+     * been set passing in a zero value has no effect on the duration.
+     * If the value passed is non-zero the duration passed gets restricted between the Agent's MIN_DURATION
+     * and MAX_DURATION.
+     *
+     * @param duration the new Subscription lifetime in seconds.
+     */
+    public void setDuration(long duration)
+    {
+        if (duration == 0)
+        {
+            if (_duration == 0)
+            {
+                _duration = DEFAULT_DURATION;
+            } 
+            return;
+        }
+        else
+        {
+            if (duration > MAX_DURATION)
+            {
+                duration = MAX_DURATION;
+            }
+            else if (duration < MIN_DURATION)
+            {
+                duration = MIN_DURATION;
+            }
+        }
+        _duration = duration;
+    }
+
+    /**
+     * Return the current Subscription lifetime value in seconds.
+     * @return the current Subscription lifetime value in seconds.
+     */
+    public long getDuration()
+    {
+        return _duration;
+    }
+
+    /**
+     * Set the Subscription refresh interval in seconds. If the value passed to this method is zero the interval gets
+     * set to the Agent's DEFAULT_INTERVAL otherwise the interval passed gets restricted to be >= the Agent's
+     * MIN_INTERVAL.
+     *
+     * @param interval the time (in milliseconds) between periodic updates of data in this Subscription. 
+     */
+    public void setInterval(long interval)
+    {
+        if (interval == 0)
+        {
+            interval = DEFAULT_INTERVAL;
+        }
+        else if (interval < MIN_INTERVAL)
+        {
+            interval = MIN_INTERVAL;
+        }
+        _interval = interval;
+    }
+
+    /**
+     * Return The time (in milliseconds) between periodic updates of data in this Subscription. 
+     * @return The time (in milliseconds) between periodic updates of data in this Subscription. 
+     */
+    public long getInterval()
+    {
+        return _interval;
+    }
+
+    /**
+     * Return The Subscription's QmfQuery.
+     * @return The Subscription's QmfQuery.
+     */
+    public QmfQuery getQuery()
+    {
+        return _query;
+    }
+}
+

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/Subscription.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/Subscription.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/SubscriptionParams.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/SubscriptionParams.java?rev=1465662&view=auto
==============================================================================
--- qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/SubscriptionParams.java (added)
+++ qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/SubscriptionParams.java Mon Apr  8 15:19:04 2013
@@ -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.qmf2.agent;
+
+import java.util.Map;
+
+// QMF2 Imports
+import org.apache.qpid.qmf2.common.Handle;
+import org.apache.qpid.qmf2.common.QmfData;
+import org.apache.qpid.qmf2.common.QmfException;
+import org.apache.qpid.qmf2.common.QmfQuery;
+
+/**
+ * Holds the information contained in a subscription request made by a Console to an Agent
+ *
+ * @author Fraser Adams
+ */
+public final class SubscriptionParams extends QmfData
+{
+    private final Handle _consoleHandle;
+
+    /**
+     * Construct SubscriptionParams.
+     *
+     * @param handle the handle that the console uses to identify this subscription.
+     * @param m the Map used to populate the SubscriptionParams state.
+     */
+    public SubscriptionParams(final Handle handle, final Map m)
+    {
+        super(m);
+        _consoleHandle = handle;
+    }
+
+    /**
+     * Return the handle that the console uses to identify this subscription.
+     * @return the handle that the console uses to identify this subscription.
+     * <p>
+     * This handle must be passed along with every published update from the Agent.
+     */
+    public Handle getConsoleHandle()
+    {
+        return _consoleHandle;
+    }
+
+    /**
+     * Return the QmfQuery object associated with the SubscriptionParams.
+     * @return the QmfQuery object associated with the SubscriptionParams.
+     */
+    public QmfQuery getQuery() throws QmfException
+    {
+        return new QmfQuery((Map)getValue("_query"));
+    }
+
+    /**
+     * Return the requested time interval in seconds for updates.
+     * @return the requested time interval in seconds for updates. Zero if the Agent's default interval should be used.
+     */
+    public long getPublishInterval()
+    {
+        return getLongValue("_interval");
+    }
+
+    /**
+     * Return the requested lifetime for the subscription.
+     * @return the requested lifetime for the subscription. Zero if the Agent's default subscription lifetime
+     *         should be used.
+     */
+    public long getLifetime()
+    {
+        return getLongValue("_duration");
+    }
+
+    /**
+     * Return authenticated user id of caller if present, else null.
+     * @return authenticated user id of caller if present, else null.
+     */
+    public String getUserId()
+    {
+        return getStringValue("_user_id");
+    }
+}
+
+
+

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/SubscriptionParams.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/SubscriptionParams.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/UnsubscribeRequestWorkItem.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/UnsubscribeRequestWorkItem.java?rev=1465662&view=auto
==============================================================================
--- qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/UnsubscribeRequestWorkItem.java (added)
+++ qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/UnsubscribeRequestWorkItem.java Mon Apr  8 15:19:04 2013
@@ -0,0 +1,65 @@
+/*
+ *
+ * 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.qmf2.agent;
+
+import java.util.Map;
+
+// QMF2 Imports
+import org.apache.qpid.qmf2.common.Handle;
+import org.apache.qpid.qmf2.common.WorkItem;
+
+/**
+ * Descriptions below are taken from <a href=https://cwiki.apache.org/qpid/qmfv2-api-proposal.html>QMF2 API Proposal</a> 
+ * <pre>
+ * UNSUBSCRIBE_REQUEST: The UNSUBSCRIBE_REQUEST is sent by a Console to terminate an existing subscription. The Agent 
+ *                      application should terminate the given subscription if it exists, and cancel sending any further 
+ *                      updates against it.
+ *
+ *                      The getParams() method of a UNSUBSCRIBE_REQUEST WorkItem will return a String holding the 
+ *                      subscriptionId
+ *
+ *                      The getHandle() method returns null.
+ * </pre>
+ * @author Fraser Adams
+ */
+
+public final class UnsubscribeRequestWorkItem extends WorkItem
+{
+    /**
+     * Construct an UnsubscribeRequestWorkItem. Convenience constructor not in API
+     *
+     * @param params the ResubscribeParams used to populate the WorkItem's param
+     */
+    public UnsubscribeRequestWorkItem(final String params)
+    {
+        super(WorkItemType.UNSUBSCRIBE_REQUEST, null, params);
+    }
+
+    /**
+     * Return the subscriptionId String stored in the params Map.
+     * @return the subscriptionId String stored in the params Map.
+     */
+    public String getSubscriptionId()
+    {
+        return (String)getParams();
+    }
+}
+

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/UnsubscribeRequestWorkItem.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/UnsubscribeRequestWorkItem.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/doc-files/QmfData.png
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/doc-files/QmfData.png?rev=1465662&view=auto
==============================================================================
Binary file - no diff available.

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/doc-files/QmfData.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/doc-files/QmfEventListenerModel.png
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/doc-files/QmfEventListenerModel.png?rev=1465662&view=auto
==============================================================================
Binary file - no diff available.

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/doc-files/QmfEventListenerModel.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/doc-files/QmfQuery.png
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/doc-files/QmfQuery.png?rev=1465662&view=auto
==============================================================================
Binary file - no diff available.

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/doc-files/QmfQuery.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/doc-files/Schema.png
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/doc-files/Schema.png?rev=1465662&view=auto
==============================================================================
Binary file - no diff available.

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/doc-files/Schema.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/doc-files/Subscriptions.png
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/doc-files/Subscriptions.png?rev=1465662&view=auto
==============================================================================
Binary file - no diff available.

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/doc-files/Subscriptions.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/doc-files/WorkQueueEventModel.png
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/doc-files/WorkQueueEventModel.png?rev=1465662&view=auto
==============================================================================
Binary file - no diff available.

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/agent/doc-files/WorkQueueEventModel.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/common/AMQPMessage.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/common/AMQPMessage.java?rev=1465662&view=auto
==============================================================================
--- qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/common/AMQPMessage.java (added)
+++ qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/common/AMQPMessage.java Mon Apr  8 15:19:04 2013
@@ -0,0 +1,309 @@
+/*
+ *
+ * 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.qmf2.common;
+
+// JMS Imports
+import javax.jms.BytesMessage;
+import javax.jms.JMSException;
+import javax.jms.MapMessage;
+import javax.jms.Message;
+import javax.jms.MessageFormatException;
+import javax.jms.Session;
+
+// Misc Imports
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.HashMap;
+import java.util.Map;
+
+// Need the following to decode and encode amqp/list messages
+import java.nio.ByteBuffer;
+import org.apache.qpid.transport.codec.BBDecoder;
+import org.apache.qpid.transport.codec.BBEncoder;
+
+// QMF2 Imports
+import org.apache.qpid.qmf2.common.QmfData;
+
+/**
+ * Provides static helper methods for encoding and decoding "amqp/list" and "amqp/map" ContentTypes.
+ *<p> 
+ * Unfortunately the encoding of amqp/map and amqp/list messages is not as useful as it might be in the
+ * Qpid JMS runtime. amqp/list messages don't <i>actually</i> have a useful encoding in Qpid JMS, so we have to
+ * fake it in this class by encoding/decoding java.util.List objects into a JMS BytesMessage and setting
+ * the ContentType to "amqp/list".
+ *<p>
+ * Whilst amqp/map messages are encoded as JMS MapMessage this isn't necessarily the most useful format as
+ * MapMessage does not conform to the java.util.Map interface. As QMF methods returning lists return lists
+ * of java.util.Map there's a bit of an inconsistency of type that getMap() resolves.
+ * 
+ * @author Fraser Adams
+ */
+public final class AMQPMessage
+{
+    /**
+     * Make constructor private at this class provides a set of static helper methods and doesn't need instantiated.
+     */
+    private AMQPMessage()
+    {
+    }
+
+    /**
+     * This method exposes the AMQP Content-Type from a JMS Message. This has been put into an accessor
+     * method because some evil hackery has to take place to set the Content-Type as no pure JMS API
+     * property currently gets mapped to Content-Type, so we have to cast to AbstractJMSMessage.
+     *
+     * @param message a JMS Message.
+     * @return the AMQP Content-Type e.g. amqp/list, amqp/map etc.
+     */
+    public static String getContentType(final Message message)
+    {
+        return ((org.apache.qpid.client.message.AbstractJMSMessage)message).getContentType();
+    }
+
+    /**
+     * This method sets the AMQP Content-Type on a JMS Message. This has been put into a mutator
+     * method because some evil hackery has to take place to set the Content-Type as no pure JMS API
+     * property currently gets mapped to Content-Type, so we have to cast to AbstractJMSMessage.
+     *
+     * @param message a JMS Message.
+     * @param contentType the AMQP Content-Type that we'd like to set, e.g. amqp/list, amqp/map etc.
+     */
+    public static void setContentType(final Message message, String contentType)
+    {
+        ((org.apache.qpid.client.message.AbstractJMSMessage)message).setContentType(contentType);
+    }
+
+    /**
+     * Provides an abstracted way for client code to explicitly check if a Message is an AMQP List.
+     *
+     * @param message a JMS Message.
+     * @return true if the Message is an AMQP List, otherwise returns false.
+     */
+    public static boolean isAMQPList(final Message message)
+    {
+        if (getContentType(message).equals("amqp/list") || message instanceof BytesMessage)
+        {
+            // I *think* that the test for BytesMessage is actually redundant and that Content-Type would
+            // always have to be "amqp/list" for JMS to expose the Message as a BytesMessage but I've
+            // kept the test because pre Qpid 0.20 exposed lists as BytesMessage.
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+    /**
+     * Provides an abstracted way for client code to explicitly check if a Message is an AMQP Map.
+     *
+     * @param message a JMS Message.
+     * @return true if the Message is an AMQP Map, otherwise returns false.
+     */
+    public static boolean isAMQPMap(final Message message)
+    {
+        if (getContentType(message).equals("amqp/map") || 
+            (message instanceof MapMessage && !isAMQPList(message)))
+        {
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+    /** 
+     * Builds a java.util.Map from a JMS MapMessage.
+     * This is really a helper method to make code more homogenous as QmfData objects are constructed from Maps
+     * but JMS returns MapMessages which don't share a common interface. This method enumerates MapMessage
+     * Properties and Objects and stores them in a java.util.Map.
+     *
+     * @param message a JMS Message
+     * @return a java.util.Map containing the the properties extracted from the Message.
+     * <p>
+     * Note that this method copies the Message properties <b>and</b> the properties from the MapMessage Map.
+     * <p>
+     * This method also attempts to populate "_user_id" using the JMSXUserID property, however that's not as
+     * easy as it sounds!! There's a bug in AMQMessageDelegate_0_10.getStringProperty() whereby if the property
+     * is "JMSXUserID" it returns "new String(_messageProps.getUserId());" however if the client uses anonymous
+     * authentication _messageProps.getUserId() returns null. In order to get around this this class unfortunately
+     * has to delve inside "org.apache.qpid.client.message.AbstractJMSMessage".
+     */
+    public static Map<String, Object> getMap(final Message message) throws JMSException
+    {
+        if (message == null)
+        {
+            throw new MessageFormatException("Attempting to do AMQPMessage.getMap() on null Message");
+        }
+        else if (message instanceof MapMessage)
+        {
+            Map<String, Object> object = new HashMap<String, Object>();
+            MapMessage msg = (MapMessage)message;
+            for (Enumeration e = msg.getMapNames(); e.hasMoreElements();)
+            {
+                String key = (String)e.nextElement();
+                object.put(key, msg.getObject(key));
+            }
+            
+            if (object.size() == 0)
+            { // If there is no MapMessage content return an empty Map.
+                return object;
+            }
+
+            // If there is MapMessage content include the Message properties in the returned Map.
+            for (Enumeration e = msg.getPropertyNames(); e.hasMoreElements();)
+            {
+                String prop = (String)e.nextElement();
+                object.put(prop, QmfData.getString(msg.getObjectProperty(prop)));
+            }
+
+            // Should be msg.getStringProperty("JMSXUserID"). See comments above for the reason behind this evil hack.
+            org.apache.qpid.client.message.AMQMessageDelegate_0_10 delegate = (org.apache.qpid.client.message.AMQMessageDelegate_0_10)(((org.apache.qpid.client.message.AbstractJMSMessage)msg).getDelegate());
+            byte[] rawUserId = delegate.getMessageProperties().getUserId();
+            if (rawUserId != null)
+            {
+                String userId = new String(rawUserId);
+                object.put("_user_id", userId);
+            }
+
+            return object;
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+    /**
+     * JMS QMF returns amqp/list types as a BytesMessage this method decodes that into a java.util.List
+     * <p>
+     * Taken from Gordon Sim's initial JMS QMF Example using the BBDecoder
+     * <p>
+     * Trivia: This block of code from Gordon Sim is the seed that spawned the whole of this Java QMF2 API
+     * implementation - cheers Gordon.
+     *
+     * @param message amqp/list encoded JMS Message
+     * @return a java.util.List decoded from Message
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> List<T> getList(final Message message) throws JMSException
+    {
+        if (message == null)
+        {
+            throw new MessageFormatException("Attempting to do AMQPMessage.getList() on null Message");
+        }
+        else if (message instanceof BytesMessage)
+        {
+            BytesMessage msg = (BytesMessage)message;
+
+            //only handles responses up to 2^31-1 bytes long
+            byte[] data = new byte[(int) msg.getBodyLength()];
+            msg.readBytes(data);
+            BBDecoder decoder = new BBDecoder();
+            decoder.init(ByteBuffer.wrap(data));
+            return (List<T>)decoder.readList();
+        }
+        else if (message instanceof MapMessage)
+        {   /*
+             * In Qpid version 0.20 instead of exposing amqp/list as a BytesMessage as above rather it is exposed
+             * as a MapMessage!!??? the Object Keys are the indices into the List. We create a java.util.List
+             * out of this by iterating through the getMapNames() Enumeration and copying the Objects into the List.
+             * This amount of copying doesn't feel healthy and we can't even work out the capacity for the List
+             * a priori, but I'm not sure of a better way at present. I can't say I much like how amqp/list or indeed
+             * amqp/map are currently encoded. I'd *much* prefer to see them exposed as JMS ObjectMessage.
+             */
+            MapMessage msg = (MapMessage)message;
+            List resultList = new ArrayList(50); // Initial capacity of 50, can we better estimate this?
+
+            for (Enumeration e = msg.getMapNames(); e.hasMoreElements();)
+            {
+                String key = (String)e.nextElement();
+                resultList.add(msg.getObject(key));
+            }
+            return resultList;
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+    /**
+     * Creates an amqp/list encoded Message out of a BytesMessage.
+     * <p>
+     * This is somewhat of a dirty hack that needs to be monitored as qpid versions change.
+     * <p>
+     * Unfortunately there's no "clean" way to encode or decode amqp/list messages via the JMS API.
+     *
+     * @param session used to create the JMS Message
+     * @return an amqp/list encoded JMS Message
+     */
+    public static Message createListMessage(final Session session) throws JMSException
+    {
+        BytesMessage message = session.createBytesMessage();
+        setContentType(message, "amqp/list");
+        return message;
+    }
+
+    /**
+     * Encodes a java.util.List on an amqp/list encoded BytesMessage.
+     * <p>
+     * This is somewhat of a dirty hack that needs to be monitored as qpid versions change.
+     * <p>
+     * This method uses the org.apache.qpid.transport.codec.BBEncoder writeList() method to encode
+     * a List into a ByteBuffer then writes the bytes from the buffer into a JMS BytesMessage.
+     *
+     * @param message amqp/list encoded JMS BytesMessage
+     * @param list to encode into JMS Message
+     */
+    @SuppressWarnings("unchecked")
+    public static void setList(final Message message, final List list) throws JMSException
+    {
+        String type = getContentType(message);
+        if (!type.equals("amqp/list"))
+        {
+            throw new MessageFormatException("Can only do setList() on amqp/list encoded Message");
+        }
+
+        if (message == null)
+        {
+            throw new MessageFormatException("Attempting to do AMQPMessage.setList() on null Message");
+        }
+        else if (message instanceof BytesMessage)
+        {
+            BBEncoder encoder = new BBEncoder(1024);
+            encoder.writeList(list);
+            ByteBuffer buf = encoder.segment();
+            byte[] data = new byte[buf.limit()];
+            buf.get(data);
+            ((BytesMessage)message).writeBytes(data);
+        }
+        else
+        {
+            throw new MessageFormatException("Attempting to do setList() on " + message.getClass().getCanonicalName());
+        }
+    }
+}
+
+
+

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/common/AMQPMessage.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/common/AMQPMessage.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/common/BlockingNotifier.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/common/BlockingNotifier.java?rev=1465662&view=auto
==============================================================================
--- qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/common/BlockingNotifier.java (added)
+++ qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/common/BlockingNotifier.java Mon Apr  8 15:19:04 2013
@@ -0,0 +1,65 @@
+/*
+ *
+ * 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.qmf2.common;
+
+/**
+ * Implementation of the Notifier Interface that provides a waitForWorkItem() method which blocks until the
+ * Console has called the indication() method indicating that there are WorkItems available.
+ * <p>
+ * This class isn't part of the QMF2 API however it's almost certainly how most clients would choose to use the
+ * Notifier API so it seems useful to provide an implementation.
+ * 
+ * @author Fraser Adams
+ */
+public final class BlockingNotifier implements Notifier
+{
+    private boolean _waiting = true;
+
+    /**
+     * This method blocks until the indication() method has been called, this is generally called by the Console
+     * when new WorkItems are made available.
+     */
+    public synchronized void waitForWorkItem()
+    {
+        while (_waiting)
+        {
+            try
+            {
+                wait();
+            }
+            catch (InterruptedException ie)
+            {
+                continue;
+            }
+        }
+        _waiting = true;
+    }
+
+    /**
+     * Called to indicate the availability of WorkItems. This method unblocks waitForWorkItem()
+     */
+    public synchronized void indication()
+    {
+        _waiting = false;
+        notifyAll();
+    }
+}
+

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/common/BlockingNotifier.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/common/BlockingNotifier.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/common/BooleanEquals.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/common/BooleanEquals.java?rev=1465662&view=auto
==============================================================================
--- qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/common/BooleanEquals.java (added)
+++ qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/common/BooleanEquals.java Mon Apr  8 15:19:04 2013
@@ -0,0 +1,79 @@
+/*
+ *
+ * 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.qmf2.common;
+
+// Misc Imports
+import java.util.List;
+
+/**
+ * A class to create and evaluate the BooleanEquals Expression
+ *
+ * @author Fraser Adams
+ */
+public final class BooleanEquals extends BooleanExpression
+{
+    /**
+     * Factory method to create an instance of BooleanEquals
+     * @param expr the List of Expressions extracted by parsing the Query predicate
+     * @return an instance of the concrete BooleanExpression
+     */
+    public Expression create(final List expr) throws QmfException
+    {
+        return new BooleanEquals(expr);
+    }
+
+    /**
+     * Basic Constructor primarily used by the prototype instance of each concrete BooleanExpression
+     */
+    public BooleanEquals()
+    {
+    }
+
+    /**
+     * Main Constructor, uses base class constructor to populate unevaluated operands
+     * @param expr the List of Expressions extracted by parsing the Query predicate
+     */
+    public BooleanEquals(final List expr) throws QmfException
+    {
+        super(2, expr);
+    }
+    
+    /**
+     * Evaluate "equal to" expression against a QmfData instance.
+     * N.B. to avoid complexities with types this class treats operands as Strings performing an appropriate evaluation
+     * of the String that makes sense for a given expression e.g. parsing as a double for >, >=, <, <=
+     *
+     * @param data the object to evaluate the expression against
+     * @return true if query matches the QmfData instance, else false.
+     */
+    public boolean evaluate(final QmfData data)
+    {
+        populateOperands(data);
+
+        if (_operands[0] == null || _operands[1] == null)
+        {
+            return false;
+        }
+
+        return _operands[0].equals(_operands[1]);
+    }
+}
+

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/common/BooleanEquals.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/common/BooleanEquals.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/common/BooleanExists.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/common/BooleanExists.java?rev=1465662&view=auto
==============================================================================
--- qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/common/BooleanExists.java (added)
+++ qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/common/BooleanExists.java Mon Apr  8 15:19:04 2013
@@ -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.qmf2.common;
+
+// Misc Imports
+import java.util.List;
+
+/**
+ * A class to create and evaluate the BooleanExists Expression
+ *
+ * @author Fraser Adams
+ */
+public final class BooleanExists extends BooleanExpression
+{
+    /**
+     * Factory method to create an instance of BooleanExists
+     * @param expr the List of Expressions extracted by parsing the Query predicate
+     * @return an instance of the concrete BooleanExpression
+     */
+    public Expression create(final List expr) throws QmfException
+    {
+        return new BooleanExists(expr);
+    }
+
+    /**
+     * Basic Constructor primarily used by the prototype instance of each concrete BooleanExpression
+     */
+    public BooleanExists()
+    {
+    }
+
+    /**
+     * Main Constructor, uses base class constructor to populate unevaluated operands
+     * @param expr the List of Expressions extracted by parsing the Query predicate
+     */
+    public BooleanExists(final List expr) throws QmfException
+    {
+        super(1, expr);
+    }
+
+    /**
+     * Evaluate "exists" expression against a QmfData instance.
+     * N.B. to avoid complexities with types this class treats operands as Strings performing an appropriate evaluation
+     * of the String that makes sense for a given expression e.g. parsing as a double for >, >=, <, <=
+     *
+     * @param data the object to evaluate the expression against
+     * @return true if query matches the QmfData instance, else false.
+     */    
+    public boolean evaluate(final QmfData data)
+    {
+        return _operands[0] != null;
+    }
+}
+

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/common/BooleanExists.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/common/BooleanExists.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date



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