All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.adaptrex.core.ext.ModelInstance Maven / Gradle / Ivy

The newest version!
/*
 * 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.commons.lang3.StringUtils;
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 data = new HashMap();

	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 ();
		}
		this.getObjectGraph(entity, extConfig.getModelName(), null, null);
		
	}
	
	public Map getData() {
		return this.data;
	}
	
	
	@SuppressWarnings("unchecked")
	private Map 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 entityData = new HashMap();

		/*
		 * Get the class for the current node
		 */
		Class entityClazz = entity.getClass();
		
		/*
		 * In some cases, hibernate entities return proxy class... we need the original class
		 */
		String entityClazzName = entityClazz.getSimpleName();
		if (entityClazzName.contains("_$$_")) {
			entityClazzName = StringUtils.substringBefore(entityClazzName, "_$$_");
		}
		
		/*
		 * 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 entityIncludes = PersistenceTools.getIncludes(extConfig, nodePath);
		List entityExcludes = PersistenceTools.getExcludes(extConfig, nodePath);
		List entityJoins = PersistenceTools.getJoins(extConfig, nodePath);

		AdaptrexEntityType adaptrexEntity = apm.getAdaptrexEntity(entityClazzName);
		Map adaptrexFields = adaptrexEntity.getFields();
		Map adaptrexCollections = adaptrexEntity.getCollections();
		Map 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) + 
					StringUtils.capitalize(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 associatedIds = new ArrayList();
			List> associatedData = new ArrayList>();
			
			List assocObjList = fieldValue == null
					? new ArrayList()
					: new ArrayList((Collection) 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 + StringUtils.capitalize(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 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 entityIncludes, List 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;
	}
}