001package co.codewizards.cloudstore.core.dto.jaxb; 002 003import static co.codewizards.cloudstore.core.io.StreamUtil.*; 004import static co.codewizards.cloudstore.core.util.AssertUtil.*; 005 006import java.io.BufferedInputStream; 007import java.io.BufferedOutputStream; 008import co.codewizards.cloudstore.core.io.ByteArrayInputStream; 009import co.codewizards.cloudstore.core.io.ByteArrayOutputStream; 010import java.io.IOException; 011import java.io.InputStream; 012import java.io.OutputStream; 013import java.lang.reflect.ParameterizedType; 014import java.lang.reflect.Type; 015import java.util.zip.GZIPInputStream; 016import java.util.zip.GZIPOutputStream; 017 018import javax.xml.bind.JAXBException; 019import javax.xml.bind.Marshaller; 020import javax.xml.bind.Unmarshaller; 021 022import co.codewizards.cloudstore.core.io.NoCloseInputStream; 023import co.codewizards.cloudstore.core.io.NoCloseOutputStream; 024import co.codewizards.cloudstore.core.oio.File; 025import co.codewizards.cloudstore.core.util.AssertUtil; 026 027public abstract class DtoIo <D> { 028 029 private final Class<D> dtoClass; 030 031 private Marshaller marshaller; 032 private Unmarshaller unmarshaller; 033 034 protected DtoIo() { 035 final ParameterizedType superclass = (ParameterizedType) getClass().getGenericSuperclass(); 036 final Type[] actualTypeArguments = superclass.getActualTypeArguments(); 037 if (actualTypeArguments == null || actualTypeArguments.length < 1) 038 throw new IllegalStateException("Subclass " + getClass().getName() + " has no generic type argument!"); 039 040 @SuppressWarnings("unchecked") 041 final Class<D> c = (Class<D>) actualTypeArguments[0]; 042 this.dtoClass = c; 043 if (this.dtoClass == null) 044 throw new IllegalStateException("Subclass " + getClass().getName() + " has no generic type argument!"); 045 } 046 047 public byte[] serialize(final D dto) { 048 final ByteArrayOutputStream out = new ByteArrayOutputStream(); 049 serialize(dto, out); 050 return out.toByteArray(); 051 } 052 053 public void serialize(final D dto, final OutputStream out) { 054 assertNotNull(dto, "dto"); 055 assertNotNull(out, "out"); 056 try { 057 getMarshaller().marshal(dto, new NoCloseOutputStream(out)); 058 } catch (final JAXBException e) { 059 throw new RuntimeException(e); 060 } 061 } 062 063 public byte[] serializeWithGz(final D dto) { 064 final ByteArrayOutputStream out = new ByteArrayOutputStream(); 065 serializeWithGz(dto, out); 066 return out.toByteArray(); 067 } 068 069 public void serializeWithGz(final D dto, final OutputStream out) { 070 assertNotNull(dto, "dto"); 071 assertNotNull(out, "out"); 072 try { 073 try (GZIPOutputStream gzOut = new GZIPOutputStream(new NoCloseOutputStream(out));) { 074 getMarshaller().marshal(dto, gzOut); 075 } 076 } catch (JAXBException | IOException e) { 077 throw new RuntimeException(e); 078 } 079 } 080 081 public void serialize(final D dto, final File file) { 082 assertNotNull(dto, "dto"); 083 assertNotNull(file, "file"); 084 try { 085 // Even though https://github.com/cloudstore/cloudstore/issues/31 seems to affect only unmarshal(File), 086 // we manage the OutputStream ourself, as well. 087 try (final OutputStream out = new BufferedOutputStream(castStream(file.createOutputStream()))) { 088 getMarshaller().marshal(dto, out); 089 } 090 } catch (JAXBException | IOException e) { 091 throw new RuntimeException("Writing file '" + file.getAbsolutePath() + "' failed: " + e, e); 092 } 093 } 094 095 public void serializeWithGz(final D dto, final File file) { 096 assertNotNull(dto, "dto"); 097 assertNotNull(file, "file"); 098 try { 099 // Even though https://github.com/cloudstore/cloudstore/issues/31 seems to affect only unmarshal(File), 100 // we manage the OutputStream ourself, as well. 101 try (final OutputStream out = new BufferedOutputStream(castStream(file.createOutputStream()))) { 102 try (GZIPOutputStream gzOut = new GZIPOutputStream(out);) { 103 getMarshaller().marshal(dto, gzOut); 104 } 105 } 106 } catch (JAXBException | IOException e) { 107 throw new RuntimeException("Writing file '" + file.getAbsolutePath() + "' failed: " + e, e); 108 } 109 } 110 111 public D deserialize(final byte[] in) { 112 assertNotNull(in, "in"); 113 return deserialize(new ByteArrayInputStream(in)); 114 } 115 116 public D deserialize(final InputStream in) { 117 assertNotNull(in, "in"); 118 try { 119 return dtoClass.cast(getUnmarshaller().unmarshal(new NoCloseInputStream(in))); 120 } catch (final JAXBException e) { 121 throw new RuntimeException(e); 122 } 123 } 124 125 public D deserializeWithGz(final byte[] in) { 126 assertNotNull(in, "in"); 127 return deserializeWithGz(new ByteArrayInputStream(in)); 128 } 129 130 public D deserializeWithGz(final InputStream in) { 131 assertNotNull(in, "in"); 132 try { 133 try (GZIPInputStream gzIn = new GZIPInputStream(new NoCloseInputStream(in));) { 134 return dtoClass.cast(getUnmarshaller().unmarshal(gzIn)); 135 } 136 } catch (JAXBException | IOException e) { 137 throw new RuntimeException(e); 138 } 139 } 140 141 public D deserialize(final File file) { 142 AssertUtil.assertNotNull(file, "file"); 143 try { 144 // Because of https://github.com/cloudstore/cloudstore/issues/31 we do not use unmarshal(File), anymore. 145 try (final InputStream in = new BufferedInputStream(castStream(file.createInputStream()))) { 146 return dtoClass.cast(getUnmarshaller().unmarshal(in)); 147 } 148 } catch (JAXBException | IOException e) { 149 throw new RuntimeException("Reading file '" + file.getAbsolutePath() + "' failed: " + e, e); 150 } 151 } 152 153 public D deserializeWithGz(final File file) { 154 AssertUtil.assertNotNull(file, "file"); 155 try { 156 // Because of https://github.com/cloudstore/cloudstore/issues/31 we do not use unmarshal(File), anymore. 157 try (final InputStream in = new BufferedInputStream(castStream(file.createInputStream()))) { 158 try (GZIPInputStream gzIn = new GZIPInputStream(in);) { 159 return dtoClass.cast(getUnmarshaller().unmarshal(gzIn)); 160 } 161 } 162 } catch (JAXBException | IOException e) { 163 throw new RuntimeException("Reading file '" + file.getAbsolutePath() + "' failed: " + e, e); 164 } 165 } 166 167 private Marshaller getMarshaller() { 168 if (marshaller == null) { 169 try { 170 marshaller = CloudStoreJaxbContext.getJaxbContext().createMarshaller(); 171 } catch (final JAXBException e) { 172 throw new RuntimeException(e); 173 } 174 } 175 return marshaller; 176 } 177 178 private Unmarshaller getUnmarshaller() { 179 if (unmarshaller == null) { 180 try { 181 unmarshaller = CloudStoreJaxbContext.getJaxbContext().createUnmarshaller(); 182 } catch (final JAXBException e) { 183 throw new RuntimeException(e); 184 } 185 } 186 return unmarshaller; 187 } 188}