package org.greengin.sciencetoolkit.common.model;
import java.util.Collections;
import java.util.Comparator;
import java.util.Hashtable;
import java.util.Map.Entry;
import java.util.Vector;
public class Model {
Model parent;
Hashtable<String, Object> entries;
ModelChangeListener listener;
private Model(Model parent, ModelChangeListener listener) {
this.parent = parent;
this.listener = listener;
this.entries = new Hashtable<String, Object>();
}
public Model(Model parent) {
this(parent, parent.listener);
}
public Model(ModelChangeListener listener) {
this(null, listener);
}
public Model cloneModel(Model parent) {
Model clone = new Model(parent, this.listener);
for (Entry<String, Object> entry : entries.entrySet()) {
Object value = entry.getValue() instanceof Model ? ((Model) entry.getValue()).cloneModel(clone) : entry.getValue();
clone.set(entry.getKey(), value, true);
}
return clone;
}
public boolean containsKey(String key) {
return entries.contains(key);
}
public Model getParent() {
return parent;
}
public Model getRootParent() {
return parent == null ? this : parent.getRootParent();
}
public void fireModifiedEvent() {
this.listener.modelModified(this);
}
public Hashtable<String, Object> entries() {
return entries;
}
private boolean set(String key, Object obj, boolean suppressSave) {
if (obj != null && !obj.equals(entries.get(key))) {
entries.put(key, obj);
if (!suppressSave) {
fireModifiedEvent();
}
return true;
} else {
return false;
}
}
public boolean clearAll(boolean suppressSave) {
if (entries.size() > 0) {
entries.clear();
if (!suppressSave) {
listener.modelModified(this);
}
return true;
} else {
return false;
}
}
public boolean clear(String key) {
return clear(key, false);
}
public boolean clear(String key, boolean suppressSave) {
boolean removed = entries.remove(key) != null;
if (removed && !suppressSave) {
listener.modelModified(this);
}
return removed;
}
private Object get(String key, Object defaultValue) {
return entries.containsKey(key) ? entries.get(key) : defaultValue;
}
public boolean setInt(String key, int value) {
return setInt(key, value, false);
}
public boolean setLong(String key, long value) {
return setLong(key, value, false);
}
public boolean setDouble(String key, double value) {
return setDouble(key, value, false);
}
public boolean setString(String key, String value) {
return setString(key, value, false);
}
public boolean setBool(String key, boolean value) {
return setBool(key, value, false);
}
public boolean setModel(String key, Model model) {
return set(key, model, false);
}
public boolean setInt(String key, int value, boolean suppressSave) {
return set(key, value, suppressSave);
}
public boolean setLong(String key, long value, boolean suppressSave) {
return set(key, value, suppressSave);
}
public boolean setDouble(String key, double value, boolean suppressSave) {
return set(key, value, suppressSave);
}
public boolean setString(String key, String value, boolean suppressSave) {
return set(key, value, suppressSave);
}
public boolean setBool(String key, boolean value, boolean suppressSave) {
return set(key, value, suppressSave);
}
public boolean setModel(String key, Model model, boolean suppressSave) {
return set(key, model, suppressSave);
}
public Integer getInt(String key) {
return getInt(key, 0);
}
public Long getLong(String key) {
return getLong(key, 0);
}
public Integer getInt(String key, int defaultValue) {
return (Integer) get(key, defaultValue);
}
public Long getLong(String key, long defaultValue) {
return (Long) get(key, defaultValue);
}
public Number getNumber(String key, Number defaultValue) {
return (Number) get(key, defaultValue);
}
public Double getDouble(String key) {
return getDouble(key, 0.);
}
public Double getDouble(String key, double defaultValue) {
return (Double) get(key, defaultValue);
}
public Boolean getBool(String key) {
return getBool(key, false);
}
public Boolean getBool(String key, boolean defaultValue) {
return (Boolean) get(key, defaultValue);
}
public String getString(String key) {
return getString(key, "");
}
public String getString(String key, String defaultValue) {
return (String) get(key, defaultValue);
}
public boolean copyPrimitives(Model source, boolean suppressSave) {
if (source != null) {
boolean modified = false;
for (Entry<String, Object> entry : source.entries.entrySet()) {
if (!"id".equals(entry.getKey()) && (entry.getValue() instanceof String || entry.getValue() instanceof Boolean || entry.getValue() instanceof Number)) {
modified = this.set(entry.getKey(), entry.getValue(), true) || modified;
}
}
if (modified && !suppressSave) {
this.listener.modelModified(this);
}
return modified;
}
return false;
}
public Model getModel(String key) {
return getModel(key, false, false);
}
public Model getModel(String key, boolean createIfNotExists) {
return getModel(key, createIfNotExists, false);
}
public Model getModel(String key, boolean createIfNotExists, boolean suppressSave) {
if (entries.containsKey(key)) {
return (Model) entries.get(key);
} else if (createIfNotExists) {
Model model = new Model(this);
entries.put(key, model);
if (!suppressSave) {
listener.modelModified(this);
}
return model;
} else {
return null;
}
}
public Hashtable<String, String> getStrings() {
Hashtable<String, String> values = new Hashtable<String, String>();
for (Entry<String, Object> entry : entries.entrySet()) {
if (entry.getValue() instanceof String) {
values.put(entry.getKey(), (String) entry.getValue());
}
}
return values;
}
public Vector<Model> getModels() {
Vector<Model> models = new Vector<Model>();
for (Entry<String, Object> entry : entries.entrySet()) {
if (entry.getValue() instanceof Model) {
models.add((Model) entry.getValue());
}
}
return models;
}
public Vector<Model> getModels(String orderKey) {
return getModels(orderKey, false);
}
public Vector<Model> getModels(String orderKey, boolean reverse) {
Vector<Model> models = getModels();
if (orderKey != null) {
Collections.sort(models, new ModelComparator(orderKey, reverse));
}
return models;
}
private static class ModelComparator implements Comparator<Model> {
String key;
int k;
public ModelComparator(String key, boolean reverse) {
this.key = key;
this.k = reverse ? -1 : 1;
}
@Override
public int compare(Model lhs, Model rhs) {
Object va = lhs.get(key, null);
Object vb = rhs.get(key, null);
int result;
if (va == null && vb == null) {
result = 0;
} else if (va == null) {
result = -1;
} else if (vb == null) {
result = 1;
} else if (va instanceof String && vb instanceof String) {
result = ((String) va).compareTo((String) vb);
} else if (va instanceof Long && vb instanceof Long) {
result = ((Long) va).compareTo((Long) vb);
} else if (va instanceof Double && vb instanceof Double) {
result = ((Double) va).compareTo((Double) vb);
} else if (va instanceof Integer && vb instanceof Integer) {
result = ((Integer) va).compareTo((Integer) vb);
} else if (va instanceof Boolean && vb instanceof Boolean) {
result = ((Boolean) va).compareTo((Boolean) vb);
} else {
result = 0;
}
return k * result;
}
}
}