001/**
002 *
003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved.
004 *
005 * This library is free software; you can redistribute it and/or
006 * modify it under the terms of the GNU Lesser General Public
007 * License as published by the Free Software Foundation; either 
008 * version 2.1 of the License, or (at your option) any later version.
009 * 
010 * This library is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013 * Lesser General Public License for more details.
014 * 
015 * You should have received a copy of the GNU Lesser General Public 
016 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
017 * 
018 **/
019
020package lucee.runtime.sql.old;
021
022import java.util.Vector;
023
024// Referenced classes of package Zql:
025//            ZExp, ZQuery, ZConstant, ZUtils
026
027public final class ZExpression
028    implements ZExp
029{
030
031    public ZExpression(String s)
032    {
033        op_ = null;
034        operands_ = null;
035        op_ = new String(s);
036    }
037
038    public ZExpression(String s, ZExp zexp)
039    {
040        op_ = null;
041        operands_ = null;
042        op_ = new String(s);
043        addOperand(zexp);
044    }
045
046    public ZExpression(String s, ZExp zexp, ZExp zexp1)
047    {
048        op_ = null;
049        operands_ = null;
050        op_ = new String(s);
051        addOperand(zexp);
052        addOperand(zexp1);
053    }
054
055    public String getOperator()
056    {
057        return op_;
058    }
059
060    public void setOperands(Vector vector)
061    {
062        operands_ = vector;
063    }
064
065    public Vector getOperands()
066    {
067        return operands_;
068    }
069
070    public void addOperand(ZExp zexp)
071    {
072        if(operands_ == null)
073            operands_ = new Vector();
074        operands_.addElement(zexp);
075    }
076
077    public ZExp getOperand(int i)
078    {
079        if(operands_ == null || i >= operands_.size())
080            return null;
081        return (ZExp)operands_.elementAt(i);
082    }
083
084    public int nbOperands()
085    {
086        if(operands_ == null)
087            return 0;
088        return operands_.size();
089    }
090
091    public String toReversePolish()
092    {
093        StringBuffer stringbuffer = new StringBuffer("(");
094        stringbuffer.append(op_);
095        for(int i = 0; i < nbOperands(); i++)
096        {
097            ZExp zexp = getOperand(i);
098            if(zexp instanceof ZExpression)
099                stringbuffer.append(" " + ((ZExpression)zexp).toReversePolish());
100            else
101            if(zexp instanceof ZQuery)
102                stringbuffer.append(" (" + zexp.toString() + ")");
103            else
104                stringbuffer.append(" " + zexp.toString());
105        }
106
107        stringbuffer.append(")");
108        return stringbuffer.toString();
109    }
110
111    public String toString()
112    {
113        if(op_.equals("?"))
114            return op_;
115        if(ZUtils.isCustomFunction(op_) > 0)
116            return formatFunction();
117        StringBuffer stringbuffer = new StringBuffer();
118        if(needPar(op_))
119            stringbuffer.append("(");
120        switch(nbOperands())
121        {
122        case 1: // '\001'
123            ZExp zexp = getOperand(0);
124            if(zexp instanceof ZConstant)
125            {
126                if(ZUtils.isAggregate(op_))
127                    stringbuffer.append(op_ + "(" + zexp.toString() + ")");
128                else
129                    stringbuffer.append(op_ + " " + zexp.toString());
130            } else
131            if(zexp instanceof ZQuery)
132                stringbuffer.append(op_ + " (" + zexp.toString() + ")");
133            else
134                stringbuffer.append(op_ + " " + zexp.toString());
135            break;
136
137        case 3: // '\003'
138            if(op_.toUpperCase().endsWith("BETWEEN"))
139            {
140                stringbuffer.append(getOperand(0).toString() + " " + op_ + " " + getOperand(1).toString() + " AND " + getOperand(2).toString());
141                break;
142            }
143            // fall through
144
145        default:
146            boolean flag = op_.equals("IN") || op_.equals("NOT IN");
147            int i = nbOperands();
148            for(int j = 0; j < i; j++)
149            {
150                if(flag && j == 1)
151                    stringbuffer.append(" " + op_ + " (");
152                ZExp zexp1 = getOperand(j);
153                if((zexp1 instanceof ZQuery) && !flag)
154                    stringbuffer.append("(" + zexp1.toString() + ")");
155                else
156                    stringbuffer.append(zexp1.toString());
157                if(j < i - 1)
158                    if(op_.equals(",") || flag && j > 0)
159                        stringbuffer.append(", ");
160                    else
161                    if(!flag)
162                        stringbuffer.append(" " + op_ + " ");
163            }
164
165            if(flag)
166                stringbuffer.append(")");
167            break;
168        }
169        if(needPar(op_))
170            stringbuffer.append(")");
171        return stringbuffer.toString();
172    }
173
174    private boolean needPar(String s)
175    {
176        s = s.toUpperCase();
177        return !s.equals("ANY") && !s.equals("ALL") && !s.equals("UNION") && !ZUtils.isAggregate(s);
178    }
179
180    private String formatFunction()
181    {
182        StringBuffer stringbuffer = new StringBuffer(op_ + "(");
183        int i = nbOperands();
184        for(int j = 0; j < i; j++)
185            stringbuffer.append(getOperand(j).toString() + (j >= i - 1 ? "" : ","));
186
187        stringbuffer.append(")");
188        return stringbuffer.toString();
189    }
190
191    String op_;
192    Vector operands_;
193}