Skip to content

Commit

Permalink
Closes #405; JSON query for !web.
Browse files Browse the repository at this point in the history
  • Loading branch information
twpol committed Jul 27, 2012
1 parent bd38568 commit 0017e02
Showing 1 changed file with 104 additions and 2 deletions.
106 changes: 104 additions & 2 deletions src/main/plugins/Web.java
@@ -1,6 +1,8 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.text.ParseException;

import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathFactory;
Expand All @@ -12,8 +14,16 @@
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;

public class Web
{
private final int MAXIMUM_DATA_LENGTH = 400;

private final JSONParser jsonParser = new JSONParser();

public String[] info()
{
return new String[] {
Expand All @@ -25,12 +35,17 @@ public String[] info()
}

public String commandGetAndSelect(final String paramString)
{
return commandXML(paramString);
}

public String commandXML(final String paramString)
{
try {
final int splitAt = paramString.indexOf(" ");
final String uri = paramString.substring(0,splitAt);
final String uri = paramString.substring(0, splitAt);
final String xpathIn = paramString.substring(splitAt + 1, paramString.length());
final HTMLDocument doc = getDocument(new URL(uri).openConnection().getInputStream(),uri);
final HTMLDocument doc = getDocument(new URL(uri).openConnection().getInputStream(), uri);

final XPath xpath = XPathFactory.newInstance().newXPath();
final StringBuilder result = new StringBuilder();
Expand All @@ -39,6 +54,36 @@ public String commandGetAndSelect(final String paramString)
result.append(xpath.evaluate(xpathOr.trim(), doc).toString().replaceAll("\\s+", " "));
}

if (result.length() > MAXIMUM_DATA_LENGTH)
return result.substring(0, MAXIMUM_DATA_LENGTH);
return result.toString();
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}

public String commandJSON(final String paramString)
{
try {
final int splitAt = paramString.indexOf(" ");
final String uri = paramString.substring(0, splitAt);
final String queryIn = paramString.substring(splitAt + 1, paramString.length());
final Object doc = jsonParser.parse(new InputStreamReader(new URL(uri).openStream()));

final StringBuilder result = new StringBuilder();

for (final String query : queryIn.split("\\|")) {
final String queryT = query.trim();
if (queryT.startsWith("'") || queryT.startsWith("\""))
result.append(unquoteString(queryT));
else
result.append(jsonqEvaluate(doc, queryT).toString().replaceAll("\\s+", " "));
}

if (result.length() > MAXIMUM_DATA_LENGTH)
return result.substring(0, MAXIMUM_DATA_LENGTH);
return result.toString();
} catch (RuntimeException e) {
throw e;
Expand All @@ -55,4 +100,61 @@ private HTMLDocument getDocument(final InputStream input, final String uri) thro
final InputSource source = new InputSourceImpl(input,uri,"UTF-8");
return (HTMLDocument) dbi.parse(source);
}

private Object jsonqEvaluate(final Object json, final String query) throws ParseException, PropertyException
{
final int start = query.startsWith(".") ? 1 : 0;
final int ars = query.indexOf("[");
final int are = query.indexOf("]", ars);
final int dot = query.indexOf(".", start);
final String property;
final String subQuery;
if (ars != -1 && (ars < dot || dot == -1)) {
if (are == -1) throw new ParseException("Could not find matched ]", 0);
if (ars == 0) {
final String queryProperty = query.substring(1, are);
if (queryProperty.startsWith("'") || queryProperty.startsWith("\"")) {
property = unquoteString(queryProperty);
subQuery = query.substring(are + 1);
} else {
property = queryProperty;
subQuery = query.substring(are + 1);
}
} else {
property = query.substring(start, ars);
subQuery = query.substring(ars);
}
} else if (dot != -1) {
property = query.substring(start, dot);
subQuery = query.substring(dot + 1);
} else if (query.length() > start) {
property = query.substring(start);
subQuery = null;
} else {
return json;
}
final Object jsonChild = json instanceof JSONArray ? ((JSONArray)json).get(Integer.parseInt(property)) : ((JSONObject)json).get(property);
if (jsonChild == null) throw new PropertyException("Property '" + property + "' not found");
if (subQuery != null)
return jsonqEvaluate(jsonChild, subQuery);
return jsonChild;
}

private String unquoteString(final String string) throws ParseException
{
if (string.startsWith("'") || string.startsWith("\"")) {
if (string.startsWith("'") && !string.endsWith("'")) throw new ParseException("Could not find matching '", 0);
if (string.startsWith("\"") && !string.endsWith("\"")) throw new ParseException("Could not find matching \"", 0);
return string.substring(1, string.length() - 1);
}
return string;
}
}

class PropertyException extends Exception
{
public PropertyException(final String message)
{
super(message);
}
}

0 comments on commit 0017e02

Please sign in to comment.