/*
* 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.ModelData;
import com.adaptrex.core.ext.rest.RestOptions;
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 javax.persistence.EntityManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/*
* Model... wraps a ModelInstance and ModelDefinition
*/
public class Model {
private AdaptrexSession adaptrexSession;
private Object entity;
private DataConfig config;
private static String[] dateFormatStrings = {"yyyy-MM-dd'T'HH:mm:ss", "yyyy-MM-dd", "HH:mm:ss"};
private static Logger log = LoggerFactory.getLogger(Model.class);
public Model(AdaptrexSession adaptrexSession, DataConfig config) {
this(adaptrexSession, config, null);
}
public Model(AdaptrexSession adaptrexSeession, DataConfig config, Integer id) {
this.adaptrexSession = new AdaptrexSession(config.getAdaptrexPersistence());
this.config = config;
if (id != null) {
this.entity = config.getAdaptrexPersistence().getEntity(adaptrexSession, config.getClazz(), id);
} else {
log.debug("Creating new instance of " + config.getClazz().getSimpleName());
try {
this.entity = config.getClazz().newInstance();
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
}
}
}
/*
* Read
*/
public static Model read(String entityName, Integer id) {
return read(entityName, id, null, null);
}
public static Model read(String entityName, Integer id, String factoryName) {
return read(entityName, id, null, factoryName);
}
public static Model read(String entityName, Integer id, RestOptions restOptions) {
return read(entityName, id, restOptions, null);
}
public static Model read(String entityName, Integer id, RestOptions restOptions, String factoryName) {
AdaptrexPersistence persistence = Adaptrex.getAdaptrex().getPersistenceManager().getPersistence(factoryName);
AdaptrexSession session = new AdaptrexSession(persistence);
Class<?> clazz = persistence.getEntityClass(entityName);
DataConfig config = new DataConfig(clazz, persistence);
if (restOptions != null) {
config.applyRestOptions(restOptions);
}
return new Model(session, config, id);
}
/*
* Create
*/
public static Model create(String entityName, ModelData modelData) {
return create(entityName, modelData, null, null);
}
public static Model create(String entityName, ModelData modelData, String factoryName) {
return create(entityName, modelData, null, factoryName);
}
public static Model create(String entityName, ModelData modelData, RestOptions restOptions) {
return create(entityName, modelData, restOptions, null);
}
public static Model create(String entityName, ModelData modelData, RestOptions restOptions, String factoryName) {
AdaptrexPersistence persistence = Adaptrex.getAdaptrex().getPersistenceManager().getPersistence(factoryName);
AdaptrexSession session = new AdaptrexSession(persistence);
Class<?> clazz = persistence.getEntityClass(entityName);
DataConfig config = new DataConfig(clazz, persistence);
if (restOptions != null) {
config.applyRestOptions(restOptions);
}
Model model = new Model(session, config);
model.entity = updateEntity(session, model, modelData);
session.close();
return model;
}
/*
* Update
*/
public static Model update(String entityName, Integer id, ModelData modelData) {
return update(entityName, id, modelData, null, null);
}
public static Model update(String entityName, Integer id, ModelData modelData, String factoryName) {
return update(entityName, id, modelData, null, factoryName);
}
public static Model update(String entityName, Integer id, ModelData modelData, RestOptions restOptions) {
return update(entityName, id, modelData, restOptions, null);
}
public static Model update(String entityName, Integer id, ModelData modelData, RestOptions restOptions, String factoryName) {
AdaptrexPersistence persistence = Adaptrex.getAdaptrex().getPersistenceManager().getPersistence(factoryName);
AdaptrexSession session = new AdaptrexSession(persistence);
Class<?> clazz = persistence.getEntityClass(entityName);
DataConfig config = new DataConfig(clazz, persistence);
if (restOptions != null) {
config.applyRestOptions(restOptions);
}
Model model = new Model(session, config, id);
updateEntity(session, model, modelData);
session.close();
return model;
}
/*
* Delete
*/
public static Model delete(String entityName, Integer id) {
return delete(entityName, id, null);
}
public static Model delete(String entityName, Integer id, String factoryName) {
AdaptrexPersistence persistence = Adaptrex.getAdaptrex().getPersistenceManager().getPersistence(factoryName);
AdaptrexSession session = new AdaptrexSession(persistence);
Class<?> clazz = persistence.getEntityClass(entityName);
DataConfig config = new DataConfig(clazz, persistence);
Model model = new Model(session, config, id);
persistence.deleteEntity(session, model.getEntity());
session.close();
return model;
}
/*
* Expose this model's config
*/
public DataConfig getConfig() {
return config;
}
public Object getEntity() {
return entity;
}
/**
* ********************************************************************************
*
* 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(adaptrexSession, config, entity);
}
/*
* Update Entity
*/
private static Object updateEntity(AdaptrexSession session, Model model, ModelData modelData) {
AdaptrexPersistence persistence = session.getPersistence();
Object entity = model.getEntity();
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) {
val = persistence.getEntity(session, field.getType(), (Integer) val);
}
} catch (Exception e) {
continue;
}
}
if (field == null) {
continue;
}
String typeName = field.getType().getSimpleName().toLowerCase();
/*
* Handle Date Fields
*/
if (typeName.equals("date")) {
for (String formatString : dateFormatStrings) {
try {
val = new SimpleDateFormat(formatString, Locale.ENGLISH).parse((String) val);
break;
} catch (Exception e) {}
}
}
try {
Method getter = clazz.getMethod("set" + StringUtilities.capitalize(key), field.getType());
getter.invoke(entity, val);
} catch (Exception e) {
}
}
} catch (Exception e) {
}
Object e = persistence.saveEntity(session, entity);
return e;
}
}