You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by rm...@apache.org on 2016/06/01 18:24:36 UTC

tomee git commit: TOMEE-1825 TOMEE-1824 adding datepattern and converter config to johnzon for jaxrs

Repository: tomee
Updated Branches:
  refs/heads/master 7e1f083ad -> 475f7dfa5


TOMEE-1825 TOMEE-1824 adding datepattern and converter config to johnzon for jaxrs


Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/475f7dfa
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/475f7dfa
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/475f7dfa

Branch: refs/heads/master
Commit: 475f7dfa55cd6480cea9ab5aa8aa6f24974b2875
Parents: 7e1f083
Author: Romain manni-Bucau <rm...@gmail.com>
Authored: Wed Jun 1 20:24:08 2016 +0200
Committer: Romain manni-Bucau <rm...@gmail.com>
Committed: Wed Jun 1 20:24:08 2016 +0200

----------------------------------------------------------------------
 .../assembler/classic/util/ServiceInfos.java    |  14 +-
 .../rs/johnzon/TomEEConfigurableJohnzon.java    |  85 +++++++++++
 .../johnzon/TomEEConfigurableJohnzonTest.java   | 153 +++++++++++++++++++
 3 files changed, 250 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tomee/blob/475f7dfa/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/util/ServiceInfos.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/util/ServiceInfos.java b/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/util/ServiceInfos.java
index 71b92c7..ecc0c59 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/util/ServiceInfos.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/util/ServiceInfos.java
@@ -161,8 +161,18 @@ public final class ServiceInfos {
             final String key = entry.getKey().toString();
             final Object value = entry.getValue();
             if (value instanceof String) {
-                final String valueStr = value.toString();
-                if (valueStr.startsWith("$")) {
+                String valueStr = value.toString();
+                if (valueStr.startsWith("collection:")) { // for now only supports Service cause that's where it is useful but feel free to enrich it
+                    valueStr = valueStr.substring("collection:".length());
+                    final String[] elt = valueStr.split(" *, *");
+                    final List<Object> val = new ArrayList<>(elt.length);
+                    for (final String e : elt) {
+                        if (!e.trim().isEmpty()) {
+                            val.add(resolve(services, e.startsWith("$") ? e.substring(1) : e));
+                        }
+                    }
+                    serviceRecipe.setProperty(key, val);
+                } else if (valueStr.startsWith("$")) {
                     serviceRecipe.setProperty(key, resolve(services, valueStr.substring(1)));
                 } else if (valueStr.startsWith("@")) {
                     final Context jndiContext = SystemInstance.get().getComponent(ContainerSystem.class).getJNDIContext();

http://git-wip-us.apache.org/repos/asf/tomee/blob/475f7dfa/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/johnzon/TomEEConfigurableJohnzon.java
----------------------------------------------------------------------
diff --git a/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/johnzon/TomEEConfigurableJohnzon.java b/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/johnzon/TomEEConfigurableJohnzon.java
new file mode 100644
index 0000000..57bb29f
--- /dev/null
+++ b/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/johnzon/TomEEConfigurableJohnzon.java
@@ -0,0 +1,85 @@
+/*
+ *     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.openejb.server.cxf.rs.johnzon;
+
+import org.apache.johnzon.jaxrs.ConfigurableJohnzonProvider;
+import org.apache.johnzon.mapper.Adapter;
+import org.apache.johnzon.mapper.Converter;
+import org.apache.johnzon.mapper.MapperBuilder;
+import org.apache.johnzon.mapper.converter.DateConverter;
+import org.apache.johnzon.mapper.internal.ConverterAdapter;
+import org.apache.openejb.util.reflection.Reflections;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.Produces;
+import javax.ws.rs.ext.Provider;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+
+import static java.util.Arrays.asList;
+
+@Provider
+@Produces("application/json")
+@Consumes("application/json")
+public class TomEEConfigurableJohnzon<T> extends ConfigurableJohnzonProvider<T> {
+    private MapperBuilder localBuilder;
+
+    public void setConverters(final Collection<Converter<?>> converters) {
+        for (final Converter<?> converter : converters) {
+            final Type type = findType(converter, Converter.class);
+            builder().addAdapter(ParameterizedType.class.cast(type).getActualTypeArguments()[0], String.class, new ConverterAdapter(converter));
+        }
+    }
+
+    public void setConverter(final Converter<?> converter) {
+        setConverters(Collections.<Converter<?>>singletonList(converter));
+    }
+
+    public void setAdapter(final Adapter<?, ?> converter) {
+        setAdapters(Collections.<Adapter<?, ?>>singletonList(converter));
+    }
+
+    // @Experimental
+    public void setAdapters(final Collection<Adapter<?, ?>> adapters) {
+        for (final Adapter<?, ?> adapter : adapters) {
+            final Type type = findType(adapter, Adapter.class);
+            final ParameterizedType pt = ParameterizedType.class.cast(type);
+            final Type[] actualTypeArguments = pt.getActualTypeArguments();
+            builder().addAdapter(actualTypeArguments[0], actualTypeArguments[1], adapter);
+        }
+    }
+
+    public void setDatePattern(final String datePattern) {
+        builder().addAdapter(Date.class, String.class, new ConverterAdapter<>(new DateConverter(datePattern)));
+    }
+
+    private Type findType(final Object ref, final Class<?> api) { // need to impl adapters directly
+        for (final Type type : ref.getClass().getGenericInterfaces()) {
+            if (ParameterizedType.class.isInstance(type) && ParameterizedType.class.cast(type).getRawType() == api) {
+                return type;
+            }
+        }
+        throw new IllegalArgumentException("Didn't find " + ref + " in interfaces: " + asList(ref.getClass().getGenericInterfaces()));
+    }
+
+    private MapperBuilder builder() {
+        return localBuilder == null ? (localBuilder = MapperBuilder.class.cast(Reflections.get(this, "builder"))) : localBuilder;
+    }
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/475f7dfa/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/johnzon/TomEEConfigurableJohnzonTest.java
----------------------------------------------------------------------
diff --git a/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/johnzon/TomEEConfigurableJohnzonTest.java b/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/johnzon/TomEEConfigurableJohnzonTest.java
new file mode 100644
index 0000000..72862ef
--- /dev/null
+++ b/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/johnzon/TomEEConfigurableJohnzonTest.java
@@ -0,0 +1,153 @@
+/*
+ *     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.openejb.server.cxf.rs.johnzon;
+
+import org.apache.johnzon.mapper.Converter;
+import org.apache.openejb.config.EjbModule;
+import org.apache.openejb.config.sys.Resources;
+import org.apache.openejb.config.sys.Service;
+import org.apache.openejb.jee.EjbJar;
+import org.apache.openejb.jee.EnterpriseBean;
+import org.apache.openejb.jee.SingletonBean;
+import org.apache.openejb.jee.oejb3.OpenejbJar;
+import org.apache.openejb.jee.oejb3.PojoDeployment;
+import org.apache.openejb.junit.ApplicationComposer;
+import org.apache.openejb.loader.IO;
+import org.apache.openejb.testing.EnableServices;
+import org.apache.openejb.testing.Module;
+import org.apache.openejb.testing.RandomPort;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import java.io.IOException;
+import java.net.URL;
+import java.text.SimpleDateFormat;
+import java.util.Comparator;
+import java.util.Date;
+
+import static org.junit.Assert.assertEquals;
+
+@EnableServices("jax-rs")
+@RunWith(ApplicationComposer.class)
+public class TomEEConfigurableJohnzonTest {
+    @RandomPort("http")
+    private URL base;
+
+    @Module
+    public static EjbModule service() throws Exception {
+        final EjbModule module = new EjbModule(new EjbJar(), new OpenejbJar());
+        final EnterpriseBean bean = new SingletonBean(Endpoint.class).localBean();
+        module.getEjbJar().addEnterpriseBean(bean);
+
+        final Resources resources = new Resources();
+
+        final Service sorter = new Service("testSorter", null);
+        sorter.setClassName(Sorter.class.getName());
+        resources.getService().add(sorter);
+
+
+        final Service converter = new Service("customerConverter", null);
+        converter.setClassName(MyConverter.class.getName());
+        resources.getService().add(converter);
+
+        final Service johnzon = new Service("johnzon", null);
+        johnzon.setClassName(TomEEConfigurableJohnzon.class.getName());
+        johnzon.getProperties().put("datePattern", "yyyy");
+        // johnzon.getProperties().put("converter", "$customerConverter"); // or the collection syntax
+        johnzon.getProperties().put("converters", "collection:$customerConverter,$customerConverter");
+        johnzon.getProperties().put("attributeOrder", "$testSorter");
+        resources.getService().add(johnzon);
+
+        module.initResources(resources);
+
+        final PojoDeployment e = new PojoDeployment();
+        e.setClassName("jaxrs-application");
+        e.getProperties().setProperty("cxf.jaxrs.providers", "johnzon");
+        module.getOpenejbJar().getPojoDeployment().add(e);
+
+        return module;
+    }
+
+    @Test
+    public void run() throws IOException {
+        assertEquals("{\"date\":\"" + year() + "\",\"horrible\":\"awesome\"}", IO.slurp(new URL(base.toExternalForm() + getClass().getSimpleName() + "/test")));
+    }
+
+    private String year() { // same johnzon should have done
+        return new SimpleDateFormat("yyyy").format(new Date());
+    }
+
+    @Path("test")
+    public static class Endpoint {
+        @GET
+        @Produces(MediaType.APPLICATION_JSON)
+        public Model get() {
+            final Model model = new Model();
+            model.setDate(new Date());
+            model.setHorrible(new Horrible());
+            return model;
+        }
+    }
+
+    public static class Model {
+        private Horrible horrible;
+        private Date date;
+
+        public Horrible getHorrible() {
+            return horrible;
+        }
+
+        public void setHorrible(final Horrible horrible) {
+            this.horrible = horrible;
+        }
+
+        public Date getDate() {
+            return date;
+        }
+
+        public void setDate(final Date date) {
+            this.date = date;
+        }
+    }
+
+    public static class Horrible {
+    }
+
+
+    public static class MyConverter implements Converter<Horrible> {
+        @Override
+        public String toString(final Horrible instance) {
+            return "awesome";
+        }
+
+        @Override
+        public Horrible fromString(final String text) {
+            return new Horrible();
+        }
+    }
+
+    public static class Sorter implements Comparator<String> {
+        @Override
+        public int compare(final String o1, final String o2) {
+            return o1.compareTo(o2);
+        }
+    }
+}