Initial import
[jpf-core.git] / src / main / gov / nasa / jpf / util / script / ScriptElementContainer.java
1 /*
2  * Copyright (C) 2014, United States Government, as represented by the
3  * Administrator of the National Aeronautics and Space Administration.
4  * All rights reserved.
5  *
6  * The Java Pathfinder core (jpf-core) platform is licensed under the
7  * Apache License, Version 2.0 (the "License"); you may not use this file except
8  * in compliance with the License. You may obtain a copy of the License at
9  * 
10  *        http://www.apache.org/licenses/LICENSE-2.0. 
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and 
16  * limitations under the License.
17  */
18
19 package gov.nasa.jpf.util.script;
20
21 import java.io.PrintWriter;
22 import java.util.Iterator;
23
24 public abstract class ScriptElementContainer extends ScriptElement implements Iterable <ScriptElement> {
25
26   protected class SECIterator implements Iterator<ScriptElement>, Cloneable {
27
28     SECIterator prev; // to build ad hoc stacks
29     ScriptElement cur;
30
31     SECIterator () {
32       cur = firstChild;
33     }
34
35     @Override
36         public boolean hasNext() {
37       return (cur != null);
38     }
39
40     @Override
41         public ScriptElement next() {
42       if (cur != null) {
43         ScriptElement ret = cur;
44         cur = cur.nextSibling;
45         return ret;
46       } else {
47         return null;
48       }
49     }
50
51     @Override
52         public void remove() {
53       throw new UnsupportedOperationException("no ScriptElement removal supported");
54     }
55
56     public SECIterator getPrev() {
57       return prev;
58     }
59
60     public void setPrev (SECIterator it) {
61       prev = it;
62     }
63
64     @Override
65         public Object clone() {
66       try {
67         // need to deep copy iterators
68         SECIterator it = (SECIterator)super.clone();
69         if (prev != null) {
70           it.prev = (SECIterator) prev.clone();
71         }
72         return it;
73       } catch (CloneNotSupportedException cnsx) {
74         return null; // can't happen, just compiler pleasing
75       }
76     }
77   }
78
79
80   ScriptElement firstChild;
81
82   ScriptElementContainer (ScriptElement parent, int line) {
83     super(parent, line);
84   }
85
86   public ScriptElement getFirstChild () {
87     return firstChild;
88   }
89
90   /**
91    * beware, this sets the nextSibling
92    */
93   public void add (ScriptElement e) {
94     e.nextSibling = null;
95
96     if (firstChild == null) {
97       firstChild = e;
98     } else {
99       ScriptElement p=firstChild;
100       while (p.nextSibling != null) p=p.nextSibling;
101       p.nextSibling = e;
102     }
103   }
104
105   public int getNumberOfChildren() {
106     int n=0;
107     ScriptElement e = firstChild;
108     while (e != null) {
109       n++;
110       e = e.getNextSibling();
111     }
112     return n;
113   }
114
115   @Override
116   public SECIterator iterator () {
117     return new SECIterator();
118   }
119
120   void dump (PrintWriter w, int level, ScriptElement elem) {
121
122     try {
123       while (elem != null) {
124         for (int i=0; i<level; i++) {
125           w.print("  ");
126         }
127         w.print(elem);
128
129         if (elem instanceof ScriptElementContainer) {
130           ScriptElementContainer c = (ScriptElementContainer) elem;
131           w.println(" {");
132           dump(w, level+1, c.getFirstChild());
133           for (int i=0; i<level; i++) {
134             w.print("  ");
135           }
136           w.println("}");
137         } else {
138           w.println();
139         }
140
141         elem = elem.getNextSibling();
142       }
143     }
144     catch (Throwable t) {
145       t.printStackTrace();
146     }
147   }
148
149   protected String toString (String type) {
150     StringBuilder sb = new StringBuilder();
151
152     if (type != null) {
153       sb.append(type);
154       sb.append(' ');
155     }
156
157     sb.append("{");
158     int i=0;
159     for (ScriptElement e = firstChild; e != null; e = e.nextSibling) {
160       if (i++ > 0) {
161         sb.append(',');
162       }
163       sb.append(e);
164     }
165     sb.append("}");
166     return sb.toString();
167   }
168
169   @Override
170   public String toString() {
171     return toString(null);
172   }
173
174   public void dump (PrintWriter w) {
175     dump(w, 0, firstChild);
176   }
177
178   public void processChildren(ElementProcessor p) {
179     for (ScriptElement e = firstChild; e != null; e = e.nextSibling) {
180       e.process(p);
181     }
182   }
183 }