package net.pterodactylus.demoscenemusic.data;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
/**
* TODO
*
* @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
*/
-public class AbstractBase {
+public abstract class AbstractBase implements Base {
private final String id;
+ private final Map<String, Value<?>> attributes = new HashMap<String, Value<?>>();
+
protected AbstractBase(String id) {
this.id = id;
}
return id;
}
+ @SuppressWarnings({ "synthetic-access", "unchecked" })
+ protected <T> Value<T> value(String name, Class<T> clazz) {
+ if (!attributes.containsKey(name)) {
+ attributes.put(name, new Value<T>());
+ }
+ return (Value<T>) attributes.get(name);
+ }
+
+ protected boolean dirty() {
+ for (Value<?> value : attributes.values()) {
+ if (value.dirty()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ //
+ // OBJECT METHODS
+ //
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+ return id().hashCode();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof Base)) {
+ return false;
+ }
+ return id().equals(((Base) obj).id());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ StringBuilder stringBuilder = new StringBuilder();
+ stringBuilder.append(getClass().getName());
+ stringBuilder.append('[').append("id=").append(id());
+ for (Entry<String, Value<?>> attributeEntry : attributes.entrySet()) {
+ stringBuilder.append(',').append(attributeEntry.getKey()).append('=').append(attributeEntry.getValue().get());
+ }
+ stringBuilder.append(']');
+ return stringBuilder.toString();
+ }
+
+ protected static class Value<T> {
+
+ private T original;
+
+ private boolean originalSet;
+
+ private T current;
+
+ public T get() {
+ return current;
+ }
+
+ public Value<T> set(T value) {
+ if (!originalSet) {
+ original = value;
+ originalSet = true;
+ }
+ current = value;
+ return this;
+ }
+
+ public boolean dirty() {
+ return (original != null) ? !original.equals(current) : current != null;
+ }
+
+ public Value<T> commit() {
+ original = current;
+ return this;
+ }
+
+ }
+
}