/*
* 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.data;
import com.adaptrex.core.Adaptrex;
import com.adaptrex.core.ext.rest.ExtConfig;
import com.adaptrex.core.ext.rest.ModelData;
import com.adaptrex.core.persistence.AdaptrexPersistence;
import com.adaptrex.core.persistence.AdaptrexSession;
import com.adaptrex.core.utilities.StringUtilities;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Locale;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/*
* Model... wraps a ModelInstance and ModelDefinition
*/
public class Model {
private static AdaptrexPersistence persistence = Adaptrex.getPersistence();
private Object entity;
private Config config;
private static Logger log = LoggerFactory.getLogger(Model.class);
public Model(String entityName, String ns) {
config = new Config();
config.setClazz(persistence.getEntityClass(entityName));
}
/*
* Each factory method represents a CRUD operation on a speficif model
*/
private Model(Object entity, ExtConfig extConfig) {
config = new Config();
config.setClazz(entity.getClass());
if (extConfig != null) {
this.config.applyExtConfig(extConfig);
}
}
private Model(String entityName, Integer id, ExtConfig extConfig) {
try {
AdaptrexSession session = new AdaptrexSession();
entity = session.getEntity(entityName, id);
session.close();
config = new Config();
config.setClazz(entity.getClass());
if (extConfig != null) {
this.config.applyExtConfig(extConfig);
}
} catch (Exception e) {
log.warn("Error", e);
}
}
private Model(String entityName, ModelData modelData, Integer id, ExtConfig extConfig) {
AdaptrexSession session = new AdaptrexSession();
try {
Class<?> clazz = null;
if (id == null) {
clazz = persistence.getEntityClass(entityName);
entity = clazz.newInstance();
} else {
entity = session.getEntity(entityName, id);
clazz = entity.getClass();
}
entity = updateEntity(entity, modelData);
config = new Config();
config.setClazz(clazz);
if (extConfig != null) {
this.config.applyExtConfig(extConfig);
}
} catch (Exception e) {
log.warn("Error", e);
}
}
/*
* Create and return a model based on an entity name and id
*/
public static Model get(String entityName, Integer id) {
return new Model(entityName, id, null);
}
public static Model get(String entityName, Integer id, ExtConfig extConfig) {
return new Model(entityName, id, extConfig);
}
/*
* Create and return a model based on a new entity instance
*/
public static Model create(String entityName, ModelData modelData) {
return new Model(entityName, modelData, null, null);
}
public static Model create(String entityName, ModelData modelData, ExtConfig extConfig) {
return new Model(entityName, modelData, null, extConfig);
}
/*
* Update an existing model
*/
public static Model update(String entityName, Integer id, ModelData modelData) {
return new Model(entityName, modelData, id, null);
}
public static Model update(String entityName, Integer id, ModelData modelData, ExtConfig extConfig) {
return new Model(entityName, modelData, id, extConfig);
}
/*
* Delete an existing model
*/
public static Model delete(String entityName, Integer id) {
AdaptrexSession session = new AdaptrexSession();
Model m = new Model(session.deleteEntity(entityName, id), null);
session.close();
return m;
}
/*
* Allow users to get the store config at any point
*/
public Config getConfig() {
return config;
}
public Model proxy(String restPath) {
this.config.setProxy(new RestProxy(restPath, config));
return this;
}
public Model modelName(String modelName) {
this.config.setModelName(modelName);
return this;
}
public Model include(String items) {
this.config.include(items);
return this;
}
public Model exclude(String items) {
this.config.exclude(items);
return this;
}
public Model associations(String association) {
this.config.associations(association);
return this;
}
/**
* ********************************************************************************
*
* Model Output
*
* Models are created to ultimately retrieve a model definition and a model instance
*/
public ModelDefinition getModelDefinition() {
return new ModelDefinition(config);
}
public ModelInstance getModelInstance() {
return new ModelInstance(config, entity);
}
private Object updateEntity(Object entity, ModelData modelData) {
try {
Class<?> clazz = entity.getClass();
Map<String, Object> data = modelData.getData();
for (String key : data.keySet()) {
if (key.equals("id")) {
continue;
}
Object val = data.get(key);
/*
* Get info about the field we're updating
*/
Field field = null;
try {
field = entity.getClass().getDeclaredField(key);
} catch (Exception e) {
}
/*
* If we don't have a field with the current name, check for a foreign entity
*/
if (key.endsWith("Id") && persistence.isManyToOne(clazz, key.substring(0, key.length() - 2))) {
key = key.substring(0, key.length() - 2);
try {
field = entity.getClass().getDeclaredField(key);
if (field != null && val != null) {
AdaptrexSession session = new AdaptrexSession();
val = session.getEntity(field.getType(), (Integer) val);
}
} catch (Exception e) {
log.warn("Error", e);
continue;
}
}
if (field == null) {
log.debug("Unable to serialize " + key);
continue;
}
String typeName = field.getType().getSimpleName().toLowerCase();
/*
* Handle Date Fields
*/
if (typeName.equals("date")) {
try {
val = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ENGLISH).parse((String) val);
} catch (Exception e) {
continue;
}
}
try {
Method getter = clazz.getMethod("set" + StringUtilities.capitalize(key), field.getType());
getter.invoke(entity, val);
} catch (Exception e) {
log.warn("Error updating field: Couldn't invoke set" + StringUtilities.capitalize(key));
}
}
} catch (Exception e) {
log.warn("Error", e);
}
AdaptrexSession session = new AdaptrexSession();
Object e = session.saveEntity(entity);
session.close();
return e;
}
}