001 /*
002 * Java Genetic Algorithm Library (jenetics-1.6.0).
003 * Copyright (c) 2007-2014 Franz Wilhelmstötter
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 *
017 * Author:
018 * Franz Wilhelmstötter (franz.wilhelmstoetter@gmx.at)
019 */
020 package org.jenetics.util;
021
022 import static org.jenetics.internal.util.jaxb.CONTEXT;
023 import static org.jenetics.internal.util.jaxb.adapterFor;
024
025 import java.io.File;
026 import java.io.FileInputStream;
027 import java.io.FileOutputStream;
028 import java.io.IOException;
029 import java.io.InputStream;
030 import java.io.ObjectInputStream;
031 import java.io.ObjectOutputStream;
032 import java.io.OutputStream;
033 import java.nio.file.Path;
034
035 import javax.xml.bind.Marshaller;
036 import javax.xml.bind.Unmarshaller;
037 import javax.xml.bind.annotation.adapters.XmlAdapter;
038
039 import javolution.xml.XMLObjectReader;
040 import javolution.xml.XMLObjectWriter;
041 import javolution.xml.stream.XMLStreamException;
042
043
044 /**
045 * Class for object serialization. The following example shows how to write and
046 * reload a given population.
047 *
048 * [code]
049 * // Writing the population to disk.
050 * final File file = new File("population.xml");
051 * IO.jaxb.write(ga.getPopulation(), file);
052 *
053 * // Reading the population from disk.
054 * final Population<Float64Gene,Float64> population =
055 * (Population<Float64Gene, Float64)IO.jaxb.read(file);
056 * ga.setPopulation(population);
057 * [/code]
058 *
059 * @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
060 * @since 1.0
061 * @version 1.6 — <em>$Date: 2014-02-27 $</em>
062 */
063 public abstract class IO {
064
065 protected IO() {
066 }
067
068 /**
069 * IO implementation for <i>XML</i> serialization.
070 *
071 * @deprecated Will be removed when the Javolution is removed. Use the
072 * {@link #jaxb} {@code IO} implementation instead, which is
073 * compatible to the existing XML marshalling.
074 */
075 @Deprecated
076 public static final IO xml = new IO() {
077
078 @Override
079 public void write(final Object object, final OutputStream out)
080 throws IOException
081 {
082 try {
083 final OutputStream nco = new NonClosableOutputStream(out);
084 final XMLObjectWriter writer = XMLObjectWriter.newInstance(nco);
085 writer.setIndentation("\t");
086 try {
087 writer.write(object);
088 writer.flush();
089 } finally {
090 writer.reset();
091 }
092 } catch (XMLStreamException e) {
093 throw new IOException(e);
094 }
095 }
096
097 @Override
098 public <T> T read(final Class<T> type, final InputStream in)
099 throws IOException
100 {
101 try {
102 final InputStream nci = new NonClosableInputStream(in);
103 final XMLObjectReader reader = XMLObjectReader.newInstance(nci);
104 try {
105 return type.cast(reader.read());
106 } finally {
107 reader.reset();
108 }
109 } catch (XMLStreamException e) {
110 throw new IOException(e);
111 }
112 }
113 };
114
115 /**
116 * JAXB for <i>XML</i> serialization. Is compatible to the existing,
117 * deprecated {@link #xml} marshalling.
118 */
119 public static final IO jaxb = new IO() {
120
121 @Override
122 public void write(final Object object, final OutputStream out)
123 throws IOException
124 {
125 try {
126 final Marshaller marshaller = CONTEXT.createMarshaller();
127 marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
128
129 //final XMLOutputFactory factory = XMLOutputFactory.newInstance();
130 //final XMLStreamWriter writer = factory.createXMLStreamWriter(out);
131 //try {
132 final XmlAdapter<Object, Object> adapter = adapterFor(object);
133 if (adapter != null) {
134 marshaller.marshal(adapter.marshal(object), out);
135 } else {
136 marshaller.marshal(object, out);
137 }
138 //} finally {
139 // writer.close();
140 //}
141 } catch (Exception e) {
142 throw new IOException(e);
143 }
144 }
145
146 @Override
147 public <T> T read(final Class<T> type, final InputStream in)
148 throws IOException
149 {
150 try {
151 final Unmarshaller unmarshaller = CONTEXT.createUnmarshaller();
152
153 //final XMLInputFactory factory = XMLInputFactory.newInstance();
154 //final XMLStreamReader reader = factory.createXMLStreamReader(in);
155 //try {
156 final Object object = unmarshaller.unmarshal(in);
157 final XmlAdapter<Object, Object> adapter = adapterFor(object);
158 if (adapter != null) {
159 return type.cast(adapter.unmarshal(object));
160 } else {
161 return type.cast(object);
162 }
163 //} finally {
164 // reader.close();
165 //}
166 } catch (Exception e) {
167 throw new IOException(e);
168 }
169 }
170 };
171
172 /**
173 * IO implementation for "native" <i>Java</i> serialization.
174 */
175 public static final IO object = new IO() {
176
177 @Override
178 public void write(final Object object, final OutputStream out)
179 throws IOException
180 {
181 final ObjectOutputStream oout = new ObjectOutputStream(out);
182 oout.writeObject(object);
183 out.flush();
184 }
185
186 @Override
187 public <T> T read(final Class<T> type, final InputStream in)
188 throws IOException
189 {
190 final ObjectInputStream oin = new ObjectInputStream(in);
191 try {
192 return type.cast(oin.readObject());
193 } catch (ClassNotFoundException | ClassCastException e) {
194 throw new IOException(e);
195 }
196 }
197 };
198
199
200 /**
201 * Write the (serializable) object to the given path.
202 *
203 * @param object the object to serialize.
204 * @param path the path to write the object to.
205 * @throws NullPointerException if one of the arguments is {@code null}.
206 * @throws IOException if the object could not be serialized.
207 */
208 public void write(final Object object, final String path)
209 throws IOException
210 {
211 write(object, new File(path));
212 }
213
214 /**
215 * Write the (serializable) object to the given path.
216 *
217 * @param object the object to serialize.
218 * @param path the path to write the object to.
219 * @throws NullPointerException if one of the arguments is {@code null}.
220 * @throws IOException if the object could not be serialized.
221 */
222 public void write(final Object object, final Path path)
223 throws IOException
224 {
225 write(object, path.toFile());
226 }
227
228 /**
229 * Write the (serializable) object to the given file.
230 *
231 * @param object the object to serialize.
232 * @param file the file to write the object to.
233 * @throws NullPointerException if one of the arguments is {@code null}.
234 * @throws IOException if the object could not be serialized.
235 */
236 public void write(final Object object, final File file)
237 throws IOException
238 {
239 try (final FileOutputStream out = new FileOutputStream(file)) {
240 write(object, out);
241 }
242 }
243
244 /**
245 * Write the (serializable) object to the given output stream.
246 *
247 * @param object the object to serialize.
248 * @param out the output stream to write the object to.
249 * @throws NullPointerException if one of the arguments is {@code null}.
250 * @throws IOException if the object could not be serialized.
251 */
252 public abstract void write(final Object object, final OutputStream out)
253 throws IOException;
254
255 /**
256 * Reads an object from the given file.
257 *
258 * @param path the path to read from.
259 * @param type the type of the read object.
260 * @return the de-serialized object.
261 * @throws NullPointerException if the input stream {@code in} is {@code null}.
262 * @throws IOException if the object could not be read.
263 */
264 public <T> T read(final Class<T> type, final String path)
265 throws IOException
266 {
267 try (final FileInputStream in = new FileInputStream(new File(path))) {
268 return read(type, in);
269 }
270 }
271
272 /**
273 * Reads an object from the given file.
274 *
275 * @param path the path to read from.
276 * @return the de-serialized object.
277 * @throws NullPointerException if the input stream {@code in} is {@code null}.
278 * @throws IOException if the object could not be read.
279 */
280 public Object read(final String path) throws IOException {
281 return read(Object.class, path);
282 }
283
284 /**
285 * Reads an object from the given file.
286 *
287 * @param path the path to read from.
288 * @param type the type of the read object.
289 * @return the de-serialized object.
290 * @throws NullPointerException if the input stream {@code in} is {@code null}.
291 * @throws IOException if the object could not be read.
292 */
293 public <T> T read(final Class<T> type, final Path path)
294 throws IOException
295 {
296 try (final FileInputStream in = new FileInputStream(path.toFile())) {
297 return read(type, in);
298 }
299 }
300
301 /**
302 * Reads an object from the given file.
303 *
304 * @param path the path to read from.
305 * @return the de-serialized object.
306 * @throws NullPointerException if the input stream {@code in} is {@code null}.
307 * @throws IOException if the object could not be read.
308 */
309 public Object read(final Path path) throws IOException {
310 return read(Object.class, path);
311 }
312
313 /**
314 * Reads an object from the given file.
315 *
316 * @param file the file to read from.
317 * @param type the type of the read object.
318 * @return the de-serialized object.
319 * @throws NullPointerException if the input stream {@code in} is {@code null}.
320 * @throws IOException if the object could not be read.
321 */
322 public <T> T read(final Class<T> type, final File file)
323 throws IOException
324 {
325 try (final FileInputStream in = new FileInputStream(file)) {
326 return read(type, in);
327 }
328 }
329
330 /**
331 * Reads an object from the given file.
332 *
333 * @param file the file to read from.
334 * @return the de-serialized object.
335 * @throws NullPointerException if the input stream {@code in} is {@code null}.
336 * @throws IOException if the object could not be read.
337 */
338 public Object read(final File file) throws IOException {
339 return read(Object.class, file);
340 }
341
342 /**
343 * Reads an object from the given input stream.
344 *
345 * @param in the input stream to read from.
346 * @param type the type of the read object.
347 * @return the de-serialized object.
348 * @throws NullPointerException if the input stream {@code in} is {@code null}.
349 * @throws IOException if the object could not be read.
350 */
351 public abstract <T> T read(final Class<T> type, final InputStream in)
352 throws IOException;
353
354 /**
355 * Reads an object from the given input stream.
356 *
357 * @param in the input stream to read from.
358 * @return the de-serialized object.
359 * @throws NullPointerException if the input stream {@code in} is {@code null}.
360 * @throws IOException if the object could not be read.
361 */
362 public Object read(final InputStream in) throws IOException {
363 return read(Object.class, in);
364 }
365
366
367 /**
368 * @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
369 * @version 1.0 — <em>$Date: 2014-02-27 $</em>
370 */
371 private static final class NonClosableOutputStream extends OutputStream {
372 private final OutputStream _adoptee;
373
374 public NonClosableOutputStream(final OutputStream adoptee) {
375 _adoptee = adoptee;
376 }
377
378 @Override
379 public void close() throws IOException {
380 //Ignore close call.
381 _adoptee.flush();
382 }
383
384 @Override
385 public void flush() throws IOException {
386 _adoptee.flush();
387 }
388
389 @Override
390 public String toString() {
391 return _adoptee.toString();
392 }
393
394 @Override
395 public void write(byte[] b, int off, int len) throws IOException {
396 _adoptee.write(b, off, len);
397 }
398
399 @Override
400 public void write(byte[] b) throws IOException {
401 _adoptee.write(b);
402 }
403
404 @Override
405 public void write(int b) throws IOException {
406 _adoptee.write(b);
407 }
408
409 }
410
411 /**
412 * @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
413 * @version 1.0 — <em>$Date: 2014-02-27 $</em>
414 */
415 private static final class NonClosableInputStream extends InputStream {
416 private final InputStream _adoptee;
417
418 public NonClosableInputStream(final InputStream adoptee) {
419 _adoptee = adoptee;
420 }
421
422 @Override
423 public int available() throws IOException {
424 return _adoptee.available();
425 }
426
427 @Override
428 public void close() throws IOException {
429 }
430
431 @Override
432 public void mark(int readlimit) {
433 _adoptee.mark(readlimit);
434 }
435
436 @Override
437 public boolean markSupported() {
438 return _adoptee.markSupported();
439 }
440
441 @Override
442 public int read() throws IOException {
443 return _adoptee.read();
444 }
445
446 @Override
447 public int read(byte[] b, int off, int len) throws IOException {
448 return _adoptee.read(b, off, len);
449 }
450
451 @Override
452 public int read(byte[] b) throws IOException {
453 return _adoptee.read(b);
454 }
455
456 @Override
457 public void reset() throws IOException {
458 _adoptee.reset();
459 }
460
461 @Override
462 public long skip(long n) throws IOException {
463 return _adoptee.skip(n);
464 }
465 }
466
467 }
|