source: SRUClient/tags/SRUClient-0.9.5/src/main/java/eu/clarin/sru/client/fcs/AbstractClarinFCSRecordDataParser.java @ 6079

Last change on this file since 6079 was 6079, checked in by Oliver Schonefeld, 9 years ago
  • tag version 0.9.5
  • Property svn:eol-style set to native
File size: 7.6 KB
Line 
1/**
2 * This software is copyright (c) 2012-2014 by
3 *  - 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 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.util.ArrayList;
20import java.util.Collections;
21import java.util.LinkedList;
22import java.util.List;
23
24import javax.xml.stream.XMLStreamException;
25import javax.xml.stream.XMLStreamReader;
26
27import org.slf4j.Logger;
28import org.slf4j.LoggerFactory;
29
30import eu.clarin.sru.client.SRUClientException;
31import eu.clarin.sru.client.SRURecordData;
32import eu.clarin.sru.client.SRURecordDataParser;
33import eu.clarin.sru.client.XmlStreamReaderUtils;
34
35
36/**
37 * An abstract base class for CLARIN-FCS record data parsers.
38 */
39abstract class AbstractClarinFCSRecordDataParser implements SRURecordDataParser {
40    protected static final Logger logger =
41            LoggerFactory.getLogger(AbstractClarinFCSRecordDataParser.class);
42    protected final List<DataViewParser> parsers;
43
44
45    /**
46     * Constructor.
47     *
48     * @param parsers
49     *            the list of data view parsers to be used by this record data
50     *            parser. This list should contain one
51     *            {@link DataViewParserGenericDOM} or
52     *            {@link DataViewParserGenericString} instance.
53     * @throws NullPointerException
54     *             if parsers is <code>null</code>
55     * @throws IllegalArgumentException
56     *             if parsers is empty or contains duplicate entries
57     */
58    protected AbstractClarinFCSRecordDataParser(List<DataViewParser> parsers) {
59        if (parsers == null) {
60            throw new NullPointerException("parsers == null");
61        }
62        if (parsers.isEmpty()) {
63            throw new IllegalArgumentException("parsers is empty");
64        }
65
66        ArrayList<DataViewParser> list = new ArrayList<DataViewParser>();
67        boolean foundGeneric = false;
68        for (DataViewParser parser : parsers) {
69            if ((parser instanceof DataViewParserGenericDOM) ||
70                    (parser instanceof DataViewParserGenericString)) {
71                if (foundGeneric) {
72                    throw new IllegalAccessError("parser list should contain " +
73                            "only one instance of DataViewParserGenericDOM " +
74                            "or DataViewParserGenericString");
75                }
76                foundGeneric = true;
77            }
78            if (list.contains(parser)) {
79                throw new IllegalArgumentException("parser list should not " +
80                        "contain douplicates: " + parser.getClass().getName());
81            }
82            list.add(parser);
83        }
84
85        if (!foundGeneric) {
86            logger.warn("No generic type data view parser found. You should " +
87                    "make sure that the parser list contains one " +
88                    "DataViewParserGenericDOM or DataViewParserGenericString " +
89                    "instance");
90        }
91
92        this.parsers = Collections.unmodifiableList(list);
93    }
94
95
96    protected SRURecordData parse(XMLStreamReader reader, String ns)
97            throws XMLStreamException, SRUClientException {
98        // Resource
99        XmlStreamReaderUtils.readStart(reader, ns, "Resource", true, true);
100        final String pid =
101                XmlStreamReaderUtils.readAttributeValue(reader, null, "pid");
102        final String ref =
103                XmlStreamReaderUtils.readAttributeValue(reader, null, "ref");
104        XmlStreamReaderUtils.consumeStart(reader);
105
106        // Resource/Resource (optional)
107        if (XmlStreamReaderUtils.readStart(reader, ns, "Resource", false)) {
108            logger.info("skipping nested <Resource> element");
109            XmlStreamReaderUtils.readEnd(reader, ns, "Resource", true);
110        }
111
112        // Resource/DataView
113        final List<DataView> dataviews = parseDataViews(reader, ns);
114
115        // Resource/ResourceFragment
116        final List<Resource.ResourceFragment> resourceFragments =
117                parseResourceFragments(reader, ns);
118
119        XmlStreamReaderUtils.readEnd(reader, ns, "Resource", true);
120
121        return new ClarinFCSRecordData(pid, ref, dataviews, resourceFragments);
122    }
123
124
125    private List<DataView> parseDataViews(XMLStreamReader reader, String ns)
126            throws XMLStreamException, SRUClientException {
127        List<DataView> dataviews = null;
128
129        while (XmlStreamReaderUtils.readStart(reader, ns, "DataView", false, true)) {
130            final String pid =
131                    XmlStreamReaderUtils.readAttributeValue(reader, null, "pid");
132            final String ref =
133                    XmlStreamReaderUtils.readAttributeValue(reader, null, "ref");
134            final String type =
135                    XmlStreamReaderUtils.readAttributeValue(reader, null, "type");
136            if ((type == null) || type.isEmpty()) {
137                throw new SRUClientException("element <DataView> needs a "
138                        + "non-empty 'type' attribute");
139            }
140
141            // consume start element and get rid of any whitespace
142            XmlStreamReaderUtils.consumeStart(reader);
143            XmlStreamReaderUtils.consumeWhitespace(reader);
144
145            logger.debug("processing <DataView> of type = {}", type);
146
147            DataViewParser selectedParser = null;
148            for (DataViewParser parser : parsers) {
149                if (parser.acceptType(type) &&
150                        ((selectedParser == null) ||
151                         (selectedParser.getPriority() < parser.getPriority()))) {
152                    selectedParser = parser;
153                }
154            }
155
156            DataView dataview = null;
157            if (selectedParser != null) {
158                dataview = selectedParser.parse(reader, type, pid, ref);
159            } else {
160                logger.warn("no parser found for <DataView> of type = {}", type);
161            }
162
163            XmlStreamReaderUtils.readEnd(reader, ns, "DataView", true);
164
165            if (dataview != null) {
166                if (dataviews == null) {
167                    dataviews = new LinkedList<DataView>();
168                }
169                dataviews.add(dataview);
170            } else {
171                logger.warn("skipped <DataView> of type = {}", type);
172            }
173        } // while
174        return dataviews;
175    }
176
177
178    private List<Resource.ResourceFragment> parseResourceFragments(
179            XMLStreamReader reader, String ns) throws XMLStreamException,
180            SRUClientException {
181        List<Resource.ResourceFragment> resourceFragments = null;
182        while (XmlStreamReaderUtils.readStart(reader, ns, "ResourceFragment", false, true)) {
183            logger.debug("found ResourceFragment");
184            String pid = XmlStreamReaderUtils.readAttributeValue(reader, null, "pid");
185            String ref = XmlStreamReaderUtils.readAttributeValue(reader, null, "ref");
186            XmlStreamReaderUtils.consumeStart(reader);
187            final List<DataView> dataviews = parseDataViews(reader, ns);
188            XmlStreamReaderUtils.readEnd(reader, ns, "ResourceFragment", true);
189
190            if (resourceFragments == null) {
191                resourceFragments = new LinkedList<Resource.ResourceFragment>();
192            }
193            resourceFragments.add(new Resource.ResourceFragment(pid, ref, dataviews));
194        } // while
195        return resourceFragments;
196    }
197
198} // class AbstractClarinFCSRecordDataParser
Note: See TracBrowser for help on using the repository browser.