Return-Path: X-Original-To: apmail-activemq-commits-archive@www.apache.org Delivered-To: apmail-activemq-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 9A58017A83 for ; Tue, 11 Nov 2014 18:41:34 +0000 (UTC) Received: (qmail 32349 invoked by uid 500); 11 Nov 2014 18:41:33 -0000 Delivered-To: apmail-activemq-commits-archive@activemq.apache.org Received: (qmail 32261 invoked by uid 500); 11 Nov 2014 18:41:33 -0000 Mailing-List: contact commits-help@activemq.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@activemq.apache.org Delivered-To: mailing list commits@activemq.apache.org Received: (qmail 30512 invoked by uid 99); 11 Nov 2014 18:41:32 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 11 Nov 2014 18:41:32 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 189BAA0D75D; Tue, 11 Nov 2014 18:41:32 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: andytaylor@apache.org To: commits@activemq.apache.org Date: Tue, 11 Nov 2014 18:41:54 -0000 Message-Id: <9ef35df679934d0c983a5592f02bce78@git.apache.org> In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [24/51] [abbrv] [partial] activemq-6 git commit: ACTIVEMQ6-4 - Rename packages to ActiveMQ http://git-wip-us.apache.org/repos/asf/activemq-6/blob/23e8edd9/activemq6-core-client/src/main/java/org/apache/activemq6/utils/json/JSONObject.java ---------------------------------------------------------------------- diff --git a/activemq6-core-client/src/main/java/org/apache/activemq6/utils/json/JSONObject.java b/activemq6-core-client/src/main/java/org/apache/activemq6/utils/json/JSONObject.java new file mode 100644 index 0000000..bf74a3e --- /dev/null +++ b/activemq6-core-client/src/main/java/org/apache/activemq6/utils/json/JSONObject.java @@ -0,0 +1,1751 @@ +/* + * Copyright 2005-2014 Red Hat, Inc. + * Red Hat 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. + */ +/* +Copyright (c) 2002 JSON.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +package org.apache.activemq6.utils.json; + +import java.io.IOException; +import java.io.Writer; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.TreeSet; + +/** + * A JSONObject is an unordered collection of name/value pairs. + *

+ * Its external form is a string wrapped in curly braces with colons between the names and values, + * and commas between the values and names. The internal form is an object having get + * and opt methods for accessing the values by name, and put methods for + * adding or replacing values by name. + *

+ * The values can be any of these types: Boolean, JSONArray, + * JSONObject, Number, {@code string}, or the + * JSONObject.NULL object. A JSONObject constructor can be used to convert an external + * form JSON text into an internal form whose values can be retrieved with the get and + * opt methods, or to convert values into a JSON text using the put and + * toString methods. A get method returns a value if one can be found, and + * throws an exception if one cannot be found. An opt method returns a default value + * instead of throwing an exception, and so is useful for obtaining optional values. + *

+ * The generic get() and opt() methods return an object, which you can + * cast or query for type. There are also typed get and opt methods that + * do type checking and type coercion for you. + *

+ * The put methods adds values to an object. For example, + * + *

+ * myString = new JSONObject().put("JSON", "Hello, World!").toString();
+ * 
+ * + * produces the string {"JSON": "Hello, World"}. + *

+ * The texts produced by the toString methods strictly conform to the JSON syntax + * rules. The constructors are more forgiving in the texts they will accept: + *

    + *
  • An extra , (comma) may appear just before the closing brace. + *
  • + *
  • Strings may be quoted with ' (single quote).
  • + *
  • Strings do not need to be quoted at all if they do not begin with a quote or single quote, + * and if they do not contain leading or trailing spaces, and if they do not contain any of these + * characters: { } [ ] / \ : , = ; # and if they do not look like numbers and if they + * are not the reserved words true, false, or {@code null}.
  • + *
  • Keys can be followed by = or => as well as by :.
  • + *
  • Values can be followed by ; (semicolon) as well as by + * , (comma).
  • + *
  • Numbers may have the 0- (octal) or 0x- + * (hex) prefix.
  • + *
+ * @author JSON.org + * @version 2009-03-06 + */ +public class JSONObject +{ + + /** + * JSONObject.NULL is equivalent to the value that JavaScript calls null, + * whilst Java's null is equivalent to the value that JavaScript calls + * undefined. + */ + private static final class Null + { + + /** + * There is only intended to be a single instance of the NULL object, + * so the clone method returns itself. + * @return NULL. + */ + @Override + protected Object clone() + { + return this; + } + + /** + * A Null object is equal to the null value and to itself. + * @param object An object to test for nullness. + * @return true if the object parameter is the JSONObject.NULL object + * or null. + */ + @Override + public boolean equals(final Object object) + { + return object == null || object == this; + } + + @Override + public int hashCode() + { + // TODO + return 0; + } + + /** + * Get the "null" string value. + * @return The string "null". + */ + @Override + public String toString() + { + return "null"; + } + } + + /** + * The map where the JSONObject's properties are kept. + */ + private final Map map; + + /** + * It is sometimes more convenient and less ambiguous to have a + * {@code null} object than to use Java's {@code null} value. + * JSONObject.NULL.equals(null) returns true. + * JSONObject.NULL.toString() returns "null". + */ + public static final Object NULL = new Null(); + + /** + * Construct an empty JSONObject. + */ + public JSONObject() + { + map = new HashMap(); + } + + /** + * Construct a JSONObject from a subset of another JSONObject. + * An array of strings is used to identify the keys that should be copied. + * Missing keys are ignored. + * @param jo A JSONObject. + * @param names An array of strings. + * @exception JSONException If a value is a non-finite number or if a name is duplicated. + */ + public JSONObject(final JSONObject jo, final String[] names) throws JSONException + { + this(); + for (String name : names) + { + putOnce(name, jo.opt(name)); + } + } + + /** + * Construct a JSONObject from a JSONTokener. + * @param x A JSONTokener object containing the source string. + * @throws JSONException If there is a syntax error in the source string + * or a duplicated key. + */ + public JSONObject(final JSONTokener x) throws JSONException + { + this(); + char c; + String key; + + if (x.nextClean() != '{') + { + throw x.syntaxError("A JSONObject text must begin with '{'"); + } + for (;;) + { + c = x.nextClean(); + switch (c) + { + case 0: + throw x.syntaxError("A JSONObject text must end with '}'"); + case '}': + return; + default: + x.back(); + key = x.nextValue().toString(); + } + + /* + * The key is followed by ':'. We will also tolerate '=' or '=>'. + */ + + c = x.nextClean(); + if (c == '=') + { + if (x.next() != '>') + { + x.back(); + } + } + else if (c != ':') + { + throw x.syntaxError("Expected a ':' after a key"); + } + putOnce(key, x.nextValue()); + + /* + * Pairs are separated by ','. We will also tolerate ';'. + */ + + switch (x.nextClean()) + { + case ';': + case ',': + if (x.nextClean() == '}') + { + return; + } + x.back(); + break; + case '}': + return; + default: + throw x.syntaxError("Expected a ',' or '}'"); + } + } + } + + /** + * Construct a JSONObject from a Map. + * + * @param map A map object that can be used to initialize the contents of + * the JSONObject. + */ + public JSONObject(final Map map) + { + this.map = map == null ? new HashMap() : map; + } + + /** + * Construct a JSONObject from a Map. + * + * Note: Use this constructor when the map contains <key,bean>. + * + * @param map - A map with Key-Bean data. + * @param includeSuperClass - Tell whether to include the super class properties. + */ + public JSONObject(final Map map, final boolean includeSuperClass) + { + this.map = new HashMap(); + if (map != null) + { + Iterator i = map.entrySet().iterator(); + while (i.hasNext()) + { + Map.Entry e = i.next(); + if (JSONObject.isStandardProperty(e.getValue().getClass())) + { + this.map.put(e.getKey(), e.getValue()); + } + else + { + this.map.put(e.getKey(), new JSONObject(e.getValue(), includeSuperClass)); + } + } + } + } + + /** + * Construct a JSONObject from an Object using bean getters. + * It reflects on all of the public methods of the object. + * For each of the methods with no parameters and a name starting + * with "get" or "is" followed by an uppercase letter, + * the method is invoked, and a key and the value returned from the getter method + * are put into the new JSONObject. + * + * The key is formed by removing the "get" or "is" prefix. + * If the second remaining character is not upper case, then the first + * character is converted to lower case. + * + * For example, if an object has a method named "getName", and + * if the result of calling object.getName() is "Larry Fine", + * then the JSONObject will contain "name": "Larry Fine". + * + * @param bean An object that has getter methods that should be used + * to make a JSONObject. + */ + public JSONObject(final Object bean) + { + this(); + populateInternalMap(bean, false); + } + + /** + * Construct a JSONObject from an Object using bean getters. + * It reflects on all of the public methods of the object. + * For each of the methods with no parameters and a name starting + * with "get" or "is" followed by an uppercase letter, + * the method is invoked, and a key and the value returned from the getter method + * are put into the new JSONObject. + * + * The key is formed by removing the "get" or "is" prefix. + * If the second remaining character is not upper case, then the first + * character is converted to lower case. + * + * @param bean An object that has getter methods that should be used + * to make a JSONObject. + * @param includeSuperClass If true, include the super class properties. + */ + public JSONObject(final Object bean, final boolean includeSuperClass) + { + this(); + populateInternalMap(bean, includeSuperClass); + } + + private void populateInternalMap(final Object bean, boolean includeSuperClass) + { + Class klass = bean.getClass(); + + /* If klass.getSuperClass is System class then force includeSuperClass to false. */ + + if (klass.getClassLoader() == null) + { + includeSuperClass = false; + } + + Method[] methods = includeSuperClass ? klass.getMethods() : klass.getDeclaredMethods(); + for (Method method : methods) + { + try + { + if (Modifier.isPublic(method.getModifiers())) + { + String name = method.getName(); + String key = ""; + if (name.startsWith("get")) + { + key = name.substring(3); + } + else if (name.startsWith("is")) + { + key = name.substring(2); + } + if (key.length() > 0 && Character.isUpperCase(key.charAt(0)) && method.getParameterTypes().length == 0) + { + if (key.length() == 1) + { + key = key.toLowerCase(); + } + else if (!Character.isUpperCase(key.charAt(1))) + { + key = key.substring(0, 1).toLowerCase() + key.substring(1); + } + + Object result = method.invoke(bean, (Object[])null); + if (result == null) + { + map.put(key, JSONObject.NULL); + } + else if (result.getClass().isArray()) + { + map.put(key, new JSONArray(result, includeSuperClass)); + } + else if (result instanceof Collection) + { // List or Set + map.put(key, new JSONArray((Collection)result, includeSuperClass)); + } + else if (result instanceof Map) + { + map.put(key, new JSONObject((Map)result, includeSuperClass)); + } + else if (JSONObject.isStandardProperty(result.getClass())) + { // Primitives, String and Wrapper + map.put(key, result); + } + else + { + if (result.getClass().getPackage().getName().startsWith("java") || result.getClass() + .getClassLoader() == null) + { + map.put(key, result.toString()); + } + else + { // User defined Objects + map.put(key, new JSONObject(result, includeSuperClass)); + } + } + } + } + } + catch (IllegalAccessException e) + { + throw new RuntimeException(e); + } + catch (JSONException e) + { + throw new RuntimeException(e); + } + catch (InvocationTargetException e) + { + throw new RuntimeException(e); + } + } + } + + static boolean isStandardProperty(final Class clazz) + { + return clazz.isPrimitive() || clazz.isAssignableFrom(Byte.class) || + clazz.isAssignableFrom(Short.class) || + clazz.isAssignableFrom(Integer.class) || + clazz.isAssignableFrom(Long.class) || + clazz.isAssignableFrom(Float.class) || + clazz.isAssignableFrom(Double.class) || + clazz.isAssignableFrom(Character.class) || + clazz.isAssignableFrom(String.class) || + clazz.isAssignableFrom(Boolean.class); + } + + /** + * Construct a JSONObject from an Object, using reflection to find the + * public members. The resulting JSONObject's keys will be the strings + * from the names array, and the values will be the field values associated + * with those keys in the object. If a key is not found or not visible, + * then it will not be copied into the new JSONObject. + * @param object An object that has fields that should be used to make a + * JSONObject. + * @param names An array of strings, the names of the fields to be obtained + * from the object. + */ + public JSONObject(final Object object, final String[] names) + { + this(); + Class c = object.getClass(); + for (String name : names) + { + try + { + putOpt(name, c.getField(name).get(object)); + } + catch (Exception e) + { + /* forget about it */ + } + } + } + + /** + * Construct a JSONObject from a source JSON text string. + * This is the most commonly used JSONObject constructor. + * @param source A string beginning + * with { (left brace) and ending + * with } (right brace). + * @exception JSONException If there is a syntax error in the source + * string or a duplicated key. + */ + public JSONObject(final String source) throws JSONException + { + this(new JSONTokener(source)); + } + + /** + * Accumulate values under a key. It is similar to the put method except + * that if there is already an object stored under the key then a + * JSONArray is stored under the key to hold all of the accumulated values. + * If there is already a JSONArray, then the new value is appended to it. + * In contrast, the put method replaces the previous value. + * @param key A key string. + * @param value An object to be accumulated under the key. + * @return this. + * @throws JSONException If the value is an invalid number + * or if the key is null. + */ + public JSONObject accumulate(final String key, final Object value) throws JSONException + { + JSONObject.testValidity(value); + Object o = opt(key); + if (o == null) + { + put(key, value instanceof JSONArray ? new JSONArray().put(value) : value); + } + else if (o instanceof JSONArray) + { + ((JSONArray)o).put(value); + } + else + { + put(key, new JSONArray().put(o).put(value)); + } + return this; + } + + /** + * Append values to the array under a key. If the key does not exist in the + * JSONObject, then the key is put in the JSONObject with its value being a + * JSONArray containing the value parameter. If the key was already + * associated with a JSONArray, then the value parameter is appended to it. + * @param key A key string. + * @param value An object to be accumulated under the key. + * @return this. + * @throws JSONException If the key is null or if the current value + * associated with the key is not a JSONArray. + */ + public JSONObject append(final String key, final Object value) throws JSONException + { + JSONObject.testValidity(value); + Object o = opt(key); + if (o == null) + { + put(key, new JSONArray().put(value)); + } + else if (o instanceof JSONArray) + { + put(key, ((JSONArray)o).put(value)); + } + else + { + throw new JSONException("JSONObject[" + key + "] is not a JSONArray."); + } + return this; + } + + /** + * Produce a string from a double. The string "null" will be returned if + * the number is not finite. + * @param d A double. + * @return A String. + */ + public static String doubleToString(final double d) + { + if (Double.isInfinite(d) || Double.isNaN(d)) + { + return "null"; + } + + // Shave off trailing zeros and decimal point, if possible. + + String s = Double.toString(d); + if (s.indexOf('.') > 0 && s.indexOf('e') < 0 && s.indexOf('E') < 0) + { + while (s.endsWith("0")) + { + s = s.substring(0, s.length() - 1); + } + if (s.endsWith(".")) + { + s = s.substring(0, s.length() - 1); + } + } + return s; + } + + /** + * Get the value object associated with a key. + * + * @param key A key string. + * @return The object associated with the key. + * @throws JSONException if the key is not found. + */ + public Object get(final String key) throws JSONException + { + Object o = opt(key); + if (o == null) + { + throw new JSONException("JSONObject[" + JSONObject.quote(key) + "] not found."); + } + return o; + } + + /** + * Get the boolean value associated with a key. + * + * @param key A key string. + * @return The truth. + * @throws JSONException + * if the value is not a Boolean or the String "true" or "false". + */ + public boolean getBoolean(final String key) throws JSONException + { + Object o = get(key); + if (o.equals(Boolean.FALSE) || o instanceof String && ((String)o).equalsIgnoreCase("false")) + { + return false; + } + else if (o.equals(Boolean.TRUE) || o instanceof String && ((String)o).equalsIgnoreCase("true")) + { + return true; + } + throw new JSONException("JSONObject[" + JSONObject.quote(key) + "] is not a Boolean."); + } + + /** + * Get the double value associated with a key. + * @param key A key string. + * @return The numeric value. + * @throws JSONException if the key is not found or + * if the value is not a Number object and cannot be converted to a number. + */ + public double getDouble(final String key) throws JSONException + { + Object o = get(key); + try + { + return o instanceof Number ? ((Number)o).doubleValue() : Double.valueOf((String)o).doubleValue(); + } + catch (Exception e) + { + throw new JSONException("JSONObject[" + JSONObject.quote(key) + "] is not a number."); + } + } + + /** + * Get the int value associated with a key. If the number value is too + * large for an int, it will be clipped. + * + * @param key A key string. + * @return The integer value. + * @throws JSONException if the key is not found or if the value cannot + * be converted to an integer. + */ + public int getInt(final String key) throws JSONException + { + Object o = get(key); + return o instanceof Number ? ((Number)o).intValue() : (int)getDouble(key); + } + + /** + * Get the JSONArray value associated with a key. + * + * @param key A key string. + * @return A JSONArray which is the value. + * @throws JSONException if the key is not found or + * if the value is not a JSONArray. + */ + public JSONArray getJSONArray(final String key) throws JSONException + { + Object o = get(key); + if (o instanceof JSONArray) + { + return (JSONArray)o; + } + throw new JSONException("JSONObject[" + JSONObject.quote(key) + "] is not a JSONArray."); + } + + /** + * Get the JSONObject value associated with a key. + * + * @param key A key string. + * @return A JSONObject which is the value. + * @throws JSONException if the key is not found or + * if the value is not a JSONObject. + */ + public JSONObject getJSONObject(final String key) throws JSONException + { + Object o = get(key); + if (o instanceof JSONObject) + { + return (JSONObject)o; + } + throw new JSONException("JSONObject[" + JSONObject.quote(key) + "] is not a JSONObject."); + } + + /** + * Get the long value associated with a key. If the number value is too + * long for a long, it will be clipped. + * + * @param key A key string. + * @return The long value. + * @throws JSONException if the key is not found or if the value cannot + * be converted to a long. + */ + public long getLong(final String key) throws JSONException + { + Object o = get(key); + return o instanceof Number ? ((Number)o).longValue() : (long)getDouble(key); + } + + /** + * Get an array of field names from a JSONObject. + * + * @return An array of field names, or null if there are no names. + */ + public static String[] getNames(final JSONObject jo) + { + int length = jo.length(); + if (length == 0) + { + return null; + } + Iterator i = jo.keys(); + String[] names = new String[length]; + int j = 0; + while (i.hasNext()) + { + names[j] = (String)i.next(); + j += 1; + } + return names; + } + + /** + * Get an array of field names from an Object. + * + * @return An array of field names, or null if there are no names. + */ + public static String[] getNames(final Object object) + { + if (object == null) + { + return null; + } + Class klass = object.getClass(); + Field[] fields = klass.getFields(); + int length = fields.length; + if (length == 0) + { + return null; + } + String[] names = new String[length]; + for (int i = 0; i < length; i += 1) + { + names[i] = fields[i].getName(); + } + return names; + } + + /** + * Get the string associated with a key. + * + * @param key A key string. + * @return A string which is the value. + * @throws JSONException if the key is not found. + */ + public String getString(final String key) throws JSONException + { + return get(key).toString(); + } + + /** + * Determine if the JSONObject contains a specific key. + * @param key A key string. + * @return true if the key exists in the JSONObject. + */ + public boolean has(final String key) + { + return map.containsKey(key); + } + + /** + * Determine if the value associated with the key is null or if there is + * no value. + * @param key A key string. + * @return true if there is no value associated with the key or if + * the value is the JSONObject.NULL object. + */ + public boolean isNull(final String key) + { + return JSONObject.NULL.equals(opt(key)); + } + + /** + * Get an enumeration of the keys of the JSONObject. + * + * @return An iterator of the keys. + */ + public Iterator keys() + { + return map.keySet().iterator(); + } + + /** + * Get the number of keys stored in the JSONObject. + * + * @return The number of keys in the JSONObject. + */ + public int length() + { + return map.size(); + } + + /** + * Produce a JSONArray containing the names of the elements of this + * JSONObject. + * @return A JSONArray containing the key strings, or null if the JSONObject + * is empty. + */ + public JSONArray names() + { + JSONArray ja = new JSONArray(); + Iterator keys = keys(); + while (keys.hasNext()) + { + ja.put(keys.next()); + } + return ja.length() == 0 ? null : ja; + } + + /** + * Produce a string from a Number. + * @param n A Number + * @return A String. + * @throws JSONException If n is a non-finite number. + */ + public static String numberToString(final Number n) throws JSONException + { + if (n == null) + { + throw new JSONException("Null pointer"); + } + JSONObject.testValidity(n); + + // Shave off trailing zeros and decimal point, if possible. + + String s = n.toString(); + if (s.indexOf('.') > 0 && s.indexOf('e') < 0 && s.indexOf('E') < 0) + { + while (s.endsWith("0")) + { + s = s.substring(0, s.length() - 1); + } + if (s.endsWith(".")) + { + s = s.substring(0, s.length() - 1); + } + } + return s; + } + + /** + * Get an optional value associated with a key. + * @param key A key string. + * @return An object which is the value, or null if there is no value. + */ + public Object opt(final String key) + { + return key == null ? null : map.get(key); + } + + /** + * Get an optional boolean associated with a key. + * It returns false if there is no such key, or if the value is not + * Boolean.TRUE or the String "true". + * + * @param key A key string. + * @return The truth. + */ + public boolean optBoolean(final String key) + { + return optBoolean(key, false); + } + + /** + * Get an optional boolean associated with a key. + * It returns the defaultValue if there is no such key, or if it is not + * a Boolean or the String "true" or "false" (case insensitive). + * + * @param key A key string. + * @param defaultValue The default. + * @return The truth. + */ + public boolean optBoolean(final String key, final boolean defaultValue) + { + try + { + return getBoolean(key); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * Put a key/value pair in the JSONObject, where the value will be a + * JSONArray which is produced from a Collection. + * @param key A key string. + * @param value A Collection value. + * @return this. + * @throws JSONException + */ + public JSONObject put(final String key, final Collection value) throws JSONException + { + put(key, new JSONArray(value)); + return this; + } + + /** + * Get an optional double associated with a key, + * or NaN if there is no such key or if its value is not a number. + * If the value is a string, an attempt will be made to evaluate it as + * a number. + * + * @param key A string which is the key. + * @return An object which is the value. + */ + public double optDouble(final String key) + { + return optDouble(key, Double.NaN); + } + + /** + * Get an optional double associated with a key, or the + * defaultValue if there is no such key or if its value is not a number. + * If the value is a string, an attempt will be made to evaluate it as + * a number. + * + * @param key A key string. + * @param defaultValue The default. + * @return An object which is the value. + */ + public double optDouble(final String key, final double defaultValue) + { + try + { + Object o = opt(key); + return o instanceof Number ? ((Number)o).doubleValue() : new Double((String)o).doubleValue(); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * Get an optional int value associated with a key, + * or zero if there is no such key or if the value is not a number. + * If the value is a string, an attempt will be made to evaluate it as + * a number. + * + * @param key A key string. + * @return An object which is the value. + */ + public int optInt(final String key) + { + return optInt(key, 0); + } + + /** + * Get an optional int value associated with a key, + * or the default if there is no such key or if the value is not a number. + * If the value is a string, an attempt will be made to evaluate it as + * a number. + * + * @param key A key string. + * @param defaultValue The default. + * @return An object which is the value. + */ + public int optInt(final String key, final int defaultValue) + { + try + { + return getInt(key); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * Get an optional JSONArray associated with a key. + * It returns null if there is no such key, or if its value is not a + * JSONArray. + * + * @param key A key string. + * @return A JSONArray which is the value. + */ + public JSONArray optJSONArray(final String key) + { + Object o = opt(key); + return o instanceof JSONArray ? (JSONArray)o : null; + } + + /** + * Get an optional JSONObject associated with a key. + * It returns null if there is no such key, or if its value is not a + * JSONObject. + * + * @param key A key string. + * @return A JSONObject which is the value. + */ + public JSONObject optJSONObject(final String key) + { + Object o = opt(key); + return o instanceof JSONObject ? (JSONObject)o : null; + } + + /** + * Get an optional long value associated with a key, + * or zero if there is no such key or if the value is not a number. + * If the value is a string, an attempt will be made to evaluate it as + * a number. + * + * @param key A key string. + * @return An object which is the value. + */ + public long optLong(final String key) + { + return optLong(key, 0); + } + + /** + * Get an optional long value associated with a key, + * or the default if there is no such key or if the value is not a number. + * If the value is a string, an attempt will be made to evaluate it as + * a number. + * + * @param key A key string. + * @param defaultValue The default. + * @return An object which is the value. + */ + public long optLong(final String key, final long defaultValue) + { + try + { + return getLong(key); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * Get an optional string associated with a key. + * It returns an empty string if there is no such key. If the value is not + * a string and is not null, then it is converted to a string. + * + * @param key A key string. + * @return A string which is the value. + */ + public String optString(final String key) + { + return optString(key, ""); + } + + /** + * Get an optional string associated with a key. + * It returns the defaultValue if there is no such key. + * + * @param key A key string. + * @param defaultValue The default. + * @return A string which is the value. + */ + public String optString(final String key, final String defaultValue) + { + Object o = opt(key); + return o != null ? o.toString() : defaultValue; + } + + /** + * Put a key/boolean pair in the JSONObject. + * + * @param key A key string. + * @param value A boolean which is the value. + * @return this. + * @throws JSONException If the key is null. + */ + public JSONObject put(final String key, final boolean value) throws JSONException + { + put(key, value ? Boolean.TRUE : Boolean.FALSE); + return this; + } + + /** + * Put a key/double pair in the JSONObject. + * + * @param key A key string. + * @param value A double which is the value. + * @return this. + * @throws JSONException If the key is null or if the number is invalid. + */ + public JSONObject put(final String key, final double value) throws JSONException + { + put(key, new Double(value)); + return this; + } + + /** + * Put a key/int pair in the JSONObject. + * + * @param key A key string. + * @param value An int which is the value. + * @return this. + * @throws JSONException If the key is null. + */ + public JSONObject put(final String key, final int value) throws JSONException + { + put(key, Integer.valueOf(value)); + return this; + } + + /** + * Put a key/long pair in the JSONObject. + * + * @param key A key string. + * @param value A long which is the value. + * @return this. + * @throws JSONException If the key is null. + */ + public JSONObject put(final String key, final long value) throws JSONException + { + put(key, Long.valueOf(value)); + return this; + } + + /** + * Put a key/value pair in the JSONObject, where the value will be a + * JSONObject which is produced from a Map. + * @param key A key string. + * @param value A Map value. + * @return this. + * @throws JSONException + */ + public JSONObject put(final String key, final Map value) throws JSONException + { + put(key, new JSONObject(value)); + return this; + } + + /** + * Put a key/value pair in the JSONObject. If the value is null, + * then the key will be removed from the JSONObject if it is present. + * @param key A key string. + * @param value An object which is the value. It should be of one of these + * types: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, + * or the JSONObject.NULL object. + * @return this. + * @throws JSONException If the value is non-finite number + * or if the key is null. + */ + public JSONObject put(final String key, final Object value) throws JSONException + { + if (key == null) + { + throw new JSONException("Null key."); + } + if (value != null) + { + JSONObject.testValidity(value); + map.put(key, value); + } + else + { + remove(key); + } + return this; + } + + /** + * Put a key/value pair in the JSONObject, but only if the key and the + * value are both non-null, and only if there is not already a member + * with that name. + * @param key + * @param value + * @return his. + * @throws JSONException if the key is a duplicate + */ + public JSONObject putOnce(final String key, final Object value) throws JSONException + { + if (key != null && value != null) + { + if (opt(key) != null) + { + throw new JSONException("Duplicate key \"" + key + "\""); + } + put(key, value); + } + return this; + } + + /** + * Put a key/value pair in the JSONObject, but only if the + * key and the value are both non-null. + * @param key A key string. + * @param value An object which is the value. It should be of one of these + * types: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, + * or the JSONObject.NULL object. + * @return this. + * @throws JSONException If the value is a non-finite number. + */ + public JSONObject putOpt(final String key, final Object value) throws JSONException + { + if (key != null && value != null) + { + put(key, value); + } + return this; + } + + /** + * Produce a string in double quotes with backslash sequences in all the + * right places. A backslash will be inserted within </, allowing JSON + * text to be delivered in HTML. In JSON text, a string cannot contain a + * control character or an unescaped quote or backslash. + * @param string A String + * @return A String correctly formatted for insertion in a JSON text. + */ + public static String quote(final String string) + { + if (string == null || string.length() == 0) + { + return "\"\""; + } + + char b; + char c = 0; + int i; + int len = string.length(); + StringBuffer sb = new StringBuffer(len + 4); + String t; + + sb.append('"'); + for (i = 0; i < len; i += 1) + { + b = c; + c = string.charAt(i); + switch (c) + { + case '\\': + case '"': + sb.append('\\'); + sb.append(c); + break; + case '/': + if (b == '<') + { + sb.append('\\'); + } + sb.append(c); + break; + case '\b': + sb.append("\\b"); + break; + case '\t': + sb.append("\\t"); + break; + case '\n': + sb.append("\\n"); + break; + case '\f': + sb.append("\\f"); + break; + case '\r': + sb.append("\\r"); + break; + default: + if (c < ' ' || c >= '\u0080' && c < '\u00a0' || c >= '\u2000' && c < '\u2100') + { + t = "000" + Integer.toHexString(c); + sb.append("\\u" + t.substring(t.length() - 4)); + } + else + { + sb.append(c); + } + } + } + sb.append('"'); + return sb.toString(); + } + + /** + * Remove a name and its value, if present. + * @param key The name to be removed. + * @return The value that was associated with the name, + * or null if there was no value. + */ + public Object remove(final String key) + { + return map.remove(key); + } + + /** + * Get an enumeration of the keys of the JSONObject. + * The keys will be sorted alphabetically. + * + * @return An iterator of the keys. + */ + public Iterator sortedKeys() + { + return new TreeSet(map.keySet()).iterator(); + } + + /** + * Try to convert a string into a number, boolean, or null. If the string + * can't be converted, return the string. + * @param s A String. + * @return A simple JSON value. + */ + public static Object stringToValue(final String s) + { + if (s.equals("")) + { + return s; + } + if (s.equalsIgnoreCase("true")) + { + return Boolean.TRUE; + } + if (s.equalsIgnoreCase("false")) + { + return Boolean.FALSE; + } + if (s.equalsIgnoreCase("null")) + { + return JSONObject.NULL; + } + + /* + * If it might be a number, try converting it. We support the 0- and 0x- + * conventions. If a number cannot be produced, then the value will just + * be a string. Note that the 0-, 0x-, plus, and implied string + * conventions are non-standard. A JSON parser is free to accept + * non-JSON forms as long as it accepts all correct JSON forms. + */ + + char b = s.charAt(0); + if (b >= '0' && b <= '9' || b == '.' || b == '-' || b == '+') + { + if (b == '0') + { + if (s.length() > 2 && (s.charAt(1) == 'x' || s.charAt(1) == 'X')) + { + try + { + return Integer.valueOf(Integer.parseInt(s.substring(2), 16)); + } + catch (Exception e) + { + /* Ignore the error */ + } + } + else + { + try + { + return Integer.valueOf(Integer.parseInt(s, 8)); + } + catch (Exception e) + { + /* Ignore the error */ + } + } + } + try + { + if (s.indexOf('.') > -1 || s.indexOf('e') > -1 || s.indexOf('E') > -1) + { + return Double.valueOf(s); + } + else + { + Long myLong = Long.valueOf(s); + if (myLong.longValue() == myLong.intValue()) + { + return Integer.valueOf(myLong.intValue()); + } + else + { + return myLong; + } + } + } + catch (Exception f) + { + /* Ignore the error */ + } + } + return s; + } + + /** + * Throw an exception if the object is an NaN or infinite number. + * @param o The object to test. + * @throws JSONException If o is a non-finite number. + */ + static void testValidity(final Object o) throws JSONException + { + if (o != null) + { + if (o instanceof Double) + { + if (((Double)o).isInfinite() || ((Double)o).isNaN()) + { + throw new JSONException("JSON does not allow non-finite numbers."); + } + } + else if (o instanceof Float) + { + if (((Float)o).isInfinite() || ((Float)o).isNaN()) + { + throw new JSONException("JSON does not allow non-finite numbers."); + } + } + } + } + + /** + * Produce a JSONArray containing the values of the members of this + * JSONObject. + * @param names A JSONArray containing a list of key strings. This + * determines the sequence of the values in the result. + * @return A JSONArray of values. + * @throws JSONException If any of the values are non-finite numbers. + */ + public JSONArray toJSONArray(final JSONArray names) throws JSONException + { + if (names == null || names.length() == 0) + { + return null; + } + JSONArray ja = new JSONArray(); + for (int i = 0; i < names.length(); i += 1) + { + ja.put(opt(names.getString(i))); + } + return ja; + } + + /** + * Make a JSON text of this JSONObject. For compactness, no whitespace + * is added. If this would not result in a syntactically correct JSON text, + * then null will be returned instead. + *

+ * Warning: This method assumes that the data structure is acyclical. + * + * @return a printable, displayable, portable, transmittable + * representation of the object, beginning + * with { (left brace) and ending + * with } (right brace). + */ + @Override + public String toString() + { + try + { + Iterator keys = keys(); + StringBuilder sb = new StringBuilder("{"); + + while (keys.hasNext()) + { + if (sb.length() > 1) + { + sb.append(','); + } + Object o = keys.next(); + sb.append(JSONObject.quote(o.toString())); + sb.append(':'); + sb.append(JSONObject.valueToString(map.get(o))); + } + sb.append('}'); + return sb.toString(); + } + catch (JSONException e) + { + return null; + } + } + + /** + * Make a prettyprinted JSON text of this JSONObject. + *

+ * Warning: This method assumes that the data structure is acyclical. + * @param indentFactor The number of spaces to add to each level of + * indentation. + * @return a printable, displayable, portable, transmittable + * representation of the object, beginning + * with { (left brace) and ending + * with } (right brace). + * @throws JSONException If the object contains an invalid number. + */ + public String toString(final int indentFactor) throws JSONException + { + return toString(indentFactor, 0); + } + + /** + * Make a prettyprinted JSON text of this JSONObject. + *

+ * Warning: This method assumes that the data structure is acyclical. + * @param indentFactor The number of spaces to add to each level of + * indentation. + * @param indent The indentation of the top level. + * @return a printable, displayable, transmittable + * representation of the object, beginning + * with { (left brace) and ending + * with } (right brace). + * @throws JSONException If the object contains an invalid number. + */ + String toString(final int indentFactor, final int indent) throws JSONException + { + int j; + int n = length(); + if (n == 0) + { + return "{}"; + } + Iterator keys = sortedKeys(); + StringBuffer sb = new StringBuffer("{"); + int newindent = indent + indentFactor; + Object o; + if (n == 1) + { + o = keys.next(); + sb.append(JSONObject.quote(o.toString())); + sb.append(": "); + sb.append(JSONObject.valueToString(map.get(o), indentFactor, indent)); + } + else + { + while (keys.hasNext()) + { + o = keys.next(); + if (sb.length() > 1) + { + sb.append(",\n"); + } + else + { + sb.append('\n'); + } + for (j = 0; j < newindent; j += 1) + { + sb.append(' '); + } + sb.append(JSONObject.quote(o.toString())); + sb.append(": "); + sb.append(JSONObject.valueToString(map.get(o), indentFactor, newindent)); + } + if (sb.length() > 1) + { + sb.append('\n'); + for (j = 0; j < indent; j += 1) + { + sb.append(' '); + } + } + } + sb.append('}'); + return sb.toString(); + } + + /** + * Make a JSON text of an Object value. If the object has an + * value.toJSONString() method, then that method will be used to produce + * the JSON text. The method is required to produce a strictly + * conforming text. If the object does not contain a toJSONString + * method (which is the most common case), then a text will be + * produced by other means. If the value is an array or Collection, + * then a JSONArray will be made from it and its toJSONString method + * will be called. If the value is a MAP, then a JSONObject will be made + * from it and its toJSONString method will be called. Otherwise, the + * value's toString method will be called, and the result will be quoted. + * + *

+ * Warning: This method assumes that the data structure is acyclical. + * @param value The value to be serialized. + * @return a printable, displayable, transmittable + * representation of the object, beginning + * with { (left brace) and ending + * with } (right brace). + * @throws JSONException If the value is or contains an invalid number. + */ + static String valueToString(final Object value) throws JSONException + { + if (value == null || JSONObject.NULL == value) + { + return "null"; + } + if (value instanceof JSONString) + { + String o; + try + { + o = ((JSONString)value).toJSONString(); + } + catch (RuntimeException e) + { + throw new JSONException(e); + } + if (o == null) + throw new JSONException("Bad value from toJSONString: " + o); + return o; + } + if (value instanceof Number) + { + return JSONObject.numberToString((Number)value); + } + if (value instanceof Boolean || value instanceof JSONObject || value instanceof JSONArray) + { + return value.toString(); + } + if (value instanceof Map) + { + return new JSONObject((Map)value).toString(); + } + if (value instanceof Collection) + { + return new JSONArray((Collection)value).toString(); + } + if (value.getClass().isArray()) + { + return new JSONArray(value).toString(); + } + return JSONObject.quote(value.toString()); + } + + /** + * Make a prettyprinted JSON text of an object value. + *

+ * Warning: This method assumes that the data structure is acyclical. + * @param value The value to be serialized. + * @param indentFactor The number of spaces to add to each level of + * indentation. + * @param indent The indentation of the top level. + * @return a printable, displayable, transmittable + * representation of the object, beginning + * with { (left brace) and ending + * with } (right brace). + * @throws JSONException If the object contains an invalid number. + */ + static String valueToString(final Object value, final int indentFactor, final int indent) throws JSONException + { + if (value == null || JSONObject.NULL == value) + { + return "null"; + } + try + { + if (value instanceof JSONString) + { + String o = ((JSONString)value).toJSONString(); + if (o != null) + return o; + } + } + catch (RuntimeException e) + { + /* forget about it */ + } + if (value instanceof Number) + { + return JSONObject.numberToString((Number)value); + } + if (value instanceof Boolean) + { + return value.toString(); + } + if (value instanceof JSONObject) + { + return ((JSONObject)value).toString(indentFactor, indent); + } + if (value instanceof JSONArray) + { + return ((JSONArray)value).toString(indentFactor, indent); + } + if (value instanceof Map) + { + return new JSONObject((Map)value).toString(indentFactor, indent); + } + if (value instanceof Collection) + { + return new JSONArray((Collection)value).toString(indentFactor, indent); + } + if (value.getClass().isArray()) + { + return new JSONArray(value).toString(indentFactor, indent); + } + return JSONObject.quote(value.toString()); + } + + /** + * Write the contents of the JSONObject as JSON text to a writer. + * For compactness, no whitespace is added. + *

+ * Warning: This method assumes that the data structure is acyclical. + * + * @return The writer. + * @throws JSONException + */ + public Writer write(final Writer writer) throws JSONException + { + try + { + boolean b = false; + Iterator keys = keys(); + writer.write('{'); + + while (keys.hasNext()) + { + if (b) + { + writer.write(','); + } + Object k = keys.next(); + writer.write(JSONObject.quote(k.toString())); + writer.write(':'); + Object v = map.get(k); + if (v instanceof JSONObject) + { + ((JSONObject)v).write(writer); + } + else if (v instanceof JSONArray) + { + ((JSONArray)v).write(writer); + } + else + { + writer.write(JSONObject.valueToString(v)); + } + b = true; + } + writer.write('}'); + return writer; + } + catch (IOException e) + { + throw new JSONException(e); + } + } +} http://git-wip-us.apache.org/repos/asf/activemq-6/blob/23e8edd9/activemq6-core-client/src/main/java/org/apache/activemq6/utils/json/JSONString.java ---------------------------------------------------------------------- diff --git a/activemq6-core-client/src/main/java/org/apache/activemq6/utils/json/JSONString.java b/activemq6-core-client/src/main/java/org/apache/activemq6/utils/json/JSONString.java new file mode 100644 index 0000000..7679041 --- /dev/null +++ b/activemq6-core-client/src/main/java/org/apache/activemq6/utils/json/JSONString.java @@ -0,0 +1,56 @@ +/* + * Copyright 2005-2014 Red Hat, Inc. + * Red Hat 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. + */ +/* +Copyright (c) 2002 JSON.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +package org.apache.activemq6.utils.json; + +/** + * The JSONString interface allows a toJSONString() + * method so that a class can change the behavior of + * JSONObject.toString(), JSONArray.toString(), + * and JSONWriter.value(Object). The + * toJSONString method will be used instead of the default behavior + * of using the Object's toString() method and quoting the result. + */ +public interface JSONString +{ + /** + * The toJSONString method allows a class to produce its own JSON + * serialization. + * + * @return A strictly syntactically correct JSON text. + */ + String toJSONString(); +} http://git-wip-us.apache.org/repos/asf/activemq-6/blob/23e8edd9/activemq6-core-client/src/main/java/org/apache/activemq6/utils/json/JSONTokener.java ---------------------------------------------------------------------- diff --git a/activemq6-core-client/src/main/java/org/apache/activemq6/utils/json/JSONTokener.java b/activemq6-core-client/src/main/java/org/apache/activemq6/utils/json/JSONTokener.java new file mode 100644 index 0000000..19cc407 --- /dev/null +++ b/activemq6-core-client/src/main/java/org/apache/activemq6/utils/json/JSONTokener.java @@ -0,0 +1,476 @@ +/* + * Copyright 2005-2014 Red Hat, Inc. + * Red Hat 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. + */ +/* +Copyright (c) 2002 JSON.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +package org.apache.activemq6.utils.json; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; + +/** + * A JSONTokener takes a source string and extracts characters and tokens from + * it. It is used by the JSONObject and JSONArray constructors to parse + * JSON source strings. + * @author JSON.org + * @version 2008-09-18 + */ +public class JSONTokener +{ + + private int index; + + private final Reader reader; + + private char lastChar; + + private boolean useLastChar; + + /** + * Construct a JSONTokener from a string. + * + * @param reader A reader. + */ + public JSONTokener(final Reader reader) + { + this.reader = reader.markSupported() ? reader : new BufferedReader(reader); + useLastChar = false; + index = 0; + } + + /** + * Construct a JSONTokener from a string. + * + * @param s A source string. + */ + public JSONTokener(final String s) + { + this(new StringReader(s)); + } + + /** + * Back up one character. This provides a sort of lookahead capability, + * so that you can test for a digit or letter before attempting to parse + * the next number or identifier. + */ + public void back() throws JSONException + { + if (useLastChar || index <= 0) + { + throw new JSONException("Stepping back two steps is not supported"); + } + index -= 1; + useLastChar = true; + } + + /** + * Get the hex value of a character (base16). + * @param c A character between '0' and '9' or between 'A' and 'F' or + * between 'a' and 'f'. + * @return An int between 0 and 15, or -1 if c was not a hex digit. + */ + public static int dehexchar(final char c) + { + if (c >= '0' && c <= '9') + { + return c - '0'; + } + if (c >= 'A' && c <= 'F') + { + return c - ('A' - 10); + } + if (c >= 'a' && c <= 'f') + { + return c - ('a' - 10); + } + return -1; + } + + /** + * Determine if the source string still contains characters that next() + * can consume. + * @return true if not yet at the end of the source. + */ + public boolean more() throws JSONException + { + char nextChar = next(); + if (nextChar == 0) + { + return false; + } + back(); + return true; + } + + /** + * Get the next character in the source string. + * + * @return The next character, or 0 if past the end of the source string. + */ + public char next() throws JSONException + { + if (useLastChar) + { + useLastChar = false; + if (lastChar != 0) + { + index += 1; + } + return lastChar; + } + int c; + try + { + c = reader.read(); + } + catch (IOException exc) + { + throw new JSONException(exc); + } + + if (c <= 0) + { // End of stream + lastChar = 0; + return 0; + } + index += 1; + lastChar = (char)c; + return lastChar; + } + + /** + * Consume the next character, and check that it matches a specified + * character. + * @param c The character to match. + * @return The character. + * @throws JSONException if the character does not match. + */ + public char next(final char c) throws JSONException + { + char n = next(); + if (n != c) + { + throw syntaxError("Expected '" + c + "' and instead saw '" + n + "'"); + } + return n; + } + + /** + * Get the next n characters. + * + * @param n The number of characters to take. + * @return A string of n characters. + * @throws JSONException + * Substring bounds error if there are not + * n characters remaining in the source string. + */ + public String next(final int n) throws JSONException + { + if (n == 0) + { + return ""; + } + + char[] buffer = new char[n]; + int pos = 0; + + if (useLastChar) + { + useLastChar = false; + buffer[0] = lastChar; + pos = 1; + } + + try + { + int len; + while (pos < n && (len = reader.read(buffer, pos, n - pos)) != -1) + { + pos += len; + } + } + catch (IOException exc) + { + throw new JSONException(exc); + } + index += pos; + + if (pos < n) + { + throw syntaxError("Substring bounds error"); + } + + lastChar = buffer[n - 1]; + return new String(buffer); + } + + /** + * Get the next char in the string, skipping whitespace. + * @throws JSONException + * @return A character, or 0 if there are no more characters. + */ + public char nextClean() throws JSONException + { + for (;;) + { + char c = next(); + if (c == 0 || c > ' ') + { + return c; + } + } + } + + /** + * Return the characters up to the next close quote character. + * Backslash processing is done. The formal JSON format does not + * allow strings in single quotes, but an implementation is allowed to + * accept them. + * @param quote The quoting character, either + * " (double quote) or + * ' (single quote). + * @return A String. + * @throws JSONException Unterminated string. + */ + public String nextString(final char quote) throws JSONException + { + char c; + StringBuffer sb = new StringBuffer(); + for (;;) + { + c = next(); + switch (c) + { + case 0: + case '\n': + case '\r': + throw syntaxError("Unterminated string"); + case '\\': + c = next(); + switch (c) + { + case 'b': + sb.append('\b'); + break; + case 't': + sb.append('\t'); + break; + case 'n': + sb.append('\n'); + break; + case 'f': + sb.append('\f'); + break; + case 'r': + sb.append('\r'); + break; + case 'u': + sb.append((char)Integer.parseInt(next(4), 16)); + break; + case 'x': + sb.append((char)Integer.parseInt(next(2), 16)); + break; + default: + sb.append(c); + } + break; + default: + if (c == quote) + { + return sb.toString(); + } + sb.append(c); + } + } + } + + /** + * Get the text up but not including the specified character or the + * end of line, whichever comes first. + * @param d A delimiter character. + * @return A string. + */ + public String nextTo(final char d) throws JSONException + { + StringBuffer sb = new StringBuffer(); + for (;;) + { + char c = next(); + if (c == d || c == 0 || c == '\n' || c == '\r') + { + if (c != 0) + { + back(); + } + return sb.toString().trim(); + } + sb.append(c); + } + } + + /** + * Get the text up but not including one of the specified delimiter + * characters or the end of line, whichever comes first. + * @param delimiters A set of delimiter characters. + * @return A string, trimmed. + */ + public String nextTo(final String delimiters) throws JSONException + { + char c; + StringBuffer sb = new StringBuffer(); + for (;;) + { + c = next(); + if (delimiters.indexOf(c) >= 0 || c == 0 || c == '\n' || c == '\r') + { + if (c != 0) + { + back(); + } + return sb.toString().trim(); + } + sb.append(c); + } + } + + /** + * Get the next value. The value can be a Boolean, Double, Integer, + * JSONArray, JSONObject, Long, or String, or the JSONObject.NULL object. + * @throws JSONException If syntax error. + * + * @return An object. + */ + public Object nextValue() throws JSONException + { + char c = nextClean(); + String s; + + switch (c) + { + case '"': + case '\'': + return nextString(c); + case '{': + back(); + return new JSONObject(this); + case '[': + case '(': + back(); + return new JSONArray(this); + } + + /* + * Handle unquoted text. This could be the values true, false, or + * null, or it can be a number. An implementation (such as this one) + * is allowed to also accept non-standard forms. + * + * Accumulate characters until we reach the end of the text or a + * formatting character. + */ + + StringBuffer sb = new StringBuffer(); + while (c >= ' ' && ",:]}/\\\"[{;=#".indexOf(c) < 0) + { + sb.append(c); + c = next(); + } + back(); + + s = sb.toString().trim(); + if (s.equals("")) + { + throw syntaxError("Missing value"); + } + return JSONObject.stringToValue(s); + } + + /** + * Skip characters until the next character is the requested character. + * If the requested character is not found, no characters are skipped. + * @param to A character to skip to. + * @return The requested character, or zero if the requested character + * is not found. + */ + public char skipTo(final char to) throws JSONException + { + char c; + try + { + int startIndex = index; + reader.mark(Integer.MAX_VALUE); + do + { + c = next(); + if (c == 0) + { + reader.reset(); + index = startIndex; + return c; + } + } + while (c != to); + } + catch (IOException exc) + { + throw new JSONException(exc); + } + + back(); + return c; + } + + /** + * Make a JSONException to signal a syntax error. + * + * @param message The error message. + * @return A JSONException object, suitable for throwing + */ + public JSONException syntaxError(final String message) + { + return new JSONException(message + toString()); + } + + /** + * Make a printable string of this JSONTokener. + * + * @return " at character [this.index]" + */ + @Override + public String toString() + { + return " at character " + index; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/activemq-6/blob/23e8edd9/activemq6-core-client/src/main/java/org/apache/activemq6/utils/package-info.java ---------------------------------------------------------------------- diff --git a/activemq6-core-client/src/main/java/org/apache/activemq6/utils/package-info.java b/activemq6-core-client/src/main/java/org/apache/activemq6/utils/package-info.java new file mode 100644 index 0000000..c532481 --- /dev/null +++ b/activemq6-core-client/src/main/java/org/apache/activemq6/utils/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2005-2014 Red Hat, Inc. + * Red Hat 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. + */ +/** + * Utilities and helper classes. + *
+ * This package defines the utilities class used by HornetQ. + */ +package org.apache.activemq6.utils; + http://git-wip-us.apache.org/repos/asf/activemq-6/blob/23e8edd9/activemq6-core-client/src/main/resources/HornetQDefaultConfiguration.txt ---------------------------------------------------------------------- diff --git a/activemq6-core-client/src/main/resources/HornetQDefaultConfiguration.txt b/activemq6-core-client/src/main/resources/HornetQDefaultConfiguration.txt new file mode 100644 index 0000000..23d4b71 --- /dev/null +++ b/activemq6-core-client/src/main/resources/HornetQDefaultConfiguration.txt @@ -0,0 +1,116 @@ +package org.apache.activemq6.api.config; + +import org.apache.activemq6.api.core.SimpleString; +import org.apache.activemq6.core.journal.impl.JournalConstants; + +/** + * Default values of HornetQ configuration parameters. + */ +public final class HornetQDefaultConfiguration +{ + /* + *

In order to avoid compile time in-lining of constants, all access is done through methods + * and all fields are PRIVATE STATIC but not FINAL. This is done following the recommendation at + * 13.4.9. + * final Fields and Constants + * @see http://docs.oracle.com/javase/specs/jls/se7/html/jls-13.html#jls-13.4.9 + */ + + private HornetQDefaultConfiguration() + { + // Utility class + } + + public static long getDefaultClientFailureCheckPeriod() + { + return DEFAULT_CLIENT_FAILURE_CHECK_PERIOD; + } + + public static long getDefaultFileDeployerScanPeriod() + { + return DEFAULT_FILE_DEPLOYER_SCAN_PERIOD; + } + + public static int getDefaultJournalMaxIoAio() + { + return DEFAULT_JOURNAL_MAX_IO_AIO; + } + + public static int getDefaultJournalBufferTimeoutAio() + { + return DEFAULT_JOURNAL_BUFFER_TIMEOUT_AIO; + } + + public static int getDefaultJournalBufferSizeAio() + { + return DEFAULT_JOURNAL_BUFFER_SIZE_AIO; + } + + public static int getDefaultJournalMaxIoNio() + { + return DEFAULT_JOURNAL_MAX_IO_NIO; + } + + public static int getDefaultJournalBufferTimeoutNio() + { + return DEFAULT_JOURNAL_BUFFER_TIMEOUT_NIO; + } + + public static int getDefaultJournalBufferSizeNio() + { + return DEFAULT_JOURNAL_BUFFER_SIZE_NIO; + } + + public static String getPropMaskPassword() + { + return PROP_MASK_PASSWORD; + } + + public static String getPropPasswordCodec() + { + return PROP_PASSWORD_CODEC; + } + + /** + * what kind of HA Policy should we use + */ + public static String getDefaultHapolicyType() + { + return DEFAULT_HAPOLICY_TYPE; + } + + /** + * The backup strategy to use if we are a backup or for any colocated backups. + */ + public static String getDefaultHapolicyBackupStrategy() + { + return DEFAULT_HAPOLICY_BACKUP_STRATEGY; + } + + //shared by client and core/server + // XXX not on schema? + private static long DEFAULT_CLIENT_FAILURE_CHECK_PERIOD = 30000; + + // XXX not on schema? + private static long DEFAULT_FILE_DEPLOYER_SCAN_PERIOD = 5000; + + // These defaults are applied depending on whether the journal type + // is NIO or AIO. + private static int DEFAULT_JOURNAL_MAX_IO_AIO = 500; + private static int DEFAULT_JOURNAL_BUFFER_TIMEOUT_AIO = JournalConstants.DEFAULT_JOURNAL_BUFFER_TIMEOUT_AIO; + private static int DEFAULT_JOURNAL_BUFFER_SIZE_AIO = JournalConstants.DEFAULT_JOURNAL_BUFFER_SIZE_AIO; + private static int DEFAULT_JOURNAL_MAX_IO_NIO = 1; + private static int DEFAULT_JOURNAL_BUFFER_TIMEOUT_NIO = JournalConstants.DEFAULT_JOURNAL_BUFFER_TIMEOUT_NIO; + private static int DEFAULT_JOURNAL_BUFFER_SIZE_NIO = JournalConstants.DEFAULT_JOURNAL_BUFFER_SIZE_NIO; + + // XXX not on schema. + //properties passed to acceptor/connectors. + private static String PROP_MASK_PASSWORD = "hornetq.usemaskedpassword"; + private static String PROP_PASSWORD_CODEC = "hornetq.passwordcodec"; + + + // what kind of HA Policy should we use + private static String DEFAULT_HAPOLICY_TYPE = "NONE"; + + // The backup strategy to use if we are a backup or for any colocated backups. + private static String DEFAULT_HAPOLICY_BACKUP_STRATEGY = "FULL"; http://git-wip-us.apache.org/repos/asf/activemq-6/blob/23e8edd9/activemq6-core-client/src/main/resources/hornetq-version.properties ---------------------------------------------------------------------- diff --git a/activemq6-core-client/src/main/resources/hornetq-version.properties b/activemq6-core-client/src/main/resources/hornetq-version.properties new file mode 100644 index 0000000..53cf7c7 --- /dev/null +++ b/activemq6-core-client/src/main/resources/hornetq-version.properties @@ -0,0 +1,9 @@ +hornetq.version.versionName=${hornetq.version.versionName} +hornetq.version.majorVersion=${hornetq.version.majorVersion} +hornetq.version.minorVersion=${hornetq.version.minorVersion} +hornetq.version.microVersion=${hornetq.version.microVersion} +hornetq.version.incrementingVersion=${hornetq.version.incrementingVersion} +hornetq.version.versionSuffix=${hornetq.version.versionSuffix} +hornetq.version.versionTag=${hornetq.version.versionTag} +hornetq.netty.version=${netty.version.string} +hornetq.version.compatibleVersionList=121,122,123,124,125 http://git-wip-us.apache.org/repos/asf/activemq-6/blob/23e8edd9/activemq6-core-client/src/main/resources/hqDefaults.xsl ---------------------------------------------------------------------- diff --git a/activemq6-core-client/src/main/resources/hqDefaults.xsl b/activemq6-core-client/src/main/resources/hqDefaults.xsl new file mode 100644 index 0000000..fe09670 --- /dev/null +++ b/activemq6-core-client/src/main/resources/hqDefaults.xsl @@ -0,0 +1,128 @@ + + + + + + + + + + /* + * THIS IS A GENERATED FILE! DO NOT EDIT IT DIRECTLY! + + To see how this file is generated, please refer to + hornetq-core-client/src/main/resources/hqDefaults.xsl + + To add new entries either document them in the hornetq-configuration.xsd by adding: + + 1. a default value to the schema element (using the standard way of adding a default) + 2. adding a hq:field_name attribute to a xsd:annotation element of the element in question. + + It is probably easier to just go to the hornetq-configuration.xsd and see how this is done for + other values, and then copy it. + + The advantage of adding the default to the schema is that: + + a. the schema will inform users of it (for users that check such things through the schema, + think of XML editors as users...); + + b. the manual gets an entry for it automatically; + + c. the Java code gets the same value; + + d. all 3 sources of defaults will match since they take the value from the same place + (i.e. the schema). + + */ + +/* + XSLT Version = + XSLT Vendor = + XSLT Vendor URL = +*/ + + + // ------------------------------------------------------------------- + // Following fields are generated from the hornetq-schema.xsd annotations + // ------------------------------------------------------------------- + + + // + private static = ; + + + + + + + /** * + + */ + public static + +() + { return + + ; + } + + +} + + + + + + is + + get + + + + + + + + + + + + + + + + + + + + + + + + + String + + + + + + + + + + http://git-wip-us.apache.org/repos/asf/activemq-6/blob/23e8edd9/activemq6-core-client/src/test/java/org/apache/activemq6/tests/CoreUnitTestCase.java ---------------------------------------------------------------------- diff --git a/activemq6-core-client/src/test/java/org/apache/activemq6/tests/CoreUnitTestCase.java b/activemq6-core-client/src/test/java/org/apache/activemq6/tests/CoreUnitTestCase.java new file mode 100644 index 0000000..bee8784 --- /dev/null +++ b/activemq6-core-client/src/test/java/org/apache/activemq6/tests/CoreUnitTestCase.java @@ -0,0 +1,85 @@ +/* + * Copyright 2005-2014 Red Hat, Inc. + * Red Hat 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.activemq6.tests; + + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import org.apache.activemq6.core.client.HornetQClientLogger; +import org.junit.Assert; +import org.junit.Rule; +import org.junit.rules.TestRule; +import org.junit.rules.TestWatcher; +import org.junit.runner.Description; + +public abstract class CoreUnitTestCase extends Assert +{ + public static void assertEqualsByteArrays(final byte[] expected, final byte[] actual) + { + for (int i = 0; i < expected.length; i++) + { + Assert.assertEquals("byte at index " + i, expected[i], actual[i]); + } + } + + private static final HornetQClientLogger log = HornetQClientLogger.LOGGER; + + @Rule + public TestRule watcher = new TestWatcher() + { + @Override + protected void starting(Description description) + { + log.info(String.format("#*#*# Starting test: %s()...", description.getMethodName())); + } + + @Override + protected void finished(Description description) + { + log.info(String.format("#*#*# Finished test: %s()...", description.getMethodName())); + } + }; + + /** + * Asserts that latch completes within a (rather large interval). + *

+ * Use this instead of just calling {@code latch.await()}. Otherwise your test may hang the whole + * test run if it fails to count-down the latch. + * + * @param latch + * @throws InterruptedException + */ + public static void waitForLatch(CountDownLatch latch) throws InterruptedException + { + assertTrue("Latch has got to return within a minute", latch.await(1, TimeUnit.MINUTES)); + } + + public static int countOccurrencesOf(String str, String sub) + { + if (str == null || sub == null || str.length() == 0 || sub.length() == 0) + { + return 0; + } + int count = 0; + int pos = 0; + int idx; + while ((idx = str.indexOf(sub, pos)) != -1) + { + ++count; + pos = idx + sub.length(); + } + return count; + } + +}