jmlamare
9 years ago
5 changed files with 445 additions and 2 deletions
@ -0,0 +1,425 @@
|
||||
/* |
||||
* Copyright 2011 the original author or authors. |
||||
* Licensed 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 com.jayway.jsonpath.spi.json; |
||||
|
||||
import java.io.IOException; |
||||
import java.io.InputStream; |
||||
import java.util.ArrayList; |
||||
import java.util.Collection; |
||||
import java.util.Collections; |
||||
import java.util.Iterator; |
||||
import java.util.List; |
||||
import java.util.NoSuchElementException; |
||||
|
||||
import org.apache.commons.io.IOUtils; |
||||
import org.codehaus.jettison.json.JSONException; |
||||
|
||||
import com.jayway.jsonpath.InvalidJsonException; |
||||
|
||||
public class JettisonProvider extends AbstractJsonProvider |
||||
{ |
||||
private static Object jettisonUnwrap(Object obj) |
||||
{ |
||||
if( obj!=null && obj.equals(org.codehaus.jettison.json.JSONObject.NULL) ) |
||||
{ |
||||
return null; |
||||
} |
||||
return obj; |
||||
} |
||||
|
||||
private static Object jettisonWrap(Object obj) |
||||
{ |
||||
if( obj==null ) |
||||
{ |
||||
return org.codehaus.jettison.json.JSONObject.NULL; |
||||
} |
||||
return obj; |
||||
} |
||||
|
||||
/** JSON Object implementation */ |
||||
private static class JettisonTokener extends org.codehaus.jettison.json.JSONTokener |
||||
{ |
||||
public JettisonTokener(String s) |
||||
{ |
||||
super(s); |
||||
} |
||||
@Override |
||||
protected JettisonObject newJSONObject() throws JSONException |
||||
{ |
||||
return new JettisonObject(this); |
||||
} |
||||
@Override |
||||
protected JettisonArray newJSONArray() throws JSONException |
||||
{ |
||||
return new JettisonArray(this); |
||||
} |
||||
} |
||||
|
||||
/** JSON Object implementation */ |
||||
private static class JettisonObject extends org.codehaus.jettison.json.JSONObject implements Iterable<Object> |
||||
{ |
||||
private static final long serialVersionUID = 1L; |
||||
|
||||
private JettisonObject(JettisonTokener tokener) throws JSONException |
||||
{ |
||||
super(tokener); |
||||
} |
||||
|
||||
private JettisonObject() |
||||
{ |
||||
super(); |
||||
} |
||||
|
||||
@Override |
||||
public Iterator<Object> iterator() |
||||
{ |
||||
return new JettisonObjectIterator(this); |
||||
} |
||||
} |
||||
/** JSON Array implementation */ |
||||
private static class JettisonArray extends org.codehaus.jettison.json.JSONArray implements Iterable<Object> |
||||
{ |
||||
private static final long serialVersionUID = 2L; |
||||
|
||||
private JettisonArray(JettisonTokener tokener) throws JSONException |
||||
{ |
||||
super(tokener); |
||||
} |
||||
|
||||
private JettisonArray() |
||||
{ |
||||
super(); |
||||
} |
||||
|
||||
@Override |
||||
public Iterator<Object> iterator() |
||||
{ |
||||
return new JettisonArrayIterator(this); |
||||
} |
||||
} |
||||
|
||||
private static class JettisonArrayIterator implements Iterator<Object> |
||||
{ |
||||
private final org.codehaus.jettison.json.JSONArray jsonArray; |
||||
private int index = 0; |
||||
|
||||
private JettisonArrayIterator(org.codehaus.jettison.json.JSONArray jsonArray) |
||||
{ |
||||
this.jsonArray = jsonArray; |
||||
} |
||||
|
||||
@Override |
||||
public boolean hasNext() |
||||
{ |
||||
return index < jsonArray.length(); |
||||
} |
||||
|
||||
@Override |
||||
public Object next() |
||||
{ |
||||
try |
||||
{ |
||||
return jettisonUnwrap(jsonArray.get(index++)); |
||||
} |
||||
catch( org.codehaus.jettison.json.JSONException jsonException ) |
||||
{ |
||||
throw new NoSuchElementException(jsonException.toString()); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void remove() |
||||
{ |
||||
throw new UnsupportedOperationException(); |
||||
} |
||||
|
||||
} |
||||
|
||||
private static class JettisonObjectIterator implements Iterator<Object> |
||||
{ |
||||
private final org.codehaus.jettison.json.JSONObject jsonObject; |
||||
private final Iterator<?> jsonKeysIt; |
||||
|
||||
|
||||
private JettisonObjectIterator(org.codehaus.jettison.json.JSONObject jsonObject) |
||||
{ |
||||
this.jsonObject = jsonObject; |
||||
this.jsonKeysIt = jsonObject.keys(); |
||||
} |
||||
|
||||
@Override |
||||
public boolean hasNext() |
||||
{ |
||||
return jsonKeysIt.hasNext(); |
||||
} |
||||
|
||||
@Override |
||||
public Object next() |
||||
{ |
||||
try |
||||
{ |
||||
return jettisonUnwrap(jsonObject.get(String.valueOf(jsonKeysIt.next()))); |
||||
} |
||||
catch( org.codehaus.jettison.json.JSONException jsonException ) |
||||
{ |
||||
throw new NoSuchElementException(jsonException.toString()); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void remove() |
||||
{ |
||||
jsonKeysIt.remove(); |
||||
} |
||||
|
||||
} |
||||
|
||||
private Object parse(JettisonTokener JsonTokener) |
||||
{ |
||||
try |
||||
{ |
||||
char nextChar = JsonTokener.nextClean(); |
||||
JsonTokener.back(); |
||||
if (nextChar == '{') |
||||
{ |
||||
return new JettisonObject(JsonTokener); |
||||
} |
||||
if (nextChar == '[') |
||||
{ |
||||
return new JettisonArray(JsonTokener); |
||||
} |
||||
throw new JSONException("Invalid JSON"); |
||||
} |
||||
catch( org.codehaus.jettison.json.JSONException jsonException ) |
||||
{ |
||||
throw new IllegalStateException(jsonException); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public Object parse(String json) throws InvalidJsonException |
||||
{ |
||||
return parse(new JettisonTokener(json)); |
||||
} |
||||
|
||||
@Override |
||||
public Object parse(InputStream jsonStream, String charset) throws InvalidJsonException |
||||
{ |
||||
try |
||||
{ |
||||
return parse(new JettisonTokener(IOUtils.toString(jsonStream, charset))); |
||||
} |
||||
catch( IOException ioe ) |
||||
{ |
||||
throw new InvalidJsonException(ioe); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public String toJson(Object obj) |
||||
{ |
||||
try |
||||
{ |
||||
if( obj instanceof org.codehaus.jettison.json.JSONArray ) |
||||
{ |
||||
return ((org.codehaus.jettison.json.JSONArray)obj).toString(2); |
||||
} |
||||
if( obj instanceof org.codehaus.jettison.json.JSONObject ) |
||||
{ |
||||
return ((org.codehaus.jettison.json.JSONObject)obj).toString(2); |
||||
} |
||||
return String.valueOf(obj); |
||||
} |
||||
catch( org.codehaus.jettison.json.JSONException jsonException ) |
||||
{ |
||||
throw new IllegalStateException(jsonException); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public Object createMap() |
||||
{ |
||||
return new JettisonObject(); |
||||
} |
||||
|
||||
@Override |
||||
public Iterable<?> createArray() |
||||
{ |
||||
return new JettisonArray(); |
||||
} |
||||
|
||||
@Override |
||||
public Object unwrap(Object obj) |
||||
{ |
||||
return jettisonUnwrap(obj); |
||||
} |
||||
|
||||
@Override |
||||
public boolean isArray(Object obj) |
||||
{ |
||||
return obj instanceof org.codehaus.jettison.json.JSONArray; |
||||
} |
||||
|
||||
@Override |
||||
public boolean isMap(Object obj) |
||||
{ |
||||
return obj instanceof org.codehaus.jettison.json.JSONObject; |
||||
} |
||||
|
||||
@Override |
||||
public int length(Object obj) |
||||
{ |
||||
if( obj instanceof org.codehaus.jettison.json.JSONArray ) |
||||
{ |
||||
return ((org.codehaus.jettison.json.JSONArray) obj).length(); |
||||
} |
||||
if( obj instanceof org.codehaus.jettison.json.JSONObject ) |
||||
{ |
||||
return ((org.codehaus.jettison.json.JSONObject)obj).length(); |
||||
} |
||||
if( obj instanceof String ) |
||||
{ |
||||
return ((String)obj).length(); |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
@Override |
||||
public Iterable<?> toIterable(final Object obj) |
||||
{ |
||||
return new Iterable<Object>() |
||||
{ |
||||
@Override |
||||
public Iterator<Object> iterator() |
||||
{ |
||||
if( obj instanceof org.codehaus.jettison.json.JSONArray ) |
||||
{ |
||||
return new JettisonArrayIterator((org.codehaus.jettison.json.JSONArray)obj); |
||||
} |
||||
if( obj instanceof org.codehaus.jettison.json.JSONObject ) |
||||
{ |
||||
return new JettisonObjectIterator((org.codehaus.jettison.json.JSONObject)obj); |
||||
} |
||||
return Collections.emptyList().iterator(); |
||||
} |
||||
}; |
||||
|
||||
} |
||||
|
||||
public Collection<String> getPropertyKeys(Object obj) |
||||
{ |
||||
List<String> keys = new ArrayList<String>(length(obj)); |
||||
|
||||
if( obj instanceof org.codehaus.jettison.json.JSONArray ) |
||||
{ |
||||
for (int i = 0; i < length(obj); i++) |
||||
{ |
||||
keys.add(String.valueOf(i)); |
||||
} |
||||
} |
||||
if( obj instanceof org.codehaus.jettison.json.JSONObject ) |
||||
{ |
||||
Iterator<?> keysIt = ((org.codehaus.jettison.json.JSONObject)obj).keys(); |
||||
while (keysIt.hasNext()) |
||||
{ |
||||
keys.add(String.valueOf(keysIt.next())); |
||||
} |
||||
} |
||||
return keys; |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public Object getArrayIndex(Object obj, int index) |
||||
{ |
||||
return jettisonUnwrap(((org.codehaus.jettison.json.JSONArray)obj).opt(index)); |
||||
} |
||||
|
||||
@Override public void setArrayIndex(Object array, int index, Object value) |
||||
{ |
||||
if( !isArray(array) ) |
||||
{ |
||||
throw new UnsupportedOperationException(); |
||||
} |
||||
|
||||
try |
||||
{ |
||||
((org.codehaus.jettison.json.JSONArray)array).put(index, jettisonWrap(value)); |
||||
} |
||||
catch( org.codehaus.jettison.json.JSONException jsonException ) |
||||
{ |
||||
throw new IllegalArgumentException(jsonException); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public Object getMapValue(Object obj, String key) |
||||
{ |
||||
Object value = ((org.codehaus.jettison.json.JSONObject)obj).opt(key); |
||||
if( value==null ) |
||||
{ |
||||
return com.jayway.jsonpath.spi.json.JsonProvider.UNDEFINED; |
||||
} |
||||
return jettisonUnwrap(value); |
||||
} |
||||
|
||||
@Override |
||||
public void setProperty(Object obj, Object key, Object value) |
||||
{ |
||||
try |
||||
{ |
||||
if( obj instanceof org.codehaus.jettison.json.JSONArray ) |
||||
{ |
||||
int index = key instanceof Integer? (Integer) key : Integer.parseInt(key.toString()); |
||||
((org.codehaus.jettison.json.JSONArray)obj).put(index, jettisonWrap(value)); |
||||
} |
||||
if( obj instanceof org.codehaus.jettison.json.JSONObject ) |
||||
{ |
||||
((org.codehaus.jettison.json.JSONObject)obj).put(String.valueOf(key), jettisonWrap(value)); |
||||
} |
||||
} |
||||
catch( org.codehaus.jettison.json.JSONException jsonException ) |
||||
{ |
||||
throw new IllegalStateException(jsonException); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void removeProperty(Object obj, Object key) |
||||
{ |
||||
try |
||||
{ |
||||
if( obj instanceof org.codehaus.jettison.json.JSONArray ) |
||||
{ |
||||
int index = key instanceof Integer? (Integer) key : Integer.parseInt(key.toString()); |
||||
if( index<length(obj) ) |
||||
{ |
||||
Object temp = new Object(); // Need FIX: JSONArray.remove(int)
|
||||
((org.codehaus.jettison.json.JSONArray)obj).put(index, temp); |
||||
((org.codehaus.jettison.json.JSONArray)obj).remove(temp); |
||||
} |
||||
} |
||||
if( obj instanceof org.codehaus.jettison.json.JSONObject ) |
||||
{ |
||||
((org.codehaus.jettison.json.JSONObject)obj).remove(String.valueOf(key)); |
||||
} |
||||
} |
||||
catch( org.codehaus.jettison.json.JSONException jsonException ) |
||||
{ |
||||
throw new IllegalStateException(jsonException); |
||||
} |
||||
} |
||||
|
||||
} |
Loading…
Reference in new issue