Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,16 @@
import java.util.Map;

/**
*
* @author joseph
* The Location Element Data from the cloud.
*/
public interface CloudGeoData extends GeoData {
public void setNoValueReasons(Map<String, String> value);

/**
* Has no effect.
* @param value the messages for properties with no value, by name
* @deprecated The cloud engine sets the message of each property with no
* value on the value itself.
*/
@Deprecated
void setNoValueReasons(Map<String, String> value);
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,145 +24,32 @@

import fiftyone.geolocation.core.data.GeoDataDefault;
import fiftyone.pipeline.core.data.FlowData;
import fiftyone.pipeline.core.data.TryGetResult;
import fiftyone.pipeline.core.data.types.JavaScript;
import fiftyone.pipeline.engines.data.AspectData;
import fiftyone.pipeline.engines.data.AspectPropertyMetaData;
import fiftyone.pipeline.engines.data.AspectPropertyValue;
import fiftyone.pipeline.engines.data.AspectPropertyValueDefault;
import fiftyone.pipeline.engines.flowelements.AspectEngine;
import fiftyone.pipeline.engines.services.MissingPropertyService;
import java.util.Map;
import java.util.Objects;
import org.json.JSONObject;
import org.slf4j.Logger;

/**
* The Location Element Data from the cloud. The cloud engine stores each
* property the response holds as an AspectPropertyValue, so the getters of
* GeoDataDefault return them as they are.
*/
public class CloudGeoDataDefault extends GeoDataDefault implements CloudGeoData {

private Map<String, String> noValueReasons;

public CloudGeoDataDefault(Logger logger, FlowData flowData, AspectEngine<? extends AspectData, ? extends AspectPropertyMetaData> engine, MissingPropertyService missingPropertyService) {
super(logger, flowData, engine, missingPropertyService);
}

public void setNoValueReasons(Map<String, String> value){
noValueReasons = value;
}

@SuppressWarnings("unchecked")
@Override
public AspectPropertyValue<JavaScript> getJavaScript() {
return getAs("javascript", AspectPropertyValue.class, JavaScript.class);
}

@Override
public AspectPropertyValue<String> getRoad() {
return getValueAsString("road");
}

@Override
public AspectPropertyValue<String> getTown() {
return getValueAsString("town");
}

@Override
public AspectPropertyValue<String> getSuburb() {
return getValueAsString("suburb");
}

@Override
public AspectPropertyValue<String> getCounty() {
return getValueAsString("county");
}

@Override
public AspectPropertyValue<String> getRegion() {
return getValueAsString("region");
}

@Override
public AspectPropertyValue<String> getState() {
return getValueAsString("state");
}

@Override
public AspectPropertyValue<String> getZipCode() {
return getValueAsString("zipcode");
}

@Override
public AspectPropertyValue<String> getCountry() {
return getValueAsString("country");
}

@Override
public AspectPropertyValue<String> getCountryCode() {
return getValueAsString("countrycode");
}

@Override
public AspectPropertyValue<String> getCountryCode3() {
return getValueAsString("countrycode3");
}

@Override
public AspectPropertyValue<Integer> getTimeZoneOffset() {
return getValueAs("timezoneoffset");
}

/**
* Has no effect.
* @param value the messages for properties with no value, by name
* @deprecated The cloud engine sets the message of each property with no
* value on the value itself.
*/
@Deprecated
@Override
public AspectPropertyValue<String> getAddress() {
return getValueAsString("address");
public void setNoValueReasons(Map<String, String> value) {
}

private AspectPropertyValue<String> getValueAsString(String key) {
return getValueAs(key);
}

@SuppressWarnings("unchecked")
private <T> AspectPropertyValue<T> getValueAs(String key) {
AspectPropertyValue<T> value = getAs(key, AspectPropertyValue.class);

if(noValueReasons.containsKey(key))
value.setNoValueMessage(noValueReasons.get(key));

return value;
}

@Override
protected <T> TryGetResult<T> tryGetValue(String key, Class<T> type, Class<?>... parameterisedTypes) {
if (AspectPropertyValue.class.isAssignableFrom(type)) {
TryGetResult<T> result = new TryGetResult<>();
Map<String, Object> map = asKeyMap();
if (map.containsKey(key)) {
Object obj = map.get(key);

try {
Object temp = setValue(key, obj);
T value = type.cast(temp);
result.setValue(value);
} catch (ClassCastException e) {
throw new ClassCastException("Expected property '" + key +
"' to be of type '" + type.getSimpleName() +
"' but it is '" + obj.getClass().getSimpleName() + "'");
}
}
return result;
}
else {
return super.tryGetValue(key, type, parameterisedTypes);
}
}

private AspectPropertyValue<Object> setValue(String key, Object obj) {
AspectPropertyValue<Object> temp = new AspectPropertyValueDefault<Object>();
if (Objects.isNull(obj) || obj == JSONObject.NULL) {
temp.setNoValueMessage(noValueReasons.get(key));
}
else {
temp.setValue(obj);
}
return temp;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
import fiftyone.pipeline.core.flowelements.Pipeline;
import fiftyone.pipeline.engines.data.AspectPropertyMetaData;
import fiftyone.pipeline.engines.data.AspectPropertyMetaDataDefault;
import fiftyone.pipeline.engines.data.AspectPropertyValue;
import fiftyone.pipeline.engines.data.AspectPropertyValueDefault;

import org.json.JSONObject;
import org.slf4j.Logger;
Expand Down Expand Up @@ -141,39 +143,34 @@ protected void processEngine(FlowData data, CloudGeoData aspectData) {
Map<String, Object> methodData = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);

for (AspectPropertyMetaData property : getProperties()) {
String key = property.getName().toLowerCase();
// A property the response leaves out has no entry, so
// reading it throws a PropertyMissingException.
if (geoObj.has(key) == false) {
continue;
}
Object value;
switch(property.getType().getSimpleName()) {
case ("List"):
JSONArray jsonArray = geoObj.optJSONArray(property.getName().toLowerCase());
methodData.put(
property.getName(),
jsonArray == null ? null : jsonArray.toList());
JSONArray jsonArray = geoObj.optJSONArray(key);
value = jsonArray == null ? null : jsonArray.toList();
break;
case ("JavaScript"):
String javascript = geoObj.optString(property.getName().toLowerCase(), null);
methodData.put(
property.getName(),
javascript == null ? null : new JavaScript(javascript));
String javascript = geoObj.optString(key, null);
value = javascript == null ?
null :
new JavaScript(javascript);
break;
default:
methodData.put(
property.getName(),
geoObj.opt(property.getName().toLowerCase()));
break;
value = geoObj.opt(key);
break;
}
methodData.put(
property.getName(),
toAspectPropertyValue(geoObj, key, value));
}

aspectData.populateFromMap(methodData);

Map<String, String> noValueReasonsMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
for(Map.Entry<String, Object> entry : methodData.entrySet()){
if("null".equals(String.valueOf(entry.getValue()))){
String key = entry.getKey().toLowerCase();
Object reason = tryToGet(geoObj, key);
noValueReasonsMap.put(entry.getKey().toLowerCase(), (reason == null ? "" : reason.toString()));
}
}

aspectData.setNoValueReasons(noValueReasonsMap);
}
else {
throw new PipelineConfigurationException(
Expand All @@ -187,6 +184,41 @@ public static Object tryToGet(JSONObject jsonObj, String key) {
return jsonObj.opt(key + "nullreason");
}

/**
* The message for a property with no value when the response gives no
* reason.
*/
private static final String UNKNOWN_NULL_REASON = "Unknown";

/**
* Wrap a value read from the response. A JSON null is no value, with the
* reason the response gives under the property's name followed by
* nullreason.
* @param geoObj the response's part for this engine
* @param key the lower case property name
* @param value the value read, null or JSONObject.NULL where the
* response has none
* @return the property value
*/
private static AspectPropertyValue<Object> toAspectPropertyValue(
JSONObject geoObj,
String key,
Object value) {
AspectPropertyValue<Object> result =
new AspectPropertyValueDefault<>();
if (value == null || value == JSONObject.NULL) {
Object reason = tryToGet(geoObj, key);
result.setNoValueMessage(
reason == null || reason == JSONObject.NULL ?
UNKNOWN_NULL_REASON :
reason.toString());
}
else {
result.setValue(value);
}
return result;
}

@Override
protected void unmanagedResourcesCleanup() {
}
Expand Down
Loading
Loading