Ignore:
Timestamp:
08/09/14 20:45:17 (10 years ago)
Author:
Oliver Schonefeld
Message:
  • support new FCS specification (with some backwards compatibility for old spec)

HEADS UP: not yet ready for release; needs more testing

File:
1 edited

Legend:

Unmodified
Added
Removed
  • FCSSimpleEndpoint/trunk/src/main/java/eu/clarin/sru/server/fcs/XMLStreamWriterHelper.java

    r2751 r5546  
    88 * This class provides several helper methods for writing records in the
    99 * CLARIN-FCS record schema. These methods <em>do not</em> cover the full
    10  * spectrum of all variations of records that are permitted by the CLARIN FCS
     10 * spectrum of all variations of records that are permitted by the CLARIN-FCS
    1111 * specification.
    1212 *
    1313 * @see <a
    14  *      href="https://trac.clarin.eu/wiki/FCS-specification#SearchRetrieveOperation">
    15  *      CLARIN FCS specification, section "SearchRetrieve Operation"</a>
     14 *      href="https://trac.clarin.eu/wiki/FCS/Specification">
     15 *      CLARIN FCS specification, section "Operation searchRetrieve"</a>
    1616 */
    1717public final class XMLStreamWriterHelper {
     
    2323    private static final String FCS_KWIC_MIMETYPE =
    2424            "application/x-clarin-fcs-kwic+xml";
     25    private static final String FCS_HITS_NS =
     26            "http://clarin.eu/fcs/dataview/hits";
     27    private static final String FCS_HITS_PREFIX = "hits";
     28    private static final String FCS_HITS_MIMETYPE =
     29            "application/x-clarin-fcs-hits+xml";
    2530
    2631
     
    205210     * @throws XMLStreamException
    206211     *             if an error occurred
    207      */
     212     * @deprecated The the HITS data view instead.
     213     */
     214    @Deprecated
    208215    public static void writeKWICDataView(XMLStreamWriter writer, String left,
    209216            String keyword, String right) throws XMLStreamException {
    210217        if (writer == null) {
    211218            throw new NullPointerException("writer == null");
     219        }
     220        if (keyword == null) {
     221            throw new NullPointerException("keyword == null");
    212222        }
    213223
     
    246256     * Convince method for writing a record with a KWIC data view. The following
    247257     * code (arguments omitted) would accomplish the same result:
     258     *
    248259     * <pre>
    249260     * ...
     
    272283     * @throws XMLStreamException
    273284     *             if an error occurred
    274      */
     285     * @deprecated The the HITS data view instead.
     286     */
     287    @Deprecated
    275288    public static void writeResourceWithKWICDataView(XMLStreamWriter writer,
    276289            String pid, String ref, String left, String keyword, String right)
     
    285298    }
    286299
     300
     301
     302    /**
     303     * Convince method to write a simple HITS data view. It automatically
     304     * performs the calls to
     305     * {@link #writeStartDataView(XMLStreamWriter, String)} and
     306     * {@link #writeEndDataView(XMLStreamWriter)}.
     307     *
     308     * @param writer
     309     *            the {@link XMLStreamWriter} to be used
     310     * @param left
     311     *            the left context of the hit or <code>null</code> if not
     312     *            applicable
     313     * @param hit
     314     *            the actual hit, that will be highlighted
     315     * @param right
     316     *            the right context of the hit or <code>null</code> if not
     317     *            applicable
     318     * @throws XMLStreamException
     319     *             if an error occurred
     320     */
     321    public static void writeHitsDataView(XMLStreamWriter writer, String left,
     322            String hit, String right) throws XMLStreamException {
     323        if (writer == null) {
     324            throw new NullPointerException("writer == null");
     325        }
     326        if (hit == null) {
     327            throw new NullPointerException("hit == null");
     328        }
     329
     330        writeStartDataView(writer, FCS_HITS_MIMETYPE);
     331
     332        // actual "hits" data view
     333        writer.setPrefix(FCS_HITS_PREFIX, FCS_HITS_NS);
     334        writer.writeStartElement(FCS_HITS_NS, "Result");
     335        writer.writeNamespace(FCS_HITS_PREFIX, FCS_HITS_NS);
     336
     337        if ((left != null) && !left.isEmpty()) {
     338            writer.writeCharacters(left);
     339        }
     340
     341        writer.writeStartElement(FCS_HITS_NS, "Hit");
     342        writer.writeCharacters(hit);
     343        writer.writeEndElement(); // "Hit" element
     344
     345        if ((right != null) && !right.isEmpty()) {
     346            writer.writeCharacters(right);
     347        }
     348
     349        writer.writeEndElement(); // "Result" element
     350
     351        writeEndDataView(writer);
     352    }
     353
     354
     355    /**
     356     * Convince method for writing a record with a KWIC data view. The following
     357     * code (arguments omitted) would accomplish the same result:
     358     *
     359     * <pre>
     360     * ...
     361     * writeStartResource(...);
     362     * writeHitsDataView(...);
     363     * writeEndResource(...);
     364     * ...
     365     * </pre>
     366     *
     367     * @param writer
     368     *            the {@link XMLStreamWriter} to be used
     369     * @param pid
     370     *            the persistent identifier of this resource or
     371     *            <code>null</code>, if not applicable
     372     * @param ref
     373     *            the reference of this resource or <code>null</code>, if not
     374     *            applicable
     375     * @param left
     376     *            the left context of the hit or <code>null</code> if not
     377     *            applicable
     378     * @param hit
     379     *            the actual hit, that will be highlighted
     380     * @param right
     381     *            the right context of the hit or <code>null</code> if not
     382     *            applicable
     383     * @throws XMLStreamException
     384     *             if an error occurred
     385     */
     386    public static void writeResourceWithHitsDataView(XMLStreamWriter writer,
     387            String pid, String ref, String left, String hit, String right)
     388            throws XMLStreamException {
     389        if (writer == null) {
     390            throw new NullPointerException("writer == null");
     391        }
     392
     393        writeStartResource(writer, pid, ref);
     394        writeHitsDataView(writer, left, hit, right);
     395        writeEndResource(writer);
     396    }
     397
     398
     399    /**
     400     * Convince method to write a simple HITS data view. It automatically
     401     * performs the calls to
     402     * {@link #writeStartDataView(XMLStreamWriter, String)} and
     403     * {@link #writeEndDataView(XMLStreamWriter)}.
     404     *
     405     * @param writer
     406     *            the {@link XMLStreamWriter} to be used
     407     * @param text
     408     *            the text content of the hit
     409     * @param hits
     410     *            an even-element array containing tuples for the hit markers in
     411     *            the text content
     412     * @param secondIsLength
     413     *            if <code>true</code> the second element of each tuple in this
     414     *            <code>hits</code> array is interpreted as an length; if
     415     *            <code>false</code> it is interpreted as an end-offset
     416     * @throws XMLStreamException
     417     *             if an error occurred
     418     */
     419    public static void writeHitsDataView(XMLStreamWriter writer, String text,
     420            int[] hits, boolean secondIsLength) throws XMLStreamException {
     421        if (writer == null) {
     422            throw new NullPointerException("writer == null");
     423        }
     424        if (text == null) {
     425            throw new NullPointerException("text == null");
     426        }
     427        if (hits == null) {
     428            throw new NullPointerException("text == null");
     429        }
     430        if ((hits.length == 0) || ((hits.length % 2) != 0)) {
     431            throw new NullPointerException("length of hits array must " +
     432                    "contain an even number of elements");
     433        }
     434
     435        writeStartDataView(writer, FCS_HITS_MIMETYPE);
     436
     437        // actual "hits" data view
     438        writer.setPrefix(FCS_HITS_PREFIX, FCS_HITS_NS);
     439        writer.writeStartElement(FCS_HITS_NS, "Result");
     440        writer.writeNamespace(FCS_HITS_PREFIX, FCS_HITS_NS);
     441
     442        int pos = 0;
     443        for (int i = 0; i < hits.length; i += 2) {
     444            int start  = hits[i];
     445            int end    = hits[i + 1];
     446
     447            if ((start < 0) && (start > text.length())) {
     448                throw new IllegalArgumentException("start index out of " +
     449                        "bounds: start=" + start);
     450            }
     451            if (secondIsLength) {
     452                if (end < 1) {
     453                    throw new IllegalArgumentException(
     454                            "length must be larger than 0: length = " + end);
     455                }
     456                end += start;
     457            }
     458            if (start >= end) {
     459                throw new IllegalArgumentException("end offset must be " +
     460                        "larger then start offset: start=" + start +
     461                        ", end="+ end);
     462            }
     463
     464            if (start > pos) {
     465                String s = text.substring(pos, start);
     466                writer.writeCharacters(s);
     467            }
     468            writer.writeStartElement(FCS_HITS_NS, "Hit");
     469            writer.writeCharacters(text.substring(start, end));
     470            writer.writeEndElement(); // "Hits" element
     471            pos = end;
     472        }
     473        if (pos < text.length() - 1) {
     474            writer.writeCharacters(text.substring(pos));
     475        }
     476
     477        writer.writeEndElement(); // "Result" element
     478
     479        writeEndDataView(writer);
     480    }
     481
     482
     483    /**
     484     * Convince method to write a simple HITS data view. It automatically
     485     * performs the calls to
     486     * {@link #writeStartDataView(XMLStreamWriter, String)} and
     487     * {@link #writeEndDataView(XMLStreamWriter)}.
     488     *
     489     * <pre>
     490     * ...
     491     * writeStartResource(...);
     492     * writeHitsDataView(...);
     493     * writeEndResource(...);
     494     * ...
     495     * </pre>
     496     *
     497     * @param writer
     498     *            the {@link XMLStreamWriter} to be used
     499     * @param pid
     500     *            the persistent identifier of this resource or
     501     *            <code>null</code>, if not applicable
     502     * @param ref
     503     *            the reference of this resource or <code>null</code>, if not
     504     *            applicable
     505     * @param text
     506     *            the text content of the hit
     507     * @param hits
     508     *            an even-element array containing tuples for the hit markers in
     509     *            the text content
     510     * @param secondIsLength
     511     *            if <code>true</code> the second element of each tuple in this
     512     *            <code>hits</code> array is interpreted as an length; if
     513     *            <code>false</code> it is interpreted as an end-offset
     514     * @throws XMLStreamException
     515     *             if an error occurred
     516     */
     517    public static void writeResourceWithHitsDataView(XMLStreamWriter writer,
     518            String pid, String ref, String text,
     519            int[] hits, boolean secondIsLength)
     520            throws XMLStreamException {
     521        if (writer == null) {
     522            throw new NullPointerException("writer == null");
     523        }
     524
     525        writeStartResource(writer, pid, ref);
     526        writeHitsDataView(writer, text, hits, secondIsLength);
     527        writeEndResource(writer);
     528    }
     529
    287530} // class XMLStreamWriterHelper
Note: See TracChangeset for help on using the changeset viewer.