KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > japex > testsuite > impl > runtime > SAXMarshaller


1 //
2
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v1.0.3-b18-fcs
3
// See <a HREF="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
4
// Any modifications to this file will be lost upon recompilation of the source schema.
5
// Generated on: 2005.06.14 at 12:02:17 PDT
6
//
7

8 package com.sun.japex.testsuite.impl.runtime;
9
10 import java.util.HashSet JavaDoc;
11 import java.util.Iterator JavaDoc;
12 import java.util.Set JavaDoc;
13
14 import javax.xml.bind.JAXBException;
15 import javax.xml.bind.ValidationEvent;
16 import javax.xml.bind.ValidationEventHandler;
17 import javax.xml.bind.helpers.NotIdentifiableEventImpl;
18 import javax.xml.bind.helpers.ValidationEventLocatorImpl;
19
20 import org.xml.sax.ContentHandler JavaDoc;
21 import org.xml.sax.SAXException JavaDoc;
22 import org.xml.sax.helpers.AttributesImpl JavaDoc;
23
24 import com.sun.xml.bind.JAXBAssertionError;
25 import com.sun.xml.bind.JAXBObject;
26 import com.sun.xml.bind.marshaller.IdentifiableObject;
27 import com.sun.xml.bind.marshaller.Messages;
28 import com.sun.xml.bind.marshaller.NamespacePrefixMapper;
29 import com.sun.xml.bind.serializer.AbortSerializationException;
30 import com.sun.xml.bind.serializer.Util;
31
32 /**
33  * XMLSerializer that produces SAX2 events.
34  *
35  * To marshal an object, create an instance of SAXMarshaller
36  * and call the serializeElements method of the XMLSerializable
37  * object that you want to marshal.
38  *
39  * @author Kohsuke Kawaguchi
40  */

41 public class SAXMarshaller implements XMLSerializer
42 {
43     /**
44      * "Attributes" object that is passed to the startElement event.
45      * One object is reused throughout the marshalling.
46      */

47     private final AttributesImpl JavaDoc attributes = new AttributesImpl JavaDoc();
48  
49     /** This object receives SAX2 events generated from the marshaller. */
50     private final ContentHandler JavaDoc writer;
51     
52     /** Marshaller object to which this object belongs. */
53     private final MarshallerImpl owner;
54     
55     /** Objects referenced through IDREF. */
56     private final Set JavaDoc idReferencedObjects = new HashSet JavaDoc();
57     
58     /** Objects with ID. */
59     private final Set JavaDoc objectsWithId = new HashSet JavaDoc();
60     
61     /** Object currently marshalling itself. */
62     private JAXBObject currentTarget;
63     
64     /**
65      * Creates a marshalling context by designating the ContentHandler
66      * that receives generated SAX2 events.
67      */

68     public SAXMarshaller( ContentHandler JavaDoc _writer, NamespacePrefixMapper prefixMapper, MarshallerImpl _owner ) {
69         this.writer = _writer;
70         this.owner = _owner;
71         this.nsContext = new NamespaceContextImpl(
72             prefixMapper!=null?prefixMapper:defaultNamespacePrefixMapper);
73     }
74     
75     /** namespace context. */
76     private final NamespaceContextImpl nsContext;
77     
78     public NamespaceContext2 getNamespaceContext() { return nsContext; }
79     
80     //
81
//
82
// name stack
83
//
84
//
85

86     /** Element name stack implemented as an array of (uri,local) pairs. */
87     private String JavaDoc[] elementStack = new String JavaDoc[16];;
88     private int elementLen=0;
89     
90     
91     
92     private void pushElement( String JavaDoc uri, String JavaDoc local ) {
93         if(elementStack.length==elementLen) {
94             // reallocate buffer
95
String JavaDoc[] buf = new String JavaDoc[elementStack.length*2];
96             System.arraycopy( elementStack, 0, buf, 0, elementStack.length );
97             elementStack = buf;
98         }
99         elementStack[elementLen++] = uri;
100         elementStack[elementLen++] = local;
101     }
102     
103     private void popElement() { elementLen-=2; }
104     
105     private String JavaDoc getCurrentElementUri() { return elementStack[elementLen-2]; }
106     private String JavaDoc getCurrentElementLocal() { return elementStack[elementLen-1]; }
107     
108     
109     
110     
111     
112     /**
113      * Starts marshalling of an element.
114      * Calling this method will push the internal state into the
115      * internal stack.
116      */

117     public void startElement( String JavaDoc uri, String JavaDoc local ) throws SAXException JavaDoc {
118         boolean isRoot = false;
119         String JavaDoc suggestion = null;
120         if( elementLen==0 ) {
121             isRoot = true;
122             // this is the root element. suggest this as the default namespace
123
suggestion = "";
124         }
125         
126         writePendingText();
127         nsContext.startElement();
128         pushElement(uri,local); // memorize element name
129

130         // declare this uri
131
nsContext.declareNamespace(uri,suggestion,false);
132         
133         // if this is the root element, declare user-specified namespace URIs.
134
if( isRoot ) {
135             // work defensively. we are calling an user-defined method.
136
String JavaDoc[] uris = nsContext.getNamespacePrefixMapper().getPreDeclaredNamespaceUris();
137             if( uris!=null ) {
138                 for( int i=0; i<uris.length; i++ ) {
139                     if( uris[i]!=null )
140                         nsContext.declareNamespace(uris[i],null,false);
141                 }
142             }
143         }
144     }
145     
146     
147     private final PrefixCallback startPrefixCallback = new PrefixCallback() {
148         public void onPrefixMapping( String JavaDoc prefix, String JavaDoc nsUri ) throws SAXException JavaDoc {
149             writer.startPrefixMapping(prefix,nsUri);
150         }
151     };
152     private final PrefixCallback endPrefixCallback = new PrefixCallback() {
153         public void onPrefixMapping( String JavaDoc prefix, String JavaDoc nsUri ) throws SAXException JavaDoc {
154             writer.endPrefixMapping(prefix);
155         }
156     };
157     
158     public void endNamespaceDecls() throws SAXException JavaDoc {
159         nsContext.endNamespaceDecls();
160     }
161     
162     /**
163      * Switches to the "marshal child texts/elements" mode.
164      * This method has to be called after the 1st pass is completed.
165      */

166     public void endAttributes() throws SAXException JavaDoc {
167         // calculate QName of the element
168
String JavaDoc uri = getCurrentElementUri();
169         String JavaDoc local = getCurrentElementLocal();
170         
171         String JavaDoc prefix = nsContext.getPrefix(uri);
172         _assert(prefix!=null); // since we've declared it, it should be available
173

174         String JavaDoc qname;
175         if(prefix.length()!=0 )
176             qname = prefix+':'+local;
177         else
178             qname = local;
179
180         // fire startPrefixMapping events
181
nsContext.iterateDeclaredPrefixes(startPrefixCallback);
182         
183         // fire the startElement event
184
writer.startElement( uri, local, qname, attributes );
185         
186         
187         // reset attributes
188
attributes.clear();
189         
190         // prepare to collect texts
191
textBuf.setLength(0);
192     }
193     
194     /**
195      * Ends marshalling of an element.
196      * Pops the internal stack.
197      */

198     public void endElement() throws SAXException JavaDoc {
199         writePendingText();
200         
201         String JavaDoc uri = getCurrentElementUri();
202         String JavaDoc local = getCurrentElementLocal();
203         
204         String JavaDoc prefix = nsContext.getPrefix(uri);
205         _assert(prefix!=null); // we've declared it earlier.
206

207         String JavaDoc qname;
208         if(prefix.length()!=0)
209             qname = prefix+':'+local;
210         else
211             qname = local;
212         
213         writer.endElement( uri, local, qname );
214
215         // pop namespace bindings and
216
// fire endPrefixMapping events
217
nsContext.iterateDeclaredPrefixes(endPrefixCallback);
218         
219         popElement();
220         
221         // prepare to collect texts
222
textBuf.setLength(0);
223         
224         nsContext.endElement();
225     }
226     
227     
228     /** Buffer for collecting characters. */
229     private final StringBuffer JavaDoc textBuf = new StringBuffer JavaDoc();
230     
231     /**
232      * Marshalls text.
233      *
234      * <p>
235      * This method can be called (i) after the startAttribute method
236      * and (ii) before the endAttribute method, to marshal attribute values.
237      * If the method is called more than once, those texts are considered
238      * as separated by whitespaces. For example,
239      *
240      * <pre>
241      * c.startAttribute();
242      * c.text("abc");
243      * c.text("def");
244      * c.endAttribute("","foo");
245      * </pre>
246      *
247      * will generate foo="abc def".
248      *
249      * <p>
250      * Similarly, this method can be called after the endAttributes
251      * method to marshal texts inside elements. The same rule about
252      * multiple invokations apply to this case, too. For example,
253      *
254      * <pre>
255      * c.startElement("","foo");
256      * c.endAttributes();
257      * c.text("abc");
258      * c.text("def");
259      * c.startElement("","bar");
260      * c.endAttributes();
261      * c.endElement();
262      * c.text("ghi");
263      * c.endElement();
264      * </pre>
265      *
266      * will generate <code>&lt;foo>abc def&lt;bar/>ghi&lt;/foo></code>.
267      */

268     public void text( String JavaDoc text, String JavaDoc fieldName ) throws SAXException JavaDoc {
269         // If the assertion fails, it must be a bug of xjc.
270
// right now, we are not expecting the text method to be called.
271
if(text==null) {
272             reportError(Util.createMissingObjectError(currentTarget,fieldName));
273             return;
274         }
275     
276         if(textBuf.length()!=0)
277             textBuf.append(' ');
278         textBuf.append(text);
279     }
280     
281     /**
282      * Writes pending text (characters inside elements) to the writer.
283      * This method is called from startElement and endElement.
284      */

285     private void writePendingText() throws SAXException JavaDoc {
286         // assert(textBuf!=null);
287
int len = textBuf.length();
288         
289         if(len!=0)
290             writer.characters( textBuf.toString().toCharArray(), 0, len );
291     }
292     
293     /**
294      * Starts marshalling of an attribute.
295      *
296      * The marshalling of an attribute will be done by
297      * <ol>
298      * <li>call the startAttribute method
299      * <li>call the text method (several times if necessary)
300      * <li>call the endAttribute method
301      * </ol>
302      *
303      * No two attributes can be marshalled at the same time.
304      * Note that the whole attribute marshalling must be happened
305      * after the startElement method and before the endAttributes method.
306      */

307     public void startAttribute( String JavaDoc uri, String JavaDoc local ) {
308         // initialize the buffer to collect attribute value
309
textBuf.setLength(0);
310         
311         // remember the attribute name. We'll use this value later.
312
this.attNamespaceUri = uri;
313         this.attLocalName = local;
314     }
315     
316     // used to keep attribute names until the endAttribute method is called.
317
private String JavaDoc attNamespaceUri;
318     private String JavaDoc attLocalName;
319
320     public void endAttribute() {
321         // use CDATA as the attribute type. This preserves
322
// successive processors to collapse whitespaces.
323
// (we cannot prevent characters like #xD to be replaced to
324
// #x20, though).
325
//
326
// strictly speaking, attribute value normalization should be
327
// provessed by XML parser, so it's unclear whether XML writer
328
// uses this type value.
329
//
330
// in any way, CDATA type is the safest choice here.
331

332         String JavaDoc qname;
333         if(attNamespaceUri.length()==0) {
334             // default namespace. don't need prefix
335
qname = attLocalName;
336         } else {
337             qname = nsContext.declareNamespace(attNamespaceUri,null,true)+':'+attLocalName;
338         }
339
340         attributes.addAttribute(attNamespaceUri,attLocalName,qname,"CDATA",textBuf.toString());
341     }
342     
343     public String JavaDoc onID( IdentifiableObject owner, String JavaDoc value ) throws SAXException JavaDoc {
344         objectsWithId.add(owner);
345         return value;
346     }
347     public String JavaDoc onIDREF( IdentifiableObject obj ) throws SAXException JavaDoc {
348         idReferencedObjects.add(obj);
349         String JavaDoc id = obj.____jaxb____getId();
350         if(id==null) {
351             reportError( new NotIdentifiableEventImpl(
352                 ValidationEvent.ERROR,
353                 Messages.format(Messages.ERR_NOT_IDENTIFIABLE),
354                 new ValidationEventLocatorImpl(obj) ) );
355         }
356         return id;
357     }
358     
359     void reconcileID() throws AbortSerializationException {
360         // find objects that were not a part of the object graph
361
idReferencedObjects.removeAll(objectsWithId);
362         
363         for( Iterator JavaDoc itr=idReferencedObjects.iterator(); itr.hasNext(); ) {
364             IdentifiableObject o = (IdentifiableObject)itr.next();
365             reportError( new NotIdentifiableEventImpl(
366                 ValidationEvent.ERROR,
367                 Messages.format(Messages.ERR_DANGLING_IDREF,o.____jaxb____getId()),
368                 new ValidationEventLocatorImpl(o) ) );
369         }
370         
371         // clear the garbage
372
idReferencedObjects.clear();
373         objectsWithId.clear();
374     }
375
376
377
378     public void childAsBody( JAXBObject o, String JavaDoc fieldName ) throws SAXException JavaDoc {
379         if(o==null) {
380             // if null is passed, it usually means that the content tree object
381
// doesn't have some of its required property.
382
reportMissingObjectError(fieldName);
383             // as a marshaller, we should be generous, so we'll continue to marshal
384
// this document by skipping this missing object.
385
return;
386         }
387         
388         JAXBObject oldTarget = currentTarget;
389         currentTarget = o;
390         
391         owner.context.getGrammarInfo().castToXMLSerializable(o).serializeBody(this);
392         
393         currentTarget = oldTarget;
394     }
395     
396     public void childAsAttributes( JAXBObject o, String JavaDoc fieldName ) throws SAXException JavaDoc {
397         if(o==null) {
398             reportMissingObjectError(fieldName);
399             return;
400         }
401
402         JAXBObject oldTarget = currentTarget;
403         currentTarget = o;
404         
405         owner.context.getGrammarInfo().castToXMLSerializable(o).serializeAttributes(this);
406         
407         currentTarget = oldTarget;
408     }
409     
410     public void childAsURIs( JAXBObject o, String JavaDoc fieldName ) throws SAXException JavaDoc {
411         if(o==null) {
412             reportMissingObjectError(fieldName);
413             return;
414         }
415         
416         JAXBObject oldTarget = currentTarget;
417         currentTarget = o;
418         
419         owner.context.getGrammarInfo().castToXMLSerializable(o).serializeURIs(this);
420         
421         currentTarget = oldTarget;
422     }
423     
424
425     public void reportError( ValidationEvent ve ) throws AbortSerializationException {
426         ValidationEventHandler handler;
427         
428         try {
429             handler = owner.getEventHandler();
430         } catch( JAXBException e ) {
431             throw new AbortSerializationException(e);
432         }
433         
434         if(!handler.handleEvent(ve)) {
435             if(ve.getLinkedException() instanceof Exception JavaDoc)
436                 throw new AbortSerializationException((Exception JavaDoc)ve.getLinkedException());
437             else
438                 throw new AbortSerializationException(ve.getMessage());
439         }
440     }
441     
442     
443     public void reportMissingObjectError(String JavaDoc fieldName) throws SAXException JavaDoc {
444         reportError(Util.createMissingObjectError(currentTarget,fieldName));
445     }
446     
447     
448     private static void _assert( boolean b ) {
449         if(!b)
450             throw new JAXBAssertionError();
451     }
452     
453     /**
454      * Default {@link NamespacePrefixMapper} implementation used when
455      * it is not specified by the user.
456      */

457     private static NamespacePrefixMapper defaultNamespacePrefixMapper = new NamespacePrefixMapper() {
458         public String JavaDoc getPreferredPrefix(String JavaDoc namespaceUri, String JavaDoc suggestion, boolean requirePrefix) {
459             if( namespaceUri.equals("http://www.w3.org/2001/XMLSchema-instance") )
460                 return "xsi";
461             return suggestion;
462         }
463     };
464 }
465
Popular Tags