Changeset 2114


Ignore:
Timestamp:
08/17/12 11:49:47 (12 years ago)
Author:
oschonef
Message:
  • add toggle to operate client in strict SRU protocol conformance mode and a quirks mode
  • do not raise fatal errors for certain errors when running in quicks mode
File:
1 edited

Legend:

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

    r2092 r2114  
    4949/**
    5050 * A class to perform SRU operations.
    51  * <p><em>This class is not thread-safe!</em></p>
     51 * <p>This class is <em>not</em> thread-safe!</p>
    5252 */
    5353public class SRUClient {
    5454    /** constant record data schema parser to match any schema */
    5555    public static final String RECORD_DATA_PARSER_SCHEMA_ANY = "*";
     56    /** default version the client will use, if not otherwise specified */
     57    public static final SRUVersion DEFAULT_SRU_VERSION = SRUVersion.VERSION_1_2;
    5658    private static final String SRU_NS =
    5759            "http://www.loc.gov/zing/srw/";
     
    7173            new HashMap<String, SRURecordDataParser>();
    7274    private final XmlStreamReaderProxy proxy = new XmlStreamReaderProxy();
     75    private boolean strictMode;
     76
     77
     78    /**
     79     * Constructor. This constructor will create a <em>strict</em> client and
     80     * use the default SRU version.
     81     *
     82     * @see #SRUClient(SRUVersion, boolean)
     83     * @see #DEFAULT_SRU_VERSION
     84     */
     85    public SRUClient() {
     86        this(DEFAULT_SRU_VERSION, true);
     87    }
     88
     89
     90    /**
     91     * Constructor. This constructor will create a <em>strict</em> client.
     92     *
     93     * @param defaultVersion
     94     *            the default version to use for SRU requests; may be overridden
     95     *            by individual requests
     96     * @see #SRUClient(SRUVersion, boolean)
     97     */
     98    public SRUClient(SRUVersion defaultVersion) {
     99        this(defaultVersion, true);
     100    }
    73101
    74102
     
    79107     *            the default version to use for SRU requests; may be overridden
    80108     *            by individual requests
     109     * @param strictMode
     110     *            if <code>true</code> the client will strictly adhere to the
     111     *            SRU standard and raise fatal errors on violations, if
     112     *            <code>false</code> it will act more forgiving and ignore
     113     *            certain violations
     114     *
    81115     */
    82     public SRUClient(SRUVersion defaultVersion) {
     116    public SRUClient(SRUVersion defaultVersion, boolean strictMode) {
    83117        if (defaultVersion == null) {
    84118            throw new NullPointerException("version == null");
    85119        }
    86120        this.defaultVersion = defaultVersion;
     121        this.strictMode = strictMode;
    87122        this.httpClient = new DefaultHttpClient();
    88123        this.httpClient.getParams().setParameter(CoreProtocolPNames.USER_AGENT,
     
    90125    }
    91126
     127
     128    /**
     129     * Get the SRU protocol conformance mode of the client.
     130     *
     131     * @return <code>true</code> if the client operation in strict mode,
     132     *         <code>false</code> otherwise
     133     */
     134    public boolean isStrictMode() {
     135        return strictMode;
     136    }
     137
     138
     139    /**
     140     * Set the SRU protocol conformance mode of the client.
     141     *
     142     * @param strictMode
     143     *            <code>true</code> if the client should operate in strict mode,
     144     *            <code>false</code> if the client should be more tolerant
     145     */
     146    public void setStrictMode(boolean strictMode) {
     147        this.strictMode = strictMode;
     148    }
    92149
    93150    /**
     
    434491            String schema = reader.readContent(SRU_NS, "recordSchema", true);
    435492
    436             SRURecordPacking packing = parseRecordPacking(reader);
     493            SRURecordPacking packing = parseRecordPacking(reader, strictMode);
    437494
    438495            logger.debug("schema = {}, packing = {}", schema, packing);
     
    457514            if (reader.readStart(SRU_NS, "echoedExplainRequest", false)) {
    458515                reader.readEnd(SRU_NS, "echoedExplainRequest", true);
     516            }
     517
     518            /*
     519             * common error: echoedExplainRequest in default namespace
     520             */
     521            if (reader.readStart("", "echoedExplainRequest", false)) {
     522                logger.error("Element 'echoedExplainRequest' must be in SRU namespace, but endpoint put it into default namespace");
     523                if (strictMode) {
     524                    throw new SRUClientException("Element 'echoedExplainRequest' must be in SRU namespace, but endpoint put it into default namespace");
     525                }
     526                reader.readEnd("", "echoedExplainRequest", true);
    459527            }
    460528
     
    597665                }
    598666
     667                /*
     668                 * common error: echoedScanRequest in default namespace
     669                 */
     670                if (reader.readStart("", "echoedScanRequest", false)) {
     671                    logger.error("Element 'echoedScanRequest' must be in SRU namespace, but endpoint put it into default namespace");
     672                    if (strictMode) {
     673                        throw new SRUClientException("Element 'echoedScanRequest' must be in SRU namespace, but endpoint put it into default namespace");
     674                    }
     675                    reader.readEnd("", "echoedScanRequest", true);
     676                }
     677
    599678                // scanResponse/diagnostics
    600679                final List<SRUDiagnostic> diagnostics = parseDiagnostics(reader);
     
    696775                                "recordSchema", true);
    697776
    698                         SRURecordPacking packing = parseRecordPacking(reader);
     777                        SRURecordPacking packing =
     778                                parseRecordPacking(reader, strictMode);
    699779
    700780                        logger.debug("schema = {}, packing = {}, " +
     
    707787                            final SRURecordPacking p =
    708788                                    request.getRecordPacking();
    709                             logger.warn("requested '{}' record packing, but " +
     789                            logger.error("requested '{}' record packing, but " +
    710790                                "server responded with '{}' record packing",
    711791                                    p.getStringValue(),
    712792                                    packing.getStringValue());
    713                             // XXX: only throw if client is pedantic?
    714                             throw new SRUClientException("requested '" +
    715                                             p.getStringValue() +
    716                                             "' record packing, but server " +
    717                                             "responded with '" +
    718                                             packing.getStringValue() +
    719                                             "' record packing");
     793                            if (strictMode) {
     794                                throw new SRUClientException("requested '" +
     795                                        p.getStringValue() +
     796                                        "' record packing, but server " +
     797                                        "responded with '" +
     798                                        packing.getStringValue() +
     799                                        "' record packing");
     800                            }
    720801                        }
    721802
     
    815896                    } // while
    816897                    reader.readEnd(SRU_NS, "records");
     898                } else {
     899                    /*
     900                     * provide a better error format, if
     901                     */
     902                    if (reader.readStart(SRU_NS, "records", false)) {
     903                        int bad = 0;
     904                        while (reader.readStart(SRU_NS, "record", false)) {
     905                            bad++;
     906                            reader.readEnd(SRU_NS, "record", true);
     907                        }
     908                        reader.readEnd(SRU_NS, "records", true);
     909                        if (bad == 0) {
     910                            logger.error("endpoint declared 0 results, but " +
     911                                    "response contained an empty 'records' " +
     912                                    "element");
     913                            if (strictMode) {
     914                                throw new SRUClientException(
     915                                        "endpoint declared 0 results, but response contained an empty 'records' element (behavior violates SRU specification)");
     916                            }
     917                        } else {
     918                            logger.error("endpoint declared 0 results, but " +
     919                                    "response contained an " + bad +
     920                                    " record(s)");
     921                            if (strictMode) {
     922                            throw new SRUClientException("endpoint declared 0 results, but response containted " +
     923                                    bad + " records (behavior may violate SRU specification)");
     924                            }
     925                        }
     926                    }
    817927                }
    818928
     
    826936                        "echoedSearchRetrieveRequest", false)) {
    827937                    reader.readEnd(SRU_NS, "echoedSearchRetrieveRequest", true);
     938                }
     939
     940                /*
     941                 * common error: echoedSearchRetrieveRequest in default namespace
     942                 */
     943                if (reader.readStart("", "echoedSearchRetrieveRequest", false)) {
     944                    logger.error("Element 'echoedSearchRetrieveRequest' must be in SRU namespace, but endpoint put it into default namespace");
     945                    if (strictMode) {
     946                        throw new SRUClientException("Element 'echoedSearchRetrieveRequest' must be in SRU namespace, but endpoint put it into default namespace");
     947                    }
     948                    reader.readEnd("", "echoedSearchRetrieveRequest", true);
    828949                }
    829950
     
    9191040
    9201041
    921     private static SRURecordPacking parseRecordPacking(SRUXMLStreamReader reader)
     1042    private static SRURecordPacking parseRecordPacking(
     1043            SRUXMLStreamReader reader, boolean pedantic)
    9221044            throws XMLStreamException, SRUClientException {
    9231045        final String v = reader.readContent(SRU_NS, "recordPacking", true);
     
    9271049        } else if (RECORD_PACKING_STRING.equals(v)) {
    9281050            return SRURecordPacking.STRING;
     1051        } else if (!pedantic && RECORD_PACKING_XML.equalsIgnoreCase(v)) {
     1052            logger.error("invalid value '{}' for record packing, should be '{}'",
     1053                         v, RECORD_PACKING_XML);
     1054            return SRURecordPacking.XML;
     1055        } else if (!pedantic && RECORD_PACKING_STRING.equalsIgnoreCase(v)) {
     1056            logger.error("invalid value '{}' for record packing, should be '{}'",
     1057                         v, RECORD_PACKING_STRING);
     1058            return SRURecordPacking.STRING;
     1059
    9291060        } else {
    9301061            throw new SRUClientException("invalid value '" + v +
Note: See TracChangeset for help on using the changeset viewer.