/* * 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.teiid.query.sql.lang; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import org.teiid.client.metadata.ParameterInfo; import org.teiid.core.util.EquivalenceUtil; import org.teiid.query.QueryPlugin; import org.teiid.query.sql.symbol.ElementSymbol; import org.teiid.query.sql.symbol.Expression; /** * Represents a StoredProcedure's parameter for encapsulation in the Query framework * This is basically a holder object set from the Server's implementation of * a stored procedure. * The connector will utilize this class to set the appropriate values at the * datasource layer. */ public class SPParameter implements Cloneable { /** Constant identifying an IN parameter */ public static final int IN = ParameterInfo.IN; /** Constant identifying an OUT parameter */ public static final int OUT = ParameterInfo.OUT; /** Constant identifying an INOUT parameter */ public static final int INOUT = ParameterInfo.INOUT; /** Constant identifying a RETURN parameter */ public static final int RETURN_VALUE = ParameterInfo.RETURN_VALUE; /** Constant identifying a RESULT SET parameter */ public static final int RESULT_SET = ParameterInfo.RESULT_SET; // Basic state private int parameterType = ParameterInfo.IN; private Expression expression; private int index; private List<ElementSymbol> resultSetColumns; //contains List of columns if it is result set private List<Object> resultSetIDs; // contains List of metadataIDs for each column in the result set private boolean usingDefault; private boolean varArg; private ElementSymbol parameterSymbol; /** * Constructor used when constructing a parameter during execution. In this case we * know what the parameter is being filled with but no metadata about the parameter. * * @param index the positional index of this parameter * @param value the Value of this parameter */ public SPParameter(int index, Expression expression){ setIndex(index); setExpression(expression); this.parameterSymbol = new ElementSymbol(""); //$NON-NLS-1$ } /** * Constructor used when constructing a parameter from metadata. * In this case we specify the description of the parameter but * no notion of what it is being filled with. * * @param index Parameter index * @param parameterType Type of parameter based on class constant - IN, OUT, etc * @param name Full name of parameter (including proc name) */ public SPParameter(int index, int parameterType, String name) { setIndex(index); setParameterType(parameterType); this.parameterSymbol = new ElementSymbol(name); } private SPParameter() { } /** * Get full parameter name,. If unknown, null is returned. * @return Parameter name */ public String getName() { return this.parameterSymbol.getName(); } /** * Set full parameter name * @param name Parameter name */ public void setName(String name) { ElementSymbol es = new ElementSymbol(name); es.setMetadataID(parameterSymbol.getMetadataID()); es.setType(parameterSymbol.getType()); this.parameterSymbol = es; } /** * Set parameter type according to class constants. * @param parameterType Type to set * @see ParameterInfo#IN * @see ParameterInfo#OUT * @see ParameterInfo#INOUT * @see ParameterInfo#RESULT_SET * @see ParameterInfo#RETURN_VALUE */ public void setParameterType(int parameterType){ // validate against above types if(parameterType < ParameterInfo.IN || parameterType > ParameterInfo.RESULT_SET) { throw new IllegalArgumentException(QueryPlugin.Util.getString("ERR.015.010.0006", parameterType)); //$NON-NLS-1$ } this.parameterType = parameterType; } /** * Get type of parameter according to class constants. * @return Parameter type * @see ParameterInfo#IN * @see ParameterInfo#OUT * @see ParameterInfo#INOUT * @see ParameterInfo#RESULT_SET * @see ParameterInfo#RETURN_VALUE */ public int getParameterType(){ return this.parameterType; } /** * Set class type - MetaMatrix runtime types. * @param classType See {@link org.teiid.core.types.DataTypeManager.DefaultDataClasses} * for types */ public void setClassType(Class<?> classType){ this.parameterSymbol.setType(classType); } /** * Get class type - MetaMatrix runtime types. * @return MetaMatrix runtime type description */ public Class<?> getClassType(){ return this.parameterSymbol.getType(); } /** * Set the expression defining this parameter * @param expression The expression defining this parameter's value */ public void setExpression(Expression expression){ this.expression = expression; } /** * Return the expression defining the value of this parameter * @return Expression defining the value of this parameter */ public Expression getExpression(){ return this.expression; } /** * Set the positional index of this parameter * @param index The positional index of this parameter */ public void setIndex(int index){ this.index = index; } /** * Return the index of this parameter * @return The index */ public int getIndex(){ return this.index; } /** * Add a result set column if this parameter is a return * result set. * @param colName Name of column * @param type Type of column */ public void addResultSetColumn(String colName, Class<?> type, Object id) { if(resultSetColumns == null){ resultSetColumns = new ArrayList<ElementSymbol>(); resultSetIDs = new ArrayList<Object>(); } ElementSymbol rsColumn = new ElementSymbol(colName); rsColumn.setType(type); rsColumn.setMetadataID(id); resultSetColumns.add(rsColumn); resultSetIDs.add(id); } /** * Get the result set columns. If none exist, return empty list. * @return List of ElementSymbol representing result set columns */ public List<ElementSymbol> getResultSetColumns(){ if(resultSetColumns == null){ return Collections.emptyList(); } return resultSetColumns; } /** * Get the result set metadata IDs. If none exist, return empty list. * @return List of Object representing result set metadata IDs */ public List<Object> getResultSetIDs() { if(resultSetIDs == null) { return Collections.emptyList(); } return this.resultSetIDs; } /** * Get a particular result set column at the specified position. * @param position Position of the result set column * @return Element symbol representing the result set column at position * @throws IllegalArgumentException If column doesn't exist */ public ElementSymbol getResultSetColumn(int position){ if(resultSetColumns == null){ throw new IllegalArgumentException(QueryPlugin.Util.getString("ERR.015.010.0009")); //$NON-NLS-1$ } //position is 1 based position--; if(position >= 0 && position < resultSetColumns.size()) { return resultSetColumns.get(position); } throw new IllegalArgumentException(QueryPlugin.Util.getString("ERR.015.010.0010", new Integer(position + 1))); //$NON-NLS-1$ } /** * Get actual metadataID for this parameter * @return Actual metadata ID for this parameter */ public Object getMetadataID() { return this.parameterSymbol.getMetadataID(); } /** * Set actual metadataID for this parameter * @param metadataID Actual metadataID */ public void setMetadataID(Object metadataID) { this.parameterSymbol.setMetadataID(metadataID); } /** * Get element symbol representing this parameter. The symbol will have the * same name and type as the parameter. * @return Element symbol representing the parameter */ public ElementSymbol getParameterSymbol() { return parameterSymbol; } /** * Checks whether another parameter equals this one based on the index. * @see java.lang.Object#equals(Object) */ public boolean equals(Object obj) { if(obj == this) { return true; } if(!(obj instanceof SPParameter)){ return false; } //the parameters are considered equal if the indexes are the same SPParameter other = (SPParameter) obj; if (this.getIndex() != other.getIndex()) { return false; } // If indexes match, check associated IDs if existent return EquivalenceUtil.areEqual(this.expression, other.expression); } /** * @see java.lang.Object#hashCode() */ public int hashCode() { return this.index; } /** * @see java.lang.Object#clone() */ public Object clone() { SPParameter copy = new SPParameter(); copy.index = this.index; copy.parameterType = this.parameterType; copy.parameterSymbol = this.parameterSymbol.clone(); if(this.expression != null) { copy.setExpression((Expression)this.expression.clone()); } if(this.resultSetColumns != null) { Iterator<ElementSymbol> iter = this.resultSetColumns.iterator(); Iterator<Object> idIter = this.resultSetIDs.iterator(); while(iter.hasNext()) { ElementSymbol column = iter.next(); copy.addResultSetColumn(column.getName(), column.getType(), idIter.next()); } } copy.setUsingDefault(this.usingDefault); copy.varArg = this.varArg; return copy; } /** * @see java.lang.Object#toString() */ public String toString() { if(this.expression != null) { return this.expression.toString(); } return "?"; //$NON-NLS-1$ } public boolean isUsingDefault() { return usingDefault; } public void setUsingDefault(boolean usingDefault) { this.usingDefault = usingDefault; } public void setVarArg(boolean varArg) { this.varArg = varArg; } public boolean isVarArg() { return varArg; } }