/** * diqube: Distributed Query Base. * * Copyright (C) 2015 Bastian Gloeckle * * This file is part of diqube. * * diqube is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.diqube.diql.request; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.UUID; import org.diqube.util.ColumnOrValue; /** * Represents a restriction that can either be present in a WHERE or in a HAVING clause in a select stmt. * * <p> * Correctly implements {@link Object#equals(Object)} and {@link Object#hashCode()}. * * @author Bastian Gloeckle */ public abstract class ComparisonRequest { public enum Operator { EQ, GT_EQ, GT, LT, LT_EQ } private UUID virtualId = UUID.randomUUID(); public abstract <T extends ComparisonRequest> Collection<T> findRecursivelyAllOfType(Class<T> type); public UUID getVirtualId() { return virtualId; } public static class Leaf extends ComparisonRequest { private Operator op; private String leftColumnName; private ColumnOrValue right; public String getLeftColumnName() { return leftColumnName; } public void setLeftColumnName(String leftColumnName) { this.leftColumnName = leftColumnName; } public Operator getOp() { return op; } public void setOp(Operator op) { this.op = op; } public ColumnOrValue getRight() { return right; } public void setRight(ColumnOrValue right) { this.right = right; } @SuppressWarnings("unchecked") @Override public <T extends ComparisonRequest> Collection<T> findRecursivelyAllOfType(Class<T> type) { Collection<T> res = new ArrayList<T>(); if (type.equals(Leaf.class)) res.add((T) this); return res; } @Override public String toString() { return "[" + getLeftColumnName().toString() + " " + op.toString() + " " + getRight().toString() + "]"; } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + ((leftColumnName == null) ? 0 : leftColumnName.hashCode()); result = prime * result + ((op == null) ? 0 : op.hashCode()); result = prime * result + ((right == null) ? 0 : right.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (!(obj instanceof Leaf)) return false; Leaf other = (Leaf) obj; if (leftColumnName == null) { if (other.leftColumnName != null) return false; } else if (!leftColumnName.equals(other.leftColumnName)) return false; if (op != other.op) return false; if (right == null) { if (other.right != null) return false; } else if (!right.equals(other.right)) return false; return true; } } public abstract static class DelegateComparisonRequest extends ComparisonRequest { private ComparisonRequest left; private ComparisonRequest right; public ComparisonRequest getRight() { return right; } public void setRight(ComparisonRequest right) { this.right = right; } public ComparisonRequest getLeft() { return left; } public void setLeft(ComparisonRequest left) { this.left = left; } @SuppressWarnings("unchecked") @Override public <T extends ComparisonRequest> Collection<T> findRecursivelyAllOfType(Class<T> type) { Collection<T> res = new ArrayList<T>(); res.addAll(getLeft().findRecursivelyAllOfType(type)); res.addAll(getRight().findRecursivelyAllOfType(type)); if (type.equals(this.getClass())) res.add((T) this); return res; } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + ((left == null) ? 0 : left.hashCode()); result = prime * result + ((right == null) ? 0 : right.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (!(obj instanceof DelegateComparisonRequest)) return false; DelegateComparisonRequest other = (DelegateComparisonRequest) obj; if (left == null) { if (other.left != null) return false; } else if (!left.equals(other.left)) return false; if (right == null) { if (other.right != null) return false; } else if (!right.equals(other.right)) return false; return true; } } public static class And extends DelegateComparisonRequest { @Override public String toString() { return "And[" + getLeft().toString() + "," + getRight().toString() + "]"; } } public static class Or extends DelegateComparisonRequest { @Override public String toString() { return "Or[" + getLeft().toString() + "," + getRight().toString() + "]"; } } public static class Not extends ComparisonRequest { private ComparisonRequest child; public ComparisonRequest getChild() { return child; } public void setChild(ComparisonRequest child) { this.child = child; } @SuppressWarnings("unchecked") @Override public <T extends ComparisonRequest> Collection<T> findRecursivelyAllOfType(Class<T> type) { List<T> res = new ArrayList<>(); if (type.equals(Not.class)) res.add((T) this); res.addAll(child.findRecursivelyAllOfType(type)); return res; } @Override public String toString() { return "Not[" + child.toString() + "]"; } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + ((child == null) ? 0 : child.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (!(obj instanceof Not)) return false; Not other = (Not) obj; if (child == null) { if (other.child != null) return false; } else if (!child.equals(other.child)) return false; return true; } } }