IO.java
001 /*
002  * Java Genetic Algorithm Library (jenetics-3.0.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.adapterFor;
023 import static org.jenetics.internal.util.jaxb.context;
024 import static org.jenetics.internal.util.jaxb.marshal;
025 
026 import java.io.File;
027 import java.io.FileInputStream;
028 import java.io.FileOutputStream;
029 import java.io.IOException;
030 import java.io.InputStream;
031 import java.io.ObjectInputStream;
032 import java.io.ObjectOutputStream;
033 import java.io.OutputStream;
034 import java.nio.file.Path;
035 
036 import javax.xml.bind.Marshaller;
037 import javax.xml.bind.Unmarshaller;
038 import javax.xml.bind.annotation.adapters.XmlAdapter;
039 
040 /**
041  * Class for object serialization. The following example shows how to write and
042  * reload a given population.
043  *
044  * [code]
045  * // Creating result population.
046  * EvolutionResult<DoubleGene, Double> result = stream
047  *     .collect(toBestEvolutionResult());
048  *
049  * // Writing the population to disk.
050  * final File file = new File("population.xml");
051  * IO.jaxb.write(result.getPopulation(), file);
052  *
053  * // Reading the population from disk.
054  * Population<DoubleGene, Double> population =
055  *     (Population<DoubleGene, Double>)IO.jaxb.read(file);
056  * EvolutionStream<DoubleGene, Double> stream = Engine
057  *     .build(ff, gtf)
058  *     .stream(population, 1);
059  * [/code]
060  *
061  @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
062  @since 1.0
063  @version 2.0 &mdash; <em>$Date: 2014-12-28 $</em>
064  */
065 public abstract class IO {
066 
067     protected IO() {
068     }
069 
070     /**
071      * JAXB for <i>XML</i> serialization.
072      */
073     public static final IO jaxb = new IO() {
074 
075         @Override
076         public void write(final Object object, final OutputStream out)
077             throws IOException
078         {
079             try {
080                 final Marshaller marshaller = context().createMarshaller();
081                 marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
082                 marshaller.marshal(marshal(object), out);
083             catch (Exception e) {
084                 throw new IOException(e);
085             }
086         }
087 
088         @Override
089         public <T> T read(final Class<T> type, final InputStream in)
090             throws IOException
091         {
092             try {
093                 final Unmarshaller unmarshaller = context().createUnmarshaller();
094 
095                 //final XMLInputFactory factory = XMLInputFactory.newInstance();
096                 //final XMLStreamReader reader = factory.createXMLStreamReader(in);
097                 //try {
098                     final Object object = unmarshaller.unmarshal(in);
099                     final XmlAdapter<Object, Object> adapter = adapterFor(object);
100                     if (adapter != null) {
101                         return type.cast(adapter.unmarshal(object));
102                     else {
103                         return type.cast(object);
104                     }
105                 //} finally {
106                 //    reader.close();
107                 //}
108             catch (Exception e) {
109                 throw new IOException(e);
110             }
111         }
112     };
113 
114     /**
115      * IO implementation for "native" <i>Java</i> serialization.
116      */
117     public static final IO object = new IO() {
118 
119         @Override
120         public void write(final Object object, final OutputStream out)
121             throws IOException
122         {
123             final ObjectOutputStream oout = new ObjectOutputStream(out);
124             oout.writeObject(object);
125             out.flush();
126         }
127 
128         @Override
129         public <T> T read(final Class<T> type, final InputStream in)
130             throws IOException
131         {
132             final ObjectInputStream oin = new ObjectInputStream(in);
133             try {
134                 return type.cast(oin.readObject());
135             catch (ClassNotFoundException | ClassCastException e) {
136                 throw new IOException(e);
137             }
138         }
139     };
140 
141 
142     /**
143      * Write the (serializable) object to the given path.
144      *
145      @param object the object to serialize.
146      @param path the path to write the object to.
147      @throws NullPointerException if one of the arguments is {@code null}.
148      @throws IOException if the object could not be serialized.
149      */
150     public void write(final Object object, final String path)
151         throws IOException
152     {
153         write(object, new File(path));
154     }
155 
156     /**
157      * Write the (serializable) object to the given path.
158      *
159      @param object the object to serialize.
160      @param path the path to write the object to.
161      @throws NullPointerException if one of the arguments is {@code null}.
162      @throws IOException if the object could not be serialized.
163      */
164     public void write(final Object object, final Path path)
165         throws IOException
166     {
167         write(object, path.toFile());
168     }
169 
170     /**
171      * Write the (serializable) object to the given file.
172      *
173      @param object the object to serialize.
174      @param file the file to write the object to.
175      @throws NullPointerException if one of the arguments is {@code null}.
176      @throws IOException if the object could not be serialized.
177      */
178     public void write(final Object object, final File file)
179         throws IOException
180     {
181         try (final FileOutputStream out = new FileOutputStream(file)) {
182             write(object, out);
183         }
184     }
185 
186     /**
187      * Write the (serializable) object to the given output stream.
188      *
189      @param object the object to serialize.
190      @param out the output stream to write the object to.
191      @throws NullPointerException if one of the arguments is {@code null}.
192      @throws IOException if the object could not be serialized.
193      */
194     public abstract void write(final Object object, final OutputStream out)
195         throws IOException;
196 
197     /**
198      * Reads an object from the given file.
199      *
200      @param <T> the type of the read object
201      @param path the path to read from.
202      @param type the type of the read object.
203      @return the de-serialized object.
204      @throws NullPointerException if the input stream {@code in} is {@code null}.
205      @throws IOException if the object could not be read.
206      */
207     public <T> T read(final Class<T> type, final String path)
208         throws IOException
209     {
210         try (final FileInputStream in = new FileInputStream(new File(path))) {
211             return read(type, in);
212         }
213     }
214 
215     /**
216      * Reads an object from the given file.
217      *
218      @param path the path to read from.
219      @return the de-serialized object.
220      @throws NullPointerException if the input stream {@code in} is {@code null}.
221      @throws IOException if the object could not be read.
222      */
223     public Object read(final String paththrows IOException {
224         return read(Object.class, path);
225     }
226 
227     /**
228      * Reads an object from the given file.
229      *
230      @param <T> the type of the read object
231      @param path the path to read from.
232      @param type the type of the read object.
233      @return the de-serialized object.
234      @throws NullPointerException if the input stream {@code in} is {@code null}.
235      @throws IOException if the object could not be read.
236      */
237     public <T> T read(final Class<T> type, final Path path)
238         throws IOException
239     {
240         try (final FileInputStream in = new FileInputStream(path.toFile())) {
241             return read(type, in);
242         }
243     }
244 
245     /**
246      * Reads an object from the given file.
247      *
248      @param path the path to read from.
249      @return the de-serialized object.
250      @throws NullPointerException if the input stream {@code in} is {@code null}.
251      @throws IOException if the object could not be read.
252      */
253     public Object read(final Path paththrows IOException {
254         return read(Object.class, path);
255     }
256 
257     /**
258      * Reads an object from the given file.
259      *
260      @param <T> the type of the read object
261      @param file the file to read from.
262      @param type the type of the read object.
263      @return the de-serialized object.
264      @throws NullPointerException if the input stream {@code in} is {@code null}.
265      @throws IOException if the object could not be read.
266      */
267     public <T> T read(final Class<T> type, final File file)
268         throws IOException
269     {
270         try (final FileInputStream in = new FileInputStream(file)) {
271             return read(type, in);
272         }
273     }
274 
275     /**
276      * Reads an object from the given file.
277      *
278      @param file the file to read from.
279      @return the de-serialized object.
280      @throws NullPointerException if the input stream {@code in} is {@code null}.
281      @throws IOException if the object could not be read.
282      */
283     public Object read(final File filethrows IOException {
284         return read(Object.class, file);
285     }
286 
287     /**
288      * Reads an object from the given input stream.
289      *
290      @param <T> the type of the read object
291      @param in the input stream to read from.
292      @param type the type of the read object.
293      @return the de-serialized object.
294      @throws NullPointerException if the input stream {@code in} is {@code null}.
295      @throws IOException if the object could not be read.
296      */
297     public abstract <T> T read(final Class<T> type, final InputStream in)
298         throws IOException;
299 
300     /**
301      * Reads an object from the given input stream.
302      *
303      @param in the input stream to read from.
304      @return the de-serialized object.
305      @throws NullPointerException if the input stream {@code in} is {@code null}.
306      @throws IOException if the object could not be read.
307      */
308     public Object read(final InputStream inthrows IOException {
309         return read(Object.class, in);
310     }
311 }