public Version initialize()

in endorsed/src/org.apache.sis.storage.xml/main/org/apache/sis/storage/gpx/Reader.java [145:247]


    public Version initialize(final boolean readMetadata) throws DataStoreException,
            XMLStreamException, JAXBException, URISyntaxException, EOFException
    {
        /*
         * Skip comments, characters, entity declarations, etc. until we find the root element.
         * If that root is anything other than <gpx>, we consider that this is not a GPX file.
         */
        moveToRootElement(Reader::isGPX, Tags.GPX);
        /*
         * If a version attribute is found on the <gpx> element, use that value for detecting the GPX version.
         * If a version is specified, we require major.minor version 1.0 or 1.1 but accept any bug-fix versions
         * (e.g. 1.1.x). If no version attribute was found, try to infer the version from the namespace URL.
         */
        namespace = reader.getNamespaceURI();
        String ver = reader.getAttributeValue(null, Attributes.VERSION);
        Version version = null;
        if (ver != null) {
            version = new Version(ver);
            if (version.compareTo(StoreProvider.V1_0, 2) < 0 ||
                version.compareTo(StoreProvider.V1_1, 2) > 0)
            {
                throw new DataStoreContentException(errors().getString(
                        Errors.Keys.UnsupportedFormatVersion_2, owner.getFormatName(), version));
            }
        } else if (namespace != null) {
            switch (namespace) {
                case Tags.NAMESPACE_V10: version = StoreProvider.V1_0; break;
                case Tags.NAMESPACE_V11: version = StoreProvider.V1_1; break;
            }
        }
        /*
         * Read metadata immediately, from current position until the beginning of way points, tracks or routes.
         * The metadata can appear in two forms:
         *
         *   - In GPX 1.0, they are declared directly in the <gpx> body.
         *     Those elements are parsed in the switch statement below.
         *
         *   - In GPX 1.1, they are declared in a <metadata> sub-element and their structure is a little bit
         *     more elaborated than what it was in the previous version. We will use JAXB for parsing them.
         */
parse:  while (reader.hasNext()) {
            switch (next()) {
                case START_ELEMENT: {
                    /*
                     * GPX 1.0 and 1.1 metadata should not be mixed. However, the following code will work even
                     * if GPX 1.0 metadata like <name> or <author> appear after the GPX 1.1 <metadata> element.
                     * If both kind of metadata are specified, the latest value overwrites the values before it.
                     */
                    if (isGPX()) {
                        final String name = reader.getLocalName();
                        if (readMetadata) {
                            switch (name) {
                                // GPX 1.1 metadata
                                case Tags.METADATA:     metadata = unmarshal(Metadata.class); break;

                                // GPX 1.0 metadata
                                case Tags.NAME:         metadata().name        = getElementText();        break;
                                case Tags.DESCRIPTION:  metadata().description = getElementText();        break;
                                case Tags.AUTHOR:       author()  .name        = getElementText();        break;
                                case Tags.EMAIL:        author()  .email       = getElementText();        break;
                                case Tags.URL:          link()    .uri         = getElementAsURI();       break;
                                case Tags.URL_NAME:     link()    .text        = getElementText();        break;
                                case Tags.TIME:         metadata().time        = getElementAsDate();      break;
                                case Tags.KEYWORDS:     metadata().keywords    = getElementAsList();      break;
                                case Tags.BOUNDS:       metadata().bounds      = unmarshal(Bounds.class); break;
                                case Tags.WAY_POINT:    // stop metadata parsing.
                                case Tags.TRACKS:
                                case Tags.ROUTES:       break parse;
                                case Tags.GPX:          throw new DataStoreContentException(nestedElement(Tags.GPX));
                            }
                        } else {
                            /*
                             * If the caller asked to skip metadata, just look for the end of metadata elements.
                             */
                            switch (name) {
                                case Tags.METADATA:  skipUntilEnd(reader.getName()); break;
                                case Tags.WAY_POINT:
                                case Tags.TRACKS:
                                case Tags.ROUTES:    break parse;
                                case Tags.GPX:       throw new DataStoreContentException(nestedElement(Tags.GPX));
                            }
                        }
                    }
                    break;
                }
                case END_ELEMENT: {
                    /*
                     * Reminder: calling next() after getElementText(), getElementAsFoo() and unmarshal(…) methods
                     * moves the reader after the END_ELEMENT event. Consequently, there is only the enclosing <gpx>
                     * tag to check here.
                     */
                    if (isEndGPX()) {
                        break parse;
                    }
                    break;
                }
            }
        }
        if (readMetadata) {
            metadata().store = (Store) owner;
        }
        return version;
    }