View Javadoc

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  			// can't happen
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  			// can't happen
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 	 * (non-Javadoc)
158 	 *
159 	 * @see de.netseeker.ejoe.adapter.SerializeAdapter#read(java.io.InputStream)
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 	 * (non-Javadoc)
183 	 *
184 	 * @see de.netseeker.ejoe.adapter.SerializeAdapter#write(java.lang.Object,
185 	 *      java.io.OutputStream)
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 	 * (non-Javadoc)
218 	 *
219 	 * @see de.netseeker.ejoe.adapter.SerializeAdapter#handleClassLoaderChange(java.lang.ClassLoader)
220 	 */
221 	public void handleClassLoaderChange(ClassLoader classLoader)
222 	{
223 		_unmarshaller.setClassLoader(classLoader);
224 	}
225 }