package com.yahoo.dtf.range; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import org.apache.commons.jxpath.JXPathContext; import com.yahoo.dtf.exception.RangeException; import com.yahoo.dtf.json.JSONException; import com.yahoo.dtf.json.JSONObject; public class JSONDataRange extends Range { private String expression = null; private long nextcalled = 0; private String jpath = null; private String json = null; private ArrayList<Object> names = null; public JSONDataRange() { } public static boolean matches(String expression) throws RangeException { if ( expression.startsWith("jpath(") ) { if ( expression.endsWith(")") ) { return true; } throw new RangeException("JPath range is invalid [" + expression + "]"); } return false; } public JSONDataRange(String expression) throws RangeException { this.expression = expression; init(); } public void init() throws RangeException { String arguments = expression.substring("jpath(".length(), expression.length()-1); String[] args = arguments.split(",/"); json = args[0]; jpath = "/" + args[1]; try { JSONObject obj = new JSONObject(json); JXPathContext ctx = JXPathContext.newContext(obj); Iterator iter = ctx.iterate(jpath); names = new ArrayList<Object>(); while (iter.hasNext()) { names.add(iter.next()); } } catch (JSONException e) { throw new RangeException("Error parsing JSON.",e); } } public boolean hasMoreElements() { return (names.size() != 0); } public String nextElement() throws RangeException { Object obj = names.remove(0); nextcalled++; return obj.toString(); } public void reset() throws RangeException { init(); nextcalled = 0; } public int size() { return names.size(); } @Override public void restoreState(DataInputStream dis) throws RangeException { try { expression = dis.readUTF(); init(); long calls = dis.readLong(); // move this range into the same position. for(long i = 0; i < calls ; i++) nextElement(); } catch (IOException e) { throw new RangeException("Error suspending state.",e); } } @Override public void suspendState(DataOutputStream dos) throws RangeException { try { dos.writeUTF(expression); dos.writeLong(nextcalled); } catch (IOException e) { throw new RangeException("Error suspending state.",e); } } }