1 /**********************************************************************
2 * CastorAdapter.java
3 * created on 11.03.2005 by netseeker
4 * $Source: /cvsroot/ejoe/EJOE/src/de/netseeker/ejoe/adapter/CastorAdapter.java,v $
5 * $Date: 2006/02/04 14:16:49 $
6 * $Revision: 1.4 $
7 *********************************************************************/
8 package de.netseeker.ejoe.adapter;
9
10 import java.io.IOException;
11 import java.io.InputStream;
12 import java.io.InputStreamReader;
13 import java.io.OutputStream;
14 import java.io.OutputStreamWriter;
15 import java.net.URL;
16
17 import org.exolab.castor.mapping.Mapping;
18 import org.exolab.castor.mapping.MappingException;
19 import org.exolab.castor.xml.ClassDescriptorResolver;
20 import org.exolab.castor.xml.MarshalException;
21 import org.exolab.castor.xml.Marshaller;
22 import org.exolab.castor.xml.Unmarshaller;
23 import org.exolab.castor.xml.ValidationException;
24 import org.exolab.castor.xml.util.ClassDescriptorResolverImpl;
25
26 /***
27 * An adapter for (de)serializing objects via the Castor XML library. This
28 * adapter implementation uses the performance hints described in the Castor
29 * Marshalling FAQ, that means it does:
30 * <ul>
31 * <li>reuse the castor mapping repository</li>
32 * <li>cache the class desciptors of already marshalled/unmarshalled objects
33 * </li>
34 * <li>disable validation per default</li>
35 * </ul>
36 * Furthermore it does reuse one Unmarshaller instance.
37 *
38 * @link http://castor.codehaus.org/xml-faq.html#How-can-I-speed-up-marshalling/unmarshalling-performance
39 * @link http://castor.codehaus.org/
40 * @author netseeker
41 */
42 public class CastorAdapter implements SerializeAdapter
43 {
44 private Mapping _mapping;
45
46 private ClassDescriptorResolver _cdr;
47
48 private Unmarshaller _unmarshaller;
49
50 /***
51 * Creates a new instance of this adapter.
52 */
53 public CastorAdapter()
54 {
55 try
56 {
57 initCastor(false);
58 }
59 catch (MappingException e)
60 {
61
62 }
63 }
64
65 /***
66 * Creates a new instance of this adapter. Castor validation is
67 * enabled/disabled according to the given value.
68 *
69 * @param validate
70 * either Castor validation should be enabled or not.
71 */
72 public CastorAdapter(boolean validate)
73 {
74 try
75 {
76 initCastor(validate);
77 }
78 catch (MappingException e)
79 {
80
81 }
82 }
83
84 /***
85 * Creates a new instance of this adapter using the given Castor mapping.
86 *
87 * @param mapping
88 * existing Castor mapping to use
89 * @throws MappingException
90 */
91 public CastorAdapter(Mapping mapping) throws MappingException
92 {
93 _mapping = mapping;
94 initCastor(false);
95 }
96
97 /***
98 * Creates a new instance of this adapter using the Castor mapping loaded
99 * from the given mapping file.
100 *
101 * @param pathToMappingFile
102 * path of the Castor mapping file to use
103 * @throws IOException
104 * @throws MappingException
105 */
106 public CastorAdapter(String pathToMappingFile) throws IOException, MappingException
107 {
108 this();
109 _mapping = new Mapping();
110 _mapping.loadMapping(pathToMappingFile);
111 initCastor(false);
112 }
113
114 /***
115 * Creates a new instance of this adapter using the Castor mapping loaded
116 * from the given mapping file.
117 *
118 * @param pathToMappingFile
119 * path of the Castor mapping file to use
120 * @throws IOException
121 * @throws MappingException
122 */
123 public CastorAdapter(URL pathToMappingFile) throws IOException, MappingException
124 {
125 this();
126 _mapping = new Mapping();
127 _mapping.loadMapping(pathToMappingFile);
128 initCastor(false);
129 }
130
131 /***
132 * Either enables or disables Castors validation feature.
133 *
134 * @param enable
135 */
136 public void setValidation(boolean enable)
137 {
138 _unmarshaller.setValidation(enable);
139 }
140
141 private void initCastor(boolean validate) throws MappingException
142 {
143 _cdr = new ClassDescriptorResolverImpl();
144 if (_mapping != null)
145 {
146 _unmarshaller = new Unmarshaller(_mapping);
147 }
148 else
149 {
150 _unmarshaller = new Unmarshaller();
151 }
152 _unmarshaller.setResolver(_cdr);
153 _unmarshaller.setValidation(validate);
154 }
155
156
157
158
159
160
161 public Object read(InputStream in) throws IOException
162 {
163 Object result = null;
164
165 try
166 {
167 result = _unmarshaller.unmarshal(new InputStreamReader(in));
168 }
169 catch (MarshalException e)
170 {
171 throw new IOException(e.getMessage());
172 }
173 catch (ValidationException e)
174 {
175 throw new IOException(e.getMessage());
176 }
177
178 return result;
179 }
180
181
182
183
184
185
186
187 public void write(Object obj, OutputStream out) throws IOException
188 {
189 Marshaller marshaller = new Marshaller(new OutputStreamWriter(out));
190 try
191 {
192 if (_mapping != null)
193 {
194 marshaller.setMapping(_mapping);
195 }
196 marshaller.setResolver(_cdr);
197 marshaller.setValidation(false);
198 marshaller.setSuppressXSIType(false);
199 marshaller.setUseXSITypeAtRoot(true);
200 marshaller.marshal(obj);
201 }
202 catch (MarshalException e)
203 {
204 throw new IOException(e.getMessage());
205 }
206 catch (MappingException e)
207 {
208 throw new IOException(e.getMessage());
209 }
210 catch (ValidationException e)
211 {
212 throw new IOException(e.getMessage());
213 }
214 }
215
216
217
218
219
220
221 public void handleClassLoaderChange(ClassLoader classLoader)
222 {
223 _unmarshaller.setClassLoader(classLoader);
224 }
225 }