source: FCSSimpleClient/trunk/src/main/java/eu/clarin/sru/client/fcs/AbstractClarinFCSRecordDataParser.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: 7.9 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.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    @SuppressWarnings("deprecation")
97    protected SRURecordData parse(XMLStreamReader reader, String ns,
98            boolean fullLegacyCompatMode)
99            throws XMLStreamException, SRUClientException {
100        // Resource
101        XmlStreamReaderUtils.readStart(reader, ns, "Resource", true, true);
102        final String pid =
103                XmlStreamReaderUtils.readAttributeValue(reader, null, "pid");
104        final String ref =
105                XmlStreamReaderUtils.readAttributeValue(reader, null, "ref");
106        XmlStreamReaderUtils.consumeStart(reader);
107
108        // Resource/Resource (optional)
109        if (XmlStreamReaderUtils.readStart(reader, ns, "Resource", false)) {
110            logger.info("skipping nested <Resource> element");
111            XmlStreamReaderUtils.readEnd(reader, ns, "Resource", true);
112        }
113
114        // Resource/DataView
115        final List<DataView> dataviews = parseDataViews(reader, ns);
116
117        // Resource/ResourceFragment
118        final List<Resource.ResourceFragment> resourceFragments =
119                parseResourceFragments(reader, ns);
120
121        XmlStreamReaderUtils.readEnd(reader, ns, "Resource", true);
122        if (fullLegacyCompatMode) {
123            return new LegacyClarinFCSRecordData(pid, ref, dataviews,
124                    resourceFragments);
125        } else {
126            return new ClarinFCSRecordData(pid, ref, dataviews,
127                    resourceFragments);
128        }
129    }
130
131
132    private List<DataView> parseDataViews(XMLStreamReader reader, String ns)
133            throws XMLStreamException, SRUClientException {
134        List<DataView> dataviews = null;
135
136        while (XmlStreamReaderUtils.readStart(reader, ns, "DataView", false, true)) {
137            final String pid =
138                    XmlStreamReaderUtils.readAttributeValue(reader, null, "pid");
139            final String ref =
140                    XmlStreamReaderUtils.readAttributeValue(reader, null, "ref");
141            final String type =
142                    XmlStreamReaderUtils.readAttributeValue(reader, null, "type");
143            if ((type == null) || type.isEmpty()) {
144                throw new SRUClientException("element <DataView> needs a "
145                        + "non-empty 'type' attribute");
146            }
147
148            // consume start element and get rid of any whitespace
149            XmlStreamReaderUtils.consumeStart(reader);
150            XmlStreamReaderUtils.consumeWhitespace(reader);
151
152            logger.debug("processing <DataView> of type = {}", type);
153
154            DataViewParser selectedParser = null;
155            for (DataViewParser parser : parsers) {
156                if (parser.acceptType(type) &&
157                        ((selectedParser == null) ||
158                         (selectedParser.getPriority() < parser.getPriority()))) {
159                    selectedParser = parser;
160                }
161            }
162
163            DataView dataview = null;
164            if (selectedParser != null) {
165                dataview = selectedParser.parse(reader, type, pid, ref);
166            } else {
167                logger.warn("no parser found for <DataView> of type = {}", type);
168            }
169
170            XmlStreamReaderUtils.readEnd(reader, ns, "DataView", true);
171
172            if (dataview != null) {
173                if (dataviews == null) {
174                    dataviews = new LinkedList<DataView>();
175                }
176                dataviews.add(dataview);
177            } else {
178                logger.warn("skipped <DataView> of type = {}", type);
179            }
180        } // while
181        return dataviews;
182    }
183
184
185    private List<Resource.ResourceFragment> parseResourceFragments(
186            XMLStreamReader reader, String ns) throws XMLStreamException,
187            SRUClientException {
188        List<Resource.ResourceFragment> resourceFragments = null;
189        while (XmlStreamReaderUtils.readStart(reader, ns, "ResourceFragment", false, true)) {
190            logger.debug("found ResourceFragment");
191            String pid = XmlStreamReaderUtils.readAttributeValue(reader, null, "pid");
192            String ref = XmlStreamReaderUtils.readAttributeValue(reader, null, "ref");
193            XmlStreamReaderUtils.consumeStart(reader);
194            final List<DataView> dataviews = parseDataViews(reader, ns);
195            XmlStreamReaderUtils.readEnd(reader, ns, "ResourceFragment", true);
196
197            if (resourceFragments == null) {
198                resourceFragments = new LinkedList<Resource.ResourceFragment>();
199            }
200            resourceFragments.add(new Resource.ResourceFragment(pid, ref, dataviews));
201        } // while
202        return resourceFragments;
203    }
204
205} // class AbstractClarinFCSRecordDataParser
Note: See TracBrowser for help on using the repository browser.