Juan Hernandez has uploaded a new change for review.

Change subject: restapi: JAXB provider
......................................................................

restapi: JAXB provider

Currently we use a custom message body reader to parse XML input
documents, and we use the default message body writer to generate XML
documents. This patch converts the custom message body reader into a
provider that acts as both reader and writer. This reduces the number of
JAXB contexts created and will simplify removing some dependencies on
Resteasy.

Change-Id: I5208c9d41ab892f55c85ef095f25648f1a95d8df
Signed-off-by: Juan Hernandez <[email protected]>
---
R 
backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/xml/JAXBProvider.java
M 
backend/manager/modules/restapi/interface/definition/src/main/resources/META-INF/services/javax.ws.rs.ext.Providers
2 files changed, 79 insertions(+), 7 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/89/29789/1

diff --git 
a/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/xml/JAXBMessageBodyReader.java
 
b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/xml/JAXBProvider.java
similarity index 60%
rename from 
backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/xml/JAXBMessageBodyReader.java
rename to 
backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/xml/JAXBProvider.java
index 922f401..376c47a 100644
--- 
a/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/xml/JAXBMessageBodyReader.java
+++ 
b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/xml/JAXBProvider.java
@@ -18,17 +18,23 @@
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.OutputStream;
 import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.lang.reflect.Type;
 import javax.ws.rs.Consumes;
+import javax.ws.rs.Produces;
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.ext.MessageBodyReader;
+import javax.ws.rs.ext.MessageBodyWriter;
 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.Marshaller;
 import javax.xml.bind.Unmarshaller;
 import javax.xml.bind.ValidationEventHandler;
 import javax.xml.stream.XMLInputFactory;
@@ -36,20 +42,28 @@
 import javax.xml.stream.XMLStreamReader;
 
 import org.ovirt.engine.api.model.API;
+import org.ovirt.engine.api.model.ObjectFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * This class is responsible for converting XML documents into model objects. 
Note that it can't be a generic class
- * because if it is then the JAX-RS framework will select other builtin 
classes that are more specific.
+ * This class is responsible for converting XML documents into model objects, 
and the other way around. Note that it
+ * can't be a generic class because if it is then the JAX-RS framework will 
select other builtin classes that are more
+ * specific.
  */
 @Provider
 @Consumes(MediaType.APPLICATION_XML)
-public class JAXBMessageBodyReader implements MessageBodyReader<Object> {
+@Produces(MediaType.APPLICATION_XML)
+public class JAXBProvider implements MessageBodyReader<Object>, 
MessageBodyWriter<Object> {
     /**
      * The logger used by this class.
      */
-    private Logger log = LoggerFactory.getLogger(JAXBMessageBodyReader.class);
+    private Logger log = LoggerFactory.getLogger(JAXBProvider.class);
+
+    /**
+     * The factory used to create JAXB elements.
+     */
+    private ObjectFactory objectFactory;
 
     /**
      * The factory used to create XML document readers.
@@ -66,7 +80,10 @@
      */
     private ValidationEventHandler jaxbHandler = new 
JAXBValidationEventHandler();
 
-    public JAXBMessageBodyReader() {
+    public JAXBProvider() {
+        // Create the object factory:
+        objectFactory = new ObjectFactory();
+
         // Create a factory that will produce XML parsers that ignore entity 
references and DTDs:
         parserFactory = XMLInputFactory.newFactory();
         
parserFactory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, 
false);
@@ -87,8 +104,24 @@
      * {@inheritDoc}
      */
     @Override
-    public boolean isReadable(Class<?> type, Type genericType, Annotation 
annotations[], MediaType mediaType) {
+    public boolean isReadable(Class<?> type, Type genericType, Annotation[] 
annotations, MediaType mediaType) {
         return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isWriteable(Class<?> type, Type genericType, Annotation[] 
annotations, MediaType mediaType) {
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public long getSize(Object o, Class<?> type, Type genericType, 
Annotation[] annotations, MediaType mediaType) {
+        return -1;
     }
 
     /**
@@ -144,4 +177,43 @@
             throw new IOException(exception);
         }
     }
+
+    @Override
+    public void writeTo(Object object, Class<?> type, Type genericType, 
Annotation[] annotations, MediaType mediaType,
+            MultivaluedMap<String, Object> httpHeaders, OutputStream 
entityStream)
+            throws IOException, WebApplicationException {
+        // In order to create the JAXB element that wraps the object we need 
to iterate the object factory and find the
+        // method that creates it:
+        Method factoryMethod = null;
+        for (Method currentMethod : ObjectFactory.class.getDeclaredMethods()) {
+            Class<?>[] parameterTypes = currentMethod.getParameterTypes();
+            if (parameterTypes.length == 1 && parameterTypes[0] == type) {
+                factoryMethod = currentMethod;
+                break;
+            }
+        }
+        if (factoryMethod == null) {
+            throw new IOException("Can't find factory method for type \"" + 
type.getName() + "\".");
+        }
+
+        // Invoke the method to create the JAXB element:
+        JAXBElement<Object> element;
+        try {
+            element = (JAXBElement<Object>) 
factoryMethod.invoke(objectFactory, object);
+        }
+        catch (IllegalAccessException|InvocationTargetException exception) {
+            throw new IOException("Error invoking factory method for type \"" 
+  type.getName() + "\".", exception);
+        }
+
+        // Marshal the element:
+        try {
+            Marshaller marshaller = jaxbContext.createMarshaller();
+            marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
+            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, 
Boolean.TRUE);
+            marshaller.marshal(element, entityStream);
+        }
+        catch (JAXBException exception) {
+            throw new IOException("Can't marshall JAXB element of type \"" + 
type.getName() + "\".", exception);
+        }
+    }
 }
diff --git 
a/backend/manager/modules/restapi/interface/definition/src/main/resources/META-INF/services/javax.ws.rs.ext.Providers
 
b/backend/manager/modules/restapi/interface/definition/src/main/resources/META-INF/services/javax.ws.rs.ext.Providers
index 68c4f63..27d3917 100644
--- 
a/backend/manager/modules/restapi/interface/definition/src/main/resources/META-INF/services/javax.ws.rs.ext.Providers
+++ 
b/backend/manager/modules/restapi/interface/definition/src/main/resources/META-INF/services/javax.ws.rs.ext.Providers
@@ -1,3 +1,3 @@
 org.ovirt.engine.api.resteasy.json.JsonProvider
-org.ovirt.engine.api.xml.JAXBMessageBodyReader
+org.ovirt.engine.api.xml.JAXBProvider
 org.ovirt.engine.api.pdf.FOPMessageBodyWriter


-- 
To view, visit http://gerrit.ovirt.org/29789
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I5208c9d41ab892f55c85ef095f25648f1a95d8df
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Juan Hernandez <[email protected]>
_______________________________________________
Engine-patches mailing list
[email protected]
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to