cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From r...@apache.org
Subject git commit: CXF-5413: Support Java API for JSON Processing
Date Wed, 30 Apr 2014 16:51:25 GMT
Repository: cxf
Updated Branches:
  refs/heads/master bf6da99ae -> 2156bf58d


CXF-5413: Support Java API for JSON Processing


Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/2156bf58
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/2156bf58
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/2156bf58

Branch: refs/heads/master
Commit: 2156bf58d496383900cd964933f09379cf4f8b7a
Parents: bf6da99
Author: reta <drreta@gmail.com>
Authored: Wed Apr 30 12:51:01 2014 -0400
Committer: reta <drreta@gmail.com>
Committed: Wed Apr 30 12:51:01 2014 -0400

----------------------------------------------------------------------
 parent/pom.xml                                  |  14 ++
 rt/rs/extensions/providers/pom.xml              |  10 +
 .../provider/jsr353/JsonJsr353Provider.java     | 111 +++++++++++
 .../provider/jsr353/JsonJsr353ProviderTest.java | 189 ++++++++++++++++++
 systests/jaxrs/pom.xml                          |   8 +
 .../apache/cxf/systest/jaxrs/provider/Book.java |  62 ++++++
 .../cxf/systest/jaxrs/provider/BookChapter.java |  48 +++++
 .../systest/jaxrs/provider/BookJsonStore.java   | 127 ++++++++++++
 .../jaxrs/provider/JsonJsr353ProviderTest.java  | 192 +++++++++++++++++++
 9 files changed, 761 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/2156bf58/parent/pom.xml
----------------------------------------------------------------------
diff --git a/parent/pom.xml b/parent/pom.xml
index f980366..e219105 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -160,9 +160,11 @@
         <cxf.xpp3.bundle.version>1.1.4c_6</cxf.xpp3.bundle.version>
         <cxf.validation.api.version>1.1.0.Final</cxf.validation.api.version>
         <cxf.cdi.api.version>1.1</cxf.cdi.api.version>
+        <cxf.json.api.version>1.0</cxf.json.api.version>
         <cxf.jboss.weld.version>2.1.2.Final</cxf.jboss.weld.version>
         <cxf.osgi.validation.api.version>1.1.0</cxf.osgi.validation.api.version>
         <cxf.hibernate.validator.version>5.0.2.Final</cxf.hibernate.validator.version>
+        <cxf.glassfish.json.version>1.0.4</cxf.glassfish.json.version>
         <cxf.javax.el.version>3.0.0</cxf.javax.el.version>
         <cxf.hibernate-validator.bundle.version>5.0.2.Final_1</cxf.hibernate-validator.bundle.version>

         <!-- various OSGi related versions -->
@@ -831,6 +833,18 @@
                 <artifactId>cdi-api</artifactId>
                 <version>${cxf.cdi.api.version}</version>
                 <optional>true</optional>
+            </dependency>  
+            <dependency>
+                <groupId>javax.json</groupId>
+                <artifactId>javax.json-api</artifactId>
+                <version>${cxf.json.api.version}</version>
+                <optional>true</optional>
+            </dependency>          
+            <dependency>
+                <groupId>org.glassfish</groupId>
+                <artifactId>javax.json</artifactId>
+                <version>${cxf.glassfish.json.version}</version>
+                <optional>true</optional>
             </dependency>            
             <dependency>
                 <groupId>org.slf4j</groupId>

http://git-wip-us.apache.org/repos/asf/cxf/blob/2156bf58/rt/rs/extensions/providers/pom.xml
----------------------------------------------------------------------
diff --git a/rt/rs/extensions/providers/pom.xml b/rt/rs/extensions/providers/pom.xml
index cfa5df7..c1feea8 100644
--- a/rt/rs/extensions/providers/pom.xml
+++ b/rt/rs/extensions/providers/pom.xml
@@ -103,6 +103,16 @@
             <optional>true</optional>
         </dependency>
         <dependency>
+            <groupId>javax.json</groupId>
+            <artifactId>javax.json-api</artifactId>
+            <optional>true</optional>
+        </dependency>          
+        <dependency>
+            <groupId>org.glassfish</groupId>
+            <artifactId>javax.json</artifactId>
+            <optional>true</optional>
+        </dependency>     
+        <dependency>
             <groupId>org.apache.cxf</groupId>
             <artifactId>cxf-rt-bindings-soap</artifactId>
             <version>${project.version}</version>

http://git-wip-us.apache.org/repos/asf/cxf/blob/2156bf58/rt/rs/extensions/providers/src/main/java/org/apache/cxf/jaxrs/provider/jsr353/JsonJsr353Provider.java
----------------------------------------------------------------------
diff --git a/rt/rs/extensions/providers/src/main/java/org/apache/cxf/jaxrs/provider/jsr353/JsonJsr353Provider.java
b/rt/rs/extensions/providers/src/main/java/org/apache/cxf/jaxrs/provider/jsr353/JsonJsr353Provider.java
new file mode 100644
index 0000000..26ef3ed
--- /dev/null
+++ b/rt/rs/extensions/providers/src/main/java/org/apache/cxf/jaxrs/provider/jsr353/JsonJsr353Provider.java
@@ -0,0 +1,111 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.cxf.jaxrs.provider.jsr353;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonException;
+import javax.json.JsonObject;
+import javax.json.JsonReader;
+import javax.json.JsonStructure;
+import javax.json.JsonWriter;
+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 org.apache.cxf.jaxrs.utils.ExceptionUtils;
+
+@Produces({"application/json", "application/*+json" })
+@Consumes({"application/json", "application/*+json" })
+@Provider
+public class JsonJsr353Provider implements MessageBodyReader<JsonStructure>, MessageBodyWriter<JsonStructure>
{
+    @Override
+    public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations,
MediaType mediaType) {
+        return JsonStructure.class.isAssignableFrom(type) 
+                || JsonObject.class.isAssignableFrom(type) 
+                || JsonArray.class.isAssignableFrom(type);
+    }
+
+    @Override
+    public long getSize(JsonStructure t, Class<?> type, Type genericType, Annotation[]
annotations, 
+        MediaType mediaType) {
+        
+        return -1;
+    }
+
+    @Override
+    public void writeTo(JsonStructure t, Class<?> type, Type genericType, Annotation[]
annotations, 
+        MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream
entityStream) 
+        throws IOException, WebApplicationException {
+        
+        if (entityStream == null) {
+            throw new IOException("Initialized OutputStream should be provided");
+        }
+        
+        JsonWriter writer = null;
+        try {
+            writer = Json.createWriter(entityStream);
+            writer.write(t);
+        } finally {
+            if (writer != null) {
+                writer.close();
+            }
+        }
+    }
+
+    @Override
+    public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations,
MediaType mediaType) {
+        return JsonStructure.class.isAssignableFrom(type) 
+                || JsonObject.class.isAssignableFrom(type) 
+                || JsonArray.class.isAssignableFrom(type);
+    }
+
+    @Override
+    public JsonStructure readFrom(Class<JsonStructure> type, Type genericType, Annotation[]
annotations, 
+        MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream
entityStream)
+        throws IOException, WebApplicationException {
+        
+        if (entityStream == null) {
+            throw new IOException("Initialized InputStream should be provided");
+        }
+
+        JsonReader reader = null;
+        try {
+            reader = Json.createReader(entityStream);
+            return reader.read();
+        } catch (JsonException ex) {
+            throw ExceptionUtils.toBadRequestException(ex, null);
+        } finally {
+            if (reader != null) {
+                reader.close();
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/2156bf58/rt/rs/extensions/providers/src/test/java/org/apache/cxf/jaxrs/provider/jsr353/JsonJsr353ProviderTest.java
----------------------------------------------------------------------
diff --git a/rt/rs/extensions/providers/src/test/java/org/apache/cxf/jaxrs/provider/jsr353/JsonJsr353ProviderTest.java
b/rt/rs/extensions/providers/src/test/java/org/apache/cxf/jaxrs/provider/jsr353/JsonJsr353ProviderTest.java
new file mode 100644
index 0000000..355e33b
--- /dev/null
+++ b/rt/rs/extensions/providers/src/test/java/org/apache/cxf/jaxrs/provider/jsr353/JsonJsr353ProviderTest.java
@@ -0,0 +1,189 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.cxf.jaxrs.provider.jsr353;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.StringWriter;
+
+import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonObject;
+import javax.json.JsonStructure;
+import javax.json.JsonValue;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Response;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.instanceOf;
+
+public class JsonJsr353ProviderTest extends Assert {
+    private JsonJsr353Provider provider;
+    
+    @Before
+    public void setUp() {
+        provider = new JsonJsr353Provider();
+    }
+    
+    @Test(expected = IOException.class)
+    public void testReadWithNullStream() throws Exception {
+        provider.readFrom(JsonStructure.class, null, null, null, null, null);
+    }
+    
+    @Test
+    public void testGetSizeReturnsMinusOne() throws Exception {
+        assertThat(provider.getSize(null, JsonStructure.class, null, null, null),
+            equalTo(-1L));
+    }
+
+    @Test
+    public void testReadableTypes() throws Exception {
+        assertThat(provider.isReadable(JsonArray.class, null, null, null), 
+            equalTo(true));
+        assertThat(provider.isReadable(JsonStructure.class, null, null, null), 
+            equalTo(true));
+        assertThat(provider.isReadable(JsonObject.class, null, null, null), 
+            equalTo(true));
+        assertThat(provider.isReadable(JsonValue.class, null, null, null), 
+            equalTo(false));        
+    }
+
+    @Test
+    public void testWritableTypes() throws Exception {
+        assertThat(provider.isWriteable(JsonArray.class, null, null, null), 
+            equalTo(true));
+        assertThat(provider.isWriteable(JsonStructure.class, null, null, null), 
+            equalTo(true));
+        assertThat(provider.isWriteable(JsonObject.class, null, null, null), 
+            equalTo(true));
+        assertThat(provider.isWriteable(JsonValue.class, null, null, null), 
+            equalTo(false));        
+    }
+    
+    @Test(expected = IOException.class)
+    public void testWriteWithNullStream() throws Exception {
+        final JsonObject obj = Json.createObjectBuilder()
+            .add("firstName", "Tom")
+            .add("lastName", "Tommyknocker")
+            .build();
+        
+        provider.writeTo(obj, JsonObject.class, null, null, null, null, null);
+    }
+    
+    @Test
+    public void testReadMalformedJson() throws Exception {
+        byte[] bytes = "junk".getBytes();
+         
+        try {
+            provider.readFrom(JsonStructure.class, null, null, null, null, 
+                new ByteArrayInputStream(bytes));
+            fail("400 BAD REQUEST is expected");
+        } catch (WebApplicationException ex) {
+            assertThat(ex.getResponse().getStatus(), 
+                equalTo(Response.Status.BAD_REQUEST.getStatusCode()));
+        }
+    }
+    
+    @Test
+    public void testReadJsonObject() throws Exception {
+        final StringWriter writer = new StringWriter();
+        
+        Json.createGenerator(writer)
+            .writeStartObject()
+            .write("firstName", "Tom")
+            .write("lastName", "Tommyknocker")
+            .writeEnd()
+            .close();
+        
+        final String str = writer.toString();
+        writer.close();
+        
+        final JsonStructure obj = provider.readFrom(JsonStructure.class, null, null, null,
null, 
+            new ByteArrayInputStream(str.getBytes()));
+        
+        assertThat(obj, instanceOf(JsonObject.class));
+        assertThat(((JsonObject)obj).getString("firstName"), equalTo("Tom"));
+        assertThat(((JsonObject)obj).getString("lastName"), equalTo("Tommyknocker"));
+    }
+    
+    @Test
+    public void testReadJsonArray() throws Exception {
+        final StringWriter writer = new StringWriter();
+        
+        Json.createGenerator(writer)
+            .writeStartArray()
+            .write("Tom")
+            .write("Tommyknocker")
+            .writeEnd()
+            .close();
+        
+        final JsonStructure obj = provider.readFrom(JsonStructure.class, null, null, null,
null, 
+            new ByteArrayInputStream(writer.toString().getBytes()));
+        
+        assertThat(obj, instanceOf(JsonArray.class));
+        assertThat(((JsonArray)obj).getString(0), equalTo("Tom"));
+        assertThat(((JsonArray)obj).getString(1), equalTo("Tommyknocker"));
+        assertThat(((JsonArray)obj).size(), equalTo(2));
+    }
+    
+    @Test
+    public void testWriteJsonObject() throws Exception {        
+        final JsonObject obj = Json.createObjectBuilder()
+            .add("firstName", "Tom")
+            .add("lastName", "Tommyknocker")
+            .build();              
+        
+        final ByteArrayOutputStream out = new ByteArrayOutputStream();
+        provider.writeTo(obj, JsonStructure.class, null, null, null, null, out);
+        out.close();
+        
+        assertThat(new String(out.toByteArray()), 
+            equalTo("{\"firstName\":\"Tom\",\"lastName\":\"Tommyknocker\"}"));
+    }
+
+    @Test
+    public void testWriteJsonArray() throws Exception {
+        final JsonArray obj = Json.createArrayBuilder()             
+            .add(
+                Json.createObjectBuilder()
+                    .add("firstName", "Tom")
+                    .add("lastName", "Tommyknocker")
+            )
+            .add(
+                Json.createObjectBuilder()
+                    .add("firstName", "Bob")
+                    .add("lastName", "Bobbyknocker")
+            )
+            .build();              
+
+        final ByteArrayOutputStream out = new ByteArrayOutputStream();
+        provider.writeTo(obj, JsonStructure.class, null, null, null, null, out);
+        out.close();
+        
+        assertThat(new String(out.toByteArray()),
+            equalTo("[{\"firstName\":\"Tom\",\"lastName\":\"Tommyknocker\"},"
+                    + "{\"firstName\":\"Bob\",\"lastName\":\"Bobbyknocker\"}]"));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/2156bf58/systests/jaxrs/pom.xml
----------------------------------------------------------------------
diff --git a/systests/jaxrs/pom.xml b/systests/jaxrs/pom.xml
index e453479..7e951ec 100644
--- a/systests/jaxrs/pom.xml
+++ b/systests/jaxrs/pom.xml
@@ -47,6 +47,14 @@
             <artifactId>hibernate-validator</artifactId>
             <version>${cxf.hibernate.validator.version}</version>
         </dependency>
+        <dependency>
+            <groupId>javax.json</groupId>
+            <artifactId>javax.json-api</artifactId>            
+        </dependency>          
+        <dependency>
+            <groupId>org.glassfish</groupId>
+            <artifactId>javax.json</artifactId>
+        </dependency>             
         <!--
           <dependency>
             <groupId>org.apache.bval</groupId>

http://git-wip-us.apache.org/repos/asf/cxf/blob/2156bf58/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/provider/Book.java
----------------------------------------------------------------------
diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/provider/Book.java
b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/provider/Book.java
new file mode 100644
index 0000000..5c2bfcc
--- /dev/null
+++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/provider/Book.java
@@ -0,0 +1,62 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.cxf.systest.jaxrs.provider;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+public class Book {
+    private String name;
+    private long id;
+    private Map<Long, BookChapter> chapters = new HashMap<Long, BookChapter>();
+    
+    public Book() {
+    }
+    
+    public Book(String name, long id) {
+        this.setName(name);
+        this.setId(id);
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public long getId() {
+        return id;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+    
+    public void addChapter(long chapterId, String title) {
+        chapters.put(chapterId, new BookChapter(chapterId, title));
+    }
+    
+    public Collection<BookChapter> getChapters() {
+        return chapters.values();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cxf/blob/2156bf58/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/provider/BookChapter.java
----------------------------------------------------------------------
diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/provider/BookChapter.java
b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/provider/BookChapter.java
new file mode 100644
index 0000000..0d8e72f
--- /dev/null
+++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/provider/BookChapter.java
@@ -0,0 +1,48 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.cxf.systest.jaxrs.provider;
+
+public class BookChapter {
+    private String title;
+    private long id;
+    
+    public BookChapter() {
+    }
+    
+    public BookChapter(long id, String title) {
+        this.id = id;
+        this.title = title;
+    }
+    
+    public void setTitle(String n) {
+        title = n;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+    
+    public void setId(long i) {
+        id = i;
+    }
+    public long getId() {
+        return id;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/2156bf58/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/provider/BookJsonStore.java
----------------------------------------------------------------------
diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/provider/BookJsonStore.java
b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/provider/BookJsonStore.java
new file mode 100644
index 0000000..9d44cc6
--- /dev/null
+++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/provider/BookJsonStore.java
@@ -0,0 +1,127 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.cxf.systest.jaxrs.provider;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonArrayBuilder;
+import javax.json.JsonObject;
+import javax.json.JsonObjectBuilder;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+@Path("/bookstore/")
+public class BookJsonStore {
+    private Map< Long, Book > books = new HashMap< Long, Book >();
+
+    @GET
+    @Path("/books/{bookId}")
+    @Produces(MediaType.APPLICATION_JSON)
+    public JsonObject getBook(@PathParam("bookId") Long id) {
+        final Book book = books.get(id);
+        
+        if (book == null) {
+            return null;
+        }
+        
+        return bookToJson(book);
+    }
+
+    @GET
+    @Path("/books")
+    @Produces(MediaType.APPLICATION_JSON)
+    public JsonArray getBooks() {
+        final JsonArrayBuilder builder = Json.createArrayBuilder();
+        
+        for (final Book book: books.values()) {
+            builder.add(bookToJson(book));
+        }
+        
+        return builder.build();
+    }
+
+    @POST
+    @Path("/books")
+    @Consumes(MediaType.APPLICATION_JSON)
+    public Response addBook(@Context final UriInfo uriInfo, JsonObject obj) {
+        final Book book = bookFromJson(obj);
+        books.put(book.getId(), book);
+        
+        return Response.created(
+            uriInfo
+                .getRequestUriBuilder()
+                .path(Long.toString(book.getId()))
+                .build()).build();    
+    }
+
+    @DELETE
+    @Path("/books")
+    public Response deleteAll() {
+        books.clear();
+        return Response.ok().build();
+    }
+
+    private JsonObject bookToJson(final Book book) {
+        final JsonObjectBuilder builder = Json
+                .createObjectBuilder()
+                .add("id", book.getId())
+                .add("name", book.getName());
+        
+        if (!book.getChapters().isEmpty()) {
+            final JsonArrayBuilder chapters = Json.createArrayBuilder();
+            
+            for (final BookChapter chapter: book.getChapters()) {
+                chapters.add(Json.createObjectBuilder()
+                    .add("id", chapter.getId())
+                    .add("title", chapter.getTitle())
+                );
+            }
+            
+            builder.add("chapters", chapters);
+        }
+                
+        return builder.build();
+    }
+    
+    private Book bookFromJson(JsonObject obj) {
+        final Book book = new Book(obj.getString("name"), obj.getInt("id"));
+        final JsonArray chapters = (JsonArray)obj.get("chapters");
+        if (chapters != null && !chapters.isEmpty()) {
+            for (final JsonObject chapter: chapters.getValuesAs(JsonObject.class)) {
+                book.addChapter(chapter.getInt("id"), chapter.getString("title"));
+            }
+        }
+        
+        return book;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/2156bf58/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/provider/JsonJsr353ProviderTest.java
----------------------------------------------------------------------
diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/provider/JsonJsr353ProviderTest.java
b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/provider/JsonJsr353ProviderTest.java
new file mode 100644
index 0000000..d0e7d1a
--- /dev/null
+++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/provider/JsonJsr353ProviderTest.java
@@ -0,0 +1,192 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.cxf.systest.jaxrs.provider;
+
+import java.util.Arrays;
+
+import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonObject;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
+import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider;
+import org.apache.cxf.jaxrs.model.AbstractResourceInfo;
+import org.apache.cxf.jaxrs.provider.jsr353.JsonJsr353Provider;
+import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
+import org.apache.cxf.testutil.common.AbstractBusTestServerBase;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.core.IsNull.nullValue;
+
+
+public class JsonJsr353ProviderTest extends AbstractBusClientServerTestBase {
+    public static final String PORT = allocatePort(JsonJsr353ProviderTest.class);
+    
+    @Ignore
+    public static class Server extends AbstractBusTestServerBase {        
+        protected void run() {
+            final JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
+            sf.setResourceClasses(BookJsonStore.class);
+            sf.setResourceProvider(BookJsonStore.class, 
+                new SingletonResourceProvider(new BookJsonStore()));
+            sf.setProvider(new JsonJsr353Provider());
+            sf.setAddress("http://localhost:" + PORT + "/");
+            sf.create();
+        }
+
+        public static void main(String[] args) {
+            try {
+                Server s = new Server();
+                s.start();
+            } catch (Exception ex) {
+                ex.printStackTrace();
+                System.exit(-1);
+            } finally {
+                System.out.println("done!");
+            }
+        }
+    }
+    
+    @BeforeClass
+    public static void startServers() throws Exception {
+        AbstractResourceInfo.clearAllMaps();
+        //keep out of process due to stack traces testing failures
+        assertTrue("server did not launch correctly", launchServer(Server.class, true));
+        createStaticBus();
+    }
+
+    @Before
+    public void setUp() {
+        final Response r = createWebClient("/bookstore/books").delete();
+        assertEquals(Status.OK.getStatusCode(), r.getStatus());
+    }
+       
+    @Test
+    public void testNoResultsAreReturned() throws Exception {
+        final Response r = createWebClient("/bookstore/books/155").get();
+        assertEquals(Status.NO_CONTENT.getStatusCode(), r.getStatus());
+    }
+    
+    @Test
+    public void testPostSimpleJsonObject() {
+        final Response r = createWebClient("/bookstore/books")
+            .header("Content-Type", MediaType.APPLICATION_JSON)
+            .post(
+                Json
+                    .createObjectBuilder()
+                    .add("id", 1)
+                    .add("name", "Book 1")
+                    .build()
+            );
+        assertEquals(Status.CREATED.getStatusCode(), r.getStatus());        
+    }
+    
+    @Test
+    public void testPostComplexJsonObject() {
+        final Response r = createWebClient("/bookstore/books")
+            .header("Content-Type", MediaType.APPLICATION_JSON)
+            .post(
+                Json
+                    .createObjectBuilder()
+                    .add("id", 1)
+                    .add("name", "Book 1")
+                    .add("chapters",
+                        Json.createArrayBuilder()
+                            .add(
+                                Json.createObjectBuilder()
+                                    .add("id", 1)
+                                    .add("title", "Chapter 1")
+                            )
+                            .add(
+                                Json.createObjectBuilder()
+                                    .add("id", 2)
+                                    .add("title", "Chapter 2")
+                            )
+                    )
+                    .build()
+            );
+        assertEquals(Status.CREATED.getStatusCode(), r.getStatus());        
+    }
+    
+    @Test
+    public void testPostAndGetSimpleJsonObject() {
+        testPostSimpleJsonObject();
+        
+        final Response r = createWebClient("/bookstore/books/1").get();
+        assertEquals(Status.OK.getStatusCode(), r.getStatus());
+        
+        JsonObject obj = r.readEntity(JsonObject.class);
+        assertThat(obj.getInt("id"), equalTo(1));
+        assertThat(obj.getString("name"), equalTo("Book 1"));
+        assertThat(obj.get("chapters"), nullValue());
+    }
+
+    @Test
+    public void testPostAndGetComplexJsonObject() {
+        testPostComplexJsonObject();
+        
+        final Response r = createWebClient("/bookstore/books/1").get();
+        assertEquals(Status.OK.getStatusCode(), r.getStatus());
+        
+        JsonObject obj = r.readEntity(JsonObject.class);
+        assertThat(obj.getInt("id"), equalTo(1));
+        assertThat(obj.getString("name"), equalTo("Book 1"));
+        assertThat(obj.get("chapters"), instanceOf(JsonArray.class));
+        
+        final JsonArray chapters = (JsonArray)obj.get("chapters");
+        assertThat(chapters.size(), equalTo(2));
+        assertThat(((JsonObject)chapters.get(0)).getInt("id"), equalTo(1));
+        assertThat(((JsonObject)chapters.get(0)).getString("title"), equalTo("Chapter 1"));
+        assertThat(((JsonObject)chapters.get(1)).getInt("id"), equalTo(2));
+        assertThat(((JsonObject)chapters.get(1)).getString("title"), equalTo("Chapter 2"));
+    }
+
+    @Test
+    public void testPostAndGetBooks() {
+        testPostSimpleJsonObject();
+        
+        final Response r = createWebClient("/bookstore/books").get();
+        assertEquals(Status.OK.getStatusCode(), r.getStatus());
+        
+        final JsonArray obj = r.readEntity(JsonArray.class);
+        assertThat(obj.size(), equalTo(1));
+        assertThat(obj.get(0), instanceOf(JsonObject.class));
+        
+        assertThat(((JsonObject)obj.get(0)).getInt("id"), equalTo(1));
+        assertThat(((JsonObject)obj.get(0)).getString("name"), equalTo("Book 1"));
+    }
+
+    private static WebClient createWebClient(final String url) {
+        return WebClient
+            .create("http://localhost:" + PORT + url, 
+                Arrays.< Object >asList(new JsonJsr353Provider()))
+            .accept(MediaType.APPLICATION_JSON);
+    }
+
+}


Mime
View raw message