/******************************************************************************* * Copyright (c) 2004, 2007 IBM Corporation and Cambridge Semantics Incorporated. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * File: $Source: /cvsroot/slrp/glitter/com.ibm.adtech.glitter/src/com/ibm/adtech/glitter/rdf/Variable.java,v $ * Created by: Lee Feigenbaum (<a href="mailto:feigenbl@us.ibm.com">feigenbl@us.ibm.com</a>) * Created on: 10/23/06 * Revision: $Id: Variable.java 164 2007-07-31 14:11:09Z mroy $ * * Contributors: IBM Corporation - initial API and implementation * Cambridge Semantics Incorporated - Fork to Anzo *******************************************************************************/ package org.openanzo.rdf; import java.io.ObjectStreamException; import java.lang.ref.SoftReference; import java.util.Map; import java.util.WeakHashMap; import org.apache.commons.lang.StringUtils; import org.openanzo.exceptions.AnzoRuntimeException; import org.openanzo.exceptions.ExceptionConstants; /** * A variable in a SPARQL query. The {@link MemVariable} class maintains a cache to reuse {@link MemVariable} objects sharing the same name. * * @author lee <lee@cambridgesemantics.com> * */ public class MemVariable implements Variable { private static final long serialVersionUID = -7113608448508192908L; private final String name; private int hashCode = -1; private String varName; /** WeakHashMap cache of uris */ static private final Map<String, SoftReference<MemVariable>> cache = new WeakHashMap<String, SoftReference<MemVariable>>(); /** * Static factory method that uses an WeakHashMap cache to reuse {@link MemVariable} objects for variables with the same name. * * @param variableName * name of variable * @return {@link MemVariable} for given name */ static public MemVariable createVariable(String variableName) { if (variableName.startsWith("?")) { throw new AnzoRuntimeException(ExceptionConstants.CLIENT.VARIABLE_START_QUESTION, variableName); } if (!StringUtils.containsNone(variableName, " \t\n\r\f")) { throw new AnzoRuntimeException(ExceptionConstants.CLIENT.VARIABLE_NO_SPACES, variableName); } SoftReference<MemVariable> ref = cache.get(variableName); MemVariable var = (ref != null) ? ref.get() : null; if (var == null) { var = new MemVariable(variableName); cache.put(variableName, new SoftReference<MemVariable>(var)); } return var; } private MemVariable(String variableName) { this.name = variableName; this.varName = "?" + this.name; } protected Object readResolve() throws ObjectStreamException { return createVariable(name); } @Override public String toString() { return this.varName; } /* (non-Javadoc) * @see org.openanzo.rdf.Variable#getName() */ public String getName() { return this.name; } @Override public boolean equals(Object other) { //Since we have a weak-hash-map of variables, you will always get the same object for the same variable return (this == other); // we've gone back and forth over whether identity for // variables is universal identity (object identity) or // whether the name of a variableis universally scoped // such that ?x always is equal to ?x. Currently, that's // the definition we go with. } @Override public int hashCode() { if (hashCode == -1) { hashCode = this.name.hashCode(); } return hashCode; } public boolean equalName(Variable other) { return other != null && this.getName().equals(other.getName()); } public int compareTo(TriplePatternComponent o) { if (o == this) return 0; return toString().compareTo(o.toString()); } }