All Downloads are FREE. Search and download functionalities are using the official Maven repository.

no.digipost.jakarta.xml.bind.JaxbMarshaller Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) Posten Norge AS
 *
 * 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 no.digipost.jakarta.xml.bind;

import no.digipost.xml.parsers.SaxParserProvider;
import no.digipost.xml.transform.sax.SaxInputSources;
import org.w3c.dom.Document;
import org.w3c.dom.Node;

import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.Marshaller;
import jakarta.xml.bind.Unmarshaller;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMResult;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Set;

import static java.nio.charset.StandardCharsets.UTF_8;


public class JaxbMarshaller {

    private final JAXBContext jaxbContext;
    private final MarshallingCustomization marshallingCustomization;
    private final SaxParserProvider saxParserProvider;

    public JaxbMarshaller(MarshallingCustomization marshallingCustomization, Class ... classesToBeBound) {
        this.jaxbContext = JaxbUtils.initContext(classesToBeBound);
        this.marshallingCustomization = marshallingCustomization;
        this.saxParserProvider = SaxParserProvider.createSecuredProvider();
    }

    public JaxbMarshaller(MarshallingCustomization marshallingCustomization, Set> classesToBeBound) {
        this(marshallingCustomization, classesToBeBound.toArray(new Class[classesToBeBound.size()]));
    }

    public JaxbMarshaller(Class ... classesToBeBound) {
        this(MarshallingCustomization.NO_CUSTOMIZATION, classesToBeBound);
    }

    public JaxbMarshaller(Set> classesToBeBound) {
        this(MarshallingCustomization.NO_CUSTOMIZATION, classesToBeBound);
    }


    public String marshalToString(Object object) {
        return marshalToResult(object, xml -> xml.toString(UTF_8.name()));
    }

    public byte[] marshalToBytes(Object object) {
        return marshalToResult(object, ByteArrayOutputStream::toByteArray);
    }

    public Document marshalToDomDocument(Object object) {
        DOMResult domResult = new DOMResult();
        doWithMarshaller(object, (o, marshaller) -> marshaller.marshal(o, domResult));
        return (Document) domResult.getNode();
    }

    public void marshal(Object object, OutputStream outputStream) {
        doWithMarshaller(object, (o, marshaller) -> marshaller.marshal(o, outputStream));
    }


    private  R marshalToResult(Object object, ThrowingFunction outputStreamMapper) {
        try (ByteArrayOutputStream xmlOutputStream = new ByteArrayOutputStream(128)) {
            marshal(object, xmlOutputStream);
            return outputStreamMapper.apply(xmlOutputStream);
        } catch (MarshallingException marshalException) {
            throw marshalException;
        } catch (Exception e) {
            throw MarshallingException.failedMarshal(object, e);
        }
    }

    private  void doWithMarshaller(T object, ThrowingBiConsumer operation) {
        try {
            Marshaller marshaller = jaxbContext.createMarshaller();
            marshallingCustomization.customize(marshaller);
            operation.accept(object, marshaller);
        } catch (Exception e) {
            throw MarshallingException.failedMarshal(object, e);
        }
    }

    public  T unmarshal(InputStream inputStream, Class type) {
        Source xmlSource = saxParserProvider.createSource(SaxInputSources.fromInputStreamPreventClose(inputStream));
        return unmarshal(unmarshaller -> unmarshaller.unmarshal(xmlSource), type);
    }

    public  T unmarshal(byte[] bytes, Class type) {
        return unmarshal(new ByteArrayInputStream(bytes), type);
    }

    public  T unmarshal(Node node, Class type) {
        return unmarshal(unmarshaller -> unmarshaller.unmarshal(node), type);
    }

    private  T unmarshal(ThrowingFunction operation, Class type) {
        try {
            Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
            marshallingCustomization.customize(unmarshaller);
            return type.cast(operation.apply(unmarshaller));
        } catch (Exception e) {
            throw MarshallingException.failedUnmarshal(type, e);
        }
    }


    @FunctionalInterface
    private interface ThrowingFunction {
        R apply(T t) throws Exception;
    }

    @FunctionalInterface
    private interface ThrowingBiConsumer {
        void accept(T t, S s) throws Exception;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy