package co.codewizards.cloudstore.core.dto.jaxb;
import static co.codewizards.cloudstore.core.io.StreamUtil.*;
import static co.codewizards.cloudstore.core.util.AssertUtil.*;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import co.codewizards.cloudstore.core.io.ByteArrayInputStream;
import co.codewizards.cloudstore.core.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import co.codewizards.cloudstore.core.io.NoCloseInputStream;
import co.codewizards.cloudstore.core.io.NoCloseOutputStream;
import co.codewizards.cloudstore.core.oio.File;
import co.codewizards.cloudstore.core.util.AssertUtil;
public abstract class DtoIo <D> {
private final Class<D> dtoClass;
private Marshaller marshaller;
private Unmarshaller unmarshaller;
protected DtoIo() {
final ParameterizedType superclass = (ParameterizedType) getClass().getGenericSuperclass();
final Type[] actualTypeArguments = superclass.getActualTypeArguments();
if (actualTypeArguments == null || actualTypeArguments.length < 1)
throw new IllegalStateException("Subclass " + getClass().getName() + " has no generic type argument!");
@SuppressWarnings("unchecked")
final Class<D> c = (Class<D>) actualTypeArguments[0];
this.dtoClass = c;
if (this.dtoClass == null)
throw new IllegalStateException("Subclass " + getClass().getName() + " has no generic type argument!");
}
public byte[] serialize(final D dto) {
final ByteArrayOutputStream out = new ByteArrayOutputStream();
serialize(dto, out);
return out.toByteArray();
}
public void serialize(final D dto, final OutputStream out) {
assertNotNull(dto, "dto");
assertNotNull(out, "out");
try {
getMarshaller().marshal(dto, new NoCloseOutputStream(out));
} catch (final JAXBException e) {
throw new RuntimeException(e);
}
}
public byte[] serializeWithGz(final D dto) {
final ByteArrayOutputStream out = new ByteArrayOutputStream();
serializeWithGz(dto, out);
return out.toByteArray();
}
public void serializeWithGz(final D dto, final OutputStream out) {
assertNotNull(dto, "dto");
assertNotNull(out, "out");
try {
try (GZIPOutputStream gzOut = new GZIPOutputStream(new NoCloseOutputStream(out));) {
getMarshaller().marshal(dto, gzOut);
}
} catch (JAXBException | IOException e) {
throw new RuntimeException(e);
}
}
public void serialize(final D dto, final File file) {
assertNotNull(dto, "dto");
assertNotNull(file, "file");
try {
// Even though https://github.com/cloudstore/cloudstore/issues/31 seems to affect only unmarshal(File),
// we manage the OutputStream ourself, as well.
try (final OutputStream out = new BufferedOutputStream(castStream(file.createOutputStream()))) {
getMarshaller().marshal(dto, out);
}
} catch (JAXBException | IOException e) {
throw new RuntimeException("Writing file '" + file.getAbsolutePath() + "' failed: " + e, e);
}
}
public void serializeWithGz(final D dto, final File file) {
assertNotNull(dto, "dto");
assertNotNull(file, "file");
try {
// Even though https://github.com/cloudstore/cloudstore/issues/31 seems to affect only unmarshal(File),
// we manage the OutputStream ourself, as well.
try (final OutputStream out = new BufferedOutputStream(castStream(file.createOutputStream()))) {
try (GZIPOutputStream gzOut = new GZIPOutputStream(out);) {
getMarshaller().marshal(dto, gzOut);
}
}
} catch (JAXBException | IOException e) {
throw new RuntimeException("Writing file '" + file.getAbsolutePath() + "' failed: " + e, e);
}
}
public D deserialize(final byte[] in) {
assertNotNull(in, "in");
return deserialize(new ByteArrayInputStream(in));
}
public D deserialize(final InputStream in) {
assertNotNull(in, "in");
try {
return dtoClass.cast(getUnmarshaller().unmarshal(new NoCloseInputStream(in)));
} catch (final JAXBException e) {
throw new RuntimeException(e);
}
}
public D deserializeWithGz(final byte[] in) {
assertNotNull(in, "in");
return deserializeWithGz(new ByteArrayInputStream(in));
}
public D deserializeWithGz(final InputStream in) {
assertNotNull(in, "in");
try {
try (GZIPInputStream gzIn = new GZIPInputStream(new NoCloseInputStream(in));) {
return dtoClass.cast(getUnmarshaller().unmarshal(gzIn));
}
} catch (JAXBException | IOException e) {
throw new RuntimeException(e);
}
}
public D deserialize(final File file) {
AssertUtil.assertNotNull(file, "file");
try {
// Because of https://github.com/cloudstore/cloudstore/issues/31 we do not use unmarshal(File), anymore.
try (final InputStream in = new BufferedInputStream(castStream(file.createInputStream()))) {
return dtoClass.cast(getUnmarshaller().unmarshal(in));
}
} catch (JAXBException | IOException e) {
throw new RuntimeException("Reading file '" + file.getAbsolutePath() + "' failed: " + e, e);
}
}
public D deserializeWithGz(final File file) {
AssertUtil.assertNotNull(file, "file");
try {
// Because of https://github.com/cloudstore/cloudstore/issues/31 we do not use unmarshal(File), anymore.
try (final InputStream in = new BufferedInputStream(castStream(file.createInputStream()))) {
try (GZIPInputStream gzIn = new GZIPInputStream(in);) {
return dtoClass.cast(getUnmarshaller().unmarshal(gzIn));
}
}
} catch (JAXBException | IOException e) {
throw new RuntimeException("Reading file '" + file.getAbsolutePath() + "' failed: " + e, e);
}
}
private Marshaller getMarshaller() {
if (marshaller == null) {
try {
marshaller = CloudStoreJaxbContext.getJaxbContext().createMarshaller();
} catch (final JAXBException e) {
throw new RuntimeException(e);
}
}
return marshaller;
}
private Unmarshaller getUnmarshaller() {
if (unmarshaller == null) {
try {
unmarshaller = CloudStoreJaxbContext.getJaxbContext().createUnmarshaller();
} catch (final JAXBException e) {
throw new RuntimeException(e);
}
}
return unmarshaller;
}
}