- Timestamp:
- 06/16/12 17:12:37 (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRUServer.java
r1989 r1990 37 37 import eu.clarin.sru.server.SRUServerConfig.LocalizedString; 38 38 import eu.clarin.sru.server.SRUServerConfig.SchemaInfo; 39 import eu.clarin.sru.server.utils.SRUServerServlet; 39 40 40 41 … … 42 43 * SRU/CQL protocol implementation for the server-side (SRU/S). This class 43 44 * implements SRU/CQL version 1.1 and and 1.2. 44 * <p>45 * An example servlet using this class:46 * </p>47 * <pre>48 * public class MySRUServlet extends HttpServlet {49 * private transient SRUServer sruServer;50 *51 *52 * public void init() throws ServletException {53 * final ServletContext ctx = getServletContext();54 * try {55 * URL url = MySRUServlet.class.getClassLoader().getResource(56 * "META-INF/endpoint-config.xml");57 * if (url == null) {58 * throw new ServletException("not found, url == null");59 * }60 *61 * // get additional runtime configuration from Servlet context62 * HashMap<String, String> params = new HashMap<String, String>();63 * for (Enumeration<?> i = ctx.getInitParameterNames(); i64 * .hasMoreElements();) {65 * String key = (String) i.nextElement();66 * String value = ctx.getInitParameter(key);67 * if ((value != null) && !value.isEmpty()) {68 * params.put(key, value);69 * }70 * }71 *72 * SRUServerConfig config = SRUServerConfig.parse(params,73 * url.openStream());74 * SRUSearchEngine searchEngine = new MySRUSearchEngine(config, params);75 * sruServer = new SRUServer(config, searchEngine);76 * } catch (Exception e) {77 * throw new ServletException("error initializing endpoint", e);78 * }79 * }80 *81 *82 * protected void doGet(HttpServletRequest request,83 * HttpServletResponse response) throws ServletException, IOException {84 * sruServer.handleRequest(request, response);85 * }86 *87 *88 * protected void doPost(HttpServletRequest request,89 * HttpServletResponse response) throws ServletException, IOException {90 * sruServer.handleRequest(request, response);91 * }92 * }93 * </pre>94 45 * 95 46 * @see SRUServerConfig 96 47 * @see SRUSearchEngine 48 * @see SRUServerServlet 97 49 * @see <a href="http://www.loc.gov/standards/sru/">SRU/CQL protocol 1.2</a> 98 50 */ 99 public class SRUServer {51 public final class SRUServer { 100 52 private static final String SRU_NS = 101 53 "http://www.loc.gov/zing/srw/"; … … 228 180 229 181 // commence explain ... 230 SRUExplainResult result = searchEngine.explain(config, 231 request, request); 232 233 // send results 234 SRUXMLStreamWriter out = 235 createXMLStreamWriter(response.getOutputStream(), 236 request.getRecordPacking(), 237 request.getIndentResponse()); 238 239 beginResponse(out, request); 240 241 // write the explain record 242 writeExplainRecord(out, request); 243 244 if (config.getEchoRequests()) { 245 writeEchoedExplainRequest(out, request); 246 } 247 248 // diagnostics 249 writeDiagnosticList(out, request.getDiagnostics()); 250 251 // extraResponseData 252 if (result != null) { 182 final SRUExplainResult result = 183 searchEngine.explain(config, request, request); 184 185 try { 186 // send results 187 SRUXMLStreamWriter out = 188 createXMLStreamWriter(response.getOutputStream(), 189 request.getRecordPacking(), 190 request.getIndentResponse()); 191 192 beginResponse(out, request); 193 194 // write the explain record 195 writeExplainRecord(out, request); 196 197 if (config.getEchoRequests()) { 198 writeEchoedExplainRequest(out, request); 199 } 200 201 // diagnostics 202 writeDiagnosticList(out, request.getDiagnostics()); 203 204 // extraResponseData 205 if (result != null) { 206 if (result.hasExtraResponseData()) { 207 out.writeStartElement(SRU_NS, "extraResponseData"); 208 result.writeExtraResponseData(out); 209 out.writeEndElement(); // "extraResponseData" element 210 } 211 } 212 213 endResponse(out); 214 } finally { 215 if (result != null) { 216 result.close(); 217 } 218 } 219 } 220 221 222 private void scan(SRURequestImpl request, HttpServletResponse response) 223 throws IOException, XMLStreamException, SRUException { 224 logger.info("scan: scanClause = \"{}\"", 225 new Object[] { request.getRawScanClause() }); 226 227 // commence scan 228 final SRUScanResultSet result = 229 searchEngine.scan(config, request, request); 230 if (result == null) { 231 throw new SRUException(SRUConstants.SRU_UNSUPPORTED_OPERATION, 232 "The 'scan' operation is not supported by this endpoint."); 233 } 234 235 try { 236 // send results 237 SRUXMLStreamWriter out = 238 createXMLStreamWriter(response.getOutputStream(), 239 request.getRecordPacking(), 240 request.getIndentResponse()); 241 242 beginResponse(out, request); 243 244 try { 245 out.writeStartElement(SRU_NS, "terms"); 246 while (result.nextTerm()) { 247 out.writeStartElement(SRU_NS, "term"); 248 249 out.writeStartElement(SRU_NS, "value"); 250 out.writeCharacters(result.getValue()); 251 out.writeEndElement(); // "value" element 252 253 if (result.getNumberOfRecords() > -1) { 254 out.writeStartElement(SRU_NS, "numberOfRecords"); 255 out.writeCharacters( 256 Integer.toString(result.getNumberOfRecords())); 257 out.writeEndElement(); // "numberOfRecords" element 258 } 259 260 if (result.getDisplayTerm() != null) { 261 out.writeStartElement(SRU_NS, "displayTerm"); 262 out.writeCharacters(result.getDisplayTerm()); 263 out.writeEndElement(); // "displayTerm" element 264 } 265 266 if (result.getWhereInList() != null) { 267 out.writeStartElement(SRU_NS, "whereInList"); 268 switch (result.getWhereInList()) { 269 case FIRST: 270 out.writeCharacters("first"); 271 break; 272 case LAST: 273 out.writeCharacters("last"); 274 break; 275 case ONLY: 276 out.writeCharacters("only"); 277 break; 278 case INNER: 279 out.writeCharacters("inner"); 280 break; 281 } // switch 282 out.writeEndElement(); // "whereInList" element 283 } 284 285 if (result.hasExtraTermData()) { 286 out.writeStartElement(SRU_NS, "extraTermData"); 287 result.writeExtraTermData(out); 288 out.writeEndElement(); // "extraTermData" element 289 } 290 291 out.writeEndElement(); // "term" element 292 } // while 293 out.writeEndElement(); // "terms" element 294 } catch (NoSuchElementException e) { 295 throw new SRUException(SRUConstants.SRU_GENERAL_SYSTEM_ERROR, 296 "An internal error occurred while " 297 + "serializing scan results."); 298 } 299 300 // echoedScanRequest 301 if (config.getEchoRequests()) { 302 writeEchoedScanRequest(out, request, request.getScanClause()); 303 } 304 305 // diagnostics 306 writeDiagnosticList(out, request.getDiagnostics()); 307 308 // extraResponseData 253 309 if (result.hasExtraResponseData()) { 254 310 out.writeStartElement(SRU_NS, "extraResponseData"); … … 256 312 out.writeEndElement(); // "extraResponseData" element 257 313 } 258 } 259 260 endResponse(out); 261 } 262 263 264 private void scan(SRURequestImpl request, HttpServletResponse response) 265 throws IOException, XMLStreamException, SRUException { 266 logger.info("scan: scanClause = \"{}\"", 267 new Object[] { request.getRawScanClause() }); 268 269 // commence scan 270 final SRUScanResultSet result = searchEngine.scan(config, 271 request, request); 272 if (result == null) { 273 throw new SRUException(SRUConstants.SRU_UNSUPPORTED_OPERATION, 274 "The 'scan' operation is not supported by this endpoint."); 275 } 276 277 // send results 278 SRUXMLStreamWriter out = 279 createXMLStreamWriter(response.getOutputStream(), 280 request.getRecordPacking(), 281 request.getIndentResponse()); 282 283 beginResponse(out, request); 284 285 try { 286 out.writeStartElement(SRU_NS, "terms"); 287 while (result.hasMoreTerms()) { 288 out.writeStartElement(SRU_NS, "term"); 289 290 out.writeStartElement(SRU_NS, "value"); 291 out.writeCharacters(result.getValue()); 292 out.writeEndElement(); // "value" element 293 294 if (result.getNumberOfRecords() > -1) { 295 out.writeStartElement(SRU_NS, "numberOfRecords"); 296 out.writeCharacters( 297 Integer.toString(result.getNumberOfRecords())); 298 out.writeEndElement(); // "numberOfRecords" element 299 } 300 301 if (result.getDisplayTerm() != null) { 302 out.writeStartElement(SRU_NS, "displayTerm"); 303 out.writeCharacters(result.getDisplayTerm()); 304 out.writeEndElement(); // "displayTerm" element 305 } 306 307 if (result.getWhereInList() != null) { 308 out.writeStartElement(SRU_NS, "whereInList"); 309 switch (result.getWhereInList()) { 310 case FIRST: 311 out.writeCharacters("first"); 312 break; 313 case LAST: 314 out.writeCharacters("last"); 315 break; 316 case ONLY: 317 out.writeCharacters("only"); 318 break; 319 case INNER: 320 out.writeCharacters("inner"); 321 break; 322 } // switch 323 out.writeEndElement(); // "whereInList" element 324 } 325 326 if (result.hasExtraTermData()) { 327 out.writeStartElement(SRU_NS, "extraTermData"); 328 result.writeExtraTermData(out); 329 out.writeEndElement(); // "extraTermData" element 330 } 331 332 out.writeEndElement(); // "term" element 333 334 result.nextTerm(); 335 } 336 out.writeEndElement(); // "terms" element 337 } catch (NoSuchElementException e) { 338 throw new SRUException(SRUConstants.SRU_GENERAL_SYSTEM_ERROR, 339 "An internal error occurred while " + 340 "serializing scan results."); 341 } 342 343 // echoedScanRequest 344 if (config.getEchoRequests()) { 345 writeEchoedScanRequest(out, request, request.getScanClause()); 346 } 347 348 // diagnostics 349 writeDiagnosticList(out, request.getDiagnostics()); 350 351 // extraResponseData 352 if (result.hasExtraResponseData()) { 353 out.writeStartElement(SRU_NS, "extraResponseData"); 354 result.writeExtraResponseData(out); 355 out.writeEndElement(); // "extraResponseData" element 356 } 357 358 endResponse(out); 314 315 endResponse(out); 316 } finally { 317 if (result != null) { 318 result.close(); 319 } 320 } 359 321 } 360 322 … … 370 332 371 333 // commence search ... 372 final SRUSearchResultSet result = searchEngine.search(config,373 request, request);334 final SRUSearchResultSet result = 335 searchEngine.search(config, request, request); 374 336 if (result == null) { 375 337 throw new SRUException(SRUConstants.SRU_GENERAL_SYSTEM_ERROR, 376 "Database implementation returned invalid result (null)."); 377 } 378 379 // send results 380 SRUXMLStreamWriter out = 381 createXMLStreamWriter(response.getOutputStream(), 382 request.getRecordPacking(), 383 request.getIndentResponse()); 384 385 beginResponse(out, request); 386 387 // numberOfRecords 388 out.writeStartElement(SRU_NS, "numberOfRecords"); 389 out.writeCharacters(Integer.toString(result.getTotalRecordCount())); 390 out.writeEndElement(); // "numberOfRecords" element 391 392 // resultSetId 393 if (result.getResultSetId() != null) { 394 out.writeStartElement(SRU_NS, "resultSetId"); 395 out.writeCharacters(result.getResultSetId()); 396 out.writeEndElement(); // "resultSetId" element 397 } 398 399 // resultSetIdleTime 400 if (result.getResultSetIdleTime() > 0) { 401 out.writeStartElement(SRU_NS, "resultSetIdleTime"); 338 "SRUSearchEngine implementation returned invalid result (null)."); 339 } 340 341 try { 342 // send results 343 SRUXMLStreamWriter out = 344 createXMLStreamWriter(response.getOutputStream(), 345 request.getRecordPacking(), 346 request.getIndentResponse()); 347 348 beginResponse(out, request); 349 350 // numberOfRecords 351 out.writeStartElement(SRU_NS, "numberOfRecords"); 402 352 out.writeCharacters( 403 Integer.toString(result.getResultSetIdleTime())); 404 out.writeEndElement(); // "resultSetIdleTime" element 405 } 406 407 int position = (request.getStartRecord() > 0) 408 ? request.getStartRecord() : 1; 409 if (result.getRecordCount() > 0) { 410 final int maxPositionOffset = 411 (request.getMaximumRecords() != -1) 412 ? (position + request.getMaximumRecords() - 1) : - 1; 413 try { 414 out.writeStartElement(SRU_NS, "records"); 415 while (result.hasMoreRecords()) { 416 /* 417 * Sanity check: do not return more then the maximum 418 * requested records. If database implementation does 419 * not honor limit truncate the result set. 420 */ 421 if ((maxPositionOffset != -1) && 422 (position > maxPositionOffset)) { 423 logger.error("SRUSearchEngine implementation did not " + 424 "honor limit for the amount of requsted " + 425 "records. Result set truncated!"); 426 break; 427 } 428 429 out.writeStartElement(SRU_NS, "record"); 430 431 /* 432 * We need to output either the record or a 433 * surrogate diagnostic. In case of the latter, we need 434 * to output the appropriate record schema ... 435 */ 436 SRUDiagnostic diagnostic = result.getSurrogateDiagnostic(); 437 438 out.writeStartElement(SRU_NS, "recordSchema"); 439 if (diagnostic == null) { 440 out.writeCharacters(result.getRecordSchemaIdentifier()); 441 } else { 442 out.writeCharacters(SRU_DIAGNOSTIC_RECORD_SCHEMA); 443 } 444 out.writeEndElement(); // "recordSchema" element 445 446 // recordPacking 447 writeRecordPacking(out, request.getRecordPacking()); 448 449 /* 450 * Output either record data or surrogate diagnostic ... 451 */ 452 out.writeStartElement(SRU_NS, "recordData"); 453 out.startRecord(); 454 if (diagnostic == null) { 455 result.writeRecord(out); 456 } else { 457 // write a surrogate diagnostic 458 writeDiagnostic(out, diagnostic, true); 459 } 460 out.endRecord(); 461 out.writeEndElement(); // "recordData" element 462 463 /* 464 * recordIdentifier is version 1.2 only 465 */ 466 if (request.isVersion(SRUVersion.VERSION_1_2)) { 467 final String identifier = result.getRecordIdentifier(); 468 if (identifier != null) { 469 out.writeStartElement(SRU_NS, "recordIdentifier"); 470 out.writeCharacters(identifier); 471 out.writeEndElement(); // "recordIdentifier" element 353 Integer.toString(result.getTotalRecordCount())); 354 out.writeEndElement(); // "numberOfRecords" element 355 356 // resultSetId 357 if (result.getResultSetId() != null) { 358 out.writeStartElement(SRU_NS, "resultSetId"); 359 out.writeCharacters(result.getResultSetId()); 360 out.writeEndElement(); // "resultSetId" element 361 } 362 363 // resultSetIdleTime 364 if (result.getResultSetIdleTime() > 0) { 365 out.writeStartElement(SRU_NS, "resultSetIdleTime"); 366 out.writeCharacters(Integer.toString(result 367 .getResultSetIdleTime())); 368 out.writeEndElement(); // "resultSetIdleTime" element 369 } 370 371 int position = (request.getStartRecord() > 0) 372 ? request.getStartRecord() : 1; 373 if (result.getRecordCount() > 0) { 374 final int maxPositionOffset = 375 (request.getMaximumRecords() != -1) 376 ? (position + request.getMaximumRecords() - 1) 377 : -1; 378 try { 379 out.writeStartElement(SRU_NS, "records"); 380 while (result.nextRecord()) { 381 /* 382 * Sanity check: do not return more then the maximum 383 * requested records. If the search engine 384 * implementation does not honor limit truncate the 385 * result set. 386 */ 387 if ((maxPositionOffset != -1) && 388 (position > maxPositionOffset)) { 389 logger.error("SRUSearchEngine implementation did " + 390 "not honor limit for the amount of " + 391 "requsted records. Result set truncated!"); 392 break; 472 393 } 473 } 474 475 out.writeStartElement(SRU_NS, "recordPosition"); 476 out.writeCharacters(Integer.toString(position)); 477 out.writeEndElement(); // "recordPosition" element 478 479 if (result.hasExtraRecordData()) { 480 out.writeStartElement(SRU_NS, "extraRecordData"); 481 result.writeExtraRecordData(out); 482 out.writeEndElement(); // "extraRecordData" 483 } 484 485 out.writeEndElement(); // "record" element 486 487 result.nextRecord(); 488 position++; 394 395 out.writeStartElement(SRU_NS, "record"); 396 397 /* 398 * We need to output either the record or a surrogate 399 * diagnostic. In case of the latter, we need to output 400 * the appropriate record schema ... 401 */ 402 final SRUDiagnostic diagnostic = 403 result.getSurrogateDiagnostic(); 404 405 out.writeStartElement(SRU_NS, "recordSchema"); 406 if (diagnostic == null) { 407 out.writeCharacters( 408 result.getRecordSchemaIdentifier()); 409 } else { 410 out.writeCharacters(SRU_DIAGNOSTIC_RECORD_SCHEMA); 411 } 412 out.writeEndElement(); // "recordSchema" element 413 414 // recordPacking 415 writeRecordPacking(out, request.getRecordPacking()); 416 417 /* 418 * Output either record data or surrogate diagnostic ... 419 */ 420 out.writeStartElement(SRU_NS, "recordData"); 421 out.startRecord(); 422 if (diagnostic == null) { 423 result.writeRecord(out); 424 } else { 425 // write a surrogate diagnostic 426 writeDiagnostic(out, diagnostic, true); 427 } 428 out.endRecord(); 429 out.writeEndElement(); // "recordData" element 430 431 /* 432 * recordIdentifier is version 1.2 only 433 */ 434 if (request.isVersion(SRUVersion.VERSION_1_2)) { 435 final String identifier = 436 result.getRecordIdentifier(); 437 if (identifier != null) { 438 out.writeStartElement(SRU_NS, 439 "recordIdentifier"); 440 out.writeCharacters(identifier); 441 out.writeEndElement(); // "recordIdentifier" element 442 } 443 } 444 445 out.writeStartElement(SRU_NS, "recordPosition"); 446 out.writeCharacters(Integer.toString(position)); 447 out.writeEndElement(); // "recordPosition" element 448 449 if (result.hasExtraRecordData()) { 450 out.writeStartElement(SRU_NS, "extraRecordData"); 451 result.writeExtraRecordData(out); 452 out.writeEndElement(); // "extraRecordData" 453 } 454 455 out.writeEndElement(); // "record" element 456 457 position++; 458 } // while 459 out.writeEndElement(); // "records" element 460 } catch (NoSuchElementException e) { 461 throw new SRUException( 462 SRUConstants.SRU_GENERAL_SYSTEM_ERROR, 463 "An internal error occurred while " + 464 "serializing search result set."); 489 465 } 490 out.writeEndElement(); // "records" element 491 } catch (NoSuchElementException e) { 492 throw new SRUException(SRUConstants.SRU_GENERAL_SYSTEM_ERROR, 493 "An internal error occurred while " + 494 "serializing search result set."); 495 } 496 } 497 498 // nextRecordPosition 499 if (position <= result.getTotalRecordCount()) { 500 out.writeStartElement(SRU_NS, "nextRecordPosition"); 501 out.writeCharacters(Integer.toString(position)); 502 out.writeEndElement(); 503 } 504 505 // echoedSearchRetrieveRequest 506 if (config.getEchoRequests()) { 507 writeEchoedSearchRetrieveRequest(out, request, request.getQuery()); 508 } 509 510 // diagnostics 511 writeDiagnosticList(out, request.getDiagnostics()); 512 513 // extraResponseData 514 if (result.hasExtraResponseData()) { 515 out.writeStartElement(SRU_NS, "extraResponseData"); 516 result.writeExtraResponseData(out); 517 out.writeEndElement(); // "extraResponseData" element 518 } 519 520 endResponse(out); 466 } 467 468 // nextRecordPosition 469 if (position <= result.getTotalRecordCount()) { 470 out.writeStartElement(SRU_NS, "nextRecordPosition"); 471 out.writeCharacters(Integer.toString(position)); 472 out.writeEndElement(); 473 } 474 475 // echoedSearchRetrieveRequest 476 if (config.getEchoRequests()) { 477 writeEchoedSearchRetrieveRequest(out, request, 478 request.getQuery()); 479 } 480 481 // diagnostics 482 writeDiagnosticList(out, request.getDiagnostics()); 483 484 // extraResponseData 485 if (result.hasExtraResponseData()) { 486 out.writeStartElement(SRU_NS, "extraResponseData"); 487 result.writeExtraResponseData(out); 488 out.writeEndElement(); // "extraResponseData" element 489 } 490 491 endResponse(out); 492 } finally { 493 result.close(); 494 } 521 495 } 522 496
Note: See TracChangeset
for help on using the changeset viewer.