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; } } }