KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > tools > xjc > runtime > InterleaveDispatcher


1 package com.sun.tools.xjc.runtime;
2
3 import java.util.Iterator JavaDoc;
4
5 import javax.xml.bind.ValidationEvent;
6
7 import org.xml.sax.Attributes JavaDoc;
8 import org.xml.sax.Locator JavaDoc;
9 import org.xml.sax.SAXException JavaDoc;
10
11 import com.sun.xml.bind.JAXBAssertionError;
12 import com.sun.xml.bind.unmarshaller.Tracer;
13
14 /**
15  * Splits the unmarshalling events to bracnhes to support
16  * XML Schema's <all> and RELAX NG's <interleave>
17  *
18  * <p>
19  * This class will be extended by the generated code.
20  *
21  * @optionalRuntime
22  *
23  * @author
24  * Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
25  */

26 public abstract class InterleaveDispatcher implements UnmarshallingEventHandler {
27     
28     /** Parent context. */
29     private final UnmarshallingContext parent;
30     
31     /** Branches of an interleave. */
32     protected final Site[] sites;
33     
34     /** Set to true while all the branches are joining. */
35     private boolean isJoining;
36     
37     /** Counts the depth of the element nesting. */
38     private int nestLevel = 0;
39     
40     /** When nestLevel>0, all the events shall be sent to this branch. */
41     private Site currentSite;
42
43     
44     protected InterleaveDispatcher( UnmarshallingContext context, int size ) {
45         this.parent = context;
46         sites = new Site[size];
47         for( int i=0; i<size; i++ )
48             sites[i] = new Site();
49     }
50     
51     protected void init( UnmarshallingEventHandler[] handlers ) {
52         for( int i=0; i<handlers.length; i++ )
53             sites[i].pushContentHandler(handlers[i],0);
54     }
55     
56
57 // abstract methods
58
/**
59      * Returns the branch number that consumes the given element,
60      * or -1 if the name is not recognized.
61      */

62     protected abstract int getBranchForElement( String JavaDoc uri, String JavaDoc local );
63     
64     /**
65      * Returns the branch number that consumes the given attribute,
66      * or -1 if the name is not recognized.
67      */

68     protected abstract int getBranchForAttribute( String JavaDoc uri, String JavaDoc local );
69     
70     /**
71      * Returns the branch number that consumes the text events,
72      * or -1 if no branch is expected to consume it.
73      */

74     protected abstract int getBranchForText();
75     
76     
77     
78     
79     
80     public Object JavaDoc owner() {
81         if( nestLevel>0 )
82             return currentSite.getCurrentHandler().owner();
83         else
84             throw new JAXBAssertionError();
85     }
86
87     public void enterElement(String JavaDoc uri, String JavaDoc local, String JavaDoc qname, Attributes JavaDoc atts) throws SAXException JavaDoc {
88         if( nestLevel++==0 ) {
89             int idx = getBranchForElement(uri, local);
90             if(idx==-1) {
91                 // unknown element. revert to parent.
92
joinByEnterElement(null, uri, local, qname, atts);
93                 return;
94             }
95             currentSite = sites[idx];
96         }
97             
98         currentSite.getCurrentHandler().enterElement(uri, local, qname, atts);
99     }
100     private void joinByEnterElement( Site source, String JavaDoc uri, String JavaDoc local, String JavaDoc qname, Attributes JavaDoc atts ) throws SAXException JavaDoc {
101         if(isJoining) return; // during a join, child branches send us tokens we sent them. ignore.
102
isJoining = true;
103         
104         // send the token to all the other branches.
105
// since they don't recognize this token, it should try to move
106
// to the final state (or report an error)
107
for( int i=0; i<sites.length; i++ )
108             if( sites[i]!=source )
109                 sites[i].getCurrentHandler().enterElement(uri, local, qname, atts);
110         
111         // revert to the parent
112
parent.popContentHandler();
113         parent.getCurrentHandler().enterElement(uri,local,qname,atts);
114     }
115
116
117     public void leaveElement(String JavaDoc uri, String JavaDoc local, String JavaDoc qname) throws SAXException JavaDoc {
118         if( nestLevel==0 )
119             joinByLeaveElement(null,uri,local,qname);
120         else {
121             currentSite.getCurrentHandler().leaveElement(uri,local,qname);
122             // leaveElement invocation might cause some unprocessed attributes
123
// to be handled. Therefore, while the execution is in the leaveElement,
124
// we need to let the branch maintain the control.
125
nestLevel--;
126         }
127     }
128     private void joinByLeaveElement(Site source,String JavaDoc uri, String JavaDoc local, String JavaDoc qname) throws SAXException JavaDoc {
129         if(isJoining) return; // during a join, child branches send us tokens we sent them. ignore.
130
isJoining = true;
131         
132         // send the token to all the other branches.
133
// since they don't recognize this token, it should try to move
134
// to the final state (or report an error)
135
for( int i=0; i<sites.length; i++ )
136             if( sites[i]!=source )
137                 sites[i].getCurrentHandler().leaveElement(uri,local,qname);
138         
139         // revert to the parent
140
parent.popContentHandler();
141         parent.getCurrentHandler().leaveElement(uri,local,qname);
142     }
143
144
145     public void text(String JavaDoc s) throws SAXException JavaDoc {
146         if( nestLevel==0 ) {
147             int idx = getBranchForText();
148             if(idx==-1) {
149                 if( s.trim().length()==0 ) {
150                     // if ignorable, just ignore.
151
} else {
152                     joinByText(null,s);
153                 }
154                 return;
155             }
156             currentSite = sites[idx];
157         }
158         
159         currentSite.getCurrentHandler().text(s);
160     }
161     private void joinByText(Site source, String JavaDoc s) throws SAXException JavaDoc {
162         if(isJoining) return; // during a join, child branches send us tokens we sent them. ignore.
163
isJoining = true;
164         
165         // send the token to all the other branches.
166
// since they don't recognize this token, it should try to move
167
// to the final state (or report an error)
168
for( int i=0; i<sites.length; i++ )
169             if( sites[i]!=source )
170                 sites[i].getCurrentHandler().text(s);
171         
172         // revert to the parent
173
parent.popContentHandler();
174         parent.getCurrentHandler().text(s);
175     }
176
177
178     public void enterAttribute(String JavaDoc uri, String JavaDoc local, String JavaDoc qname) throws SAXException JavaDoc {
179         if( nestLevel++==0 ) {
180             int idx = getBranchForAttribute(uri, local);
181             if(idx==-1) {
182                 // unknown element. revert to parent.
183
joinByEnterAttribute(null, uri, local, qname);
184                 return;
185             }
186             currentSite = sites[idx];
187         }
188             
189         currentSite.getCurrentHandler().enterAttribute(uri, local, qname);
190     }
191     private void joinByEnterAttribute( Site source, String JavaDoc uri, String JavaDoc local, String JavaDoc qname ) throws SAXException JavaDoc {
192         if(isJoining) return; // during a join, child branches send us tokens we sent them. ignore.
193
isJoining = true;
194         
195         // send the token to all the other branches.
196
// since they don't recognize this token, it should try to move
197
// to the final state (or report an error)
198
for( int i=0; i<sites.length; i++ )
199             if( sites[i]!=source )
200                 sites[i].getCurrentHandler().enterAttribute(uri, local, qname);
201         
202         // revert to the parent
203
parent.popContentHandler();
204         parent.getCurrentHandler().enterAttribute(uri,local,qname);
205     }
206
207
208     public void leaveAttribute(String JavaDoc uri, String JavaDoc local, String JavaDoc qname) throws SAXException JavaDoc {
209         if( nestLevel==0 )
210             joinByLeaveAttribute(null,uri,local,qname);
211         else {
212             nestLevel--;
213             currentSite.getCurrentHandler().leaveAttribute(uri,local,qname);
214         }
215     }
216     private void joinByLeaveAttribute(Site source,String JavaDoc uri, String JavaDoc local, String JavaDoc qname) throws SAXException JavaDoc {
217         if(isJoining) return; // during a join, child branches send us tokens we sent them. ignore.
218
isJoining = true;
219         
220         // send the token to all the other branches.
221
// since they don't recognize this token, it should try to move
222
// to the final state (or report an error)
223
for( int i=0; i<sites.length; i++ )
224             if( sites[i]!=source )
225                 sites[i].getCurrentHandler().leaveAttribute(uri,local,qname);
226         
227         // revert to the parent
228
parent.popContentHandler();
229         parent.getCurrentHandler().leaveAttribute(uri,local,qname);
230     }
231
232     public void leaveChild(int nextState) throws SAXException JavaDoc {
233         // assertion failed. since we don't launch any child
234
// this method shall never be called.
235
throw new JAXBAssertionError();
236     }
237     
238     
239 // /** triggers join. */
240
// private final UnmarshallingEventHandler nullHandler = new UnmarshallingEventHandler() {
241
// public Object owner() {
242
// return null;
243
// }
244
//
245
// public void enterElement(String uri, String local, String qname, Attributes atts) throws UnreportedException {
246
// join
247
// }
248
// public void leaveElement(String uri, String local, String qname) throws UnreportedException {
249
// }
250
// public void text(String s) throws UnreportedException {
251
// }
252
// public void enterAttribute(String uri, String local, String qname) throws UnreportedException {
253
// }
254
// public void leaveAttribute(String uri, String local, String qname) throws UnreportedException {
255
// }
256
// public void leaveChild(int nextState) throws UnreportedException {
257
// }
258
// };
259

260     
261     /**
262      * This implementation will be passed to branches as
263      * the {@link UnmarshallingContext} implementation.
264      *
265      * Used to maintain separate handler stacks for each branch.
266      *
267      * As an {@link UnmarshallingEventHandler}, this object
268      * triggers join.
269      */

270     private class Site implements UnmarshallingContext, UnmarshallingEventHandler {
271         
272         // handler stack implemented as an array
273
private UnmarshallingEventHandler[] handlers = new UnmarshallingEventHandler[8];
274         private int[] mementos = new int[8];
275         private int handlerLen=0;
276         
277         private Site() {
278             pushContentHandler(this, 0);
279         }
280     
281         public void pushContentHandler( UnmarshallingEventHandler handler, int memento ) {
282             if(handlerLen==handlers.length) {
283                 // expand buffer
284
UnmarshallingEventHandler[] h = new UnmarshallingEventHandler[handlerLen*2];
285                 int[] m = new int[handlerLen*2];
286                 System.arraycopy(handlers,0,h,0,handlerLen);
287                 System.arraycopy(mementos,0,m,0,handlerLen);
288                 handlers = h;
289                 mementos = m;
290             }
291             handlers[handlerLen] = handler;
292             mementos[handlerLen] = memento;
293             handlerLen++;
294         }
295     
296         public void popContentHandler() throws SAXException JavaDoc {
297             handlerLen--;
298             handlers[handlerLen]=null; // this handler is removed
299
getCurrentHandler().leaveChild(mementos[handlerLen]);
300         }
301
302         public UnmarshallingEventHandler getCurrentHandler() {
303             return handlers[handlerLen-1];
304         }
305
306         
307         // UnmarshallingEventHandler impl. triggers the join operation
308
public Object JavaDoc owner() { return null; }
309         public void enterElement(String JavaDoc uri, String JavaDoc local, String JavaDoc qname, Attributes JavaDoc atts) throws SAXException JavaDoc {
310             joinByEnterElement(this,uri,local,qname,atts);
311         }
312         public void leaveElement(String JavaDoc uri, String JavaDoc local, String JavaDoc qname) throws SAXException JavaDoc {
313             joinByLeaveElement(this,uri,local,qname);
314         }
315         public void enterAttribute(String JavaDoc uri, String JavaDoc local, String JavaDoc qname) throws SAXException JavaDoc {
316             joinByEnterAttribute(this,uri,local,qname);
317         }
318         public void leaveAttribute(String JavaDoc uri, String JavaDoc local, String JavaDoc qname) throws SAXException JavaDoc {
319             joinByLeaveAttribute(this,uri,local,qname);
320         }
321         public void text(String JavaDoc s) throws SAXException JavaDoc {
322             joinByText(this,s);
323         }
324         public void leaveChild(int nextState) throws SAXException JavaDoc {
325         }
326         
327         
328         // the rest of the methods are just delegations for UnmarshallingContext
329

330         public void addPatcher(Runnable JavaDoc job) {
331             parent.addPatcher(job);
332         }
333
334         public String JavaDoc addToIdTable(String JavaDoc id) {
335             return parent.addToIdTable(id);
336         }
337
338         public void consumeAttribute(int idx) throws SAXException JavaDoc {
339             parent.consumeAttribute(idx);
340         }
341
342         public String JavaDoc eatAttribute(int idx) throws SAXException JavaDoc {
343             return parent.eatAttribute(idx);
344         }
345
346         public int getAttribute(String JavaDoc uri, String JavaDoc name) {
347             return parent.getAttribute(uri, name);
348         }
349
350         public String JavaDoc getBaseUri() {
351             return parent.getBaseUri();
352         }
353
354         public GrammarInfo getGrammarInfo() {
355             return parent.getGrammarInfo();
356         }
357
358         public Locator JavaDoc getLocator() {
359             return parent.getLocator();
360         }
361
362         public String JavaDoc getNamespaceURI(String JavaDoc prefix) {
363             return parent.getNamespaceURI(prefix);
364         }
365
366         public Object JavaDoc getObjectFromId(String JavaDoc id) {
367             return parent.getObjectFromId(id);
368         }
369
370         public String JavaDoc getPrefix(String JavaDoc namespaceURI) {
371             return parent.getPrefix(namespaceURI);
372         }
373
374         public Iterator JavaDoc getPrefixes(String JavaDoc namespaceURI) {
375             return parent.getPrefixes(namespaceURI);
376         }
377
378         public Tracer getTracer() {
379             return parent.getTracer();
380         }
381
382         public Attributes JavaDoc getUnconsumedAttributes() {
383             return parent.getUnconsumedAttributes();
384         }
385
386         public void handleEvent(ValidationEvent event, boolean canRecover) throws SAXException JavaDoc {
387             parent.handleEvent(event,canRecover);
388         }
389
390         public boolean isNotation(String JavaDoc arg0) {
391             return parent.isNotation(arg0);
392         }
393
394         public boolean isUnparsedEntity(String JavaDoc arg0) {
395             return parent.isUnparsedEntity(arg0);
396         }
397
398         public void popAttributes() {
399             parent.popAttributes();
400         }
401
402         public void pushAttributes(Attributes JavaDoc atts,boolean collectTextFlag) {
403             parent.pushAttributes(atts,collectTextFlag);
404         }
405
406         public String JavaDoc resolveNamespacePrefix(String JavaDoc prefix) {
407             return parent.resolveNamespacePrefix(prefix);
408         }
409
410         public String JavaDoc[] getNewlyDeclaredPrefixes() {
411             return parent.getNewlyDeclaredPrefixes();
412         }
413
414         public String JavaDoc[] getAllDeclaredPrefixes() {
415             return parent.getAllDeclaredPrefixes();
416         }
417
418     }
419 }
420
Popular Tags