package com.breeze.metadata;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.breeze.metadata.DataType;
import com.breeze.metadata.IDataProperty;
import com.breeze.metadata.IEntityType;
import com.breeze.metadata.INavigationProperty;
import com.breeze.metadata.IProperty;
import com.breeze.metadata.MetadataHelper;
import com.breeze.util.JsonGson;
/**
* Strongly typed metadata the describes all of the entityTypes for a single model and all of their associated data and navigation properties.
* @author IdeaBlade
*
*/
@SuppressWarnings("unchecked")
public abstract class Metadata {
private HashMap<String, Object> _resourceEntityTypeMap;
private HashMap<String, IEntityType> _entityTypeMap = new HashMap<String, IEntityType>();
private RawMetadata _rawMetadata;
public void build() {
if (_rawMetadata == null) {
_rawMetadata = buildRawMetadata();
wrapRawMetadata(_rawMetadata);
}
}
protected abstract RawMetadata buildRawMetadata();
/**
* Creates strongly typed wrapper over raw breeze json metadata.
* @param rawMetadata The raw metadata in json format that is used to communicate with the breeze client.
*/
private void wrapRawMetadata(RawMetadata rawMetadata) {
_rawMetadata = rawMetadata;
List<HashMap<String, Object>> structuralTypes = (List<HashMap<String, Object>>) rawMetadata.get("structuralTypes");
_resourceEntityTypeMap = (HashMap<String, Object>) rawMetadata.get("resourceEntityTypeMap");
for (Map<String, Object> entityMap: structuralTypes) {
IEntityType entityType = new EntityType(entityMap, this);
_entityTypeMap.put(entityType.getName(), entityType);
}
}
public RawMetadata getRawMetadata() {
return _rawMetadata;
}
public String toJson() {
return JsonGson.toJson(this._rawMetadata);
}
/**
* @param resourceName The name of the url resource.
* @return The EntityType associated with the specified resource name.
*/
public IEntityType getEntityTypeForResourceName(String resourceName) {
String entityTypeName = (String) _resourceEntityTypeMap.get(resourceName);
if (entityTypeName == null) {
throw new RuntimeException("There is no entityType name registered for this resource: " + resourceName);
}
return getEntityType(entityTypeName);
}
/**
* @param clazz An entity class.
* @return The EntityType associated with the specified class.
*/
public IEntityType getEntityTypeForClass(Class<?> clazz) {
String entityTypeName = MetadataHelper.getEntityTypeName(clazz);
return getEntityType(entityTypeName);
}
/**
* @param entityTypeName An EntityType name.
* @return The EntityType associated with the specified name.
*/
public IEntityType getEntityType(String entityTypeName) {
if (entityTypeName == null) return null;
return _entityTypeMap.get(entityTypeName);
}
/**
* The metadata that describes a single java entity class.
* @author IdeaBlade
*
*/
public class EntityType implements IEntityType {
private Map<String, Object> _entityMap;
private Metadata _metadata;
private String _entityTypeName;
private Map<String, IProperty> _propertyMap = new HashMap<String, IProperty>();
private List<IDataProperty> _keyProperties = new ArrayList<IDataProperty>();
protected EntityType(Map<String, Object> entityMap, Metadata metadata) {
_entityMap = entityMap;
_metadata = metadata;
String ns = (String) _entityMap.get("namespace");
String shortName = (String) _entityMap.get("shortName");
_entityTypeName = MetadataHelper.getEntityTypeName(ns, shortName);
List<HashMap<String, Object>> properties;
properties = (List<HashMap<String, Object>>) _entityMap.get("dataProperties");
for (HashMap<String, Object> p: properties) {
IDataProperty prop = new DataProperty(this, p, metadata);
if (prop.isKeyProperty()) {
_keyProperties.add(prop);
}
_propertyMap.put(prop.getName(), prop);
}
properties = (List<HashMap<String, Object>>) _entityMap.get("navigationProperties");
if (properties != null) {
for (HashMap<String, Object> p: properties) {
INavigationProperty prop = new NavigationProperty(this, p, metadata);
_propertyMap.put(prop.getName(), prop);
}
}
}
/* (non-Javadoc)
* @see com.breeze.metadata.IEntityType#getName()
*/
@Override
public String getName() {
return _entityTypeName;
}
public Metadata getMetadata() {
return _metadata;
}
@Override
public IProperty getProperty(String propertyName) {
return _propertyMap.get(propertyName);
}
public List<IDataProperty> getKeyProperties() {
return _keyProperties;
}
public boolean isComplexType() {
Boolean isComplexType = (Boolean) _entityMap.get("isComplexType");
return isComplexType != null && isComplexType == true;
}
public AutoGeneratedKeyType getAutoGeneratedKeyType() {
String tmp = (String) _entityMap.get("autoGeneratedKeyType");
if (tmp == null) {
return AutoGeneratedKeyType.None;
} else {
return AutoGeneratedKeyType.valueOf(tmp);
}
}
}
public class DataProperty implements IDataProperty {
private IEntityType _parentType;
private Map<String, Object> _dpMap;
private Metadata _metadata;
public DataProperty(IEntityType parentType, Map<String, Object> dpMap, Metadata metadata) {
_parentType = parentType;
_dpMap = dpMap;
_metadata = metadata;
}
@Override
public String getName() {
return (String) _dpMap.get("nameOnServer");
}
public boolean isKeyProperty() {
Boolean isKey = (Boolean) _dpMap.get("isPartOfKey");
return isKey == null ? false : isKey.booleanValue();
}
@Override
public DataType getDataType() {
String dataTypeName = (String) _dpMap.get("dataType");
if (dataTypeName == null) return null;
return DataType.fromName(dataTypeName);
}
public IEntityType getComplexType() {
String complexTypeName = (String) _dpMap.get("complexTypeName");
if (complexTypeName == null) return null;
return _metadata.getEntityType(complexTypeName);
}
@Override
public IEntityType getParentType() {
return _parentType;
}
public Class getEnumType() {
String enumTypeName = (String) _dpMap.get("enumType");
try {
return enumTypeName == null ? null : Class.forName(enumTypeName);
} catch (ClassNotFoundException e) {
return null;
}
}
}
public class NavigationProperty implements INavigationProperty {
private IEntityType _parentType;
private Map<String, Object> _npMap;
private Metadata _metadata;
public NavigationProperty(IEntityType parentType, Map<String, Object> npMap, Metadata metadata) {
_parentType = parentType;
_npMap = npMap;
_metadata = metadata;
}
@Override
public String getName() {
return (String) _npMap.get("nameOnServer");
}
@Override
public IEntityType getEntityType() {
String entityTypeName = (String) _npMap.get("entityTypeName");
return _metadata.getEntityType(entityTypeName);
}
@Override
public IEntityType getParentType() {
return _parentType;
}
@Override
public boolean isScalar() {
return (boolean) _npMap.get("isScalar");
}
public String[] getInvForeignKeyNames() {
Object invFkNames = _npMap.get("invForeignKeyNamesOnServer");
return (String[]) invFkNames;
}
}
}