001/**
002 *
003 * Copyright 2015-2017 Ishan Khanna, Fernando Ramirez, 2019-2021 Florian Schmaus
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.jivesoftware.smackx.geoloc.provider;
018
019import java.io.IOException;
020import java.text.ParseException;
021
022import javax.xml.namespace.QName;
023
024import org.jivesoftware.smack.packet.XmlEnvironment;
025import org.jivesoftware.smack.parsing.SmackParsingException;
026import org.jivesoftware.smack.parsing.SmackParsingException.SmackUriSyntaxParsingException;
027import org.jivesoftware.smack.provider.ExtensionElementProvider;
028import org.jivesoftware.smack.util.ParserUtils;
029import org.jivesoftware.smack.xml.XmlPullParser;
030import org.jivesoftware.smack.xml.XmlPullParserException;
031
032import org.jivesoftware.smackx.geoloc.packet.GeoLocation;
033import org.jivesoftware.smackx.xdata.provider.FormFieldChildElementProvider;
034
035public class GeoLocationProvider extends ExtensionElementProvider<GeoLocation> {
036
037    public static final GeoLocationProvider INSTANCE = new GeoLocationProvider();
038
039    @Override
040    public GeoLocation parse(XmlPullParser parser, int initialDepth, XmlEnvironment xmlEnvironment) throws XmlPullParserException, IOException,
041                    SmackUriSyntaxParsingException, ParseException {
042
043        GeoLocation.Builder builder = GeoLocation.builder();
044
045        outerloop: while (true) {
046            XmlPullParser.Event event = parser.next();
047            switch (event) {
048            case START_ELEMENT:
049                String name = parser.getName();
050                switch (name) {
051                case "accuracy":
052                    builder.setAccuracy(ParserUtils.getDoubleFromNextText(parser));
053                    break;
054                case "alt":
055                    builder.setAlt(ParserUtils.getDoubleFromNextText(parser));
056                    break;
057                case "altaccuracy":
058                    builder.setAltAccuracy(ParserUtils.getDoubleFromNextText(parser));
059                    break;
060                case "area":
061                    builder.setArea(parser.nextText());
062                    break;
063                case "bearing":
064                    builder.setBearing(ParserUtils.getDoubleFromNextText(parser));
065                    break;
066                case "building":
067                    builder.setBuilding(parser.nextText());
068                    break;
069                case "country":
070                    builder.setCountry(parser.nextText());
071                    break;
072                case "countrycode":
073                    builder.setCountryCode(parser.nextText());
074                    break;
075                case "datum":
076                    builder.setDatum(parser.nextText());
077                    break;
078                case "description":
079                    builder.setDescription(parser.nextText());
080                    break;
081                case "error":
082                    parseError(builder, parser);
083                    break;
084                case "floor":
085                    builder.setFloor(parser.nextText());
086                    break;
087                case "lat":
088                    builder.setLat(ParserUtils.getDoubleFromNextText(parser));
089                    break;
090                case "locality":
091                    builder.setLocality(parser.nextText());
092                    break;
093                case "lon":
094                    builder.setLon(ParserUtils.getDoubleFromNextText(parser));
095                    break;
096                case "postalcode":
097                    builder.setPostalcode(parser.nextText());
098                    break;
099                case "region":
100                    builder.setRegion(parser.nextText());
101                    break;
102                case "room":
103                    builder.setRoom(parser.nextText());
104                    break;
105                case "speed":
106                    builder.setSpeed(ParserUtils.getDoubleFromNextText(parser));
107                    break;
108                case "street":
109                    builder.setStreet(parser.nextText());
110                    break;
111                case "text":
112                    builder.setText(parser.nextText());
113                    break;
114                case "timestamp":
115                    builder.setTimestamp(ParserUtils.getDateFromNextText(parser));
116                    break;
117                case "tzo":
118                    builder.setTzo(parser.nextText());
119                    break;
120                case "uri":
121                    builder.setUri(ParserUtils.getUriFromNextText(parser));
122                    break;
123                }
124                break;
125            case END_ELEMENT:
126                if (parser.getDepth() == initialDepth) {
127                    break outerloop;
128                }
129                break;
130            default:
131                // Catch all for incomplete switch (MissingCasesInEnumSwitch) statement.
132                break;
133            }
134        }
135
136        return builder.build();
137    }
138
139    @SuppressWarnings("deprecation")
140    private static void parseError(GeoLocation.Builder builder, XmlPullParser parser) throws XmlPullParserException, IOException {
141        double error = ParserUtils.getDoubleFromNextText(parser);
142        builder.setError(error);
143    }
144
145    public static class GeoLocationFormFieldChildElementProvider extends FormFieldChildElementProvider<GeoLocation> {
146
147        public static final GeoLocationFormFieldChildElementProvider INSTANCE = new GeoLocationFormFieldChildElementProvider();
148
149        @Override
150        public QName getQName() {
151            return GeoLocation.QNAME;
152        }
153
154        @Override
155        public GeoLocation parse(XmlPullParser parser, int initialDepth, XmlEnvironment xmlEnvironment)
156                        throws XmlPullParserException, IOException, SmackParsingException, ParseException {
157            return GeoLocationProvider.INSTANCE.parse(parser, initialDepth, xmlEnvironment);
158        }
159
160    }
161
162}