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 java.text.SimpleDateFormat;
00033 import java.util.ArrayList;
00034 import java.util.Date;
00035 import java.util.Iterator;
00036 import java.util.NoSuchElementException;
00037
00038 import ros.RosException;
00039 import ros.pkg.json_prolog.srv.PrologFinish;
00040 import ros.pkg.json_prolog.srv.PrologNextSolution;
00041 import ros.pkg.json_prolog.srv.PrologQuery;
00042
00048 public class PrologQueryProxy implements Iterable<PrologBindings> {
00049
00050 boolean finished_;
00051 Prolog prolog_;
00052 String query_id_;
00053 ArrayList<PrologBindings> bindings_;
00054 QueryIterator q_it;
00055
00056
00064 public PrologQueryProxy(Prolog prolog, String query_str) {
00065
00066 this.query_id_ = makeQueryID();
00067 this.prolog_ = prolog;
00068 this.finished_ = false;
00069 this.bindings_ = new ArrayList<PrologBindings>();
00070
00071 PrologQuery.Request req = new PrologQuery.Request();
00072 PrologQuery.Response resp = new PrologQuery.Response();
00073
00074 req.id = query_id_;
00075 req.query = query_str;
00076
00077
00078 try{
00079
00080 resp=prolog_.prolog_query.call(req);
00081
00082 } catch (RosException e) {
00083 throw(new QueryError("Service call '" + prolog_.prolog_query.getService() + "' failed"));
00084 }
00085
00086 if(resp.ok == false) {
00087 throw(new QueryError("Prolog query failed: " + resp.message));
00088 }
00089
00090
00091
00092 q_it = new QueryIterator(this);
00093
00094
00095 }
00096
00100 public Iterator<PrologBindings> iterator() {
00101 return q_it;
00102 }
00103
00104
00108 public boolean isFinished() {
00109 return finished_;
00110 }
00111
00112
00116 public void finish() {
00117
00118 PrologFinish.Request req = new PrologFinish.Request();
00119
00120 req.id = query_id_;
00121 try{
00122
00123 prolog_.prolog_finish.call(req);
00124
00125 } catch (RosException e) {
00126 throw(new QueryError("Service call '" + prolog_.prolog_finish.getService() + "' failed"));
00127 }
00128 finished_ = true;
00129 }
00130
00131
00140 class QueryIterator implements Iterator<PrologBindings> {
00141
00142 Iterator<PrologBindings> data_;
00143 PrologQueryProxy query_;
00144
00145
00146 public QueryIterator(PrologQueryProxy proxy) {
00147 query_ = proxy;
00148 data_=proxy.bindings_.iterator();
00149 }
00150
00151
00156 @Override
00157 public boolean hasNext() {
00158 return requestNextSolution();
00159 }
00160
00161
00166 @Override
00167 public PrologBindings next() {
00168
00169 if(query_==null)
00170 throw( new NullPointerException());
00171
00172
00173 if(data_.hasNext()) {
00174 data_ = query_.bindings_.listIterator(query_.bindings_.size()-1);
00175 return data_.next();
00176 }
00177
00178
00179 if(query_.finished_) {
00180 data_ = query_.bindings_.listIterator(query_.bindings_.size()-1);
00181 return data_.next();
00182 }
00183
00184 else throw( new NoSuchElementException());
00185 }
00186
00187
00188
00189 @Override
00190 public void remove() {
00191
00192
00193 return;
00194 }
00195
00196
00203 protected boolean requestNextSolution() {
00204
00205
00206 if(data_.hasNext()) {
00207 return true;
00208 }
00209
00210 PrologNextSolution.Request req = new PrologNextSolution.Request();
00211 PrologNextSolution.Response resp = new PrologNextSolution.Response();
00212
00213 req.id = query_.query_id_;
00214
00215 try{
00216
00217 resp=prolog_.next_solution.call(req);
00218
00219 } catch (RosException e) {
00220 throw(new QueryError("Service call '" + prolog_.next_solution.getService() + "' failed"));
00221 }
00222
00223 switch(resp.status) {
00224
00225 case PrologNextSolution.Response.NO_SOLUTION:
00226 finish();
00227 data_ = query_.bindings_.listIterator(query_.bindings_.size());
00228 query_.finished_ = true;
00229 return false;
00230
00231 case PrologNextSolution.Response.WRONG_ID:
00232 finish();
00233 query_.finished_ = true;
00234 throw(new PrologQueryProxy.QueryError("Wrong id. Maybe the server is already processing a query."));
00235
00236 case PrologNextSolution.Response.QUERY_FAILED:
00237 finish();
00238 query_.finished_ = true;
00239 throw(new PrologQueryProxy.QueryError("Prolog query failed: " + resp.solution));
00240
00241 case PrologNextSolution.Response.OK:
00242 query_.bindings_.add(PrologBindings.parseJSONBindings(resp.solution));
00243 return true;
00244
00245 default:
00246 finish();
00247 query_.finished_ = true;
00248 throw(new PrologQueryProxy.QueryError("Unknow query status."));
00249 }
00250 }
00251 };
00252
00253
00258 protected String makeQueryID() {
00259 SimpleDateFormat sdf = new SimpleDateFormat("yy-MM-dd_HH-mm-ss-SSS");
00260 return "JAVA_QUERY_"+sdf.format(new Date());
00261 }
00262
00263
00268 class QueryError extends RuntimeException {
00269 private static final long serialVersionUID = 1190356215893161319L;
00270 public QueryError(String msg) {
00271 super(msg);
00272 }
00273 };
00274
00275
00276 }