import java.util.Map.Entry;
/**
- * TODO
+ * Base implementation of a data container. It stores the ID of a container and
+ * can contain arbitrary attributes.
*
* @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
*/
public class DefaultBase implements Base {
+ /** The ID of the data container. */
private final String id;
+ /** The attributes of the data container. */
private final Map<String, Value<?>> attributes = new HashMap<String, Value<?>>();
+ /**
+ * Creates a new data container with the given ID.
+ *
+ * @param id
+ * The ID of the data container
+ */
protected DefaultBase(String id) {
this.id = id;
}
- public String id() {
+ //
+ // ACCESSORS
+ //
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getId() {
return id;
}
- @SuppressWarnings({ "synthetic-access", "unchecked" })
- protected <T> Value<T> value(String name, Class<T> clazz) {
+ /**
+ * Returns whether the data container contains an attribute with the given
+ * name.
+ *
+ * @param name
+ * The name of the attribute to check for
+ * @return {@code true} if this data container contains an attribute with
+ * the given name, {@code false} otherwise
+ */
+ protected boolean hasValue(String name) {
+ return attributes.containsKey(name);
+ }
+
+ /**
+ * Returns the value of the attribute with the given name. If no value for
+ * the given attribute exists, one will be created, stored, and returned.
+ *
+ * @param <T>
+ * The type of the value to return
+ * @param name
+ * The name of the attribute to get
+ * @param clazz
+ * The class of the value
+ * @return The value of the attribute
+ */
+ @SuppressWarnings({ "unchecked" })
+ protected <T> Value<T> getValue(String name, Class<T> clazz) {
if (!attributes.containsKey(name)) {
attributes.put(name, new Value<T>());
}
return (Value<T>) attributes.get(name);
}
- protected boolean dirty() {
+ /**
+ * Returns whether any of the attributes of this data container is dirty,
+ * i.e. it was modified after its initial inception.
+ *
+ * @return {@code true} if any attribute of this data container was modified
+ */
+ protected boolean isDirty() {
for (Value<?> value : attributes.values()) {
- if (value.dirty()) {
+ if (value.isDirty()) {
return true;
}
}
*/
@Override
public int hashCode() {
- return id().hashCode();
+ return getId().hashCode();
}
/**
if (!(obj instanceof Base)) {
return false;
}
- return id().equals(((Base) obj).id());
+ return getId().equals(((Base) obj).getId());
}
/**
public String toString() {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(getClass().getName());
- stringBuilder.append('[').append("id=").append(id());
+ stringBuilder.append('[').append("id=").append(getId());
for (Entry<String, Value<?>> attributeEntry : attributes.entrySet()) {
stringBuilder.append(',').append(attributeEntry.getKey()).append('=').append(attributeEntry.getValue().get());
}
return stringBuilder.toString();
}
+ /**
+ * Container for an attribute value stored in a data container.
+ *
+ * @see DefaultBase#attributes
+ * @param <T>
+ * The type of the value
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
protected static class Value<T> {
+ /** The original value. */
private T original;
+ /** Whether the original value has been set. */
private boolean originalSet;
+ /** The current value. */
private T current;
+ //
+ // ACCESSORS
+ //
+
+ /**
+ * Returns the current value.
+ *
+ * @return The current value
+ */
public T get() {
return current;
}
+ /**
+ * Sets the current value. If no original value has yet been set, the
+ * given value is also stored as original value.
+ *
+ * @param value
+ * The value to set
+ * @return This value
+ */
public Value<T> set(T value) {
if (!originalSet) {
original = value;
return this;
}
- public boolean dirty() {
+ /**
+ * Returns whether the value of this value does not equal its original
+ * value.
+ *
+ * @return {@code true} if the current value is not equal to the
+ * original value, {@code false} if it is equal to the original
+ * value
+ */
+ public boolean isDirty() {
return (original != null) ? !original.equals(current) : current != null;
}
+ /**
+ * Commits the current value, i.e. sets the original value to the
+ * current value.
+ *
+ * @return This value
+ */
public Value<T> commit() {
original = current;
return this;