001: /*
002: * Created on 13-May-2005
003: *
004: */
005: package com.jofti.tree;
006:
007: import java.lang.reflect.Array;
008: import java.util.ArrayList;
009: import java.util.Collection;
010: import java.util.Iterator;
011: import java.util.List;
012: import java.util.Map;
013:
014: import org.apache.commons.logging.Log;
015: import org.apache.commons.logging.LogFactory;
016:
017: import com.jofti.btree.BTOperations;
018: import com.jofti.btree.BTree;
019: import com.jofti.btree.KeyValueObject;
020: import com.jofti.btree.ValueObject;
021: import com.jofti.exception.JoftiException;
022: import com.jofti.introspect.ClassIntrospector;
023:
024: /**
025: * @author Steve Woodcock (steve@jofti.com)
026: *
027: */
028: public class TreeOperationAdapter {
029:
030: private static Log log = LogFactory
031: .getLog(TreeOperationAdapter.class);
032:
033: public void insertEntry(Comparable key, Object value, BTree tree,
034: ClassIntrospector parser) throws IllegalArgumentException,
035: JoftiException {
036: List addedObjects = new ArrayList();
037:
038: ValueObject val = (ValueObject) value;
039:
040: try {
041:
042: if (log.isDebugEnabled()) {
043: log.debug("Attempting to insert key '" + key + "'");
044: }
045:
046: if (val.getDimension() < 0) {
047: // must be a key value
048: BTOperations.insertKeyValue(tree, key,
049: ((KeyValueObject) val).getAttributes(), val
050: .getDimension());
051: addedObjects.add(key);
052: } else {
053: BTOperations.insertValue(tree, key, (Comparable) val
054: .getRealValue(), val.getDimension());
055: }
056: } catch (JoftiException e) {
057: log.error("Error encountered - removing indexed objects "
058: + addedObjects, e);
059: removeIndexedValuesByKey(addedObjects, tree, parser);
060: }
061:
062: }
063:
064: public void insert(Comparable key, Object value, BTree tree,
065: ClassIntrospector parser) throws IllegalArgumentException,
066: JoftiException {
067: // first is it the right type
068: List addedObjects = new ArrayList();
069: Map attributes = parser.getAttributeValues(value);
070: if (attributes == null || attributes.isEmpty()) {
071: if (log.isDebugEnabled()) {
072: log.debug("No attributes found for '" + key
073: + "' ignoring in index");
074: }
075: return;
076: }
077: try {
078:
079: if (log.isDebugEnabled()) {
080: log.debug("Attempting to insert key '" + key + "'");
081: }
082:
083: // we index the key first
084:
085: BTOperations.insertKeyValue(tree, key, attributes, parser
086: .getKeyDimension(key.getClass()));
087: addedObjects.add(key);
088: if (log.isDebugEnabled()) {
089: log.debug("inserted key '" + key + "'");
090: }
091:
092: treeInsert(key, tree, attributes, addedObjects);
093:
094: } catch (JoftiException e) {
095: log.error("Error encountered - removing indexed objects "
096: + addedObjects, e);
097: removeIndexedValues(key, addedObjects, tree);
098: }
099: }
100:
101: protected void treeInsert(Comparable key, BTree tree,
102: Map attributes, List addedObjects)
103: throws IllegalArgumentException, JoftiException {
104:
105: int size = attributes.entrySet().size();
106: Iterator it = attributes.entrySet().iterator();
107: for (int i = 0; i < size; i++) {
108: Map.Entry entry = (Map.Entry) it.next();
109:
110: if (log.isDebugEnabled()) {
111: log.debug("Attempting to insert key '" + key
112: + "' value '" + entry.getValue());
113: }
114:
115: if (entry.getValue().getClass().isArray()) {
116: Object temp = entry.getValue();
117: // we need to loop through the values here
118: int arraySize = Array.getLength(temp);
119: for (int j = 0; j < arraySize; j++) {
120: Object val = Array.get(temp, j);
121: BTOperations.insertValue(tree, key,
122: (Comparable) val,
123: ((Integer) entry.getKey()).intValue());
124:
125: }
126: } else {
127: BTOperations.insertValue(tree, key, (Comparable) entry
128: .getValue(), ((Integer) entry.getKey())
129: .intValue());
130: }
131: addedObjects.add(entry.getValue());
132: if (log.isDebugEnabled()) {
133: log.debug("Insert key '" + key + "' value '"
134: + entry.getValue());
135: }
136:
137: }
138:
139: }
140:
141: public void remove(Comparable key, Object value, BTree tree,
142: ClassIntrospector parser) throws IllegalArgumentException,
143: JoftiException {
144: // first is it the right type
145:
146: treeRemove(key, value, tree, parser);
147:
148: if (log.isDebugEnabled()) {
149: log.debug("Attempting to remove key '" + key + "'");
150: }
151:
152: BTOperations.removeValue(tree, key, key, parser
153: .getKeyDimension(key.getClass()));
154: if (log.isDebugEnabled()) {
155: log.debug("Removed key '" + key + "'");
156: }
157: }
158:
159: protected void treeRemove(Comparable key, Object value, BTree tree,
160: ClassIntrospector parser) throws IllegalArgumentException,
161: JoftiException {
162:
163: try {
164: Map attributes = parser.getAttributeValues(value);
165:
166: for (Iterator it = attributes.entrySet().iterator(); it
167: .hasNext();) {
168: Map.Entry entry = (Map.Entry) it.next();
169: if (log.isDebugEnabled()) {
170: log.debug("Attempting to remove key '" + key
171: + "' value '" + entry.getValue());
172: }
173: BTOperations.removeValue(tree, key, (Comparable) entry
174: .getValue(), ((Integer) entry.getKey())
175: .intValue());
176: if (log.isDebugEnabled()) {
177: log.debug("Removed key '" + key + "' value '"
178: + entry.getValue());
179: }
180: }
181: } catch (JoftiException e) {
182: throw e;
183: }
184: }
185:
186: public void removeIndexedValuesByKey(List added, BTree tree,
187: ClassIntrospector parser) {
188: for (Iterator it = added.iterator(); it.hasNext();) {
189: Comparable obj = null;
190: try {
191: obj = (Comparable) it.next();
192: removeByKey(obj, tree, parser);
193: } catch (JoftiException e) {
194: log.error("unable to remove value " + obj
195: + " under key " + obj, e);
196: }
197: }
198: }
199:
200: public void removeIndexedValues(Object key, List added, BTree tree) {
201: for (Iterator it = added.iterator(); it.hasNext();) {
202: Comparable obj = null;
203: try {
204: obj = (Comparable) it.next();
205: BTOperations.removeValueObject(tree, key, obj);
206: } catch (JoftiException e) {
207: log.error("unable to remove value " + obj
208: + " under key " + key, e);
209: }
210: }
211: }
212:
213: public void removeEntries(Comparable value, BTree tree,
214: ClassIntrospector parser) throws JoftiException {
215: Collection matchingValues = BTOperations.getAllValuesForKey(
216: tree, value, parser.getKeyDimension(value.getClass()));
217:
218: for (Iterator it = matchingValues.iterator(); it.hasNext();) {
219: BTOperations.removeValueObject(tree, value, (Comparable) it
220: .next());
221:
222: }
223: }
224:
225: public void removeByKey(Comparable value, BTree tree,
226: ClassIntrospector parser) throws JoftiException {
227:
228: Collection matchingValues = BTOperations.getKeyAttributes(tree,
229: value, parser.getKeyDimension(value.getClass()));
230: if (matchingValues != null) {
231: if (matchingValues.size() > 0) {
232: for (Iterator it = matchingValues.iterator(); it
233: .hasNext();) {
234: BTOperations.removeValueObject(tree, value,
235: (Comparable) it.next());
236:
237: }
238: }
239: if (log.isDebugEnabled()) {
240: log.debug("Attempting to remove key '" + value + "'");
241: }
242:
243: BTOperations.removeValue(tree, value, value, parser
244: .getKeyDimension(value.getClass()));
245: if (log.isDebugEnabled()) {
246: log.debug("Removed key '" + value + "'");
247: }
248:
249: }
250:
251: }
252:
253: public Collection getAttribsByKey(Comparable value, BTree tree,
254: ClassIntrospector parser) throws JoftiException {
255:
256: return BTOperations.getKeyAttributes(tree, value, parser
257: .getKeyDimension(value.getClass()));
258:
259: }
260:
261: public boolean contains(Comparable key, BTree tree,
262: ClassIntrospector parser) throws JoftiException {
263: return BTOperations.contains(tree, key, parser
264: .getKeyDimension(key.getClass()));
265: }
266:
267: public Map getAllValuesForKey(Comparable key, BTree tree,
268: ClassIntrospector parser) throws JoftiException {
269:
270: return BTOperations.match(tree, key, parser.getKeyDimension(key
271: .getClass()));
272:
273: }
274:
275: public Map getAllValuesForTree(BTree tree, ClassIntrospector parser)
276: throws JoftiException {
277:
278: return BTOperations.getSubTreeKeyValues(tree, null, null,
279: Integer.MIN_VALUE, Integer.MAX_VALUE - 1, true);
280:
281: }
282:
283: }
|