001: /*
002: * Copyright Aduna (http://www.aduna-software.com/) (c) 1997-2007.
003: *
004: * Licensed under the Aduna BSD-style license.
005: */
006: package org.openrdf.query.impl;
007:
008: import java.util.Iterator;
009: import java.util.LinkedHashMap;
010: import java.util.Map;
011: import java.util.Set;
012:
013: import org.openrdf.model.Value;
014: import org.openrdf.query.Binding;
015: import org.openrdf.query.BindingSet;
016:
017: /**
018: * A Map-based implementation of the {@link BindingSet} interface.
019: */
020: public class MapBindingSet implements BindingSet {
021:
022: /*-----------*
023: * Variables *
024: *-----------*/
025:
026: private Map<String, Binding> bindings;
027:
028: /*--------------*
029: * Constructors *
030: *--------------*/
031:
032: public MapBindingSet() {
033: this (8);
034: }
035:
036: /**
037: * Creates a new Map-based BindingSet with the specified initial capacity.
038: * Bindings can be added to this solution using the {@link #addBinding}
039: * methods.
040: *
041: * @param capacity
042: * The initial capacity of the created BindingSet object.
043: */
044: public MapBindingSet(int capacity) {
045: // Create bindings map, compensating for HashMap's load factor
046: bindings = new LinkedHashMap<String, Binding>(capacity * 2);
047: }
048:
049: /*---------*
050: * Methods *
051: *---------*/
052:
053: /**
054: * Adds a binding to the solution.
055: *
056: * @param name
057: * The binding's name.
058: * @param value
059: * The binding's value.
060: */
061: public void addBinding(String name, Value value) {
062: addBinding(new BindingImpl(name, value));
063: }
064:
065: /**
066: * Adds a binding to the solution.
067: *
068: * @param binding
069: * The binding to add to the solution.
070: */
071: public void addBinding(Binding binding) {
072: bindings.put(binding.getName(), binding);
073: }
074:
075: /**
076: * Removes a binding from the solution.
077: *
078: * @param name
079: * The binding's name.
080: */
081: public void removeBinding(String name) {
082: bindings.remove(name);
083: }
084:
085: public Iterator<Binding> iterator() {
086: return bindings.values().iterator();
087: }
088:
089: public Set<String> getBindingNames() {
090: return bindings.keySet();
091: }
092:
093: public Binding getBinding(String bindingName) {
094: return bindings.get(bindingName);
095: }
096:
097: public boolean hasBinding(String bindingName) {
098: return bindings.containsKey(bindingName);
099: }
100:
101: public Value getValue(String bindingName) {
102: Binding binding = getBinding(bindingName);
103:
104: if (binding != null) {
105: return binding.getValue();
106: }
107:
108: return null;
109: }
110:
111: public int size() {
112: return bindings.size();
113: }
114:
115: @Override
116: public boolean equals(Object other) {
117: if (this == other) {
118: return true;
119: } else if (other instanceof BindingSet) {
120: int otherSize = 0;
121:
122: // Compare other's bindings to own
123: for (Binding binding : (BindingSet) other) {
124: Value ownValue = getValue(binding.getName());
125:
126: if (!binding.getValue().equals(ownValue)) {
127: // Unequal bindings for this name
128: return false;
129: }
130:
131: otherSize++;
132: }
133:
134: // All bindings have been matched, sets are equal if this solution
135: // doesn't have any additional bindings.
136: return otherSize == bindings.size();
137: }
138:
139: return false;
140: }
141:
142: @Override
143: public int hashCode() {
144: int hashCode = 0;
145:
146: for (Binding binding : this ) {
147: hashCode ^= binding.hashCode();
148: }
149:
150: return hashCode;
151: }
152:
153: @Override
154: public String toString() {
155: StringBuilder sb = new StringBuilder(32 * size());
156:
157: sb.append('[');
158:
159: Iterator<Binding> iter = iterator();
160: while (iter.hasNext()) {
161: sb.append(iter.next().toString());
162: if (iter.hasNext()) {
163: sb.append(';');
164: }
165: }
166:
167: sb.append(']');
168:
169: return sb.toString();
170: }
171: }
|