Splitting the client/server example into three independent modules
authorJaroslav Tulach <jtulach@netbeans.org>
Mon, 06 May 2013 17:40:19 +0200
changeset 13fd9a16bbfd0e
parent 12 84266695c06f
child 14 7d1be0cc9595
child 15 91219d000cb8
Splitting the client/server example into three independent modules
chat/client/bck2brwsr-assembly.xml
chat/client/pom.xml
chat/client/src/main/java/org/apidesign/html/chatserver/client/ChatClient.java
chat/client/src/main/resources/org/apidesign/html/chatserver/client/chat.html
chat/client/src/test/java/org/apidesign/html/chatserver/client/ChatClientTest.java
chat/model/pom.xml
chat/model/src/main/java/org/apidesign/html/chatserver/model/MessageImpl.java
chat/model/src/test/java/org/apidesign/html/chatserver/model/MessageImplTest.java
chat/pom.xml
chat/server/nbactions.xml
chat/server/pom.xml
chat/server/src/main/java/org/apidesign/bck2brwsr/demo/chatserver/impl/ChatServerResource.java
chat/server/src/main/java/org/apidesign/bck2brwsr/demo/chatserver/impl/ClientPagesResource.java
chat/server/src/main/java/org/apidesign/bck2brwsr/demo/chatserver/impl/Main.java
pom.xml
serverside/nbactions.xml
serverside/pom.xml
serverside/src/main/java/org/apidesign/bck2brwsr/demo/serverside/ChatClient.java
serverside/src/main/java/org/apidesign/bck2brwsr/demo/serverside/ChatServerResource.java
serverside/src/main/java/org/apidesign/bck2brwsr/demo/serverside/MessageImpl.java
serverside/src/main/resources/org/apidesign/bck2brwsr/demo/serverside/chat.html
serverside/src/test/java/org/apidesign/bck2brwsr/demo/serverside/ChatClientTest.java
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/chat/client/bck2brwsr-assembly.xml	Mon May 06 17:40:19 2013 +0200
     1.3 @@ -0,0 +1,67 @@
     1.4 +<?xml version="1.0"?>
     1.5 +<!--
     1.6 +
     1.7 +    The MIT License (MIT)
     1.8 +
     1.9 +    Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    1.10 +
    1.11 +    Permission is hereby granted, free of charge, to any person obtaining a copy
    1.12 +    of this software and associated documentation files (the "Software"), to deal
    1.13 +    in the Software without restriction, including without limitation the rights
    1.14 +    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    1.15 +    copies of the Software, and to permit persons to whom the Software is
    1.16 +    furnished to do so, subject to the following conditions:
    1.17 +
    1.18 +    The above copyright notice and this permission notice shall be included in
    1.19 +    all copies or substantial portions of the Software.
    1.20 +
    1.21 +    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    1.22 +    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    1.23 +    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    1.24 +    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    1.25 +    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    1.26 +    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    1.27 +    THE SOFTWARE.
    1.28 +
    1.29 +-->
    1.30 +<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    1.31 +  xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
    1.32 +  
    1.33 +  <id>bck2brwsr</id>
    1.34 +  <formats>
    1.35 +      <format>zip</format>
    1.36 +  </formats>
    1.37 +  <baseDirectory>client</baseDirectory>
    1.38 +  <dependencySets>
    1.39 +    <dependencySet>
    1.40 +        <useProjectArtifact>false</useProjectArtifact>
    1.41 +        <scope>runtime</scope>
    1.42 +        <outputDirectory>lib</outputDirectory>
    1.43 +        <includes>
    1.44 +            <include>*:jar</include>
    1.45 +            <include>*:rt</include>
    1.46 +        </includes>
    1.47 +    </dependencySet>
    1.48 +    <dependencySet>
    1.49 +        <useProjectArtifact>false</useProjectArtifact>
    1.50 +        <scope>provided</scope>
    1.51 +        <includes>
    1.52 +            <include>*:js</include>
    1.53 +        </includes>
    1.54 +        <unpack>true</unpack>
    1.55 +        <outputDirectory>/</outputDirectory>
    1.56 +    </dependencySet>
    1.57 +  </dependencySets> 
    1.58 +  <files>
    1.59 +    <file>
    1.60 +      <source>${project.build.directory}/${project.build.finalName}.jar</source>
    1.61 +      <outputDirectory>/</outputDirectory>
    1.62 +    </file>
    1.63 +    <file>
    1.64 +      <source>${project.build.directory}/classes/org/apidesign/html/chatserver/client/chat.html</source>
    1.65 +      <outputDirectory>/</outputDirectory>
    1.66 +      <destName>index.html</destName>
    1.67 +    </file>
    1.68 +  </files>
    1.69 +
    1.70 +</assembly>
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/chat/client/pom.xml	Mon May 06 17:40:19 2013 +0200
     2.3 @@ -0,0 +1,121 @@
     2.4 +<?xml version="1.0" encoding="UTF-8"?>
     2.5 +<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">
     2.6 +  <modelVersion>4.0.0</modelVersion>
     2.7 +  <parent>
     2.8 +    <artifactId>chat-demo</artifactId>
     2.9 +    <groupId>org.apidesign.html</groupId>
    2.10 +    <version>1.0-SNAPSHOT</version>
    2.11 +  </parent>
    2.12 +
    2.13 +  <groupId>org.apidesign.html.demo</groupId>
    2.14 +  <artifactId>chat-client</artifactId>
    2.15 +  <version>1.0-SNAPSHOT</version>
    2.16 +  <packaging>jar</packaging>
    2.17 +
    2.18 +  <name>Chat Client Bck2Brwsr</name>
    2.19 +
    2.20 +  <repositories>
    2.21 +      <repository>
    2.22 +          <id>java.net</id>
    2.23 +          <name>Java.net</name>
    2.24 +          <url>https://maven.java.net/content/repositories/releases/</url>
    2.25 +          <snapshots>
    2.26 +          </snapshots>
    2.27 +      </repository>
    2.28 +      <repository>
    2.29 +          <id>netbeans</id>
    2.30 +          <name>NetBeans</name>
    2.31 +          <url>http://bits.netbeans.org/maven2/</url>
    2.32 +      </repository>
    2.33 +  </repositories>
    2.34 +  <pluginRepositories>
    2.35 +      <pluginRepository>
    2.36 +          <id>java.net</id>
    2.37 +          <name>Java.net</name>
    2.38 +          <url>https://maven.java.net/content/repositories/releases/</url>
    2.39 +          <snapshots>
    2.40 +          </snapshots>
    2.41 +      </pluginRepository>
    2.42 +  </pluginRepositories>
    2.43 +
    2.44 +  <properties>
    2.45 +    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    2.46 +  </properties>
    2.47 +  <build>
    2.48 +      <plugins>
    2.49 +         <plugin>
    2.50 +             <groupId>org.apache.maven.plugins</groupId>
    2.51 +             <artifactId>maven-jar-plugin</artifactId>
    2.52 +             <version>2.4</version>
    2.53 +             <configuration>
    2.54 +                 <archive>
    2.55 +                     <manifest>
    2.56 +                         <addClasspath>true</addClasspath>
    2.57 +                         <classpathPrefix>lib/</classpathPrefix>
    2.58 +                     </manifest>
    2.59 +                 </archive>
    2.60 +             </configuration>
    2.61 +         </plugin>
    2.62 +         <plugin>
    2.63 +             <artifactId>maven-assembly-plugin</artifactId>
    2.64 +             <version>2.4</version>
    2.65 +             <executions>
    2.66 +                 <execution>
    2.67 +                     <id>distro-assembly</id>
    2.68 +                     <phase>package</phase>
    2.69 +                     <goals>
    2.70 +                         <goal>single</goal>
    2.71 +                     </goals>
    2.72 +                     <configuration>
    2.73 +                         <descriptors>
    2.74 +                             <descriptor>bck2brwsr-assembly.xml</descriptor>
    2.75 +                         </descriptors>
    2.76 +                     </configuration>
    2.77 +                 </execution>
    2.78 +             </executions>                
    2.79 +         </plugin>      
    2.80 +      </plugins>
    2.81 +  </build>
    2.82 +
    2.83 +  <dependencies>
    2.84 +    <dependency>
    2.85 +      <groupId>org.apidesign.html</groupId>
    2.86 +      <artifactId>net.java.html.json</artifactId>
    2.87 +      <version>${net.java.html.version}</version>
    2.88 +      <type>jar</type>
    2.89 +    </dependency>
    2.90 +    <dependency>
    2.91 +      <groupId>${project.groupId}</groupId>
    2.92 +      <artifactId>chat-model</artifactId>
    2.93 +      <version>${project.version}</version>
    2.94 +    </dependency>
    2.95 +    <dependency>
    2.96 +      <groupId>org.testng</groupId>
    2.97 +      <artifactId>testng</artifactId>
    2.98 +      <version>6.8</version>
    2.99 +      <scope>test</scope>
   2.100 +      <type>jar</type>
   2.101 +    </dependency>
   2.102 +    <dependency>
   2.103 +        <groupId>org.apidesign.bck2brwsr</groupId>
   2.104 +        <artifactId>emul</artifactId>
   2.105 +        <version>${bck2brwsr.version}</version>
   2.106 +        <classifier>rt</classifier>
   2.107 +        <scope>runtime</scope>
   2.108 +    </dependency>
   2.109 +    <dependency>
   2.110 +        <groupId>org.apidesign.bck2brwsr</groupId>
   2.111 +        <artifactId>vm4brwsr</artifactId>
   2.112 +        <version>${bck2brwsr.version}</version>
   2.113 +        <type>zip</type>
   2.114 +        <classifier>js</classifier>
   2.115 +        <scope>provided</scope>
   2.116 +    </dependency>
   2.117 +    <dependency>
   2.118 +        <groupId>org.apidesign.html</groupId>
   2.119 +        <artifactId>ko-bck2brwsr</artifactId>
   2.120 +        <version>${net.java.html.version}</version>
   2.121 +        <scope>runtime</scope>
   2.122 +    </dependency>
   2.123 +  </dependencies>
   2.124 +</project>
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/chat/client/src/main/java/org/apidesign/html/chatserver/client/ChatClient.java	Mon May 06 17:40:19 2013 +0200
     3.3 @@ -0,0 +1,104 @@
     3.4 +/**
     3.5 + * The MIT License (MIT)
     3.6 + *
     3.7 + * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     3.8 + *
     3.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
    3.10 + * of this software and associated documentation files (the "Software"), to deal
    3.11 + * in the Software without restriction, including without limitation the rights
    3.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    3.13 + * copies of the Software, and to permit persons to whom the Software is
    3.14 + * furnished to do so, subject to the following conditions:
    3.15 + *
    3.16 + * The above copyright notice and this permission notice shall be included in
    3.17 + * all copies or substantial portions of the Software.
    3.18 + *
    3.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    3.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    3.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    3.22 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    3.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    3.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    3.25 + * THE SOFTWARE.
    3.26 + */
    3.27 +package org.apidesign.html.chatserver.client;
    3.28 +
    3.29 +import net.java.html.json.ComputedProperty;
    3.30 +import net.java.html.json.Context;
    3.31 +import net.java.html.json.Function;
    3.32 +import net.java.html.json.Model;
    3.33 +import net.java.html.json.OnReceive;
    3.34 +import net.java.html.json.Property;
    3.35 +import org.apidesign.html.chatserver.model.Message;
    3.36 +import org.apidesign.html.chatserver.model.Query;
    3.37 +
    3.38 +/**
    3.39 + *
    3.40 + * @author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    3.41 + */
    3.42 +@Model(className = "ChatModel", properties = {
    3.43 +    @Property(name = "user", type = String.class),
    3.44 +    @Property(name = "comment", type = String.class),
    3.45 +    @Property(name = "msgs", type = Message.class, array = true)
    3.46 +})
    3.47 +class ChatClient {
    3.48 +    @ComputedProperty
    3.49 +    static boolean sendEnabled(String user, String comment) {
    3.50 +        boolean res = user != null && comment != null && !user.isEmpty() && !comment.isEmpty();
    3.51 +        return res;
    3.52 +    }
    3.53 +    
    3.54 +    @Function
    3.55 +    static void submit(ChatModel m) {
    3.56 +        if (!sendEnabled(m.getUser(), m.getComment())) {
    3.57 +            return;
    3.58 +        }
    3.59 +        m.postComment(m.getUser(), m.getComment());
    3.60 +    }
    3.61 +    
    3.62 +    @OnReceive(url = "/chat/addComment?user={user}&comment={comment}")
    3.63 +    static void postComment(ChatModel m, Message addedMessage) {
    3.64 +        if (addedMessage.getComment().equals(m.getComment())) {
    3.65 +            m.setComment("");
    3.66 +        }
    3.67 +    }
    3.68 +    
    3.69 +    @OnReceive(url = "/chat?since=0")
    3.70 +    static void initialRead(ChatModel m, Query q) {
    3.71 +        m.getMsgs().clear();
    3.72 +        m.getMsgs().addAll(q.getMessages());
    3.73 +        moreMessages(m);
    3.74 +    }
    3.75 +    
    3.76 +    @OnReceive(url = "/chat?since={since}")
    3.77 +    static void updateMsgs(ChatModel m, Query q) {
    3.78 +        m.getMsgs().addAll(q.getMessages());
    3.79 +        moreMessages(m);
    3.80 +    }
    3.81 +    
    3.82 +    private static void moreMessages(ChatModel m) {
    3.83 +        long now = 0;
    3.84 +        for (Message msg : m.getMsgs()) {
    3.85 +            if (now < msg.getSince()) {
    3.86 +                now = msg.getSince();
    3.87 +            }
    3.88 +        }
    3.89 +        m.updateMsgs("" + (now + 1));
    3.90 +    }
    3.91 +    
    3.92 +    static final Context CNTX = Context.findDefault(ChatClient.class);
    3.93 +    static {
    3.94 +        ChatModel chm = new ChatModel(CNTX);
    3.95 +        Message m = new Message(CNTX);
    3.96 +        m.setComment("Waiting for messages from the server...");
    3.97 +        m.setUser("system");
    3.98 +        chm.getMsgs().add(m);
    3.99 +        chm.applyBindings();
   3.100 +        try {
   3.101 +            // XXX: this should not be in static initializer -
   3.102 +            // XXX: prevents unit testing!
   3.103 +            chm.initialRead();
   3.104 +        } catch (Throwable ex) {
   3.105 +        }
   3.106 +    }
   3.107 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/chat/client/src/main/resources/org/apidesign/html/chatserver/client/chat.html	Mon May 06 17:40:19 2013 +0200
     4.3 @@ -0,0 +1,54 @@
     4.4 +<!--
     4.5 +
     4.6 +    The MIT License (MIT)
     4.7 +
     4.8 +    Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     4.9 +
    4.10 +    Permission is hereby granted, free of charge, to any person obtaining a copy
    4.11 +    of this software and associated documentation files (the "Software"), to deal
    4.12 +    in the Software without restriction, including without limitation the rights
    4.13 +    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    4.14 +    copies of the Software, and to permit persons to whom the Software is
    4.15 +    furnished to do so, subject to the following conditions:
    4.16 +
    4.17 +    The above copyright notice and this permission notice shall be included in
    4.18 +    all copies or substantial portions of the Software.
    4.19 +
    4.20 +    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    4.21 +    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    4.22 +    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    4.23 +    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    4.24 +    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    4.25 +    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    4.26 +    THE SOFTWARE.
    4.27 +
    4.28 +-->
    4.29 +<!DOCTYPE html>
    4.30 +<html>
    4.31 +    <head>
    4.32 +        <title>Chat via Jersey Server</title>
    4.33 +        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    4.34 +    </head>
    4.35 +    <body>
    4.36 +        <div>Username:</div>
    4.37 +        <input data-bind="value: user"/>
    4.38 +        <div>Message:</div>
    4.39 +        <input data-bind="value: comment"/>
    4.40 +        <button data-bind="enable: sendEnabled, click: submit">Send</button>
    4.41 +        
    4.42 +        <ul data-bind="foreach: msgs">
    4.43 +            <li>
    4.44 +                <b data-bind="text: user"></b>@<em data-bind="text: at"></em>
    4.45 +                :
    4.46 +                <span data-bind="text: comment"></span>
    4.47 +            </li>
    4.48 +        </ul>
    4.49 +        
    4.50 +        <script src="bck2brwsr.js"></script>
    4.51 +        <script type="text/javascript">
    4.52 +            var vm = bck2brwsr('chat-client-1.0-SNAPSHOT.jar');
    4.53 +            vm.loadClass('org.apidesign.html.chatserver.client.ChatClient');
    4.54 +        </script>
    4.55 +        
    4.56 +    </body>
    4.57 +</html>
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/chat/client/src/test/java/org/apidesign/html/chatserver/client/ChatClientTest.java	Mon May 06 17:40:19 2013 +0200
     5.3 @@ -0,0 +1,51 @@
     5.4 +/**
     5.5 + * The MIT License (MIT)
     5.6 + *
     5.7 + * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     5.8 + *
     5.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
    5.10 + * of this software and associated documentation files (the "Software"), to deal
    5.11 + * in the Software without restriction, including without limitation the rights
    5.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    5.13 + * copies of the Software, and to permit persons to whom the Software is
    5.14 + * furnished to do so, subject to the following conditions:
    5.15 + *
    5.16 + * The above copyright notice and this permission notice shall be included in
    5.17 + * all copies or substantial portions of the Software.
    5.18 + *
    5.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    5.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    5.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    5.22 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    5.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    5.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    5.25 + * THE SOFTWARE.
    5.26 + */
    5.27 +package org.apidesign.html.chatserver.client;
    5.28 +
    5.29 +import net.java.html.json.Context;
    5.30 +import static org.testng.Assert.*;
    5.31 +import org.testng.annotations.Test;
    5.32 +
    5.33 +/**
    5.34 + *
    5.35 + * @author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    5.36 + */
    5.37 +public class ChatClientTest {
    5.38 +    public ChatClientTest() {
    5.39 +    }
    5.40 +    
    5.41 +    @Test public void hasSendEnabled() {
    5.42 +        ChatModel m = new ChatModel(Context.EMPTY);
    5.43 +        assertFalse(m.isSendEnabled(), "By default disabled");
    5.44 +        m.setComment("some msg");
    5.45 +        m.setUser("by me");
    5.46 +        assertTrue(m.isSendEnabled(), "Now it is enabled");
    5.47 +        m.setUser(null);
    5.48 +        assertFalse(m.isSendEnabled(), "No user means disabled");
    5.49 +        m.setUser("by him");
    5.50 +        assertTrue(m.isSendEnabled(), "Again enabled");
    5.51 +        m.setComment("");
    5.52 +        assertFalse(m.isSendEnabled(), "Empty text means disabled");
    5.53 +    }
    5.54 +}
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/chat/model/pom.xml	Mon May 06 17:40:19 2013 +0200
     6.3 @@ -0,0 +1,32 @@
     6.4 +<?xml version="1.0"?>
     6.5 +<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
     6.6 +    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
     6.7 +  <modelVersion>4.0.0</modelVersion>
     6.8 +  <parent>
     6.9 +    <groupId>org.apidesign.html</groupId>
    6.10 +    <artifactId>chat-demo</artifactId>
    6.11 +    <version>1.0-SNAPSHOT</version>
    6.12 +  </parent>
    6.13 +  <groupId>org.apidesign.html.demo</groupId>
    6.14 +  <artifactId>chat-model</artifactId>
    6.15 +  <version>1.0-SNAPSHOT</version>
    6.16 +  <name>Shared Model of a Message</name>
    6.17 +  <url>http://maven.apache.org</url>
    6.18 +    <properties>
    6.19 +    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    6.20 +  </properties>
    6.21 +  <dependencies>
    6.22 +    <dependency>
    6.23 +      <groupId>org.apidesign.html</groupId>
    6.24 +      <artifactId>net.java.html.json</artifactId>
    6.25 +      <version>${net.java.html.version}</version>
    6.26 +      <type>jar</type>
    6.27 +    </dependency>
    6.28 +    <dependency>
    6.29 +      <groupId>org.testng</groupId>
    6.30 +      <artifactId>testng</artifactId>
    6.31 +      <version>6.5.2</version>
    6.32 +      <scope>test</scope>
    6.33 +    </dependency>
    6.34 +  </dependencies>
    6.35 +</project>
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/chat/model/src/main/java/org/apidesign/html/chatserver/model/MessageImpl.java	Mon May 06 17:40:19 2013 +0200
     7.3 @@ -0,0 +1,59 @@
     7.4 +/**
     7.5 + * The MIT License (MIT)
     7.6 + *
     7.7 + * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     7.8 + *
     7.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
    7.10 + * of this software and associated documentation files (the "Software"), to deal
    7.11 + * in the Software without restriction, including without limitation the rights
    7.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    7.13 + * copies of the Software, and to permit persons to whom the Software is
    7.14 + * furnished to do so, subject to the following conditions:
    7.15 + *
    7.16 + * The above copyright notice and this permission notice shall be included in
    7.17 + * all copies or substantial portions of the Software.
    7.18 + *
    7.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    7.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    7.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    7.22 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    7.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    7.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    7.25 + * THE SOFTWARE.
    7.26 + */
    7.27 +package org.apidesign.html.chatserver.model;
    7.28 +
    7.29 +import net.java.html.json.ComputedProperty;
    7.30 +import net.java.html.json.Model;
    7.31 +import net.java.html.json.Property;
    7.32 +
    7.33 +/** Generic model of communication between browser and a chat server.
    7.34 + * The same code is then used on the server, on the client and even in unit 
    7.35 + * tests.
    7.36 + * 
    7.37 + * @author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    7.38 + */
    7.39 +@Model(className = "Message", properties = {
    7.40 +    @Property(name = "user", type = String.class),
    7.41 +    @Property(name = "comment", type = String.class),
    7.42 +    @Property(name = "since", type = long.class)    
    7.43 +})
    7.44 +class MessageImpl {
    7.45 +    @ComputedProperty static String at(long since) {
    7.46 +        long delta = since / 1000;
    7.47 +        if (delta <= 0) {
    7.48 +            return "Boot-time";
    7.49 +        }
    7.50 +        if (delta < 60) {
    7.51 +            return delta + "s";
    7.52 +        }
    7.53 +        delta /= 60;
    7.54 +        return delta + "min";
    7.55 +    }
    7.56 +
    7.57 +    @Model(className = "Query", properties = {
    7.58 +        @Property(name = "messages", type = Message.class, array = true)
    7.59 +    })
    7.60 +    class QryMsgs {
    7.61 +    }
    7.62 +}
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/chat/model/src/test/java/org/apidesign/html/chatserver/model/MessageImplTest.java	Mon May 06 17:40:19 2013 +0200
     8.3 @@ -0,0 +1,46 @@
     8.4 +/**
     8.5 + * The MIT License (MIT)
     8.6 + *
     8.7 + * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     8.8 + *
     8.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
    8.10 + * of this software and associated documentation files (the "Software"), to deal
    8.11 + * in the Software without restriction, including without limitation the rights
    8.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    8.13 + * copies of the Software, and to permit persons to whom the Software is
    8.14 + * furnished to do so, subject to the following conditions:
    8.15 + *
    8.16 + * The above copyright notice and this permission notice shall be included in
    8.17 + * all copies or substantial portions of the Software.
    8.18 + *
    8.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    8.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    8.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    8.22 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    8.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    8.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    8.25 + * THE SOFTWARE.
    8.26 + */
    8.27 +package org.apidesign.html.chatserver.model;
    8.28 +
    8.29 +import net.java.html.json.Context;
    8.30 +import static org.testng.Assert.*;
    8.31 +import org.testng.annotations.Test;
    8.32 +
    8.33 +/**
    8.34 + *
    8.35 + * @author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    8.36 + */
    8.37 +public class MessageImplTest {
    8.38 +    
    8.39 +    @Test public void properlyConvertedToSeconds() {
    8.40 +        Message msg = new Message(Context.EMPTY);
    8.41 +        msg.setSince(5143);
    8.42 +        assertEquals(msg.getAt(), "5s");
    8.43 +    }
    8.44 +    @Test public void properlyConvertedToMinutes() {
    8.45 +        Message msg = new Message(Context.EMPTY);
    8.46 +        msg.setSince(63564);
    8.47 +        assertEquals(msg.getAt(), "1min");
    8.48 +    }
    8.49 +}
    8.50 \ No newline at end of file
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/chat/pom.xml	Mon May 06 17:40:19 2013 +0200
     9.3 @@ -0,0 +1,40 @@
     9.4 +<?xml version="1.0" encoding="UTF-8"?>
     9.5 +<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">
     9.6 +  <modelVersion>4.0.0</modelVersion>
     9.7 +  <parent>
     9.8 +    <artifactId>demo</artifactId>
     9.9 +    <groupId>org.apidesign.html</groupId>
    9.10 +    <version>1.0-SNAPSHOT</version>
    9.11 +  </parent>
    9.12 +  <groupId>org.apidesign.html</groupId>
    9.13 +  <artifactId>chat-demo</artifactId>
    9.14 +  <version>1.0-SNAPSHOT</version>
    9.15 +  <packaging>pom</packaging>
    9.16 +  <name>Chat Server with Jersey and Bck2Brwsr</name>
    9.17 +  <properties>
    9.18 +      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    9.19 +      <net.java.html.version>0.2</net.java.html.version>
    9.20 +      <bck2brwsr.version>0.7</bck2brwsr.version>
    9.21 +      <bck2brwsr.obfuscationlevel>MINIMAL</bck2brwsr.obfuscationlevel>
    9.22 +  </properties>
    9.23 +  <modules>
    9.24 +    <module>model</module>
    9.25 +    <module>client</module>
    9.26 +    <module>server</module>
    9.27 +  </modules>
    9.28 +  <build>
    9.29 +      <pluginManagement>
    9.30 +          <plugins>
    9.31 +              <plugin>
    9.32 +                  <groupId>org.apache.maven.plugins</groupId>
    9.33 +                  <artifactId>maven-compiler-plugin</artifactId>
    9.34 +                  <version>2.3.2</version>
    9.35 +                  <configuration>
    9.36 +                      <source>1.7</source>
    9.37 +                      <target>1.7</target>
    9.38 +                  </configuration>
    9.39 +              </plugin>
    9.40 +          </plugins>
    9.41 +      </pluginManagement>
    9.42 +  </build>
    9.43 +</project>
    9.44 \ No newline at end of file
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/chat/server/nbactions.xml	Mon May 06 17:40:19 2013 +0200
    10.3 @@ -0,0 +1,35 @@
    10.4 +<?xml version="1.0" encoding="UTF-8"?>
    10.5 +<!--
    10.6 +
    10.7 +    The MIT License (MIT)
    10.8 +
    10.9 +    Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
   10.10 +
   10.11 +    Permission is hereby granted, free of charge, to any person obtaining a copy
   10.12 +    of this software and associated documentation files (the "Software"), to deal
   10.13 +    in the Software without restriction, including without limitation the rights
   10.14 +    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   10.15 +    copies of the Software, and to permit persons to whom the Software is
   10.16 +    furnished to do so, subject to the following conditions:
   10.17 +
   10.18 +    The above copyright notice and this permission notice shall be included in
   10.19 +    all copies or substantial portions of the Software.
   10.20 +
   10.21 +    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   10.22 +    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   10.23 +    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   10.24 +    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   10.25 +    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   10.26 +    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   10.27 +    THE SOFTWARE.
   10.28 +
   10.29 +-->
   10.30 +<actions>
   10.31 +    <action>
   10.32 +        <actionName>run</actionName>
   10.33 +        <goals>
   10.34 +            <goal>process-classes</goal>
   10.35 +            <goal>exec:java</goal>
   10.36 +        </goals>
   10.37 +    </action>
   10.38 +</actions>
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/chat/server/pom.xml	Mon May 06 17:40:19 2013 +0200
    11.3 @@ -0,0 +1,105 @@
    11.4 +<?xml version="1.0"?>
    11.5 +<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    11.6 +    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    11.7 +  <modelVersion>4.0.0</modelVersion>
    11.8 +  <parent>
    11.9 +    <groupId>org.apidesign.html</groupId>
   11.10 +    <artifactId>chat-demo</artifactId>
   11.11 +    <version>1.0-SNAPSHOT</version>
   11.12 +  </parent>
   11.13 +  <groupId>org.apidesign.html.demo</groupId>
   11.14 +  <artifactId>chat-server</artifactId>
   11.15 +  <version>1.0-SNAPSHOT</version>
   11.16 +  <name>Chat Server Using @Model</name>
   11.17 +  <url>http://maven.apache.org</url>
   11.18 +  <build>
   11.19 +      <plugins>
   11.20 +          <plugin>
   11.21 +              <groupId>org.codehaus.mojo</groupId>
   11.22 +              <artifactId>exec-maven-plugin</artifactId>
   11.23 +              <version>1.2.1</version>
   11.24 +              <configuration>
   11.25 +                  <mainClass>org.apidesign.bck2brwsr.demo.chatserver.impl.Main</mainClass>
   11.26 +              </configuration>
   11.27 +          </plugin>
   11.28 +         <plugin>
   11.29 +            <groupId>org.apache.maven.plugins</groupId>
   11.30 +            <artifactId>maven-compiler-plugin</artifactId>
   11.31 +            <version>2.3.2</version>
   11.32 +            <configuration>
   11.33 +               <source>1.7</source>
   11.34 +               <target>1.7</target>
   11.35 +            </configuration>
   11.36 +         </plugin>
   11.37 +         <plugin>
   11.38 +             <groupId>org.apache.maven.plugins</groupId>
   11.39 +             <artifactId>maven-dependency-plugin</artifactId>
   11.40 +             <version>2.7</version>
   11.41 +             <executions>
   11.42 +                 <execution>
   11.43 +                    <phase>process-resources</phase>
   11.44 +                    <id>unpack-client-code</id>
   11.45 +                    <goals>
   11.46 +                        <goal>unpack</goal>
   11.47 +                    </goals>
   11.48 +                    <configuration>
   11.49 +                        <artifactItems>
   11.50 +                            <artifactItem>
   11.51 +                                <groupId>org.apidesign.html.demo</groupId>
   11.52 +                                <artifactId>chat-client</artifactId>
   11.53 +                                <version>1.0-SNAPSHOT</version>
   11.54 +                                <type>zip</type>
   11.55 +                                <classifier>bck2brwsr</classifier>
   11.56 +                            </artifactItem>
   11.57 +                        </artifactItems>
   11.58 +                        <outputDirectory>${project.build.directory}/classes/org/apidesign/bck2brwsr/demo/chatserver/impl/</outputDirectory>
   11.59 +                    </configuration>
   11.60 +                 </execution>
   11.61 +             </executions>
   11.62 +             
   11.63 +         </plugin>
   11.64 +      </plugins>
   11.65 +  </build>
   11.66 +  <dependencies>
   11.67 +    <dependency>
   11.68 +      <groupId>org.apidesign.html</groupId>
   11.69 +      <artifactId>net.java.html.json</artifactId>
   11.70 +      <version>${net.java.html.version}</version>
   11.71 +      <type>jar</type>
   11.72 +    </dependency>
   11.73 +    <dependency>
   11.74 +      <groupId>org.glassfish.jersey.incubator</groupId>
   11.75 +      <artifactId>html-json</artifactId>
   11.76 +      <version>0.1-SNAPSHOT</version>
   11.77 +      <scope>runtime</scope>
   11.78 +    </dependency>
   11.79 +    <dependency>
   11.80 +      <groupId>org.testng</groupId>
   11.81 +      <artifactId>testng</artifactId>
   11.82 +      <version>6.5.2</version>
   11.83 +      <scope>test</scope>
   11.84 +    </dependency>
   11.85 +    <dependency>
   11.86 +      <groupId>org.glassfish.jersey.connectors</groupId>
   11.87 +      <artifactId>jersey-grizzly-connector</artifactId>
   11.88 +      <version>2.0-SNAPSHOT</version>
   11.89 +    </dependency>
   11.90 +    <dependency>
   11.91 +      <groupId>org.glassfish.jersey.containers</groupId>
   11.92 +      <artifactId>jersey-container-grizzly2-http</artifactId>
   11.93 +      <version>2.0-SNAPSHOT</version>
   11.94 +      <type>jar</type>
   11.95 +    </dependency>
   11.96 +    <dependency>
   11.97 +      <groupId>org.glassfish.grizzly</groupId>
   11.98 +      <artifactId>grizzly-http-server</artifactId>
   11.99 +      <version>2.3.1</version>
  11.100 +    </dependency>
  11.101 +    <dependency>
  11.102 +      <groupId>org.apidesign.html.demo</groupId>
  11.103 +      <artifactId>chat-model</artifactId>
  11.104 +      <version>1.0-SNAPSHOT</version>
  11.105 +      <type>jar</type>
  11.106 +    </dependency>
  11.107 +  </dependencies>
  11.108 +</project>
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/chat/server/src/main/java/org/apidesign/bck2brwsr/demo/chatserver/impl/ChatServerResource.java	Mon May 06 17:40:19 2013 +0200
    12.3 @@ -0,0 +1,108 @@
    12.4 +/**
    12.5 + * The MIT License (MIT)
    12.6 + *
    12.7 + * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    12.8 + *
    12.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
   12.10 + * of this software and associated documentation files (the "Software"), to deal
   12.11 + * in the Software without restriction, including without limitation the rights
   12.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   12.13 + * copies of the Software, and to permit persons to whom the Software is
   12.14 + * furnished to do so, subject to the following conditions:
   12.15 + *
   12.16 + * The above copyright notice and this permission notice shall be included in
   12.17 + * all copies or substantial portions of the Software.
   12.18 + *
   12.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   12.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   12.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   12.22 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   12.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   12.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   12.25 + * THE SOFTWARE.
   12.26 + */
   12.27 +package org.apidesign.bck2brwsr.demo.chatserver.impl;
   12.28 +
   12.29 +import java.util.ArrayList;
   12.30 +import java.util.IdentityHashMap;
   12.31 +import java.util.List;
   12.32 +import java.util.Map;
   12.33 +import java.util.logging.Logger;
   12.34 +import javax.inject.Singleton;
   12.35 +import javax.ws.rs.DefaultValue;
   12.36 +import javax.ws.rs.GET;
   12.37 +import javax.ws.rs.Path;
   12.38 +import javax.ws.rs.Produces;
   12.39 +import javax.ws.rs.QueryParam;
   12.40 +import javax.ws.rs.container.AsyncResponse;
   12.41 +import javax.ws.rs.container.Suspended;
   12.42 +import javax.ws.rs.core.MediaType;
   12.43 +import net.java.html.json.Context;
   12.44 +import org.apidesign.html.chatserver.model.Message;
   12.45 +import org.apidesign.html.chatserver.model.Query;
   12.46 +
   12.47 +/** Server side of the chat application.*/
   12.48 +@Path("/chat/") @Singleton
   12.49 +public final class ChatServerResource {
   12.50 +    private static final Logger LOG = Logger.getLogger(ChatServerResource.class.getName());
   12.51 +    private static final long started = System.currentTimeMillis() - 10;
   12.52 +    
   12.53 +    private List<Message> msgs = new ArrayList<>();
   12.54 +    {
   12.55 +        Message welcome = new Message(Context.findDefault(Message.class));
   12.56 +        welcome.setUser("system");
   12.57 +        welcome.setComment("Welcome and enjoy!");
   12.58 +        welcome.setSince(10);
   12.59 +        msgs.add(welcome);
   12.60 +    }
   12.61 +    
   12.62 +    private final Map<AsyncResponse, Long> awaiting = new IdentityHashMap<>();
   12.63 +    
   12.64 +    @Produces(MediaType.APPLICATION_JSON)
   12.65 +    @GET public synchronized void getResources(
   12.66 +        @QueryParam("since") @DefaultValue("0") long since,
   12.67 +        @Suspended AsyncResponse ar
   12.68 +    ) {
   12.69 +        Query q = new Query(Context.findDefault(ChatServerResource.class));
   12.70 +        for (Message m : msgs) {
   12.71 +            if (m.getSince()>= since) {
   12.72 +                q.getMessages().add(m);
   12.73 +            }
   12.74 +        }
   12.75 +        if (!q.getMessages().isEmpty()) {
   12.76 +            ar.resume(q);
   12.77 +        } else {
   12.78 +            awaiting.put(ar, since);
   12.79 +        }
   12.80 +    }
   12.81 +    
   12.82 +    private void handleAwaiting(long newest) {
   12.83 +        assert Thread.holdsLock(this);
   12.84 +        AGAIN: for (;;) {
   12.85 +            for (Map.Entry<AsyncResponse, Long> entry : awaiting.entrySet()) {
   12.86 +                AsyncResponse ar = entry.getKey();
   12.87 +                Long since = entry.getValue();
   12.88 +                if (since <= newest) {
   12.89 +                    awaiting.remove(ar);
   12.90 +                    getResources(since, ar);
   12.91 +                    continue AGAIN;
   12.92 +                }
   12.93 +            }
   12.94 +            return;
   12.95 +        }
   12.96 +    }
   12.97 +    
   12.98 +    @Path("addComment") @GET 
   12.99 +    public synchronized Message publish(
  12.100 +        @QueryParam("user") String user,
  12.101 +        @QueryParam("comment") String comment
  12.102 +    ) {
  12.103 +        Message msg = new Message(Context.findDefault(ChatServerResource.class));
  12.104 +        msg.setUser(user);
  12.105 +        msg.setComment(comment);
  12.106 +        msg.setSince(System.currentTimeMillis() - started);
  12.107 +        msgs.add(msg);
  12.108 +        handleAwaiting(msg.getSince());
  12.109 +        return msg;
  12.110 +    }
  12.111 +}
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/chat/server/src/main/java/org/apidesign/bck2brwsr/demo/chatserver/impl/ClientPagesResource.java	Mon May 06 17:40:19 2013 +0200
    13.3 @@ -0,0 +1,45 @@
    13.4 +/**
    13.5 + * The MIT License (MIT)
    13.6 + *
    13.7 + * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    13.8 + *
    13.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
   13.10 + * of this software and associated documentation files (the "Software"), to deal
   13.11 + * in the Software without restriction, including without limitation the rights
   13.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   13.13 + * copies of the Software, and to permit persons to whom the Software is
   13.14 + * furnished to do so, subject to the following conditions:
   13.15 + *
   13.16 + * The above copyright notice and this permission notice shall be included in
   13.17 + * all copies or substantial portions of the Software.
   13.18 + *
   13.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   13.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   13.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   13.22 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   13.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   13.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   13.25 + * THE SOFTWARE.
   13.26 + */
   13.27 +package org.apidesign.bck2brwsr.demo.chatserver.impl;
   13.28 +
   13.29 +import java.io.InputStream;
   13.30 +import javax.ws.rs.GET;
   13.31 +import javax.ws.rs.Path;
   13.32 +import javax.ws.rs.PathParam;
   13.33 +
   13.34 +/**
   13.35 + *
   13.36 + * @author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
   13.37 + */
   13.38 +@Path("/")
   13.39 +public final class ClientPagesResource {
   13.40 +    @GET public InputStream indexHtml() {
   13.41 +        return clientData("index.html");
   13.42 +    }
   13.43 +    
   13.44 +    @GET @Path("{resource:.*}")
   13.45 +    public InputStream clientData(@PathParam("resource") String res) {
   13.46 +        return ClientPagesResource.class.getResourceAsStream("client/" + res);
   13.47 +    }
   13.48 +}
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/chat/server/src/main/java/org/apidesign/bck2brwsr/demo/chatserver/impl/Main.java	Mon May 06 17:40:19 2013 +0200
    14.3 @@ -0,0 +1,47 @@
    14.4 +/**
    14.5 + * The MIT License (MIT)
    14.6 + *
    14.7 + * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    14.8 + *
    14.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
   14.10 + * of this software and associated documentation files (the "Software"), to deal
   14.11 + * in the Software without restriction, including without limitation the rights
   14.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   14.13 + * copies of the Software, and to permit persons to whom the Software is
   14.14 + * furnished to do so, subject to the following conditions:
   14.15 + *
   14.16 + * The above copyright notice and this permission notice shall be included in
   14.17 + * all copies or substantial portions of the Software.
   14.18 + *
   14.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   14.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   14.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   14.22 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   14.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   14.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   14.25 + * THE SOFTWARE.
   14.26 + */
   14.27 +package org.apidesign.bck2brwsr.demo.chatserver.impl;
   14.28 +
   14.29 +import java.net.URI;
   14.30 +import org.glassfish.grizzly.http.server.HttpServer;
   14.31 +import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
   14.32 +import org.glassfish.jersey.server.ResourceConfig;
   14.33 +
   14.34 +/** Starts chat server based on Jersey.
   14.35 + *
   14.36 + * @author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
   14.37 + */
   14.38 +final class Main {
   14.39 +    public static void main(String... args) throws Exception {
   14.40 +        ResourceConfig rc = new ResourceConfig(
   14.41 +            ChatServerResource.class, ClientPagesResource.class
   14.42 +        );
   14.43 +        URI u = new URI("http://localhost:8080/");
   14.44 +        HttpServer server = GrizzlyHttpServerFactory.createHttpServer(u, rc);
   14.45 +        System.err.println("Server running at " + u);
   14.46 +        System.in.read();
   14.47 +        server.stop();
   14.48 +    }
   14.49 +    
   14.50 +}
    15.1 --- a/pom.xml	Sun May 05 18:11:29 2013 +0200
    15.2 +++ b/pom.xml	Mon May 06 17:40:19 2013 +0200
    15.3 @@ -13,12 +13,12 @@
    15.4    </parent>  
    15.5    <properties>
    15.6        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    15.7 -      <bck2brwsr.version>0.7-SNAPSHOT</bck2brwsr.version>
    15.8 +      <bck2brwsr.version>0.7</bck2brwsr.version>
    15.9        <license>COPYING</license>
   15.10    </properties>
   15.11    <modules>
   15.12      <module>twitter</module>
   15.13 -    <module>serverside</module>
   15.14 +    <module>chat</module>
   15.15    </modules>
   15.16    <licenses>
   15.17        <license>
    16.1 --- a/serverside/nbactions.xml	Sun May 05 18:11:29 2013 +0200
    16.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.3 @@ -1,35 +0,0 @@
    16.4 -<?xml version="1.0" encoding="UTF-8"?>
    16.5 -<!--
    16.6 -
    16.7 -    The MIT License (MIT)
    16.8 -
    16.9 -    Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
   16.10 -
   16.11 -    Permission is hereby granted, free of charge, to any person obtaining a copy
   16.12 -    of this software and associated documentation files (the "Software"), to deal
   16.13 -    in the Software without restriction, including without limitation the rights
   16.14 -    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   16.15 -    copies of the Software, and to permit persons to whom the Software is
   16.16 -    furnished to do so, subject to the following conditions:
   16.17 -
   16.18 -    The above copyright notice and this permission notice shall be included in
   16.19 -    all copies or substantial portions of the Software.
   16.20 -
   16.21 -    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   16.22 -    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   16.23 -    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   16.24 -    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   16.25 -    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   16.26 -    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   16.27 -    THE SOFTWARE.
   16.28 -
   16.29 --->
   16.30 -<actions>
   16.31 -    <action>
   16.32 -        <actionName>run</actionName>
   16.33 -        <goals>
   16.34 -            <goal>process-classes</goal>
   16.35 -            <goal>exec:java</goal>
   16.36 -        </goals>
   16.37 -    </action>
   16.38 -</actions>
    17.1 --- a/serverside/pom.xml	Sun May 05 18:11:29 2013 +0200
    17.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.3 @@ -1,104 +0,0 @@
    17.4 -<?xml version="1.0"?>
    17.5 -<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    17.6 -    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    17.7 -  <modelVersion>4.0.0</modelVersion>
    17.8 -  <parent>
    17.9 -    <groupId>org.apidesign.html</groupId>
   17.10 -    <artifactId>demo</artifactId>
   17.11 -    <version>1.0-SNAPSHOT</version>
   17.12 -  </parent>
   17.13 -  <groupId>org.apidesign.bck2brwsr</groupId>
   17.14 -  <artifactId>demo-serverside</artifactId>
   17.15 -  <version>1.0-SNAPSHOT</version>
   17.16 -  <name>Bck2Brwsr and Bck2Server</name>
   17.17 -  <url>http://maven.apache.org</url>
   17.18 -  <properties>
   17.19 -    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
   17.20 -    <net.java.html.version>0.2</net.java.html.version>
   17.21 -    <bck2brwsr.version>0.8-SNAPSHOT</bck2brwsr.version>
   17.22 -    <bck2brwsr.obfuscationlevel>MINIMAL</bck2brwsr.obfuscationlevel>
   17.23 -    <brwsr.startpage>org/apidesign/bck2brwsr/demo/serverside/chat.html</brwsr.startpage>
   17.24 -  </properties>
   17.25 -  <build>
   17.26 -      <plugins>
   17.27 -          <plugin>
   17.28 -              <groupId>org.codehaus.mojo</groupId>
   17.29 -              <artifactId>exec-maven-plugin</artifactId>
   17.30 -              <version>1.2.1</version>
   17.31 -              <configuration>
   17.32 -                  <mainClass>org.apidesign.bck2brwsr.demo.serverside.ChatServerResource</mainClass>
   17.33 -              </configuration>
   17.34 -          </plugin>
   17.35 -         <plugin>
   17.36 -            <groupId>org.apache.maven.plugins</groupId>
   17.37 -            <artifactId>maven-compiler-plugin</artifactId>
   17.38 -            <version>2.3.2</version>
   17.39 -            <configuration>
   17.40 -               <source>1.7</source>
   17.41 -               <target>1.7</target>
   17.42 -            </configuration>
   17.43 -         </plugin>
   17.44 -      </plugins>
   17.45 -  </build>
   17.46 -  <dependencies>
   17.47 -    <dependency>
   17.48 -      <groupId>org.apidesign.html</groupId>
   17.49 -      <artifactId>net.java.html.json</artifactId>
   17.50 -      <version>${net.java.html.version}</version>
   17.51 -      <type>jar</type>
   17.52 -    </dependency>
   17.53 -    <dependency>
   17.54 -      <groupId>org.glassfish.jersey.incubator</groupId>
   17.55 -      <artifactId>html-json</artifactId>
   17.56 -      <version>0.1-SNAPSHOT</version>
   17.57 -      <scope>runtime</scope>
   17.58 -    </dependency>
   17.59 -    <dependency>
   17.60 -      <groupId>org.apidesign.html</groupId>
   17.61 -      <artifactId>ko-bck2brwsr</artifactId>
   17.62 -      <version>${net.java.html.version}</version>
   17.63 -      <scope>runtime</scope>
   17.64 -    </dependency>
   17.65 -    <dependency>
   17.66 -      <groupId>${project.groupId}</groupId>
   17.67 -      <artifactId>launcher.http</artifactId>
   17.68 -      <version>${bck2brwsr.version}</version>
   17.69 -      <scope>compile</scope>
   17.70 -      <exclusions>
   17.71 -        <exclusion>
   17.72 -          <artifactId>grizzly-http-server</artifactId>
   17.73 -          <groupId>org.glassfish.grizzly</groupId>
   17.74 -        </exclusion>
   17.75 -      </exclusions>
   17.76 -    </dependency>
   17.77 -    <dependency>
   17.78 -      <groupId>${project.groupId}</groupId>
   17.79 -      <artifactId>emul</artifactId>
   17.80 -      <version>${bck2brwsr.version}</version>
   17.81 -      <classifier>rt</classifier>
   17.82 -      <scope>runtime</scope>
   17.83 -    </dependency>
   17.84 -    <dependency>
   17.85 -      <groupId>org.testng</groupId>
   17.86 -      <artifactId>testng</artifactId>
   17.87 -      <version>6.5.2</version>
   17.88 -      <scope>test</scope>
   17.89 -    </dependency>
   17.90 -    <dependency>
   17.91 -      <groupId>org.glassfish.jersey.connectors</groupId>
   17.92 -      <artifactId>jersey-grizzly-connector</artifactId>
   17.93 -      <version>2.0-SNAPSHOT</version>
   17.94 -    </dependency>
   17.95 -    <dependency>
   17.96 -      <groupId>org.glassfish.jersey.containers</groupId>
   17.97 -      <artifactId>jersey-container-grizzly2-http</artifactId>
   17.98 -      <version>2.0-SNAPSHOT</version>
   17.99 -      <type>jar</type>
  17.100 -    </dependency>
  17.101 -    <dependency>
  17.102 -      <groupId>org.glassfish.grizzly</groupId>
  17.103 -      <artifactId>grizzly-http-server</artifactId>
  17.104 -      <version>2.3.1</version>
  17.105 -    </dependency>
  17.106 -  </dependencies>
  17.107 -</project>
    18.1 --- a/serverside/src/main/java/org/apidesign/bck2brwsr/demo/serverside/ChatClient.java	Sun May 05 18:11:29 2013 +0200
    18.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.3 @@ -1,97 +0,0 @@
    18.4 -/**
    18.5 - * The MIT License (MIT)
    18.6 - *
    18.7 - * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    18.8 - *
    18.9 - * Permission is hereby granted, free of charge, to any person obtaining a copy
   18.10 - * of this software and associated documentation files (the "Software"), to deal
   18.11 - * in the Software without restriction, including without limitation the rights
   18.12 - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   18.13 - * copies of the Software, and to permit persons to whom the Software is
   18.14 - * furnished to do so, subject to the following conditions:
   18.15 - *
   18.16 - * The above copyright notice and this permission notice shall be included in
   18.17 - * all copies or substantial portions of the Software.
   18.18 - *
   18.19 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   18.20 - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   18.21 - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   18.22 - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   18.23 - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   18.24 - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   18.25 - * THE SOFTWARE.
   18.26 - */
   18.27 -package org.apidesign.bck2brwsr.demo.serverside;
   18.28 -
   18.29 -import net.java.html.json.ComputedProperty;
   18.30 -import net.java.html.json.Context;
   18.31 -import net.java.html.json.Function;
   18.32 -import net.java.html.json.Model;
   18.33 -import net.java.html.json.OnReceive;
   18.34 -import net.java.html.json.Property;
   18.35 -
   18.36 -/**
   18.37 - *
   18.38 - * @author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
   18.39 - */
   18.40 -@Model(className = "ChatModel", properties = {
   18.41 -    @Property(name = "user", type = String.class),
   18.42 -    @Property(name = "comment", type = String.class),
   18.43 -    @Property(name = "msgs", type = Message.class, array = true)
   18.44 -})
   18.45 -class ChatClient {
   18.46 -    @ComputedProperty
   18.47 -    static boolean sendEnabled(String user, String comment) {
   18.48 -        boolean res = user != null && comment != null && !user.isEmpty() && !comment.isEmpty();
   18.49 -        return res;
   18.50 -    }
   18.51 -    
   18.52 -    @Function
   18.53 -    static void submit(ChatModel m) {
   18.54 -        if (!sendEnabled(m.getUser(), m.getComment())) {
   18.55 -            return;
   18.56 -        }
   18.57 -        m.postComment(m.getUser(), m.getComment());
   18.58 -    }
   18.59 -    
   18.60 -    @OnReceive(url = "/chat/addComment?user={user}&comment={comment}")
   18.61 -    static void postComment(ChatModel m, Message addedMessage) {
   18.62 -        if (addedMessage.getComment().equals(m.getComment())) {
   18.63 -            m.setComment("");
   18.64 -        }
   18.65 -    }
   18.66 -    
   18.67 -    @OnReceive(url = "/chat?since=0")
   18.68 -    static void initialRead(ChatModel m, Query q) {
   18.69 -        m.getMsgs().clear();
   18.70 -        m.getMsgs().addAll(q.getMessages());
   18.71 -        moreMessages(m);
   18.72 -    }
   18.73 -    
   18.74 -    @OnReceive(url = "/chat?since={since}")
   18.75 -    static void updateMsgs(ChatModel m, Query q) {
   18.76 -        m.getMsgs().addAll(q.getMessages());
   18.77 -        moreMessages(m);
   18.78 -    }
   18.79 -    
   18.80 -    private static void moreMessages(ChatModel m) {
   18.81 -        long now = System.currentTimeMillis();
   18.82 -        m.updateMsgs("" + now);
   18.83 -    }
   18.84 -    
   18.85 -    static final Context CNTX = Context.findDefault(ChatClient.class);
   18.86 -    static {
   18.87 -        ChatModel chm = new ChatModel(CNTX);
   18.88 -        Message m = new Message(CNTX);
   18.89 -        m.setComment("Waiting for messages from the server...");
   18.90 -        m.setUser("system");
   18.91 -        chm.getMsgs().add(m);
   18.92 -        chm.applyBindings();
   18.93 -        try {
   18.94 -            // XXX: this should not be in static initializer -
   18.95 -            // XXX: prevents unit testing!
   18.96 -            chm.initialRead();
   18.97 -        } catch (Throwable ex) {
   18.98 -        }
   18.99 -    }
  18.100 -}
    19.1 --- a/serverside/src/main/java/org/apidesign/bck2brwsr/demo/serverside/ChatServerResource.java	Sun May 05 18:11:29 2013 +0200
    19.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.3 @@ -1,133 +0,0 @@
    19.4 -/**
    19.5 - * The MIT License (MIT)
    19.6 - *
    19.7 - * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    19.8 - *
    19.9 - * Permission is hereby granted, free of charge, to any person obtaining a copy
   19.10 - * of this software and associated documentation files (the "Software"), to deal
   19.11 - * in the Software without restriction, including without limitation the rights
   19.12 - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   19.13 - * copies of the Software, and to permit persons to whom the Software is
   19.14 - * furnished to do so, subject to the following conditions:
   19.15 - *
   19.16 - * The above copyright notice and this permission notice shall be included in
   19.17 - * all copies or substantial portions of the Software.
   19.18 - *
   19.19 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   19.20 - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   19.21 - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   19.22 - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   19.23 - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   19.24 - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   19.25 - * THE SOFTWARE.
   19.26 - */
   19.27 -package org.apidesign.bck2brwsr.demo.serverside;
   19.28 -
   19.29 -import java.io.Closeable;
   19.30 -import java.lang.reflect.Field;
   19.31 -import java.util.ArrayList;
   19.32 -import java.util.IdentityHashMap;
   19.33 -import java.util.List;
   19.34 -import java.util.Map;
   19.35 -import java.util.concurrent.Callable;
   19.36 -import java.util.logging.Level;
   19.37 -import java.util.logging.Logger;
   19.38 -import javax.inject.Singleton;
   19.39 -import javax.ws.rs.Consumes;
   19.40 -import javax.ws.rs.DefaultValue;
   19.41 -import javax.ws.rs.GET;
   19.42 -import javax.ws.rs.PUT;
   19.43 -import javax.ws.rs.Path;
   19.44 -import javax.ws.rs.Produces;
   19.45 -import javax.ws.rs.QueryParam;
   19.46 -import javax.ws.rs.container.AsyncResponse;
   19.47 -import javax.ws.rs.container.Suspended;
   19.48 -import javax.ws.rs.core.MediaType;
   19.49 -import net.java.html.json.Context;
   19.50 -import org.apidesign.bck2brwsr.launcher.Launcher;
   19.51 -import org.glassfish.grizzly.http.server.HttpServer;
   19.52 -import org.glassfish.grizzly.http.server.ServerConfiguration;
   19.53 -import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpContainer;
   19.54 -import org.glassfish.jersey.server.ContainerFactory;
   19.55 -import org.glassfish.jersey.server.ResourceConfig;
   19.56 -
   19.57 -/** Server side of the chat application.*/
   19.58 -@Path("/") @Singleton
   19.59 -public final class ChatServerResource {
   19.60 -    private static final Logger LOG = Logger.getLogger(ChatServerResource.class.getName());
   19.61 - 
   19.62 -    public static void main(String... args) throws Exception {
   19.63 -        ResourceConfig rc = new ResourceConfig(ChatServerResource.class);
   19.64 -        GrizzlyHttpContainer c = ContainerFactory.createContainer(GrizzlyHttpContainer.class, rc);
   19.65 -        Closeable s = Launcher.showURL(
   19.66 -            "bck2brwsr", ChatClient.class.getClassLoader(),
   19.67 -            "/org/apidesign/bck2brwsr/demo/serverside/chat.html"
   19.68 -        );
   19.69 -        Launcher l = (Launcher) s;
   19.70 -        Callable<?> f = (Callable<?>) l;
   19.71 -        HttpServer server = (HttpServer) f.call();
   19.72 -        ServerConfiguration conf = server.getServerConfiguration();
   19.73 -        conf.addHttpHandler(c, "/chat");
   19.74 -        System.in.read();
   19.75 -        s.close();
   19.76 -    }
   19.77 -    
   19.78 -    private List<Message> msgs = new ArrayList<>();
   19.79 -    {
   19.80 -        Message welcome = new Message(Context.findDefault(Message.class));
   19.81 -        welcome.setUser("system");
   19.82 -        welcome.setComment("Welcome and enjoy!");
   19.83 -        welcome.setWhen(System.currentTimeMillis());
   19.84 -        msgs.add(welcome);
   19.85 -    }
   19.86 -    
   19.87 -    private final Map<AsyncResponse, Long> awaiting = new IdentityHashMap<>();
   19.88 -    
   19.89 -    @Produces(MediaType.APPLICATION_JSON)
   19.90 -    @GET public synchronized void getResources(
   19.91 -        @QueryParam("since") @DefaultValue("0") long since,
   19.92 -        @Suspended AsyncResponse ar
   19.93 -    ) {
   19.94 -        Query q = new Query(Context.findDefault(ChatServerResource.class));
   19.95 -        for (Message m : msgs) {
   19.96 -            if (m.getWhen() >= since) {
   19.97 -                q.getMessages().add(m);
   19.98 -            }
   19.99 -        }
  19.100 -        if (!q.getMessages().isEmpty()) {
  19.101 -            ar.resume(q);
  19.102 -        } else {
  19.103 -            awaiting.put(ar, since);
  19.104 -        }
  19.105 -    }
  19.106 -    
  19.107 -    private void handleAwaiting(long newest) {
  19.108 -        assert Thread.holdsLock(this);
  19.109 -        AGAIN: for (;;) {
  19.110 -            for (Map.Entry<AsyncResponse, Long> entry : awaiting.entrySet()) {
  19.111 -                AsyncResponse ar = entry.getKey();
  19.112 -                Long since = entry.getValue();
  19.113 -                if (since <= newest) {
  19.114 -                    awaiting.remove(ar);
  19.115 -                    getResources(since, ar);
  19.116 -                    continue AGAIN;
  19.117 -                }
  19.118 -            }
  19.119 -            return;
  19.120 -        }
  19.121 -    }
  19.122 -    
  19.123 -    @Path("addComment") @GET 
  19.124 -    public synchronized Message publish(
  19.125 -        @QueryParam("user") String user,
  19.126 -        @QueryParam("comment") String comment
  19.127 -    ) {
  19.128 -        Message msg = new Message(Context.findDefault(ChatServerResource.class));
  19.129 -        msg.setUser(user);
  19.130 -        msg.setComment(comment);
  19.131 -        msg.setWhen(System.currentTimeMillis());
  19.132 -        msgs.add(msg);
  19.133 -        handleAwaiting(msg.getWhen());
  19.134 -        return msg;
  19.135 -    }
  19.136 -}
    20.1 --- a/serverside/src/main/java/org/apidesign/bck2brwsr/demo/serverside/MessageImpl.java	Sun May 05 18:11:29 2013 +0200
    20.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.3 @@ -1,63 +0,0 @@
    20.4 -/**
    20.5 - * The MIT License (MIT)
    20.6 - *
    20.7 - * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    20.8 - *
    20.9 - * Permission is hereby granted, free of charge, to any person obtaining a copy
   20.10 - * of this software and associated documentation files (the "Software"), to deal
   20.11 - * in the Software without restriction, including without limitation the rights
   20.12 - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   20.13 - * copies of the Software, and to permit persons to whom the Software is
   20.14 - * furnished to do so, subject to the following conditions:
   20.15 - *
   20.16 - * The above copyright notice and this permission notice shall be included in
   20.17 - * all copies or substantial portions of the Software.
   20.18 - *
   20.19 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   20.20 - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   20.21 - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   20.22 - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   20.23 - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   20.24 - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   20.25 - * THE SOFTWARE.
   20.26 - */
   20.27 -package org.apidesign.bck2brwsr.demo.serverside;
   20.28 -
   20.29 -import net.java.html.json.ComputedProperty;
   20.30 -import net.java.html.json.Model;
   20.31 -import net.java.html.json.Property;
   20.32 -
   20.33 -/**
   20.34 - *
   20.35 - * @author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
   20.36 - */
   20.37 -@Model(className = "Message", properties = {
   20.38 -    @Property(name = "user", type = String.class),
   20.39 -    @Property(name = "comment", type = String.class),
   20.40 -    @Property(name = "when", type = long.class)    
   20.41 -})
   20.42 -class MessageImpl {
   20.43 -    private static final long start = System.currentTimeMillis();
   20.44 -    
   20.45 -    static long startTime() {
   20.46 -        return start;
   20.47 -    }
   20.48 -    
   20.49 -    @ComputedProperty static String at(long when) {
   20.50 -        long delta = (when - start) / 1000;
   20.51 -        if (delta <= 0) {
   20.52 -            return "Before BigBeng";
   20.53 -        }
   20.54 -        if (delta < 60) {
   20.55 -            return delta + "s";
   20.56 -        }
   20.57 -        delta /= 60;
   20.58 -        return delta + "min";
   20.59 -    }
   20.60 -
   20.61 -    @Model(className = "Query", properties = {
   20.62 -        @Property(name = "messages", type = Message.class, array = true)
   20.63 -    })
   20.64 -    class QryMsgs {
   20.65 -    }
   20.66 -}
    21.1 --- a/serverside/src/main/resources/org/apidesign/bck2brwsr/demo/serverside/chat.html	Sun May 05 18:11:29 2013 +0200
    21.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.3 @@ -1,54 +0,0 @@
    21.4 -<!--
    21.5 -
    21.6 -    The MIT License (MIT)
    21.7 -
    21.8 -    Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    21.9 -
   21.10 -    Permission is hereby granted, free of charge, to any person obtaining a copy
   21.11 -    of this software and associated documentation files (the "Software"), to deal
   21.12 -    in the Software without restriction, including without limitation the rights
   21.13 -    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   21.14 -    copies of the Software, and to permit persons to whom the Software is
   21.15 -    furnished to do so, subject to the following conditions:
   21.16 -
   21.17 -    The above copyright notice and this permission notice shall be included in
   21.18 -    all copies or substantial portions of the Software.
   21.19 -
   21.20 -    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   21.21 -    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   21.22 -    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   21.23 -    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   21.24 -    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   21.25 -    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   21.26 -    THE SOFTWARE.
   21.27 -
   21.28 --->
   21.29 -<!DOCTYPE html>
   21.30 -<html>
   21.31 -    <head>
   21.32 -        <title>Chat via Jersey Server</title>
   21.33 -        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
   21.34 -    </head>
   21.35 -    <body>
   21.36 -        <div>Username:</div>
   21.37 -        <input data-bind="value: user"/>
   21.38 -        <div>Message:</div>
   21.39 -        <input data-bind="value: comment"/>
   21.40 -        <button data-bind="enable: sendEnabled, click: submit">Send</button>
   21.41 -        
   21.42 -        <ul data-bind="foreach: msgs">
   21.43 -            <li>
   21.44 -                <b data-bind="text: user"></b>@<em data-bind="text: at"></em>
   21.45 -                :
   21.46 -                <span data-bind="text: comment"></span>
   21.47 -            </li>
   21.48 -        </ul>
   21.49 -        
   21.50 -        <script src="bck2brwsr.js"></script>
   21.51 -        <script type="text/javascript">
   21.52 -            var vm = bck2brwsr('demo-serverside-1.0-SNAPSHOT.jar');
   21.53 -            vm.loadClass('org.apidesign.bck2brwsr.demo.serverside.ChatClient');
   21.54 -        </script>
   21.55 -        
   21.56 -    </body>
   21.57 -</html>
    22.1 --- a/serverside/src/test/java/org/apidesign/bck2brwsr/demo/serverside/ChatClientTest.java	Sun May 05 18:11:29 2013 +0200
    22.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.3 @@ -1,55 +0,0 @@
    22.4 -/**
    22.5 - * The MIT License (MIT)
    22.6 - *
    22.7 - * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    22.8 - *
    22.9 - * Permission is hereby granted, free of charge, to any person obtaining a copy
   22.10 - * of this software and associated documentation files (the "Software"), to deal
   22.11 - * in the Software without restriction, including without limitation the rights
   22.12 - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   22.13 - * copies of the Software, and to permit persons to whom the Software is
   22.14 - * furnished to do so, subject to the following conditions:
   22.15 - *
   22.16 - * The above copyright notice and this permission notice shall be included in
   22.17 - * all copies or substantial portions of the Software.
   22.18 - *
   22.19 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   22.20 - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   22.21 - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   22.22 - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   22.23 - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   22.24 - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   22.25 - * THE SOFTWARE.
   22.26 - */
   22.27 -package org.apidesign.bck2brwsr.demo.serverside;
   22.28 -
   22.29 -import net.java.html.json.Context;
   22.30 -import static org.testng.Assert.*;
   22.31 -import org.testng.annotations.AfterClass;
   22.32 -import org.testng.annotations.AfterMethod;
   22.33 -import org.testng.annotations.BeforeClass;
   22.34 -import org.testng.annotations.BeforeMethod;
   22.35 -import org.testng.annotations.Test;
   22.36 -
   22.37 -/**
   22.38 - *
   22.39 - * @author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
   22.40 - */
   22.41 -public class ChatClientTest {
   22.42 -    public ChatClientTest() {
   22.43 -    }
   22.44 -    
   22.45 -    @Test public void hasSendEnabled() {
   22.46 -        ChatModel m = new ChatModel(Context.EMPTY);
   22.47 -        assertFalse(m.isSendEnabled(), "By default disabled");
   22.48 -        m.setComment("some msg");
   22.49 -        m.setUser("by me");
   22.50 -        assertTrue(m.isSendEnabled(), "Now it is enabled");
   22.51 -        m.setUser(null);
   22.52 -        assertFalse(m.isSendEnabled(), "No user means disabled");
   22.53 -        m.setUser("by him");
   22.54 -        assertTrue(m.isSendEnabled(), "Again enabled");
   22.55 -        m.setComment("");
   22.56 -        assertFalse(m.isSendEnabled(), "Empty text means disabled");
   22.57 -    }
   22.58 -}