com.rathravane.till.data.json.JsonEval Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of silt Show documentation
Show all versions of silt Show documentation
A small collection of classes used in various Rathravane systems.
package com.rathravane.till.data.json;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONObject;
import com.rathravane.till.data.rrConvertor;
import com.rathravane.till.data.exprEval.ExprDataSource;
import com.rathravane.till.data.exprEval.ExpressionEvaluator;
public class JsonEval
{
/**
* Evaluate an expression against a JSON structure. If the expression refers to a non-existent
* node, null is returned.
*
* @param root
* @param expression
* @return a JSON element or a primitive
*/
public static Object eval ( JSONObject root, String expression )
{
final String[] parts = expression.split ( "\\." );
if ( parts.length == 1 )
{
return evalToValue ( root, parts[0] );
}
else
{
final JSONObject o = evalToContainer ( root, parts[0] );
if ( o != null )
{
return eval ( o, expression.substring ( expression.indexOf ( '.' ) + 1 ) );
}
}
return null;
}
/**
* Evaluate the given expression against the given root JSON object and return
* a string representation. If the evaluation is null, an empty string is returned.
* @param root
* @param expression
* @return a string
*/
public static String evalToString ( JSONObject root, String expression )
{
final Object result = eval ( root, expression );
if ( result == null ) return "";
return result.toString ();
}
/**
* Evaluate the given expression against the given root JSON object and return
* a boolean representation. If the evaluation is null, false is returned. If
* the evaluation results in a JSON boolean, the value is returned. Anything else
* is converted to a string (via toString) and converted to a boolean via
* rrConvertor.convertToBooleanBroad
* @param root
* @param expression
* @return true or false
*/
public static boolean evalToBoolean ( JSONObject root, String expression )
{
final Object result = eval ( root, expression );
if ( result == null ) return false;
if ( result instanceof Boolean )
{
return (Boolean) result;
}
return rrConvertor.convertToBooleanBroad ( result.toString () );
}
/**
* substitute any occurrence of ${<expr>} with the evaluation of that expression
* @param sourceString
* @param root
* @return a string
*/
public static String substitute ( String sourceString, JSONObject root )
{
return ExpressionEvaluator.evaluate ( sourceString, new JsonDataSource ( root ) );
}
public static void setValue ( JSONObject root, String key, Object data )
{
final String[] parts = key.split ( "\\." );
final List partList = new LinkedList ( Arrays.asList ( parts ) );
final String lastPart = partList.remove ( partList.size () - 1 );
final JSONObject container = getContainer ( root, partList, true );
container.put ( lastPart, data );
}
public static boolean hasKey ( JSONObject root, String key )
{
try
{
final String[] parts = key.split ( "\\." );
final List partList = new LinkedList ( Arrays.asList ( parts ) );
final String lastPart = partList.remove ( partList.size () - 1 );
final JSONObject container = getContainer ( root, partList, false );
return container != null && container.has ( lastPart );
}
catch ( IllegalArgumentException e )
{
return false;
}
}
public static JSONObject getContainer ( JSONObject root, String key )
{
final String[] parts = key.split ( "\\." );
final List partList = new LinkedList ( Arrays.asList ( parts ) );
return getContainer ( root, partList, false );
}
private static JSONObject getContainer ( JSONObject root, List parts, boolean withCreate )
{
JSONObject current = root;
for ( String thisPart : parts )
{
final Object nextContainer = current.opt ( thisPart );
if ( nextContainer == null )
{
if ( withCreate )
{
// no such thing. create it as an object.
final JSONObject newObj = new JSONObject ();
current.put ( thisPart, newObj );
current = newObj;
}
else
{
return null;
}
}
else if ( nextContainer instanceof JSONObject )
{
// normal case
current = (JSONObject) nextContainer;
}
else
{
// not a container we can support
throw new IllegalArgumentException ( "Intermediate part " + thisPart + " is not an object." );
}
}
return current;
}
private static class JsonDataSource implements ExprDataSource
{
public JsonDataSource ( JSONObject root )
{
fRoot = root;
}
@Override
public Object eval ( String label )
{
return JsonEval.eval ( fRoot, label );
}
private final JSONObject fRoot;
}
private static Object termToArrayValue ( JSONObject root, String term )
{
final int openBrace = term.indexOf ( '[' );
if ( openBrace > -1 && term.endsWith ( "]" )) // note: foo[0[1]] would pass
{
final String key = term.substring ( 0, openBrace );
final JSONArray a = root.optJSONArray ( key );
if ( a != null )
{
try
{
final String indexStr = term.substring ( openBrace+1, term.length () - 1 );
final int index = Integer.parseInt ( indexStr );
return a.opt ( index );
}
catch ( NumberFormatException x )
{
return null;
}
}
}
return null;
}
private static Object evalToValue ( JSONObject root, String term )
{
final int openBrace = term.indexOf ( '[' );
if ( openBrace > -1 && term.endsWith ( "]" )) // note: foo[0[1]] would pass
{
return termToArrayValue ( root, term );
}
else
{
return root.opt ( term );
}
}
private static JSONObject evalToContainer ( JSONObject root, String term )
{
final int openBrace = term.indexOf ( '[' );
if ( openBrace > -1 && term.endsWith ( "]" )) // note: foo[0[1]] would pass
{
final Object element = termToArrayValue ( root, term );
if ( element instanceof JSONObject )
{
return (JSONObject) element;
}
}
else
{
return root.optJSONObject ( term );
}
return null;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy