/*
* Copyright (C) 2014 SCVNGR, Inc. d/b/a LevelUp
*
* 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.scvngr.levelup.core.model;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.scvngr.levelup.core.annotation.LevelUpApi;
import com.scvngr.levelup.core.annotation.LevelUpApi.Contract;
import com.scvngr.levelup.core.annotation.model.RequiredField;
import com.scvngr.levelup.core.util.NullUtils;
import net.jcip.annotations.Immutable;
import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import lombok.Value;
// The code below will be machine-processed.
// CHECKSTYLE:OFF
/**
* Representing a location of a merchant (which can have multiple) on the server.
*/
@Immutable
@Value
@LevelUpApi(contract = Contract.DRAFT)
public final class Location implements Parcelable {
/**
* Implements the {@code Parcelable} interface.
*/
@NonNull
public static final Creator<Location> CREATOR = new LocationCreator();
/**
* The categories that this {@link Location} is classified under.
*/
@NonNull
@RequiredField
private final Set<Integer> categories;
/**
* The {@link Location}'s extended address.
*/
@Nullable
private final String extendedAddress;
/**
* The hours of operation for this {@link Location}.
*/
@Nullable
private final String hours;
/**
* The web service ID of this {@link Location}.
*/
private final long id;
/**
* The latitude of this {@link Location}.
*/
private final double latitude;
/**
* The longitude of this {@link Location}.
*/
private final double longitude;
/**
* The locality (city) of this {@link Location}.
*/
@Nullable
private final String locality;
/**
* The web service ID of the location's merchant.
*/
private final long merchantId;
/**
* The name of the location's merchant.
*/
@Nullable
private final String merchantName;
/**
* The phone number of this {@link Location}.
*/
@Nullable
private final String phone;
/**
* The postal code of this {@link Location}.
*/
@Nullable
private final String postalCode;
/**
* The region (state in the US) of this {@link Location}.
*/
@Nullable
private final String region;
/**
* Whether or not this location is to be shown to the user.
*/
private final boolean shown;
/**
* The address of this {@link Location}.
*/
@Nullable
private final String streetAddress;
/**
* A map of URLs associated with this {@link Location}. URLs are now returned as a {@link
* WebLink} through the {@link com.scvngr.levelup.core.net.request.factory
* .WebLinkRequestFactory}.
*/
@NonNull
@RequiredField
@Deprecated
private final Map<String, String> urls;
/**
* The name of the location, if different from the merchant name. This is usually a familiar
* name that would make this location distinct amongst a set of locations where the merchant
* name would otherwise be identical e.g. "North End", "Charles St."
*/
@Nullable
private final String name;
/**
* URL key for Yelp.
*/
@NonNull
public static final String URL_YELP = "yelp";
/**
* URL key for OpenTable.
*/
@NonNull
public static final String URL_OPENTABLE = "opentable";
/**
* URL key for Menu.
*/
@NonNull
public static final String URL_MENU = "menu";
/**
* URL key for Twitter.
*/
@NonNull
public static final String URL_TWITTER = "twitter";
/**
* URL key for a newsletter.
*/
@NonNull
public static final String URL_NEWSLETTER = "newsletter";
/**
* URL key for Facebook.
*/
@NonNull
public static final String URL_FACEBOOK = "facebook";
/**
* URL key for Foodler.
*/
@NonNull
public static final String URL_FOODLER = "foodler";
/**
* @param categories the categories that this {@link Location} is classified under. {@code null}
* will turn into an empty set.
* @param extendedAddress the {@link Location}'s extended address.
* @param hours the hours of operation for this {@link Location}.
* @param id the ID on the web service of this {@link Location}.
* @param latitude the latitude of this {@link Location}.
* @param longitude the longitude of this {@link Location}.
* @param locality the locality (city) of this {@link Location}.
* @param merchantId the ID number of the location's merchant.
* @param merchantName The name of the location's merchant.
* @param name The name of the location, if different from the merchant name.
* @param phone the phone number for this {@link Location}.
* @param postalCode the postal code for this {@link Location}.
* @param region the region (state in the US) for this {@link Location}.
* @param shown whether or not this location is to be shown to the user.
* @param streetAddress the address of this {@link Location}.
* @param urls a map of URLs associated with this {@link Location}. This map will be made
* unmodifiable.
*/
@Deprecated
public Location(@Nullable final Set<Integer> categories,
@Nullable final String extendedAddress, @Nullable final String hours, final long id,
final double latitude, final double longitude, @Nullable final String locality,
final long merchantId, @Nullable final String merchantName,
@Nullable final String name, @Nullable final String phone,
@Nullable final String postalCode, @Nullable final String region, final boolean shown,
@Nullable final String streetAddress, @Nullable final Map<String, String> urls) {
if (null == categories) {
// Collections' emptySet is immutable.
this.categories = NullUtils.nonNullContract(Collections.<Integer> emptySet());
} else {
this.categories =
NullUtils.nonNullContract(Collections.<Integer> unmodifiableSet(categories));
}
this.extendedAddress = extendedAddress;
this.hours = hours;
this.id = id;
this.latitude = latitude;
this.longitude = longitude;
this.locality = locality;
this.merchantId = merchantId;
this.merchantName = merchantName;
this.name = name;
this.phone = phone;
this.postalCode = postalCode;
this.region = region;
this.shown = shown;
this.streetAddress = streetAddress;
/*
* An empty map is used to simplify parceling, so that a null value doesn't need to be
* persisted separately from an empty hash map.
*/
this.urls =
NullUtils.nonNullContract(Collections
.unmodifiableMap(null == urls ? new HashMap<String, String>(0) : urls));
}
/**
* @param categories the categories that this {@link Location} is classified under. {@code null}
* will turn into an empty set.
* @param extendedAddress the {@link Location}'s extended address.
* @param hours the hours of operation for this {@link Location}.
* @param id the ID on the web service of this {@link Location}.
* @param latitude the latitude of this {@link Location}.
* @param longitude the longitude of this {@link Location}.
* @param locality the locality (city) of this {@link Location}.
* @param merchantId the ID number of the location's merchant.
* @param merchantName The name of the location's merchant.
* @param name The name of the location, if different from the merchant name.
* @param phone the phone number for this {@link Location}.
* @param postalCode the postal code for this {@link Location}.
* @param region the region (state in the US) for this {@link Location}.
* @param shown whether or not this location is to be shown to the user.
* @param streetAddress the address of this {@link Location}.
*/
public Location(@Nullable final Set<Integer> categories,
@Nullable final String extendedAddress, @Nullable final String hours, final long id,
final double latitude, final double longitude, @Nullable final String locality,
final long merchantId, @Nullable final String merchantName,
@Nullable final String name, @Nullable final String phone,
@Nullable final String postalCode, @Nullable final String region, final boolean shown,
@Nullable final String streetAddress) {
this(categories, extendedAddress, hours, id, latitude, longitude, locality, merchantId,
merchantName, name, phone, postalCode, region, shown, streetAddress, null);
}
/**
* Get a specific URL by key. URLs are now returned as a {@link WebLink} through the {@link
* com.scvngr.levelup.core.net.request.factory.WebLinkRequestFactory}.
*
* @param key the name of the given URL.
* @return a URL with the given key or {@code null} if there is no such mapping.
*/
@Nullable
@Deprecated
public String getUrl(@NonNull final String key) {
return urls.get(key);
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(final Parcel dest, final int flags) {
((LocationCreator) CREATOR).writeToParcel(NullUtils.nonNullContract(dest), flags, this);
}
/**
* Parcelable creator.
*/
@Immutable
static class LocationCreator implements Creator<Location> {
@Override
public Location[] newArray(final int size) {
return new Location[size];
}
@Override
public Location createFromParcel(final Parcel source) {
@SuppressWarnings("unchecked")
final Set<Integer> categories = (Set<Integer>) source.readSerializable();
final String extendedAddress = source.readString();
final String hours = source.readString();
final long id = source.readLong();
final double lat = source.readDouble();
final double lng = source.readDouble();
final String locality = source.readString();
final long merchantId = source.readLong();
final String merchantName = source.readString();
final String name = source.readString();
final String phone = source.readString();
final String postalCode = source.readString();
final String region = source.readString();
final boolean shown = source.readByte() != 0;
final String streetAddress = source.readString();
@SuppressWarnings("unchecked")
final Map<String, String> urls = (Map<String, String>) source.readSerializable();
return new Location(categories, extendedAddress, hours, id, lat, lng, locality,
merchantId, merchantName, name, phone, postalCode, region, shown,
streetAddress, urls);
}
/**
* Parcel writer.
*
* @param dest the destination parcel.
* @param flags flags.
* @param location the location to persist in the parcel.
*/
private void writeToParcel(@NonNull final Parcel dest, final int flags,
@NonNull final Location location) {
dest.writeSerializable((Serializable) location.getCategories());
dest.writeString(location.getExtendedAddress());
dest.writeString(location.getHours());
dest.writeLong(location.getId());
dest.writeDouble(location.getLatitude());
dest.writeDouble(location.getLongitude());
dest.writeString(location.getLocality());
dest.writeLong(location.getMerchantId());
dest.writeString(location.getMerchantName());
dest.writeString(location.getName());
dest.writeString(location.getPhone());
dest.writeString(location.getPostalCode());
dest.writeString(location.getRegion());
dest.writeByte(location.isShown() ? (byte) 0x1 : (byte) 0x0);
dest.writeString(location.getStreetAddress());
dest.writeSerializable((Serializable) location.urls);
}
}
}