Declare context in the try-catch block.
[demoscenemusic.git] / src / main / java / net / pterodactylus / demoscenemusic / data / AbstractBase.java
index 2f7f3c7..ad5cfd8 100644 (file)
 
 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;
        }
@@ -34,4 +40,91 @@ public class AbstractBase {
                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;
+               }
+
+       }
+
 }