Java tutorial
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.calrissian.accumulorecipes.commons.iterators.support; import static org.calrissian.accumulorecipes.commons.support.Constants.NULL_BYTE; import java.io.IOException; import java.util.Collection; import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreeNode; import org.apache.accumulo.core.data.ByteSequence; import org.apache.accumulo.core.data.Key; import org.apache.accumulo.core.data.Range; import org.apache.accumulo.core.iterators.SortedKeyValueIterator; import org.apache.commons.jexl2.parser.ParserTreeConstants; import org.apache.hadoop.io.Text; import org.apache.log4j.Logger; import org.calrissian.accumulorecipes.commons.iterators.AndIterator; import org.calrissian.accumulorecipes.commons.iterators.FieldIndexIterator; import org.calrissian.accumulorecipes.commons.iterators.OrIterator; /** * * */ public class BooleanLogicTreeNode extends DefaultMutableTreeNode { protected static final Logger log = Logger.getLogger(BooleanLogicTreeNode.class); private static final long serialVersionUID = 1L; private Key myTopKey = null; private Key advanceKey = null; private Text fValue = null; private Text fName = null; private boolean negated = false; private int type; private boolean done = false; private boolean valid = false; private boolean rollUp = false; private String fOperator = null; private boolean childrenAllNegated = false; private HashSet<Key> uids; private Text upperBound; private Text lowerBound; private boolean rangeNode; public BooleanLogicTreeNode(int type) { super(); this.type = type; uids = new HashSet<Key>(); setOperator(); } public BooleanLogicTreeNode(int type, String fieldName, String fieldValue) { super(); this.type = type; if (fieldValue != null) { this.fValue = new Text(fieldValue); } if (fieldName != null) { this.fName = new Text(NodeToJexl.revertToOriginalkey(fieldName)); } uids = new HashSet<Key>(); setOperator(); } public BooleanLogicTreeNode(int type, String fieldName, String fieldValue, boolean negated) { super(); this.type = type; if (fieldValue != null) { this.fValue = new Text(fieldValue); } if (fieldName != null) { this.fName = new Text(NodeToJexl.revertToOriginalkey(fieldName)); } uids = new HashSet<Key>(); this.negated = negated; setOperator(); } public static Key buildKey(Key key) { if (key == null) { log.error("Problem in BooleanLogicTreeNodeJexl.buildKey"); return null; } // Build Key(Text row, Text colfam) where colFam is dataype\0uid String[] cq = key.getColumnQualifier().toString().split(NULL_BYTE); Text uuid = new Text(cq.length > 1 ? cq[1] : cq[0]); Text row = key.getRow(); log.debug("Key-> r:" + row + " fam:" + uuid); Key k = new Key(row, uuid); return k; } public boolean isValid() { return this.valid; } public void setValid(boolean b) { this.valid = b; } public int getType() { return this.type; } public void setType(int t) { this.type = t; } public boolean isChildrenAllNegated() { return childrenAllNegated; } public void setChildrenAllNegated(boolean childrenAllNegated) { this.childrenAllNegated = childrenAllNegated; } public Key getAdvanceKey() { return advanceKey; } public void setAdvanceKey(Key advanceKey) { this.advanceKey = advanceKey; } public boolean isNegated() { return negated; } public Key getTopKey() { return myTopKey; } public void setTopKey(Key id) { this.myTopKey = id; } public boolean isDone() { return done; } public void setDone(boolean done) { this.done = done; } public void setRollUp(boolean rollUp) { this.rollUp = rollUp; } public Text getFieldValue() { return fValue; } public void setFieldValue(Text term) { this.fValue = term; } public Text getFieldName() { return fName; } public void setFieldName(Text dataLocation) { this.fName = dataLocation; } public String getFieldOperator() { return fOperator; } private void setOperator() { this.fOperator = JexlOperatorConstants.getOperator(type); if (negated && this.fOperator.equals("!=")) { this.fOperator = JexlOperatorConstants.getOperator(JexlOperatorConstants.JJTEQNODE); } } public Text getLowerBound() { return lowerBound; } public void setLowerBound(Text lowerBound) { this.lowerBound = lowerBound; } public Text getUpperBound() { return upperBound; } public void setUpperBound(Text upperBound) { this.upperBound = upperBound; } public boolean isRangeNode() { return rangeNode; } public void setRangeNode(boolean rangeNode) { this.rangeNode = rangeNode; } public String getContents() { StringBuilder s = new StringBuilder("["); s.append(toString()); if (children != null) { Enumeration<?> e = this.children(); while (e.hasMoreElements()) { BooleanLogicTreeNode n = (BooleanLogicTreeNode) e.nextElement(); s.append(","); s.append(n.getContents()); } } s.append("]"); return s.toString(); } public String printNode() { StringBuilder s = new StringBuilder("["); s.append("Full Location & Term = "); if (this.fName != null) { s.append(this.fName.toString()); } else { s.append("BlankDataLocation"); } s.append(" "); if (this.fValue != null) { s.append(this.fValue.toString()); } else { s.append("BlankTerm"); } s.append("]"); return s.toString(); } @Override public String toString() { String uidStr = "none"; if (myTopKey != null) { String cf = myTopKey.getColumnFamily().toString(); uidStr = cf; } switch (type) { case ParserTreeConstants.JJTEQNODE: return fName.toString() + ":" + fValue.toString() + ", uid=" + uidStr + " , negation=" + this.isNegated(); case ParserTreeConstants.JJTNENODE: return fName.toString() + ":" + fValue.toString() + ", uid=" + uidStr + " , negation=" + this.isNegated(); case ParserTreeConstants.JJTERNODE: return fName.toString() + ":" + fValue.toString() + ", uid=" + uidStr + " , negation=" + this.isNegated(); case ParserTreeConstants.JJTNRNODE: return fName.toString() + ":" + fValue.toString() + ", uid=" + uidStr + " , negation=" + this.isNegated(); case ParserTreeConstants.JJTLENODE: return "<=:" + fName.toString() + ":" + fValue.toString() + ", uid=" + uidStr + " , negation=" + this.isNegated(); case ParserTreeConstants.JJTLTNODE: return "<:" + fName.toString() + ":" + fValue.toString() + ", uid=" + uidStr + " , negation=" + this.isNegated(); case ParserTreeConstants.JJTGENODE: return ">=:" + fName.toString() + ":" + fValue.toString() + ", uid=" + uidStr + " , negation=" + this.isNegated(); case ParserTreeConstants.JJTGTNODE: return ">:" + fName.toString() + ":" + fValue.toString() + ", uid=" + uidStr + " , negation=" + this.isNegated(); case ParserTreeConstants.JJTJEXLSCRIPT: return "HEAD" + ":" + uidStr + ":" + isValid(); case ParserTreeConstants.JJTANDNODE: return "AND" + ":" + uidStr + ":" + isValid(); case ParserTreeConstants.JJTNOTNODE: return "NOT"; case ParserTreeConstants.JJTORNODE: return "OR" + ":" + uidStr + ":" + isValid(); default: System.out.println("Problem in BLTNODE.toString()"); return null; } } public void seek(Range range, Collection<ByteSequence> columnFamilies, boolean inclusive) throws IOException { // always start fresh this.setTopKey(null); this.setDone(false); // get my user object which should be an iterator SortedKeyValueIterator<?, ?> iter = (SortedKeyValueIterator<?, ?>) this.getUserObject(); if (iter != null) { iter.seek(range, columnFamilies, inclusive); if (iter.hasTop()) { Key key = (Key) iter.getTopKey(); key = buildKey(key); this.setTopKey(key); if (log.isDebugEnabled()) { log.debug("BLTNODE.seek() -> found: " + this.getTopKey()); } } else { if (log.isDebugEnabled()) { log.debug("BLTNODE.seek() -> hasTop::false"); } this.setDone(true); } } else { if (log.isDebugEnabled()) { log.debug("BLTNODE.seek(), The iterator was null!"); } this.setTopKey(null); } } public String buildTreePathString(TreeNode[] path) { StringBuilder s = new StringBuilder("["); for (TreeNode p : path) { s.append(p.toString()); s.append(","); } s.deleteCharAt(s.length() - 1); s.append("]"); return s.toString(); } public void next() throws IOException { // always start fresh this.setTopKey(null); if (log.isDebugEnabled()) { TreeNode[] path = this.getPath(); log.debug("BLTNODE.next() path-> " + this.buildTreePathString(path)); } // have I been marked as done? if (this.isDone()) { if (log.isDebugEnabled()) { log.debug("I've been marked as done, returning"); } return; } SortedKeyValueIterator<?, ?> iter = (SortedKeyValueIterator<?, ?>) this.getUserObject(); iter.next(); if (iter.hasTop()) { Key key = (Key) iter.getTopKey(); // I have a valid topKey, pull out the piece I want key = buildKey(key); this.setTopKey(key); if (log.isDebugEnabled()) { log.debug("BLTNODE.next() -> found: " + this.getTopKey()); } } else { // no top value has been returned, I'm done. if (log.isDebugEnabled()) { log.debug("BLTNODE.next() -> Nothing found"); } this.setTopKey(null); this.setDone(true); } } public boolean jump(Key jumpKey) throws IOException { boolean ok = true; if (this.getType() == ParserTreeConstants.JJTEQNODE) { FieldIndexIterator iter = (FieldIndexIterator) this.getUserObject(); ok = iter.jump(jumpKey); if (iter.hasTop()) { Key key = (Key) iter.getTopKey(); key = buildKey(key); this.setTopKey(key); if (log.isDebugEnabled()) { log.debug("BLTNODE.jump() -> found: " + this.getTopKey()); } } else { if (log.isDebugEnabled()) { log.debug("FieldIndexIteratorJexl does not have top after jump, marking done."); } this.setTopKey(null); this.setDone(true); } } else if (this.getType() == ParserTreeConstants.JJTANDNODE) { AndIterator iter = (AndIterator) this.getUserObject(); ok = iter.jump(jumpKey); if (iter.hasTop()) { Key key = iter.getTopKey(); key = buildKey(key); this.setTopKey(key); if (log.isDebugEnabled()) { log.debug("BLTNODE.jump() -> found: " + this.getTopKey()); } } else { if (log.isDebugEnabled()) { log.debug("IntersectingIteratorJexl does not have top after jump, marking done."); } this.setTopKey(null); this.setDone(true); } } else if (this.getType() == ParserTreeConstants.JJTORNODE) { OrIterator iter = (OrIterator) this.getUserObject(); ok = iter.jump(jumpKey); if (iter.hasTop()) { Key key = (Key) iter.getTopKey(); key = buildKey(key); this.setTopKey(key); if (log.isDebugEnabled()) { log.debug("BLTNODE.jump() -> found: " + this.getTopKey()); } } else { if (log.isDebugEnabled()) { log.debug("OrIteratorJexl does not have top after jump, marking done."); } this.setTopKey(null); this.setDone(true); } } return ok; } public void addToSet(Key i) { uids.add(i); } public void reSet() { uids = new HashSet<Key>(); } public Iterator<Key> getSetIterator() { return uids.iterator(); } public HashSet<Key> getIntersection(HashSet<Key> h) { h.retainAll(uids); return h; } public Key getMinUniqueID() { Iterator<Key> iter = uids.iterator(); Key min = null; while (iter.hasNext()) { Key t = (Key) iter.next(); if (log.isDebugEnabled()) { log.debug("OR set member: " + t); } if (t != null) { if (min == null) { min = t; } else if (t.compareTo(min) < 0) { min = t; } } } return min; } public boolean hasTop() { // This part really needs to be cleaned up. // It was created before I knew what was being passed back. if (this.getType() == ParserTreeConstants.JJTORNODE) { // Are you a Logical OR or an OR Iterator if (!this.isLeaf()) { // logical construct // I have a set of keys return this.uids.size() > 0; } else { // or iterator, you only have possible key if (this.getTopKey() == null) { return false; } else { return true; } } } else { return this.getTopKey() != null; } } }