From e2aace0c3370ee8a23539c53965326c2e463a834 Mon Sep 17 00:00:00 2001 From: Chris Broadfoot Date: Fri, 3 Oct 2014 13:52:35 +1000 Subject: [PATCH] Add extra safety to unmarshaling to enums. Removes existing TravelModeAdapter, AddressTypeAdapter and AddressComponentTypeAdapter, replaces them with generic SafeEnumAdapter. Add tests that check converting UNKNOWN to a UrlValue throws an exception. --- .../internal/AddressComponentTypeAdapter.java | 58 ------ .../maps/internal/AddressTypeAdapter.java | 58 ------ .../maps/internal/OkHttpPendingResult.java | 14 +- .../google/maps/internal/SafeEnumAdapter.java | 69 +++++++ .../maps/internal/TravelModeAdapter.java | 57 ------ .../maps/model/AddressComponentType.java | 173 ++++-------------- .../com/google/maps/model/LocationType.java | 23 +-- .../com/google/maps/model/TravelMode.java | 34 +--- src/main/java/com/google/maps/model/Unit.java | 15 +- .../com/google/maps/GeocodingApiTest.java | 1 + .../java/com/google/maps/model/EnumsTest.java | 47 +++++ 11 files changed, 172 insertions(+), 377 deletions(-) delete mode 100644 src/main/java/com/google/maps/internal/AddressComponentTypeAdapter.java delete mode 100644 src/main/java/com/google/maps/internal/AddressTypeAdapter.java create mode 100644 src/main/java/com/google/maps/internal/SafeEnumAdapter.java delete mode 100644 src/main/java/com/google/maps/internal/TravelModeAdapter.java create mode 100644 src/test/java/com/google/maps/model/EnumsTest.java diff --git a/src/main/java/com/google/maps/internal/AddressComponentTypeAdapter.java b/src/main/java/com/google/maps/internal/AddressComponentTypeAdapter.java deleted file mode 100644 index 4aaa7ed7d..000000000 --- a/src/main/java/com/google/maps/internal/AddressComponentTypeAdapter.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2014 Google Inc. All rights reserved. - * - * - * 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 com.google.maps.internal; - -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonToken; -import com.google.gson.stream.JsonWriter; -import com.google.maps.model.AddressComponentType; - -import java.io.IOException; - -/** - * This class handles conversion from JSON to {@link AddressComponentType}s. - * - *

Please see - * - * here for more detail. - */ -public class AddressComponentTypeAdapter extends TypeAdapter { - - /** - * Read a address component type from a Geocoding API result and convert it to a - * {@link AddressComponentType}. - */ - @Override - public AddressComponentType read(JsonReader reader) throws IOException { - if (reader.peek() == JsonToken.NULL) { - reader.nextNull(); - return null; - } - - return AddressComponentType.lookup(reader.nextString()); - } - - /** - * This method is not implemented. - */ - @Override - public void write(JsonWriter writer, AddressComponentType value) throws IOException { - throw new UnsupportedOperationException("Unimplemented method"); - } - -} - diff --git a/src/main/java/com/google/maps/internal/AddressTypeAdapter.java b/src/main/java/com/google/maps/internal/AddressTypeAdapter.java deleted file mode 100644 index ea27aea8e..000000000 --- a/src/main/java/com/google/maps/internal/AddressTypeAdapter.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2014 Google Inc. All rights reserved. - * - * - * 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 com.google.maps.internal; - -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonToken; -import com.google.gson.stream.JsonWriter; -import com.google.maps.model.AddressType; - -import java.io.IOException; - -/** - * This class handles conversion from JSON to {@link AddressType}s. - * - *

Please see - * - * here for more detail. - */ -public class AddressTypeAdapter extends TypeAdapter { - - /** - * Read a address component type from a Geocoding API result and convert it to a - * {@link com.google.maps.model.AddressComponentType}. - */ - @Override - public AddressType read(JsonReader reader) throws IOException { - if (reader.peek() == JsonToken.NULL) { - reader.nextNull(); - return null; - } - - return AddressType.lookup(reader.nextString()); - } - - /** - * This method is not implemented. - */ - @Override - public void write(JsonWriter writer, AddressType value) throws IOException { - throw new UnsupportedOperationException("Unimplemented method"); - } - -} - diff --git a/src/main/java/com/google/maps/internal/OkHttpPendingResult.java b/src/main/java/com/google/maps/internal/OkHttpPendingResult.java index cdf3fb3d2..9734c4cf9 100644 --- a/src/main/java/com/google/maps/internal/OkHttpPendingResult.java +++ b/src/main/java/com/google/maps/internal/OkHttpPendingResult.java @@ -21,11 +21,7 @@ import com.google.maps.PendingResult; import com.google.maps.errors.ApiException; import com.google.maps.errors.OverQueryLimitException; -import com.google.maps.model.AddressComponentType; -import com.google.maps.model.AddressType; -import com.google.maps.model.Distance; -import com.google.maps.model.Duration; -import com.google.maps.model.TravelMode; +import com.google.maps.model.*; import com.squareup.okhttp.Call; import com.squareup.okhttp.Callback; @@ -207,12 +203,14 @@ private T parseResponse(OkHttpPendingResult request, Response response) th } Gson gson = new GsonBuilder() - .registerTypeAdapter(AddressComponentType.class, new AddressComponentTypeAdapter()) - .registerTypeAdapter(AddressType.class, new AddressTypeAdapter()) .registerTypeAdapter(DateTime.class, new DateTimeAdapter()) .registerTypeAdapter(Distance.class, new DistanceAdapter()) .registerTypeAdapter(Duration.class, new DurationAdapter()) - .registerTypeAdapter(TravelMode.class, new TravelModeAdapter()) + .registerTypeAdapter(AddressComponentType.class, + new SafeEnumAdapter<>(AddressComponentType.UNKNOWN)) + .registerTypeAdapter(AddressType.class, new SafeEnumAdapter<>(AddressType.UNKNOWN)) + .registerTypeAdapter(TravelMode.class, new SafeEnumAdapter<>(TravelMode.UNKNOWN)) + .registerTypeAdapter(LocationType.class, new SafeEnumAdapter<>(LocationType.UNKNOWN)) .setFieldNamingPolicy(fieldNamingPolicy) .create(); diff --git a/src/main/java/com/google/maps/internal/SafeEnumAdapter.java b/src/main/java/com/google/maps/internal/SafeEnumAdapter.java new file mode 100644 index 000000000..098528d37 --- /dev/null +++ b/src/main/java/com/google/maps/internal/SafeEnumAdapter.java @@ -0,0 +1,69 @@ +/* + * Copyright 2014 Google Inc. All rights reserved. + * + * + * 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 com.google.maps.internal; + +import com.google.gson.TypeAdapter; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonToken; +import com.google.gson.stream.JsonWriter; + +import java.io.IOException; +import java.util.Locale; +import java.util.logging.Logger; + +/** + * A {@link com.google.gson.TypeAdapter} that maps case-insensitive values to an enum type. If the + * value is not found, an UNKNOWN value is returned, and logged. This allows the server to return + * values this client doesn't yet know about. + * @param the enum type to map values to. + */ +public class SafeEnumAdapter> extends TypeAdapter { + + private static Logger log = Logger.getLogger(SafeEnumAdapter.class.getName()); + + private final Class clazz; + private final E unknownValue; + + /** + * @param unknownValue the value to return if the value cannot be found. + */ + public SafeEnumAdapter(E unknownValue) { + if (unknownValue == null) throw new IllegalArgumentException(); + + this.unknownValue = unknownValue; + this.clazz = unknownValue.getDeclaringClass(); + } + + @Override + public void write(JsonWriter out, E value) throws IOException { + throw new UnsupportedOperationException("Unimplemented method"); + } + + @Override + public E read(JsonReader reader) throws IOException { + if (reader.peek() == JsonToken.NULL) { + reader.nextNull(); + return null; + } + String value = reader.nextString(); + try { + return Enum.valueOf(clazz, value.toUpperCase(Locale.ENGLISH)); + } catch (IllegalArgumentException iae) { + log.warning(String.format("Unknown type for enum %s: '%s'", clazz.getName(), value)); + return unknownValue; + } + } +} diff --git a/src/main/java/com/google/maps/internal/TravelModeAdapter.java b/src/main/java/com/google/maps/internal/TravelModeAdapter.java deleted file mode 100644 index 01ef85bfb..000000000 --- a/src/main/java/com/google/maps/internal/TravelModeAdapter.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2014 Google Inc. All rights reserved. - * - * - * 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 com.google.maps.internal; - -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonToken; -import com.google.gson.stream.JsonWriter; -import com.google.maps.model.TravelMode; - -import java.io.IOException; - -/** - * This class handles conversion from JSON to {@link TravelMode}s. - * - *

Please see - * {@url https://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/TypeAdapter.html} - * for more detail. - */ -public class TravelModeAdapter extends TypeAdapter { - - /** - * Read a travel mode from a Directions API result and convert it to a {@link TravelMode}. - */ - @Override - public TravelMode read(JsonReader reader) throws IOException { - if (reader.peek() == JsonToken.NULL) { - reader.nextNull(); - return null; - } - - return TravelMode.lookup(reader.nextString()); - } - - /** - * This method is not implemented. - */ - @Override - public void write(JsonWriter writer, TravelMode value) throws IOException { - throw new UnsupportedOperationException("Unimplemented method"); - } - -} - diff --git a/src/main/java/com/google/maps/model/AddressComponentType.java b/src/main/java/com/google/maps/model/AddressComponentType.java index 07414bd3d..4f08f02e7 100644 --- a/src/main/java/com/google/maps/model/AddressComponentType.java +++ b/src/main/java/com/google/maps/model/AddressComponentType.java @@ -15,9 +15,6 @@ package com.google.maps.model; -import java.util.logging.Level; -import java.util.logging.Logger; - /** * The Adress Component types. Please see * Address Component @@ -28,288 +25,194 @@ public enum AddressComponentType { /** * {@code STREET_ADDRESS} indicates a precise street address. */ - STREET_ADDRESS("street_address"), + STREET_ADDRESS, /** * {@code ROUTE} indicates a named route (such as "US 101"). */ - ROUTE("route"), + ROUTE, /** * {@code INTERSECTION} indicates a major intersection, usually of two major roads. */ - INTERSECTION("intersection"), + INTERSECTION, /** * {@code POLITICAL} indicates a political entity. Usually, this type indicates a polygon of * some civil administration. */ - POLITICAL("political"), + POLITICAL, /** * {@code COUNTRY} indicates the national political entity, and is typically the highest order * type returned by the Geocoder. */ - COUNTRY("country"), + COUNTRY, /** * {@code ADMINISTRATIVE_AREA_LEVEL_1} indicates a first-order civil entity below the country * level. Within the United States, these administrative levels are states. Not all nations * exhibit these administrative levels. */ - ADMINISTRATIVE_AREA_LEVEL_1("administrative_area_level_1"), + ADMINISTRATIVE_AREA_LEVEL_1, /** * {@code ADMINISTRATIVE_AREA_LEVEL_2} indicates a second-order civil entity below the country * level. Within the United States, these administrative levels are counties. Not all nations * exhibit these administrative levels. */ - ADMINISTRATIVE_AREA_LEVEL_2("administrative_area_level_2"), + ADMINISTRATIVE_AREA_LEVEL_2, /** * {@code ADMINISTRATIVE_AREA_LEVEL_3} indicates a third-order civil entity below the country * level. This type indicates a minor civil division. Not all nations exhibit these * administrative levels. */ - ADMINISTRATIVE_AREA_LEVEL_3("administrative_area_level_3"), + ADMINISTRATIVE_AREA_LEVEL_3, /** * {@code ADMINISTRATIVE_AREA_LEVEL_4} indicates a fourth-order civil entity below the country * level. This type indicates a minor civil division. Not all nations exhibit these * administrative levels. */ - ADMINISTRATIVE_AREA_LEVEL_4("administrative_area_level_4"), + ADMINISTRATIVE_AREA_LEVEL_4, /** * {@code ADMINISTRATIVE_AREA_LEVEL_5} indicates a fifth-order civil entity below the country * level. This type indicates a minor civil division. Not all nations exhibit these * administrative levels. */ - ADMINISTRATIVE_AREA_LEVEL_5("administrative_area_level_5"), + ADMINISTRATIVE_AREA_LEVEL_5, /** * {@code COLLOQUIAL_AREA} indicates a commonly-used alternative name for the entity. */ - COLLOQUIAL_AREA("colloquial_area"), + COLLOQUIAL_AREA, /** * {@code LOCALITY} indicates an incorporated city or town political entity. */ - LOCALITY("locality"), + LOCALITY, /** * {@code SUBLOCALITY} indicates a first-order civil entity below a locality. For some locations * may receive one of the additional types: sublocality_level_1 to sublocality_level_5. Each * sublocality level is a civil entity. Larger numbers indicate a smaller geographic area. */ - SUBLOCALITY("sublocality"), - SUBLOCALITY_LEVEL_1("sublocality_level_1"), - SUBLOCALITY_LEVEL_2("sublocality_level_2"), - SUBLOCALITY_LEVEL_3("sublocality_level_3"), - SUBLOCALITY_LEVEL_4("sublocality_level_4"), - SUBLOCALITY_LEVEL_5("sublocality_level_5"), + SUBLOCALITY, + SUBLOCALITY_LEVEL_1, + SUBLOCALITY_LEVEL_2, + SUBLOCALITY_LEVEL_3, + SUBLOCALITY_LEVEL_4, + SUBLOCALITY_LEVEL_5, /** * {@code NEIGHBORHOOD} indicates a named neighborhood. */ - NEIGHBORHOOD("neighborhood"), + NEIGHBORHOOD, /** * {@code PREMISE} indicates a named location, usually a building or collection of buildings * with a common name. */ - PREMISE("premise"), + PREMISE, /** * {@code SUBPREMISE} indicates a first-order entity below a named location, usually a singular * building within a collection of buildings with a common name */ - SUBPREMISE("subpremise"), + SUBPREMISE, /** * {@code POSTAL_CODE} indicates a postal code as used to address postal mail within the * country. */ - POSTAL_CODE("postal_code"), + POSTAL_CODE, /** * {@code POSTAL_CODE_SUFFIX} indicates a postal code suffix as used to address postal mail within the * country. */ - POSTAL_CODE_SUFFIX("postal_code_suffix"), + POSTAL_CODE_SUFFIX, /** * {@code NATURAL_FEATURE} indicates a prominent natural feature. */ - NATURAL_FEATURE("natural_feature"), + NATURAL_FEATURE, /** * {@code AIRPORT} indicates an airport. */ - AIRPORT("airport"), + AIRPORT, /** * {@code PARK} indicates a named park. */ - PARK("park"), + PARK, /** * {@code POINT_OF_INTEREST} indicates a named point of interest. Typically, these "POI"s are * prominent local entities that don't easily fit in another category, such as "Empire State * Building" or "Statue of Liberty." */ - POINT_OF_INTEREST("point_of_interest"), + POINT_OF_INTEREST, /** * {@code FLOOR} indicates the floor of a building address. */ - FLOOR("floor"), + FLOOR, /** * {@code ESTABLISHMENT} typically indicates a place that has not yet been categorized. */ - ESTABLISHMENT("establishment"), + ESTABLISHMENT, /** * {@code PARKING} indicates a parking lot or parking structure. */ - PARKING("parking"), + PARKING, /** * {@code POST_BOX} indicates a specific postal box. */ - POST_BOX("post_box"), + POST_BOX, /** * {@code POSTAL_TOWN} indicates a grouping of geographic areas, such as locality and * sublocality, used for mailing addresses in some countries. */ - POSTAL_TOWN("postal_town"), + POSTAL_TOWN, /** * {@code ROOM} indicates the room of a building address. */ - ROOM("room"), + ROOM, /** * {@code STREET_NUMBER} indicates the precise street number. */ - STREET_NUMBER("street_number"), + STREET_NUMBER, /** * {@code BUS_STATION} indicates the location of a bus stop. */ - BUS_STATION("bus_station"), + BUS_STATION, /** * {@code TRAIN_STATION} indicates the location of a train station. */ - TRAIN_STATION("train_station"), + TRAIN_STATION, /** * {@code TRANSIT_STATION} indicates the location of a transit station. */ - TRANSIT_STATION("transit_station"), + TRANSIT_STATION, /** * Indicates an unknown address component type returned by the server. The Java Client for Google * Maps Services should be updated to support the new value. */ - UNKNOWN("unknown"); - - private static Logger log = Logger.getLogger(AddressComponentType.class.getName()); - - private String addressComponentType; - - AddressComponentType(String addressComponentType) { - this.addressComponentType = addressComponentType; - } - - @Override - public String toString() { - return addressComponentType; - } - - public static AddressComponentType lookup(String addressComponentType) { - if (addressComponentType.equalsIgnoreCase(STREET_ADDRESS.toString())) { - return STREET_ADDRESS; - } else if (addressComponentType.equalsIgnoreCase(ROUTE.toString())) { - return ROUTE; - } else if (addressComponentType.equalsIgnoreCase(INTERSECTION.toString())) { - return INTERSECTION; - } else if (addressComponentType.equalsIgnoreCase(POLITICAL.toString())) { - return POLITICAL; - } else if (addressComponentType.equalsIgnoreCase(COUNTRY.toString())) { - return COUNTRY; - } else if (addressComponentType.equalsIgnoreCase(ADMINISTRATIVE_AREA_LEVEL_1.toString())) { - return ADMINISTRATIVE_AREA_LEVEL_1; - } else if (addressComponentType.equalsIgnoreCase(ADMINISTRATIVE_AREA_LEVEL_2.toString())) { - return ADMINISTRATIVE_AREA_LEVEL_2; - } else if (addressComponentType.equalsIgnoreCase(ADMINISTRATIVE_AREA_LEVEL_3.toString())) { - return ADMINISTRATIVE_AREA_LEVEL_3; - } else if (addressComponentType.equalsIgnoreCase(ADMINISTRATIVE_AREA_LEVEL_4.toString())) { - return ADMINISTRATIVE_AREA_LEVEL_4; - } else if (addressComponentType.equalsIgnoreCase(ADMINISTRATIVE_AREA_LEVEL_5.toString())) { - return ADMINISTRATIVE_AREA_LEVEL_5; - } else if (addressComponentType.equalsIgnoreCase(COLLOQUIAL_AREA.toString())) { - return COLLOQUIAL_AREA; - } else if (addressComponentType.equalsIgnoreCase(LOCALITY.toString())) { - return LOCALITY; - } else if (addressComponentType.equalsIgnoreCase(SUBLOCALITY.toString())) { - return SUBLOCALITY; - } else if (addressComponentType.equalsIgnoreCase(NEIGHBORHOOD.toString())) { - return NEIGHBORHOOD; - } else if (addressComponentType.equalsIgnoreCase(PREMISE.toString())) { - return PREMISE; - } else if (addressComponentType.equalsIgnoreCase(SUBPREMISE.toString())) { - return SUBPREMISE; - } else if (addressComponentType.equalsIgnoreCase(POSTAL_CODE.toString())) { - return POSTAL_CODE; - } else if (addressComponentType.equalsIgnoreCase(POSTAL_CODE_SUFFIX.toString())) { - return POSTAL_CODE_SUFFIX; - } else if (addressComponentType.equalsIgnoreCase(NATURAL_FEATURE.toString())) { - return NATURAL_FEATURE; - } else if (addressComponentType.equalsIgnoreCase(AIRPORT.toString())) { - return AIRPORT; - } else if (addressComponentType.equalsIgnoreCase(PARK.toString())) { - return PARK; - } else if (addressComponentType.equalsIgnoreCase(POINT_OF_INTEREST.toString())) { - return POINT_OF_INTEREST; - } else if (addressComponentType.equalsIgnoreCase(FLOOR.toString())) { - return FLOOR; - } else if (addressComponentType.equalsIgnoreCase(ESTABLISHMENT.toString())) { - return ESTABLISHMENT; - } else if (addressComponentType.equalsIgnoreCase(PARKING.toString())) { - return PARKING; - } else if (addressComponentType.equalsIgnoreCase(POST_BOX.toString())) { - return POST_BOX; - } else if (addressComponentType.equalsIgnoreCase(POSTAL_TOWN.toString())) { - return POSTAL_TOWN; - } else if (addressComponentType.equalsIgnoreCase(ROOM.toString())) { - return ROOM; - } else if (addressComponentType.equalsIgnoreCase(STREET_NUMBER.toString())) { - return STREET_NUMBER; - } else if (addressComponentType.equalsIgnoreCase(BUS_STATION.toString())) { - return BUS_STATION; - } else if (addressComponentType.equalsIgnoreCase(TRAIN_STATION.toString())) { - return TRAIN_STATION; - } else if (addressComponentType.equalsIgnoreCase(TRANSIT_STATION.toString())) { - return TRANSIT_STATION; - } else if (addressComponentType.equalsIgnoreCase(SUBLOCALITY_LEVEL_1.toString())) { - return SUBLOCALITY_LEVEL_1; - } else if (addressComponentType.equalsIgnoreCase(SUBLOCALITY_LEVEL_2.toString())) { - return SUBLOCALITY_LEVEL_2; - } else if (addressComponentType.equalsIgnoreCase(SUBLOCALITY_LEVEL_3.toString())) { - return SUBLOCALITY_LEVEL_3; - } else if (addressComponentType.equalsIgnoreCase(SUBLOCALITY_LEVEL_4.toString())) { - return SUBLOCALITY_LEVEL_4; - } else if (addressComponentType.equalsIgnoreCase(SUBLOCALITY_LEVEL_5.toString())) { - return SUBLOCALITY_LEVEL_5; - } else { - log.log(Level.WARNING, "Unknown address component type '%s'", addressComponentType); - return UNKNOWN; - } - } + UNKNOWN } diff --git a/src/main/java/com/google/maps/model/LocationType.java b/src/main/java/com/google/maps/model/LocationType.java index 2b4fe3d74..c68731d0c 100644 --- a/src/main/java/com/google/maps/model/LocationType.java +++ b/src/main/java/com/google/maps/model/LocationType.java @@ -17,9 +17,6 @@ import com.google.maps.internal.StringJoin.UrlValue; -import java.util.logging.Level; -import java.util.logging.Logger; - /** * Location types for a reverse geocoding request. Please see * for @@ -57,29 +54,11 @@ public enum LocationType implements UrlValue { */ UNKNOWN; - - private static Logger log = Logger.getLogger(LocationType.class.getName()); - @Override public String toUrlValue() { if (this == UNKNOWN) { throw new UnsupportedOperationException("Shouldn't use LocationType.UNKNOWN in a request."); } - return toString(); - } - - public LocationType lookup(String locationType) { - if (locationType.equalsIgnoreCase(ROOFTOP.toString())) { - return ROOFTOP; - } else if (locationType.equalsIgnoreCase(RANGE_INTERPOLATED.toString())) { - return RANGE_INTERPOLATED; - } else if (locationType.equalsIgnoreCase(GEOMETRIC_CENTER.toString())) { - return GEOMETRIC_CENTER; - } else if (locationType.equalsIgnoreCase(APPROXIMATE.toString())) { - return APPROXIMATE; - } else { - log.log(Level.WARNING, "Unknown location type '%s'", locationType); - return UNKNOWN; - } + return name(); } } diff --git a/src/main/java/com/google/maps/model/TravelMode.java b/src/main/java/com/google/maps/model/TravelMode.java index 841f0d69c..a7b7e72ab 100644 --- a/src/main/java/com/google/maps/model/TravelMode.java +++ b/src/main/java/com/google/maps/model/TravelMode.java @@ -17,8 +17,7 @@ import com.google.maps.internal.StringJoin.UrlValue; -import java.util.logging.Level; -import java.util.logging.Logger; +import java.util.Locale; /** * You may specify the transportation mode to use for calulating directions. Directions are @@ -30,40 +29,17 @@ * .com/maps/documentation/distancematrix/#RequestParameters">Distance Matrix API travel modes */ public enum TravelMode implements UrlValue { - DRIVING("driving"), WALKING("walking"), BICYCLING("bicycling"), TRANSIT("transit"), + DRIVING, WALKING, BICYCLING, TRANSIT, /** * Indicates an unknown travel mode returned by the server. The Java Client for Google Maps * Services should be updated to support the new value. */ - UNKNOWN("unknown"); - - private static Logger log = Logger.getLogger(TravelMode.class.getName()); - - private final String mode; - - TravelMode(String mode) { - this.mode = mode; - } + UNKNOWN; @Override public String toString() { - return mode; - } - - public static TravelMode lookup(String travelMode) { - if (travelMode.equalsIgnoreCase(DRIVING.toString())) { - return DRIVING; - } else if (travelMode.equalsIgnoreCase(WALKING.toString())) { - return WALKING; - } else if (travelMode.equalsIgnoreCase(BICYCLING.toString())) { - return BICYCLING; - } else if (travelMode.equalsIgnoreCase(TRANSIT.toString())) { - return TRANSIT; - } else { - log.log(Level.WARNING, "Unknown Travel Mode '%s'", travelMode); - return UNKNOWN; - } + return name().toLowerCase(Locale.ENGLISH); } @Override @@ -71,6 +47,6 @@ public String toUrlValue() { if (this == UNKNOWN) { throw new UnsupportedOperationException("Shouldn't use TravelMode.UNKNOWN in a request."); } - return mode; + return name().toLowerCase(Locale.ENGLISH); } } \ No newline at end of file diff --git a/src/main/java/com/google/maps/model/Unit.java b/src/main/java/com/google/maps/model/Unit.java index 22f9066d4..518d5081f 100644 --- a/src/main/java/com/google/maps/model/Unit.java +++ b/src/main/java/com/google/maps/model/Unit.java @@ -17,26 +17,21 @@ import com.google.maps.internal.StringJoin.UrlValue; +import java.util.Locale; + /** * Units of measurement. */ public enum Unit implements UrlValue { - METRIC("metric"), IMPERIAL("imperial"); - - private final String type; - - Unit(String type) { - this.type = type; - } + METRIC, IMPERIAL; @Override public String toString() { - return type; + return toUrlValue(); } - @Override public String toUrlValue() { - return type; + return name().toLowerCase(Locale.ENGLISH); } } diff --git a/src/test/java/com/google/maps/GeocodingApiTest.java b/src/test/java/com/google/maps/GeocodingApiTest.java index 408af735c..8ccf04dd7 100644 --- a/src/test/java/com/google/maps/GeocodingApiTest.java +++ b/src/test/java/com/google/maps/GeocodingApiTest.java @@ -90,6 +90,7 @@ private void checkSydneyResult(GeocodingResult[] results) { assertNotNull(results[0].geometry.location); assertEquals(-33.8674869, results[0].geometry.location.lat, EPSILON); assertEquals(151.2069902, results[0].geometry.location.lng, EPSILON); + assertEquals(LocationType.APPROXIMATE, results[0].geometry.locationType); } @Test diff --git a/src/test/java/com/google/maps/model/EnumsTest.java b/src/test/java/com/google/maps/model/EnumsTest.java new file mode 100644 index 000000000..e1399d627 --- /dev/null +++ b/src/test/java/com/google/maps/model/EnumsTest.java @@ -0,0 +1,47 @@ +/* + * Copyright 2014 Google Inc. All rights reserved. + * + * + * 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 com.google.maps.model; + +import com.google.maps.SmallTests; + +import static com.google.maps.internal.StringJoin.UrlValue; +import static org.junit.Assert.*; + +import org.junit.Test; +import org.junit.experimental.categories.Category; + +@Category(SmallTests.class) +public class EnumsTest { + @Test + public void testUnknown() throws Exception { + assertNotNull(AddressComponentType.UNKNOWN); // Does not implement UrlValue. + + assertCannotGetUrlValue(AddressType.UNKNOWN); + assertCannotGetUrlValue(LocationType.UNKNOWN); + assertCannotGetUrlValue(TravelMode.UNKNOWN); + + } + + private static void assertCannotGetUrlValue(T unknown) { + assertNotNull(unknown); + try { + unknown.toUrlValue(); + fail("Expected to throw UnsupportedOperationException"); + } catch (UnsupportedOperationException expected) { + // Expected. + } + } +}