You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2011/02/14 13:39:46 UTC

svn commit: r1070471 - in /cxf/trunk/rt/frontend/jaxrs/src: main/java/org/apache/cxf/jaxrs/provider/ test/java/org/apache/cxf/jaxrs/provider/

Author: sergeyb
Date: Mon Feb 14 12:39:46 2011
New Revision: 1070471

URL: http://svn.apache.org/viewvc?rev=1070471&view=rev
Log:
[JAX-RS] Few improvements to SourceProvider and XSLTJaxbProvider

Modified:
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/SourceProvider.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/XSLTJaxbProvider.java
    cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/SourceProviderTest.java
    cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/XSLTJaxbProviderTest.java

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/SourceProvider.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/SourceProvider.java?rev=1070471&r1=1070470&r2=1070471&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/SourceProvider.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/SourceProvider.java Mon Feb 14 12:39:46 2011
@@ -38,19 +38,26 @@ import javax.xml.stream.XMLStreamReader;
 import javax.xml.stream.XMLStreamWriter;
 import javax.xml.transform.Source;
 import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.sax.SAXSource;
 import javax.xml.transform.stream.StreamSource;
 
 import org.w3c.dom.Document;
 
 import org.apache.cxf.jaxrs.ext.xml.XMLSource;
+import org.apache.cxf.jaxrs.utils.HttpUtils;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.phase.PhaseInterceptorChain;
+import org.apache.cxf.staxutils.StaxSource;
 import org.apache.cxf.staxutils.StaxUtils;
 
 @Provider
 @Produces({"application/xml", "application/*+xml", "text/xml" })
 @Consumes({"application/xml", "application/*+xml", "text/xml", "text/html" })
-public class SourceProvider implements 
+public class SourceProvider extends AbstractConfigurableProvider implements 
     MessageBodyReader<Object>, MessageBodyWriter<Source> {
 
+    private static final String PREFERRED_FORMAT = "source-preferred-format";
+    
     public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mt) {
         return Source.class.isAssignableFrom(type);
     }
@@ -64,9 +71,18 @@ public class SourceProvider implements 
     public Object readFrom(Class<Object> source, Type genericType, Annotation[] annotations, MediaType m,  
         MultivaluedMap<String, String> headers, InputStream is) 
         throws IOException {
-        if (DOMSource.class.isAssignableFrom(source) || Document.class.isAssignableFrom(source)) {
+        
+        Class<?> theSource = source;
+        if (theSource == Source.class) {
+            String s = getPreferredSource();
+            if ("sax".equalsIgnoreCase(s) || "cxf.stax".equalsIgnoreCase(s)) {
+                theSource = SAXSource.class;
+            }
+        }
+        
+        if (DOMSource.class.isAssignableFrom(theSource) || Document.class.isAssignableFrom(theSource)) {
             
-            boolean docRequired = Document.class.isAssignableFrom(source);
+            boolean docRequired = Document.class.isAssignableFrom(theSource);
             XMLStreamReader reader = StaxUtils.createXMLStreamReader(is);
             try {
                 Document doc = StaxUtils.read(reader);
@@ -82,10 +98,13 @@ public class SourceProvider implements 
                     //ignore
                 }
             }
-        } else if (StreamSource.class.isAssignableFrom(source)
-                   || Source.class.isAssignableFrom(source)) {
+        } else if (SAXSource.class.isAssignableFrom(theSource)
+                  || StaxSource.class.isAssignableFrom(theSource)) {
+            return new StaxSource(StaxUtils.createXMLStreamReader(is));
+        } else if (StreamSource.class.isAssignableFrom(theSource)
+                   || Source.class.isAssignableFrom(theSource)) {
             return new StreamSource(is);
-        } else if (XMLSource.class.isAssignableFrom(source)) {
+        } else if (XMLSource.class.isAssignableFrom(theSource)) {
             return new XMLSource(is);
         }
         
@@ -93,10 +112,10 @@ public class SourceProvider implements 
     }
 
     public void writeTo(Source source, Class<?> clazz, Type genericType, Annotation[] annotations,  
-        MediaType m, MultivaluedMap<String, Object> headers, OutputStream os)
+        MediaType mt, MultivaluedMap<String, Object> headers, OutputStream os)
         throws IOException {
         
-        String encoding = "utf-8"; //FIXME
+        String encoding = HttpUtils.getSetEncoding(mt, headers, "UTF-8");
         
         XMLStreamReader reader = StaxUtils.createXMLStreamReader(source);
         XMLStreamWriter writer = StaxUtils.createXMLStreamWriter(os, encoding);
@@ -122,4 +141,18 @@ public class SourceProvider implements 
                         MediaType mt) {
         return -1;
     }
+    
+    protected String getPreferredSource() {
+        Message m = getCurrentMessage();
+        if (m != null) {
+            return (String)m.getContextualProperty(PREFERRED_FORMAT);
+        } else {
+            return "sax";
+        }
+    }
+    
+    protected Message getCurrentMessage() {
+        return PhaseInterceptorChain.getCurrentMessage();
+    }
+    
 }

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/XSLTJaxbProvider.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/XSLTJaxbProvider.java?rev=1070471&r1=1070470&r2=1070471&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/XSLTJaxbProvider.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/XSLTJaxbProvider.java Mon Feb 14 12:39:46 2011
@@ -42,6 +42,8 @@ import javax.ws.rs.ext.Provider;
 import javax.xml.bind.JAXBException;
 import javax.xml.bind.Marshaller;
 import javax.xml.bind.Unmarshaller;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
 import javax.xml.transform.Result;
 import javax.xml.transform.Source;
 import javax.xml.transform.Templates;
@@ -59,8 +61,11 @@ import org.xml.sax.InputSource;
 import org.xml.sax.XMLFilter;
 
 import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.io.CachedOutputStream;
 import org.apache.cxf.jaxrs.ext.MessageContext;
 import org.apache.cxf.jaxrs.utils.ResourceUtils;
+import org.apache.cxf.staxutils.StaxSource;
+import org.apache.cxf.staxutils.StaxUtils;
 
 @Produces({"application/xml", "application/*+xml", "text/xml", "text/html" })
 @Consumes({"application/xml", "application/*+xml", "text/xml", "text/html" })
@@ -88,16 +93,40 @@ public class XSLTJaxbProvider extends JA
     private URIResolver uriResolver;
     private String systemId;
     
+    private boolean supportJaxbOnly;
+    
+    public void setSupportJaxbOnly(boolean support) {
+        this.supportJaxbOnly = support;
+    }
+    
     @Override
     public boolean isReadable(Class<?> type, Type genericType, Annotation[] anns, MediaType mt) {
-        return inTemplatesAvailable(mt) && inClassCanBeHandled(type.getName())
-                   && super.isReadable(type, genericType, anns, mt);
+        // JAXB support is required
+        if (!super.isReadable(type, genericType, anns, mt)) {
+            return false;
+        }
+        // if the user has set the list of in classes and a given class 
+        // is in that list then it can only be handled by the template
+        if (inClassCanBeHandled(type.getName())) {
+            return inTemplatesAvailable(mt); 
+        } else {
+            return supportJaxbOnly;
+        }
     }
     
     @Override
     public boolean isWriteable(Class<?> type, Type genericType, Annotation[] anns, MediaType mt) {
-        return outTemplatesAvailable(mt) && outClassCanBeHandled(type.getName()) 
-                   && super.isWriteable(type, genericType, anns, mt);
+        // JAXB support is required
+        if (!super.isReadable(type, genericType, anns, mt)) {
+            return false;
+        }
+        // if the user has set the list of out classes and a given class 
+        // is in that list then it can only be handled by the template
+        if (outClassCanBeHandled(type.getName())) {
+            return outTemplatesAvailable(mt); 
+        } else {
+            return supportJaxbOnly;
+        }
     }
     
     protected boolean inTemplatesAvailable(MediaType mt) {
@@ -114,20 +143,24 @@ public class XSLTJaxbProvider extends JA
     
     protected Templates getInTemplates(MediaType mt) {
         return inTemplates != null ? inTemplates 
-            : inMediaTemplates.get(mt.getType() + "/" + mt.getSubtype());
+            : inMediaTemplates != null ? inMediaTemplates.get(mt.getType() + "/" + mt.getSubtype()) : null;
     }
     
     protected Templates getOutTemplates(MediaType mt) {
         return outTemplates != null ? outTemplates 
-            : outMediaTemplates.get(mt.getType() + "/" + mt.getSubtype());
+            : outMediaTemplates != null ? outMediaTemplates.get(mt.getType() + "/" + mt.getSubtype()) : null;
     }
     
     @Override
     protected Object unmarshalFromInputStream(Unmarshaller unmarshaller, InputStream is, MediaType mt) 
         throws JAXBException {
         try {
-            XMLFilter filter = factory.newXMLFilter(
-                createTemplates(getInTemplates(mt), inParamsMap, inProperties));
+
+            Templates t = createTemplates(getInTemplates(mt), inParamsMap, inProperties);
+            if (t == null && supportJaxbOnly) {
+                return super.unmarshalFromInputStream(unmarshaller, is, mt);
+            }
+            XMLFilter filter = factory.newXMLFilter(t);
             SAXSource source = new SAXSource(filter, new InputSource(is));
             if (systemId != null) {
                 source.setSystemId(systemId);
@@ -139,9 +172,45 @@ public class XSLTJaxbProvider extends JA
         }
     }
     
+    protected Object unmarshalFromReader(Unmarshaller unmarshaller, XMLStreamReader reader, MediaType mt) 
+        throws JAXBException {
+        CachedOutputStream out = new CachedOutputStream();
+        try {
+            XMLStreamWriter writer = StaxUtils.createXMLStreamWriter(out);
+            StaxUtils.copy(new StaxSource(reader), writer);
+            writer.writeEndDocument();
+            writer.flush();
+            writer.close();
+            return unmarshalFromInputStream(unmarshaller, out.getInputStream(), mt);
+        } catch (Exception ex) {
+            throw new WebApplicationException(ex);
+        }
+    }
+    
+    @Override
+    protected void marshalToWriter(Marshaller ms, Object obj, XMLStreamWriter writer, MediaType mt) 
+        throws Exception {
+        CachedOutputStream out = new CachedOutputStream();
+        marshalToOutputStream(ms, obj, out, mt);
+        
+        StaxUtils.copy(new StreamSource(out.getInputStream()), writer);
+        if (getContext() == null) {
+            writer.writeEndDocument();
+            writer.flush();
+            writer.close();
+        }
+    }
+    
     @Override
     protected void marshalToOutputStream(Marshaller ms, Object obj, OutputStream os, MediaType mt)
         throws Exception {
+        
+        Templates t = createTemplates(getOutTemplates(mt), outParamsMap, outProperties);
+        if (t == null && supportJaxbOnly) {
+            super.marshalToOutputStream(ms, obj, os, mt);
+            return;
+        }
+        
         TransformerHandler th = factory.newTransformerHandler(
             createTemplates(getOutTemplates(mt), outParamsMap, outProperties));
         Result result = new StreamResult(os);
@@ -221,8 +290,12 @@ public class XSLTJaxbProvider extends JA
                                       Map<String, Object> configuredParams,
                                       Map<String, String> outProps) {
         if (templates == null) {
-            LOG.severe("No template is available");
-            throw new WebApplicationException(500);
+            if (supportJaxbOnly) {
+                return null;
+            } else {
+                LOG.severe("No template is available");
+                throw new WebApplicationException(500);
+            }
         }
         
         TemplatesImpl templ =  new TemplatesImpl(templates);

Modified: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/SourceProviderTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/SourceProviderTest.java?rev=1070471&r1=1070470&r2=1070471&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/SourceProviderTest.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/SourceProviderTest.java Mon Feb 14 12:39:46 2011
@@ -22,15 +22,22 @@ package org.apache.cxf.jaxrs.provider;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 
+import javax.ws.rs.core.MediaType;
 import javax.ws.rs.ext.MessageBodyReader;
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.transform.Source;
 import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.sax.SAXSource;
 import javax.xml.transform.stream.StreamSource;
 
 import org.w3c.dom.Document;
 
+import org.apache.cxf.jaxrs.impl.MetadataMap;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.message.MessageImpl;
+import org.apache.cxf.staxutils.StaxSource;
+
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -55,22 +62,32 @@ public class SourceProviderTest extends 
 
     @Test
     public void testReadFrom() throws Exception {
-        SourceProvider p = new SourceProvider();
+        SourceProvider p = new TestSourceProvider();
         assertSame(StreamSource.class, verifyRead(p, StreamSource.class).getClass());
         assertSame(StreamSource.class, verifyRead(p, Source.class).getClass());
+        assertSame(StaxSource.class, verifyRead(p, SAXSource.class).getClass());
+        assertSame(StaxSource.class, verifyRead(p, StaxSource.class).getClass());
         assertSame(DOMSource.class, verifyRead(p, DOMSource.class).getClass());
         assertTrue(Document.class.isAssignableFrom(verifyRead(p, Document.class).getClass()));
     }
     
     @Test
+    public void testReadFromWithPreferredFormat() throws Exception {
+        SourceProvider p = new TestSourceProvider("sax");
+        assertSame(StaxSource.class, verifyRead(p, Source.class).getClass());
+    }
+    
+    @Test
     public void testWriteTo() throws Exception {
-        SourceProvider p = new SourceProvider();
+        SourceProvider p = new TestSourceProvider();
         StreamSource s = new StreamSource(new ByteArrayInputStream("<test/>".getBytes()));
         ByteArrayOutputStream os = new ByteArrayOutputStream();
-        p.writeTo(s, null, null, null, null, null, os);
+        p.writeTo(s, null, null, null, MediaType.APPLICATION_XML_TYPE, 
+                  new MetadataMap<String, Object>(), os);
         assertTrue(os.toString().contains("<test/>"));
         os = new ByteArrayOutputStream();
-        p.writeTo(createDomSource(), null, null, null, null, null, os);
+        p.writeTo(createDomSource(), null, null, null, MediaType.APPLICATION_XML_TYPE, 
+                  new MetadataMap<String, Object>(), os);
         assertTrue(os.toString().contains("<test/>"));
     }
     
@@ -87,4 +104,25 @@ public class SourceProviderTest extends 
         builder = factory.newDocumentBuilder();
         return new DOMSource(builder.parse(new ByteArrayInputStream("<test/>".getBytes())));
     }
+    
+    private static class TestSourceProvider extends SourceProvider {
+        
+        private String format;
+        
+        public TestSourceProvider() {
+            
+        }
+        
+        public TestSourceProvider(String format) {
+            this.format = format;    
+        }
+
+        protected Message getCurrentMessage() {
+            Message m = new MessageImpl();
+            if (format != null) {
+                m.put("source-preferred-format", format);
+            }
+            return m;
+        };
+    }
 }

Modified: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/XSLTJaxbProviderTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/XSLTJaxbProviderTest.java?rev=1070471&r1=1070470&r2=1070471&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/XSLTJaxbProviderTest.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/XSLTJaxbProviderTest.java Mon Feb 14 12:39:46 2011
@@ -20,13 +20,21 @@ package org.apache.cxf.jaxrs.provider;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.List;
 
 import javax.ws.rs.core.MediaType;
 import javax.xml.bind.Unmarshaller;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
 
 import org.apache.cxf.jaxrs.impl.MetadataMap;
 import org.apache.cxf.jaxrs.resources.Book;
+import org.apache.cxf.jaxrs.resources.SuperBook;
+import org.apache.cxf.staxutils.StaxUtils;
 
 import org.junit.Assert;
 import org.junit.Test;
@@ -36,6 +44,45 @@ public class XSLTJaxbProviderTest extend
     private static final String TEMPLATE_LOCATION = "classpath:/org/apache/cxf/jaxrs/provider/template.xsl";
     private static final String BOOK_XML = "<Book><id>123</id><name>TheBook</name></Book>";
     
+    
+    @Test
+    public void testIsWriteable() throws Exception {
+        XSLTJaxbProvider provider = new XSLTJaxbProvider();
+        provider.setOutTemplate(TEMPLATE_LOCATION);
+        provider.isWriteable(Book.class, Book.class, null, MediaType.APPLICATION_XML_TYPE);
+    }
+    
+    @Test
+    public void testIsWriteableWithSetClasses() throws Exception {
+        XSLTJaxbProvider provider = new XSLTJaxbProvider();
+        provider.setOutTemplate(TEMPLATE_LOCATION);
+        List<String> names = new ArrayList<String>();
+        names.add(Book.class.getName());
+        provider.setOutClassNames(names);
+        provider.isWriteable(Book.class, Book.class, null, MediaType.APPLICATION_XML_TYPE);
+    }
+    
+    @Test
+    public void testNotWriteableWithSetClasses() throws Exception {
+        XSLTJaxbProvider provider = new XSLTJaxbProvider();
+        provider.setOutTemplate(TEMPLATE_LOCATION);
+        List<String> names = new ArrayList<String>();
+        names.add(Book.class.getName());
+        provider.setOutClassNames(names);
+        provider.isWriteable(SuperBook.class, SuperBook.class, null, MediaType.APPLICATION_XML_TYPE);
+    }
+    
+    @Test
+    public void testIsWriteableWithSetClassesAndJaxbOnly() throws Exception {
+        XSLTJaxbProvider provider = new XSLTJaxbProvider();
+        provider.setSupportJaxbOnly(true);
+        provider.setOutTemplate(TEMPLATE_LOCATION);
+        List<String> names = new ArrayList<String>();
+        names.add(Book.class.getName());
+        provider.setOutClassNames(names);
+        provider.isWriteable(SuperBook.class, SuperBook.class, null, MediaType.APPLICATION_XML_TYPE);
+    }
+    
     @Test
     public void testWrite() throws Exception {
         XSLTJaxbProvider provider = new XSLTJaxbProvider();
@@ -53,6 +100,82 @@ public class XSLTJaxbProviderTest extend
         assertEquals("Transformation is bad", b, b2);
     }
     
+    @Test
+    public void testWriteToStreamWriter() throws Exception {
+        XSLTJaxbProvider provider = new XSLTJaxbProvider() {
+            @Override
+            protected XMLStreamWriter getStreamWriter(Object obj, OutputStream os, MediaType mt) {
+                return StaxUtils.createXMLStreamWriter(os);
+            }
+        };
+        provider.setOutTemplate(TEMPLATE_LOCATION);
+        
+        Book b = new Book();
+        b.setId(123L);
+        b.setName("TheBook");
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        provider.writeTo(b, Book.class, Book.class, b.getClass().getAnnotations(),
+                         MediaType.TEXT_XML_TYPE, new MetadataMap<String, Object>(), bos);
+        Unmarshaller um = provider.getClassContext(Book.class).createUnmarshaller();
+        Book b2 = (Book)um.unmarshal(new StringReader(bos.toString()));
+        b.setName("TheBook2");
+        assertEquals("Transformation is bad", b, b2);
+    }
+    
+    @Test
+    public void testWriteWithoutTemplate() throws Exception {
+        XSLTJaxbProvider provider = new XSLTJaxbProvider();
+        provider.setSupportJaxbOnly(true);
+        
+        Book b = new Book();
+        b.setId(123L);
+        b.setName("TheBook");
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        provider.writeTo(b, Book.class, Book.class, b.getClass().getAnnotations(),
+                         MediaType.TEXT_XML_TYPE, new MetadataMap<String, Object>(), bos);
+        Unmarshaller um = provider.getClassContext(Book.class).createUnmarshaller();
+        Book b2 = (Book)um.unmarshal(new StringReader(bos.toString()));
+        assertEquals(b, b2);
+    }
+    
+    @Test
+    public void testIsReadable() throws Exception {
+        XSLTJaxbProvider provider = new XSLTJaxbProvider();
+        provider.setInTemplate(TEMPLATE_LOCATION);
+        provider.isReadable(Book.class, Book.class, null, MediaType.APPLICATION_XML_TYPE);
+    }
+    
+    @Test
+    public void testIsReadableWithSetClasses() throws Exception {
+        XSLTJaxbProvider provider = new XSLTJaxbProvider();
+        provider.setInTemplate(TEMPLATE_LOCATION);
+        List<String> names = new ArrayList<String>();
+        names.add(Book.class.getName());
+        provider.setInClassNames(names);
+        provider.isReadable(Book.class, Book.class, null, MediaType.APPLICATION_XML_TYPE);
+    }
+    
+    @Test
+    public void testNotReadableWithSetClasses() throws Exception {
+        XSLTJaxbProvider provider = new XSLTJaxbProvider();
+        provider.setInTemplate(TEMPLATE_LOCATION);
+        List<String> names = new ArrayList<String>();
+        names.add(Book.class.getName());
+        provider.setInClassNames(names);
+        provider.isReadable(SuperBook.class, SuperBook.class, null, MediaType.APPLICATION_XML_TYPE);
+    }
+    
+    @Test
+    public void testIsReadableWithSetClassesAndJaxbOnly() throws Exception {
+        XSLTJaxbProvider provider = new XSLTJaxbProvider();
+        provider.setSupportJaxbOnly(true);
+        provider.setInTemplate(TEMPLATE_LOCATION);
+        List<String> names = new ArrayList<String>();
+        names.add(Book.class.getName());
+        provider.setInClassNames(names);
+        provider.isReadable(SuperBook.class, SuperBook.class, null, MediaType.APPLICATION_XML_TYPE);
+    }
+    
     @SuppressWarnings("unchecked")
     @Test
     public void testRead() throws Exception {
@@ -69,6 +192,40 @@ public class XSLTJaxbProviderTest extend
         assertEquals("Transformation is bad", b, b2);
     }
     
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testReadFromStreamReader() throws Exception {
+        XSLTJaxbProvider provider = new XSLTJaxbProvider() {
+            @Override
+            protected XMLStreamReader getStreamReader(InputStream is, Class<?> type, MediaType mt) {
+                return StaxUtils.createXMLStreamReader(is);
+            }
+        };
+        provider.setInTemplate(TEMPLATE_LOCATION);
+        
+        Book b = new Book();
+        b.setId(123L);
+        b.setName("TheBook");
+        Book b2 = (Book)provider.readFrom((Class)Book.class, Book.class, b.getClass().getAnnotations(),
+                          MediaType.TEXT_XML_TYPE, new MetadataMap<String, String>(),
+                          new ByteArrayInputStream(BOOK_XML.getBytes()));
+        b.setName("TheBook2");
+        assertEquals("Transformation is bad", b, b2);
+    }
     
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testReadWithoutTemplate() throws Exception {
+        XSLTJaxbProvider provider = new XSLTJaxbProvider();
+        provider.setSupportJaxbOnly(true);
+        
+        Book b = new Book();
+        b.setId(123L);
+        b.setName("TheBook");
+        Book b2 = (Book)provider.readFrom((Class)Book.class, Book.class, b.getClass().getAnnotations(),
+                          MediaType.TEXT_XML_TYPE, new MetadataMap<String, String>(),
+                          new ByteArrayInputStream(BOOK_XML.getBytes()));
+        assertEquals("Transformation is bad", b, b2);
+    }
     
 }