1 5 6 package com.hp.hpl.jena.joseki; 7 8 import org.joseki.*; 9 import org.joseki.util.Convert ; 10 import org.joseki.util.HttpContentType; 11 import org.joseki.vocabulary.*; 12 13 import java.net.* ; 14 import java.io.* ; 15 import java.util.* ; 16 import org.apache.commons.logging.* ; 17 18 import com.hp.hpl.jena.rdf.model.* ; 19 import com.hp.hpl.jena.shared.* ; 20 21 34 public class HttpQuery 35 { 36 static final Log log = LogFactory.getLog(HttpQuery.class.getName()) ; 37 38 39 static public int urlLimit = 2*1024 ; 41 42 String modelURI ; 44 String queryLang ; 45 Map params = new HashMap() ; 46 47 String queryString = null ; 48 49 final static Object noValue = new Object () ; 51 52 int responseCode = 0; 53 String responseMessage = null ; 54 boolean forcePOST = false ; 55 56 static final String ENC_UTF8 = "UTF-8" ; 57 58 61 62 public HttpQuery(String urlString) 63 { 64 init(urlString, null) ; 65 } 66 67 68 71 72 public HttpQuery(URL url) 73 { 74 init(url.toString(), null) ; 75 } 76 77 78 82 83 public HttpQuery(URL url, String queryLang) 84 { 85 init(url.toString(), queryLang) ; 87 } 88 89 90 94 95 public HttpQuery(String urlString, String queryLang) 96 { 97 init(urlString, queryLang) ; 98 } 99 100 private void init(String urlStr, String qLang) 101 { 102 if ( log.isTraceEnabled()) 103 log.trace("URL: "+urlStr+" Lang="+qLang) ; 104 105 if ( urlStr.indexOf('?') >= 0 ) 106 throw new HttpException(-1, "URL already has a query string ("+urlStr+")") ; 107 108 modelURI = urlStr ; 109 queryLang = qLang ; 110 queryString = null ; 111 } 112 113 114 private void makeQueryString() 115 { 116 if (queryString != null) 117 return; 119 120 if (queryLang != null) 122 queryString = "?lang=" + Convert.encWWWForm(queryLang); 123 124 boolean first = (queryString == null); 126 for (Iterator iter = params.keySet().iterator(); iter.hasNext();) 127 { 128 String name = (String ) iter.next(); 129 Object obj = params.get(name); 130 String tmp = name ; 131 if ( obj != noValue ) 132 tmp = name + "=" + Convert.encWWWForm((String )obj); 133 134 if (first) 135 queryString = "?" + tmp; 136 else 137 queryString = queryString + "&" + tmp; 138 first = false ; 139 } 140 141 if ( queryString == null ) 142 queryString = "" ; 143 } 144 145 146 150 151 public void setParam(String name, String value) 152 { 153 if ( value == null ) 154 params.put(name, noValue) ; 155 else 156 params.put(name, value) ; 157 queryString = null ; 159 } 160 161 165 166 public void addParam(String name, String value) 167 { 168 setParam(name, value) ; 169 } 170 171 174 175 public void addParam(String name) { addParam(name, null) ; } 176 177 182 183 186 public boolean usesPOST() 187 { 188 if ( forcePOST ) 189 return true ; 190 makeQueryString() ; 191 192 return queryString != null && +modelURI.length()+queryString.length() >= urlLimit ; 193 } 194 195 197 198 public void setForcePOST() 199 { 200 forcePOST = true ; 201 } 202 203 204 public int getResponseCode() { return responseCode ; } 205 206 207 public String getResponseMessage() { return responseMessage ; } 208 209 210 214 public Model exec() throws HttpException 215 { 216 makeQueryString() ; 217 218 try { 219 if (usesPOST()) 220 return execPost(); 221 else 222 return execGet(); 223 } catch (HttpException httpEx) 224 { 225 log.trace("Exception in exec", httpEx); 226 throw httpEx; 227 } 228 catch (JenaException jEx) 229 { 230 log.trace("JenaException in exec", jEx); 231 throw jEx ; 232 } 233 } 234 235 236 private Model execGet() throws HttpException 237 { 238 URL target = null ; 239 try { 240 if ( queryString.equals("")) 241 { 242 target = new URL(modelURI) ; 244 } 245 else 246 target = new URL(modelURI+queryString) ; 247 } 248 catch (MalformedURLException malEx) 249 { throw new HttpException(0, "Malformed URL: "+malEx) ; } 250 log.trace("GET "+target.toExternalForm()) ; 251 252 try 253 { 254 HttpURLConnection conn = (HttpURLConnection) target.openConnection(); 255 conn.setRequestProperty("Accept", Joseki.contentTypeRDFXML+", "+ 256 Joseki.contentTypeN3) ; 257 260 conn.setDoInput(true); 261 conn.connect(); 262 try 263 { 264 return execCommon(conn); 265 } 266 catch (HttpException qEx) 267 { 268 if (qEx.getResponseCode() == 414 ) 271 return execPost(); 272 throw qEx; 273 } 274 } 275 catch (java.net.ConnectException connEx) 276 { 277 throw new HttpException(HttpException.NoServer, "Failed to connect to remote server"); 278 } 279 280 catch (IOException ioEx) 281 { 282 throw new HttpException(ioEx); 283 } 284 } 285 286 288 private Model execPost() throws HttpException 289 { 290 URL target = null; 291 try { target = new URL(modelURI + "?op=query"); } 292 catch (MalformedURLException malEx) 293 { throw new HttpException(0, "Malformed URL: " + malEx); } 294 log.trace("POST "+target.toExternalForm()) ; 295 296 try 297 { 298 HttpURLConnection conn = (HttpURLConnection) target.openConnection(); 299 conn.setRequestProperty("Accept", Joseki.contentTypeRDFXML+", "+ 300 Joseki.contentTypeN3) ; 301 conn.setRequestProperty("Accept-Charset", ENC_UTF8) ; 302 conn.setRequestProperty("Content-Type", Joseki.clientContentType+ "; charset="+ENC_UTF8) ; 304 conn.setDoOutput(true) ; 305 conn.setDoInput(true) ; 306 307 309 Model model = ModelFactory.createDefaultModel() ; 310 Resource r = model.createResource() ; 311 312 r.addProperty(JosekiVocab.requestQueryLanguage, queryLang) ; 315 316 for ( Iterator iter = params.keySet().iterator() ; iter.hasNext() ; ) 317 { 318 String name = (String )iter.next() ; 319 if ( name.equals("query")) 320 r.addProperty(JosekiVocab.queryScript, (String )params.get("query")) ; 321 else 322 log.warn("execPost: Skipping parameter: "+name) ; 323 log.trace("Post: "+name+" = "+(String )params.get(name)) ; 324 } 325 326 String rdfSyntax = Joseki.getWriterType(Joseki.clientContentType) ; 327 RDFWriter rdfw = model.getWriter() ; 328 if ( rdfSyntax.startsWith("RDF/XML") ) 329 rdfw.setProperty("showXmlDeclaration", "true") ; 330 rdfw.write(model, conn.getOutputStream(), null) ; 331 332 conn.getOutputStream().flush() ; 333 conn.connect() ; 334 return execCommon(conn) ; 335 } 336 catch (RDFException rdfEx) 337 { 338 throw new HttpException(-1, "Failed to create RDF request"); 339 } 340 catch (java.net.ConnectException connEx) 341 { 342 throw new HttpException(-1, "Failed to connect to remote server"); 343 } 344 345 catch (IOException ioEx) 346 { 347 throw new HttpException(ioEx); 348 } 349 } 350 351 private Model execCommon(HttpURLConnection conn) throws HttpException 352 { 353 try { 354 responseCode = conn.getResponseCode() ; 355 responseMessage = conn.getResponseMessage() ; 356 357 363 if ( 300 <= responseCode && responseCode < 400 ) 364 { 365 throw new HttpException(responseCode, responseMessage) ; 366 } 367 368 370 if ( responseCode >= 400 ) 371 { 372 throw new HttpException(responseCode, responseMessage) ; 373 } 374 375 InputStream in = conn.getInputStream() ; 378 379 382 HttpContentType ct = new HttpContentType(conn.getContentType(), Joseki.contentTypeRDFXML, ENC_UTF8) ; 383 384 if ( ! ct.getCharset().equalsIgnoreCase(ENC_UTF8) ) 385 log.warn("Charset is not UTF-8 : danger of mismatch with XML body") ; 386 387 Reader r = null ; 388 try { r = new InputStreamReader(in, ct.getCharset()) ; } 389 catch ( UnsupportedEncodingException ex) 390 { 391 log.warn("Unsupported encoding '"+ct.getCharset()+"' : trying with UTF-8") ; 392 r = new InputStreamReader(in, ENC_UTF8) ; 393 } 394 395 Model resultModel = ModelFactory.createDefaultModel() ; 396 397 resultModel.read(r, "http://somewhere/", Joseki.getReaderType(ct.getMediaType())) ; 398 return resultModel ; 399 } 400 catch (IOException ioEx) 401 { 402 throw new HttpException(ioEx) ; 403 } 404 catch (RDFException rdfEx) 405 { 406 throw new HttpException(rdfEx) ; 407 } 408 } 409 410 public String toString() 411 { 412 makeQueryString() ; 413 414 if ( queryString.equals("")) 415 return modelURI ; 416 else 417 return modelURI+queryString ; 418 } 419 } 420 421 447 | Popular Tags |