source: FCSSimpleClient/trunk/src/main/java/eu/clarin/sru/client/fcs/DataViewParserAdvanced.java @ 7274

Last change on this file since 7274 was 7274, checked in by Oliver Schonefeld, 2 years ago
  • update copyright
  • Property svn:eol-style set to native
File size: 8.2 KB
Line 
1/**
2 * This software is copyright (c) 2012-2022 by
3 *  - Leibniz-Institut fuer Deutsche Sprache (http://www.ids-mannheim.de)
4 * This is free software. You can redistribute it
5 * and/or modify it under the terms described in
6 * the GNU General Public License v3 of which you
7 * should have received a copy. Otherwise you can download
8 * it from
9 *
10 *   http://www.gnu.org/licenses/gpl-3.0.txt
11 *
12 * @copyright Leibniz-Institut fuer Deutsche Sprache (http://www.ids-mannheim.de)
13 *
14 * @license http://www.gnu.org/licenses/gpl-3.0.txt
15 *  GNU General Public License v3
16 */
17package eu.clarin.sru.client.fcs;
18
19import java.net.URI;
20import java.net.URISyntaxException;
21import java.util.ArrayList;
22import java.util.HashMap;
23import java.util.List;
24import java.util.Map;
25
26import javax.xml.namespace.QName;
27import javax.xml.stream.XMLStreamException;
28import javax.xml.stream.XMLStreamReader;
29
30import org.slf4j.Logger;
31import org.slf4j.LoggerFactory;
32
33import eu.clarin.sru.client.SRUClientException;
34import eu.clarin.sru.client.XmlStreamReaderUtils;
35
36
37/**
38 * An implementation of a Data View parser that parses Advanced Data Views. This
39 * parser expects input that conforms to the CLARIN-FCS specification for the
40 * Advanced Data View.
41 *
42 * @see DataViewAdvanced
43 */
44public final class DataViewParserAdvanced implements DataViewParser {
45    private static final String FCS_ADV_NS =
46            "http://clarin.eu/fcs/dataview/advanced";
47    private static final String UNIT_ITEM      = "item";
48    private static final String UNIT_TIMESTAMP = "timestamp";
49    private static final Logger logger =
50            LoggerFactory.getLogger(DataViewParserAdvanced.class);
51
52
53    @Override
54    public boolean acceptType(String type) {
55        return DataViewAdvanced.TYPE.equals(type);
56    }
57
58
59    @Override
60    public int getPriority() {
61        return 1000;
62    }
63
64
65    @Override
66    public DataView parse(XMLStreamReader reader, String type, String pid,
67            String ref) throws XMLStreamException, SRUClientException {
68        XmlStreamReaderUtils.readStart(reader, FCS_ADV_NS, "Advanced", true, true);
69        final DataViewAdvanced.Unit unit = readUnit(reader);
70        logger.debug("Advanced: unit={}", unit);
71        reader.next(); // skip start tag
72
73        // Segments
74        final Map<String, DataViewAdvanced.Segment> segments =
75                new HashMap<String, DataViewAdvanced.Segment>();
76        XmlStreamReaderUtils.readStart(reader, FCS_ADV_NS, "Segments", true);
77        while (XmlStreamReaderUtils.readStart(reader, FCS_ADV_NS, "Segment",
78                segments.isEmpty(), true)) {
79            final String id =
80                    XmlStreamReaderUtils.readAttributeValue(reader, null, "id");
81            final long start = readOffset(reader, "start", unit);
82            final long end = readOffset(reader, "end", unit);
83            final URI reference = readAttributeURI(reader, null, "ref", false);
84            if (start > end) {
85                throw new SRUClientException("invalid offsets: start > end");
86            }
87            reader.next(); // skip start element
88            XmlStreamReaderUtils.readEnd(reader, FCS_ADV_NS, "Segment");
89
90            logger.debug("segment: id={}, start={}, end={}, ref={}",
91                    id, start, end, reference);
92            DataViewAdvanced.Segment segment =
93                    new DataViewAdvanced.Segment(id, start, end, reference);
94            segments.put(id, segment);
95        } // while
96        XmlStreamReaderUtils.readEnd(reader, FCS_ADV_NS, "Segments");
97
98        // Layers
99        List<DataViewAdvanced.Layer> layers =
100                new ArrayList<DataViewAdvanced.Layer>();
101
102        XmlStreamReaderUtils.readStart(reader, FCS_ADV_NS, "Layers", true);
103        while (XmlStreamReaderUtils.readStart(reader, FCS_ADV_NS, "Layer",
104                layers.isEmpty(), true)) {
105            String id = XmlStreamReaderUtils.readAttributeValue(reader, null, "id");
106            reader.next(); // skip start element
107            logger.debug("layer: id={}", id);
108
109            final List<DataViewAdvanced.Span> spans =
110                    new ArrayList<DataViewAdvanced.Span>();
111            while (XmlStreamReaderUtils.readStart(reader, FCS_ADV_NS, "Span",
112                    spans.isEmpty(), true)) {
113                String segment_ref = XmlStreamReaderUtils.readAttributeValue(reader, null, "ref");
114                String highlight = XmlStreamReaderUtils.readAttributeValue(reader, null, "highlight", false);
115                String altValue = XmlStreamReaderUtils.readAttributeValue(reader, null, "alt-value", false);
116                reader.next(); // skip start element
117                String content = XmlStreamReaderUtils.readString(reader, false);
118                XmlStreamReaderUtils.readEnd(reader, FCS_ADV_NS, "Span");
119
120                logger.debug("span: ref={}, highlight={}, alt-value={}, content={}",
121                        segment_ref, highlight, altValue, content);
122                DataViewAdvanced.Segment segment = segments.get(segment_ref);
123                if (segment == null) {
124                    throw new XMLStreamException("No segment with id '" +
125                            segment_ref + "' found", reader.getLocation());
126                }
127                DataViewAdvanced.Span span =
128                        new DataViewAdvanced.Span(segment, highlight, altValue, content);
129                spans.add(span);
130            } // while
131            XmlStreamReaderUtils.readEnd(reader, FCS_ADV_NS, "Layer");
132
133            DataViewAdvanced.Layer layer =
134                    new DataViewAdvanced.Layer(id, spans);
135            layers.add(layer);
136        } // while
137        XmlStreamReaderUtils.readEnd(reader, FCS_ADV_NS, "Layers");
138
139        XmlStreamReaderUtils.readEnd(reader, FCS_ADV_NS, "Advanced");
140        return new DataViewAdvanced(pid, ref, unit, layers);
141    }
142
143
144    private static final DataViewAdvanced.Unit readUnit(XMLStreamReader reader)
145            throws XMLStreamException {
146
147        final String s = XmlStreamReaderUtils.readAttributeValue(reader, null,
148                "unit", true);
149        if (UNIT_ITEM.equals(s)) {
150            return DataViewAdvanced.Unit.ITEM;
151        } else if (UNIT_TIMESTAMP.equals(s)) {
152            return DataViewAdvanced.Unit.TIMESTAMP;
153        } else {
154            throw new XMLStreamException(
155                    "Attribute 'unit' may only have values '" + UNIT_ITEM +
156                            "' or '" + UNIT_TIMESTAMP + "'",
157                    reader.getLocation());
158        }
159    }
160
161
162    private static final URI readAttributeURI(XMLStreamReader reader,
163            String namespaceURI, String localName, boolean required)
164                    throws XMLStreamException, SRUClientException {
165        final String s = XmlStreamReaderUtils.readAttributeValue(reader,
166                namespaceURI, localName, required);
167        if (s != null) {
168            try {
169                return new URI(s);
170            } catch (URISyntaxException e) {
171                throw new XMLStreamException("malformed URI in attribute '" +
172                        new QName(namespaceURI, localName) + "'",
173                        reader.getLocation(), e);
174            }
175        } else {
176            return null;
177        }
178    }
179
180
181    private static final long readOffset(XMLStreamReader reader,
182            String localName, DataViewAdvanced.Unit unit)
183                    throws XMLStreamException, SRUClientException {
184        String s = XmlStreamReaderUtils.readAttributeValue(reader,
185                null, localName, true);
186        switch (unit) {
187        case ITEM:
188            try {
189                long num = Long.parseLong(s);
190                if (num < 0) {
191                    throw new XMLStreamException("offset is smaller than '0'",
192                            reader.getLocation());
193                }
194                return num;
195            } catch (NumberFormatException e) {
196                throw new XMLStreamException(
197                        "invalid number in attribute '" + localName + "'",
198                        reader.getLocation(), e);
199            }
200        case TIMESTAMP:
201            throw new SRUClientException("no support for 'timestamp' offsets, yet!");
202        default:
203            throw new SRUClientException("internal error: invalid unit (" +
204                    unit + ")");
205        }
206    }
207
208} // class DataViewParserAdvanced
Note: See TracBrowser for help on using the repository browser.