/**
* Copyright 2011-2017 Asakusa Framework Team.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.asakusafw.utils.io;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.NoSuchElementException;
/**
* A {@link Serialization} using the built-in Java serialization facility.
* Clients can inherit this class.
* @param <T> the object type
* @see Serializable
* @since 0.6.0
*/
public class DefaultSerialization<T> implements Serialization<T> {
@Override
public Source<T> createSource(InputStream stream) throws IOException, InterruptedException {
return new ObjectSource<>(createObjectInput(stream));
}
@Override
public Sink<T> createSink(OutputStream stream) throws IOException, InterruptedException {
return new ObjectSink<>(createObjectOutput(stream));
}
/**
* Creates an {@link ObjectInput} object from the {@link InputStream}.
* This implementation returns {@link ObjectInputStream}.
* @param stream the source {@link InputStream}
* @return the {@link ObjectInput} which takes objects from the source
* @throws IOException if failed to create {@link ObjectInput} by I/O error
* @throws InterruptedException if interrupted while preparing {@link ObjectInput}
*/
protected ObjectInput createObjectInput(InputStream stream) throws IOException, InterruptedException {
return new ObjectInputStream(stream);
}
/**
* Creates an {@link ObjectOutput} object from the {@link OutputStream}.
* This implementation returns {@link ObjectOutputStream}.
* @param stream the target {@link OutputStream}
* @return the {@link ObjectOutput} which puts objects into the target
* @throws IOException if failed to create {@link ObjectOutput} by I/O error
* @throws InterruptedException if interrupted while preparing {@link ObjectOutput}
*/
protected ObjectOutput createObjectOutput(OutputStream stream) throws IOException, InterruptedException {
return new ObjectOutputStream(stream);
}
/**
* An {@link ObjectInput} adapter implementation of {@link Source}.
* @param <T> the object type
*/
public static final class ObjectSource<T> implements Source<T> {
private final ObjectInput input;
private boolean prepared = false;
private T next = null;
/**
* Creates a new instance.
* @param input the source {@link ObjectInput}
*/
public ObjectSource(ObjectInput input) {
this.input = input;
}
@Override
public boolean next() throws IOException {
try {
@SuppressWarnings("unchecked")
T object = (T) input.readObject();
prepared = true;
next = object;
return true;
} catch (EOFException e) {
prepared = false;
next = null;
return false;
} catch (ClassNotFoundException e) {
throw new IOException(e);
}
}
@Override
public T get() throws IOException {
if (prepared == false) {
throw new NoSuchElementException();
}
return next;
}
@Override
public void close() throws IOException {
prepared = false;
next = null;
input.close();
}
}
/**
* An {@link ObjectOutput} adapter implementation of {@link Sink}.
* @param <T> the object type
*/
public static final class ObjectSink<T> implements Sink<T> {
private final ObjectOutput output;
/**
* Creates a new instance.
* @param output the target {@link ObjectOutput}.
*/
public ObjectSink(ObjectOutput output) {
this.output = output;
}
@Override
public void put(T object) throws IOException, InterruptedException {
output.writeObject(object);
}
@Override
public void flush() throws IOException {
output.flush();
}
@Override
public void close() throws IOException {
output.close();
}
}
}