You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
171 lines
4.5 KiB
171 lines
4.5 KiB
14 years ago
|
package com.jayway.jsonassert.impl;
|
||
|
|
||
|
import com.jayway.jsonassert.InvalidPathException;
|
||
14 years ago
|
import com.jayway.jsonassert.JSONReader;
|
||
14 years ago
|
import org.json.simple.JSONArray;
|
||
|
import org.json.simple.JSONObject;
|
||
|
import org.json.simple.parser.JSONParser;
|
||
|
import org.json.simple.parser.ParseException;
|
||
|
|
||
|
import java.util.LinkedList;
|
||
|
import java.util.List;
|
||
|
import java.util.Map;
|
||
|
|
||
|
import static org.apache.commons.lang.Validate.notNull;
|
||
|
|
||
|
/**
|
||
|
* User: kalle stenflo
|
||
|
* Date: 1/20/11
|
||
|
* Time: 4:27 PM
|
||
|
*/
|
||
14 years ago
|
public class JSONReaderImpl implements JSONReader {
|
||
14 years ago
|
|
||
|
|
||
|
private static final JSONParser JSON_PARSER = new JSONParser();
|
||
|
|
||
|
private Object root;
|
||
|
|
||
|
|
||
|
public static JSONReader parse(String jsonDoc) throws java.text.ParseException {
|
||
|
try {
|
||
14 years ago
|
return new JSONReaderImpl(JSON_PARSER.parse(jsonDoc));
|
||
14 years ago
|
} catch (ParseException e) {
|
||
|
throw new java.text.ParseException(e.getMessage(), e.getPosition());
|
||
|
}
|
||
|
}
|
||
|
|
||
14 years ago
|
/**
|
||
|
* {@inheritDoc}
|
||
|
*/
|
||
14 years ago
|
public boolean hasJsonPath(String path) {
|
||
|
boolean contains = true;
|
||
|
try {
|
||
|
get(path);
|
||
|
} catch (InvalidPathException e) {
|
||
|
contains = false;
|
||
|
}
|
||
|
return contains;
|
||
|
}
|
||
|
|
||
14 years ago
|
/**
|
||
|
* {@inheritDoc}
|
||
|
*/
|
||
|
public boolean isNull(String path) {
|
||
14 years ago
|
return (null == get(path));
|
||
|
}
|
||
|
|
||
14 years ago
|
/**
|
||
|
* {@inheritDoc}
|
||
|
*/
|
||
14 years ago
|
public Object get(String path) {
|
||
|
return getByPath(Object.class, path);
|
||
|
}
|
||
|
|
||
14 years ago
|
/**
|
||
|
* {@inheritDoc}
|
||
|
*/
|
||
14 years ago
|
public String getString(String path) {
|
||
|
return getByPath(String.class, path);
|
||
|
}
|
||
|
|
||
14 years ago
|
/**
|
||
|
* {@inheritDoc}
|
||
|
*/
|
||
14 years ago
|
public Long getLong(String path) {
|
||
|
return getByPath(Long.class, path);
|
||
|
}
|
||
|
|
||
14 years ago
|
/**
|
||
|
* {@inheritDoc}
|
||
|
*/
|
||
14 years ago
|
public Boolean getBoolean(String path) {
|
||
|
return getByPath(Boolean.class, path);
|
||
|
}
|
||
|
|
||
14 years ago
|
/**
|
||
|
* {@inheritDoc}
|
||
|
*/
|
||
14 years ago
|
public <T> List<T> getList(String path) {
|
||
14 years ago
|
return getByPath(List.class, path);
|
||
|
}
|
||
|
|
||
14 years ago
|
/**
|
||
|
* {@inheritDoc}
|
||
|
*/
|
||
14 years ago
|
public Map getMap(String path) {
|
||
|
return getByPath(Map.class, path);
|
||
|
}
|
||
|
|
||
|
|
||
|
//------------------------------------------------------------
|
||
|
//
|
||
|
// private methods
|
||
|
//
|
||
|
//------------------------------------------------------------
|
||
14 years ago
|
private JSONReaderImpl(Object root) {
|
||
14 years ago
|
notNull(root, "root object can not be null");
|
||
|
this.root = root;
|
||
|
}
|
||
|
|
||
|
private <T> T getByPath(Class<T> clazz, String stringPath) {
|
||
|
Object current = this.root;
|
||
|
JSONPath path = new JSONPath(stringPath);
|
||
|
|
||
|
while (path.hasMoreFragments()) {
|
||
|
JSONPathFragment fragment = path.nextFragment();
|
||
|
if (fragment.isArrayIndex()) {
|
||
|
current = getArray(current).get(fragment.getArrayIndex());
|
||
|
} else if (fragment.isArrayWildcard()) {
|
||
|
current = getContainerValue(current, path.nextFragment().fragment());
|
||
|
} else {
|
||
|
current = getContainerValue(current, fragment.fragment());
|
||
|
}
|
||
|
}
|
||
|
return clazz.cast(current);
|
||
|
}
|
||
|
|
||
|
private JSONArray getArray(Object array) {
|
||
|
return (JSONArray) array;
|
||
|
}
|
||
|
|
||
|
private JSONObject getDocument(Object document) {
|
||
|
return (JSONObject) document;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Extracts a field from a given container. If the given container
|
||
|
* is an Array the field specified represents a field in the objects
|
||
|
* contained in the array. Values from all instances of this field
|
||
|
* will be returned in a List
|
||
|
*
|
||
|
* @param container a json document or array
|
||
|
* @param field the field to extract from the document alt. the documents contained in the array
|
||
|
* @return a single field value or a List of fields
|
||
|
*/
|
||
|
private Object getContainerValue(Object container, Object field) {
|
||
|
Object result;
|
||
|
|
||
|
if (container instanceof JSONArray) {
|
||
|
List list = new LinkedList();
|
||
|
for (Object doc : getArray(container)) {
|
||
|
list.add(getContainerValue(doc, field));
|
||
|
}
|
||
|
result = list;
|
||
|
|
||
|
} else if (container instanceof JSONObject) {
|
||
|
JSONObject document = getDocument(container);
|
||
|
|
||
14 years ago
|
if (!document.containsKey(field)) {
|
||
14 years ago
|
throw new InvalidPathException();
|
||
|
}
|
||
|
|
||
|
result = document.get(field);
|
||
|
} else {
|
||
|
throw new UnsupportedOperationException("can not get value from " + container.getClass().getName());
|
||
|
}
|
||
|
//notNull(result, "invalid path: " + field);
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
}
|