All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.tinkerpop.rexster.util.ElementHelper Maven / Gradle / Ivy

There is a newer version: 2.6.0
Show newest version
package com.tinkerpop.rexster.util;

import com.tinkerpop.blueprints.util.io.graphson.GraphSONTokens;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * Converts a property value from the query string into a typed value using standard Rexster Data Typing.
 *
 * @author Stephen Mallette (http://stephen.genoprime.com)
 */
public class ElementHelper {

    /**
     * Takes a property value string from the URI and attempts to parse it
     * to its defined data type using Rexster Data Typing.
     */
    public static Object getTypedPropertyValue(final Object propertyValue) {
        return getTypedPropertyValue(propertyValue, true);
    }

    /**
     * Takes a property value string from the URI and attempts to parse it
     * to its defined data type.  Also accepts a JSONObject or JSONArray.
     * 

* The format of the property value must be enclosed with parens with * two values within it separated by a comma. The first value is the data * type which may be one of the following: *

* i or integer * f or float * l or long * d or double * s or string * b or boolean * map * list * null *

* In the event that the type is not set or the parens cannot be tracked * as open and closed the parser will determine the value to simply be a string. *

* The value of a list must be defined with enclosing square brackets with values * separated by commas. Values are defined with the same rules involving parens * defined above. *

* The value of a map must be defined with enclosing parens where comma * separated segments of new key-value pairs represent the properties of the * map itself. *

* Values may be nested to any depth. * * @param propertyValue The value from a key-value pair. At a top level, this will * come from the URI as a one of the query parameters. * @param parseTypes Set to true to check strings for data type formatting. * @return The property value coerced to the appropriate Java data type. */ public static Object getTypedPropertyValue(final Object propertyValue, final boolean parseTypes) { Object typedPropertyValue = propertyValue; if (typedPropertyValue == null) { typedPropertyValue = null; } // determine if the property is typed, otherwise assume it is a string if (propertyValue != null) { if (propertyValue instanceof String) { String stringPropertyValue = propertyValue.toString(); if (parseTypes && stringPropertyValue.startsWith("(") && stringPropertyValue.endsWith(")")) { String dataType = getDataTypeSegment(stringPropertyValue); String theValue = getValueSegment(stringPropertyValue); if (dataType.equals(GraphSONTokens.TYPE_STRING)) { typedPropertyValue = theValue; } else if (dataType.equals(GraphSONTokens.TYPE_INTEGER)) { typedPropertyValue = tryParseInteger(theValue); } else if (dataType.equals(GraphSONTokens.TYPE_BOOLEAN)) { typedPropertyValue = tryParseBoolean(theValue); } else if (dataType.equals(GraphSONTokens.TYPE_LONG)) { typedPropertyValue = tryParseLong(theValue); } else if (dataType.equals(GraphSONTokens.TYPE_DOUBLE)) { typedPropertyValue = tryParseDouble(theValue); } else if (dataType.equals(GraphSONTokens.TYPE_FLOAT)) { typedPropertyValue = tryParseFloat(theValue); } else if (dataType.equals(GraphSONTokens.TYPE_LIST)) { ArrayList items = tryParseList(theValue); ArrayList typedItems = new ArrayList(); for (String item : items) { typedItems.add(getTypedPropertyValue(item)); } typedPropertyValue = typedItems; } else if (dataType.equals(GraphSONTokens.TYPE_MAP)) { HashMap stringProperties = tryParseMap(theValue); HashMap properties = new HashMap(); for (Map.Entry entry : stringProperties.entrySet()) { properties.put(entry.getKey(), getTypedPropertyValue(entry.getValue())); } typedPropertyValue = properties; } else if (dataType.equals("null")) { typedPropertyValue = null; } } } else if (propertyValue == JSONObject.NULL) { typedPropertyValue = null; } else if (propertyValue instanceof JSONObject) { JSONObject innerJson = (JSONObject) propertyValue; HashMap properties = new HashMap(); Iterator itty = innerJson.keys(); while (itty.hasNext()) { String key = (String) itty.next(); properties.put(key, getTypedPropertyValue(innerJson.opt(key), parseTypes)); } typedPropertyValue = properties; } else if (propertyValue instanceof JSONArray) { JSONArray innerJson = (JSONArray) propertyValue; ArrayList typedItems = new ArrayList(); for (int ix = 0; ix < innerJson.length(); ix++) { typedItems.add(getTypedPropertyValue(innerJson.opt(ix), parseTypes)); } typedPropertyValue = typedItems; } } return typedPropertyValue; } private static HashMap tryParseMap(final String mapValue) { // parens on the ends have been validated already...they must be // here to have gotten this far. String stripped = mapValue.substring(1, mapValue.length() - 1); HashMap pairs = new HashMap(); ArrayList delimiterPlaces = new ArrayList(); int parensOpened = 0; for (int ix = 0; ix < stripped.length(); ix++) { char c = stripped.charAt(ix); if (c == ',') { if (parensOpened == 0) { delimiterPlaces.add(ix); } } else if (c == '(') { parensOpened++; } else if (c == ')') { parensOpened--; } } int lastPlace = 0; int equalPlace = 0; for (Integer place : delimiterPlaces) { final String property = stripped.substring(lastPlace, place); equalPlace = property.indexOf("="); pairs.put(property.substring(0, equalPlace), property.substring(equalPlace + 1)); lastPlace = place + 1; } String property = stripped.substring(lastPlace); equalPlace = property.indexOf("="); pairs.put(property.substring(0, equalPlace), property.substring(equalPlace + 1)); return pairs; } private static ArrayList tryParseList(final String listValue) { // square brackets on the ends have been validated already...they must be // here to have gotten this far. String stripped = listValue.substring(1, listValue.length() - 1); ArrayList items = new ArrayList(); int place = stripped.indexOf(','); if (place > -1) { boolean isEndItem = false; int parensOpened = 0; StringBuffer sb = new StringBuffer(); for (int ix = 0; ix < stripped.length(); ix++) { char c = stripped.charAt(ix); if (c == ',') { // a delimiter was found, determine if it is a true // delimiter or if it is part of a value or a separator // with a paren set if (parensOpened == 0) { isEndItem = true; } } else if (c == '(') { parensOpened++; } else if (c == ')') { parensOpened--; } if (ix == stripped.length() - 1) { // this is the last character in the value...by default // this is an end item event isEndItem = true; // append the character because it is valid in the value and // not a delimiter that would normally be added. sb.append(c); } if (isEndItem) { items.add(sb.toString()); sb = new StringBuffer(); isEndItem = false; } else { sb.append(c); } } } else { // there is one item in the array or the array is empty items.add(stripped); } return items; } private static String getValueSegment(final String propertyValue) { // assumes that the propertyValue has open and closed parens String value = ""; String stripped = propertyValue.substring(1, propertyValue.length() - 1); int place = stripped.indexOf(','); // assume that the first char could be the comma, which // would default to a string data type. if (place > -1) { if (place + 1 < stripped.length()) { // stripped doesn't have the trailing paren so take // the value from the first character after the comma to the end value = stripped.substring(place + 1); } else { // there is nothing after the comma value = ""; } } else { // there was no comma, so the whole thing is the value and it // is assumed to be a string value = stripped; } return value; } private static String getDataTypeSegment(final String propertyValue) { // assumes that the propertyValue has open and closed parens String dataType = GraphSONTokens.TYPE_STRING; // strip the initial parens and read up to the command. // no need to check for string as that is the default int place = propertyValue.indexOf(','); String inner = propertyValue.substring(1, place).trim(); if (inner.equals("s") || inner.equals(GraphSONTokens.TYPE_STRING)) { dataType = GraphSONTokens.TYPE_STRING; } else if (inner.equals("b") || inner.equals(GraphSONTokens.TYPE_BOOLEAN)) { dataType = GraphSONTokens.TYPE_BOOLEAN; } else if (inner.equals("i") || inner.equals(GraphSONTokens.TYPE_INTEGER)) { dataType = GraphSONTokens.TYPE_INTEGER; } else if (inner.equals("d") || inner.equals(GraphSONTokens.TYPE_DOUBLE)) { dataType = GraphSONTokens.TYPE_DOUBLE; } else if (inner.equals("f") || inner.equals(GraphSONTokens.TYPE_FLOAT)) { dataType = GraphSONTokens.TYPE_FLOAT; } else if (inner.equals(GraphSONTokens.TYPE_LIST)) { dataType = GraphSONTokens.TYPE_LIST; } else if (inner.equals("l") || inner.equals(GraphSONTokens.TYPE_LONG)) { dataType = GraphSONTokens.TYPE_LONG; } else if (inner.equals(GraphSONTokens.TYPE_MAP)) { dataType = GraphSONTokens.TYPE_MAP; } else if (inner.equals("null")) { dataType = "null"; } return dataType; } private static Object tryParseInteger(final String intValue) { Object parsedValue; try { parsedValue = Integer.parseInt(intValue); } catch (NumberFormatException nfe) { parsedValue = intValue; } return parsedValue; } private static Object tryParseFloat(final String floatValue) { Object parsedValue; try { parsedValue = Float.parseFloat(floatValue); } catch (NumberFormatException nfe) { parsedValue = floatValue; } return parsedValue; } private static Object tryParseBoolean(final String booleanValue) { Object parsedValue; try { parsedValue = Boolean.parseBoolean(booleanValue); } catch (NumberFormatException nfe) { parsedValue = booleanValue; } return parsedValue; } private static Object tryParseLong(final String longValue) { Object parsedValue; try { parsedValue = Long.parseLong(longValue); } catch (NumberFormatException nfe) { parsedValue = longValue; } return parsedValue; } private static Object tryParseDouble(final String doubleValue) { Object parsedValue; try { parsedValue = Double.parseDouble(doubleValue); } catch (NumberFormatException nfe) { parsedValue = doubleValue; } return parsedValue; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy