Changeset 1989


Ignore:
Timestamp:
06/15/12 13:39:00 (12 years ago)
Author:
oschonef
Message:
  • conform to SRU spec when generating fatal diagnostic
  • minor clenaups
File:
1 edited

Legend:

Unmodified
Added
Removed
  • SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRUServer.java

    r1968 r1989  
    183183                    SRUXMLStreamWriter out =
    184184                        createXMLStreamWriter(response.getOutputStream(),
    185                                 SRURecordPacking.XML, getIndent(req));
     185                                SRURecordPacking.XML, req.getIndentResponse());
    186186                    writeFatalError(out, req, req.getDiagnostics());
    187187                }
     
    208208                    SRUXMLStreamWriter out =
    209209                            createXMLStreamWriter(response.getOutputStream(),
    210                                     SRURecordPacking.XML, getIndent(req));
     210                                    SRURecordPacking.XML,
     211                                    req.getIndentResponse());
    211212                    writeFatalError(out, req, diagnostics);
    212213                } catch (Exception ex) {
     
    234235                createXMLStreamWriter(response.getOutputStream(),
    235236                                      request.getRecordPacking(),
    236                                       getIndent(request));
     237                                      request.getIndentResponse());
    237238
    238239        beginResponse(out, request);
    239240
     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) {
     253            if (result.hasExtraResponseData()) {
     254                out.writeStartElement(SRU_NS, "extraResponseData");
     255                result.writeExtraResponseData(out);
     256                out.writeEndElement(); // "extraResponseData" element
     257            }
     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);
     359    }
     360
     361
     362    private void search(SRURequestImpl request, HttpServletResponse response)
     363            throws IOException, XMLStreamException, SRUException {
     364        logger.info("searchRetrieve: query = \"{}\", startRecord = {}, " +
     365                "maximumRecords = {}, recordSchema = {}, resultSetTTL = {}",
     366                new Object[] { request.getRawQuery(), request.getStartRecord(),
     367                        request.getMaximumRecords(),
     368                        request.getRecordSchemaIdentifier(),
     369                        request.getResultSetTTL() });
     370
     371        // commence search ...
     372        final SRUSearchResultSet result = searchEngine.search(config,
     373                request, request);
     374        if (result == null) {
     375            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");
     402            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
     472                        }
     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++;
     489                }
     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);
     521    }
     522
     523
     524    private void beginResponse(SRUXMLStreamWriter out, SRUOperation operation,
     525            SRUVersion version, String stylesheet) throws XMLStreamException {
     526        out.writeStartDocument("utf-8", "1.0");
     527
     528        if (stylesheet != null) {
     529            StringBuilder param = new StringBuilder();
     530            param.append("type=\"text/xsl\"");
     531            param.append(" ");
     532            param.append("href=\"");
     533            param.append(stylesheet);
     534            param.append("\"");
     535            out.writeProcessingInstruction("xml-stylesheet", param.toString());
     536        }
     537
     538        out.setPrefix(SRU_PREFIX, SRU_NS);
     539        switch (operation) {
     540        case EXPLAIN:
     541            out.writeStartElement(SRU_NS, "explainResponse");
     542            break;
     543        case SCAN:
     544            out.writeStartElement(SRU_NS, "scanResponse");
     545            break;
     546        case SEARCH_RETRIEVE:
     547            out.writeStartElement(SRU_NS, "searchRetrieveResponse");
     548            break;
     549        }
     550        out.writeNamespace(SRU_PREFIX, SRU_NS);
     551
     552        // version
     553        writeVersion(out, version);
     554    }
     555
     556
     557    private void beginResponse(SRUXMLStreamWriter out, SRURequest request)
     558            throws XMLStreamException {
     559        beginResponse(out, request.getOperation(), request.getVersion(),
     560                request.getStylesheet());
     561    }
     562
     563
     564    private void endResponse(SRUXMLStreamWriter out)
     565            throws XMLStreamException {
     566        out.writeEndElement(); // "root" element
     567
     568        out.writeEndDocument();
     569        out.close();
     570        try {
     571            out.getWriter().close();
     572        } catch (IOException e) {
     573            /* IGNORE */
     574        }
     575    }
     576
     577
     578    private void writeFatalError(SRUXMLStreamWriter out,
     579            SRURequestImpl request, List<SRUDiagnostic> diagnotics)
     580            throws XMLStreamException {
     581        /*
     582         * if operation is unknown, default to 'explain'
     583         */
     584        SRUOperation operation = request.getOperation();
     585        if (operation == null) {
     586            operation = SRUOperation.EXPLAIN;
     587        }
     588        SRUVersion version = request.getVersion();
     589        if (version == null) {
     590            version = config.getDefaultVersion();
     591        }
     592        /*
     593         * write a response which conforms to the schema
     594         */
     595        beginResponse(out, operation, version, null);
     596        switch (operation) {
     597        case EXPLAIN:
     598            // 'explain' requires a complete explain record ...
     599            writeExplainRecord(out, request);
     600            break;
     601        case SCAN:
     602            // 'scan' fortunately does not need any elements ...
     603            break;
     604        case SEARCH_RETRIEVE:
     605            // 'searchRetrieve' needs numberOfRecords ..
     606            out.writeStartElement(SRU_NS, "numberOfRecords");
     607            out.writeCharacters("0");
     608            out.writeEndElement(); // "numberOfRecords" element
     609            break;
     610        }
     611        writeDiagnosticList(out, diagnotics);
     612        endResponse(out);
     613    }
     614
     615
     616    private void writeDiagnosticList(SRUXMLStreamWriter out,
     617            List<SRUDiagnostic> diagnostics) throws XMLStreamException {
     618        if ((diagnostics != null) && !diagnostics.isEmpty()) {
     619            out.setPrefix(SRU_DIAGNOSTIC_PREFIX, SRU_DIAGNOSIC_NS);
     620            out.writeStartElement(SRU_NS, "diagnostics");
     621            out.writeNamespace(SRU_DIAGNOSTIC_PREFIX, SRU_DIAGNOSIC_NS);
     622            for (SRUDiagnostic diagnostic : diagnostics) {
     623                writeDiagnostic(out, diagnostic, false);
     624            }
     625            out.writeEndElement(); // "diagnostics" element
     626        }
     627    }
     628
     629
     630    private void writeExplainRecord(SRUXMLStreamWriter out,
     631            SRURequestImpl request) throws XMLStreamException {
    240632        out.writeStartElement(SRU_NS, "record");
    241633
     
    392784        out.writeEndElement(); // "recordData" element
    393785        out.writeEndElement(); // "record" element
    394 
    395         if (config.getEchoRequests()) {
    396             writeEchoedExplainRequest(out, request);
    397         }
    398 
    399         // diagnostics
    400         writeDiagnosticList(out, request.getDiagnostics());
    401 
    402         // extraResponseData
    403         if (result != null) {
    404             if (result.hasExtraResponseData()) {
    405                 out.writeStartElement(SRU_NS, "extraResponseData");
    406                 result.writeExtraResponseData(out);
    407                 out.writeEndElement(); // "extraResponseData" element
    408             }
    409         }
    410 
    411         endResponse(out);
    412     }
    413 
    414 
    415     private void scan(SRURequestImpl request, HttpServletResponse response)
    416             throws IOException, XMLStreamException, SRUException {
    417         logger.info("scan: scanClause = \"{}\"",
    418                 new Object[] { request.getRawScanClause() });
    419 
    420         // commence scan
    421         final SRUScanResultSet result = searchEngine.scan(config,
    422                 request, request);
    423         if (result == null) {
    424             throw new SRUException(SRUConstants.SRU_UNSUPPORTED_OPERATION,
    425                     "The 'scan' operation is not supported by this endpoint.");
    426         }
    427 
    428         // send results
    429         SRUXMLStreamWriter out =
    430                 createXMLStreamWriter(response.getOutputStream(),
    431                                       request.getRecordPacking(),
    432                                       getIndent(request));
    433 
    434         beginResponse(out, request);
    435 
    436         try {
    437             out.writeStartElement(SRU_NS, "terms");
    438             while (result.hasMoreTerms()) {
    439                 out.writeStartElement(SRU_NS, "term");
    440 
    441                 out.writeStartElement(SRU_NS, "value");
    442                 out.writeCharacters(result.getValue());
    443                 out.writeEndElement(); // "value" element
    444 
    445                 if (result.getNumberOfRecords() > -1) {
    446                     out.writeStartElement(SRU_NS, "numberOfRecords");
    447                     out.writeCharacters(
    448                             Integer.toString(result.getNumberOfRecords()));
    449                     out.writeEndElement(); // "numberOfRecords" element
    450                 }
    451 
    452                 if (result.getDisplayTerm() != null) {
    453                     out.writeStartElement(SRU_NS, "displayTerm");
    454                     out.writeCharacters(result.getDisplayTerm());
    455                     out.writeEndElement(); // "displayTerm" element
    456                 }
    457 
    458                 if (result.getWhereInList() != null) {
    459                     out.writeStartElement(SRU_NS, "whereInList");
    460                     switch (result.getWhereInList()) {
    461                     case FIRST:
    462                         out.writeCharacters("first");
    463                         break;
    464                     case LAST:
    465                         out.writeCharacters("last");
    466                         break;
    467                     case ONLY:
    468                         out.writeCharacters("only");
    469                         break;
    470                     case INNER:
    471                         out.writeCharacters("inner");
    472                         break;
    473                     } // switch
    474                     out.writeEndElement(); // "whereInList" element
    475                 }
    476 
    477                 if (result.hasExtraTermData()) {
    478                     out.writeStartElement(SRU_NS, "extraTermData");
    479                     result.writeExtraTermData(out);
    480                     out.writeEndElement(); // "extraTermData" element
    481                 }
    482 
    483                 out.writeEndElement(); // "term" element
    484 
    485                 result.nextTerm();
    486             }
    487             out.writeEndElement(); // "terms" element
    488         } catch (NoSuchElementException e) {
    489             throw new SRUException(SRUConstants.SRU_GENERAL_SYSTEM_ERROR,
    490                     "An internal error occurred while " +
    491                     "serializing scan results.");
    492         }
    493 
    494         // echoedScanRequest
    495         if (config.getEchoRequests()) {
    496             writeEchoedScanRequest(out, request, request.getScanClause());
    497         }
    498 
    499         // diagnostics
    500         writeDiagnosticList(out, request.getDiagnostics());
    501 
    502         // extraResponseData
    503         if (result.hasExtraResponseData()) {
    504             out.writeStartElement(SRU_NS, "extraResponseData");
    505             result.writeExtraResponseData(out);
    506             out.writeEndElement(); // "extraResponseData" element
    507         }
    508 
    509         endResponse(out);
    510     }
    511 
    512 
    513     private void search(SRURequestImpl request, HttpServletResponse response)
    514             throws IOException, XMLStreamException, SRUException {
    515         logger.info("searchRetrieve: query = \"{}\", startRecord = {}, " +
    516                 "maximumRecords = {}, recordSchema = {}, resultSetTTL = {}",
    517                 new Object[] { request.getRawQuery(), request.getStartRecord(),
    518                         request.getMaximumRecords(),
    519                         request.getRecordSchemaIdentifier(),
    520                         request.getResultSetTTL() });
    521 
    522         // commence search ...
    523         final SRUSearchResultSet result = searchEngine.search(config,
    524                 request, request);
    525         if (result == null) {
    526             throw new SRUException(SRUConstants.SRU_GENERAL_SYSTEM_ERROR,
    527                     "Database implementation returned invalid result (null).");
    528         }
    529 
    530         // send results
    531         SRUXMLStreamWriter out =
    532                 createXMLStreamWriter(response.getOutputStream(),
    533                                       request.getRecordPacking(),
    534                                       getIndent(request));
    535 
    536         beginResponse(out, request);
    537 
    538         // numberOfRecords
    539         out.writeStartElement(SRU_NS, "numberOfRecords");
    540         out.writeCharacters(Integer.toString(result.getTotalRecordCount()));
    541         out.writeEndElement(); // "numberOfRecords" element
    542 
    543         // resultSetId
    544         if (result.getResultSetId() != null) {
    545             out.writeStartElement(SRU_NS, "resultSetId");
    546             out.writeCharacters(result.getResultSetId());
    547             out.writeEndElement(); // "resultSetId" element
    548         }
    549 
    550         // resultSetIdleTime
    551         if (result.getResultSetIdleTime() > 0) {
    552             out.writeStartElement(SRU_NS, "resultSetIdleTime");
    553             out.writeCharacters(
    554                     Integer.toString(result.getResultSetIdleTime()));
    555             out.writeEndElement();  // "resultSetIdleTime" element
    556         }
    557 
    558         int position = (request.getStartRecord() > 0)
    559                      ? request.getStartRecord() : 1;
    560         if (result.getRecordCount() > 0) {
    561             final int maxPositionOffset =
    562                     (request.getMaximumRecords() != -1)
    563                     ? (position + request.getMaximumRecords() - 1) : - 1;
    564             try {
    565                 out.writeStartElement(SRU_NS, "records");
    566                 while (result.hasMoreRecords()) {
    567                     /*
    568                      * Sanity check: do not return more then the maximum
    569                      * requested records. If database implementation does
    570                      * not honor limit truncate the result set.
    571                      */
    572                     if ((maxPositionOffset != -1) &&
    573                             (position > maxPositionOffset)) {
    574                         logger.error("SRUSearchEngine implementation did not " +
    575                                 "honor limit for the amount of requsted " +
    576                                 "records. Result set truncated!");
    577                         break;
    578                     }
    579 
    580                     out.writeStartElement(SRU_NS, "record");
    581 
    582                     /*
    583                      *  We need to output either the record or a
    584                      *  surrogate diagnostic. In case of the latter, we need
    585                      *  to output the appropriate record schema ...
    586                      */
    587                     SRUDiagnostic diagnostic = result.getSurrogateDiagnostic();
    588 
    589                     out.writeStartElement(SRU_NS, "recordSchema");
    590                     if (diagnostic == null) {
    591                         out.writeCharacters(result.getRecordSchemaIdentifier());
    592                     } else {
    593                         out.writeCharacters(SRU_DIAGNOSTIC_RECORD_SCHEMA);
    594                     }
    595                     out.writeEndElement(); // "recordSchema" element
    596 
    597                     // recordPacking
    598                     writeRecordPacking(out, request.getRecordPacking());
    599 
    600                     /*
    601                      * Output either record data or surrogate diagnostic ...
    602                      */
    603                     out.writeStartElement(SRU_NS, "recordData");
    604                     out.startRecord();
    605                     if (diagnostic == null) {
    606                         result.writeRecord(out);
    607                     } else {
    608                         writeSurrogateDiagnostic(out, diagnostic);
    609                     }
    610                     out.endRecord();
    611                     out.writeEndElement(); // "recordData" element
    612 
    613                     /*
    614                      * recordIdentifier is version 1.2 only
    615                      */
    616                     if (request.isVersion(SRUVersion.VERSION_1_2)) {
    617                         final String identifier = result.getRecordIdentifier();
    618                         if (identifier != null) {
    619                             out.writeStartElement(SRU_NS, "recordIdentifier");
    620                             out.writeCharacters(identifier);
    621                             out.writeEndElement(); // "recordIdentifier" element
    622                         }
    623                     }
    624 
    625                     out.writeStartElement(SRU_NS, "recordPosition");
    626                     out.writeCharacters(Integer.toString(position));
    627                     out.writeEndElement(); // "recordPosition" element
    628 
    629                     if (result.hasExtraRecordData()) {
    630                         out.writeStartElement(SRU_NS, "extraRecordData");
    631                         result.writeExtraRecordData(out);
    632                         out.writeEndElement(); // "extraRecordData"
    633                     }
    634 
    635                     out.writeEndElement(); // "record" element
    636 
    637                     result.nextRecord();
    638                     position++;
    639                 }
    640                 out.writeEndElement(); // "records" element
    641             } catch (NoSuchElementException e) {
    642                 throw new SRUException(SRUConstants.SRU_GENERAL_SYSTEM_ERROR,
    643                         "An internal error occurred while " +
    644                         "serializing search result set.");
    645             }
    646         }
    647 
    648         // nextRecordPosition
    649         if (position <= result.getTotalRecordCount()) {
    650             out.writeStartElement(SRU_NS, "nextRecordPosition");
    651             out.writeCharacters(Integer.toString(position));
    652             out.writeEndElement();
    653         }
    654 
    655         // echoedSearchRetrieveRequest
    656         if (config.getEchoRequests()) {
    657             writeEchoedSearchRetrieveRequest(out, request, request.getQuery());
    658         }
    659 
    660         // diagnostics
    661         writeDiagnosticList(out, request.getDiagnostics());
    662 
    663         // extraResponseData
    664         if (result.hasExtraResponseData()) {
    665             out.writeStartElement(SRU_NS, "extraResponseData");
    666             result.writeExtraResponseData(out);
    667             out.writeEndElement(); // "extraResponseData" element
    668         }
    669 
    670         endResponse(out);
    671     }
    672 
    673 
    674     private void beginResponse(SRUXMLStreamWriter out, SRUOperation operation,
    675             SRUVersion version, String stylesheet) throws XMLStreamException {
    676         out.writeStartDocument("utf-8", "1.0");
    677 
    678         if (stylesheet != null) {
    679             StringBuilder param = new StringBuilder();
    680             param.append("type=\"text/xsl\"");
    681             param.append(" ");
    682             param.append("href=\"");
    683             param.append(stylesheet);
    684             param.append("\"");
    685             out.writeProcessingInstruction("xml-stylesheet", param.toString());
    686         }
    687 
    688         out.setPrefix(SRU_PREFIX, SRU_NS);
    689         switch (operation) {
    690         case EXPLAIN:
    691             out.writeStartElement(SRU_NS, "explainResponse");
    692             break;
    693         case SCAN:
    694             out.writeStartElement(SRU_NS, "scanResponse");
    695             break;
    696         case SEARCH_RETRIEVE:
    697             out.writeStartElement(SRU_NS, "searchRetrieveResponse");
    698             break;
    699         }
    700         out.writeNamespace(SRU_PREFIX, SRU_NS);
    701 
    702         // version
    703         writeVersion(out, version);
    704     }
    705 
    706 
    707     private void beginResponse(SRUXMLStreamWriter out, SRURequest request)
    708             throws XMLStreamException {
    709         beginResponse(out, request.getOperation(), request.getVersion(),
    710                 request.getStylesheet());
    711     }
    712 
    713 
    714     private void endResponse(SRUXMLStreamWriter out)
    715             throws XMLStreamException {
    716         out.writeEndElement(); // "root" element
    717 
    718         out.writeEndDocument();
    719         out.close();
    720         try {
    721             out.getWriter().close();
    722         } catch (IOException e) {
    723             /* IGNORE */
    724         }
    725     }
    726 
    727 
    728     private void writeFatalError(SRUXMLStreamWriter out, SRURequest req,
    729             List<SRUDiagnostic> diagnotics) throws XMLStreamException {
    730         SRUOperation operation = req.getOperation();
    731         if (operation == null) {
    732             operation = SRUOperation.SEARCH_RETRIEVE;
    733         }
    734         SRUVersion version = req.getVersion();
    735         if (version == null) {
    736             version = config.getDefaultVersion();
    737         }
    738         beginResponse(out, operation, version, null);
    739         writeDiagnosticList(out, diagnotics);
    740         endResponse(out);
    741     }
    742 
    743 
    744     private void writeDiagnosticList(SRUXMLStreamWriter out,
    745             List<SRUDiagnostic> diagnostics) throws XMLStreamException {
    746         if ((diagnostics != null) && !diagnostics.isEmpty()) {
    747             out.setPrefix(SRU_DIAGNOSTIC_PREFIX, SRU_DIAGNOSIC_NS);
    748             out.writeStartElement(SRU_NS, "diagnostics");
    749             out.writeNamespace(SRU_DIAGNOSTIC_PREFIX, SRU_DIAGNOSIC_NS);
    750             for (SRUDiagnostic diagnostic : diagnostics) {
    751                 writeDiagnostic(out, diagnostic, false);
    752             }
    753             out.writeEndElement(); // "diagnostics" element
    754         }
    755     }
    756 
    757 
    758     private void writeSurrogateDiagnostic(SRUXMLStreamWriter out,
    759             SRUDiagnostic diagnostic) throws XMLStreamException {
    760         writeDiagnostic(out, diagnostic, true);
    761786    }
    762787
     
    10361061    }
    10371062
    1038 
    1039     private int getIndent(SRURequestImpl request) {
    1040         return request.getIndentResponse();
    1041     }
    1042 
    10431063} // class SRUService
Note: See TracChangeset for help on using the changeset viewer.