1 5 6 package org.joseki.server.http; 7 8 import java.util.* ; 9 import org.apache.commons.logging.* ; 10 import java.io.* ; 11 12 import javax.servlet.http.* ; 13 import org.joseki.* ; 14 import org.joseki.util.NullOutputStream; 15 import org.joseki.util.HttpContentType ; 16 import org.joseki.server.*; 17 import com.hp.hpl.jena.rdf.model.*; 18 19 24 public class HttpOperationCodec 25 { 26 static Log log = LogFactory.getLog(HttpOperationCodec.class.getName()) ; 27 static public final String ENC_UTF8 = "UTF-8" ; 28 29 30 public HttpOperationCodec() {} 31 32 public void setArgs(Request request, HttpServletRequest httpRequest) throws ExecutionException 33 { 34 if ( request.getProcessor().argsNeeded() == 0) 37 return; 38 39 if (request.getProcessor().argsNeeded() > 1) 40 { 41 throw new ExecutionException(ExecutionError.rcOperationNotSupported, 42 "Processor error: needs more args", 43 "Processor needs "+request.getProcessor().argsNeeded()+" args - unsupported") ; 44 } 45 46 47 try{ 49 int len = httpRequest.getContentLength(); 50 if ( len == 0 ) 51 log.warn("No data supplied - Content-length: "+len) ; 53 54 HttpContentType ct = new HttpContentType(httpRequest.getContentType(), 55 "RDF/XML", ENC_UTF8) ; 56 57 BufferedReader r = httpRequest.getReader(); 59 60 64 if ( !ct.getCharset().equalsIgnoreCase("UTF-8") ) 65 log.warn("Request charset is "+ct.getCharset()) ; 66 67 71 try 72 { 73 Model model = ModelFactory.createDefaultModel(); 74 75 model.read(r, "", Joseki.getReaderType(ct.getMediaType())); 76 request.addArg(model); 77 } 78 catch (RDFException rdfEx) 79 { 80 throw new ExecutionException( 81 ExecutionError.rcArgumentUnreadable, 82 "Argument error", 83 rdfEx.getMessage()); 84 } 85 } 86 catch (IOException ioEx) 87 { 88 throw new ExecutionException( 89 ExecutionError.rcInternalError, 90 "IOException", 91 "IOExeception: " + ioEx); 92 } 93 catch (Exception ex) 94 { 95 log.warn("Exception: " + ex); 96 throw new ExecutionException( 97 ExecutionError.rcArgumentUnreadable, 98 "Argument error", 99 null); 100 } 101 if ( request.getDataArgs().size() != request.getProcessor().argsNeeded() ) 102 log.warn("Failed to get the argument(s)") ; 103 } 104 105 public void setParameters(Request request, HttpServletRequest httpRequest) 106 { 107 String s = httpRequest.getQueryString() ; 108 String[] params = s.split("&") ; 110 for ( int i = 0 ; i < params.length ; i++ ) 111 { 112 String p = params[i] ; 113 String[] x = p.split("=",2) ; 114 if ( x.length == 0 ) 115 request.setParam(p,"" ) ; 116 else if ( x.length == 1 ) 117 request.setParam(x[0], "") ; 118 else 119 request.setParam(x[0], x[1]) ; 120 } 121 } 122 123 131 132 public boolean sendResponse(Model resultModel, Request request, 133 HttpServletRequest httpRequest, 134 HttpServletResponse httpResponse) 135 throws IOException 136 { 137 if (resultModel == null) 139 { 140 log.warn("Result is null pointer for result model") ; 141 sendPanic(request, httpRequest, httpResponse, null, 142 "Server internal error: processor returned a null pointer, not a model") ; 143 return false; 144 } 145 146 String mimeType = Joseki.contentTypeRDFXML ; 147 148 if ( Joseki.serverDebug ) 149 mimeType = "text/plain" ; 150 151 155 158 Enumeration enum = httpRequest.getHeaders("Accept") ; 159 for ( ; enum.hasMoreElements() ; ) 160 { 161 String s = (String)enum.nextElement() ; 162 String m = Joseki.getWriterType(s) ; 163 if ( m != null ) 164 { 165 mimeType = s ; 166 break ; 167 } 168 } 169 170 String acceptCharset = httpRequest.getHeader("Accept-Charset") ; 171 if ( acceptCharset != null ) 172 { 173 if ( ! acceptCharset.equalsIgnoreCase(ENC_UTF8) ) 174 log.warn("Accept-Charset: "+acceptCharset) ; 175 } 176 177 String writerType = Joseki.getWriterType(mimeType) ; 178 179 if ( writerType == null ) 180 { 181 writerType = Joseki.getWriterType(Joseki.serverContentType) ; 183 } 185 186 if (false) 187 { 188 FileOutputStream out = new FileOutputStream("response.n3"); 189 resultModel.write(out, "N3"); 190 out.close() ; 191 } 192 193 if ( false ) 194 { 195 log.info("Result model ("+writerType+")") ; 196 StringWriter sw = new StringWriter() ; 197 resultModel.write(sw, "N3"); 199 log.info("\n"+sw.toString()) ; 200 201 } 202 203 209 RDFWriter rdfw = resultModel.getWriter(writerType) ; 210 211 if ( writerType.equals("RDF/XML-ABBREV") || writerType.equals("RDF/XML") ) 212 { 213 rdfw.setProperty("showXmlDeclaration", "true") ; 214 215 if ( writerType.equals("RDF/XML-ABBREV") ) 216 rdfw.setProperty("blockRules", "propertyAttr") ; 218 } 219 220 try { 223 OutputStream out = new NullOutputStream() ; 224 rdfw.write(resultModel, out, null) ; 225 out.flush() ; 226 } catch (Exception ex) 227 { 228 log.warn("Exception test writing model: "+ex.getMessage(), ex) ; 230 sendPanic(request, httpRequest, httpResponse, ex, 231 "Server internal error: can't write the model.") ; 232 return false; 233 } 234 235 237 if ( Joseki.serverDebug ) 239 { 240 httpResponse.setHeader("Cache-Control", "no-cache") ; 241 httpResponse.setHeader("Pragma", "no-cache") ; 242 } 243 244 httpResponse.setHeader(Joseki.httpHeaderField, Joseki.httpHeaderValue) ; 245 246 String contentType = mimeType+"; charset=UTF-8" ; 248 log.trace("Content-Type for response: "+contentType) ; 249 httpResponse.setContentType(contentType) ; 250 251 log.trace("HTTP response 200") ; 252 rdfw.write(resultModel, httpResponse.getOutputStream(), null) ; 253 return true ; 254 } 255 256 257 258 public void sendError(ExecutionException execEx, HttpServletResponse response) 259 throws IOException 260 { 261 int httpRC = -1; 262 String httpMsg = ExecutionError.errorString(execEx.returnCode); 263 if (execEx.shortMessage != null) 264 httpMsg = execEx.shortMessage; 265 266 switch (execEx.returnCode) 268 { 269 case ExecutionError.rcOK : 270 httpRC = 200; 271 break; 272 case ExecutionError.rcQueryParseFailure : 273 httpRC = HttpServletResponse.SC_BAD_REQUEST; 274 break; 275 case ExecutionError.rcQueryExecutionFailure : 276 httpRC = HttpServletResponse.SC_BAD_REQUEST; 277 break; 278 case ExecutionError.rcNoSuchQueryLanguage : 279 httpRC = HttpServletResponse.SC_NOT_IMPLEMENTED ; 280 break; 281 case ExecutionError.rcInternalError : 282 httpRC = HttpServletResponse.SC_INTERNAL_SERVER_ERROR; 283 break; 284 case ExecutionError.rcRDFException : 285 httpRC = HttpServletResponse.SC_BAD_REQUEST ; 286 break ; 287 case ExecutionError.rcNoSuchURI: 288 httpRC = HttpServletResponse.SC_NOT_FOUND ; 289 break ; 290 case ExecutionError.rcSecurityError: 291 httpRC = HttpServletResponse.SC_FORBIDDEN ; 292 break ; 293 case ExecutionError.rcOperationNotSupported: 294 httpRC = HttpServletResponse.SC_NOT_IMPLEMENTED ; 295 break ; 296 case ExecutionError.rcArgumentUnreadable: 297 httpRC = HttpServletResponse.SC_BAD_REQUEST ; 298 break ; 299 case ExecutionError.rcImmutableModel: 300 httpRC = HttpServletResponse.SC_METHOD_NOT_ALLOWED ; 301 break ; 302 case ExecutionError.rcConfigurationError: 303 httpRC = HttpServletResponse.SC_INTERNAL_SERVER_ERROR ; 304 break ; 305 case ExecutionError.rcArgumentError: 306 httpRC = HttpServletResponse.SC_BAD_REQUEST ; 307 default : 308 httpRC = HttpServletResponse.SC_INTERNAL_SERVER_ERROR; 309 break; 310 } 311 response.setHeader(Joseki.httpHeaderField, Joseki.httpHeaderValue) ; 312 response.sendError(httpRC, httpMsg) ; 313 } 314 315 316 private void sendPanic( Request request, 318 HttpServletRequest httpRequest, 319 HttpServletResponse httpResponse, 320 Exception ex, 321 String msg) 322 throws IOException 323 { 324 httpResponse.setContentType("text/plain"); 325 httpResponse.setHeader(Joseki.httpHeaderField, Joseki.httpHeaderValue); 326 httpResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); 327 328 PrintWriter pw = httpResponse.getWriter(); 329 pw.println(msg); 330 pw.println(); 331 pw.println("URI = " + request.getModelURI()); 332 for (Iterator iter = request.getParams().keySet().iterator(); iter.hasNext();) 333 { 334 String p = (String)iter.next(); 335 pw.println(p + " = " + request.getParam(p)); 336 } 337 pw.println() ; 338 if ( ex != null ) 339 ex.printStackTrace(pw) ; 340 pw.flush(); 341 return; 342 } 343 } 344 345 346 372 | Popular Tags |