package org.openanzo.rdf; import java.io.ObjectStreamException; import java.lang.ref.SoftReference; import java.lang.ref.WeakReference; import java.util.Map; import java.util.WeakHashMap; /** * Represents a blank node, identified by an index. Identity is determined purely by object reference equality. * * @author lee <lee@cambridgesemantics.com> * */ public class MemBlankNode implements BlankNode { private static final long serialVersionUID = 4126408067877740675L; private int hashCode = -1; final private String value; private transient SoftReference<String> toStringValue = null; private static Map<String, WeakReference<String>> map = new WeakHashMap<String, WeakReference<String>>(); private synchronized static String replace(String object) { if (object == null) { return null; } WeakReference<String> reference = map.get(object); if (reference != null) { String result = reference.get(); // Another null check, since the GC may have kicked in between the // two lines above. if (result != null) { return result; } } // If we got here it is because the map doesn't have the key, add it. map.put(object, new WeakReference<String>(object)); return object; } /** * Create a blanknode with the given ID * * @param id * id of blank node * @return blank node for id */ public static BlankNode create(String id) { return MemValueFactory.defaultFactory.createBNode(id); } protected Object readResolve() throws ObjectStreamException { return create(value); } /** * Constructor. * * @param index */ protected MemBlankNode(String value) { this.value = replace(value); } @Override public String toString() { String string = (toStringValue != null) ? toStringValue.get() : null; if (string == null) { string = Constants.BNODE_PREFIX + this.value; toStringValue = new SoftReference<String>(string); } return string; } @Override public boolean equals(Object other) { if (other instanceof MemBlankNode) { // we don't change the natural meaning of equals, and want to be explicit about it. // blank nodes are only equal if they're the same object. return this == other || ((MemBlankNode) other).value.equals(value); } else if (other instanceof BlankNode) { // we don't change the natural meaning of equals, and want to be explicit about it. // blank nodes are only equal if they're the same object. return this == other || ((BlankNode) other).getLabel().equals(value); } else { return false; } } @Override public int hashCode() { if (hashCode == -1) { hashCode = value.hashCode(); } // we don't change the natural meaning of hashCode, and want to be explicit about it. // blank nodes are only the same if they're the same object. return hashCode; } public int compareTo(TriplePatternComponent o) { return toString().compareTo(o.toString()); } public String getLabel() { return value; } }