JSONQuery.java
Go to the documentation of this file.
00001 /* 
00002  * Copyright (c) 2010, Lorenz Moesenlechner
00003  * All rights reserved.
00004  * 
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  * 
00008  *     * Redistributions of source code must retain the above copyright
00009  *       notice, this list of conditions and the following disclaimer.
00010  *     * Redistributions in binary form must reproduce the above copyright
00011  *       notice, this list of conditions and the following disclaimer in the
00012  *       documentation and/or other materials provided with the distribution.
00013  *     * Neither the name of Willow Garage, Inc. nor the names of its
00014  *       contributors may be used to endorse or promote products derived from
00015  *       this software without specific prior written permission.
00016  * 
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027  * POSSIBILITY OF SUCH DAMAGE.
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           // wrap string in single quotes if it contains special characters
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     // Hack. No idea if we need to serialize bools and how.
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 }       // 


json_prolog
Author(s): Lorenz Moesenlechner, Moritz Tenorth
autogenerated on Sat Dec 28 2013 17:10:00