package mil.nga.giat.geowave.adapter.vector.plugin.visibility;
import java.io.IOException;
import java.util.Iterator;
import mil.nga.giat.geowave.core.index.StringUtils;
import mil.nga.giat.geowave.core.store.data.field.FieldVisibilityHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.map.ObjectMapper;
/**
* Object defining visibility is a json structure where each attribute defines
* the visibility for a field with the same name (as the attribute).
*
* Example: { "geometry" : "S", "eventName": "TS"}
*
* Json attributes can also be regular expressions, matching more than one field
* name.
*
* Example: { "geo.*" : "S", ".*" : "TS"}.
*
* The order of the expression must be considered if one expression is more
* general than another, as shown in the example. The expression ".*" matches
* all attributes. The more specific expression "geo.*" must be ordered first.
*
*
*
*/
public class JsonDefinitionColumnVisibilityManagement<T> implements
ColumnVisibilityManagementSpi<T>
{
private final static Logger LOGGER = LoggerFactory.getLogger(JsonDefinitionColumnVisibilityManagement.class);
private static class JsonDefinitionFieldLevelVisibilityHandler<T, CommonIndexValue> extends
FieldLevelVisibilityHandler<T, CommonIndexValue>
{
public JsonDefinitionFieldLevelVisibilityHandler(
String fieldName,
FieldVisibilityHandler<T, Object> fieldVisiblityHandler,
String visibilityAttribute ) {
super(
fieldName,
fieldVisiblityHandler,
visibilityAttribute);
}
private final ObjectMapper mapper = new ObjectMapper();
@Override
public byte[] translateVisibility(
Object visibilityObject,
String fieldName ) {
if (visibilityObject == null) {
return null;
}
try {
final JsonNode attributeMap = mapper.readTree(visibilityObject.toString());
final JsonNode field = attributeMap.get(fieldName);
if ((field != null) && field.isValueNode()) {
return validate(field.getTextValue());
}
final Iterator<String> attNameIt = attributeMap.getFieldNames();
while (attNameIt.hasNext()) {
final String attName = attNameIt.next();
if (fieldName.matches(attName)) {
final JsonNode attNode = attributeMap.get(attName);
if (attNode == null) {
LOGGER.error("Cannot parse visibility expression, JsonNode for attribute " + attName
+ " was null");
return null;
}
return validate(attNode.getTextValue());
}
}
}
catch (IOException | NullPointerException e) {
LOGGER.error(
"Cannot parse visibility expression " + visibilityObject.toString(),
e);
}
return null;
}
protected byte[] validate(
final String vis ) {
return StringUtils.stringToBinary(vis);
// TODO come up with another way to validate, below is the accumulo
// dependent validation
// try {
// ColumnVisibility cVis = new ColumnVisibility(
// vis);
// return cVis.getExpression();
// }
// catch (Exception ex) {
// LOGGER.error(
// "Failed to parse visibility " + vis,
// ex);
// return null;
// }
}
}
@Override
public FieldVisibilityHandler<T, Object> createVisibilityHandler(
final String fieldName,
final FieldVisibilityHandler<T, Object> defaultHandler,
final String visibilityAttributeName ) {
return new JsonDefinitionFieldLevelVisibilityHandler<T, Object>(
fieldName,
defaultHandler,
visibilityAttributeName);
}
}