
com.morpheusdata.model.MorpheusModel Maven / Gradle / Ivy
package com.morpheusdata.model;
import com.fasterxml.jackson.annotation.JsonIgnore;
import java.io.StringReader;
import java.lang.reflect.Field;
import java.math.*;
import java.util.*;
import javax.json.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Base class for all Morpheus Model classes. This provides dirty checking capabilities for most base object representations
* and common id property representations. All setter methods in a Morpheus class should call the markDirty method. So that
* the underlying Context classes can perform differential updates of these models.
*
* @author David Estes
*/
public class MorpheusModel {
static Logger log = LoggerFactory.getLogger(MorpheusModel.class);
/**
* Database reference Id of the Object. Typically not directly set.
*/
protected Long id;
protected String config;
//TODO: Add validation errors property for all Models here. Think this should be a collection and not a map since
//a key could have multiple errors.
/**
* Internal property used to keep track of a list of dirty fields on the currently extended Model class.
*/
@JsonIgnore
private LinkedHashMap dirtyProperties = new LinkedHashMap<>();
/**
* Internal property used to keep track of a fields chages on the currently extended Model class.
*/
private LinkedHashMap persistedProperties = new LinkedHashMap<>();
/**
* Gets the uniquely generated ID from the database record stored via the Morpheus appliance.
* @return id
*/
public Long getId() {
return id;
}
/**
* Used for setting the unique ID of the Pool Type. This should not be directly used.
* @param id unique identifer
*/
public void setId(Long id) {
this.id = id;
}
/**
* All setters that are presented to the morpheus API should call markDirty with a string representation of the fieldname.
* This enables the {@link com.morpheusdata.core.MorpheusContext} to reconcile differences and perform differential updates.
* @param propertyName Name of the property that has been changed
* @param value The newly assigned value the property has been given.
*
*/
protected void markDirty(String propertyName, Object value) {
dirtyProperties.put(propertyName,value);
}
/**
* All setters that are presented to the morpheus API should call markDirty with a string representation of the fieldname.
* This enables the {@link com.morpheusdata.core.MorpheusContext} to reconcile differences and perform differential updates.
* @param propertyName Name of the property that has been changed
* @param value The newly assigned value the property has been given.
* @param persistedValue The old value of the property.
*/
protected void markDirty(String propertyName, Object value, Object persistedValue) {
markDirty(propertyName, value);
persistedProperties.put(propertyName, persistedValue);
}
/**
* Marks the corresponding Model clean from all changes. This resets all stored differential value changes.
*/
public void markClean() {
dirtyProperties.clear();
persistedProperties.clear();
}
/**
* Checks if a property has been modified
* @param propertyName Name of the property to check
* @return true or false
*/
public Boolean isDirty(String propertyName) {
return dirtyProperties.containsKey(propertyName);
}
/**
* Gets a list of all dirty properties / fields (things that have changes) on the corresponding model based on the
* used setters.
* @return A List of dirty fields by name
*/
@JsonIgnore
public Set getDirtyProperties() {
return dirtyProperties.keySet();
}
/**
* Gets a Map containing all dirty properties as well as their newly assigned values.
* @return A Map containing all model changes on properties from the original object.
*/
@JsonIgnore
public LinkedHashMap getDirtyPropertyValues() {
return dirtyProperties;
}
/**
* @return A Map of all properties, similar to Groovy's getProperties()
*/
@JsonIgnore
public HashMap getProperties() {
HashMap map = new HashMap<>();
for(Class clazz = this.getClass(); clazz != null && clazz != Object.class; clazz = clazz.getSuperclass()) {
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
String name = field.getName();
Object value = null;
try {
value = field.get(this);
} catch (IllegalAccessException ignore) { }
map.put(name, value);
}
}
return map;
}
public String getConfig() {
return this.config;
}
public void setConfig(String config) {
markDirty("config", config, this.config);
this.config = config;
}
public Map getConfigMap() {
Map map = new HashMap();
try {
if(this.config != null && this.config != "") {
JsonReader jsonReader = Json.createReader(new StringReader(this.config));
JsonObject object = jsonReader.readObject();
jsonReader.close();
map = toMap(object);
}
} catch(Exception e) {
//fail silently
log.error("Error parsing config as JSON: {}",e.getMessage(),e);
}
return map;
}
public void setConfigMap(Map map) {
JsonObject object = mapToJson(map);
setConfig(object.toString());
}
private JsonObject mapToJson(Map map) {
JsonObjectBuilder builder = Json.createObjectBuilder();
for (String key : map.keySet()) {
Object val = map.get(key);
if (val instanceof String) {
builder.add(key, (String) val);
} else if (val instanceof Number) {
if(val instanceof Integer) {
builder.add(key, (Integer) val);
} else if(val instanceof Double) {
builder.add(key, (Double) val);
} else if(val instanceof Long) {
builder.add(key, (Long) val);
} else if(val instanceof Boolean) {
builder.add(key, (Boolean) val);
} else if(val instanceof Short) {
builder.add(key, (Short) val);
} else if(val instanceof Float) {
builder.add(key, (Float) val);
} else {
builder.add(key, (BigDecimal) val);
}
} else if(val instanceof Boolean) {
builder.add(key, (Boolean) val);
} else if(val instanceof Map) {
builder.add(key, mapToJson((Map) val));
} else if (val instanceof List) {
builder.add(key, listToJson((List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy