/* * This file is part of DLect. DLect is a suite of code that facilitates the downloading of lecture recordings. * * Copyright © 2014 Lee Symes. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.dlect.helpers; import com.google.common.collect.ImmutableList; import com.google.common.io.CharStreams; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URI; import java.util.Arrays; import java.util.List; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.ResponseHandler; import org.dlect.log.Stores; /** * * @author lee */ public class JAXBHelper { public static <T> JaxbBindingSet<T> binding(Class<T> returnClass, Class... boundClasses) { return new JaxbBindingSet<>(ImmutableList.<Class<?>>builder().add(returnClass).add(boundClasses).build()); } public static <T> JaxbBindingSet<T> bindingInterface(Class... boundClasses) { return new JaxbBindingSet<>(ImmutableList.<Class<?>>copyOf(boundClasses)); } public static <T> ResponseHandler<T> responseHandlerFor(Class<T> returnClass, Class... boundClasses) { return responseHandlerFor(binding(returnClass, boundClasses)); } public static <T> ResponseHandler<T> responseHandlerFor(final JaxbBindingSet<T> binding) { return new ResponseHandler<T>() { @Override public T handleResponse(HttpResponse response) throws ClientProtocolException, IOException { InputStream c = response.getEntity().getContent(); String str = CharStreams.toString(new InputStreamReader(c)); Stores.LOG.error("XML\n{}", str); try { return unmarshalFromStream(new ByteArrayInputStream(str.getBytes()), binding); } catch (JAXBException ex) { Stores.LOG.error("Headers: {}", Arrays.toString(response.getAllHeaders())); Stores.LOG.error("Targeting: {}", Arrays.toString(binding.getBindings())); Stores.LOG.error("Handle Responce failed", ex); throw new IOException(ex); } } }; } /** * Unmarshal XML data from the specified InputStream and return the * resulting content tree. Validation event location information may be * incomplete when using this form of the unmarshal API. * * <p> * Implements <a href="#unmarshalGlobal">Unmarshal Global Root Element</a>. * * @param stream the InputStream to unmarshal XML data from * @param classesToBind * * @return the newly created root object of the java content tree * * @throws java.io.IOException * @throws JAXBException If any unexpected errors occur while unmarshalling * @throws IllegalArgumentException If the InputStream parameter is null */ public static Object unmarshalFromStream(InputStream stream, Class<?>... classesToBind) throws IOException, JAXBException { try (InputStream s = stream) { String str = CharStreams.toString(new InputStreamReader(s)); stream.close(); Stores.LOG.error("XML\n{}", str); JAXBContext j = JAXBContext.newInstance(classesToBind); return j.createUnmarshaller().unmarshal(new ByteArrayInputStream(str.getBytes())); } } /** * Unmarshal XML data from the specified InputStream and return the * resulting content tree. Validation event location information may be * incomplete when using this form of the unmarshal API. * * <p> * Implements <a href="#unmarshalGlobal">Unmarshal Global Root Element</a>. * * @param <T> * @param stream the InputStream to unmarshal XML data from * @param classToBind * * @return the newly created root object of the java content tree * * @throws IOException * @throws JAXBException If any unexpected errors occur while unmarshalling * @throws IllegalArgumentException If the InputStream parameter is null */ @SuppressWarnings({"unchecked", "rawtypes"}) public static <T> T unmarshalObjectFromStream(InputStream stream, Class<T> classToBind) throws IOException, JAXBException { return (T) unmarshalFromStream(stream, classToBind); } /** * Unmarshal XML data from the specified InputStream and return the * resulting content tree. Validation event location information may be * incomplete when using this form of the unmarshal API. * * <p> * Implements <a href="#unmarshalGlobal">Unmarshal Global Root Element</a>. * * @param <T> * @param stream the InputStream to unmarshal XML data from * @param bindingType * * @return the newly created root object of the java content tree * * @throws IOException * @throws JAXBException If any unexpected errors occur while unmarshalling * @throws IllegalArgumentException If the InputStream parameter is null */ @SuppressWarnings("unchecked") public static <T> T unmarshalFromStream(InputStream stream, JaxbBindingSet<T> bindingType) throws IOException, JAXBException { return (T) unmarshalFromStream(stream, bindingType.getBindings()); } /** * Unmarshal XML data from the specified URI and return the resulting * content tree. * * All further documentation copied from {@link javax.xml.bind.Unmarshaller#unmarshal(org.xml.sax.InputSource) } * * Validation event location information may be incomplete * when using this form of the unmarshal API. * * <p> * Implements <a href="#unmarshalGlobal">Unmarshal Global Root Element</a>. * * @param <T> * @param uri the URI to open a connection to and unmarshal XML data from. * @param bindingType A set of classes that this binding should respond to. * * @return the newly created root object of the java content tree * * @throws JAXBException If any unexpected errors occur while unmarshalling * @throws IOException If there was a problem opening the URI. Also * encompasses {@linkplain java.net.MalformedURLException}. * @throws IllegalArgumentException If the InputStream parameter is null */ @SuppressWarnings("unchecked") public static <T> T unmarshalFromUri(URI uri, JaxbBindingSet<T> bindingType) throws JAXBException, IOException { return (T) unmarshalFromStream(uri.toURL().openStream(), bindingType.getBindings()); } private JAXBHelper() { } public static class JaxbBindingSet<T> { private final List<Class<?>> classes; /** * * @param classes */ public JaxbBindingSet(List<Class<?>> classes) { this.classes = classes; } public Class<?>[] getBindings() { return classes.toArray(new Class<?>[classes.size()]); } } }