package org.limewire.geocode;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Map.Entry;
/**
* Defines a class for geographic information created from a
* {@link org.limewire.geocode.Geocoder} about the client. This is
* basically a map from property names to values. Access to these values is
* through the method {@link #getProperty(GeocodeInformation.Property)}.
*/
public final class GeocodeInformation {
private final Map<Property, String> names2values = new HashMap<Property, String>();
/**
* Maps {@link Property} names to values so that we can turn {@link String}s
* into {@link Property Properties}. In order to use these without
* specifically naming one you must make some reference to one of the enum
* members. For example:
*
* <pre>
* Property.AreaCode.getValue();
* </pre>
*
* in {@link GeocodeInformation}.
*/
private final static Map<String, Property> STRINGS2PROPERTIES = new HashMap<String, Property>();
/**
* The various values.
*
*/
public enum Property {
/**
* IP address -- e.g. <code>12.12.12.12</code>.
*/
Ip("Ip"),
/**
* 2-letter country code -- e.g. <code>US</code>.
*/
CountryCode("CountryCode"),
/**
* 3-letter country code -- e.g. <code>USs</code>.
*/
CountryCode3("CountryCode3"),
/**
* Full country name -- e.g. <code>United States</code>.
*/
CountryName("CountryName"),
/**
* Short region name -- e.g. <code>NY</code>.
*/
Region("Region"),
/**
* Full region name -- e.g. <code>New York</code>.
*/
Region2("Region2"),
/**
* Full city name -- e.g. <code>New York</code>.
*/
City("City"),
/**
* Country-specific postal code -- e.g. <code>10004</code>.
*/
PostalCode("PostalCode"),
/**
* Latitude in decimal degrees -- e.g. <code>40.6888</code>.
*/
Latitude("Latitude"),
/**
* Longitude in decimal degrees -- e.g. <code>40.6888</code>.
*/
Longitude("Longitude"),
/**
* Designated market area code (<a
* href="http://en.wikipedia.org/wiki/Media_market">wikipedia</a>) --
* e.g.<code>501</code>.
*/
DmaCode("DmaCode"),
/**
* Country-specific area code -- e.g. <code>212</code>.
*/
AreaCode("AreaCode");
private final String s;
Property(String s) {
this.s = s;
getStrings2Properties().put(s, this);
}
public String getValue() {
return s;
}
}
static {
// We have to make reference to one so they resolve, in case we're
// creating them only from GeocodeInformation.STRINGS2PROPERTIES
Property.AreaCode.getValue();
}
/**
* Returns the String value for {@link Property} or <code>null</code>.
*
* @param p key value
* @return the String value for {@link Property} or <code>null</code>
*/
public String getProperty(Property p) {
return names2values.get(p);
}
public void setProperty(String name, String value) {
Property prop = getStrings2Properties().get(name);
if (prop != null) {
setProperty(prop, value);
}
}
public void setProperty(Property p, String value) {
names2values.put(p, value);
}
@Override
public String toString() {
return String.valueOf(names2values);
}
public static Map<String, Property> getStrings2Properties() {
return STRINGS2PROPERTIES;
}
/**
* Flattens out the keys and values to an array of strings.
*/
public Properties toProperties() {
Properties props = new Properties();
for (Entry<Property, String> entry : names2values.entrySet()) {
props.setProperty(entry.getKey().getValue(), entry.getValue());
}
return props;
}
/**
* @return null if there is an error
*/
public static GeocodeInformation fromProperties(Properties props) {
if (props.isEmpty()) {
return null;
}
GeocodeInformation info = new GeocodeInformation();
for (Property property : Property.values()) {
String value = props.getProperty(property.getValue());
if (value != null) {
info.setProperty(property, value);
}
}
return info;
}
}