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 2015/03/24 16:30:04 UTC
incubator-johnzon git commit: JOHNZON-41 jsr 356 integration,
note: still some work to do on client annotation endpoint integration
but didnt find a right api yet
Repository: incubator-johnzon
Updated Branches:
refs/heads/master e98915914 -> 29a79edb9
JOHNZON-41 jsr 356 integration, note: still some work to do on client annotation endpoint integration but didnt find a right api yet
Project: http://git-wip-us.apache.org/repos/asf/incubator-johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-johnzon/commit/29a79edb
Tree: http://git-wip-us.apache.org/repos/asf/incubator-johnzon/tree/29a79edb
Diff: http://git-wip-us.apache.org/repos/asf/incubator-johnzon/diff/29a79edb
Branch: refs/heads/master
Commit: 29a79edb9a9845a01098188c418331319079009d
Parents: e989159
Author: Romain Manni-Bucau <rm...@apache.org>
Authored: Tue Mar 24 16:29:57 2015 +0100
Committer: Romain Manni-Bucau <rm...@apache.org>
Committed: Tue Mar 24 16:29:57 2015 +0100
----------------------------------------------------------------------
johnzon-websocket/pom.xml | 91 +++++++++++++++
.../websocket/internal/jsr/FactoryLocator.java | 89 +++++++++++++++
.../websocket/internal/jsr/JsrDecoder.java | 53 +++++++++
.../websocket/internal/jsr/JsrEncoder.java | 53 +++++++++
.../internal/mapper/MapperLocator.java | 62 +++++++++++
.../johnzon/websocket/jsr/JsrArrayDecoder.java | 31 ++++++
.../johnzon/websocket/jsr/JsrArrayEncoder.java | 31 ++++++
.../johnzon/websocket/jsr/JsrObjectDecoder.java | 34 ++++++
.../johnzon/websocket/jsr/JsrObjectEncoder.java | 31 ++++++
.../websocket/jsr/JsrStructureDecoder.java | 34 ++++++
.../websocket/jsr/JsrStructureEncoder.java | 31 ++++++
.../websocket/mapper/JohnzonTextDecoder.java | 110 +++++++++++++++++++
.../websocket/mapper/JohnzonTextEncoder.java | 47 ++++++++
.../apache/johnzon/websocket/JsrCodecTest.java | 93 ++++++++++++++++
.../johnzon/websocket/MapperCodecTest.java | 95 ++++++++++++++++
.../websocket/endpoint/ClientEndpointImpl.java | 53 +++++++++
.../endpoint/JsrClientEndpointImpl.java | 41 +++++++
.../endpoint/JsrServerEndpointImpl.java | 50 +++++++++
.../johnzon/websocket/endpoint/Message.java | 42 +++++++
.../websocket/endpoint/ServerEndpointImpl.java | 44 ++++++++
.../websocket/endpoint/ServerReport.java | 71 ++++++++++++
.../src/test/resources/arquillian.xml | 38 +++++++
pom.xml | 1 +
23 files changed, 1225 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/29a79edb/johnzon-websocket/pom.xml
----------------------------------------------------------------------
diff --git a/johnzon-websocket/pom.xml b/johnzon-websocket/pom.xml
new file mode 100644
index 0000000..43e9366
--- /dev/null
+++ b/johnzon-websocket/pom.xml
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>apache-johnzon</artifactId>
+ <groupId>org.apache.johnzon</groupId>
+ <version>0.8-incubating-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>johnzon-websocket</artifactId>
+ <name>Johnzon :: WebSocket</name>
+
+ <properties>
+ <tomcat.version>7.0.59</tomcat.version>
+ <tomee.version>1.7.1</tomee.version>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.tomcat</groupId>
+ <artifactId>tomcat-websocket-api</artifactId>
+ <version>${tomcat.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tomcat</groupId>
+ <artifactId>tomcat-servlet-api</artifactId>
+ <version>${tomcat.version}</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.johnzon</groupId>
+ <artifactId>johnzon-mapper</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.arquillian.junit</groupId>
+ <artifactId>arquillian-junit-container</artifactId>
+ <version>1.1.7.Final</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.openejb</groupId>
+ <artifactId>arquillian-tomee-remote</artifactId>
+ <version>${tomee.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.openejb</groupId>
+ <artifactId>apache-tomee</artifactId>
+ <version>${tomee.version}</version>
+ <type>zip</type>
+ <classifier>jaxrs</classifier>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.12</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tomcat</groupId>
+ <artifactId>tomcat7-websocket</artifactId>
+ <version>${tomcat.version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/29a79edb/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/internal/jsr/FactoryLocator.java
----------------------------------------------------------------------
diff --git a/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/internal/jsr/FactoryLocator.java b/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/internal/jsr/FactoryLocator.java
new file mode 100644
index 0000000..48463d9
--- /dev/null
+++ b/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/internal/jsr/FactoryLocator.java
@@ -0,0 +1,89 @@
+/*
+ * 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.websocket.internal.jsr;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import javax.json.Json;
+import javax.json.JsonReaderFactory;
+import javax.json.JsonWriterFactory;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+import javax.servlet.annotation.WebListener;
+
+@WebListener
+public class FactoryLocator implements ServletContextListener {
+ private static final Map<ClassLoader, JsonReaderFactory> READER_FACTORY_BY_LOADER = new ConcurrentHashMap<ClassLoader, JsonReaderFactory>();
+ private static final Map<ClassLoader, JsonWriterFactory> WRITER_FACTORY_BY_LOADER = new ConcurrentHashMap<ClassLoader, JsonWriterFactory>();
+ private static final String READER_ATTRIBUTE = FactoryLocator.class.getName() + ".readerFactory";
+ private static final String WRITER_ATTRIBUTE = FactoryLocator.class.getName() + ".writerFactory";
+
+ @Override
+ public void contextInitialized(final ServletContextEvent servletContextEvent) {
+ final ClassLoader classLoader = servletContextEvent.getServletContext().getClassLoader();
+
+ final JsonReaderFactory reader = newReadFactory();
+ READER_FACTORY_BY_LOADER.put(classLoader, reader);
+ servletContextEvent.getServletContext().setAttribute(READER_ATTRIBUTE, reader);
+
+ final JsonWriterFactory writer = newWriterFactory();
+ WRITER_FACTORY_BY_LOADER.put(classLoader, writer);
+ servletContextEvent.getServletContext().setAttribute(WRITER_ATTRIBUTE, reader);
+ }
+
+ @Override
+ public void contextDestroyed(final ServletContextEvent servletContextEvent) {
+ final ClassLoader classLoader = servletContextEvent.getServletContext().getClassLoader();
+ READER_FACTORY_BY_LOADER.remove(classLoader);
+ WRITER_FACTORY_BY_LOADER.remove(classLoader);
+ }
+
+ public static JsonReaderFactory readerLocate() {
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+ if (loader == null) {
+ loader = FactoryLocator.class.getClassLoader();
+ }
+ final JsonReaderFactory factory = READER_FACTORY_BY_LOADER.get(loader);
+ if (factory == null) {
+ return newReadFactory();
+ }
+ return factory;
+ }
+
+ public static JsonWriterFactory writerLocate() {
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+ if (loader == null) {
+ loader = FactoryLocator.class.getClassLoader();
+ }
+ final JsonWriterFactory factory = WRITER_FACTORY_BY_LOADER.get(loader);
+ if (factory == null) {
+ return newWriterFactory();
+ }
+ return factory;
+ }
+
+ private static JsonReaderFactory newReadFactory() {
+ return Json.createReaderFactory(Collections.<String, Object>emptyMap());
+ }
+
+ private static JsonWriterFactory newWriterFactory() {
+ return Json.createWriterFactory(Collections.<String, Object>emptyMap());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/29a79edb/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/internal/jsr/JsrDecoder.java
----------------------------------------------------------------------
diff --git a/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/internal/jsr/JsrDecoder.java b/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/internal/jsr/JsrDecoder.java
new file mode 100644
index 0000000..2edb3c9
--- /dev/null
+++ b/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/internal/jsr/JsrDecoder.java
@@ -0,0 +1,53 @@
+/*
+ * 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.websocket.internal.jsr;
+
+import java.io.IOException;
+import java.io.Reader;
+import javax.json.JsonReader;
+import javax.json.JsonReaderFactory;
+import javax.websocket.DecodeException;
+import javax.websocket.Decoder;
+import javax.websocket.EndpointConfig;
+
+public abstract class JsrDecoder<T> implements Decoder.TextStream<T> {
+ private JsonReaderFactory factory;
+
+ protected abstract T doRead(JsonReader jsonReader);
+
+ @Override
+ public void init(final EndpointConfig endpointConfig) {
+ factory = FactoryLocator.readerLocate();
+ }
+
+ @Override
+ public T decode(final Reader reader) throws DecodeException, IOException {
+ final JsonReader jsonReader = factory.createReader(reader);
+ try {
+ return doRead(jsonReader);
+ } finally {
+ jsonReader.close();
+ }
+ }
+
+ @Override
+ public void destroy() {
+ // no-op
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/29a79edb/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/internal/jsr/JsrEncoder.java
----------------------------------------------------------------------
diff --git a/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/internal/jsr/JsrEncoder.java b/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/internal/jsr/JsrEncoder.java
new file mode 100644
index 0000000..917482b
--- /dev/null
+++ b/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/internal/jsr/JsrEncoder.java
@@ -0,0 +1,53 @@
+/*
+ * 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.websocket.internal.jsr;
+
+import java.io.IOException;
+import java.io.Writer;
+import javax.json.JsonWriter;
+import javax.json.JsonWriterFactory;
+import javax.websocket.EncodeException;
+import javax.websocket.Encoder;
+import javax.websocket.EndpointConfig;
+
+public abstract class JsrEncoder<T> implements Encoder.TextStream<T> {
+ private JsonWriterFactory factory;
+
+ protected abstract void doWrite(JsonWriter writer, T t);
+
+ @Override
+ public void init(final EndpointConfig endpointConfig) {
+ factory = FactoryLocator.writerLocate();
+ }
+
+ @Override
+ public void destroy() {
+ // no-op
+ }
+
+ @Override
+ public void encode(final T t, final Writer writer) throws EncodeException, IOException {
+ final JsonWriter jsonWriter = factory.createWriter(writer);
+ try {
+ doWrite(jsonWriter, t);
+ } finally {
+ jsonWriter.close();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/29a79edb/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/internal/mapper/MapperLocator.java
----------------------------------------------------------------------
diff --git a/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/internal/mapper/MapperLocator.java b/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/internal/mapper/MapperLocator.java
new file mode 100644
index 0000000..9145694
--- /dev/null
+++ b/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/internal/mapper/MapperLocator.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.johnzon.websocket.internal.mapper;
+
+import org.apache.johnzon.mapper.Mapper;
+import org.apache.johnzon.mapper.MapperBuilder;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+import javax.servlet.annotation.WebListener;
+
+@WebListener
+public class MapperLocator implements ServletContextListener {
+ private static final Map<ClassLoader, Mapper> MAPPER_BY_LOADER = new ConcurrentHashMap<ClassLoader, Mapper>();
+ private static final String ATTRIBUTE = MapperLocator.class.getName() + ".mapper";
+
+ @Override
+ public void contextInitialized(final ServletContextEvent servletContextEvent) {
+ final Mapper build = newMapper();
+ MAPPER_BY_LOADER.put(servletContextEvent.getServletContext().getClassLoader(), build);
+ servletContextEvent.getServletContext().setAttribute(ATTRIBUTE, build);
+ }
+
+ @Override
+ public void contextDestroyed(final ServletContextEvent servletContextEvent) {
+ MAPPER_BY_LOADER.remove(servletContextEvent.getServletContext().getClassLoader());
+ }
+
+ public static Mapper locate() {
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+ if (loader == null) {
+ loader = MapperLocator.class.getClassLoader();
+ }
+ final Mapper mapper = MAPPER_BY_LOADER.get(loader);
+ if (mapper == null) {
+ return newMapper();
+ }
+ return mapper;
+ }
+
+ private static Mapper newMapper() {
+ return new MapperBuilder().build();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/29a79edb/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/jsr/JsrArrayDecoder.java
----------------------------------------------------------------------
diff --git a/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/jsr/JsrArrayDecoder.java b/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/jsr/JsrArrayDecoder.java
new file mode 100644
index 0000000..284b036
--- /dev/null
+++ b/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/jsr/JsrArrayDecoder.java
@@ -0,0 +1,31 @@
+/*
+ * 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.websocket.jsr;
+
+import org.apache.johnzon.websocket.internal.jsr.JsrDecoder;
+
+import javax.json.JsonArray;
+import javax.json.JsonReader;
+
+public class JsrArrayDecoder extends JsrDecoder<JsonArray> {
+ @Override
+ protected JsonArray doRead(JsonReader jsonReader) {
+ return jsonReader.readArray();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/29a79edb/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/jsr/JsrArrayEncoder.java
----------------------------------------------------------------------
diff --git a/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/jsr/JsrArrayEncoder.java b/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/jsr/JsrArrayEncoder.java
new file mode 100644
index 0000000..9eb02f8
--- /dev/null
+++ b/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/jsr/JsrArrayEncoder.java
@@ -0,0 +1,31 @@
+/*
+ * 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.websocket.jsr;
+
+import org.apache.johnzon.websocket.internal.jsr.JsrEncoder;
+
+import javax.json.JsonArray;
+import javax.json.JsonWriter;
+
+public class JsrArrayEncoder extends JsrEncoder<JsonArray> {
+ @Override
+ protected void doWrite(final JsonWriter writer, final JsonArray array) {
+ writer.writeArray(array);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/29a79edb/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/jsr/JsrObjectDecoder.java
----------------------------------------------------------------------
diff --git a/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/jsr/JsrObjectDecoder.java b/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/jsr/JsrObjectDecoder.java
new file mode 100644
index 0000000..c63bfaa
--- /dev/null
+++ b/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/jsr/JsrObjectDecoder.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.websocket.jsr;
+
+import org.apache.johnzon.websocket.internal.jsr.JsrDecoder;
+
+import javax.json.JsonObject;
+import javax.json.JsonReader;
+import javax.json.JsonReaderFactory;
+
+public class JsrObjectDecoder extends JsrDecoder<JsonObject> {
+ private JsonReaderFactory factory;
+
+ @Override
+ protected JsonObject doRead(final JsonReader jsonReader) {
+ return jsonReader.readObject();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/29a79edb/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/jsr/JsrObjectEncoder.java
----------------------------------------------------------------------
diff --git a/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/jsr/JsrObjectEncoder.java b/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/jsr/JsrObjectEncoder.java
new file mode 100644
index 0000000..b5cd180
--- /dev/null
+++ b/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/jsr/JsrObjectEncoder.java
@@ -0,0 +1,31 @@
+/*
+ * 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.websocket.jsr;
+
+import org.apache.johnzon.websocket.internal.jsr.JsrEncoder;
+
+import javax.json.JsonObject;
+import javax.json.JsonWriter;
+
+public class JsrObjectEncoder extends JsrEncoder<JsonObject> {
+ @Override
+ protected void doWrite(final JsonWriter writer, final JsonObject jsonObject) {
+ writer.writeObject(jsonObject);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/29a79edb/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/jsr/JsrStructureDecoder.java
----------------------------------------------------------------------
diff --git a/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/jsr/JsrStructureDecoder.java b/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/jsr/JsrStructureDecoder.java
new file mode 100644
index 0000000..f4ad438
--- /dev/null
+++ b/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/jsr/JsrStructureDecoder.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.websocket.jsr;
+
+import org.apache.johnzon.websocket.internal.jsr.JsrDecoder;
+
+import javax.json.JsonReader;
+import javax.json.JsonReaderFactory;
+import javax.json.JsonStructure;
+
+public class JsrStructureDecoder extends JsrDecoder<JsonStructure> {
+ private JsonReaderFactory factory;
+
+ @Override
+ protected JsonStructure doRead(final JsonReader jsonReader) {
+ return jsonReader.read();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/29a79edb/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/jsr/JsrStructureEncoder.java
----------------------------------------------------------------------
diff --git a/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/jsr/JsrStructureEncoder.java b/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/jsr/JsrStructureEncoder.java
new file mode 100644
index 0000000..69169f3
--- /dev/null
+++ b/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/jsr/JsrStructureEncoder.java
@@ -0,0 +1,31 @@
+/*
+ * 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.websocket.jsr;
+
+import org.apache.johnzon.websocket.internal.jsr.JsrEncoder;
+
+import javax.json.JsonStructure;
+import javax.json.JsonWriter;
+
+public class JsrStructureEncoder extends JsrEncoder<JsonStructure> {
+ @Override
+ protected void doWrite(final JsonWriter writer, final JsonStructure structure) {
+ writer.write(structure);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/29a79edb/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/mapper/JohnzonTextDecoder.java
----------------------------------------------------------------------
diff --git a/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/mapper/JohnzonTextDecoder.java b/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/mapper/JohnzonTextDecoder.java
new file mode 100644
index 0000000..4530966
--- /dev/null
+++ b/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/mapper/JohnzonTextDecoder.java
@@ -0,0 +1,110 @@
+/*
+ * 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.websocket.mapper;
+
+import org.apache.johnzon.mapper.Mapper;
+import org.apache.johnzon.websocket.internal.mapper.MapperLocator;
+
+import java.io.Reader;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import javax.websocket.DecodeException;
+import javax.websocket.Decoder;
+import javax.websocket.EndpointConfig;
+import javax.websocket.OnMessage;
+import javax.websocket.Session;
+import javax.websocket.server.PathParam;
+import javax.websocket.server.ServerEndpointConfig;
+
+public class JohnzonTextDecoder implements Decoder.TextStream<Object> {
+ protected Mapper mapper;
+ protected Type type;
+
+ public JohnzonTextDecoder() {
+ // no-op
+ }
+
+ // for client side no way to guess the type so let the user provide it easily
+ public JohnzonTextDecoder(final Type type) {
+ this(null, type);
+ }
+
+ public JohnzonTextDecoder(final Mapper mapper, final Type type) {
+ this.mapper = mapper;
+ this.type = type;
+ }
+
+ @Override
+ public Object decode(final Reader stream) throws DecodeException {
+ return mapper.readObject(stream, type);
+ }
+
+ @Override
+ public void init(final EndpointConfig endpointConfig) {
+ if (mapper == null) {
+ mapper = MapperLocator.locate();
+ }
+ if (type != null) {
+ return;
+ }
+
+ if (ServerEndpointConfig.class.isInstance(endpointConfig)) {
+ final Class<?> endpointClass = ServerEndpointConfig.class.cast(endpointConfig).getEndpointClass();
+ for (final Method m : endpointClass.getMethods()) {
+ if (Object.class == m.getDeclaringClass()) {
+ continue;
+ }
+ if (m.getAnnotation(OnMessage.class) != null) {
+ final Type[] genericParameterTypes = m.getGenericParameterTypes();
+ for (int i = 0; i < genericParameterTypes.length; i++) {
+ if (genericParameterTypes[i] == Session.class) {
+ continue;
+ }
+ boolean param = false;
+ for (final Annotation a : m.getParameterAnnotations()[i]) {
+ if (PathParam.class == a.annotationType()) {
+ param = true;
+ break;
+ }
+ }
+ if (!param) {
+ this.type = genericParameterTypes[i];
+ break;
+ }
+ }
+ break;
+ }
+ }
+ if (type == null) {
+ throw new IllegalArgumentException("didn't find @OnMessage in " + endpointClass);
+ }
+ } else {
+ type = Type.class.cast(endpointConfig.getUserProperties().get("johnzon.websocket.message.type"));
+ if (type == null) {
+ throw new IllegalArgumentException("didn't find johnzon.websocket.message.type");
+ }
+ }
+ }
+
+ @Override
+ public void destroy() {
+ // no-op
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/29a79edb/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/mapper/JohnzonTextEncoder.java
----------------------------------------------------------------------
diff --git a/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/mapper/JohnzonTextEncoder.java b/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/mapper/JohnzonTextEncoder.java
new file mode 100644
index 0000000..964c3b5
--- /dev/null
+++ b/johnzon-websocket/src/main/java/org/apache/johnzon/websocket/mapper/JohnzonTextEncoder.java
@@ -0,0 +1,47 @@
+/*
+ * 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.websocket.mapper;
+
+import org.apache.johnzon.mapper.Mapper;
+import org.apache.johnzon.websocket.internal.mapper.MapperLocator;
+
+import java.io.IOException;
+import java.io.Writer;
+import javax.websocket.EncodeException;
+import javax.websocket.Encoder;
+import javax.websocket.EndpointConfig;
+
+public class JohnzonTextEncoder implements Encoder.TextStream<Object> {
+ private Mapper mapper;
+
+ @Override
+ public void init(final EndpointConfig endpointConfig) {
+ mapper = MapperLocator.locate();
+ }
+
+ @Override
+ public void destroy() {
+ // no-op
+ }
+
+ @Override
+ public void encode(final Object object, final Writer writer) throws EncodeException, IOException {
+ mapper.writeObject(object, writer);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/29a79edb/johnzon-websocket/src/test/java/org/apache/johnzon/websocket/JsrCodecTest.java
----------------------------------------------------------------------
diff --git a/johnzon-websocket/src/test/java/org/apache/johnzon/websocket/JsrCodecTest.java b/johnzon-websocket/src/test/java/org/apache/johnzon/websocket/JsrCodecTest.java
new file mode 100644
index 0000000..9fc860e
--- /dev/null
+++ b/johnzon-websocket/src/test/java/org/apache/johnzon/websocket/JsrCodecTest.java
@@ -0,0 +1,93 @@
+/*
+ * 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.websocket;
+
+import org.apache.johnzon.core.JsonProviderImpl;
+import org.apache.johnzon.websocket.endpoint.JsrClientEndpointImpl;
+import org.apache.johnzon.websocket.endpoint.JsrServerEndpointImpl;
+import org.apache.johnzon.websocket.endpoint.Message;
+import org.apache.johnzon.websocket.endpoint.ServerReport;
+import org.apache.johnzon.websocket.internal.jsr.FactoryLocator;
+import org.apache.johnzon.websocket.internal.jsr.JsrDecoder;
+import org.apache.johnzon.websocket.internal.jsr.JsrEncoder;
+import org.apache.johnzon.websocket.jsr.JsrObjectDecoder;
+import org.apache.johnzon.websocket.jsr.JsrObjectEncoder;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.arquillian.test.api.ArquillianResource;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.JavaArchive;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.net.URI;
+import java.net.URL;
+import javax.json.Json;
+import javax.json.JsonObject;
+import javax.websocket.CloseReason;
+import javax.websocket.ContainerProvider;
+import javax.websocket.Session;
+import javax.websocket.WebSocketContainer;
+
+import static org.apache.openejb.loader.JarLocation.jarLocation;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+@RunWith(Arquillian.class)
+public class JsrCodecTest {
+ @Deployment(testable = false)
+ public static WebArchive war() {
+ return ShrinkWrap.create(WebArchive.class, "jsr-codec.war")
+ .addClasses(JsrServerEndpointImpl.class, ServerReport.class, Message.class /* for report endpoint */)
+ .addAsLibrary(
+ ShrinkWrap.create(JavaArchive.class, "johnzon-websocket.jar")
+ .addClasses(FactoryLocator.class, JsrDecoder.class, JsrEncoder.class, JsrObjectDecoder.class, JsrObjectEncoder.class))
+ .addAsLibraries(
+ jarLocation(Json.class),
+ jarLocation(JsonProviderImpl.class));
+ }
+
+ @ArquillianResource
+ private URL url;
+
+ @Test
+ public void codec() throws Exception {
+ JsrClientEndpointImpl.MESSAGES.clear();
+
+ final WebSocketContainer container = ContainerProvider.getWebSocketContainer();
+ final Session session = container.connectToServer(
+ JsrClientEndpointImpl.class,
+ new URI("ws://localhost:" + url.getPort() + url.getPath() + "jsrserver"));
+
+ session.getBasicRemote().sendObject(Json.createObjectBuilder().add("value", "jsr@client").build());
+
+ JsrClientEndpointImpl.SEMAPHORE.acquire();
+
+ // it does wait for the server, using same jaxrs provider to match format, it uses jettison which is weird but we don't care for that part of test
+ final JsonObject serverMessage = Json.createReader(new URL(url.toExternalForm() + "report/jsr").openStream()).readObject();
+
+ session.close(new CloseReason(CloseReason.CloseCodes.GOING_AWAY, "bye"));
+
+ assertNotNull(serverMessage);
+ assertEquals("jsr@client", serverMessage.getString("value"));
+ assertEquals(1, JsrClientEndpointImpl.MESSAGES.size());
+ assertEquals("jsr@server", JsrClientEndpointImpl.MESSAGES.iterator().next().getString("value"));
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/29a79edb/johnzon-websocket/src/test/java/org/apache/johnzon/websocket/MapperCodecTest.java
----------------------------------------------------------------------
diff --git a/johnzon-websocket/src/test/java/org/apache/johnzon/websocket/MapperCodecTest.java b/johnzon-websocket/src/test/java/org/apache/johnzon/websocket/MapperCodecTest.java
new file mode 100644
index 0000000..1212941
--- /dev/null
+++ b/johnzon-websocket/src/test/java/org/apache/johnzon/websocket/MapperCodecTest.java
@@ -0,0 +1,95 @@
+/*
+ * 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.websocket;
+
+import org.apache.johnzon.core.JsonProviderImpl;
+import org.apache.johnzon.mapper.Mapper;
+import org.apache.johnzon.mapper.MapperBuilder;
+import org.apache.johnzon.websocket.endpoint.ClientEndpointImpl;
+import org.apache.johnzon.websocket.endpoint.Message;
+import org.apache.johnzon.websocket.endpoint.ServerEndpointImpl;
+import org.apache.johnzon.websocket.endpoint.ServerReport;
+import org.apache.johnzon.websocket.internal.mapper.MapperLocator;
+import org.apache.johnzon.websocket.mapper.JohnzonTextDecoder;
+import org.apache.johnzon.websocket.mapper.JohnzonTextEncoder;
+import org.apache.openejb.arquillian.common.IO;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.arquillian.test.api.ArquillianResource;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.JavaArchive;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.net.URI;
+import java.net.URL;
+import javax.json.Json;
+import javax.websocket.CloseReason;
+import javax.websocket.ContainerProvider;
+import javax.websocket.Session;
+import javax.websocket.WebSocketContainer;
+
+import static org.apache.openejb.loader.JarLocation.jarLocation;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+@RunWith(Arquillian.class)
+public class MapperCodecTest {
+ @Deployment(testable = false)
+ public static WebArchive war() {
+ return ShrinkWrap.create(WebArchive.class, "codec.war")
+ .addClasses(ServerEndpointImpl.class, ServerReport.class, Message.class)
+ .addAsLibrary(
+ ShrinkWrap.create(JavaArchive.class, "johnzon-websocket.jar")
+ .addClasses(MapperLocator.class, JohnzonTextDecoder.class, JohnzonTextEncoder.class))
+ .addAsLibraries(
+ jarLocation(Json.class),
+ jarLocation(JsonProviderImpl.class),
+ jarLocation(Mapper.class));
+ }
+
+ @ArquillianResource
+ private URL url;
+
+ @Test
+ public void codec() throws Exception {
+ ClientEndpointImpl.MESSAGES.clear();
+ ClientEndpointImpl.SEMAPHORE.acquire(ClientEndpointImpl.SEMAPHORE.availablePermits());
+
+ final WebSocketContainer container = ContainerProvider.getWebSocketContainer();
+ final Session session = container.connectToServer(
+ ClientEndpointImpl.class,
+ new URI("ws://localhost:" + url.getPort() + url.getPath() + "server"));
+
+ session.getBasicRemote().sendObject(new Message("client"));
+
+ ClientEndpointImpl.SEMAPHORE.acquire();
+
+ // it does wait for the server, using same jaxrs provider to match format, it uses jettison which is weird but we don't care for that part of test
+ final Message serverMessage = new MapperBuilder().build().readObject(IO.slurp(new URL(url.toExternalForm() + "report/annotation")), Message.class);
+
+ session.close(new CloseReason(CloseReason.CloseCodes.GOING_AWAY, "bye"));
+
+ assertNotNull(serverMessage);
+ assertEquals("client", serverMessage.getValue());
+ assertEquals(1, ClientEndpointImpl.MESSAGES.size());
+ assertEquals("server", ClientEndpointImpl.MESSAGES.iterator().next().getValue());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/29a79edb/johnzon-websocket/src/test/java/org/apache/johnzon/websocket/endpoint/ClientEndpointImpl.java
----------------------------------------------------------------------
diff --git a/johnzon-websocket/src/test/java/org/apache/johnzon/websocket/endpoint/ClientEndpointImpl.java b/johnzon-websocket/src/test/java/org/apache/johnzon/websocket/endpoint/ClientEndpointImpl.java
new file mode 100644
index 0000000..10020ad
--- /dev/null
+++ b/johnzon-websocket/src/test/java/org/apache/johnzon/websocket/endpoint/ClientEndpointImpl.java
@@ -0,0 +1,53 @@
+/*
+ * 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.websocket.endpoint;
+
+import org.apache.johnzon.websocket.mapper.JohnzonTextDecoder;
+import org.apache.johnzon.websocket.mapper.JohnzonTextEncoder;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.Semaphore;
+import javax.websocket.ClientEndpoint;
+import javax.websocket.EndpointConfig;
+import javax.websocket.OnMessage;
+import javax.websocket.OnOpen;
+
+@ClientEndpoint(encoders = JohnzonTextEncoder.class, decoders = ClientEndpointImpl.MessageDecoder.class)
+public class ClientEndpointImpl {
+ public static final List<Message> MESSAGES = new LinkedList<Message>();
+ public static final Semaphore SEMAPHORE = new Semaphore(0);
+
+ @OnOpen
+ public void init(final EndpointConfig config) {
+
+ }
+
+ @OnMessage
+ public synchronized void on(final Message message) {
+ MESSAGES.add(message);
+ SEMAPHORE.release();
+ }
+
+ public static class MessageDecoder extends JohnzonTextDecoder {
+ public MessageDecoder() {
+ type = Message.class;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/29a79edb/johnzon-websocket/src/test/java/org/apache/johnzon/websocket/endpoint/JsrClientEndpointImpl.java
----------------------------------------------------------------------
diff --git a/johnzon-websocket/src/test/java/org/apache/johnzon/websocket/endpoint/JsrClientEndpointImpl.java b/johnzon-websocket/src/test/java/org/apache/johnzon/websocket/endpoint/JsrClientEndpointImpl.java
new file mode 100644
index 0000000..644585e
--- /dev/null
+++ b/johnzon-websocket/src/test/java/org/apache/johnzon/websocket/endpoint/JsrClientEndpointImpl.java
@@ -0,0 +1,41 @@
+/*
+ * 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.websocket.endpoint;
+
+import org.apache.johnzon.websocket.jsr.JsrObjectDecoder;
+import org.apache.johnzon.websocket.jsr.JsrObjectEncoder;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.Semaphore;
+import javax.json.JsonObject;
+import javax.websocket.ClientEndpoint;
+import javax.websocket.OnMessage;
+
+@ClientEndpoint(encoders = JsrObjectEncoder.class, decoders = JsrObjectDecoder.class)
+public class JsrClientEndpointImpl {
+ public static final List<JsonObject> MESSAGES = new LinkedList<JsonObject>();
+ public static final Semaphore SEMAPHORE = new Semaphore(0);
+
+ @OnMessage
+ public synchronized void on(final JsonObject message) {
+ MESSAGES.add(message);
+ SEMAPHORE.release();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/29a79edb/johnzon-websocket/src/test/java/org/apache/johnzon/websocket/endpoint/JsrServerEndpointImpl.java
----------------------------------------------------------------------
diff --git a/johnzon-websocket/src/test/java/org/apache/johnzon/websocket/endpoint/JsrServerEndpointImpl.java b/johnzon-websocket/src/test/java/org/apache/johnzon/websocket/endpoint/JsrServerEndpointImpl.java
new file mode 100644
index 0000000..a442259
--- /dev/null
+++ b/johnzon-websocket/src/test/java/org/apache/johnzon/websocket/endpoint/JsrServerEndpointImpl.java
@@ -0,0 +1,50 @@
+/*
+ * 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.websocket.endpoint;
+
+import org.apache.johnzon.websocket.jsr.JsrObjectDecoder;
+import org.apache.johnzon.websocket.jsr.JsrObjectEncoder;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.Semaphore;
+import javax.json.Json;
+import javax.json.JsonObject;
+import javax.json.JsonObjectBuilder;
+import javax.websocket.EncodeException;
+import javax.websocket.OnMessage;
+import javax.websocket.Session;
+import javax.websocket.server.ServerEndpoint;
+
+@ServerEndpoint(value = "/jsrserver", encoders = JsrObjectEncoder.class, decoders = JsrObjectDecoder.class)
+public class JsrServerEndpointImpl {
+ public static final List<JsonObject> MESSAGES = new LinkedList<JsonObject>();
+ public static final Semaphore SEMAPHORE = new Semaphore(0);
+
+ @OnMessage
+ public synchronized void on(final Session session, final JsonObject message) throws IOException, EncodeException {
+ MESSAGES.add(message);
+ SEMAPHORE.release();
+
+ final JsonObjectBuilder builder = Json.createBuilderFactory(Collections.<String, Object>emptyMap()).createObjectBuilder();
+ session.getBasicRemote().sendObject(builder.add("value", "jsr@server").build());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/29a79edb/johnzon-websocket/src/test/java/org/apache/johnzon/websocket/endpoint/Message.java
----------------------------------------------------------------------
diff --git a/johnzon-websocket/src/test/java/org/apache/johnzon/websocket/endpoint/Message.java b/johnzon-websocket/src/test/java/org/apache/johnzon/websocket/endpoint/Message.java
new file mode 100644
index 0000000..99f2d24
--- /dev/null
+++ b/johnzon-websocket/src/test/java/org/apache/johnzon/websocket/endpoint/Message.java
@@ -0,0 +1,42 @@
+/*
+ * 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.websocket.endpoint;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement // old tomee default json provider (pre-johnzon erea) was using jaxb
+public class Message {
+ private String value;
+
+ public Message() {
+ // no-op
+ }
+
+ public Message(final String msg) {
+ this.value = msg;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(final String value) {
+ this.value = value;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/29a79edb/johnzon-websocket/src/test/java/org/apache/johnzon/websocket/endpoint/ServerEndpointImpl.java
----------------------------------------------------------------------
diff --git a/johnzon-websocket/src/test/java/org/apache/johnzon/websocket/endpoint/ServerEndpointImpl.java b/johnzon-websocket/src/test/java/org/apache/johnzon/websocket/endpoint/ServerEndpointImpl.java
new file mode 100644
index 0000000..ae42c88
--- /dev/null
+++ b/johnzon-websocket/src/test/java/org/apache/johnzon/websocket/endpoint/ServerEndpointImpl.java
@@ -0,0 +1,44 @@
+/*
+ * 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.websocket.endpoint;
+
+import org.apache.johnzon.websocket.mapper.JohnzonTextDecoder;
+import org.apache.johnzon.websocket.mapper.JohnzonTextEncoder;
+
+import java.io.IOException;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.Semaphore;
+import javax.websocket.EncodeException;
+import javax.websocket.OnMessage;
+import javax.websocket.Session;
+import javax.websocket.server.ServerEndpoint;
+
+@ServerEndpoint(value = "/server", encoders = JohnzonTextEncoder.class, decoders = JohnzonTextDecoder.class)
+public class ServerEndpointImpl {
+ public static final List<Message> MESSAGES = new LinkedList<Message>();
+ public static final Semaphore SEMAPHORE = new Semaphore(0);
+
+ @OnMessage
+ public synchronized void on(final Session session, final Message message) throws IOException, EncodeException {
+ MESSAGES.add(message);
+ SEMAPHORE.release();
+ session.getBasicRemote().sendObject(new Message("server"));
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/29a79edb/johnzon-websocket/src/test/java/org/apache/johnzon/websocket/endpoint/ServerReport.java
----------------------------------------------------------------------
diff --git a/johnzon-websocket/src/test/java/org/apache/johnzon/websocket/endpoint/ServerReport.java b/johnzon-websocket/src/test/java/org/apache/johnzon/websocket/endpoint/ServerReport.java
new file mode 100644
index 0000000..3fc211b
--- /dev/null
+++ b/johnzon-websocket/src/test/java/org/apache/johnzon/websocket/endpoint/ServerReport.java
@@ -0,0 +1,71 @@
+/*
+ * 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.websocket.endpoint;
+
+import org.apache.johnzon.mapper.MapperBuilder;
+
+import java.io.StringWriter;
+import java.util.concurrent.TimeUnit;
+import javax.json.Json;
+import javax.json.JsonWriter;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+@Path("report")
+@Produces(MediaType.APPLICATION_JSON)
+public class ServerReport {
+ @GET
+ @Path("annotation")
+ public String amessage() {
+ try {
+ if (!ServerEndpointImpl.SEMAPHORE.tryAcquire(1, TimeUnit.MINUTES)) {
+ throw new IllegalStateException("acquire failed");
+ }
+ } catch (final InterruptedException e) {
+ Thread.interrupted();
+ return null;
+ }
+
+ // don't setup (+dependency) for just this method the mapper jaxrs provider
+ return new MapperBuilder().build().writeObjectAsString(ServerEndpointImpl.MESSAGES.iterator().next());
+ }
+
+ @GET
+ @Path("jsr")
+ @Produces(MediaType.APPLICATION_JSON)
+ public String pmessage() {
+ try {
+ if (!JsrServerEndpointImpl.SEMAPHORE.tryAcquire(1, TimeUnit.MINUTES)) {
+ throw new IllegalStateException("acquire failed");
+ }
+ } catch (final InterruptedException e) {
+ Thread.interrupted();
+ return null;
+ }
+
+ // don't setup (+dependency) for just this method the jsr jaxrs provider
+ final StringWriter output = new StringWriter();
+ final JsonWriter writer = Json.createWriter(output);
+ writer.write(JsrServerEndpointImpl.MESSAGES.iterator().next());
+ writer.close();
+ return output.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/29a79edb/johnzon-websocket/src/test/resources/arquillian.xml
----------------------------------------------------------------------
diff --git a/johnzon-websocket/src/test/resources/arquillian.xml b/johnzon-websocket/src/test/resources/arquillian.xml
new file mode 100644
index 0000000..c86d7a3
--- /dev/null
+++ b/johnzon-websocket/src/test/resources/arquillian.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+<!--
+ 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.
+-->
+<arquillian xmlns="http://jboss.org/schema/arquillian"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ http://jboss.org/schema/arquillian
+ http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
+ <container qualifier="tomee" default="true">
+ <configuration>
+ <property name="classifier">jaxrs</property>
+ <property name="httpsPort">-1</property>
+ <property name="httpPort">-1</property>
+ <property name="stopPort">-1</property>
+ <property name="ajpPort">-1</property>
+ <property name="simpleLog">true</property>
+ <property name="cleanOnStartUp">true</property>
+ <property name="dir">target/apache-tomee-remote</property>
+ <property name="appWorkingDir">target/arquillian-test-working-dir</property>
+ </configuration>
+ </container>
+</arquillian>
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/29a79edb/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index a848fc2..0aef897 100644
--- a/pom.xml
+++ b/pom.xml
@@ -51,6 +51,7 @@
<module>johnzon-core</module>
<module>johnzon-mapper</module>
<module>johnzon-jaxrs</module>
+ <module>johnzon-websocket</module>
</modules>
<dependencies>