KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > mvnforum > jaxb > db > impl > runtime > MSVValidator


1 //
2
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v1.0.5-b16-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.12.17 at 09:43:27 AM GMT+07:00
6
//
7

8 package com.mvnforum.jaxb.db.impl.runtime;
9
10 import javax.xml.bind.ValidationEvent;
11
12 import org.relaxng.datatype.Datatype;
13 import org.xml.sax.SAXException JavaDoc;
14 import org.xml.sax.helpers.AttributesImpl JavaDoc;
15
16 import com.sun.msv.grammar.IDContextProvider2;
17 import com.sun.msv.util.LightStack;
18 import com.sun.msv.util.StartTagInfo;
19 import com.sun.msv.util.StringRef;
20 import com.sun.msv.verifier.Acceptor;
21 import com.sun.msv.verifier.regexp.StringToken;
22 import com.sun.xml.bind.JAXBAssertionError;
23 import com.sun.xml.bind.JAXBObject;
24 import com.sun.xml.bind.RIElement;
25 import com.sun.xml.bind.marshaller.IdentifiableObject;
26 import com.sun.xml.bind.serializer.AbortSerializationException;
27 import com.sun.xml.bind.serializer.Util;
28 import com.sun.xml.bind.validator.Messages;
29
30 /**
31  * XMLSerializer that calls the native interface of MSV and performs validation.
32  * Used in a pair with a ValidationContext.
33  *
34  * @author Kohsuke Kawaguchi
35  */

36 public class MSVValidator implements XMLSerializer, IDContextProvider2
37 {
38     /** Current acceptor in use. */
39     private Acceptor acceptor;
40     
41     /** Context object that coordinates the entire validation effort. */
42     private final ValidationContext context;
43     
44     /** The object which we are validating. */
45     private final ValidatableObject target;
46     
47     final DefaultJAXBContextImpl jaxbContext;
48     
49     /**
50      * Acceptor stack. Whenever an element is found, the current acceptor is
51      * pushed to the stack and new one is created.
52      *
53      * LightStack is a light-weight stack implementation
54      */

55     private final LightStack stack = new LightStack();
56
57     public NamespaceContext2 getNamespaceContext() {
58         return context.getNamespaceContext();
59     }
60     
61     /**
62      * To use this class, call the static validate method.
63      */

64     private MSVValidator( DefaultJAXBContextImpl _jaxbCtx, ValidationContext _ctxt, ValidatableObject vo ) {
65         jaxbContext = _jaxbCtx;
66         acceptor = vo.createRawValidator().createAcceptor();
67         context = _ctxt;
68         target = vo;
69     }
70     
71     /**
72      * Validates the specified object and reports any error to the context.
73      */

74     public static void validate( DefaultJAXBContextImpl jaxbCtx, ValidationContext context, ValidatableObject vo )
75             throws SAXException JavaDoc {
76         try {
77             new MSVValidator(jaxbCtx,context,vo)._validate();
78         } catch( RuntimeException JavaDoc e ) {
79             // sometimes when a conversion between Java object and
80
// lexical value fails, it may throw an exception like
81
// NullPointerException or NumberFormatException.
82
//
83
// catch them and report them as an error.
84
context.reportEvent(vo,e);
85         }
86     }
87     
88     /** performs the validation to the object specified in the constructor. */
89     private void _validate() throws SAXException JavaDoc {
90         context.getNamespaceContext().startElement();
91         
92         // validate attributes
93
target.serializeURIs(this);
94         
95         endNamespaceDecls();
96         
97         target.serializeAttributes(this);
98         
99         endAttributes();
100         
101         // validate content model
102
target.serializeBody(this);
103         writePendingText();
104         
105         context.getNamespaceContext().endElement();
106         
107         if(!acceptor.isAcceptState(null)) {
108             // some elements are missing
109
// report error
110
StringRef ref = new StringRef();
111             acceptor.isAcceptState(ref);
112             context.reportEvent(target,ref.str);
113         }
114     }
115     
116     public void endNamespaceDecls() throws SAXException JavaDoc {
117         context.getNamespaceContext().endNamespaceDecls();
118     }
119     
120     public void endAttributes() throws SAXException JavaDoc {
121         if(!acceptor.onEndAttributes( null, null )) {
122             // some required attributes are missing.
123
// report a validation error
124
// Note that we don't know which property of this object
125
// causes this error.
126
StringRef ref = new StringRef();
127             StartTagInfo sti = new StartTagInfo(
128                 currentElementUri,currentElementLocalName,currentElementLocalName,
129                 emptyAttributes,this);
130             acceptor.onEndAttributes( sti, ref );
131             context.reportEvent(target,ref.str);
132         }
133     }
134     
135     /** stores text reported by the text method. */
136     private StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
137         
138     public final void text( String JavaDoc text, String JavaDoc fieldName ) throws SAXException JavaDoc {
139         if(text==null) {
140             reportMissingObjectError(fieldName);
141             return;
142         }
143         
144         if(buf.length()!=0)
145             buf.append(' ');
146         buf.append(text);
147     }
148     
149     public void reportMissingObjectError(String JavaDoc fieldName) throws SAXException JavaDoc {
150         reportError(Util.createMissingObjectError(target,fieldName));
151     }
152     
153
154     // used to keep attribute names until the endAttribute method is called.
155
private String JavaDoc attNamespaceUri;
156     private String JavaDoc attLocalName;
157     private boolean insideAttribute;
158
159     public void startAttribute( String JavaDoc uri, String JavaDoc local ) {
160         // we will do the processing at the end element
161
this.attNamespaceUri = uri;
162         this.attLocalName = local;
163         insideAttribute = true;
164     }
165     
166     public void endAttribute() throws SAXException JavaDoc {
167         insideAttribute = false;
168         if(!acceptor.onAttribute2( attNamespaceUri, attLocalName,
169             attLocalName /* we don't have QName, so just use the local name */,
170             buf.toString(),
171             this, null, null )) {
172             
173             // either the name was incorrect (which is quite unlikely),
174
// or the value was wrong.
175
// report an error
176
StringRef ref = new StringRef();
177             acceptor.onAttribute2( attNamespaceUri, attLocalName, attLocalName,
178             buf.toString(), this, ref, null );
179             
180             context.reportEvent(target,ref.str);
181         }
182         
183         buf = new StringBuffer JavaDoc();
184     }
185     
186     private void writePendingText() throws SAXException JavaDoc {
187         // assert(textBuf!=null);
188
if(!acceptor.onText2( buf.toString(), this, null, null )) {
189             // this text is invalid.
190
// report an error
191
StringRef ref = new StringRef();
192             acceptor.onText2( buf.toString(), this, ref, null );
193             context.reportEvent(target,ref.str);
194         }
195         
196         if(buf.length()>1024)
197             buf = new StringBuffer JavaDoc();
198         else
199             buf.setLength(0);
200     }
201     
202     private String JavaDoc currentElementUri;
203     private String JavaDoc currentElementLocalName;
204     
205     public void startElement( String JavaDoc uri, String JavaDoc local ) throws SAXException JavaDoc {
206         writePendingText();
207         
208         context.getNamespaceContext().startElement();
209         
210         stack.push(acceptor);
211         
212         StartTagInfo sti = new StartTagInfo(uri,local,local,emptyAttributes,this);
213         
214         // we pass in an empty attributes, as there is just no way for us to
215
// properly re-construct attributes. Fortunately, I know MSV is not using
216
// attribute values, so this would work, but nevertheless this code is
217
// ugly. This is one of the problems of the "middle" approach.
218
Acceptor child = acceptor.createChildAcceptor( sti, null );
219         if( child==null ) {
220             // this element is invalid. probably, so this object is invalid
221
// report an error
222
StringRef ref = new StringRef();
223             child = acceptor.createChildAcceptor( sti, ref );
224             context.reportEvent(target,ref.str);
225         }
226         
227         this.currentElementUri = uri;
228         this.currentElementLocalName = local;
229         
230         acceptor = child;
231     }
232     
233     public void endElement() throws SAXException JavaDoc {
234         writePendingText();
235         
236         if(!acceptor.isAcceptState(null)) {
237             // some required elements are missing
238
// report error
239
StringRef ref = new StringRef();
240             acceptor.isAcceptState(ref);
241             context.reportEvent(target,ref.str);
242         }
243         
244         // pop the acceptor
245
Acceptor child = acceptor;
246         acceptor = (Acceptor)stack.pop();
247         if(!acceptor.stepForward( child, null )) {
248             // some required elements are missing.
249
// report an error
250
StringRef ref = new StringRef();
251             acceptor.stepForward( child, ref ); // force recovery and obtain an error message.
252

253             context.reportEvent(target,ref.str);
254         }
255         
256         context.getNamespaceContext().endElement();
257     }
258     
259     
260     public void childAsAttributes( JAXBObject o, String JavaDoc fieldName ) throws SAXException JavaDoc {
261         // do nothing
262

263         // either the onMarshallableObjectInElement method
264
// or the onMarshallableObjectInAttributeBody method will be
265
// called for every content tree objects.
266
//
267
// so we don't need to validate an object within this method.
268
}
269
270     public void childAsURIs( JAXBObject o, String JavaDoc fieldName ) throws SAXException JavaDoc {
271         // ditto.
272
}
273
274     
275     /** An empty <code>Attributes</code> object. */
276     private static final AttributesImpl JavaDoc emptyAttributes = new AttributesImpl JavaDoc();
277     
278     /** namespace URI of dummy elements. TODO: allocate one namespace URI for this. */
279     public static final String JavaDoc DUMMY_ELEMENT_NS =
280         "http://java.sun.com/jaxb/xjc/dummy-elements";
281
282     public void childAsBody( JAXBObject o, String JavaDoc fieldName ) throws SAXException JavaDoc {
283         //final ValidatableObject vo = Util.toValidatableObject(o);
284
final ValidatableObject vo = jaxbContext.getGrammarInfo().castToValidatableObject(o);
285
286         if(vo==null) {
287             reportMissingObjectError(fieldName);
288             return;
289         }
290         
291         if( insideAttribute ) childAsAttributeBody(vo,fieldName);
292         else childAsElementBody(o,vo);
293     }
294     
295     private void childAsElementBody( Object JavaDoc o, ValidatableObject vo ) throws SAXException JavaDoc {
296         String JavaDoc intfName = vo.getPrimaryInterface().getName();
297         intfName = intfName.replace('$','.');
298         
299         // if the object implements the RIElement interface,
300
// add a marker attribute to the dummy element.
301
//
302
// For example, if the object is org.acme.impl.FooImpl,
303
// the dummy element will look like
304
// <{DUMMY_ELEMENT_NS}org.acme.Foo
305
// {<URI of this element>}:<local name of this element>="" />
306
//
307
// This extra attribute is used to validate wildcards.
308
// AttributesImpl atts;
309
// if(o instanceof RIElement) {
310
// RIElement rie = (RIElement)o;
311
// atts = new AttributesImpl();
312
// atts.addAttribute(
313
// rie.____jaxb_ri____getNamespaceURI(),
314
// rie.____jaxb_ri____getLocalName(),
315
// rie.____jaxb_ri____getLocalName(), // use local name as qname
316
// "CDATA",
317
// ""); // we don't care about the attribute value
318
// } else
319
// atts = emptyAttributes;
320

321         
322         // feed a dummy element to the acceptor.
323
StartTagInfo sti = new StartTagInfo(
324             DUMMY_ELEMENT_NS,
325             intfName,
326             intfName/*just pass the local name as QName.*/,
327             emptyAttributes,
328             this );
329         
330             
331         Acceptor child = acceptor.createChildAcceptor(sti,null);
332         if(child==null) {
333             // some required elements were missing. report errors
334
StringRef ref = new StringRef();
335             child = acceptor.createChildAcceptor(sti,ref);
336             context.reportEvent(target,ref.str);
337         }
338         
339         if(o instanceof RIElement) {
340             RIElement rie = (RIElement)o;
341             if(!child.onAttribute2(
342                 rie.____jaxb_ri____getNamespaceURI(),
343                 rie.____jaxb_ri____getLocalName(),
344                 rie.____jaxb_ri____getLocalName(),
345                 "",
346                 null, null, null ))
347                 
348                 // this object is not a valid member of the wildcard
349
context.reportEvent(target,
350                     Messages.format( Messages.INCORRECT_CHILD_FOR_WILDCARD,
351                         rie.____jaxb_ri____getNamespaceURI(),
352                         rie.____jaxb_ri____getLocalName() ));
353         }
354         
355         child.onEndAttributes(sti,null);
356         
357         
358         if(!acceptor.stepForward(child,null)) {
359             // this can't be possible, as the dummy element was
360
// generated by XJC.
361
throw new JAXBAssertionError();
362         }
363
364         
365         // we need a separate validator instance to validate a child object
366
context.validate(vo);
367         
368     }
369     
370     private void childAsAttributeBody( ValidatableObject vo, String JavaDoc fieldName ) throws SAXException JavaDoc {
371         /*
372         Dirty quick hack. When we split a schema into fragments, basically
373         every chlid object needs a place holder in the fragment
374         (so that the parent schema fragment can correctly validate that the
375         child objects are at their supposed places.)
376         
377         For example, cconsider the following schema:
378         
379         imagine:
380         <class>
381           <attribute>
382             <list>
383               <oneOrMore>
384                 <ref name="bar"/>
385               </oneOrMore>
386             </list>
387           </attribute>
388         </class>
389         
390         In our algorithm, the corresponding schema fragment will be:
391         
392         <class>
393           <attribute>
394             <list>
395               <oneOrMore>
396                 <value>full.class.name.of.BarImpl</value>
397               </oneOrMore>
398             </list>
399           </attribute>
400         </class>
401         
402         If we find a child object inside an attribute
403         (that's why we are in this method BTW),
404         we generate a class name (with a special marker ).
405         */

406         
407         // put a class name with a special marker \u0000. This char is an invalid
408
// XML char, so sensible datatypes should reject this (although many
409
// datatype implementations will accept it in actuality)
410
text("\u0000"+vo.getPrimaryInterface().getName(),fieldName);
411
412         // validate a child object
413
context.validate(vo);
414     }
415
416
417     public void reportError( ValidationEvent e ) throws AbortSerializationException {
418         context.reportEvent(target,e);
419     }
420
421 //
422
//
423
// ID/IDREF validation
424
//
425
//
426
public String JavaDoc onID( IdentifiableObject owner, String JavaDoc value ) throws SAXException JavaDoc {
427         return context.onID(target,value);
428     }
429     public String JavaDoc onIDREF( IdentifiableObject value ) throws SAXException JavaDoc {
430         return context.onIDREF(target,value.____jaxb____getId());
431     }
432
433 //
434
//
435
// ValidationContext implementation. Used by MSV to obtain
436
// contextual information related to validation.
437
//
438
//
439
public String JavaDoc getBaseUri() { return null; }
440     public boolean isUnparsedEntity( String JavaDoc entityName ) {
441         // abandon the validation of ENTITY type.
442
return true;
443     }
444     public boolean isNotation( String JavaDoc notation ) {
445         // abandon the validation of NOTATION type.
446
return true;
447     }
448     public void onID( Datatype dt, StringToken s ) {
449         // ID/IDREF validation will be done by ourselves.
450
// so we will not rely on the validator to perform this check.
451
// because we will use multiple instances of validators, so
452
// they cannot check global consistency.
453

454         // see onID/onIDREF of the ValidationContext.
455
}
456     public String JavaDoc resolveNamespacePrefix( String JavaDoc prefix ) {
457         return context.getNamespaceContext().getNamespaceURI(prefix);
458     }
459     
460 }
461
Popular Tags