summaryrefslogtreecommitdiff
path: root/qpid/tools/src/java/qpid-qmf2/src/main/java/org/apache/qpid/qmf2/common/QmfData.java
diff options
context:
space:
mode:
Diffstat (limited to 'qpid/tools/src/java/qpid-qmf2/src/main/java/org/apache/qpid/qmf2/common/QmfData.java')
-rw-r--r--qpid/tools/src/java/qpid-qmf2/src/main/java/org/apache/qpid/qmf2/common/QmfData.java443
1 files changed, 443 insertions, 0 deletions
diff --git a/qpid/tools/src/java/qpid-qmf2/src/main/java/org/apache/qpid/qmf2/common/QmfData.java b/qpid/tools/src/java/qpid-qmf2/src/main/java/org/apache/qpid/qmf2/common/QmfData.java
new file mode 100644
index 0000000000..571db16064
--- /dev/null
+++ b/qpid/tools/src/java/qpid-qmf2/src/main/java/org/apache/qpid/qmf2/common/QmfData.java
@@ -0,0 +1,443 @@
+/*
+ *
+ * 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.io.UnsupportedEncodingException;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * QMF defines the QmfData class to represent an atomic unit of managment data.
+ * <p>
+ * The QmfData class defines a collection of named data values. Optionally, a string tag, or "sub-type" may be
+ * associated with each data item. This tag may be used by an application to annotate the data item.
+ * (Note the tag implementation is TBD).
+ * <p>
+ * In QMFv2, message bodies are AMQP maps and are therefore easily extended without causing backward
+ * compatibility problems. Another benefit of the map-message format is that all messages can be fully
+ * parsed when received without the need for external schema data
+ * <p>
+ * This class is the base class for all QMF2 Data Types in this implementation. It is intended to provide a
+ * useful wrapper for the underlying Map, supplying accessor and mutator methods that give an element of type
+ * safety (for example strings appear to be encoded as a mixture of byte[] and String depending of the agent, so
+ * this class checks for this in its getString())
+ * <p>
+ * The following diagram represents the QmfData class hierarchy.
+ * <p>
+ * <img src="doc-files/QmfData.png"/>
+ *
+ * @author Fraser Adams
+ */
+public class QmfData
+{
+ protected Map<String, Object> _values = null;
+ protected Map<String, String> _subtypes = null;
+
+ /**
+ * The default constructor, initialises the QmfData with an empty Map.
+ */
+ public QmfData()
+ {
+ _values = new HashMap<String, Object>();
+ }
+
+ /**
+ * The main constructor, taking a java.util.Map as a parameter. In essence it "deserialises" its state from the Map.
+ *
+ * @param m the Map used to construct the QmfData.
+ */
+ @SuppressWarnings("unchecked")
+ public QmfData(final Map m)
+ {
+ if (m == null)
+ { // This branch is just a safety precaution and shouldn't generally occur in normal usage scenarios.
+ // Initialise with a new HashMap. Should then behave the same as the default Constructor.
+ _values = new HashMap<String, Object>();
+ }
+ else
+ {
+ Map<String, Object> values = (Map<String, Object>)m.get("_values");
+ _values = (values == null) ? m : values;
+
+ Map<String, String> subtypes = (Map<String, String>)m.get("_subtypes");
+ _subtypes = subtypes;
+ }
+ }
+
+ /**
+ * Get the state of the _subtypes Map, (generally used when serialising method request/response arguments.
+ *
+ * @return the value of the _subtypes Map.
+ */
+ public Map<String, String> getSubtypes()
+ {
+ return _subtypes;
+ }
+
+
+ /**
+ * Set the state of the _subtypes Map, (generally used when deserialising method request/response arguments.
+ *
+ * @param subtypes the new value of the _subtypes Map.
+ */
+ @SuppressWarnings("unchecked")
+ public void setSubtypes(Map subtypes)
+ {
+ _subtypes = subtypes;
+ }
+
+ /**
+ * Helper method to return the <i>best</i> String representation of the given Object.
+ * <p>
+ * There seem to be some inconsistencies where string properties are sometimes returned as byte[] and
+ * sometimes as Strings. It seems to vary depending on the Agent and is due to strings being encoded as a mix of
+ * binary strings and UTF-8 strings by C++ Agent classes. Getting it wrong results in ClassCastExceptions, which
+ * is clearly unfortunate.
+ * <p>
+ * This is basically a helper method to check the type of a property and return the most "appropriate"
+ * String representation for it.
+ *
+ * @param p a property in Object form
+ * @return the most appropriate String representation of the property
+ */
+ public static final String getString(final Object p)
+ {
+ if (p == null)
+ {
+ return "";
+ }
+ else if (p instanceof String)
+ {
+ return (String)p;
+ }
+ else if (p instanceof byte[])
+ {
+ return new String((byte[])p);
+ }
+ else return p.toString();
+ }
+
+ /**
+ * Helper method to return the <i>best</i> long representation of the given Object.
+ * <p>
+ * There seem to be some inconsistencies where properties are sometimes returned as Integer and
+ * sometimes as Long. It seems to vary depending on the Agent and getting it wrong results in
+ * ClassCastExceptions, which is clearly unfortunate.
+ * <p>
+ * This is basically a helper method to check the type of a property and return a long representation for it.
+ *
+ * @param p a property in Object form
+ * @return the long representation for it.
+ */
+ public static final long getLong(final Object p)
+ {
+ if (p == null)
+ {
+ return 0;
+ }
+ else if (p instanceof Long)
+ {
+ return ((Long)p).longValue();
+ }
+ else if (p instanceof Integer)
+ {
+ return ((Integer)p).intValue();
+ }
+ else if (p instanceof Short)
+ {
+ return ((Short)p).shortValue();
+ }
+ else return 0;
+ }
+
+ /**
+ * Helper method to return the <i>best</i> boolean representation of the given Object.
+ * <p>
+ * There seem to be some inconsistencies where boolean properties are sometimes returned as Boolean and
+ * sometimes as Long/Integer/Short. It seems to vary depending on the Agent and getting it wrong results in
+ * ClassCastExceptions, which is clearly unfortunate.
+ * <p>
+ * This is basically a helper method to check the type of a property and return a boolean representation for it.
+ *
+ * @param p a property in Object form
+ * @return the boolean representation for it.
+ */
+ public static final boolean getBoolean(final Object p)
+ {
+ if (p == null)
+ {
+ return false;
+ }
+ else if (p instanceof Boolean)
+ {
+ return ((Boolean)p).booleanValue();
+ }
+ else if (p instanceof Long)
+ {
+ return ((Long)p).longValue() > 0;
+ }
+ else if (p instanceof Integer)
+ {
+ return ((Integer)p).intValue() > 0;
+ }
+ else if (p instanceof Short)
+ {
+ return ((Short)p).shortValue() > 0;
+ }
+ else if (p instanceof String)
+ {
+ return Boolean.parseBoolean((String)p);
+ }
+ else return false;
+ }
+
+ /**
+ * Helper method to return the <i>best</i> double representation of the given Object.
+ * <p>
+ * There seem to be some inconsistencies where properties are sometimes returned as Float and
+ * sometimes as Double. It seems to vary depending on the Agent and getting it wrong results in
+ * ClassCastExceptions, which is clearly unfortunate.
+ * <p>
+ * This is basically a helper method to check the type of a property and return a Double representation for it.
+ *
+ * @param p a property in Object form
+ * @return the Double representation for it.
+ */
+ public static final double getDouble(final Object p)
+ {
+ if (p == null)
+ {
+ return 0.0d;
+ }
+ else if (p instanceof Float)
+ {
+ return ((Float)p).floatValue();
+ }
+ else if (p instanceof Double)
+ {
+ return ((Double)p).doubleValue();
+ }
+ else return 0.0d;
+ }
+
+ /**
+ * Determines if the named property exists.
+ *
+ * @param name of the property to check.
+ * @return true if the property exists otherwise false.
+ */
+ public final boolean hasValue(final String name)
+ {
+ return _values.containsKey(name);
+ }
+
+ /**
+ * Accessor method to return a named property as an Object.
+ *
+ * @param name of the property to return as an Object.
+ * @return value of property as an Object.
+ */
+ @SuppressWarnings("unchecked")
+ public final <T> T getValue(final String name)
+ {
+ return (T)_values.get(name);
+ }
+
+ /**
+ * Mutator method to set a named Object property.
+ *
+ * @param name the name of the property to set.
+ * @param value the value of the property to set.
+ */
+ public final void setValue(final String name, final Object value)
+ {
+ _values.put(name, value);
+ }
+
+ /**
+ * Mutator method to set a named Object property.
+ *
+ * @param name the name of the property to set.
+ * @param value the value of the property to set.
+ * @param subtype the subtype of the property.
+ */
+ public final void setValue(final String name, final Object value, final String subtype)
+ {
+ setValue(name, value);
+ setSubtype(name, subtype);
+ }
+
+ /**
+ * Mutator to set or modify the subtype associated with name.
+ *
+ * @param name the name of the property to set the subtype for.
+ * @param subtype the subtype of the property.
+ */
+ public final void setSubtype(final String name, final String subtype)
+ {
+ if (_subtypes == null)
+ {
+ _subtypes = new HashMap<String, String>();
+ }
+ _subtypes.put(name, subtype);
+ }
+
+ /**
+ * Accessor to return the subtype associated with named property.
+ *
+ * @param name the name of the property to get the subtype for.
+ * @return the subtype of the named property or null if not present.
+ */
+ public final String getSubtype(final String name)
+ {
+ if (_subtypes == null)
+ {
+ return null;
+ }
+ return _subtypes.get(name);
+ }
+
+ /**
+ * Accessor method to return a named property as a boolean.
+ *
+ * @param name of the property to return as a boolean.
+ * @return value of property as a boolean.
+ */
+ public final boolean getBooleanValue(final String name)
+ {
+ return getBoolean(getValue(name));
+ }
+
+ /**
+ * Accessor method to return a named property as a long.
+ *
+ * @param name of the property to return as a long.
+ * @return value of property as a long.
+ */
+ public final long getLongValue(final String name)
+ {
+ return getLong(getValue(name));
+ }
+
+ /**
+ * Accessor method to return a named property as a double.
+ *
+ * @param name of the property to return as a double.
+ * @return value of property as a double.
+ */
+ public final double getDoubleValue(final String name)
+ {
+ return getDouble(getValue(name));
+ }
+
+ /**
+ * Accessor method to return a named property as a String.
+ *
+ * @param name of the property to return as a String.
+ * @return value of property as a String.
+ */
+ public final String getStringValue(final String name)
+ {
+ return getString(getValue(name));
+ }
+
+ /**
+ * Accessor method to return a reference property.
+ * <p>
+ * Many QMF Objects contain reference properties, e.g. references to other QMF Objects.
+ * This method allows these to be obtained as ObjectId objects to enable much easier
+ * comparison and rendering.
+ * @return the retrieved value as an ObjectId instance.
+ */
+ public final ObjectId getRefValue(final String name)
+ {
+ return new ObjectId((Map)getValue(name));
+ }
+
+ /**
+ * Mutator method to set a named reference property.
+ * <p>
+ * Many QMF Objects contain reference properties, e.g. references to other QMF Objects.
+ * This method allows these to be set as ObjectId objects.
+ *
+ * @param name the name of the property to set.
+ * @param value the value of the property to set.
+ */
+ public final void setRefValue(final String name, final ObjectId value)
+ {
+ setValue(name, value.mapEncode());
+ }
+
+ /**
+ * Mutator method to set a named reference property.
+ * <p>
+ * Many QMF Objects contain reference properties, e.g. references to other QMF Objects.
+ * This method allows these to be set as ObjectId objects.
+ *
+ * @param name the name of the property to set.
+ * @param value the value of the property to set.
+ * @param subtype the subtype of the property.
+ */
+ public final void setRefValue(final String name, final ObjectId value, final String subtype)
+ {
+ setRefValue(name, value);
+ setSubtype(name, subtype);
+ }
+
+ /**
+ * Return the underlying Map representation of this QmfData.
+ * @return the underlying Map.
+ */
+ public Map<String, Object> mapEncode()
+ {
+ return _values;
+ }
+
+ /**
+ * Helper/debug method to list the properties and their type.
+ */
+ public void listValues()
+ {
+ for (Map.Entry<String, Object> entry : _values.entrySet())
+ {
+ Object key = entry.getKey();
+ Object value = entry.getValue();
+ if (value instanceof Map)
+ { // Check if the value part is an ObjectId and display appropriately
+ Map map = (Map)value;
+ if (map.containsKey("_object_name"))
+ {
+ System.out.println(key + ": " + new ObjectId(map));
+ }
+ else
+ {
+ System.out.println(key + ": " + getString(value));
+ }
+ }
+ else
+ {
+ System.out.println(key + ": " + getString(value));
+ }
+ }
+ }
+}
+