001/**
002 *
003 * Copyright 2015-2017 Ishan Khanna, Fernando Ramirez
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.packet;
018
019import java.io.Serializable;
020import java.net.URI;
021import java.util.Date;
022import java.util.logging.Level;
023import java.util.logging.Logger;
024
025import org.jivesoftware.smack.packet.ExtensionElement;
026import org.jivesoftware.smack.packet.Message;
027import org.jivesoftware.smack.util.StringUtils;
028import org.jivesoftware.smack.util.XmlStringBuilder;
029
030/**
031 * A GeoLocation Extension packet, which is used by the XMPP clients to exchange their respective geographic locations.
032 *
033 * @see <a href="http://www.xmpp.org/extensions/xep-0080.html">XEP-0080</a>
034 * @author Ishan Khanna
035 */
036public final class GeoLocation implements Serializable, ExtensionElement {
037
038    private static final long serialVersionUID = 1L;
039    public static final String NAMESPACE = "http://jabber.org/protocol/geoloc";
040    public static final String ELEMENT = "geoloc";
041
042    private static final Logger LOGGER = Logger.getLogger(GeoLocation.class.getName());
043
044    private final Double accuracy;
045    private final Double alt;
046    private final Double altAccuracy;
047    private final String area;
048    private final Double bearing;
049    private final String building;
050    private final String country;
051    private final String countryCode;
052    private final String datum;
053    private final String description;
054    private final Double error;
055    private final String floor;
056    private final Double lat;
057    private final String locality;
058    private final Double lon;
059    private final String postalcode;
060    private final String region;
061    private final String room;
062    private final Double speed;
063    private final String street;
064    private final String text;
065    private final Date timestamp;
066    private final String tzo;
067    private final URI uri;
068
069    private GeoLocation(Double accuracy, Double alt, Double altAccuracy, String area, Double bearing, String building, String country,
070                    String countryCode, String datum, String description, Double error, String floor, Double lat,
071                    String locality, Double lon, String postalcode, String region, String room, Double speed,
072                    String street, String text, Date timestamp, String tzo, URI uri) {
073        this.accuracy = accuracy;
074        this.alt = alt;
075        this.altAccuracy = altAccuracy;
076        this.area = area;
077        this.bearing = bearing;
078        this.building = building;
079        this.country = country;
080        this.countryCode = countryCode;
081
082        // If datum is not included, receiver MUST assume WGS84; receivers MUST implement WGS84; senders MAY use another
083        // datum, but it is not recommended.
084
085        if (StringUtils.isNullOrEmpty(datum)) {
086            datum = "WGS84";
087        }
088
089        this.datum = datum;
090        this.description = description;
091
092        // error element is deprecated in favor of accuracy
093        if (accuracy != null) {
094            error = null;
095            LOGGER.log(Level.WARNING,
096                            "Error and accuracy set. Ignoring error as it is deprecated in favor of accuracy");
097        }
098
099        this.error = error;
100        this.floor = floor;
101        this.lat = lat;
102        this.locality = locality;
103        this.lon = lon;
104        this.postalcode = postalcode;
105        this.region = region;
106        this.room = room;
107        this.speed = speed;
108        this.street = street;
109        this.text = text;
110        this.timestamp = timestamp;
111        this.tzo = tzo;
112        this.uri = uri;
113    }
114
115    public Double getAccuracy() {
116        return accuracy;
117    }
118
119    public Double getAlt() {
120        return alt;
121    }
122
123    public Double getAltAccuracy() {
124        return altAccuracy;
125    }
126
127    public String getArea() {
128        return area;
129    }
130
131    public Double getBearing() {
132        return bearing;
133    }
134
135    public String getBuilding() {
136        return building;
137    }
138
139    public String getCountry() {
140        return country;
141    }
142
143    public String getCountryCode() {
144        return countryCode;
145    }
146
147    public String getDatum() {
148        return datum;
149    }
150
151    public String getDescription() {
152        return description;
153    }
154
155    public Double getError() {
156        return error;
157    }
158
159    public String getFloor() {
160        return floor;
161    }
162
163    public Double getLat() {
164        return lat;
165    }
166
167    public String getLocality() {
168        return locality;
169    }
170
171    public Double getLon() {
172        return lon;
173    }
174
175    public String getPostalcode() {
176        return postalcode;
177    }
178
179    public String getRegion() {
180        return region;
181    }
182
183    public String getRoom() {
184        return room;
185    }
186
187    public Double getSpeed() {
188        return speed;
189    }
190
191    public String getStreet() {
192        return street;
193    }
194
195    public String getText() {
196        return text;
197    }
198
199    public Date getTimestamp() {
200        return timestamp;
201    }
202
203    public String getTzo() {
204        return tzo;
205    }
206
207    public URI getUri() {
208        return uri;
209    }
210
211    @Override
212    public String getElementName() {
213        return ELEMENT;
214    }
215
216    @Override
217    public CharSequence toXML(String enclosingNamespace) {
218        XmlStringBuilder xml = new XmlStringBuilder(this);
219        xml.rightAngleBracket();
220        xml.optElement("accuracy", accuracy);
221        xml.optElement("alt", alt);
222        xml.optElement("altaccuracy", altAccuracy);
223        xml.optElement("area", area);
224        xml.optElement("bearing", bearing);
225        xml.optElement("building", building);
226        xml.optElement("country", country);
227        xml.optElement("countrycode", countryCode);
228        xml.optElement("datum", datum);
229        xml.optElement("description", description);
230        xml.optElement("error", error);
231        xml.optElement("floor", floor);
232        xml.optElement("lat", lat);
233        xml.optElement("locality", locality);
234        xml.optElement("lon", lon);
235        xml.optElement("postalcode", postalcode);
236        xml.optElement("region", region);
237        xml.optElement("room", room);
238        xml.optElement("speed", speed);
239        xml.optElement("street", street);
240        xml.optElement("text", text);
241        xml.optElement("timestamp", timestamp);
242        xml.optElement("tzo", tzo);
243        xml.optElement("uri", uri);
244        xml.closeElement(this);
245        return xml;
246    }
247
248    @Override
249    public String getNamespace() {
250        return NAMESPACE;
251    }
252
253    public static Builder builder() {
254        return new GeoLocation.Builder();
255    }
256
257    public static GeoLocation from(Message message) {
258        return message.getExtension(ELEMENT, NAMESPACE);
259    }
260
261    public static class Builder {
262
263        private Double accuracy;
264        private Double alt;
265        private Double altAccuracy;
266        private String area;
267        private Double bearing;
268        private String building;
269        private String country;
270        private String countryCode;
271        private String datum;
272        private String description;
273        private Double error;
274        private String floor;
275        private Double lat;
276        private String locality;
277        private Double lon;
278        private String postalcode;
279        private String region;
280        private String room;
281        private Double speed;
282        private String street;
283        private String text;
284        private Date timestamp;
285        private String tzo;
286        private URI uri;
287
288        public Builder setAccuracy(Double accuracy) {
289            this.accuracy = accuracy;
290            return this;
291        }
292
293        public Builder setAlt(Double alt) {
294            this.alt = alt;
295            return this;
296        }
297
298        public Builder setAltAccuracy(Double altAccuracy) {
299            this.altAccuracy = altAccuracy;
300            return this;
301        }
302
303        public Builder setArea(String area) {
304            this.area = area;
305            return this;
306        }
307
308        public Builder setBearing(Double bearing) {
309            this.bearing = bearing;
310            return this;
311        }
312
313        public Builder setBuilding(String building) {
314            this.building = building;
315            return this;
316        }
317
318        public Builder setCountry(String country) {
319            this.country = country;
320            return this;
321        }
322
323        public Builder setCountryCode(String countryCode) {
324            this.countryCode = countryCode;
325            return this;
326        }
327
328        public Builder setDatum(String datum) {
329            this.datum = datum;
330            return this;
331        }
332
333        public Builder setDescription(String description) {
334            this.description = description;
335            return this;
336        }
337
338        public Builder setError(Double error) {
339            this.error = error;
340            return this;
341        }
342
343        public Builder setFloor(String floor) {
344            this.floor = floor;
345            return this;
346        }
347
348        public Builder setLat(Double lat) {
349            this.lat = lat;
350            return this;
351        }
352
353        public Builder setLocality(String locality) {
354            this.locality = locality;
355            return this;
356        }
357
358        public Builder setLon(Double lon) {
359            this.lon = lon;
360            return this;
361        }
362
363        public Builder setPostalcode(String postalcode) {
364            this.postalcode = postalcode;
365            return this;
366        }
367
368        public Builder setRegion(String region) {
369            this.region = region;
370            return this;
371        }
372
373        public Builder setRoom(String room) {
374            this.room = room;
375            return this;
376        }
377
378        public Builder setSpeed(Double speed) {
379            this.speed = speed;
380            return this;
381        }
382
383        public Builder setStreet(String street) {
384            this.street = street;
385            return this;
386        }
387
388        public Builder setText(String text) {
389            this.text = text;
390            return this;
391        }
392
393        public Builder setTimestamp(Date timestamp) {
394            this.timestamp = timestamp;
395            return this;
396        }
397
398        public Builder setTzo(String tzo) {
399            this.tzo = tzo;
400            return this;
401        }
402
403        public Builder setUri(URI uri) {
404            this.uri = uri;
405            return this;
406        }
407
408        public GeoLocation build() {
409
410            return new GeoLocation(accuracy, alt, altAccuracy, area, bearing, building, country, countryCode, datum, description,
411                            error, floor, lat, locality, lon, postalcode, region, room, speed, street, text, timestamp,
412                            tzo, uri);
413        }
414
415    }
416
417}