package org.eclipse.buckminster.core.metadata; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; import org.eclipse.buckminster.core.metadata.model.ElementNotFoundException; import org.eclipse.buckminster.runtime.BuckminsterException; import org.eclipse.buckminster.runtime.Trivial; import org.eclipse.buckminster.sax.UUIDKeyed; import org.eclipse.core.runtime.CoreException; public class MemoryStorage<T extends UUIDKeyed> extends AbstractSaxableStorage<T> { static class TimestampedElement<ET extends UUIDKeyed> extends TimestampedKey { private final ET element; TimestampedElement(ET element) { super(element.getId(), System.currentTimeMillis()); this.element = element; } ET getElement() { return element; } } private final Map<UUID, TimestampedElement<T>> elements = new HashMap<UUID, TimestampedElement<T>>(); public MemoryStorage(Class<T> elementClass) { super(elementClass); } @Override public synchronized void clear() { elements.clear(); } @Override public synchronized boolean contains(T element) throws CoreException { return elements.containsKey(element.getId()); } @Override public synchronized long getCreationTime(UUID elementId) throws CoreException { TimestampedElement<T> t = elements.get(elementId); if (t == null) throw new ElementNotFoundException(this, elementId); return t.getCreationTime(); } @Override public synchronized T getElement(UUID elementId) throws CoreException, ElementNotFoundException { TimestampedElement<T> t = elements.get(elementId); if (t == null) throw new ElementNotFoundException(this, elementId); return t.getElement(); } @Override public synchronized T[] getElements() throws CoreException { T[] elems = createArray(elements.size()); int idx = 0; for (TimestampedElement<T> te : elements.values()) elems[idx++] = te.getElement(); return elems; } @Override public synchronized UUID[] getKeys() { return elements.keySet().toArray(new UUID[elements.size()]); } @Override public String getName() { return getClass().getName(); } @Override public synchronized List<UUID> getReferencingKeys(UUID foreignKey, String keyName) throws CoreException { List<UUID> result = null; Method getter = getGetter(keyName); try { for (TimestampedElement<T> et : elements.values()) { T element = et.getElement(); UUID fkey = (UUID) getter.invoke(element, Trivial.EMPTY_OBJECT_ARRAY); if (fkey != null && fkey.equals(foreignKey)) { if (result == null) result = new ArrayList<UUID>(); result.add(element.getId()); } } if (result == null) result = Collections.emptyList(); return result; } catch (Exception e) { throw BuckminsterException.wrap(e); } } @Override public synchronized TimestampedKey[] getTimestampedKeys() { return elements.values().toArray(new TimestampedKey[elements.size()]); } @Override public void putElement(T element) throws CoreException { putElement(element.getId(), element); } @Override public synchronized void putElement(UUID id, T element) throws CoreException { elements.put(id, new TimestampedElement<T>(element)); } @Override public synchronized void removeElement(UUID elementId) throws CoreException { elements.remove(elementId); } @Override public boolean sequenceChanged() { return false; } }