001package ball.activation;
002/*-
003 * ##########################################################################
004 * Utilities
005 * $Id: JAXBDataSource.java 5285 2020-02-05 04:23:21Z ball $
006 * $HeadURL: svn+ssh://svn.hcf.dev/var/spool/scm/repository.svn/ball-util/trunk/src/main/java/ball/activation/JAXBDataSource.java $
007 * %%
008 * Copyright (C) 2008 - 2020 Allen D. Ball
009 * %%
010 * Licensed under the Apache License, Version 2.0 (the "License");
011 * you may not use this file except in compliance with the License.
012 * You may obtain a copy of the License at
013 *
014 *      http://www.apache.org/licenses/LICENSE-2.0
015 *
016 * Unless required by applicable law or agreed to in writing, software
017 * distributed under the License is distributed on an "AS IS" BASIS,
018 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
019 * See the License for the specific language governing permissions and
020 * limitations under the License.
021 * ##########################################################################
022 */
023import java.io.IOException;
024import java.io.InputStream;
025import java.io.OutputStream;
026import javax.xml.bind.JAXBContext;
027import javax.xml.bind.JAXBException;
028import javax.xml.bind.Marshaller;
029import javax.xml.bind.Unmarshaller;
030
031/**
032 * {@link ReaderWriterDataSource} implementation to provide
033 * {@link Marshaller} marshalling and {@link Unmarshaller} unmarshalling
034 * services.
035 *
036 * @author {@link.uri mailto:ball@hcf.dev Allen D. Ball}
037 * @version $Revision: 5285 $
038 */
039public class JAXBDataSource extends ReaderWriterDataSource {
040
041    /**
042     * Construct and marshal the argument {@link Object}.
043     *
044     * @param   object          The {@link Object} to marshal.
045     */
046    public JAXBDataSource(Object object) {
047        this();
048
049        try {
050            marshal(object);
051        } catch (Exception exception) {
052            throw new ExceptionInInitializerError(exception);
053        }
054    }
055
056    /**
057     * No-argument constructor.
058     */
059    public JAXBDataSource() { super(null, APPLICATION_XML); }
060
061    /**
062     * Marshal the argument {@link Object}.
063     *
064     * @param   object          The {@link Object} to marshal.
065     *
066     * @throws  IOException     If an I/O exception occurs.
067     * @throws  JAXBException   If a JAXB exception occurs.
068     */
069    public void marshal(Object object) throws IOException, JAXBException {
070        marshal(JAXBContext.newInstance(object.getClass()), object);
071    }
072
073    /**
074     * Marshal the argument {@link Object}.
075     *
076     * @param   context         The {@link JAXBContext}.
077     * @param   object          The {@link Object} to marshal.
078     *
079     * @throws  IOException     If an I/O exception occurs.
080     * @throws  JAXBException   If a JAXB exception occurs.
081     */
082    public void marshal(JAXBContext context,
083                        Object object) throws IOException, JAXBException {
084        try (OutputStream out = getOutputStream()) {
085            Marshaller marshaller = context.createMarshaller();
086
087            marshaller.setProperty("jaxb.encoding", getCharset().name());
088            marshaller.setProperty("jaxb.formatted.output", true);
089            marshaller.marshal(object, out);
090        }
091    }
092
093    /**
094     * Unmarshal the argument {@link Object}.
095     *
096     * @param   <T>             The target type.
097     * @param   type            The target {@link Class}.
098     *
099     * @return  The unmarshalled {@link Object}.
100     *
101     * @throws  IOException     If an I/O exception occurs.
102     * @throws  JAXBException   If a JAXB exception occurs.
103     */
104    public <T> T unmarshal(Class<? extends T> type) throws IOException,
105                                                           JAXBException {
106        return unmarshal(JAXBContext.newInstance(type), type);
107    }
108
109    /**
110     * Unmarshal the argument {@link Object}.
111     *
112     * @param   <T>             The target type.
113     * @param   context         The {@link JAXBContext}.
114     * @param   type            The target {@link Class}.
115     *
116     * @return  The unmarshalled {@link Object}.
117     *
118     * @throws  IOException     If an I/O exception occurs.
119     * @throws  JAXBException   If a JAXB exception occurs.
120     */
121    public <T> T unmarshal(JAXBContext context,
122                           Class<? extends T> type) throws IOException,
123                                                           JAXBException {
124        T object = null;
125
126        try (InputStream in = getInputStream()) {
127            Unmarshaller unmarshaller = context.createUnmarshaller();
128
129            object = type.cast(unmarshaller.unmarshal(in));
130        }
131
132        return object;
133    }
134}