source: SRUClient/tags/SRUClient-0.9.2/src/main/java/eu/clarin/sru/client/SRUExplainRecordDataParser.java @ 2998

Last change on this file since 2998 was 2998, checked in by oschonef, 11 years ago
  • tag version 0.9.2
  • Property svn:eol-style set to native
File size: 31.0 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.ArrayList;
20import java.util.HashMap;
21import java.util.HashSet;
22import java.util.List;
23import java.util.Map;
24import java.util.Set;
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.SRUExplainRecordData.ConfigInfo;
34import eu.clarin.sru.client.SRUExplainRecordData.DatabaseInfo;
35import eu.clarin.sru.client.SRUExplainRecordData.IndexInfo;
36import eu.clarin.sru.client.SRUExplainRecordData.LocalizedString;
37import eu.clarin.sru.client.SRUExplainRecordData.Schema;
38import eu.clarin.sru.client.SRUExplainRecordData.ServerInfo;
39
40
41/**
42 * This class implements a (partial) record data parser for SRU explain record
43 * data conforming to the ZeeRex schema.
44 *
45 * @see <a href="http://zeerex.z3950.org/dtd/">ZeeRex DTD</a>
46 */
47class SRUExplainRecordDataParser {
48    private static final String ZEEREX_NS       =
49            SRUExplainRecordData.RECORD_SCHEMA;
50    private static final String ZEEREX_NS_QUIRK =
51            "http://explain.z3950.org/dtd/2.1/";
52    private static final String VERSION_1_1     = "1.1";
53    private static final String VERSION_1_2     = "1.2";
54    private static final String TRANSPORT_HTTP  = "http";
55    private static final String TRANSPORT_HTTPS = "https";
56    private static final String STRING_TRUE     = "true";
57    private static final String PRIMARY_FALSE   = "false";
58    private static final Logger logger =
59            LoggerFactory.getLogger(SRUExplainRecordDataParser.class);
60
61
62    public SRURecordData parse(XMLStreamReader reader, SRUVersion version,
63            boolean strict, String recordSchema) throws XMLStreamException,
64            SRUClientException {
65        // sanity check, if we are dealing with the expected record schema
66        if (!(ZEEREX_NS.equals(recordSchema) ||
67                ZEEREX_NS_QUIRK.equals(recordSchema))) {
68            throw new SRUClientException("record schema '" + recordSchema +
69                    "' not supported in explain response record data");
70        }
71
72        logger.debug("parsing explain record data (version={}, schema={})",
73                version, recordSchema);
74
75        // explain
76        if (XmlStreamReaderUtils.peekStart(reader, ZEEREX_NS, "explain")) {
77            return parseExplain(reader, version, strict, ZEEREX_NS);
78        } else if (XmlStreamReaderUtils.peekStart(reader,
79                ZEEREX_NS_QUIRK, "explain")) {
80            if (strict) {
81                logger.warn("namespace '{}' is not defined by ZeeRex, " +
82                        "enabling quirks mode (consider using namespace '{}'" +
83                        " which is defined)", ZEEREX_NS_QUIRK, ZEEREX_NS);
84            } else {
85                logger.info("namespace '{}' is not defined by ZeeRex, " +
86                        "enabling quirks mode (consider using namespace '{}'" +
87                        " which is defined)", ZEEREX_NS_QUIRK, ZEEREX_NS);
88            }
89            return parseExplain(reader, version, strict, ZEEREX_NS_QUIRK);
90        } else {
91            throw new XMLStreamException("expected start tag for element '" +
92                    new QName(ZEEREX_NS, "explain") + " at this position",
93                    reader.getLocation());
94        }
95    }
96
97
98    private static SRURecordData parseExplain(XMLStreamReader reader,
99            SRUVersion version, boolean strict, String ns)
100            throws XMLStreamException, SRUClientException {
101
102        // explain
103        XmlStreamReaderUtils.readStart(reader, ns, "explain", true);
104
105        /*
106         * explain (serverInfo, databaseInfo?, metaInfo?, indexInfo?,
107         *     (recordInfo|schemaInfo)?, configInfo?)
108         */
109
110        // explain/serverInfo (mandatory)
111        ServerInfo serverInfo = parseServerInfo(reader, ns);
112
113        // explain/databaseInfo (optional)
114        DatabaseInfo databaseInfo = null;
115        if (XmlStreamReaderUtils.readStart(reader, ns, "databaseInfo", false)) {
116            databaseInfo = parseDatabaseInfo(reader, ns, strict);
117            XmlStreamReaderUtils.readEnd(reader, ns, "databaseInfo");
118        }
119
120        // explain/metaInfo (optional)
121        if (XmlStreamReaderUtils.readStart(reader, ns, "metaInfo", false)) {
122            /*
123             * metaInfo (dateModified, (aggregatedFrom, dateAggregated)?)
124             */
125            logger.debug("metaInfo");
126            XmlStreamReaderUtils.readEnd(reader, ns, "metaInfo", true);
127        }
128
129        // explain/indexInfo (optional)
130        IndexInfo indexInfo = null;
131        if (XmlStreamReaderUtils.readStart(reader, ns, "indexInfo", false)) {
132            indexInfo = parseIndexInfo(reader, strict, ns);
133            XmlStreamReaderUtils.readEnd(reader, ns, "indexInfo");
134        } // if
135
136        // explain/recordInfo or explain/schemaInfo
137        List<Schema> schemaInfo = null;
138        if (XmlStreamReaderUtils.peekStart(reader, ns, "recordInfo") ||
139            XmlStreamReaderUtils.peekStart(reader, ns, "schemaInfo")) {
140            if (XmlStreamReaderUtils.readStart(reader,
141                    ns, "recordInfo", false)) {
142                logger.debug("skipping 'recordInfo'");
143                XmlStreamReaderUtils.readEnd(reader, ns, "recordInfo", true);
144            } else if (XmlStreamReaderUtils.readStart(reader,
145                    ns, "schemaInfo", false)) {
146                schemaInfo = parseSchemaInfo(reader, strict, ns);
147                XmlStreamReaderUtils.readEnd(reader, ns, "schemaInfo");
148            } else {
149                throw new XMLStreamException("unexpected start element '" +
150                        reader.getName() + "'", reader.getLocation());
151            }
152        }
153
154        // explain/configInfo (optional)
155        ConfigInfo configInfo = null;
156        if (XmlStreamReaderUtils.readStart(reader, ns, "configInfo", false)) {
157            configInfo = parseConfigInfo(reader, strict, ns);
158            XmlStreamReaderUtils.readEnd(reader, ns, "configInfo");
159        }
160
161        XmlStreamReaderUtils.readEnd(reader, ns, "explain", true);
162        return new SRUExplainRecordData(serverInfo, databaseInfo, indexInfo,
163                schemaInfo, configInfo);
164    }
165
166
167    private static ServerInfo parseServerInfo(XMLStreamReader reader,
168            String ns) throws XMLStreamException, SRUClientException {
169        XmlStreamReaderUtils.readStart(reader, ns,
170                "serverInfo", true, true);
171        String protocol = XmlStreamReaderUtils.readAttributeValue(reader,
172                null, "protocol");
173
174        SRUVersion version = SRUVersion.VERSION_1_2;
175        String s = XmlStreamReaderUtils.readAttributeValue(reader, null,
176                "version");
177        if (s != null) {
178            if (VERSION_1_1.equals(s)) {
179                version = SRUVersion.VERSION_1_1;
180            } else if (VERSION_1_2.equals(s)) {
181                version = SRUVersion.VERSION_1_2;
182            } else {
183                throw new SRUClientException("invalid or unsupported value '" +
184                        s + "'for attribute 'version' on element '" +
185                        reader.getName() + "'");
186            }
187        }
188
189        Set<String> transports = new HashSet<String>();
190        s = XmlStreamReaderUtils.readAttributeValue(reader, null, "transport");
191        if (s != null) {
192            for (String i : s.split("\\s+")) {
193                String t = null;
194                if (TRANSPORT_HTTP.equalsIgnoreCase(i)) {
195                    t = TRANSPORT_HTTP;
196                } else if (TRANSPORT_HTTPS.equalsIgnoreCase(i)) {
197                    t = TRANSPORT_HTTPS;
198                } else {
199                    throw new SRUClientException("invalid value '" + i +
200                            "' for attribute 'transport' on element '" +
201                            reader.getName() +
202                            " (use either 'http' of 'https' or both " +
203                            "seperated by whitespace");
204                }
205                if (t != null) {
206                    if (!transports.contains(t)) {
207                        transports.add(t);
208                    } else {
209                        logger.warn("value '{}' already listed in " +
210                                "'transport' attribute of element '{}'",
211                                t, reader.getName());
212                    }
213                }
214
215            } // for
216        } else {
217            transports.add(TRANSPORT_HTTP);
218        }
219        XmlStreamReaderUtils.consumeStart(reader);
220
221        final String host = XmlStreamReaderUtils.readContent(reader,
222                ns, "host", true);
223        final int port = XmlStreamReaderUtils.readContent(reader,
224                ns, "port", true, -1);
225        if ((port < 0) || (port > 65535)) {
226            // FIXME: error message
227            throw new SRUClientException("invalid port number (" + port + ")");
228        }
229        String database = XmlStreamReaderUtils.readContent(reader, ns,
230                "database", true);
231        if (XmlStreamReaderUtils.readStart(reader, ns,
232                "authentication", false)) {
233            XmlStreamReaderUtils.readEnd(reader, ns,
234                    "authentication", true);
235        }
236        XmlStreamReaderUtils.readEnd(reader, ns, "serverInfo", true);
237        logger.debug("serverInfo: host={}, port={}, database={}, version={}, " +
238                "protocol={}, transport={}", host, port, database, version,
239                protocol, transports);
240        return new ServerInfo(host, port, database, protocol, version,
241                transports);
242    }
243
244
245    private static DatabaseInfo parseDatabaseInfo(XMLStreamReader reader,
246            String ns, boolean strict) throws XMLStreamException,
247            SRUClientException {
248        /*
249         * databaseInfo (title*, description*, (author | contact | extent |
250         *     history | langUsage | restrictions | subjects | links |
251         *     implementation)*)
252         */
253
254        List<LocalizedString> title = null;
255        List<LocalizedString> description = null;
256        List<LocalizedString> author = null;
257        List<LocalizedString> contact = null;
258        List<LocalizedString> extent = null;
259        List<LocalizedString> history = null;
260        List<LocalizedString> langUsage = null;
261        List<LocalizedString> restrictions = null;
262        List<LocalizedString> subjects = null;
263        List<LocalizedString> links = null;
264        List<LocalizedString> implementation = null;
265
266        byte mode = 0; /* 1 = title, 2 = description, 3 = others */
267        for (;;) {
268            if (XmlStreamReaderUtils.peekStart(reader, ns, "title")) {
269                if ((mode != 0) && (mode != 1)) {
270                    if (strict) {
271                        throw new XMLStreamException(
272                                "element '" + new QName(ns, "title") +
273                                        "' not allowed here [required content" +
274                                        " model is: title*, description*, " +
275                                        "(author | contact | extent | history" +
276                                        " | langUsage | restrictions | " +
277                                        "subjects | links | implementation)*]",
278                                        reader.getLocation());
279                    } else {
280                        logger.warn("element '{}' not allowed here [required " +
281                                "content model is: title*, description*, " +
282                                "(author | contact | extent | history | " +
283                                "langUsage | restrictions | subjects | links " +
284                                "| implementation)*] at position " +
285                                "[row, col]: [{}, {}]",
286                                new QName(ns, "title"),
287                                reader.getLocation().getLineNumber(),
288                                reader.getLocation().getColumnNumber());
289                    }
290                }
291                LocalizedString s =
292                        parseStringI18N(reader, strict, ns, "title", true);
293                if (title == null) {
294                    title = new ArrayList<LocalizedString>();
295                }
296                title.add(s);
297                mode = 1;
298            } else if (XmlStreamReaderUtils.peekStart(reader, ns, "description")) {
299                if ((mode != 0) && (mode != 1) && (mode != 2)) {
300                    if (strict) {
301                        throw new XMLStreamException(
302                                "element '" + new QName(ns, "description") +
303                                        "' not allowed here [required content" +
304                                        " model is: title*, description*, " +
305                                        "(author | contact | extent | history" +
306                                        " | langUsage | restrictions | " +
307                                        "subjects | links | implementation)*]",
308                                        reader.getLocation());
309                    } else {
310                        logger.warn("element '{}' not allowed here [required " +
311                                "content model is: title*, description*, " +
312                                "(author | contact | extent | history | " +
313                                "langUsage | restrictions | subjects | links " +
314                                "| implementation)*] at position " +
315                                "[row, col]: [{}, {}]",
316                                new QName(ns, "description"),
317                                reader.getLocation().getLineNumber(),
318                                reader.getLocation().getColumnNumber());
319                    }
320                }
321                LocalizedString s =
322                        parseStringI18N(reader, strict, ns, "description", true);
323                if (description == null) {
324                    description = new ArrayList<LocalizedString>();
325                }
326                description.add(s);
327                mode = 2;
328            } else if (XmlStreamReaderUtils.peekStart(reader, ns, "author")) {
329                LocalizedString s =
330                        parseStringI18N(reader, strict, ns, "author", true);
331                if (author == null) {
332                    author = new ArrayList<LocalizedString>();
333                }
334                author.add(s);
335                mode = 3;
336            } else if (XmlStreamReaderUtils.peekStart(reader, ns, "contact")) {
337                LocalizedString s =
338                        parseStringI18N(reader, strict, ns, "contact", true);
339                if (contact == null) {
340                    contact = new ArrayList<LocalizedString>();
341                }
342                contact.add(s);
343                mode = 3;
344            } else if (XmlStreamReaderUtils.peekStart(reader, ns, "extent")) {
345                LocalizedString s =
346                        parseStringI18N(reader, strict, ns, "extent", true);
347                if (extent == null) {
348                    extent = new ArrayList<LocalizedString>();
349                }
350                extent.add(s);
351                mode = 3;
352            } else if (XmlStreamReaderUtils.peekStart(reader, ns, "history")) {
353                LocalizedString s =
354                        parseStringI18N(reader, strict, ns, "history", true);
355                if (history == null) {
356                    history = new ArrayList<LocalizedString>();
357                }
358                history.add(s);
359                mode = 3;
360            } else if (XmlStreamReaderUtils.peekStart(reader,
361                    ns, "restrictions")) {
362                LocalizedString s =
363                        parseStringI18N(reader, strict, ns, "restrictions", true);
364                if (restrictions == null) {
365                    restrictions = new ArrayList<LocalizedString>();
366                }
367                restrictions.add(s);
368                mode = 3;
369            } else if (XmlStreamReaderUtils.peekStart(reader, ns, "subjects")) {
370                LocalizedString s =
371                        parseStringI18N(reader, strict, ns, "subjects", true);
372                if (subjects == null) {
373                    subjects = new ArrayList<LocalizedString>();
374                }
375                subjects.add(s);
376                mode = 3;
377            } else if (XmlStreamReaderUtils.peekStart(reader, ns, "links")) {
378                LocalizedString s =
379                        parseStringI18N(reader, strict, ns, "links", true);
380                if (links == null) {
381                    links = new ArrayList<LocalizedString>();
382                }
383                links.add(s);
384                mode = 3;
385            } else if (XmlStreamReaderUtils.peekStart(reader,
386                    ns, "implementation")) {
387                LocalizedString s =
388                        parseStringI18N(reader, strict, ns, "implementation", true);
389                if (implementation == null) {
390                    implementation = new ArrayList<LocalizedString>();
391                }
392                implementation.add(s);
393                mode = 3;
394            } else if (XmlStreamReaderUtils.peekStart(reader, ns, "langUsage")) {
395                // FIXME: implement!
396                XmlStreamReaderUtils.readContent(reader, ns, "langUsage", false);
397                mode = 3;
398            } else {
399                break;
400            }
401        } // for
402
403        return new DatabaseInfo(title, description, author, contact,
404                extent, history, langUsage, restrictions, subjects,
405                links, implementation);
406    }
407
408
409    private static IndexInfo parseIndexInfo(XMLStreamReader reader,
410            boolean strict, String ns) throws XMLStreamException,
411            SRUClientException {
412        /*
413         * indexInfo ((set | index | sortKeywords)+)
414         */
415        boolean found = false;
416        List<IndexInfo.Set> sets = null;
417        List<IndexInfo.Index> indexes = null;
418        for (;;) {
419            if (XmlStreamReaderUtils.readStart(reader, ns, "set", false, true)) {
420                final String identifier =
421                        XmlStreamReaderUtils.readAttributeValue(reader,
422                                null, "identifier");
423                final String name =
424                        XmlStreamReaderUtils.readAttributeValue(reader,
425                                null, "name");
426                XmlStreamReaderUtils.consumeStart(reader);
427
428                // indexInfo/set/title
429                List<LocalizedString> titles = null;
430                for (;;) {
431                    LocalizedString title =
432                            parseStringI18N(reader, strict, ns, "title", false);
433                    if (title == null) {
434                        break;
435                    }
436                    if (titles == null) {
437                        titles = new ArrayList<LocalizedString>();
438                    }
439                    titles.add(title);
440                } // for
441                XmlStreamReaderUtils.readEnd(reader, ns, "set");
442
443                if (sets == null) {
444                    sets = new ArrayList<IndexInfo.Set>();
445                }
446                sets.add(new IndexInfo.Set(identifier, name, titles));
447                found = true;
448            } else if (XmlStreamReaderUtils.readStart(reader, ns,
449                    "index", false, true)) {
450                final String id =
451                        XmlStreamReaderUtils.readAttributeValue(reader, null, "id");
452                final boolean can_search = parseBooleanAttribute(reader,
453                        strict, null, "search", false);
454                final boolean can_scan = parseBooleanAttribute(reader,
455                        strict, null, "scan", false);
456                final boolean can_sort = parseBooleanAttribute(reader,
457                        strict, null, "sort", false);
458                XmlStreamReaderUtils.consumeStart(reader);
459
460                // indexInfo/index/title
461                List<LocalizedString> titles = null;
462                for (;;) {
463                    LocalizedString title =
464                            parseStringI18N(reader, strict, ns, "title", false);
465                    if (title == null) {
466                        break;
467                    }
468                    if (titles == null) {
469                        titles = new ArrayList<LocalizedString>();
470                    }
471                    titles.add(title);
472                } // for
473
474                // indexInfo/index/map ((attr+)|name)
475                List<IndexInfo.Index.Map> maps = null;
476                boolean first_map = true;
477                while (XmlStreamReaderUtils.readStart(reader, ns, "map",
478                        first_map, true)) {
479                    final boolean primary = parseBooleanAttribute(reader,
480                            strict, null, "primary", false);
481                    XmlStreamReaderUtils.consumeStart(reader);
482
483                    if (XmlStreamReaderUtils.peekStart(reader, ns, "attr")) {
484                        /*
485                         * skip "attr" elements, because they are not supported
486                         */
487                        while (XmlStreamReaderUtils.readStart(reader,
488                                ns, "attr", false)) {
489                            logger.debug("skipping 'attr'");
490                            XmlStreamReaderUtils.readEnd(reader, ns, "attr");
491                        } // while (attr)
492                    } else if (XmlStreamReaderUtils.peekStart(reader,
493                            ns, "name")) {
494                        XmlStreamReaderUtils.readStart(reader, ns, "name", true, true);
495                        final String set =
496                                XmlStreamReaderUtils.readAttributeValue(reader,
497                                        null, "set");
498                        // FIXME: check 'set'
499                        XmlStreamReaderUtils.consumeStart(reader);
500                        final String name =
501                                XmlStreamReaderUtils.readString(reader, false);
502                        // FIXME: check 'name'
503                        XmlStreamReaderUtils.readEnd(reader, ns, "name");
504                        if ((set != null) && (name != null)) {
505                            if (maps == null) {
506                                maps = new ArrayList<IndexInfo.Index.Map>();
507                            }
508                            maps.add(new IndexInfo.Index.Map(primary, set, name));
509                        }
510                    } else {
511                        // FIXME: error message
512                        throw new XMLStreamException(
513                                "expected 'attr' or 'name'",
514                                reader.getLocation());
515                    }
516
517                    XmlStreamReaderUtils.readEnd(reader, ns, "map");
518                    first_map = false;
519                } // while (map)
520
521                // indexInfo/index/configInfo (optional)
522                if (XmlStreamReaderUtils.readStart(reader, ns, "configInfo", false)) {
523                    logger.debug("skipping 'configInfo' within 'indexInfo/index'");
524                    XmlStreamReaderUtils.readEnd(reader, ns, "configInfo", true);
525                }
526
527                XmlStreamReaderUtils.readEnd(reader, ns, "index");
528                if (indexes == null) {
529                    indexes = new ArrayList<IndexInfo.Index>();
530                }
531                indexes.add(new IndexInfo.Index(id, titles, can_search,
532                        can_scan, can_sort, maps));
533                found = true;
534            } else if (XmlStreamReaderUtils.readStart(reader, ns, "sortKeyword", false)) {
535                logger.debug("skipping 'sortKeywords'");
536                XmlStreamReaderUtils.readEnd(reader, ns, "sortKeyword", true);
537                found = true;
538            } else {
539                break;
540            }
541        } // for
542        if (!found) {
543            throw new XMLStreamException("expected at least one '" +
544                    new QName(ns, "set") + "', '" +
545                    new QName(ns, "index") + "' or '" +
546                    new QName(ns, "sortKeyword") +
547                    "' element within element '" +
548                    new QName(ns, "indexInfo") + "'",
549                    reader.getLocation());
550        }
551        return ((sets != null) || (indexes != null))
552                ? new IndexInfo(sets, indexes)
553                : null;
554    }
555
556
557    private static ConfigInfo parseConfigInfo(XMLStreamReader reader,
558            boolean strict, String ns) throws XMLStreamException,
559            SRUClientException {
560        /*
561         * configInfo ((default|setting|supports)*)
562         */
563        Map<String, String> defaults = null;
564        Map<String, String> settings = null;
565        Map<String, String> supports = null;
566        for (;;) {
567            if (XmlStreamReaderUtils.peekStart(reader, ns, "default")) {
568                defaults = parseConfigInfoItem(reader, strict, ns,
569                        "default", defaults);
570            } else if (XmlStreamReaderUtils.peekStart(reader, ns, "setting")) {
571                settings = parseConfigInfoItem(reader, strict, ns,
572                        "setting", settings);
573            } else if (XmlStreamReaderUtils.peekStart(reader, ns, "supports")) {
574                supports = parseConfigInfoItem(reader, strict, ns,
575                        "supports", supports);
576            } else {
577                break;
578            }
579        } // for
580
581        return ((defaults != null) || (settings != null) || (supports != null))
582                ? new ConfigInfo(defaults, settings, supports)
583                : null;
584    }
585
586
587    private static LocalizedString parseStringI18N(XMLStreamReader reader,
588            boolean strict, String ns, String localName, boolean required)
589            throws XMLStreamException {
590        if (!XmlStreamReaderUtils.readStart(reader, ns, localName, required,
591                true)) {
592            return null;
593        }
594        final String lang = XmlStreamReaderUtils.readAttributeValue(reader,
595                null, "lang", false);
596        if (lang != null) {
597            if (lang.length() != 2) {
598                // FIXME: message
599                logger.warn("ZeeRex sugguests to use 2-letter codes");
600            }
601        }
602        final boolean primary =
603                parseBooleanAttribute(reader, strict, null, "primary", false);
604        XmlStreamReaderUtils.consumeStart(reader);
605        String value = XmlStreamReaderUtils.readString(reader, false);
606        XmlStreamReaderUtils.readEnd(reader, ns, localName);
607        return new LocalizedString(value, lang, primary);
608    }
609
610
611    private static boolean parseBooleanAttribute(XMLStreamReader reader,
612            boolean strict, String ns, String localName, boolean defaultValue)
613            throws XMLStreamException {
614        boolean result = defaultValue;
615        final String s = XmlStreamReaderUtils.readAttributeValue(reader,
616                ns, localName, false);
617        if (s != null) {
618            if (STRING_TRUE.equalsIgnoreCase(s)) {
619                if (!STRING_TRUE.equals(s)) {
620                    if (strict) {
621                        throw new XMLStreamException("capitalization");
622                    } else {
623                        // FIXME: message
624                        logger.warn("capitalizaton");
625                    }
626                }
627                result = true;
628            } else if (PRIMARY_FALSE.equalsIgnoreCase(s)) {
629                if (!PRIMARY_FALSE.equals(s)) {
630                    if (strict) {
631                        throw new XMLStreamException("capitalization");
632                    } else {
633                        // FIXME: message
634                        logger.warn("capitalizaton");
635                    }
636                }
637                result = false;
638            } else {
639                // FIXME: message
640                throw new XMLStreamException("value of @" + localName + " invalid");
641            }
642        }
643        return result;
644    }
645
646
647    private static List<Schema> parseSchemaInfo(XMLStreamReader reader,
648            boolean strict, String ns) throws XMLStreamException {
649        /*
650         * schemaInfo (schema+)
651         * schema (title*)
652         */
653        List<Schema> schemaInfo = null;
654        boolean first_schema = true;
655        while (XmlStreamReaderUtils.readStart(reader, ns, "schema",
656                first_schema, true)) {
657            final String identifier =
658                    XmlStreamReaderUtils.readAttributeValue(reader,
659                            null, "identifier", true);
660            final String name = XmlStreamReaderUtils.readAttributeValue(reader,
661                    null, "name", true);
662            final String location =
663                    XmlStreamReaderUtils.readAttributeValue(reader,
664                            null, "location");
665            final boolean sort = parseBooleanAttribute(reader, strict,
666                    null, "sort", false);
667            final boolean retrieve = parseBooleanAttribute(reader, strict,
668                    null, "retrieve", true);
669            XmlStreamReaderUtils.consumeStart(reader);
670
671            List<LocalizedString> titles = null;
672            for (;;) {
673                LocalizedString title =
674                        parseStringI18N(reader, strict, ns, "title", false);
675                if (title == null) {
676                    break;
677                }
678                if (titles == null) {
679                    titles = new ArrayList<LocalizedString>();
680                }
681                titles.add(title);
682            } // for
683            XmlStreamReaderUtils.readEnd(reader, ns, "schema");
684
685            if (schemaInfo == null) {
686                schemaInfo = new ArrayList<Schema>();
687            }
688            schemaInfo.add(new Schema(identifier, name, location, sort,
689                    retrieve, titles));
690            first_schema = false;
691        }
692        return schemaInfo;
693    }
694
695
696    private static Map<String, String> parseConfigInfoItem(
697            XMLStreamReader reader, boolean strict, String ns,
698            String localName, Map<String, String> map)
699            throws XMLStreamException {
700        XmlStreamReaderUtils.readStart(reader, ns, localName, true, true);
701        final String type = XmlStreamReaderUtils.readAttributeValue(reader,
702                null, "type", true);
703        XmlStreamReaderUtils.consumeStart(reader);
704        final String value = XmlStreamReaderUtils.readString(reader, true);
705        XmlStreamReaderUtils.readEnd(reader, ns, localName);
706
707        if ((type != null) && (value != null)) {
708            if (map == null) {
709                map = new HashMap<String, String>();
710            }
711            if (map.containsKey(type)) {
712                logger.warn(
713                        "{} with type '{}' is already present, skipping duplicate entry",
714                        localName, type);
715            } else {
716                map.put(type, value);
717            }
718        }
719        return map;
720    }
721
722} // class SRUExplainRecordDataParser
Note: See TracBrowser for help on using the repository browser.