You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@johnzon.apache.org by rm...@apache.org on 2014/11/12 11:38:43 UTC
incubator-johnzon git commit: JOHNZON-24 ConfigurableJohnzonProvider
Repository: incubator-johnzon
Updated Branches:
refs/heads/master 222c5df80 -> e45db5c6a
JOHNZON-24 ConfigurableJohnzonProvider
Project: http://git-wip-us.apache.org/repos/asf/incubator-johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-johnzon/commit/e45db5c6
Tree: http://git-wip-us.apache.org/repos/asf/incubator-johnzon/tree/e45db5c6
Diff: http://git-wip-us.apache.org/repos/asf/incubator-johnzon/diff/e45db5c6
Branch: refs/heads/master
Commit: e45db5c6a492ee6c4c9238d987bb90f57238db71
Parents: 222c5df
Author: Romain Manni-Bucau <rm...@apache.org>
Authored: Wed Nov 12 11:38:28 2014 +0100
Committer: Romain Manni-Bucau <rm...@apache.org>
Committed: Wed Nov 12 11:38:28 2014 +0100
----------------------------------------------------------------------
.../jaxrs/ConfigurableJohnzonProvider.java | 146 +++++++++++++++++
.../apache/johnzon/jaxrs/IgnorableTypes.java | 34 ++++
.../johnzon/jaxrs/JohnzonMessageBodyReader.java | 11 +-
.../johnzon/jaxrs/JohnzonMessageBodyWriter.java | 8 +-
.../apache/johnzon/jaxrs/JohnzonProvider.java | 8 +-
.../jaxrs/ConfigurableJohnzonProviderTest.java | 161 +++++++++++++++++++
6 files changed, 358 insertions(+), 10 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/e45db5c6/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/ConfigurableJohnzonProvider.java
----------------------------------------------------------------------
diff --git a/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/ConfigurableJohnzonProvider.java b/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/ConfigurableJohnzonProvider.java
new file mode 100644
index 0000000..5937f3e
--- /dev/null
+++ b/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/ConfigurableJohnzonProvider.java
@@ -0,0 +1,146 @@
+/*
+ * 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.johnzon.jaxrs;
+
+import org.apache.johnzon.mapper.MapperBuilder;
+import org.apache.johnzon.mapper.access.AccessMode;
+
+import javax.json.JsonReaderFactory;
+import javax.json.stream.JsonGeneratorFactory;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.Produces;
+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 java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Comparator;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
+
+import static java.util.Arrays.asList;
+import static javax.ws.rs.core.MediaType.WILDCARD;
+
+@Provider
+@Produces(WILDCARD)
+@Consumes(WILDCARD)
+public class ConfigurableJohnzonProvider<T> implements MessageBodyWriter<T>, MessageBodyReader<T> {
+ // build/configuration
+ private MapperBuilder builder = new MapperBuilder();
+ private List<String> ignores;
+
+ // runtime
+ private AtomicReference<JohnzonProvider<T>> delegate = new AtomicReference<JohnzonProvider<T>>();
+
+ private JohnzonProvider<T> instance() {
+ JohnzonProvider<T> instance;
+ do {
+ instance = delegate.get();
+ if (builder != null && delegate.compareAndSet(null, new JohnzonProvider<T>(builder.build(), ignores))) {
+ // reset build instances
+ builder = null;
+ ignores = null;
+ }
+ } while (instance == null);
+ return instance;
+ }
+
+ @Override
+ public boolean isReadable(final Class<?> rawType, final Type genericType,
+ final Annotation[] annotations, final MediaType mediaType) {
+ return instance().isReadable(rawType, genericType, annotations, mediaType);
+ }
+
+ @Override
+ public T readFrom(final Class<T> rawType, final Type genericType,
+ final Annotation[] annotations, final MediaType mediaType,
+ final MultivaluedMap<String, String> httpHeaders,
+ final InputStream entityStream) throws IOException {
+ return instance().readFrom(rawType, genericType, annotations, mediaType, httpHeaders, entityStream);
+ }
+
+ @Override
+ public long getSize(final T t, final Class<?> rawType, final Type genericType,
+ final Annotation[] annotations, final MediaType mediaType) {
+ return instance().getSize(t, rawType, genericType, annotations, mediaType);
+ }
+
+ @Override
+ public boolean isWriteable(final Class<?> rawType, final Type genericType,
+ final Annotation[] annotations, final MediaType mediaType) {
+ return instance().isWriteable(rawType, genericType, annotations, mediaType);
+ }
+
+ @Override
+ public void writeTo(final T t, final Class<?> rawType, final Type genericType,
+ final Annotation[] annotations, final MediaType mediaType,
+ final MultivaluedMap<String, Object> httpHeaders,
+ final OutputStream entityStream) throws IOException {
+ instance().writeTo(t, rawType, genericType, annotations, mediaType, httpHeaders, entityStream);
+ }
+
+ public void setIgnores(final String ignores) {
+ this.ignores = ignores == null ? null : asList(ignores.split(" *, *"));
+ }
+
+ public void setAccessMode(final AccessMode mode) {
+ builder.setAccessMode(mode);
+ }
+
+ public void setAccessModeName(final String mode) {
+ builder.setAccessModeName(mode);
+ }
+
+ public void setSupportHiddenAccess(final boolean supportHiddenAccess) {
+ builder.setSupportHiddenAccess(supportHiddenAccess);
+ }
+
+ public void setAttributeOrder(final Comparator<String> attributeOrder) {
+ builder.setAttributeOrder(attributeOrder);
+ }
+
+ public void setReaderFactory(final JsonReaderFactory readerFactory) {
+ builder.setReaderFactory(readerFactory);
+ }
+
+ public void setGeneratorFactory(final JsonGeneratorFactory generatorFactory) {
+ builder.setGeneratorFactory(generatorFactory);
+ }
+
+ public void setDoCloseOnStreams(final boolean doCloseOnStreams) {
+ builder.setDoCloseOnStreams(doCloseOnStreams);
+ }
+
+ public void setVersion(final int version) {
+ builder.setVersion(version);
+ }
+
+ public void setSkipNull(final boolean skipNull) {
+ builder.setSkipNull(skipNull);
+ }
+
+ public void setSkipEmptyArray(final boolean skipEmptyArray) {
+ builder.setSkipEmptyArray(skipEmptyArray);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/e45db5c6/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/IgnorableTypes.java
----------------------------------------------------------------------
diff --git a/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/IgnorableTypes.java b/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/IgnorableTypes.java
new file mode 100644
index 0000000..938256f
--- /dev/null
+++ b/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/IgnorableTypes.java
@@ -0,0 +1,34 @@
+/*
+ * 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.johnzon.jaxrs;
+
+import java.util.Collection;
+import java.util.HashSet;
+
+public class IgnorableTypes {
+ private final Collection<String> ignores;
+
+ protected IgnorableTypes(final Collection<String> ignores) {
+ this.ignores = ignores == null ? null : new HashSet<String>(ignores);
+ }
+
+ public boolean isIgnored(final Class<?> type) {
+ return ignores != null && ignores.contains(type.getName());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/e45db5c6/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/JohnzonMessageBodyReader.java
----------------------------------------------------------------------
diff --git a/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/JohnzonMessageBodyReader.java b/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/JohnzonMessageBodyReader.java
index d0813d3..c7e7ae6 100644
--- a/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/JohnzonMessageBodyReader.java
+++ b/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/JohnzonMessageBodyReader.java
@@ -25,6 +25,7 @@ import javax.json.JsonStructure;
import javax.ws.rs.Consumes;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.Provider;
import java.io.IOException;
@@ -40,14 +41,15 @@ import static org.apache.johnzon.jaxrs.Jsons.isJson;
@Provider
@Consumes(WILDCARD)
-public class JohnzonMessageBodyReader<T> implements MessageBodyReader<T> {
+public class JohnzonMessageBodyReader<T> extends IgnorableTypes implements MessageBodyReader<T> {
private final Mapper mapper;
public JohnzonMessageBodyReader() {
- this(new MapperBuilder().setDoCloseOnStreams(false).build());
+ this(new MapperBuilder().setDoCloseOnStreams(false).build(), null);
}
- public JohnzonMessageBodyReader(final Mapper mapper) {
+ public JohnzonMessageBodyReader(final Mapper mapper, final Collection<String> ignoredTypes) {
+ super(ignoredTypes);
this.mapper = mapper;
}
@@ -55,7 +57,8 @@ public class JohnzonMessageBodyReader<T> implements MessageBodyReader<T> {
public boolean isReadable(final Class<?> rawType, final Type genericType,
final Annotation[] annotations, final MediaType mediaType) {
return isJson(mediaType)
- && InputStream.class != rawType && Reader.class != rawType
+ && !isIgnored(rawType)
+ && InputStream.class != rawType && Reader.class != rawType && Response.class != rawType
&& String.class != rawType
&& !JsonStructure.class.isAssignableFrom(rawType);
}
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/e45db5c6/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/JohnzonMessageBodyWriter.java
----------------------------------------------------------------------
diff --git a/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/JohnzonMessageBodyWriter.java b/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/JohnzonMessageBodyWriter.java
index a540d6d..840d80b 100644
--- a/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/JohnzonMessageBodyWriter.java
+++ b/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/JohnzonMessageBodyWriter.java
@@ -42,14 +42,15 @@ import static javax.ws.rs.core.MediaType.WILDCARD;
@Provider
@Produces(WILDCARD)
-public class JohnzonMessageBodyWriter<T> implements MessageBodyWriter<T> {
+public class JohnzonMessageBodyWriter<T> extends IgnorableTypes implements MessageBodyWriter<T> {
private final Mapper mapper;
public JohnzonMessageBodyWriter() {
- this(new MapperBuilder().setDoCloseOnStreams(false).build());
+ this(new MapperBuilder().setDoCloseOnStreams(false).build(), null);
}
- public JohnzonMessageBodyWriter(final Mapper mapper) {
+ public JohnzonMessageBodyWriter(final Mapper mapper, final Collection<String> ignoredTypes) {
+ super(ignoredTypes);
this.mapper = mapper;
}
@@ -63,6 +64,7 @@ public class JohnzonMessageBodyWriter<T> implements MessageBodyWriter<T> {
public boolean isWriteable(final Class<?> rawType, final Type genericType,
final Annotation[] annotations, final MediaType mediaType) {
return Jsons.isJson(mediaType)
+ && !isIgnored(rawType)
&& InputStream.class != rawType
&& OutputStream.class != rawType
&& Writer.class != rawType
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/e45db5c6/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/JohnzonProvider.java
----------------------------------------------------------------------
diff --git a/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/JohnzonProvider.java b/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/JohnzonProvider.java
index a72e9f1..58ce2e7 100644
--- a/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/JohnzonProvider.java
+++ b/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/JohnzonProvider.java
@@ -25,17 +25,19 @@ import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.ext.Provider;
+import java.util.Collection;
+
import static javax.ws.rs.core.MediaType.WILDCARD;
@Provider
@Produces(WILDCARD)
@Consumes(WILDCARD)
public class JohnzonProvider<T> extends DelegateProvider<T> {
- public JohnzonProvider(final Mapper mapper) {
- super(new JohnzonMessageBodyReader<T>(mapper), new JohnzonMessageBodyWriter<T>(mapper));
+ public JohnzonProvider(final Mapper mapper, final Collection<String> ignores) {
+ super(new JohnzonMessageBodyReader<T>(mapper, ignores), new JohnzonMessageBodyWriter<T>(mapper, ignores));
}
public JohnzonProvider() {
- this(new MapperBuilder().setDoCloseOnStreams(false).build());
+ this(new MapperBuilder().setDoCloseOnStreams(false).build(), null);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/e45db5c6/johnzon-jaxrs/src/test/java/org/apache/johnzon/jaxrs/ConfigurableJohnzonProviderTest.java
----------------------------------------------------------------------
diff --git a/johnzon-jaxrs/src/test/java/org/apache/johnzon/jaxrs/ConfigurableJohnzonProviderTest.java b/johnzon-jaxrs/src/test/java/org/apache/johnzon/jaxrs/ConfigurableJohnzonProviderTest.java
new file mode 100644
index 0000000..e95cb13
--- /dev/null
+++ b/johnzon-jaxrs/src/test/java/org/apache/johnzon/jaxrs/ConfigurableJohnzonProviderTest.java
@@ -0,0 +1,161 @@
+/*
+ * 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.johnzon.jaxrs;
+
+import org.apache.cxf.endpoint.Server;
+import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
+import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider;
+import org.apache.cxf.transport.local.LocalConduit;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.core.GenericType;
+import javax.ws.rs.core.MediaType;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.List;
+
+import static java.util.Arrays.asList;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class ConfigurableJohnzonProviderTest {
+ private final static String ENDPOINT_ADDRESS = "local://johnzon";
+ private static Server server;
+
+ @BeforeClass
+ public static void bindEndpoint() throws Exception {
+ final JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
+ sf.setResourceClasses(JohnzonResource.class);
+ sf.setProviders(asList(new ConfigurableJohnzonProvider()));
+ sf.setResourceProvider(JohnzonResource.class, new SingletonResourceProvider(new JohnzonResource(), false));
+ sf.setAddress(ENDPOINT_ADDRESS);
+ server = sf.create();
+ }
+
+ @AfterClass
+ public static void unbind() throws Exception {
+ server.stop();
+ server.destroy();
+ }
+
+ @Test
+ public void asParam() {
+ final String result = client().path("johnzon").type(MediaType.APPLICATION_JSON_TYPE).post(new Johnzon("client")).readEntity(String.class);
+ assertTrue(Boolean.parseBoolean(result));
+ }
+
+ @Test
+ public void object() {
+ final Johnzon johnzon = client().path("johnzon").get(Johnzon.class);
+ assertEquals("johnzon", johnzon.getName());
+ }
+
+ @Test
+ public void array() {
+ final Johnzon[] johnzon = client().path("johnzon/all1").get(Johnzon[].class);
+ assertEquals(2, johnzon.length);
+ for (int i = 0; i < johnzon.length; i++) {
+ assertEquals("johnzon" + (i + 1), johnzon[i].getName());
+ }
+ }
+
+ @Test
+ public void list() {
+ final ParameterizedType list = new ParameterizedType() {
+ @Override
+ public Type[] getActualTypeArguments() {
+ return new Type[]{Johnzon.class};
+ }
+
+ @Override
+ public Type getRawType() {
+ return List.class;
+ }
+
+ @Override
+ public Type getOwnerType() {
+ return null;
+ }
+ };
+ final List<Johnzon> johnzons = client().path("johnzon/all2").get(new GenericType<List<Johnzon>>(list));
+ assertEquals(2, johnzons.size());
+ int i = 1;
+ for (final Johnzon f : johnzons) {
+ assertEquals("johnzon" + i, f.getName());
+ i++;
+ }
+ }
+
+ private static WebClient client() {
+ final WebClient client = WebClient.create(ENDPOINT_ADDRESS, asList(new JohnzonProvider<Object>())).accept(MediaType.APPLICATION_JSON_TYPE);
+ WebClient.getConfig(client).getRequestContext().put(LocalConduit.DIRECT_DISPATCH, Boolean.TRUE);
+ return client;
+ }
+
+ public static class Johnzon {
+ private String name;
+
+ public Johnzon(final String name) {
+ this.name = name;
+ }
+
+ public Johnzon() {
+ // no-op
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(final String name) {
+ this.name = name;
+ }
+ }
+
+ @Path("johnzon")
+ public static class JohnzonResource {
+ @GET
+ public Johnzon johnzon() {
+ return new Johnzon("johnzon");
+ }
+
+ @GET
+ @Path("all1")
+ public Johnzon[] johnzons1() {
+ return new Johnzon[] { new Johnzon("johnzon1"), new Johnzon("johnzon2") };
+ }
+
+ @GET
+ @Path("all2")
+ public List<Johnzon> johnzons2() {
+ return asList(johnzons1());
+ }
+
+ @POST
+ public String asParam(final Johnzon f) {
+ return Boolean.toString("client".equals(f.getName()));
+ }
+ }
+}