/* * JBoss, Home of Professional Open Source. * See the COPYRIGHT.txt file distributed with this work for information * regarding copyright ownership. Some portions may be licensed * to Red Hat, Inc. under one or more contributor license agreements. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA. */ package org.jboss.bqt.jdbc.sql.lang; import java.util.*; import org.jboss.bqt.core.util.EquivalenceUtil; import org.jboss.bqt.core.util.HashCodeUtil; /** * This class represents the SELECT clause of a query, which defines what elements * or expressions are returned from the query. */ public class Select { /** The set of symbols for the data elements to be selected. */ private List<SelectSymbol> symbols; // List<SelectSymbols> /** Flag for whether duplicate removal should be performed on the results */ private boolean distinct; // ========================================================================= // C O N S T R U C T O R S // ========================================================================= /** * Constructs a default instance of this class. */ public Select() { symbols = new ArrayList<SelectSymbol>(); } /** * Constructs an instance of this class from an ordered set of symbols. * @param symbols The ordered list of symbols */ public Select( List<SelectSymbol> symbols ) { this.symbols = new ArrayList<SelectSymbol>( symbols ); } // ========================================================================= // M E T H O D S // ========================================================================= /** * Returns the number of symbols in select. * @return Get count of number of symbols in select */ public int getCount() { return symbols.size(); } /** * Checks for a Select * clause * @return True if Select * is used */ public boolean isStar() { return (symbols.size() == 1 && symbols.get(0) instanceof AllSymbol); } /** * Returns an ordered list of the symbols in the select. * @return List of SelectSymbols */ public List<SelectSymbol> getSymbols() { return symbols; } /** * Sets an ordered list of the symbols in the select. * @param symbols list of SelectSymbol in SELECT */ public void setSymbols(List<SelectSymbol> symbols) { this.symbols = symbols; } /** * Returns the select symbol at the specified index. * @param index Index to get * @return The variable identifier at the index */ public SelectSymbol getSymbol( int index ) { return (SelectSymbol) symbols.get(index); } /** * Adds a new symbol to the list of symbols. * @param symbol New symbol */ public void addSymbol( SelectSymbol symbol ) { if(symbol != null) { symbols.add(symbol); } } /** * Adds a new collection of symbols to the list of symbols. * @param symbols Collection of SelectSymbols */ public void addSymbols( Collection<SelectSymbol> symbols) { if(symbols != null) { this.symbols.addAll(symbols); } } /** * Remove all current symbols */ public void clearSymbols() { symbols.clear(); } /** * Checks if a symbol is in the Select. * @param symbol Symbol to check for * @return True if the Select contains the symbol */ public boolean containsSymbol( SelectSymbol symbol ) { return symbols.contains(symbol); } /** * Check is the element symbol is being selected by this * select clause. This includes checking for select start * and select group.star for the group of this element symbol. * ElementSymbol is assumed to be fully resolved. * @param elementSymbol fully resolved ElementSymbol * @return whether this select will select the element symbol */ // public boolean isElementBeingSelected(ElementSymbol elementSymbol){ // boolean isBeingSelected = this.containsSymbol(elementSymbol); // if (!isBeingSelected){ // GroupSymbol g = elementSymbol.getGroupSymbol(); // String groupDotStarName = g.getName() + ".*"; //$NON-NLS-1$ // Iterator i = this.getSymbols().iterator(); // while (i.hasNext()) { // Object selectSymbol = i.next(); // if (selectSymbol instanceof AllSymbol){ // isBeingSelected = true; // break; // } else if (selectSymbol instanceof AllInGroupSymbol){ // AllInGroupSymbol aigSymbol = (AllInGroupSymbol)selectSymbol; // if (aigSymbol.getName().equalsIgnoreCase(groupDotStarName)){ // isBeingSelected = true; // break; // } // } // } // } // return isBeingSelected; // } /** * Set whether select is distinct. * @param isDistinct True if SELECT is distinct */ public void setDistinct(boolean isDistinct) { this.distinct = isDistinct; } /** * Checks whether the select is distinct * @return True if select is distinct */ public boolean isDistinct() { return this.distinct; } // public void acceptVisitor(LanguageVisitor visitor) { // visitor.visit(this); // } /** * Get the ordered list of all elements returned by this select. These elements * may be ElementSymbols or ExpressionSymbols but in all cases each represents a * single column. * @return Ordered list of SingleElementSymbol */ // public List getProjectedSymbols() { // ArrayList projectedSymbols = new ArrayList(); // Iterator iter = symbols.iterator(); // while(iter.hasNext()) { // SelectSymbol symbol = (SelectSymbol) iter.next(); // if(symbol instanceof SingleElementSymbol) { // projectedSymbols.add(symbol); // } else { // List multiSymbols = ((MultipleElementSymbol)symbol).getElementSymbols(); // if(multiSymbols != null) { // projectedSymbols.addAll(multiSymbols); // } // } // } // return projectedSymbols; // } // ========================================================================= // O V E R R I D D E N O B J E C T M E T H O D S // ========================================================================= /** * Return a deep copy of this Select. * @return Deep clone */ public Object clone() { List thisSymbols = getSymbols(); List copySymbols = new ArrayList(thisSymbols.size()); Iterator iter = thisSymbols.iterator(); while(iter.hasNext()) { SelectSymbol ss = (SelectSymbol) iter.next(); copySymbols.add(ss.clone()); } Select copy = new Select(copySymbols); copy.setDistinct( isDistinct() ); return copy; } /** * Compare two Selects for equality. Order is important in the select (for * determining the order of the returned columns), so this is a compare * with order, not just a set comparison. * @param obj Other object * @return True if equal */ public boolean equals(Object obj) { if(obj == this) { return true; } if(!(obj instanceof Select)) { return false; } Select other = (Select) obj; return other.isDistinct() == isDistinct() && EquivalenceUtil.areEqual(getSymbols(), other.getSymbols()); } /** * Get hashcode for Select. WARNING: The hash code relies on the variables * in the select, so changing the variables will change the hash code, causing * a select to be lost in a hash structure. Do not hash a Select if you plan * to change it. * @return Hash code */ public int hashCode() { return HashCodeUtil.hashCode(0, getSymbols()); } /** * Returns a string representation of an instance of this class. * @return String representation of object */ public String toString() { return "Select.toString() not implemented"; // return SQLStringVisitor.getSQLString(this); } } // END CLASS