Skip to content

Commit

Permalink
Move specific methods from BaseRuntime to JcfRuntime
Browse files Browse the repository at this point in the history
Motivation:

~200 loc in JcfRuntime are actually are not used by Jackson and Gson runtimes but are specific to JcfRuntime.

Those protected methods needlessly increase the API surface, make code analysis more complicated and make things more confusing for users who might want to implement a Runtime.

Modification:

Move unparse methods to JcfRuntime and make them private.

Result:

Smaller BaseRuntime API surface.
  • Loading branch information
slandelle committed Jun 7, 2019
1 parent b435937 commit 467c7af
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 89 deletions.
88 changes: 0 additions & 88 deletions jmespath-core/src/main/java/io/burt/jmespath/BaseRuntime.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package io.burt.jmespath;

import java.util.List;
import java.util.Iterator;
import java.util.Collection;

import io.burt.jmespath.parser.ExpressionParser;
Expand All @@ -10,7 +9,6 @@
import io.burt.jmespath.function.ArgumentTypeException;
import io.burt.jmespath.node.NodeFactory;
import io.burt.jmespath.node.StandardNodeFactory;
import io.burt.jmespath.util.StringEscapeHelper;

/**
* This class can be extended instead of implementing {@link Adapter} directly,
Expand All @@ -20,16 +18,6 @@
* these methods if they have more efficient means to perform the same job.
*/
public abstract class BaseRuntime<T> implements Adapter<T> {
private static final StringEscapeHelper jsonEscapeHelper = new StringEscapeHelper(
true,
'b', '\b',
't', '\t',
'n', '\n',
'f', '\f',
'r', '\r',
'\\', '\\',
'\"', '\"'
);

private final FunctionRegistry functionRegistry;
private final NodeFactory<T> nodeFactory;
Expand Down Expand Up @@ -173,82 +161,6 @@ public int hashCode() {
return 31;
}

/**
* Helper method to render a value as JSON.
*
* Assumes that <code>null</code>, <code>number</code> and <code>boolean</code>
* render themseves correctly with <code>toString</code>, and that
* <code>string</code> renders itself as an unquoted string.
*/
protected String unparse(T object) {
switch (typeOf(object)) {
case NUMBER:
return unparseNumber(object);
case BOOLEAN:
return unparseBoolean(object);
case NULL:
return unparseNull(object);
case STRING:
return unparseString(object);
case OBJECT:
return unparseObject(object);
case ARRAY:
return unparseArray(object);
default:
throw new IllegalStateException();
}
}

protected String unparseNumber(T object) {
return object.toString();
}

protected String unparseBoolean(T object) {
return object.toString();
}

protected String unparseNull(T object) {
return "null";
}

protected String unparseString(T object) {
return String.format("\"%s\"", escapeString(toString(object)));
}

protected String escapeString(String str) {
return jsonEscapeHelper.escape(str);
}

protected String unparseObject(T object) {
StringBuilder str = new StringBuilder("{");
Iterator<T> keys = getPropertyNames(object).iterator();
while (keys.hasNext()) {
T key = keys.next();
T value = getProperty(object, key);
str.append(unparseString(key));
str.append(':');
str.append(unparse(value));
if (keys.hasNext()) {
str.append(',');
}
}
str.append('}');
return str.toString();
}

protected String unparseArray(T array) {
StringBuilder str = new StringBuilder("[");
Iterator<T> elements = toList(array).iterator();
while (elements.hasNext()) {
str.append(unparse(elements.next()));
if (elements.hasNext()) {
str.append(',');
}
}
str.append(']');
return str.toString();
}

@Override
@Deprecated
public T getProperty(T value, String name) {
Expand Down
68 changes: 67 additions & 1 deletion jmespath-core/src/main/java/io/burt/jmespath/jcf/JcfRuntime.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,30 @@
import java.util.ArrayList;
import java.util.Map;
import java.util.Collection;
import java.util.Iterator;
import java.util.Collections;

import io.burt.jmespath.BaseRuntime;
import io.burt.jmespath.JmesPathType;
import io.burt.jmespath.RuntimeConfiguration;
import io.burt.jmespath.util.StringEscapeHelper;

import static io.burt.jmespath.JmesPathType.*;

public class JcfRuntime extends BaseRuntime<Object> {

private static final StringEscapeHelper jsonEscapeHelper = new StringEscapeHelper(
true,
'b', '\b',
't', '\t',
'n', '\n',
'f', '\f',
'r', '\r',
'\\', '\\',
'\"', '\"'
);

public JcfRuntime() {
super();
}

public JcfRuntime(RuntimeConfiguration configuration) {
Expand Down Expand Up @@ -160,4 +173,57 @@ public Object createNumber(double n) {
public Object createNumber(long n) {
return n;
}

/**
* Helper method to render a value as JSON.
*
* Assumes that <code>null</code>, <code>number</code> and <code>boolean</code>
* render themseves correctly with <code>toString</code>, and that
* <code>string</code> renders itself as an unquoted string.
*/
private String unparse(Object object) {
switch (typeOf(object)) {
case NUMBER:
case BOOLEAN:
return object.toString();
case NULL:
return "null";
case STRING:
return '"' + jsonEscapeHelper.escape(toString(object)) + '"';
case OBJECT:
return unparseObject(object);
case ARRAY:
return unparseArray(object);
default:
throw new IllegalStateException();
}
}

private String unparseObject(Object object) {
StringBuilder str = new StringBuilder("{");
Collection<Object> propertyNames = getPropertyNames(object);
for (Object key: propertyNames) {
Object value = getProperty(object, key);
str.append('"').append(jsonEscapeHelper.escape(toString(key))).append("\":");
str.append(unparse(value));
str.append(',');
}
if (!propertyNames.isEmpty()) {
str.setLength(str.length() - 1);
}
return str.append('}').toString();
}

private String unparseArray(Object array) {
StringBuilder str = new StringBuilder("[");
List<Object> elements = toList(array);
for (Object element : elements) {
str.append(unparse(element)).append(',');
}
if (!elements.isEmpty()) {
str.setLength(str.length() - 1);

}
return str.append(']').toString();
}
}

0 comments on commit 467c7af

Please sign in to comment.