package org.ovirt.engine.api.restapi.resource.validation;

import org.jboss.resteasy.plugins.providers.jaxb.AbstractJAXBProvider;
import org.jboss.resteasy.plugins.providers.jaxb.JAXBMarshalException;
import org.ovirt.engine.api.utils.InvalidValueException;

import javax.ws.rs.Consumes;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.Provider;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.ValidationEventHandler;
import javax.xml.bind.helpers.DefaultValidationEventHandler;
import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

@Provider
@Consumes({ MediaType.APPLICATION_XML })
public class XmlMessageBodyReader extends AbstractJAXBProvider<Object> {

    /** Default event handler recognizes XML parsing as error and not as warning */
    private ValidationEventHandler errorhandler = new DefaultValidationEventHandler();

    @Override
    protected boolean isReadWritable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
        return true;
    }

    /**
     * {@inheritDoc}
     * <p>
     * Standard JAXB unmarshaller with custom error handler- {@link #errorhandler}
     */
    @Override
    public Object readFrom(Class<Object> type, Type genericType, Annotation[] annotations, MediaType mediaType,
                           MultivaluedMap<String, String> httpHeaders, InputStream entityStream) throws IOException, WebApplicationException {

        if (entityStream == null) {
            return null;
        }
        try {
            JAXBContext ctx = findJAXBContext(type, annotations, mediaType, true);
            Unmarshaller unmarshaller = ctx.createUnmarshaller();

            AbstractJAXBProvider.decorateUnmarshaller(type, annotations, mediaType, unmarshaller);

            unmarshaller.setEventHandler(errorhandler);
            Object parsedObj = unmarshaller.unmarshal(entityStream);
            if (parsedObj instanceof JAXBElement) {
                return ((JAXBElement) parsedObj).getValue();
            }
            return parsedObj;
        } catch (JAXBException e) {
            if (e.getLinkedException().getCause() instanceof InvalidValueException) {
                throw (InvalidValueException) e.getLinkedException().getCause();
            }
            throw new JAXBMarshalException(e);
        }
    }

}

@@ -2296,16 +2296,24 @@
        %7D
+%0A       
  catch (
@@ -2327,16 +2327,24 @@
 eption e
+xception
 ) %7B%0A    
@@ -2355,45 +2355,171 @@
     
-if (e.getLinkedException().getCause()
+Throwable linked = exception.getLinkedException();%0A            if (linked != null) %7B%0A                Throwable cause = linked.getCause();%0A                if (cause
  ins
@@ -2563,24 +2563,28 @@
             
+    
 throw (Inval
@@ -2605,42 +2605,32 @@
 on) 
-e.getLinkedException().getCause();
+cause;%0A                %7D
 %0A   
@@ -2684,16 +2684,24 @@
 eption(e
+xception
 );%0A     

No NPE when no linked exception