source: SRUClient/trunk/src/main/java/eu/clarin/sru/client/SRUExplainRecordDataParser.java @ 2940

Last change on this file since 2940 was 2940, checked in by oschonef, 11 years ago
  • Property svn:eol-style set to native
File size: 8.1 KB
Line 
1/**
2 * This software is copyright (c) 2011-2013 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;
18
19import java.util.HashSet;
20import java.util.Set;
21
22import javax.xml.stream.XMLStreamException;
23import javax.xml.stream.XMLStreamReader;
24
25import org.slf4j.Logger;
26import org.slf4j.LoggerFactory;
27
28import eu.clarin.sru.client.SRUExplainRecordData.ServerInfo;
29
30
31/**
32 * This class implements a (partial) record data parser for SRU explain record
33 * data conforming to the ZeeRex schema.
34 *
35 * @see <a href="http://zeerex.z3950.org/dtd/">The ZeeRex DTD</a>
36 */
37public class SRUExplainRecordDataParser implements SRURecordDataParser {
38    static final String ZEEREX_NS       = SRUExplainRecordData.RECORD_SCHEMA;
39    static final String ZEEREX_NS_QUIRK = "http://explain.z3950.org/dtd/2.1/";
40    private static final String VERSION_1_1     = "1.1";
41    private static final String VERSION_1_2     = "1.2";
42    private static final String TRANSPORT_HTTP  = "http";
43    private static final String TRANSPORT_HTTPS = "https";
44    private static final Logger logger =
45            LoggerFactory.getLogger(SRUExplainRecordDataParser.class);
46
47    @Override
48    public String getRecordSchema() {
49        return SRUExplainRecordData.RECORD_SCHEMA;
50    }
51
52
53    @Override
54    public SRURecordData parse(final XMLStreamReader reader, SRUVersion version)
55            throws XMLStreamException, SRUClientException {
56        logger.debug("parsing explain record data for version {}", version);
57
58        // explain
59        if (XmlStreamReaderUtils.readStart(reader, ZEEREX_NS,
60                "explain", false)) {
61            return parseExplain(reader, ZEEREX_NS, version);
62        } else if (XmlStreamReaderUtils.readStart(reader,
63                ZEEREX_NS_QUIRK, "explain", false)) {
64            logger.warn("namespace '{}' is not defined by ZeeRex, enabling " +
65                    "quirk mode (consider using namespace '{}' which is defined)",
66                    ZEEREX_NS_QUIRK, ZEEREX_NS);
67            return parseExplain(reader, ZEEREX_NS_QUIRK, version);
68        } else {
69            throw new XMLStreamException("expected element '{" + ZEEREX_NS +
70                    "}explain' at this position", reader.getLocation());
71        }
72    }
73
74
75    private static SRURecordData parseExplain(XMLStreamReader reader,
76            final String namespace, final SRUVersion version)
77            throws XMLStreamException, SRUClientException {
78
79        // explain/serverInfo
80        ServerInfo serverInfo = parseServerInfo(reader, namespace);
81
82        // explain/databaseInfo
83        if (XmlStreamReaderUtils.readStart(reader, namespace, "databaseInfo", false)) {
84            logger.debug("databaseInfo");
85            XmlStreamReaderUtils.readEnd(reader, namespace, "databaseInfo", true);
86        }
87
88        // explain/metaInfo
89        if (XmlStreamReaderUtils.readStart(reader, namespace, "metaInfo", false)) {
90            logger.debug("metaInfo");
91            XmlStreamReaderUtils.readEnd(reader, namespace, "metaInfo", true);
92        }
93
94        // explain/indexInfo
95        while (XmlStreamReaderUtils.readStart(reader, namespace, "indexInfo", false)) {
96            logger.debug("indexInfo");
97            for (;;) {
98                /*
99                 * FIXME: SRU 2.0 has *either* <set> or <index>
100                 * check with SRU 1.2 ...
101                 */
102                if (XmlStreamReaderUtils.readStart(reader, namespace, "set", false, true)) {
103                    logger.debug("set");
104                    // FIXME: read attributes
105                    XmlStreamReaderUtils.consumeStart(reader);
106
107                    XmlStreamReaderUtils.readEnd(reader, namespace, "set", true);
108                } else if (XmlStreamReaderUtils.readStart(reader, namespace, "index", false, true)) {
109                    logger.debug("index");
110                    // FIXME: read attributes
111                    XmlStreamReaderUtils.consumeStart(reader);
112                    XmlStreamReaderUtils.readEnd(reader, namespace, "index", true);
113                } else {
114                    break;
115                }
116            }
117            XmlStreamReaderUtils.readEnd(reader, namespace, "indexInfo", true);
118        } // while
119
120        XmlStreamReaderUtils.readEnd(reader, namespace, "explain", true);
121        return new SRUExplainRecordData(serverInfo);
122    }
123
124
125    private static ServerInfo parseServerInfo(final XMLStreamReader reader,
126            final String namespace) throws XMLStreamException,
127            SRUClientException {
128        XmlStreamReaderUtils.readStart(reader, namespace,
129                "serverInfo", true, true);
130        String protocol = XmlStreamReaderUtils.readAttributeValue(reader,
131                null, "protocol");
132
133        SRUVersion version = SRUVersion.VERSION_1_2;
134        String s = XmlStreamReaderUtils.readAttributeValue(reader, null,
135                "version");
136        if (s != null) {
137            if (VERSION_1_1.equals(s)) {
138                version = SRUVersion.VERSION_1_1;
139            } else if (VERSION_1_2.equals(s)) {
140                version = SRUVersion.VERSION_1_2;
141            } else {
142                throw new SRUClientException("invalid or unsupported value '" +
143                        s + "'for attribute 'version' on element '" +
144                        reader.getName() + "'");
145            }
146        }
147
148        Set<String> transports = new HashSet<String>();
149        s = XmlStreamReaderUtils.readAttributeValue(reader,
150                null, "transport");
151        if (s != null) {
152            s = s + " http";
153            for (String i : s.split("\\s+")) {
154                String t = null;
155                if (TRANSPORT_HTTP.equalsIgnoreCase(i)) {
156                    t = TRANSPORT_HTTP;
157                } else if (TRANSPORT_HTTPS.equalsIgnoreCase(i)) {
158                    t = TRANSPORT_HTTPS;
159                } else {
160                    throw new SRUClientException("invalid value '" + i +
161                            "' for attribute 'transport' on element '" +
162                            reader.getName() +
163                            " (use either 'http' of 'https' or both " +
164                            "seperated by whitespace");
165                }
166                if (t != null) {
167                    if (!transports.contains(t)) {
168                        transports.add(t);
169                    } else {
170                        logger.warn("value '{}' already listed in " +
171                                "'transport' attribute of element '{}'",
172                                t, reader.getName());
173                    }
174                }
175
176            } // for
177        } else {
178            transports.add(TRANSPORT_HTTP);
179        }
180        XmlStreamReaderUtils.consumeStart(reader);
181
182        String host = XmlStreamReaderUtils.readContent(reader, namespace,
183                "host", true);
184        int port = XmlStreamReaderUtils.readContent(reader, namespace,
185                "port", true, -1);
186        if ((port < 0) || (port > 65535)) {
187            // FIXME: error message
188            throw new SRUClientException("invalid port number (" + port + ")");
189        }
190        String database = XmlStreamReaderUtils.readContent(reader, namespace,
191                "database", true);
192        if (XmlStreamReaderUtils.readStart(reader, namespace,
193                "authentication", false)) {
194            XmlStreamReaderUtils.readEnd(reader, namespace,
195                    "authentication", true);
196        }
197        XmlStreamReaderUtils.readEnd(reader, namespace, "serverInfo", true);
198        logger.debug("serverInfo: host={}, port={}, database={}, version={}, protocol={}, transport={}",
199                host, port, database, version, protocol, transports);
200        return new ServerInfo(host, port, database, protocol, version,
201                transports);
202    }
203
204} // class SRUExplainRecordDataParser
Note: See TracBrowser for help on using the repository browser.