2626import javax .xml .stream .XMLStreamReader ;
2727import javax .xml .stream .XMLStreamWriter ;
2828
29- import org .castor .mapping .BindingType ;
30- import org .castor .mapping .MappingUnmarshaller ;
3129import org .exolab .castor .mapping .Mapping ;
3230import org .exolab .castor .mapping .MappingException ;
33- import org .exolab .castor .mapping .MappingLoader ;
34- import org .exolab .castor .xml .ClassDescriptorResolverFactory ;
3531import org .exolab .castor .xml .MarshalException ;
3632import org .exolab .castor .xml .Marshaller ;
3733import org .exolab .castor .xml .ResolverException ;
3834import org .exolab .castor .xml .UnmarshalHandler ;
3935import org .exolab .castor .xml .Unmarshaller ;
40- import org .exolab .castor .xml .XMLClassDescriptorResolver ;
36+ import org .exolab .castor .xml .XMLContext ;
4137import org .exolab .castor .xml .XMLException ;
38+ import org .w3c .dom .Node ;
39+ import org .xml .sax .ContentHandler ;
40+ import org .xml .sax .InputSource ;
41+ import org .xml .sax .SAXException ;
42+ import org .xml .sax .XMLReader ;
43+ import org .xml .sax .ext .LexicalHandler ;
44+
4245import org .springframework .beans .factory .InitializingBean ;
4346import org .springframework .core .io .Resource ;
4447import org .springframework .oxm .AbstractMarshaller ;
4548import org .springframework .oxm .XmlMappingException ;
4649import org .springframework .util .ObjectUtils ;
4750import org .springframework .util .StringUtils ;
4851import org .springframework .xml .dom .DomContentHandler ;
52+ import org .springframework .xml .sax .SaxUtils ;
4953import org .springframework .xml .stream .StaxEventContentHandler ;
5054import org .springframework .xml .stream .StaxEventXmlReader ;
5155import org .springframework .xml .stream .StaxStreamContentHandler ;
5256import org .springframework .xml .stream .StaxStreamXmlReader ;
53- import org .w3c .dom .Node ;
54- import org .xml .sax .ContentHandler ;
55- import org .xml .sax .InputSource ;
56- import org .xml .sax .SAXException ;
57- import org .xml .sax .XMLReader ;
58- import org .xml .sax .ext .LexicalHandler ;
5957
6058/**
6159 * Implementation of the <code>Marshaller</code> interface for Castor. By default, Castor does not require any further
@@ -87,7 +85,7 @@ public class CastorMarshaller extends AbstractMarshaller implements Initializing
8785
8886 private Class targetClass ;
8987
90- private XMLClassDescriptorResolver classDescriptorResolver ;
88+ private XMLContext xmlContext ;
9189
9290 private boolean validating = false ;
9391
@@ -192,35 +190,61 @@ else if (targetClass != null) {
192190 }
193191 }
194192 try {
195- classDescriptorResolver = createClassDescriptorResolver (mappingLocations , targetClass );
193+ xmlContext = createXMLContext (mappingLocations , targetClass );
196194 }
197195 catch (MappingException ex ) {
198196 throw new CastorSystemException ("Could not load Castor mapping: " + ex .getMessage (), ex );
199197 }
198+ catch (ResolverException rex ) {
199+ throw new CastorSystemException ("Could not load Castor mapping: " + rex .getMessage (), rex );
200+ }
200201 }
201202
202203 /** Returns <code>true</code> for all classes, i.e. Castor supports arbitrary classes. */
203204 public boolean supports (Class clazz ) {
204- try {
205- return classDescriptorResolver .resolve (clazz ) != null ;
205+ return true ;
206+ }
207+
208+ /**
209+ * Creates the Castor <code>XMLContext</code>. Subclasses can override this to create a custom context.
210+ * <p/>
211+ * The default implementation loads mapping files if defined, and the target class if not defined.
212+ *
213+ * @return the created resolver
214+ * @throws MappingException when the mapping file cannot be loaded
215+ * @throws IOException in case of I/O errors
216+ * @see XMLContext#addMapping(org.exolab.castor.mapping.Mapping)
217+ * @see XMLContext#addClass(Class)
218+ */
219+ protected XMLContext createXMLContext (Resource [] mappingLocations , Class targetClass )
220+ throws MappingException , IOException , ResolverException {
221+ XMLContext context = new XMLContext ();
222+ if (!ObjectUtils .isEmpty (mappingLocations )) {
223+ Mapping mapping = new Mapping ();
224+ for (int i = 0 ; i < mappingLocations .length ; i ++) {
225+ mapping .loadMapping (SaxUtils .createInputSource (mappingLocations [i ]));
226+ context .addMapping (mapping );
227+ }
206228 }
207- catch ( ResolverException e ) {
208- return false ;
229+ if ( targetClass != null ) {
230+ context . addClass ( targetClass ) ;
209231 }
232+ return context ;
210233 }
211234
235+ //
236+ // Marshalling
237+ //
238+
212239 protected final void marshalDomNode (Object graph , Node node ) throws XmlMappingException {
213240 marshalSaxHandlers (graph , new DomContentHandler (node ), null );
214241 }
215242
216243 protected final void marshalSaxHandlers (Object graph , ContentHandler contentHandler , LexicalHandler lexicalHandler )
217244 throws XmlMappingException {
218- try {
219- marshal (graph , new Marshaller (contentHandler ));
220- }
221- catch (IOException ex ) {
222- throw new CastorSystemException ("Could not construct Castor ContentHandler Marshaller" , ex );
223- }
245+ Marshaller marshaller = xmlContext .createMarshaller ();
246+ marshaller .setContentHandler (contentHandler );
247+ marshal (graph , marshaller );
224248 }
225249
226250 protected final void marshalOutputStream (Object graph , OutputStream outputStream )
@@ -229,7 +253,9 @@ protected final void marshalOutputStream(Object graph, OutputStream outputStream
229253 }
230254
231255 protected final void marshalWriter (Object graph , Writer writer ) throws XmlMappingException , IOException {
232- marshal (graph , new Marshaller (writer ));
256+ Marshaller marshaller = xmlContext .createMarshaller ();
257+ marshaller .setWriter (writer );
258+ marshal (graph , marshaller );
233259 }
234260
235261 protected final void marshalXmlEventWriter (Object graph , XMLEventWriter eventWriter ) throws XmlMappingException {
@@ -240,6 +266,30 @@ protected final void marshalXmlStreamWriter(Object graph, XMLStreamWriter stream
240266 marshalSaxHandlers (graph , new StaxStreamContentHandler (streamWriter ), null );
241267 }
242268
269+ private void marshal (Object graph , Marshaller marshaller ) {
270+ try {
271+ customizeMarshaller (marshaller );
272+ marshaller .marshal (graph );
273+ }
274+ catch (XMLException ex ) {
275+ throw convertCastorException (ex , true );
276+ }
277+ }
278+
279+ /**
280+ * Template method that allows for customizing of the given Castor {@link Marshaller}.
281+ * <p/>
282+ * Default implementation invokes {@link Marshaller#setValidation(boolean)} with the property set on this
283+ * marshaller.
284+ */
285+ protected void customizeMarshaller (Marshaller marshaller ) {
286+ marshaller .setValidation (isValidating ());
287+ }
288+
289+ //
290+ // Unmarshalling
291+ //
292+
243293 protected final Object unmarshalDomNode (Node node ) throws XmlMappingException {
244294 try {
245295 return createUnmarshaller ().unmarshal (node );
@@ -301,45 +351,12 @@ protected final Object unmarshalXmlStreamReader(XMLStreamReader streamReader) {
301351 }
302352 }
303353
304- /**
305- * Creates the Castor <code>XMLClassDescriptorResolver</code>. Subclasses can override this to create a custom
306- * resolver.
307- * <p/>
308- * The default implementation loads mapping files if defined, or loads the target class if not defined.
309- *
310- * @return the created resolver
311- * @throws MappingException when the mapping file cannot be loaded
312- * @throws IOException in case of I/O errors
313- */
314- protected XMLClassDescriptorResolver createClassDescriptorResolver (Resource [] mappingLocations , Class targetClass )
315- throws MappingException , IOException {
316- XMLClassDescriptorResolver classDescriptorResolver = (XMLClassDescriptorResolver ) ClassDescriptorResolverFactory
317- .createClassDescriptorResolver (BindingType .XML );
318- if (!ObjectUtils .isEmpty (mappingLocations )) {
319- Mapping mapping = new Mapping ();
320- for (int i = 0 ; i < mappingLocations .length ; i ++) {
321- mapping .loadMapping (new InputSource (mappingLocations [i ].getInputStream ()));
322- }
323- MappingUnmarshaller mappingUnmarshaller = new MappingUnmarshaller ();
324- MappingLoader mappingLoader = mappingUnmarshaller .getMappingLoader (mapping , BindingType .XML );
325- classDescriptorResolver .setMappingLoader (mappingLoader );
326- classDescriptorResolver .setClassLoader (mapping .getClassLoader ());
327- }
328- else if (targetClass != null ) {
329- classDescriptorResolver .setClassLoader (targetClass .getClassLoader ());
330- }
331- return classDescriptorResolver ;
332- }
333-
334354 private Unmarshaller createUnmarshaller () {
335- Unmarshaller unmarshaller = null ;
355+ Unmarshaller unmarshaller = xmlContext . createUnmarshaller () ;
336356 if (targetClass != null ) {
337- unmarshaller = new Unmarshaller (targetClass );
338- }
339- else {
340- unmarshaller = new Unmarshaller ();
357+ unmarshaller .setClass (targetClass );
358+ unmarshaller .setClassLoader (targetClass .getClassLoader ());
341359 }
342- unmarshaller .setResolver (classDescriptorResolver );
343360 customizeUnmarshaller (unmarshaller );
344361 return unmarshaller ;
345362 }
@@ -358,27 +375,6 @@ protected void customizeUnmarshaller(Unmarshaller unmarshaller) {
358375 unmarshaller .setIgnoreExtraElements (getIgnoreExtraElements ());
359376 }
360377
361- private void marshal (Object graph , Marshaller marshaller ) {
362- try {
363- marshaller .setResolver (classDescriptorResolver );
364- customizeMarshaller (marshaller );
365- marshaller .marshal (graph );
366- }
367- catch (XMLException ex ) {
368- throw convertCastorException (ex , true );
369- }
370- }
371-
372- /**
373- * Template method that allows for customizing of the given Castor {@link Marshaller}.
374- * <p/>
375- * Default implementation invokes {@link Marshaller#setValidation(boolean)} with the property set on this
376- * marshaller.
377- */
378- protected void customizeMarshaller (Marshaller marshaller ) {
379- marshaller .setValidation (isValidating ());
380- }
381-
382378 /**
383379 * Converts the given <code>CastorException</code> to an appropriate exception from the
384380 * <code>org.springframework.oxm</code> hierarchy.
0 commit comments