Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 package edu.tum.cs.ias.knowrob.json_prolog;
00031
00032 import net.sf.json.*;
00033 import net.sf.json.util.JSONUtils;
00034 import jpl.JPLException;
00035 import jpl.Query;
00036 import jpl.Term;
00037 import java.util.*;
00038 import java.util.regex.Matcher;
00039 import java.util.regex.Pattern;
00040
00041 public class JSONQuery {
00042
00043 static public class InvalidJSONQuery extends Exception {
00044 public InvalidJSONQuery() {
00045 }
00046
00047 public InvalidJSONQuery(String msg) {
00048 super(msg);
00049 }
00050
00051 private static final long serialVersionUID = 1L;
00052 }
00053
00054 static public Query makeQuery(String json) throws InvalidJSONQuery {
00055 try {
00056 JSONArray json_query = JSONArray.fromObject(json);
00057
00058 return new Query(makeCompoundTerm(json_query));
00059 } catch (Exception e) {
00060 throw new InvalidJSONQuery("Unable to parse JSON query: " + json + ", Exception: " + e.toString());
00061 }
00062 }
00063
00064
00065 static public JSONObject encodeResult(Hashtable<String, Term> bindings) {
00066 JSONObject result = new JSONObject();
00067
00068 Iterator<Map.Entry<String, Term>> it = bindings.entrySet().iterator();
00069 while (it.hasNext()) {
00070 Map.Entry<String, Term> e = it.next();
00071
00072 if (e.getValue().isFloat())
00073 result.put(e.getKey(), e.getValue().floatValue());
00074 else if (e.getValue().isInteger())
00075 result.put(e.getKey(), e.getValue().intValue());
00076 else if (e.getValue().isCompound() && !e.getValue().isAtom()) {
00077 if (isList(e.getValue()))
00078 result.put(e.getKey(), encodeList(e.getValue()));
00079 else
00080 result.put(e.getKey(), encodeCompoundTerm(e.getValue()));
00081 }
00082 else
00083 result.put(e.getKey(), e.getValue().name());
00084 }
00085 return result;
00086 }
00087
00088 static Term makeCompoundTerm(JSONArray val) throws InvalidJSONQuery {
00089 if (val.isEmpty())
00090 throw new InvalidJSONQuery("makeCompoundTerm: empty sequence.");
00091
00092 String predicate = val.getString(0);
00093 if (predicate == null)
00094 throw new InvalidJSONQuery("makeCompoundTerm: no predicate given.");
00095
00096 String[] split_predicate = predicate.split(":");
00097 if(split_predicate.length == 1) {
00098 if(val.size() > 1)
00099 return new jpl.Compound(predicate, decodeJSONArray(val, 1));
00100 else
00101 return new jpl.Atom(predicate);
00102 }
00103 else if(split_predicate.length == 2) {
00104 if(val.size() > 1)
00105 return new jpl.Compound(":", new Term[] {
00106 new jpl.Atom(split_predicate[0]),
00107 new jpl.Compound(split_predicate[1], decodeJSONArray(val, 1)) });
00108 else
00109 return new jpl.Compound(":", new Term[] {
00110 new jpl.Atom(split_predicate[0]),
00111 new jpl.Atom(split_predicate[1]) });
00112 }
00113 else
00114 throw new InvalidJSONQuery("Predicate encoding wrong. Found more than one ':' in " + predicate);
00115 }
00116
00117 static Term[] decodeJSONArray(JSONArray val) throws InvalidJSONQuery {
00118 return decodeJSONArray(val, 0);
00119 }
00120
00121 static private Term[] decodeJSONArray(JSONArray val, int startIndex)
00122 throws InvalidJSONQuery {
00123 if(startIndex >= val.size())
00124 return new Term[0];
00125
00126 Term[] terms = new Term[val.size() - startIndex];
00127
00128 for (int i = startIndex; i < val.size(); i++) {
00129 if (JSONUtils.isString(val.get(i)))
00130 terms[i - startIndex] = decodeJSONValue(val.getString(i));
00131 else if (JSONUtils.isBoolean(val.get(i)))
00132 terms[i - startIndex] = decodeJSONValue(val.getBoolean(i));
00133 else if (JSONUtils.isDouble(val.get(i).getClass()))
00134 terms[i - startIndex] = decodeJSONValue(val.getDouble(i));
00135 else if (JSONUtils.isNumber(val.get(i)))
00136 terms[i - startIndex] = decodeJSONValue(val.getInt(i));
00137 else if (JSONUtils.isObject(val.get(i)))
00138 terms[i - startIndex] = decodeJSONValue(val.getJSONObject(i));
00139 else if (JSONUtils.isArray(val.get(i)))
00140 terms[i - startIndex] = jpl.Util.termArrayToList(decodeJSONArray(val.getJSONArray(i)));
00141 else
00142 throw new InvalidJSONQuery("decodeJSONArray: unable to parse "
00143 + val.toString());
00144 }
00145 return terms;
00146 }
00147
00148 static Term decodeJSONValue(String val) {
00149
00150
00151 val = val.replace("\\", "");
00152 Matcher matcher = Pattern.compile("^[\\w_]*$").matcher(val);
00153 if(!matcher.find()) {
00154 val="'"+val+"'";
00155 }
00156 return jpl.Util.textToTerm(val);
00157 }
00158
00159 static Term decodeJSONValue(boolean val) {
00160
00161 return new jpl.Integer(val ? 1 : 0);
00162 }
00163
00164 static Term decodeJSONValue(double val) {
00165 return new jpl.Float(val);
00166 }
00167
00168 static Term decodeJSONValue(int val) {
00169 return new jpl.Integer(val);
00170 }
00171
00172 static Term decodeJSONValue(JSONObject val) throws InvalidJSONQuery {
00173 if (val.has("variable"))
00174 return new jpl.Variable(val.getString("variable"));
00175 else if (val.has("term"))
00176 return makeCompoundTerm(val.getJSONArray("term"));
00177 else if (val.has("list")) {
00178 JSONArray json_elements = val.getJSONArray("list");
00179 return jpl.Util.termArrayToList(decodeJSONArray(json_elements));
00180 } else
00181 throw new InvalidJSONQuery("decodeJSONValue: unable to parse "
00182 + val.toString());
00183 }
00184
00185 static private JSONObject encodeCompoundTerm(Term term) {
00186 JSONObject result = new JSONObject();
00187 JSONArray term_list = new JSONArray();
00188
00189 term_list.element(term.name());
00190 JSONArray args_list = encodeList(term.args());
00191
00192 for (int i = 0; i < args_list.size(); i++)
00193 term_list.element(args_list.get(i));
00194
00195 result.put("term", term_list);
00196 return result;
00197 }
00198
00199 static private JSONArray encodeList(Term term) throws JPLException {
00200 Term[] term_list = term.toTermArray();
00201 return encodeList(term_list);
00202 }
00203
00204 static private JSONArray encodeList(Term[] term_list) throws JPLException {
00205 JSONArray result = new JSONArray();
00206 for (int i = 0; i < term_list.length; i++) {
00207 if (term_list[i].isFloat())
00208 result.element(term_list[i].floatValue());
00209 else if (term_list[i].isInteger())
00210 result.element(term_list[i].intValue());
00211 else if (term_list[i].isAtom())
00212 result.element(term_list[i].name());
00213 else if (term_list[i].isCompound()) {
00214 if (isList(term_list[i]))
00215 result.element(encodeList(term_list[i]));
00216 else
00217 result.element(encodeCompoundTerm(term_list[i]));
00218 } else
00219 result.element(term_list[i].name());
00220 }
00221
00222 return result;
00223 }
00224
00225 static private boolean isList(Term term) {
00226 try {
00227 term.listLength();
00228 return true;
00229 } catch (JPLException e) {
00230 return false;
00231 }
00232 }
00233
00234 }