KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > xb > binding > sunday > unmarshalling > ChoiceBinding


1 /*
2   * JBoss, Home of Professional Open Source
3   * Copyright 2005, JBoss Inc., and individual contributors as indicated
4   * by the @authors tag. See the copyright.txt in the distribution for a
5   * full listing of individual contributors.
6   *
7   * This is free software; you can redistribute it and/or modify it
8   * under the terms of the GNU Lesser General Public License as
9   * published by the Free Software Foundation; either version 2.1 of
10   * the License, or (at your option) any later version.
11   *
12   * This software is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   * Lesser General Public License for more details.
16   *
17   * You should have received a copy of the GNU Lesser General Public
18   * License along with this software; if not, write to the Free
19   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21   */

22 package org.jboss.xb.binding.sunday.unmarshalling;
23
24 import java.util.Collections JavaDoc;
25 import java.util.HashSet JavaDoc;
26 import java.util.Set JavaDoc;
27 import java.util.List JavaDoc;
28 import java.util.ArrayList JavaDoc;
29 import java.util.Collection JavaDoc;
30 import javax.xml.namespace.QName JavaDoc;
31 import org.jboss.xb.binding.JBossXBRuntimeException;
32 import org.xml.sax.Attributes JavaDoc;
33
34
35 /**
36  * @author <a HREF="mailto:alex@jboss.org">Alexey Loubyansky</a>
37  * @version <tt>$Revision: 1970 $</tt>
38  */

39 public class ChoiceBinding
40    extends ModelGroupBinding
41 {
42    private List JavaDoc choices = Collections.EMPTY_LIST;
43
44    public ChoiceBinding(SchemaBinding schema)
45    {
46       super(schema);
47    }
48
49    public ElementBinding getArrayItem()
50    {
51       return null;
52    }
53
54    public void addParticle(ParticleBinding particle)
55    {
56       switch(choices.size())
57       {
58          case 0:
59             choices = Collections.singletonList(particle);
60             break;
61          case 1:
62             choices = new ArrayList JavaDoc(choices);
63          default:
64             choices.add(particle);
65       }
66
67       super.addParticle(particle);
68    }
69
70    public Collection JavaDoc getParticles()
71    {
72       return Collections.unmodifiableCollection(choices);
73    }
74
75    public Cursor newCursor(ParticleBinding particle)
76    {
77       return new Cursor(particle)
78       {
79          private int pos = -1;
80          private ElementBinding element;
81          private int occurence;
82
83          public ParticleBinding getCurrentParticle()
84          {
85             if(pos < 0)
86             {
87                throw new JBossXBRuntimeException(
88                   "The cursor has not been positioned yet! startElement should be called."
89                );
90             }
91             return (ParticleBinding)choices.get(pos);
92          }
93
94          public ElementBinding getElement()
95          {
96             if(pos < 0)
97             {
98                throw new JBossXBRuntimeException(
99                   "The cursor has not been positioned yet! startElement should be called."
100                );
101             }
102             return element;
103          }
104
105          public boolean isPositioned()
106          {
107             return pos != -1;
108          }
109
110          public void endElement(QName JavaDoc qName)
111          {
112             if(element == null || !element.getQName().equals(qName))
113             {
114                throw new JBossXBRuntimeException("Failed to process endElement for " + qName +
115                   " since the current element is " + (element == null ? "null" : element.getQName().toString())
116                );
117             }
118
119             if(trace)
120             {
121                log.trace("endElement " + qName + " in " + getModelGroup());
122             }
123          }
124
125          public int getOccurence()
126          {
127             return occurence;
128          }
129
130          protected List JavaDoc startElement(QName JavaDoc qName, Attributes JavaDoc atts, Set JavaDoc passedGroups, List JavaDoc groupStack, boolean required)
131          {
132             if(trace)
133             {
134                StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
135                sb.append("startElement " + qName + " in " + getModelGroup() + ", " + choices.size() + ": ");
136
137                for(int i = 0; i < choices.size(); ++i)
138                {
139                   ParticleBinding particle = (ParticleBinding)choices.get(i);
140                   Object JavaDoc o = particle.getTerm();
141                   if(o instanceof ElementBinding)
142                   {
143                      sb.append(((ElementBinding)o).getQName());
144                   }
145                   else if(o instanceof SequenceBinding)
146                   {
147                      sb.append("sequence");
148                   }
149                   else if(o instanceof ChoiceBinding)
150                   {
151                      sb.append("choice");
152                   }
153                   else if(o instanceof AllBinding)
154                   {
155                      sb.append("all");
156                   }
157
158                   sb.append(" ");
159                }
160                sb.append("]");
161                log.trace(sb.toString());
162             }
163
164             int i = pos;
165             if(pos >= 0)
166             {
167                ParticleBinding particle = getCurrentParticle();
168                if(particle.getMaxOccursUnbounded() ||
169                   occurence < particle.getMinOccurs() ||
170                   occurence < particle.getMaxOccurs())
171                {
172                   --i;
173                }
174             }
175
176             // i update pos only if the element has been found, though it seems to be irrelevant
177
// since the cursor is going to be thrown away in case the element has not been found
178
while(i < choices.size() - 1)
179             {
180                ParticleBinding particle = (ParticleBinding)choices.get(++i);
181                Object JavaDoc item = particle.getTerm();
182                if(item instanceof ElementBinding)
183                {
184                   ElementBinding element = (ElementBinding)item;
185                   if(qName.equals(element.getQName()))
186                   {
187                      if(pos == i)
188                      {
189                         ++occurence;
190                      }
191                      else
192                      {
193                         pos = i;
194                         occurence = 1;
195                      }
196                      groupStack = addItem(groupStack, this);
197                      this.element = element;
198
199                      if(trace)
200                      {
201                         log.trace("found " + qName + " in " + getModelGroup());
202                      }
203                      break;
204                   }
205                }
206                else if(item instanceof ModelGroupBinding)
207                {
208                   ModelGroupBinding modelGroup = (ModelGroupBinding)item;
209                   if(!passedGroups.contains(modelGroup))
210                   {
211                      switch(passedGroups.size())
212                      {
213                         case 0:
214                            passedGroups = Collections.singleton(this);
215                            break;
216                         case 1:
217                            passedGroups = new HashSet JavaDoc(passedGroups);
218                         default:
219                            passedGroups.add(this);
220                      }
221
222                      int groupStackSize = groupStack.size();
223                      groupStack = modelGroup.newCursor(particle).startElement(
224                         qName, atts, passedGroups, groupStack, particle.isRequired(occurence)
225                      );
226
227                      if(groupStackSize != groupStack.size())
228                      {
229                         if(pos != i)
230                         {
231                            pos = i;
232                            occurence = 1;
233                         }
234                         else
235                         {
236                            ++occurence;
237                         }
238                         groupStack = addItem(groupStack, this);
239                         element = null;
240                         break;
241                      }
242                   }
243                }
244                else if(item instanceof WildcardBinding)
245                {
246                   WildcardBinding wildcard = (WildcardBinding)item;
247                   element = wildcard.getElement(qName, atts);
248                   if(element != null)
249                   {
250                      if(pos != i)
251                      {
252                         pos = i;
253                         occurence = 1;
254                      }
255                      else
256                      {
257                         ++occurence;
258                      }
259                      groupStack = addItem(groupStack, this);
260                      break;
261                   }
262                }
263             }
264
265             if(trace)
266             {
267                if(i == choices.size())
268                {
269                   log.trace(qName + " not found in " + getModelGroup());
270                }
271                else
272                {
273                   log.trace("leaving " + getModelGroup() + " i=" + i + ", pos=" + pos);
274                }
275             }
276
277             return groupStack;
278          }
279
280          protected ElementBinding getElement(QName JavaDoc qName, Attributes JavaDoc atts, Set JavaDoc passedGroups, boolean ignoreWildcards)
281          {
282             return getElement(choices, qName, atts, passedGroups, ignoreWildcards);
283          }
284       };
285    }
286
287    protected boolean mayStartWith(QName JavaDoc qName, Set JavaDoc set)
288    {
289       boolean result = false;
290       for(int i = 0; i < choices.size(); ++i)
291       {
292          ParticleBinding particle = (ParticleBinding)choices.get(i);
293          Object JavaDoc item = particle.getTerm();
294          if(item instanceof ElementBinding)
295          {
296             ElementBinding element = (ElementBinding)item;
297             if(qName.equals(element.getQName()))
298             {
299                result = true;
300                break;
301             }
302          }
303          else if(item instanceof ModelGroupBinding)
304          {
305             ModelGroupBinding modelGroup = (ModelGroupBinding)item;
306             if(!set.contains(modelGroup))
307             {
308                switch(set.size())
309                {
310                   case 0:
311                      set = Collections.singleton(this);
312                      break;
313                   case 1:
314                      set = new HashSet JavaDoc(set);
315                   default:
316                      set.add(this);
317                }
318
319                result = modelGroup.mayStartWith(qName, set);
320
321                if(result)
322                {
323                   break;
324                }
325             }
326          }
327          else
328          {
329             throw new JBossXBRuntimeException("Unexpected item type in model group: " + item);
330          }
331       }
332
333       return result;
334    }
335 }
336
Popular Tags