Ignore:
Timestamp:
01/12/16 21:03:47 (8 years ago)
Author:
Oliver Schonefeld
Message:
  • some steps towards SRU 2.0
File:
1 edited

Legend:

Unmodified
Added
Removed
  • SRUClient/trunk/src/main/java/eu/clarin/sru/client/SRUSimpleClient.java

    r6077 r6903  
    6969    private static final String USER_AGENT = "SRU-Client/1.0.0";
    7070    /** default version the client will use, if not otherwise specified */
    71     private static final String SRU_NS =
    72             "http://www.loc.gov/zing/srw/";
    73     private static final String SRU_DIAGNOSIC_NS =
    74             "http://www.loc.gov/zing/srw/diagnostic/";
     71//    private static final String SRU_NS =
     72//            "http://www.loc.gov/zing/srw/";
     73//    private static final String SRU_DIAGNOSIC_NS =
     74//            "http://www.loc.gov/zing/srw/diagnostic/";
    7575    private static final String SRU_DIAGNOSTIC_RECORD_SCHEMA =
    7676            "info:srw/schema/1/diagnostics-v1.1";
    7777    private static final String VERSION_1_1 = "1.1";
    7878    private static final String VERSION_1_2 = "1.2";
    79     private static final String RECORD_PACKING_XML = "xml";
    80     private static final String RECORD_PACKING_STRING = "string";
     79    private static final String VERSION_2_0 = "2.0";
     80    private static final String RECORD_PACKING_PACKED = "packed";
     81    private static final String RECORD_PACKING_UNPACKED = "unpacked";
     82    private static final String RECORD_ESCAPING_XML = "xml";
     83    private static final String RECORD_ESCAPING_STRING = "string";
    8184    private static final Logger logger =
    8285            LoggerFactory.getLogger(SRUSimpleClient.class);
     
    454457        logger.debug("parsing 'explain' response (mode = {})",
    455458                (request.isStrictMode() ? "strict" : "non-strict"));
     459
     460        /* detect response namespaces */
     461        final SRUNamespaces ns =
     462                detectNamespace(reader, request.getRequestedVersion());
     463
    456464        /*
    457465         * Eventually, SRUClient should always parse explain record data.
     
    462470            logger.debug("parsing of explain record data skipped");
    463471        }
    464         doParseExplainResponse(reader, request, handler, parse);
     472        doParseExplainResponse(reader, ns, request, handler, parse);
    465473    }
    466474
    467475
    468476    private void doParseExplainResponse(SRUXMLStreamReader reader,
    469             SRUAbstractRequest request, SRUExplainHandler handler,
    470             boolean parseRecordData) throws SRUClientException {
     477            SRUNamespaces ns, SRUAbstractRequest request,
     478            SRUExplainHandler handler, boolean parseRecordData)
     479                    throws SRUClientException {
    471480        try {
    472481            final boolean strictMode = request.isStrictMode();
    473482
    474483            // explainResponse
    475             reader.readStart(SRU_NS, "explainResponse", true);
     484            reader.readStart(ns.sruNS(), "explainResponse", true);
    476485
    477486            // explainResponse/version
    478             SRUVersion version = parseVersion(reader);
     487            final SRUVersion version = parseVersion(reader, ns.sruNS());
    479488            logger.debug("version = {}, requested = {}", version,
    480489                    request.getRequestedVersion());
    481490
    482491            // explainResponse/record
    483             reader.readStart(SRU_NS, "record", true);
     492            reader.readStart(ns.sruNS(), "record", true);
    484493            if (parseRecordData) {
    485494                handler.onStartRecords(-1, null, -1);
    486495
    487                 SRURecordPacking packing = null;
    488                 if (!strictMode && reader.peekStart(SRU_NS, "recordPacking")) {
    489                     packing = parseRecordPacking(reader, false);
    490                     if (packing != null) {
     496                /*
     497                 * common error: recordEscaping / recordPacking (SRU 1.2) in
     498                 * wrong order
     499                 */
     500                SRURecordXmlEscaping recordXmlEscaping = null;
     501                if (!strictMode && reader.peekStart(ns.sruNS(), "recordPacking")) {
     502                    recordXmlEscaping = parseRecordXmlEscaping(reader, ns,
     503                            request.getRequestedVersion(), false);
     504                    if (recordXmlEscaping != null) {
    491505                        logger.error("element <recordPacking> must apperear " +
    492506                                "after element <recordSchema> within " +
     
    494508                    }
    495509                }
     510
    496511                String schema =
    497                         reader.readContent(SRU_NS, "recordSchema", true);
    498                 if (packing == null) {
    499                     packing = parseRecordPacking(reader, strictMode);
    500                 }
    501                 logger.debug("schema = {}, packing = {}", schema, packing);
     512                        reader.readContent(ns.sruNS(), "recordSchema", true);
     513
     514                // (SRU 2.0) recordPacking (optional)
     515                // XXX: what to do with it?
     516                SRURecordPacking recordPacking = null;
     517                if (version == SRUVersion.VERSION_2_0) {
     518                    recordPacking = parseRecordPacking(reader,
     519                            ns.sruNS(), strictMode);
     520                }
     521
     522                if (recordXmlEscaping == null) {
     523                    recordXmlEscaping = parseRecordXmlEscaping(reader, ns,
     524                            request.getRequestedVersion(), strictMode);
     525                }
     526                logger.debug("schema = {}, escaping = {}, packing = {}",
     527                        schema, recordXmlEscaping, recordPacking);
    502528
    503529                // explainResponse/record/recordData
    504                 reader.readStart(SRU_NS, "recordData", true);
     530                reader.readStart(ns.sruNS(), "recordData", true);
    505531                reader.consumeWhitespace();
    506532
     
    508534                SRUXMLStreamReader recordReader = null;
    509535
    510                 if (packing == SRURecordPacking.STRING) {
     536                if (recordXmlEscaping == SRURecordXmlEscaping.STRING) {
    511537                    /*
    512538                     * read content into temporary buffer and then use a new XML
     
    538564                     * string record packing
    539565                     */
    540                     if (packing == SRURecordPacking.STRING) {
     566                    if (recordXmlEscaping == SRURecordXmlEscaping.STRING) {
    541567                        recordReader.closeCompletly();
    542568                    }
     
    547573                }
    548574                reader.consumeWhitespace();
    549                 reader.readEnd(SRU_NS, "recordData", true);
     575                reader.readEnd(ns.sruNS(), "recordData", true);
    550576
    551577                if (version == SRUVersion.VERSION_1_2) {
    552                     reader.readContent(SRU_NS, "recordIdentifier", false);
    553                 }
    554                 reader.readContent(SRU_NS, "recordPosition", false, -1);
     578                    reader.readContent(ns.sruNS(), "recordIdentifier", false);
     579                }
     580                reader.readContent(ns.sruNS(), "recordPosition", false, -1);
    555581
    556582                // notify handler
    557583                handler.onRecord(null, -1, recordData);
    558584
    559                 if (reader.readStart(SRU_NS, "extraRecordData", false)) {
     585                if (reader.readStart(ns.sruNS(), "extraRecordData", false)) {
    560586                    reader.consumeWhitespace();
    561587                    proxy.reset(reader);
     
    569595                    }
    570596                    reader.consumeWhitespace();
    571                     reader.readEnd(SRU_NS, "extraRecordData", true);
     597                    reader.readEnd(ns.sruNS(), "extraRecordData", true);
    572598                }
    573599
    574600                handler.onFinishRecords(-1);
    575601
    576                 reader.readEnd(SRU_NS, "record");
     602                reader.readEnd(ns.sruNS(), "record");
    577603            } else {
    578604                /*
     
    580606                 * until <record> end tag
    581607                 */
    582                 reader.readEnd(SRU_NS, "record", true);
     608                reader.readEnd(ns.sruNS(), "record", true);
    583609            }
    584610
    585611            // explainResponse/echoedExplainRequest
    586             if (reader.readStart(SRU_NS, "echoedExplainRequest", false)) {
    587                 reader.readEnd(SRU_NS, "echoedExplainRequest", true);
     612            if (reader.readStart(ns.sruNS(), "echoedExplainRequest", false)) {
     613                reader.readEnd(ns.sruNS(), "echoedExplainRequest", true);
    588614            }
    589615
     
    604630            // explainResponse/diagnostics
    605631            final List<SRUDiagnostic> diagnostics =
    606                     parseDiagnostics(reader, strictMode);
     632                    parseDiagnostics(reader, ns, ns.scanNS(), strictMode);
    607633            if (diagnostics != null) {
    608634                handler.onDiagnostics(diagnostics);
     
    610636
    611637            // explainResponse/extraResponseData
    612             if (reader.readStart(SRU_NS, "extraResponseData", false)) {
     638            if (reader.readStart(ns.sruNS(), "extraResponseData", false)) {
    613639                reader.consumeWhitespace();
    614640                proxy.reset(reader);
     
    621647                }
    622648                reader.consumeWhitespace();
    623                 reader.readEnd(SRU_NS, "extraResponseData", true);
    624             }
    625 
    626             reader.readEnd(SRU_NS, "explainResponse");
     649                reader.readEnd(ns.sruNS(), "extraResponseData", true);
     650            }
     651
     652            reader.readEnd(ns.sruNS(), "explainResponse");
    627653        } catch (XMLStreamException e) {
    628654            throw new SRUClientException(e.getMessage(), e);
     
    635661            throws SRUClientException {
    636662        try {
     663            /* detect response namespaces */
     664            final SRUNamespaces ns =
     665                    detectNamespace(reader, request.getRequestedVersion());
     666
    637667            /*
    638668             * if the endpoint cannot determine the operation, it should create
    639669             * a explain response.
    640670             */
    641             if (reader.peekStart(SRU_NS, "explainResponse")) {
    642                 doParseExplainResponse(reader, request, new SRUExplainHandler() {
     671            if (reader.peekStart(ns.sruNS(), "explainResponse")) {
     672                doParseExplainResponse(reader, ns, request, new SRUExplainHandler() {
    643673                    @Override
    644674                    public void onRequestStatistics(int bytes, long millisTotal,
     
    691721                        (strictMode ? "strict" : "non-strict"));
    692722
    693 
    694723                // scanResponse
    695                 reader.readStart(SRU_NS, "scanResponse", true);
     724                reader.readStart(ns.scanNS(), "scanResponse", true);
    696725
    697726                // scanResponse/version
    698                 SRUVersion version = parseVersion(reader);
     727                final SRUVersion version = parseVersion(reader, ns.scanNS());
    699728                logger.debug("version = {}, requested = {}", version,
    700729                        request.getRequestedVersion());
    701730
    702731                // scanResponse/terms
    703                 if (reader.readStart(SRU_NS, "terms", false)) {
     732                if (reader.readStart(ns.scanNS(), "terms", false)) {
    704733                    boolean first = true;
    705                     while (reader.readStart(SRU_NS, "term", first)) {
     734                    while (reader.readStart(ns.scanNS(), "term", first)) {
    706735                        if (first) {
    707736                            first = false;
     
    711740                        // scanResponse/terms/value
    712741                        String value =
    713                                 reader.readContent(SRU_NS, "value", true);
     742                                reader.readContent(ns.scanNS(), "value", true);
    714743
    715744                        // scanResponse/terms/numberOfRecords
    716                         int numberOfRecords = reader.readContent(SRU_NS,
     745                        int numberOfRecords = reader.readContent(ns.scanNS(),
    717746                                "numberOfRecords", false, -1);
    718747
    719748                        // scanResponse/terms/displayTerm
    720                         String displayTerm = reader.readContent(SRU_NS,
     749                        String displayTerm = reader.readContent(ns.scanNS(),
    721750                                "displayTerm", false);
    722751
    723752                        // scanResponse/terms/whereInList
    724                         String s = reader.readContent(SRU_NS,
     753                        String s = reader.readContent(ns.scanNS(),
    725754                                "whereInList", false);
    726755                        SRUWhereInList whereInList = null;
     
    746775
    747776                        // scanResponse/terms/extraTermData
    748                         if (reader.readStart(SRU_NS, "extraTermData", first)) {
     777                        if (reader.readStart(ns.scanNS(), "extraTermData", first)) {
    749778                            reader.consumeWhitespace();
    750779                            proxy.reset(reader);
     
    757786                            }
    758787                            reader.consumeWhitespace();
    759                             reader.readEnd(SRU_NS, "extraTermData", true);
     788                            reader.readEnd(ns.scanNS(), "extraTermData", true);
    760789                        }
    761                         reader.readEnd(SRU_NS, "term", true);
     790                        reader.readEnd(ns.scanNS(), "term", true);
    762791
    763792                    } // while
    764                     reader.readEnd(SRU_NS, "terms");
     793                    reader.readEnd(ns.scanNS(), "terms");
    765794                    handler.onFinishTerms();
    766795                }
    767796
    768797                // scanResponse/echoedScanRequest
    769                 if (reader.readStart(SRU_NS, "echoedScanRequest", false)) {
    770                     reader.readEnd(SRU_NS, "echoedScanRequest", true);
     798                if (reader.readStart(ns.scanNS(), "echoedScanRequest", false)) {
     799                    reader.readEnd(ns.scanNS(), "echoedScanRequest", true);
    771800                }
    772801
     
    784813                // scanResponse/diagnostics
    785814                final List<SRUDiagnostic> diagnostics =
    786                         parseDiagnostics(reader, strictMode);
     815                        parseDiagnostics(reader, ns, ns.scanNS(), strictMode);
    787816                if (diagnostics != null) {
    788817                    handler.onDiagnostics(diagnostics);
     
    790819
    791820                // scanResponse/extraResponseData
    792                 if (reader.readStart(SRU_NS, "extraResponseData", false)) {
     821                if (reader.readStart(ns.scanNS(), "extraResponseData", false)) {
    793822                    reader.consumeWhitespace();
    794823                    proxy.reset(reader);
     
    801830                    }
    802831                    reader.consumeWhitespace();
    803                     reader.readEnd(SRU_NS, "extraResponseData", true);
    804                 }
    805 
    806                 reader.readEnd(SRU_NS, "scanResponse");
     832                    reader.readEnd(ns.scanNS(), "extraResponseData", true);
     833                }
     834
     835                reader.readEnd(ns.scanNS(), "scanResponse");
    807836            }
    808837        } catch (XMLStreamException e) {
     
    816845            final SRUSearchRetrieveHandler handler) throws SRUClientException {
    817846        try {
     847            /* detect response namespaces */
     848            final SRUNamespaces ns =
     849                    detectNamespace(reader, request.getRequestedVersion());
     850
    818851            /*
    819852             * if the endpoint cannot determine the operation, it should create
    820853             * a explain response.
    821854             */
    822             if (reader.peekStart(SRU_NS, "explainResponse")) {
    823                 doParseExplainResponse(reader, request, new SRUExplainHandler() {
     855            if (reader.peekStart(ns.sruNS(), "explainResponse")) {
     856                doParseExplainResponse(reader, ns, request, new SRUExplainHandler() {
    824857                    @Override
    825858                    public void onRequestStatistics(int bytes, long millisTotal,
     
    873906
    874907                // searchRetrieveResponse
    875                 reader.readStart(SRU_NS, "searchRetrieveResponse", true);
     908                reader.readStart(ns.sruNS(), "searchRetrieveResponse", true);
    876909
    877910                // searchRetrieveResponse/version
    878                 SRUVersion version = parseVersion(reader);
     911                final SRUVersion version = parseVersion(reader, ns.sruNS());
    879912                logger.debug("version = {}, requested = {}", version,
    880913                        request.getRequestedVersion());
    881914
    882915                // searchRetrieveResponse/numberOfRecords
    883                 int numberOfRecords = reader.readContent(SRU_NS,
     916                int numberOfRecords = reader.readContent(ns.sruNS(),
    884917                        "numberOfRecords", true, -1);
    885918
    886919                // searchRetrieveResponse/resultSetId
    887                 String resultSetId = reader.readContent(SRU_NS,
     920                String resultSetId = reader.readContent(ns.sruNS(),
    888921                        "resultSetId", false);
    889922
    890923                // searchRetrieveResponse/resultSetIdleTime
    891                 int resultSetIdleTime = reader.readContent(SRU_NS,
     924                int resultSetIdleTime = reader.readContent(ns.sruNS(),
    892925                        "resultSetIdleTime", false, -1);
    893926
     
    904937                     */
    905938                    int recordCount = 0;
    906                     if (reader.readStart(SRU_NS, "records", false)) {
     939                    if (reader.readStart(ns.sruNS(), "records", false)) {
    907940                        // searchRetrieveResponse/records/record
    908941                        boolean first = true;
    909                         while (reader.readStart(SRU_NS, "record", first)) {
     942                        while (reader.readStart(ns.sruNS(), "record", first)) {
    910943                            if (first) {
    911944                                first = false;
     
    915948
    916949                            /*
    917                              * common error: recordPacking before recordSchema
     950                             * common error: recordEscaping / recordPacking
     951                             * (SRU 1.2) in wrong order
    918952                             */
    919                             SRURecordPacking packing = null;
     953                            SRURecordXmlEscaping recordXmlEscaping = null;
    920954                            if (!strictMode &&
    921                                     reader.peekStart(SRU_NS, "recordPacking")) {
    922                                 packing = parseRecordPacking(reader, false);
    923                                 if (packing != null) {
     955                                    reader.peekStart(ns.sruNS(), "recordPacking")) {
     956                                recordXmlEscaping =
     957                                        parseRecordXmlEscaping(reader, ns,
     958                                                version, false);
     959                                if (recordXmlEscaping != null) {
    924960                                    logger.error("element <recordPacking> " +
    925961                                            "must appear after element " +
     
    928964                                }
    929965                            }
    930                             String schema = reader.readContent(SRU_NS,
     966
     967                            String schema = reader.readContent(ns.sruNS(),
    931968                                    "recordSchema", true);
    932                             if (packing == null) {
    933                                 packing = parseRecordPacking(reader, strictMode);
     969
     970                            // (SRU 2.0) recordPacking (optional)
     971                            // XXX: what to do with it?
     972                            SRURecordPacking recordPacking = null;
     973                            if (version == SRUVersion.VERSION_2_0) {
     974                                recordPacking = parseRecordPacking(reader,
     975                                        ns.sruNS(), strictMode);
    934976                            }
    935977
    936                             logger.debug("schema = {}, packing = {}, " +
     978                            if (recordXmlEscaping == null) {
     979                                recordXmlEscaping =
     980                                        parseRecordXmlEscaping(reader, ns,
     981                                                version, strictMode);
     982                            }
     983
     984                            logger.debug("schema = {}, escpaing = {}, " +
     985                                    "packing = {}, requested escaping = {}, " +
    937986                                    "requested packing = {}",
    938                                     schema, packing,
     987                                    schema, recordXmlEscaping, recordPacking,
     988                                    request.getRecordXmlEscaping(),
    939989                                    request.getRecordPacking());
    940990
    941                             if ((request.getRecordPacking() != null) &&
    942                                     (packing != request.getRecordPacking())) {
    943                                 final SRURecordPacking p =
    944                                         request.getRecordPacking();
    945                                 logger.error("requested '{}' record packing, " +
     991                            if ((request.getRecordXmlEscaping() != null) &&
     992                                    (recordXmlEscaping != request.getRecordXmlEscaping())) {
     993                                final SRURecordXmlEscaping p =
     994                                        request.getRecordXmlEscaping();
     995                                logger.error("requested '{}' record XML escaping, " +
    946996                                        "but server responded with '{}' " +
    947                                         "record packing",
     997                                        "record XML escaping",
    948998                                        p.getStringValue(),
    949                                         packing.getStringValue());
     999                                        recordXmlEscaping.getStringValue());
    9501000                                if (strictMode) {
    9511001                                    throw new SRUClientException("requested '" +
     
    9531003                                            "' record packing, but server " +
    9541004                                            "responded with '" +
    955                                             packing.getStringValue() +
     1005                                            recordXmlEscaping.getStringValue() +
    9561006                                            "' record packing");
    9571007                                }
     
    9591009
    9601010                            // searchRetrieveResponse/record/recordData
    961                             reader.readStart(SRU_NS, "recordData", true);
     1011                            reader.readStart(ns.sruNS(), "recordData", true);
    9621012                            reader.consumeWhitespace();
    9631013
     
    9661016                            SRUXMLStreamReader recordReader = null;
    9671017
    968                             if (packing == SRURecordPacking.STRING) {
     1018                            if (recordXmlEscaping == SRURecordXmlEscaping.STRING) {
    9691019                                /*
    9701020                                 * read content into temporary buffer and then
     
    9811031
    9821032                            if (SRU_DIAGNOSTIC_RECORD_SCHEMA.equals(schema)) {
    983                                 surrogate = parseDiagnostic(recordReader, true,
    984                                         strictMode);
     1033                                surrogate = parseDiagnostic(recordReader, ns,
     1034                                        true, strictMode);
    9851035                            } else {
    9861036                                SRURecordDataParser parser = findParser(schema);
     
    9981048                                         * packing
    9991049                                         */
    1000                                         if (packing == SRURecordPacking.STRING) {
     1050                                        if (recordXmlEscaping == SRURecordXmlEscaping.STRING) {
    10011051                                            recordReader.closeCompletly();
    10021052                                        }
     
    10361086
    10371087                            reader.consumeWhitespace();
    1038                             reader.readEnd(SRU_NS, "recordData", true);
     1088                            reader.readEnd(ns.sruNS(), "recordData", true);
    10391089
    10401090                            String identifier = null;
    10411091                            if (version == SRUVersion.VERSION_1_2) {
    1042                                 identifier = reader.readContent(SRU_NS,
     1092                                identifier = reader.readContent(ns.sruNS(),
    10431093                                        "recordIdentifier", false);
    10441094                            }
    10451095
    1046                             int position = reader.readContent(SRU_NS,
     1096                            int position = reader.readContent(ns.sruNS(),
    10471097                                    "recordPosition", false, -1);
    10481098
     
    10621112                            }
    10631113
    1064                             if (reader.readStart(SRU_NS,
     1114                            if (reader.readStart(ns.sruNS(),
    10651115                                    "extraRecordData", false)) {
    10661116                                reader.consumeWhitespace();
     
    10751125                                }
    10761126                                reader.consumeWhitespace();
    1077                                 reader.readEnd(SRU_NS, "extraRecordData", true);
     1127                                reader.readEnd(ns.sruNS(), "extraRecordData", true);
    10781128                            }
    10791129
    1080                             reader.readEnd(SRU_NS, "record");
     1130                            reader.readEnd(ns.sruNS(), "record");
    10811131                            recordCount++;
    10821132                        } // while
    1083                         reader.readEnd(SRU_NS, "records");
     1133                        reader.readEnd(ns.sruNS(), "records");
    10841134                    }
    10851135                    if (recordCount == 0) {
     
    10931143                     * an empty <records> element
    10941144                     */
    1095                     if (reader.readStart(SRU_NS, "records", false)) {
     1145                    if (reader.readStart(ns.sruNS(), "records", false)) {
    10961146                        int bad = 0;
    1097                         while (reader.readStart(SRU_NS, "record", false)) {
     1147                        while (reader.readStart(ns.sruNS(), "record", false)) {
    10981148                            bad++;
    1099                             reader.readEnd(SRU_NS, "record", true);
     1149                            reader.readEnd(ns.sruNS(), "record", true);
    11001150                        }
    1101                         reader.readEnd(SRU_NS, "records", true);
     1151                        reader.readEnd(ns.sruNS(), "records", true);
    11021152                        if (bad == 0) {
    11031153                            logger.error("endpoint declared 0 results, but " +
     
    11261176                }
    11271177
    1128                 int nextRecordPosition = reader.readContent(SRU_NS,
     1178                int nextRecordPosition = reader.readContent(ns.sruNS(),
    11291179                        "nextRecordPosition", false, -1);
    11301180                logger.debug("nextRecordPosition = {}", nextRecordPosition);
     
    11321182
    11331183                // searchRetrieveResponse/echoedSearchRetrieveResponse
    1134                 if (reader.readStart(SRU_NS,
     1184                if (reader.readStart(ns.sruNS(),
    11351185                        "echoedSearchRetrieveRequest", false)) {
    1136                     reader.readEnd(SRU_NS, "echoedSearchRetrieveRequest", true);
     1186                    reader.readEnd(ns.sruNS(), "echoedSearchRetrieveRequest", true);
    11371187                }
    11381188
     
    11561206                // searchRetrieveResponse/diagnostics
    11571207                final List<SRUDiagnostic> diagnostics =
    1158                         parseDiagnostics(reader, strictMode);
     1208                        parseDiagnostics(reader, ns, ns.toString(), strictMode);
    11591209                if (diagnostics != null) {
    11601210                    handler.onDiagnostics(diagnostics);
     
    11621212
    11631213                // explainResponse/extraResponseData
    1164                 if (reader.readStart(SRU_NS, "extraResponseData", false)) {
     1214                if (reader.readStart(ns.sruNS(), "extraResponseData", false)) {
    11651215                    reader.consumeWhitespace();
    11661216                    proxy.reset(reader);
     
    11721222                    }
    11731223                    reader.consumeWhitespace();
    1174                     reader.readEnd(SRU_NS, "extraResponseData", true);
    1175                 }
    1176 
    1177                 reader.readEnd(SRU_NS, "searchRetrieveResponse");
     1224                    reader.readEnd(ns.sruNS(), "extraResponseData", true);
     1225                }
     1226
     1227                if (version == SRUVersion.VERSION_2_0) {
     1228                    // SRU (2.0) arbitrary stuff
     1229                    // SRU (2.0) resultSetTTL (replaces resultSetIdleTime)
     1230                    // SRU (2.0) resultCountPrecision
     1231                    if (reader.readStart(ns.sruNS(), "resultCountPrecision", false)) {
     1232                        reader.readEnd(ns.sruNS(), "resultCountPrecision", true);
     1233                    }
     1234                    // SRU (2.0) facetedResults
     1235                    // SRU (2.0) searchResultAnalysis
     1236                }
     1237                reader.readEnd(ns.sruNS(), "searchRetrieveResponse");
    11781238            }
    11791239        } catch (XMLStreamException e) {
     
    11831243
    11841244
    1185     private static SRUVersion parseVersion(SRUXMLStreamReader reader)
    1186         throws XMLStreamException, SRUClientException {
    1187         final String v = reader.readContent(SRU_NS, "version", true);
     1245    private static SRUVersion parseVersion(SRUXMLStreamReader reader,
     1246            String envelopNs) throws XMLStreamException, SRUClientException {
     1247        final String v = reader.readContent(envelopNs, "version", true);
    11881248        if (VERSION_1_1.equals(v)) {
    11891249            return SRUVersion.VERSION_1_1;
    11901250        } else if (VERSION_1_2.equals(v)) {
    11911251            return SRUVersion.VERSION_1_2;
     1252        } else if (VERSION_2_0.equals(v)) {
     1253            return SRUVersion.VERSION_2_0;
    11921254        } else {
    11931255            throw new SRUClientException("invalid value '" + v +
     
    11991261
    12001262    private static List<SRUDiagnostic> parseDiagnostics(
    1201             SRUXMLStreamReader reader, boolean strictMode)
     1263            SRUXMLStreamReader reader, SRUNamespaces ns, String responseNs, boolean strictMode)
    12021264            throws XMLStreamException, SRUClientException {
    1203         if (reader.readStart(SRU_NS, "diagnostics", false)) {
     1265        if (reader.readStart(responseNs, "diagnostics", false)) {
    12041266            List<SRUDiagnostic> diagnostics = null;
    12051267
    12061268            SRUDiagnostic diagnostic = null;
    1207             while ((diagnostic = parseDiagnostic(reader,
     1269            while ((diagnostic = parseDiagnostic(reader, ns,
    12081270                    (diagnostics == null), strictMode)) != null) {
    12091271                if (diagnostics == null) {
     
    12121274                diagnostics.add(diagnostic);
    12131275            } // while
    1214             reader.readEnd(SRU_NS, "diagnostics");
     1276            reader.readEnd(responseNs, "diagnostics");
    12151277            return diagnostics;
    12161278        } else {
     
    12211283
    12221284    private static SRUDiagnostic parseDiagnostic(SRUXMLStreamReader reader,
    1223             boolean required, boolean strictMode) throws XMLStreamException,
     1285            SRUNamespaces ns, boolean required, boolean strictMode) throws XMLStreamException,
    12241286            SRUClientException {
    1225         if (reader.readStart(SRU_DIAGNOSIC_NS, "diagnostic", required)) {
     1287        if (reader.readStart(ns.diagnosticNS(), "diagnostic", required)) {
    12261288
    12271289            // diagnostic/uri
    1228             String uri = reader.readContent(SRU_DIAGNOSIC_NS, "uri", true);
     1290            String uri = reader.readContent(ns.diagnosticNS(), "uri", true);
    12291291
    12301292            String details = null;
     
    12321294            if (strictMode) {
    12331295                // diagnostic/details
    1234                 details = reader.readContent(SRU_DIAGNOSIC_NS, "details",
     1296                details = reader.readContent(ns.diagnosticNS(), "details",
    12351297                        false, true);
    12361298
    12371299                // diagnostic/message
    1238                 message = reader.readContent(SRU_DIAGNOSIC_NS, "message",
     1300                message = reader.readContent(ns.diagnosticNS(), "message",
    12391301                        false, true);
    12401302            } else {
     
    12431305                 * appear in any order
    12441306                 */
    1245                 if (reader.peekStart(SRU_DIAGNOSIC_NS, "details")) {
    1246                     details = reader.readContent(SRU_DIAGNOSIC_NS, "details",
     1307                if (reader.peekStart(ns.diagnosticNS(), "details")) {
     1308                    details = reader.readContent(ns.diagnosticNS(), "details",
    12471309                            false, false);
    1248                     message = reader.readContent(SRU_DIAGNOSIC_NS, "message",
     1310                    message = reader.readContent(ns.diagnosticNS(), "message",
    12491311                            false, false);
    12501312                } else {
    1251                     message = reader.readContent(SRU_DIAGNOSIC_NS, "message",
     1313                    message = reader.readContent(ns.diagnosticNS(), "message",
    12521314                            false, false);
    1253                     details = reader.readContent(SRU_DIAGNOSIC_NS, "details",
     1315                    details = reader.readContent(ns.diagnosticNS(), "details",
    12541316                            false, false);
    12551317                    if ((message != null) && (details != null)) {
     
    12721334            }
    12731335
    1274             reader.readEnd(SRU_DIAGNOSIC_NS, "diagnostic");
     1336            reader.readEnd(ns.diagnosticNS(), "diagnostic");
    12751337
    12761338            logger.debug("diagnostic: uri={}, detail={}, message={}",
     
    12841346
    12851347    private static SRURecordPacking parseRecordPacking(
    1286             SRUXMLStreamReader reader, boolean strictMode)
     1348            SRUXMLStreamReader reader, String envelopNs, boolean strictMode)
     1349                    throws XMLStreamException, SRUClientException {
     1350        final String s = reader.readContent(envelopNs, "recordPacking", false);
     1351        if (s != null) {
     1352            if (RECORD_PACKING_PACKED.equals(s)) {
     1353                return SRURecordPacking.PACKED;
     1354            } else if (RECORD_PACKING_UNPACKED.equals(s)) {
     1355                return SRURecordPacking.UNPACKED;
     1356            } else if (!strictMode && RECORD_PACKING_PACKED.equalsIgnoreCase(s)) {
     1357                logger.error("invalid value '{}' for '<recordPacking>', should be '{}'",
     1358                             s, RECORD_PACKING_PACKED);
     1359                return SRURecordPacking.PACKED;
     1360            } else if (!strictMode && RECORD_PACKING_UNPACKED.equalsIgnoreCase(s)) {
     1361                logger.error("invalid value '{}' for '<recordPacking>', should be '{}'",
     1362                             s, RECORD_PACKING_UNPACKED);
     1363                return SRURecordPacking.UNPACKED;
     1364            } else {
     1365                throw new SRUClientException("invalid value '" + s +
     1366                        "' for '<recordPacking>' (valid values are: '" +
     1367                        RECORD_PACKING_PACKED + "' and '" + RECORD_PACKING_UNPACKED +
     1368                        "')");
     1369            }
     1370        }
     1371        return null;
     1372    }
     1373
     1374
     1375    private static SRURecordXmlEscaping parseRecordXmlEscaping(
     1376            SRUXMLStreamReader reader, SRUNamespaces ns, SRUVersion version, boolean strictMode)
    12871377            throws XMLStreamException, SRUClientException {
    1288         final String v = reader.readContent(SRU_NS, "recordPacking", true);
    1289 
    1290         if (RECORD_PACKING_XML.equals(v)) {
    1291             return SRURecordPacking.XML;
    1292         } else if (RECORD_PACKING_STRING.equals(v)) {
    1293             return SRURecordPacking.STRING;
    1294         } else if (!strictMode && RECORD_PACKING_XML.equalsIgnoreCase(v)) {
    1295             logger.error("invalid value '{}' for record packing, should be '{}'",
    1296                          v, RECORD_PACKING_XML);
    1297             return SRURecordPacking.XML;
    1298         } else if (!strictMode && RECORD_PACKING_STRING.equalsIgnoreCase(v)) {
    1299             logger.error("invalid value '{}' for record packing, should be '{}'",
    1300                          v, RECORD_PACKING_STRING);
    1301             return SRURecordPacking.STRING;
    1302 
     1378
     1379        final String name = (version == SRUVersion.VERSION_2_0)
     1380                          ? "recordXMLEscaping" : "recordPacking";
     1381        final String s = reader.readContent(ns.sruNS(), name, true);
     1382
     1383        if (RECORD_ESCAPING_XML.equals(s)) {
     1384            return SRURecordXmlEscaping.XML;
     1385        } else if (RECORD_ESCAPING_STRING.equals(s)) {
     1386            return SRURecordXmlEscaping.STRING;
     1387        } else if (!strictMode && RECORD_ESCAPING_XML.equalsIgnoreCase(s)) {
     1388            logger.error("invalid value '{}' for '<{}>', should be '{}'",
     1389                         s, name, RECORD_ESCAPING_XML);
     1390            return SRURecordXmlEscaping.XML;
     1391        } else if (!strictMode && RECORD_ESCAPING_STRING.equalsIgnoreCase(s)) {
     1392            logger.error("invalid value '{}' for '<{}>', should be '{}'",
     1393                         s, name, RECORD_ESCAPING_STRING);
     1394            return SRURecordXmlEscaping.STRING;
    13031395        } else {
    1304             throw new SRUClientException("invalid value '" + v +
    1305                     "' for record packing (valid values are: '" +
    1306                     RECORD_PACKING_XML + "' and '" + RECORD_PACKING_STRING +
     1396            throw new SRUClientException("invalid value '" + s +
     1397                    "' for '<" + name + ">' (valid values are: '" +
     1398                    RECORD_ESCAPING_XML + "' and '" + RECORD_ESCAPING_STRING +
    13071399                    "')");
    13081400        }
     
    13581450    }
    13591451
     1452
     1453    private static SRUNamespaces detectNamespace(XMLStreamReader reader,
     1454            SRUVersion requestedVersion)
     1455                    throws SRUClientException {
     1456        try {
     1457            // skip to first start tag
     1458            reader.nextTag();
     1459
     1460            final String namespaceURI = reader.getNamespaceURI();
     1461            logger.debug("found namespace URI '{}', requested version = {}",
     1462                    namespaceURI, requestedVersion);
     1463
     1464            if (NAMESPACES_LEGACY_LOC.foo(namespaceURI)) {
     1465                return NAMESPACES_LEGACY_LOC;
     1466            } else if (NAMESPACES_OASIS.foo(namespaceURI)) {
     1467                return NAMESPACES_OASIS;
     1468            } else {
     1469                throw new SRUClientException(
     1470                        "invalid namespace '" + reader.getNamespaceURI() + "'");
     1471            }
     1472        } catch (XMLStreamException e) {
     1473            throw new SRUClientException("error detecting namespace", e);
     1474        }
     1475    }
     1476
     1477
     1478    private interface SRUNamespaces {
     1479        public String sruNS();
     1480
     1481        public String scanNS();
     1482
     1483        public String diagnosticNS();
     1484
     1485        public boolean foo(String namespaceURI);
     1486
     1487    } // interface SRUNamespace
     1488
     1489
     1490    private static final SRUNamespaces NAMESPACES_LEGACY_LOC = new SRUNamespaces() {
     1491        private static final String SRU_NS =
     1492                "http://www.loc.gov/zing/srw/";
     1493        private static final String SRU_DIAGNOSIC_NS =
     1494                "http://www.loc.gov/zing/srw/diagnostic/";
     1495
     1496
     1497        @Override
     1498        public String sruNS() {
     1499            return SRU_NS;
     1500        }
     1501
     1502
     1503        @Override
     1504        public String scanNS() {
     1505            return SRU_NS;
     1506        }
     1507
     1508
     1509        @Override
     1510        public String diagnosticNS() {
     1511            return SRU_DIAGNOSIC_NS;
     1512        }
     1513
     1514
     1515        @Override
     1516        public boolean foo(String namespaceURI) {
     1517            return SRU_NS.equals(namespaceURI);
     1518        }
     1519    };
     1520
     1521
     1522    private static final SRUNamespaces NAMESPACES_OASIS = new SRUNamespaces() {
     1523        private static final String SRU_NS =
     1524                "http://docs.oasis-open.org/ns/search-ws/sruResponse";
     1525        private static final String SRU_SCAN_NS =
     1526                "http://docs.oasis-open.org/ns/search-ws/scan";
     1527        private static final String SRU_DIAGNOSIC_NS =
     1528                "http://docs.oasis-open.org/ns/search-ws/diagnostic";
     1529
     1530
     1531        @Override
     1532        public String sruNS() {
     1533            return SRU_NS;
     1534        }
     1535
     1536
     1537        @Override
     1538        public String scanNS() {
     1539            return SRU_SCAN_NS;
     1540
     1541        }
     1542
     1543
     1544        @Override
     1545        public String diagnosticNS() {
     1546            return SRU_DIAGNOSIC_NS;
     1547        }
     1548
     1549
     1550        @Override
     1551        public boolean foo(String namespaceURI) {
     1552            return SRU_NS.equals(namespaceURI) || SRU_SCAN_NS.equals(namespaceURI);
     1553        }
     1554    };
     1555
    13601556} // class SRUSimpleClient
Note: See TracChangeset for help on using the changeset viewer.