/*
* Copyright 2012 Adaptrex, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.adaptrex.core.ext;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import com.adaptrex.core.persistence.PersistenceTools;
import com.adaptrex.core.persistence.api.AdaptrexAssociationType;
import com.adaptrex.core.persistence.api.AdaptrexCollectionType;
import com.adaptrex.core.persistence.api.AdaptrexEntityType;
import com.adaptrex.core.persistence.api.AdaptrexFieldType;
import com.adaptrex.core.persistence.api.AdaptrexPersistenceManager;
import com.adaptrex.core.utilities.StringUtilities;
public class ModelInstance {
private static Logger log = Logger.getLogger(ModelInstance.class);
private Map<String, Object> data = new HashMap<String, Object>();
private ExtConfig extConfig;
private AdaptrexPersistenceManager apm;
public ModelInstance(ExtConfig extConfig, Object entity) throws Exception {
this.extConfig = extConfig;
this.apm = extConfig.getORMPersistenceManager();
if (entity != null) {
log.debug("Creating a new model instance for: " + entity.getClass().getSimpleName() + " [" + entity.toString() + "]");
this.data = this.getObjectGraph(entity, extConfig.getModelName(), null, null);
} else {
log.debug("Creating an empty model instance for: " + extConfig.getModelName());
this.data = new HashMap<String,Object> ();
}
this.getObjectGraph(entity, extConfig.getModelName(), null, null);
}
public Map<String, Object> getData() {
return this.data;
}
@SuppressWarnings("unchecked")
private Map<String, Object> getObjectGraph(
Object entity, // The current node
String entityFieldName, // The local path (name) to this entity
Object parentEntity, // The current node's immediate parent
String parentName) throws Exception { // The parent node's full path (name)
String nodePath =
(parentName == null ? "" : StringUtilities.singularize(parentName)) +
StringUtilities.singularize(StringUtilities.capitalize(entityFieldName));
log.trace("Getting " + (parentName == null ? "" : parentName + ".") + entityFieldName + " [" + entity.toString() + "]");
Map<String, Object> entityData = new HashMap<String, Object>();
/*
* Get the class for the current node
*/
Class<?> entityClazz = entity.getClass();
/*
* Are we at the root node?
*/
boolean isRoot = parentName == null;
/*
* If we're at the root, the entity name is the passed entityFieldName.
* If we're not at the root, the entity name is the name of the parent
* (singularized if the parent node is a list) plus the entityFieldName
*/
String entityName = isRoot
? entityFieldName
: StringUtilities.singularize(parentName) +
StringUtilities.capitalize(entityFieldName);
List<String> entityIncludes = PersistenceTools.getIncludes(extConfig, nodePath);
List<String> entityExcludes = PersistenceTools.getExcludes(extConfig, nodePath);
List<String> entityJoins = PersistenceTools.getJoins(extConfig, nodePath);
AdaptrexEntityType adaptrexEntity = apm.getAdaptrexEntity(entityClazz.getSimpleName());
Map<String,AdaptrexFieldType> adaptrexFields = adaptrexEntity.getFields();
Map<String,AdaptrexCollectionType> adaptrexCollections = adaptrexEntity.getCollections();
Map<String,AdaptrexAssociationType> adaptrexAssociations = adaptrexEntity.getAssociations();
/*
* Add ID field
*/
entityData.put(AdaptrexEntityType.ENTITY_ID_NAME, adaptrexEntity.getEntityIdFrom(entity));
/*
* Add data fields
*/
for (String fieldName : adaptrexFields.keySet()) {
if (doInclude(entityClazz, fieldName, entityIncludes, entityExcludes)) {
AdaptrexFieldType adaptrexField = adaptrexFields.get(fieldName);
Object fieldValue = adaptrexField.getValueFrom(entity);
entityData.put(fieldName, ExtTypeFormatter.format(fieldValue));
}
}
/*
* Add collections
*/
for (String fieldName : adaptrexCollections.keySet()) {
AdaptrexCollectionType adaptrexCollection = adaptrexEntity.getCollection(fieldName);
String assocIdsName = StringUtilities.singularize(fieldName) + AdaptrexEntityType.COLLECTION_IDS_NAME;
boolean includeAssoc = entityJoins.contains(StringUtilities.capitalize(fieldName));
boolean includeAssocIds = doInclude(entityClazz, assocIdsName, entityIncludes, entityExcludes);
if (!includeAssoc && !includeAssocIds) continue;
Object fieldValue = adaptrexCollection.getCollectionFrom(entity);
List<Object> associatedIds = new ArrayList<Object>();
List<Map<String, Object>> associatedData = new ArrayList<Map<String, Object>>();
List<Object> assocObjList = fieldValue == null
? new ArrayList<Object>()
: new ArrayList<Object>((Collection<? extends Object>) fieldValue);
for (Object assocObj : assocObjList) {
if (includeAssoc)
associatedData.add(getObjectGraph(assocObj, fieldName, entity, entityName));
if (includeAssocIds)
associatedIds.add(adaptrexEntity.getEntityIdFrom(assocObj));
}
if (includeAssoc) entityData.put(fieldName, associatedData);
if (includeAssocIds) entityData.put(assocIdsName, associatedIds);
}
/*
* Add association
*/
for (String fieldName : adaptrexAssociations.keySet()) {
AdaptrexAssociationType adaptrexAssociation = adaptrexEntity.getAssociation(fieldName);
String assocIdName = fieldName + AdaptrexEntityType.ENTITY_ID_NAME;
boolean includeAssoc = entityJoins.contains(StringUtilities.capitalize(fieldName));
boolean includeAssocId = doInclude(entityClazz, assocIdName, entityIncludes, entityExcludes);
if (!includeAssoc && !includeAssocId) continue;
Object fieldValue = adaptrexAssociation.getAssociationFrom(entity);
if (includeAssoc) {
Map<String,Object> assoc = fieldValue == null
? null
: getObjectGraph(fieldValue, fieldName, entity, entityName);
entityData.put(fieldName, assoc);
}
if (includeAssocId) {
Object assocId = fieldValue == null ? null : adaptrexEntity.getEntityIdFrom(fieldValue);
entityData.put(assocIdName, assocId);
}
}
return entityData;
}
private boolean doInclude(Class<?> entityClazz, String fieldName,
List<String> entityIncludes, List<String> entityExcludes) {
if (extConfig.getIncludes().size() > 0) {
if (entityIncludes.isEmpty()) return false;
if (!entityIncludes.contains("*") && !entityIncludes.contains(fieldName))
return false;
}
if (extConfig.getExcludes().size() > 0) {
if (entityExcludes.isEmpty()) return true;
if (entityExcludes.contains("*") || entityExcludes.contains(fieldName))
return false;
}
return true;
}
}