001package co.codewizards.cloudstore.core.dto.jaxb; 002 003import static co.codewizards.cloudstore.core.util.Util.*; 004 005import java.io.BufferedInputStream; 006import java.io.BufferedOutputStream; 007import java.io.File; 008import java.io.FileInputStream; 009import java.io.FileOutputStream; 010import java.io.IOException; 011import java.io.InputStream; 012import java.io.OutputStream; 013import java.lang.reflect.ParameterizedType; 014import java.lang.reflect.Type; 015 016import javax.xml.bind.JAXBException; 017import javax.xml.bind.Marshaller; 018import javax.xml.bind.Unmarshaller; 019 020public abstract class DTOIO <D> { 021 022 private final Class<D> dtoClass; 023 024 private Marshaller marshaller; 025 private Unmarshaller unmarshaller; 026 027 protected DTOIO() { 028 ParameterizedType superclass = (ParameterizedType) getClass().getGenericSuperclass(); 029 Type[] actualTypeArguments = superclass.getActualTypeArguments(); 030 if (actualTypeArguments == null || actualTypeArguments.length < 1) 031 throw new IllegalStateException("Subclass " + getClass().getName() + " has no generic type argument!"); 032 033 @SuppressWarnings("unchecked") 034 Class<D> c = (Class<D>) actualTypeArguments[0]; 035 this.dtoClass = c; 036 if (this.dtoClass == null) 037 throw new IllegalStateException("Subclass " + getClass().getName() + " has no generic type argument!"); 038 } 039 040 public void serialize(D dto, OutputStream out) { 041 assertNotNull("dto", dto); 042 assertNotNull("out", out); 043 try { 044 getMarshaller().marshal(dto, out); 045 } catch (JAXBException e) { 046 throw new RuntimeException(e); 047 } 048 } 049 050 public void serialize(final D dto, final File file) { 051 assertNotNull("dto", dto); 052 assertNotNull("file", file); 053 try { 054 // Even though https://github.com/cloudstore/cloudstore/issues/31 seems to affect only unmarshal(File), 055 // we manage the OutputStream ourself, as well. 056 final OutputStream out = new BufferedOutputStream(new FileOutputStream(file)); 057 try { 058 getMarshaller().marshal(dto, out); 059 } finally { 060 out.close(); 061 } 062 } catch (JAXBException | IOException e) { 063 throw new RuntimeException("Writing file '" + file.getAbsolutePath() + "' failed: " + e, e); 064 } 065 } 066 067 public D deserialize(InputStream in) { 068 assertNotNull("in", in); 069 try { 070 return dtoClass.cast(getUnmarshaller().unmarshal(in)); 071 } catch (JAXBException e) { 072 throw new RuntimeException(e); 073 } 074 } 075 076 public D deserialize(final File file) { 077 assertNotNull("file", file); 078 try { 079 // Because of https://github.com/cloudstore/cloudstore/issues/31 we do not use unmarshal(File), anymore. 080 final InputStream in = new BufferedInputStream(new FileInputStream(file)); 081 try { 082 return dtoClass.cast(getUnmarshaller().unmarshal(in)); 083 } finally { 084 in.close(); 085 } 086 } catch (JAXBException | IOException e) { 087 throw new RuntimeException("Reading file '" + file.getAbsolutePath() + "' failed: " + e, e); 088 } 089 } 090 091 private Marshaller getMarshaller() { 092 if (marshaller == null) { 093 try { 094 marshaller = CloudStoreJaxbContext.getJaxbContext().createMarshaller(); 095 } catch (JAXBException e) { 096 throw new RuntimeException(e); 097 } 098 } 099 return marshaller; 100 } 101 102 private Unmarshaller getUnmarshaller() { 103 if (unmarshaller == null) { 104 try { 105 unmarshaller = CloudStoreJaxbContext.getJaxbContext().createUnmarshaller(); 106 } catch (JAXBException e) { 107 throw new RuntimeException(e); 108 } 109 } 110 return unmarshaller; 111 } 112 113}