package org.fluxtream.core.connectors;
import com.wordnik.swagger.annotations.ApiModel;
import com.wordnik.swagger.annotations.ApiModelProperty;
import org.fluxtream.core.connectors.annotations.ObjectTypeSpec;
import org.fluxtream.core.domain.AbstractFacet;
import java.util.*;
@ApiModel("Each Connector maintains bags of facets of different types. An ObjectType is the description of such a facet type.")
public class ObjectType {
@ApiModelProperty(value="The name of the object type", required=true)
String name;
@ApiModelProperty(value="The pretty name of the object type", required=true)
String prettyname;
boolean isDateBased;
boolean isMixedType;
boolean isClientFacet;
String visibleClause;
String orderBy;
private static Map<Connector,List<ObjectType>> connectorObjectTypes = new Hashtable<Connector,List<ObjectType>>();
private static Map<Connector,Map<String,ObjectType>> connectorNamedObjectTypes = new Hashtable<Connector,Map<String,ObjectType>>();
private static Map<Connector,Map<Integer,ObjectType>> connectorObjectTypeValues = new Hashtable<Connector,Map<Integer,ObjectType>>();
private static Map<String, ObjectType> customObjectTypes = new Hashtable<String, ObjectType>();
/**
* "Custom" objectTypes are there to compute a value (hashCode())
* for special API calls. We use it for counting those calls so we
* don't confuse them with the usual API calls that retrieve data.
* @param name
*/
public static void registerCustomObjectType(String name) {
ObjectType customObjectType = new ObjectType();
customObjectType.name = name;
customObjectType.value = name.hashCode();
customObjectTypes.put(name, customObjectType);
}
public static ObjectType getCustomObjectType(String name) {
return customObjectTypes.get(name);
}
public String getApiKeyAttributeName(String attName) {
return new StringBuilder(name).append("/").append(attName).toString();
}
public static ObjectType getObjectType(Connector connector, Integer objectType) {
if (objectType==null) return null;
Map<Integer, ObjectType> connectorObjectTypes = connectorObjectTypeValues.get(connector);
if (connectorObjectTypes!=null) {
ObjectType type = connectorObjectTypes.get(objectType);
return type;
}
return null;
}
static void addObjectType(String name, Connector connector, ObjectType value) {
if (!connectorObjectTypes.containsKey(connector))
connectorObjectTypes.put(connector, new Vector<ObjectType>());
connectorObjectTypes.get(connector).add(value);
if (!connectorNamedObjectTypes.containsKey(connector))
connectorNamedObjectTypes.put(connector, new Hashtable<String,ObjectType>());
connectorNamedObjectTypes.get(connector).put(value.name(), value);
if (!connectorObjectTypeValues.containsKey(connector))
connectorObjectTypeValues.put(connector, new Hashtable<Integer,ObjectType>());
connectorObjectTypeValues.get(connector).put(value.value(), value);
}
public static ObjectType getObjectType(Connector connector, String name) {
Map<String, ObjectType> connectorObjectTypes = connectorNamedObjectTypes.get(connector);
ObjectType namedObjectType = connectorObjectTypes.get(name);
return namedObjectType;
}
public static List<ObjectType> getObjectTypes(Connector connector, int objectTypes) {
List<ObjectType> connectorTypes = connectorObjectTypes.get(connector);
if (connectorTypes==null) return null;
List<ObjectType> result = new ArrayList<ObjectType>();
for (ObjectType objectType : connectorTypes) {
if ((objectTypes & objectType.value())!=0)
result.add(objectType);
}
return result;
}
@ApiModelProperty(value="Is data referred to by this object type (local) date based?", required=true)
public boolean isDateBased() {
return isDateBased;
}
@ApiModelProperty(value="Is it a client, non-technical, facet, of the type that mean something to the end-user?", required=true)
public boolean isClientFacet() {
return isClientFacet;
}
public String toString() {
return name;
}
public String getName() {
return name;
}
int value;
boolean isImageType;
Class<? extends AbstractFacet> facetClass;
ObjectType(){}
public Class<? extends AbstractFacet> facetClass() {
return facetClass;
}
public String name() {
return name;
}
@ApiModelProperty(value="The bitmask value for this ObjectType", required=true)
public int value() {
return value;
}
@ApiModelProperty(value="Does the data this object type refers to contain an image?", required=true)
public boolean isImageType() {
return isImageType;
}
public String prettyname() {
return prettyname;
}
@ApiModelProperty(hidden=true)
public String visibleClause() {
return visibleClause;
}
@ApiModelProperty(hidden=true)
public String orderBy() {
return orderBy;
}
@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final ObjectType that = (ObjectType)o;
if (isDateBased != that.isDateBased) {
return false;
}
if (isImageType != that.isImageType) {
return false;
}
if (value != that.value) {
return false;
}
if (facetClass != null ? !facetClass.equals(that.facetClass) : that.facetClass != null) {
return false;
}
if (name != null ? !name.equals(that.name) : that.name != null) {
return false;
}
if (prettyname != null ? !prettyname.equals(that.prettyname) : that.prettyname != null) {
return false;
}
return true;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + (prettyname != null ? prettyname.hashCode() : 0);
result = 31 * result + (isDateBased ? 1 : 0);
result = 31 * result + (isMixedType ? 1 : 0);
result = 31 * result + value;
result = 31 * result + (isImageType ? 1 : 0);
result = 31 * result + (facetClass != null ? facetClass.hashCode() : 0);
return result;
}
@ApiModelProperty(value="Can this object type refer both to date-based data and epoch time-based intervals?", required=true)
public boolean isMixedType() {
return isMixedType;
}
public static int getObjectTypeValue(final Class<? extends AbstractFacet> facetClass) {
try {
final ObjectTypeSpec annotation = facetClass.getAnnotation(ObjectTypeSpec.class);
final int value = annotation.value();
return value;
} catch (Throwable t) {
final String message = "Could not get Facet ObjectType value for " + facetClass.getName();
throw new RuntimeException(message);
}
}
}