001package gudusoft.gsqlparser.nodes;
002
003
004import gudusoft.gsqlparser.ESqlClause;
005import gudusoft.gsqlparser.TCustomSqlStatement;
006import gudusoft.gsqlparser.TSourceToken;
007
008import java.util.ArrayList;
009import java.util.Iterator;
010import java.util.Vector;
011
012/**
013 * List of parse tree node.
014 */
015public class TParseTreeNodeList<T extends TParseTreeNode> extends TParseTreeNode implements Iterable<T> {
016
017    public void addAll(TParseTreeNodeList sourceList){
018        v.addAll(sourceList.v);
019        modCount++;
020    }
021    public void clear(){
022        v.clear();
023        modCount++;
024    }
025    public void setListSeparatedByComma(boolean listSeparatedByComma) {
026        this.listSeparatedByComma = listSeparatedByComma;
027    }
028
029    public boolean isListSeparatedByComma() {
030        return listSeparatedByComma;
031    }
032
033    private boolean listSeparatedByComma = true;
034
035    @Override
036    public Iterator<T> iterator() {
037        return new TParseTreeNodeList.NodeSetIterator();
038    }
039
040    private class NodeSetIterator implements Iterator {
041        private int currentIndex = 0;
042
043        @Override
044        public boolean hasNext() {
045           return (currentIndex < size())&&(size()>0);
046        }
047
048        @Override
049        public T next() {
050            return elementAt(currentIndex++);
051        }
052
053        @Override
054        public void remove() {
055            throw new UnsupportedOperationException();
056        }
057    }
058
059
060    public void TParseTreeNodeList(){
061    }
062
063
064    protected int modCount = 0;
065
066    private ArrayList<T> v = new ArrayList();
067
068    public final int size()
069    {
070        return v.size();
071    }
072
073    public T elementAt(int index)
074    {
075        return  v.get(index);
076    }
077
078    public final void addElement(T ptn)
079    {
080
081        TParseTreeNode node = (TParseTreeNode)ptn;
082        if ((node!=null)&&(!node.isTokensInChain())){
083            if (this.size()>0){
084                getElement(this.size()-1).appendNewNode(node,true);
085            }else{
086
087            }
088        }
089
090        v.add(ptn);
091        modCount++;
092    }
093
094    public final void removeElementWithoutSyncTokens(int index)
095    {
096         v.remove(index);
097         modCount++;
098    }
099
100    public final void removeElementAt(int index)
101    {
102       this.removeItem(index);
103    }
104
105    public final boolean removeElement(TParseTreeNode ptn)
106    {
107        boolean removed = v.remove(ptn);
108        if (removed) modCount++;
109        return removed;
110    }
111
112    final TParseTreeNode removeAndSyncTokens(int index)
113    {
114        if(TParseTreeNode.doubleLinkedTokenListToString){
115            TParseTreeNode node = (TParseTreeNode) getElement(index);
116            if (node.getNodeStatus() != ENodeStatus.nsRemoved){
117                node.removeTokens();
118            }
119            v.remove(index);
120            modCount++;
121            // remove unnecessary comma if any
122            if (this.size() != 0){
123                TSourceToken lcPrevToken = null;
124                if (this.getStartToken()!=null){
125                    lcPrevToken = this.getStartToken().getPrevTokenInChain();
126                }
127                while (lcPrevToken != null){
128                    if (lcPrevToken.tokencode == ','){
129                        lcPrevToken.removeFromChain();
130                        break;
131                    }
132                    if (lcPrevToken.issolidtoken()){
133                        break;
134                    }
135                    lcPrevToken = lcPrevToken.getPrevTokenInChain();
136                }
137
138                TSourceToken lcNextToken = null;
139                if (this.getEndToken() != null){
140                    lcNextToken = this.getEndToken().getNextTokenInChain();
141                }
142                while (lcNextToken != null){
143                    if (lcNextToken.tokencode == ','){
144                        lcNextToken.updateNodeEndWithThisToken();
145                        lcNextToken.removeFromChain();
146                        break;
147                    }
148                    if (lcNextToken.issolidtoken()){
149                        break;
150                    }
151                    lcNextToken = lcNextToken.getNextTokenInChain();
152                }
153                lcNextToken = null;
154                if (this.getStartToken() != null){
155                    lcNextToken = this.getStartToken().getNextTokenInChain();
156                }
157                boolean foundComma = false;
158                while (lcNextToken != null){
159                    if (lcNextToken.tokencode == ','){
160                        if (foundComma){
161                            lcNextToken.removeFromChain();
162                            break;
163                        }else{
164                            foundComma = true;
165                        }
166                    }else if (lcNextToken.issolidtoken()){
167                        foundComma = false;
168                    }
169                    lcNextToken = lcNextToken.getNextTokenInChain();
170                    if (lcNextToken == this.getEndToken()) break;
171                }
172
173            }
174
175            return node;
176
177//            if (index == 0){
178//                // first element
179//                if (size() > 1){
180//                    TSourceToken st = node.getEndToken().searchToken(",",1);
181//                    if (st != null){
182//                        st.removeFromChain();
183//                    }
184//                }
185//            }else{
186//                // second or later token
187//                TSourceToken st = node.getStartToken().searchToken(",",-1);
188//                if (st != null){
189//                    st.removeFromChain();
190//                }
191//            }
192        }else {
193            modCount++;
194            return((TParseTreeNode) (v.remove(index)));
195        }
196
197    }
198
199    public final int indexOf(TParseTreeNode ptn)
200    {
201        return v.indexOf(ptn);
202    }
203
204    final void setElementAt(T ptn, int index)
205    {
206        v.set(index,ptn);
207        modCount++;
208    }
209
210
211    public final void insertElementAt(T ptn, int index)
212    {
213        TParseTreeNode node = (TParseTreeNode)ptn;
214        if (!node.isTokensInChain()){
215            if ((this.size()>0)&&(index < this.size())){
216                getElement(index).insertNewNodeBeforeMe(node,true);
217            }else{
218
219            }
220        }
221
222        v.add(index,ptn);
223        modCount++;
224    }
225
226    public void init(Object arg1)
227    {
228        addParseTreeNode(arg1);
229    }
230
231    public void init(Object arg1,Object arg2)
232    {
233        addParseTreeNode(arg1);
234        addParseTreeNode(arg2);
235    }
236
237    public void init(Object arg1,Object arg2,Object arg3)
238    {
239        addParseTreeNode(arg1);
240        addParseTreeNode(arg2);
241        addParseTreeNode(arg3);
242    }
243
244    public void init(Object arg1,Object arg2,Object arg3,Object arg4)
245    {
246        addParseTreeNode(arg1);
247        addParseTreeNode(arg2);
248        addParseTreeNode(arg3);
249        addParseTreeNode(arg4);
250    }
251
252    void addParseTreeNode(Object arg1){
253        addElement((T)arg1);
254    }
255
256    public void addNode(Object arg1){
257      addParseTreeNode((TParseTreeNode)arg1);  
258    }
259
260
261    public  TParseTreeNode getElement(int index){
262        return elementAt(index);
263    }
264    /**
265     * analyze this node
266     */
267    public void doParse(TCustomSqlStatement psql, ESqlClause plocation){
268     for(int i=0; i<size();i++){
269         if (elementAt(i) != null){
270            elementAt(i).doParse(psql,plocation);
271         }
272     }
273    }
274
275
276    public TSourceToken getStartToken() {
277        if (size() == 0){
278            return null;
279        }else{
280            return elementAt(0).getStartToken();
281        }
282    }
283
284    public TSourceToken getEndToken() {
285        if (size() == 0){
286            return null;
287        }else{
288            return elementAt(size()-1).getEndToken();
289        }
290    }
291
292    public void accept(TParseTreeVisitor v){
293        v.preVisit(this);
294        v.postVisit(this);
295    }
296
297    public void acceptChildren(TParseTreeVisitor v){
298        v.preVisit(this);
299        for(int i=0; i<size();i++){
300            if (elementAt(i) != null){
301                elementAt(i).acceptChildren(v);
302            }
303        }
304        v.postVisit(this);
305    }
306
307    public TParseTreeNode removeItem(int index){
308        return removeAndSyncTokens(index);
309    }
310}