org.calrissian.accumulorecipes.commons.iterators.support.BooleanLogicTreeNode.java Source code

Java tutorial

Introduction

Here is the source code for org.calrissian.accumulorecipes.commons.iterators.support.BooleanLogicTreeNode.java

Source

/*
 * 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;
        }
    }
}