From 0d8f3185e5db8e60c117f1645585eccb8077d540 Mon Sep 17 00:00:00 2001 From: Ishan Khanna Date: Fri, 13 Mar 2015 10:08:21 +0400 Subject: [PATCH] Add Support for XEP-80: User Location SMACK-610 --- .../jivesoftware/smack/util/ParserUtils.java | 39 ++ .../smack/util/XmlStringBuilder.java | 7 + .../smackx/geoloc/GeoLocationManager.java | 86 ++++ .../smackx/geoloc/packet/GeoLocation.java | 404 ++++++++++++++++++ .../geoloc/provider/GeoLocationProvider.java | 124 ++++++ .../extensions.providers | 7 + .../smackx/geoloc/packet/GeoLocationTest.java | 125 ++++++ .../provider/GeoLocationProviderTest.java | 229 ++++++++++ 8 files changed, 1021 insertions(+) create mode 100644 smack-extensions/src/main/java/org/jivesoftware/smackx/geoloc/GeoLocationManager.java create mode 100644 smack-extensions/src/main/java/org/jivesoftware/smackx/geoloc/packet/GeoLocation.java create mode 100644 smack-extensions/src/main/java/org/jivesoftware/smackx/geoloc/provider/GeoLocationProvider.java create mode 100644 smack-extensions/src/test/java/org/jivesoftware/smackx/geoloc/packet/GeoLocationTest.java create mode 100644 smack-extensions/src/test/java/org/jivesoftware/smackx/geoloc/provider/GeoLocationProviderTest.java diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/ParserUtils.java b/smack-core/src/main/java/org/jivesoftware/smack/util/ParserUtils.java index 6da85350c..f67b88cdb 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/ParserUtils.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/ParserUtils.java @@ -17,6 +17,10 @@ package org.jivesoftware.smack.util; import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.text.ParseException; +import java.util.Date; import java.util.Locale; import org.jxmpp.jid.BareJid; @@ -24,6 +28,7 @@ import org.jxmpp.jid.Jid; import org.jxmpp.jid.impl.JidCreate; import org.jxmpp.jid.parts.Resourcepart; import org.jxmpp.stringprep.XmppStringprepException; +import org.jxmpp.util.XmppDateTime; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -150,4 +155,38 @@ public class ParserUtils { return l; } } + + public static double getDoubleFromNextText(XmlPullParser parser) throws XmlPullParserException, IOException { + String doubleString = parser.nextText(); + return Double.valueOf(doubleString); + } + + public static Double getDoubleAttribute(XmlPullParser parser, String name) { + String valueString = parser.getAttributeValue("", name); + if (valueString == null) + return null; + return Double.valueOf(valueString); + } + + public static double getDoubleAttribute(XmlPullParser parser, String name, long defaultValue) { + Double d = getDoubleAttribute(parser, name); + if (d == null) { + return defaultValue; + } + else { + return d; + } + } + + public static Date getDateFromNextText(XmlPullParser parser) throws XmlPullParserException, IOException, ParseException { + String dateString = parser.nextText(); + return XmppDateTime.parseDate(dateString); + } + + public static URI getUriFromNextText(XmlPullParser parser) throws XmlPullParserException, IOException, URISyntaxException { + String uriString = parser.nextText(); + URI uri = new URI(uriString); + return uri; + } + } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java b/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java index c422c0e82..437a54e2f 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java @@ -111,6 +111,13 @@ public class XmlStringBuilder implements Appendable, CharSequence { } return this; } + + public XmlStringBuilder optElement(String name, Object object) { + if (object != null) { + element(name, object.toString()); + } + return this; + } public XmlStringBuilder optIntElement(String name, int value) { if (value >= 0) { diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/geoloc/GeoLocationManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/geoloc/GeoLocationManager.java new file mode 100644 index 000000000..c0f4fe3df --- /dev/null +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/geoloc/GeoLocationManager.java @@ -0,0 +1,86 @@ +/** + * + * Copyright 2015-2016 Ishan Khanna + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jivesoftware.smackx.geoloc; + +import java.util.Map; +import java.util.WeakHashMap; + +import org.jivesoftware.smack.ConnectionCreationListener; +import org.jivesoftware.smack.Manager; +import org.jivesoftware.smack.SmackException.NotConnectedException; +import org.jivesoftware.smack.XMPPConnection; +import org.jivesoftware.smack.XMPPConnectionRegistry; +import org.jivesoftware.smack.packet.Message; +import org.jivesoftware.smackx.geoloc.packet.GeoLocation; +import org.jxmpp.jid.Jid; + +public class GeoLocationManager extends Manager { + + private static final Map INSTANCES = new WeakHashMap(); + + static { + XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() { + public void connectionCreated(XMPPConnection connection) { + getInstanceFor(connection); + } + }); + } + + public GeoLocationManager(XMPPConnection connection) { + super(connection); + + } + + /** + * Retrieves a {@link GeoLocationManager} for the specified {@link XMPPConnection}, creating one if it doesn't + * already exist. + * + * @param connection The connection the manager is attached to. + * @return The new or existing manager. + */ + public synchronized static GeoLocationManager getInstanceFor(XMPPConnection connection) { + GeoLocationManager geoLocationManager = INSTANCES.get(connection); + if (geoLocationManager == null) { + geoLocationManager = new GeoLocationManager(connection); + INSTANCES.put(connection, geoLocationManager); + } + return geoLocationManager; + } + + public void sendGeoLocationToJid(GeoLocation geoLocation, Jid jid) throws InterruptedException, + NotConnectedException { + + final XMPPConnection connection = connection(); + + Message geoLocationMessage = new Message(jid); + geoLocationMessage.addExtension(geoLocation); + + connection.sendStanza(geoLocationMessage); + + } + + /** + * Returns true if the message contains a GeoLocation extension. + * + * @param message the message to check if contains a GeoLocation extension or not + * @return a boolean indicating whether the message is a GeoLocation message + */ + public static boolean isGeoLocationMessage(Message message) { + return GeoLocation.from(message) != null; + } + +} diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/geoloc/packet/GeoLocation.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/geoloc/packet/GeoLocation.java new file mode 100644 index 000000000..d868e7a8f --- /dev/null +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/geoloc/packet/GeoLocation.java @@ -0,0 +1,404 @@ +/** + * + * Copyright 2015-2016 Ishan Khanna + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jivesoftware.smackx.geoloc.packet; + +import java.io.Serializable; +import java.net.URI; +import java.util.Date; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.jivesoftware.smack.packet.ExtensionElement; +import org.jivesoftware.smack.packet.Message; +import org.jivesoftware.smack.util.StringUtils; +import org.jivesoftware.smack.util.XmlStringBuilder; + +/** + * A GeoLocation Extension packet, which is used by the XMPP clients to exchange their respective geographic locations. + * + * @see XEP-0080 + * @author Ishan Khanna + */ +public class GeoLocation implements Serializable, ExtensionElement { + + private static final long serialVersionUID = 1L; + public static final String NAMESPACE = "http://jabber.org/protocol/geoloc"; + public static final String ELEMENT = "geoloc"; + + private static final Logger LOGGER = Logger.getLogger(GeoLocation.class.getName()); + + private final Double accuracy; + private final Double alt; + private final String area; + private final Double bearing; + private final String building; + private final String country; + private final String countryCode; + private final String datum; + private final String description; + private final Double error; + private final String floor; + private final Double lat; + private final String locality; + private final Double lon; + private final String postalcode; + private final String region; + private final String room; + private final Double speed; + private final String street; + private final String text; + private final Date timestamp; + private final String tzo; + private final URI uri; + + private GeoLocation(Double accuracy, Double alt, String area, Double bearing, String building, String country, + String countryCode, String datum, String description, Double error, String floor, Double lat, + String locality, Double lon, String postalcode, String region, String room, Double speed, + String street, String text, Date timestamp, String tzo, URI uri) { + this.accuracy = accuracy; + this.alt = alt; + this.area = area; + this.bearing = bearing; + this.building = building; + this.country = country; + this.countryCode = countryCode; + + // If datum is not included, receiver MUST assume WGS84; receivers MUST implement WGS84; senders MAY use another + // datum, but it is not recommended. + + if (StringUtils.isNullOrEmpty(datum)) { + datum = "WGS84"; + } + + this.datum = datum; + this.description = description; + + // error element is deprecated in favor of accuracy + if (accuracy != null) { + error = null; + LOGGER.log(Level.WARNING, + "Error and accurracy set. Ignoring error as it is deprecated in favor of accuracy"); + } + + this.error = error; + this.floor = floor; + this.lat = lat; + this.locality = locality; + this.lon = lon; + this.postalcode = postalcode; + this.region = region; + this.room = room; + this.speed = speed; + this.street = street; + this.text = text; + this.timestamp = timestamp; + this.tzo = tzo; + this.uri = uri; + } + + public Double getAccuracy() { + return accuracy; + } + + public Double getAlt() { + return alt; + } + + public String getArea() { + return area; + } + + public Double getBearing() { + return bearing; + } + + public String getBuilding() { + return building; + } + + public String getCountry() { + return country; + } + + public String getCountryCode() { + return countryCode; + } + + public String getDatum() { + return datum; + } + + public String getDescription() { + return description; + } + + public Double getError() { + return error; + } + + public String getFloor() { + return floor; + } + + public Double getLat() { + return lat; + } + + public String getLocality() { + return locality; + } + + public Double getLon() { + return lon; + } + + public String getPostalcode() { + return postalcode; + } + + public String getRegion() { + return region; + } + + public String getRoom() { + return room; + } + + public Double getSpeed() { + return speed; + } + + public String getStreet() { + return street; + } + + public String getText() { + return text; + } + + public Date getTimestamp() { + return timestamp; + } + + public String getTzo() { + return tzo; + } + + public URI getUri() { + return uri; + } + + @Override + public String getElementName() { + return ELEMENT; + } + + @Override + public CharSequence toXML() { + XmlStringBuilder xml = new XmlStringBuilder(this); + xml.rightAngleBracket(); + xml.optElement("accuracy", String.valueOf(accuracy)); + xml.optElement("alt", String.valueOf(alt)); + xml.optElement("area", area); + xml.optElement("bearing", String.valueOf(bearing)); + xml.optElement("building", building); + xml.optElement("country", country); + xml.optElement("countrycode", countryCode); + xml.optElement("datum", datum); + xml.optElement("description", description); + xml.optElement("error", String.valueOf(error)); + xml.optElement("floor", floor); + xml.optElement("lat", String.valueOf(lat)); + xml.optElement("locality", locality); + xml.optElement("lon", String.valueOf(lon)); + xml.optElement("postalcode", postalcode); + xml.optElement("region", region); + xml.optElement("room", room); + xml.optElement("speed", String.valueOf(speed)); + xml.optElement("street", street); + xml.optElement("text", text); + xml.optElement("timestamp", timestamp); + xml.optElement("tzo", tzo); + xml.optElement("uri", uri); + xml.closeElement(this); + return xml; + } + + @Override + public String getNamespace() { + return NAMESPACE; + } + + public static Builder builder() { + return new GeoLocation.Builder(); + } + + public static GeoLocation from(Message message) { + return message.getExtension(ELEMENT, NAMESPACE); + } + + public static class Builder { + + private Double accuracy; + private Double alt; + private String area; + private Double bearing; + private String building; + private String country; + private String countryCode; + private String datum; + private String description; + private Double error; + private String floor; + private Double lat; + private String locality; + private Double lon; + private String postalcode; + private String region; + private String room; + private Double speed; + private String street; + private String text; + private Date timestamp; + private String tzo; + private URI uri; + + public Builder setAccuracy(Double accuracy) { + this.accuracy = accuracy; + return this; + } + + public Builder setAlt(Double alt) { + this.alt = alt; + return this; + } + + public Builder setArea(String area) { + this.area = area; + return this; + } + + public Builder setBearing(Double bearing) { + this.bearing = bearing; + return this; + } + + public Builder setBuilding(String building) { + this.building = building; + return this; + } + + public Builder setCountry(String country) { + this.country = country; + return this; + } + + public Builder setCountryCode(String countryCode) { + this.countryCode = countryCode; + return this; + } + + public Builder setDatum(String datum) { + this.datum = datum; + return this; + } + + public Builder setDescription(String description) { + this.description = description; + return this; + } + + public Builder setError(Double error) { + this.error = error; + return this; + } + + public Builder setFloor(String floor) { + this.floor = floor; + return this; + } + + public Builder setLat(Double lat) { + this.lat = lat; + return this; + } + + public Builder setLocality(String locality) { + this.locality = locality; + return this; + } + + public Builder setLon(Double lon) { + this.lon = lon; + return this; + } + + public Builder setPostalcode(String postalcode) { + this.postalcode = postalcode; + return this; + } + + public Builder setRegion(String region) { + this.region = region; + return this; + } + + public Builder setRoom(String room) { + this.room = room; + return this; + } + + public Builder setSpeed(Double speed) { + this.speed = speed; + return this; + } + + public Builder setStreet(String street) { + this.street = street; + return this; + } + + public Builder setText(String text) { + this.text = text; + return this; + } + + public Builder setTimestamp(Date timestamp) { + this.timestamp = timestamp; + return this; + } + + public Builder setTzo(String tzo) { + this.tzo = tzo; + return this; + } + + public Builder setUri(URI uri) { + this.uri = uri; + return this; + } + + public GeoLocation build() { + + return new GeoLocation(accuracy, alt, area, bearing, building, country, countryCode, datum, description, + error, floor, lat, locality, lon, postalcode, region, room, speed, street, text, timestamp, + tzo, uri); + } + + } + +} diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/geoloc/provider/GeoLocationProvider.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/geoloc/provider/GeoLocationProvider.java new file mode 100644 index 000000000..88215b363 --- /dev/null +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/geoloc/provider/GeoLocationProvider.java @@ -0,0 +1,124 @@ +/** + * + * Copyright 2015-2016 Ishan Khanna + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jivesoftware.smackx.geoloc.provider; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.text.ParseException; + +import org.jivesoftware.smack.provider.ExtensionElementProvider; +import org.jivesoftware.smack.util.ParserUtils; +import org.jivesoftware.smackx.geoloc.packet.GeoLocation; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +public class GeoLocationProvider extends ExtensionElementProvider { + + @Override + public GeoLocation parse(XmlPullParser parser, int initialDepth) throws XmlPullParserException, IOException, + ParseException, URISyntaxException { + + GeoLocation.Builder builder = GeoLocation.builder(); + + outerloop: while (true) { + int event = parser.next(); + switch (event) { + case XmlPullParser.START_TAG: + String name = parser.getName(); + switch (name) { + case "accuracy": + builder.setAccuracy(ParserUtils.getDoubleFromNextText(parser)); + break; + case "alt": + builder.setAlt(ParserUtils.getDoubleFromNextText(parser)); + break; + case "area": + builder.setArea(parser.nextText()); + break; + case "bearing": + builder.setBearing(ParserUtils.getDoubleFromNextText(parser)); + break; + case "building": + builder.setBuilding(parser.nextText()); + break; + case "country": + builder.setCountry(parser.nextText()); + break; + case "countrycode": + builder.setCountryCode(parser.nextText()); + break; + case "datum": + builder.setDatum(parser.nextText()); + break; + case "description": + builder.setDescription(parser.nextText()); + break; + case "error": + builder.setError(ParserUtils.getDoubleFromNextText(parser)); + break; + case "floor": + builder.setFloor(parser.nextText()); + break; + case "lat": + builder.setLat(ParserUtils.getDoubleFromNextText(parser)); + break; + case "locality": + builder.setLocality(parser.nextText()); + break; + case "lon": + builder.setLon(ParserUtils.getDoubleFromNextText(parser)); + break; + case "postalcode": + builder.setPostalcode(parser.nextText()); + break; + case "region": + builder.setRegion(parser.nextText()); + break; + case "room": + builder.setRoom(parser.nextText()); + break; + case "speed": + builder.setSpeed(ParserUtils.getDoubleFromNextText(parser)); + break; + case "street": + builder.setStreet(parser.nextText()); + break; + case "text": + builder.setText(parser.nextText()); + break; + case "timestamp": + builder.setTimestamp(ParserUtils.getDateFromNextText(parser)); + break; + case "tzo": + builder.setTzo(parser.nextText()); + break; + case "uri": + builder.setUri(ParserUtils.getUriFromNextText(parser)); + break; + } + break; + case XmlPullParser.END_TAG: + if (parser.getDepth() == initialDepth) { + break outerloop; + } + } + } + + return builder.build(); + } + +} diff --git a/smack-extensions/src/main/resources/org.jivesoftware.smack.extensions/extensions.providers b/smack-extensions/src/main/resources/org.jivesoftware.smack.extensions/extensions.providers index 1df8ce353..c3fd21089 100644 --- a/smack-extensions/src/main/resources/org.jivesoftware.smack.extensions/extensions.providers +++ b/smack-extensions/src/main/resources/org.jivesoftware.smack.extensions/extensions.providers @@ -493,4 +493,11 @@ http://jabber.org/protocol/rsm org.jivesoftware.smackx.rsm.provider.RSMSetProvider + + + + geoloc + http://jabber.org/protocol/geoloc + org.jivesoftware.smackx.geoloc.provider.GeoLocationProvider + diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/geoloc/packet/GeoLocationTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/geoloc/packet/GeoLocationTest.java new file mode 100644 index 000000000..cec9fd1e1 --- /dev/null +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/geoloc/packet/GeoLocationTest.java @@ -0,0 +1,125 @@ +/** + * + * Copyright 2015-2016 Ishan Khanna + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jivesoftware.smackx.geoloc.packet; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.net.URI; +import java.util.Calendar; +import java.util.TimeZone; + +import org.jivesoftware.smack.packet.Message; +import org.jivesoftware.smack.util.PacketParserUtils; +import org.jivesoftware.smackx.InitExtensions; +import org.jivesoftware.smackx.time.packet.Time; +import org.junit.Test; +import org.jxmpp.util.XmppDateTime; + +/** + * Unit tests for GeoLocation. + * + * @author Ishan Khanna + */ +public class GeoLocationTest extends InitExtensions { + + @Test + public void negativeTimezoneTest() { + Calendar calendar = Calendar.getInstance(); + calendar.setTimeZone(TimeZone.getTimeZone("GMT-830")); + + Time time = new Time(calendar); + + GeoLocation geoLocation = new GeoLocation.Builder().setTzo(time.getTzo()).build(); + + assertEquals("-8:30", geoLocation.getTzo()); + } + + @Test + public void positiveTimezonTest() { + Calendar calendar = Calendar.getInstance(); + calendar.setTimeZone(TimeZone.getTimeZone("GMT+530")); + + Time time = new Time(calendar); + + GeoLocation geoLocation = new GeoLocation.Builder().setTzo(time.getTzo()).build(); + + assertEquals("+5:30", geoLocation.getTzo()); + + } + + @Test + public void accuracyTest() { + + GeoLocation geoLocation = new GeoLocation.Builder().setAccuracy(1.34d).build(); + + assertEquals((Double) 1.34, geoLocation.getAccuracy()); + } + + @Test + public void toXMLMethodTest() throws Exception { + + // @formatter:off + final String geoLocationMessageString = "" + +"" + +"23" + +"1000" + +"Delhi" + +"10" + +"Small Building" + +"India" + +"IN" + +"My Description" + +"90" + +"top" + +"25.098345" + +"awesome" + +"77.992034" + +"110085" + +"North" + +"small" + +"250.0" + +"Wall Street" + +"Unit Testing GeoLocation" + +"2004-02-19" + +"+5:30" + +"http://xmpp.org" + +"" + +""; + // @formatter:on + + Message messageWithGeoLocation = (Message) PacketParserUtils.parseStanza(geoLocationMessageString); + assertNotNull(messageWithGeoLocation); + + GeoLocation geoLocation = (GeoLocation) messageWithGeoLocation.getExtension(GeoLocation.ELEMENT, + GeoLocation.NAMESPACE); + assertNotNull(geoLocation); + assertNotNull(geoLocation.toXML()); + + GeoLocation constructedGeoLocation = GeoLocation.builder().setAccuracy(23d).setAlt(1000d).setArea("Delhi").setBearing( + 10d).setBuilding("Small Building").setCountry("India").setCountryCode("IN").setDescription( + "My Description").setError(90d).setFloor("top").setLat(25.098345d).setLocality("awesome").setLon( + 77.992034).setPostalcode("110085").setRegion("North").setRoom("small").setSpeed(250.0d).setStreet( + "Wall Street").setText("Unit Testing GeoLocation").setTimestamp( + XmppDateTime.parseDate("2004-02-19")).setTzo("+5:30").setUri(new URI("http://xmpp.org")).build(); + + assertEquals(constructedGeoLocation.toXML().toString(), geoLocation.toXML().toString()); + + } + +} diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/geoloc/provider/GeoLocationProviderTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/geoloc/provider/GeoLocationProviderTest.java new file mode 100644 index 000000000..be15d1a86 --- /dev/null +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/geoloc/provider/GeoLocationProviderTest.java @@ -0,0 +1,229 @@ +/** + * + * Copyright 2015-2016 Ishan Khanna + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jivesoftware.smackx.geoloc.provider; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import java.net.URI; + +import org.jivesoftware.smack.packet.Message; +import org.jivesoftware.smack.util.PacketParserUtils; +import org.jivesoftware.smackx.InitExtensions; +import org.jivesoftware.smackx.geoloc.packet.GeoLocation; +import org.junit.Test; +import org.jxmpp.util.XmppDateTime; + +public class GeoLocationProviderTest extends InitExtensions { + + @Test + public void testGeoLocationProviderWithNoDatumSet() throws Exception { + // @formatter:off + final String geoLocationString = "" + +"" + +"23" + +"1000" + +"Delhi" + +"10" + +"Small Building" + +"India" + +"IN" + +"My Description" + +"90" + +"top" + +"25.098345" + +"awesome" + +"77.992034" + +"110085" + +"North" + +"small" + +"250.0" + +"Wall Street" + +"Unit Testing GeoLocation" + +"2004-02-19" + +"+5:30" + +"http://xmpp.org" + +"" + +""; + // @formatter:on + + Message messageWithGeoLocation = (Message) PacketParserUtils.parseStanza(geoLocationString); + assertNotNull(messageWithGeoLocation); + + GeoLocation geoLocation = (GeoLocation) messageWithGeoLocation.getExtension(GeoLocation.ELEMENT, + GeoLocation.NAMESPACE); + assertNotNull(geoLocation); + + assertEquals((Double) 23d, geoLocation.getAccuracy()); + assertEquals((Double) 1000d, geoLocation.getAlt()); + assertEquals("Delhi", geoLocation.getArea()); + assertEquals((Double) 10d, geoLocation.getBearing()); + assertEquals("Small Building", geoLocation.getBuilding()); + assertEquals("India", geoLocation.getCountry()); + assertEquals("IN", geoLocation.getCountryCode()); + assertEquals("WGS84", geoLocation.getDatum()); + assertEquals("My Description", geoLocation.getDescription()); + assertNull(geoLocation.getError()); + assertEquals("top", geoLocation.getFloor()); + assertEquals((Double) 25.098345d, geoLocation.getLat()); + assertEquals("awesome", geoLocation.getLocality()); + assertEquals((Double) 77.992034d, geoLocation.getLon()); + assertEquals("110085", geoLocation.getPostalcode()); + assertEquals("North", geoLocation.getRegion()); + assertEquals("small", geoLocation.getRoom()); + assertEquals((Double) 250d, geoLocation.getSpeed()); + assertEquals("Wall Street", geoLocation.getStreet()); + assertEquals("Unit Testing GeoLocation", geoLocation.getText()); + assertEquals(XmppDateTime.parseDate("2004-02-19"), geoLocation.getTimestamp()); + assertEquals("+5:30", geoLocation.getTzo()); + assertEquals(new URI("http://xmpp.org"), geoLocation.getUri()); + + } + + @Test + public void testGeoLocationWithDatumSet() throws Exception { + + // @formatter:off + final String geoLocationString = "" + +"" + +"23" + +"1000" + +"Delhi" + +"10" + +"Small Building" + +"India" + +"IN" + +"Test Datum" + +"My Description" + +"90" + +"top" + +"25.098345" + +"awesome" + +"77.992034" + +"110085" + +"North" + +"small" + +"250.0" + +"Wall Street" + +"Unit Testing GeoLocation" + +"2004-02-19" + +"+5:30" + +"http://xmpp.org" + +"" + +""; + // @formatter:on + + Message messageWithGeoLocation = (Message) PacketParserUtils.parseStanza(geoLocationString); + assertNotNull(messageWithGeoLocation); + + GeoLocation geoLocation = (GeoLocation) messageWithGeoLocation.getExtension(GeoLocation.ELEMENT, + GeoLocation.NAMESPACE); + assertNotNull(geoLocation); + + assertEquals((Double) 23d, geoLocation.getAccuracy()); + assertEquals((Double) 1000d, geoLocation.getAlt()); + assertEquals("Delhi", geoLocation.getArea()); + assertEquals((Double) 10d, geoLocation.getBearing()); + assertEquals("Small Building", geoLocation.getBuilding()); + assertEquals("India", geoLocation.getCountry()); + assertEquals("IN", geoLocation.getCountryCode()); + assertEquals("Test Datum", geoLocation.getDatum()); + assertEquals("My Description", geoLocation.getDescription()); + assertNull(geoLocation.getError()); + assertEquals("top", geoLocation.getFloor()); + assertEquals((Double) 25.098345d, geoLocation.getLat()); + assertEquals("awesome", geoLocation.getLocality()); + assertEquals((Double) 77.992034d, geoLocation.getLon()); + assertEquals("110085", geoLocation.getPostalcode()); + assertEquals("North", geoLocation.getRegion()); + assertEquals("small", geoLocation.getRoom()); + assertEquals((Double) 250d, geoLocation.getSpeed()); + assertEquals("Wall Street", geoLocation.getStreet()); + assertEquals("Unit Testing GeoLocation", geoLocation.getText()); + assertEquals(XmppDateTime.parseDate("2004-02-19"), geoLocation.getTimestamp()); + assertEquals("+5:30", geoLocation.getTzo()); + assertEquals(new URI("http://xmpp.org"), geoLocation.getUri()); + + } + + @Test + public void testGeoLocationWithoutAccuracySetAndWithErrorSet() throws Exception { + + // @formatter:off + final String geoLocationString = "" + +"" + +"90" + +"" + +""; + // @formatter:on + + Message messageWithGeoLocation = (Message) PacketParserUtils.parseStanza(geoLocationString); + + GeoLocation geoLocation = (GeoLocation) messageWithGeoLocation.getExtension(GeoLocation.ELEMENT, + GeoLocation.NAMESPACE); + + assertEquals((Double) 90d, geoLocation.getError()); + } + + @Test + public void testGeoLocationWithAccuracySetAndWithoutErrorSet() throws Exception { + + // @formatter:off + final String geoLocationString = "" + +"" + +"90" + +"" + +""; + // @formatter:on + + Message messageWithGeoLocation = (Message) PacketParserUtils.parseStanza(geoLocationString); + + GeoLocation geoLocation = (GeoLocation) messageWithGeoLocation.getExtension(GeoLocation.ELEMENT, + GeoLocation.NAMESPACE); + + assertEquals((Double) 90d, geoLocation.getAccuracy()); + } + + @Test + public void testGeoLocationWithAccuracySetAndErrorSet() throws Exception { + + // @formatter:off + final String geoLocationString = "" + +"" + +"90" + +"100" + +"" + +""; + // @formatter:on + + Message messageWithGeoLocation = (Message) PacketParserUtils.parseStanza(geoLocationString); + + GeoLocation geoLocation = (GeoLocation) messageWithGeoLocation.getExtension(GeoLocation.ELEMENT, + GeoLocation.NAMESPACE); + + assertEquals((Double) 90d, geoLocation.getAccuracy()); + assertNull(geoLocation.getError()); + + } + +}