WICKET-5301 Create a module for Native WebSocket based on JSR 356

Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/36ad94dd
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/36ad94dd
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/36ad94dd

Branch: refs/heads/5299-ajax-strategy
Commit: 36ad94ddf50121dd1f288232b3e6ce8453d919a5
Parents: d6ff34e
Author: Martin Tzvetanov Grigorov <mgrigo...@apache.org>
Authored: Mon Aug 5 10:05:47 2013 +0200
Committer: Martin Tzvetanov Grigorov <mgrigo...@apache.org>
Committed: Mon Aug 5 10:05:47 2013 +0200

----------------------------------------------------------------------
 .../wicket-native-websocket/pom.xml             |   1 +
 .../ws/api/AbstractWebSocketProcessor.java      |   1 -
 .../protocol/ws/api/WebSocketBehavior.java      |   4 +
 .../ws/api/res/js/wicket-websocket-jquery.js    |  23 +-
 .../api/res/js/wicket-websocket-setup.js.tmpl   |   2 +-
 .../wicket-native-websocket-javax/pom.xml       |  67 +++
 .../ws/javax/JavaxUpgradeHttpRequest.java       | 558 +++++++++++++++++++
 .../ws/javax/JavaxWebSocketConnection.java      | 119 ++++
 .../protocol/ws/javax/JavaxWebSocketFilter.java | 280 ++++++++++
 .../ws/javax/JavaxWebSocketProcessor.java       |  83 +++
 .../protocol/ws/javax/WicketEndpoint.java       |  67 +++
 .../src/test/java/log4j.properties              |  16 +
 .../util/licence/ApacheLicenceHeaderTest.java   |  34 ++
 13 files changed, 1240 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/36ad94dd/wicket-experimental/wicket-native-websocket/pom.xml
----------------------------------------------------------------------
diff --git a/wicket-experimental/wicket-native-websocket/pom.xml 
b/wicket-experimental/wicket-native-websocket/pom.xml
index e9e87cb..a2f8c05 100644
--- a/wicket-experimental/wicket-native-websocket/pom.xml
+++ b/wicket-experimental/wicket-native-websocket/pom.xml
@@ -33,5 +33,6 @@
                <module>wicket-native-websocket-jetty</module>
                <module>wicket-native-websocket-jetty9</module>
                <module>wicket-native-websocket-tomcat</module>
+               <module>wicket-native-websocket-javax</module>
        </modules>
 </project>

http://git-wip-us.apache.org/repos/asf/wicket/blob/36ad94dd/wicket-experimental/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/AbstractWebSocketProcessor.java
----------------------------------------------------------------------
diff --git 
a/wicket-experimental/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/AbstractWebSocketProcessor.java
 
b/wicket-experimental/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/AbstractWebSocketProcessor.java
index 16eeb5b..3ac7625 100644
--- 
a/wicket-experimental/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/AbstractWebSocketProcessor.java
+++ 
b/wicket-experimental/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/AbstractWebSocketProcessor.java
@@ -92,7 +92,6 @@ public abstract class AbstractWebSocketProcessor implements 
IWebSocketProcessor
        public AbstractWebSocketProcessor(final HttpServletRequest request, 
final WebApplication application)
        {
                this.sessionId = request.getSession(true).getId();
-               Session.get().bind();
 
                String pageId = request.getParameter("pageId");
                Checks.notEmpty(pageId, "Request parameter 'pageId' is 
required!");

http://git-wip-us.apache.org/repos/asf/wicket/blob/36ad94dd/wicket-experimental/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/WebSocketBehavior.java
----------------------------------------------------------------------
diff --git 
a/wicket-experimental/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/WebSocketBehavior.java
 
b/wicket-experimental/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/WebSocketBehavior.java
index ec2bbd5..f7f1e5d 100644
--- 
a/wicket-experimental/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/WebSocketBehavior.java
+++ 
b/wicket-experimental/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/WebSocketBehavior.java
@@ -114,6 +114,10 @@ public abstract class WebSocketBehavior extends Behavior
                Url baseUrl = 
component.getRequestCycle().getUrlRenderer().getBaseUrl();
                CharSequence ajaxBaseUrl = 
Strings.escapeMarkup(baseUrl.toString());
                variables.put("baseUrl", ajaxBaseUrl);
+
+               String contextPath = component.getRequest().getContextPath();
+               variables.put("contextPath", contextPath);
+
                String webSocketSetupScript = 
webSocketSetupTemplate.asString(variables);
 
                
response.render(OnDomReadyHeaderItem.forScript(webSocketSetupScript));

http://git-wip-us.apache.org/repos/asf/wicket/blob/36ad94dd/wicket-experimental/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/res/js/wicket-websocket-jquery.js
----------------------------------------------------------------------
diff --git 
a/wicket-experimental/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/res/js/wicket-websocket-jquery.js
 
b/wicket-experimental/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/res/js/wicket-websocket-jquery.js
index d1d9495..7423c47 100644
--- 
a/wicket-experimental/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/res/js/wicket-websocket-jquery.js
+++ 
b/wicket-experimental/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/res/js/wicket-websocket-jquery.js
@@ -38,18 +38,15 @@
 
                                var self = this,
                                        url,
-                                       hashIdx,
-                                       delim;
-
-                               url = document.location.toString()
-                                       .replace('http://', 'ws://')
-                                       .replace('https://', 'wss://');
-                               hashIdx = url.indexOf('#');
-                               if (hashIdx > -1) {
-                                       url = url.substring(0, hashIdx);
-                               }
-                               delim = url.indexOf('?') > -1 ? '&' : '?';
-                               url += delim + 'pageId=' + 
Wicket.WebSocket.pageId;
+                                       protocol;
+
+                               protocol = document.location.protocol
+                                       .replace('https:', 'wss:')
+                                       .replace('http:', 'ws:');
+
+                               url = protocol + '//' + document.location.host 
+ Wicket.WebSocket.contextPath + '/wicket/websocket';
+
+                               url += '?pageId=' + Wicket.WebSocket.pageId;
                                url += '&wicket-ajax-baseurl=' + 
Wicket.WebSocket.baseUrl;
                                self.ws = new WebSocket(url);
 
@@ -135,4 +132,4 @@
                }
        };
 
-})();
\ No newline at end of file
+})();

http://git-wip-us.apache.org/repos/asf/wicket/blob/36ad94dd/wicket-experimental/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/res/js/wicket-websocket-setup.js.tmpl
----------------------------------------------------------------------
diff --git 
a/wicket-experimental/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/res/js/wicket-websocket-setup.js.tmpl
 
b/wicket-experimental/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/res/js/wicket-websocket-setup.js.tmpl
index 3d8950a..6d2f8a3 100644
--- 
a/wicket-experimental/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/res/js/wicket-websocket-setup.js.tmpl
+++ 
b/wicket-experimental/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/res/js/wicket-websocket-setup.js.tmpl
@@ -2,7 +2,7 @@
        'use strict';
 
        if (!Wicket.WebSocket.pageId) {
-               jQuery.extend(Wicket.WebSocket, { pageId: ${pageId}, baseUrl: 
'${baseUrl}' });
+               jQuery.extend(Wicket.WebSocket, { pageId: ${pageId}, baseUrl: 
'${baseUrl}', contextPath: '${contextPath}' });
                Wicket.WebSocket.createDefaultConnection();
        }
 })();

http://git-wip-us.apache.org/repos/asf/wicket/blob/36ad94dd/wicket-experimental/wicket-native-websocket/wicket-native-websocket-javax/pom.xml
----------------------------------------------------------------------
diff --git 
a/wicket-experimental/wicket-native-websocket/wicket-native-websocket-javax/pom.xml
 
b/wicket-experimental/wicket-native-websocket/wicket-native-websocket-javax/pom.xml
new file mode 100644
index 0000000..1d05f36
--- /dev/null
+++ 
b/wicket-experimental/wicket-native-websocket/wicket-native-websocket-javax/pom.xml
@@ -0,0 +1,67 @@
+<?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/maven-v4_0_0.xsd";>
+       <modelVersion>4.0.0</modelVersion>
+
+       <parent>
+               <groupId>org.apache.wicket</groupId>
+               <artifactId>wicket-native-websocket</artifactId>
+               <version>0.9-SNAPSHOT</version>
+               <relativePath>../pom.xml</relativePath>
+       </parent>
+
+       <artifactId>wicket-native-websocket-javax</artifactId>
+       <packaging>jar</packaging>
+       <version>0.9-SNAPSHOT</version>
+       <name>Wicket Native WebSocket Javax</name>
+       <description>Provides the common code needed for the different 
integrations with web container's WebSocket implementations</description>
+
+       <dependencies>
+               <dependency>
+                       <groupId>org.apache.wicket</groupId>
+                       <artifactId>wicket-core</artifactId>
+               </dependency>
+
+               <dependency>
+                       <groupId>org.apache.wicket</groupId>
+                       <artifactId>wicket-native-websocket-core</artifactId>
+               </dependency>
+
+               <dependency>
+                       <groupId>javax.websocket</groupId>
+                       <artifactId>javax.websocket-api</artifactId>
+                       <version>1.0</version>
+            <scope>provided</scope>
+               </dependency>
+
+       </dependencies>
+
+       <repositories>
+               <repository>
+                       <id>tc8</id>
+                       
<url>https://repository.apache.org/content/repositories/orgapachetomcat-048/</url>
+                       <releases>
+                               <enabled>true</enabled>
+                       </releases>
+                       <snapshots>
+                               <enabled>false</enabled>
+                       </snapshots>
+               </repository>
+       </repositories>
+
+</project>

http://git-wip-us.apache.org/repos/asf/wicket/blob/36ad94dd/wicket-experimental/wicket-native-websocket/wicket-native-websocket-javax/src/main/java/org/apache/wicket/protocol/ws/javax/JavaxUpgradeHttpRequest.java
----------------------------------------------------------------------
diff --git 
a/wicket-experimental/wicket-native-websocket/wicket-native-websocket-javax/src/main/java/org/apache/wicket/protocol/ws/javax/JavaxUpgradeHttpRequest.java
 
b/wicket-experimental/wicket-native-websocket/wicket-native-websocket-javax/src/main/java/org/apache/wicket/protocol/ws/javax/JavaxUpgradeHttpRequest.java
new file mode 100644
index 0000000..2fea729
--- /dev/null
+++ 
b/wicket-experimental/wicket-native-websocket/wicket-native-websocket-javax/src/main/java/org/apache/wicket/protocol/ws/javax/JavaxUpgradeHttpRequest.java
@@ -0,0 +1,558 @@
+/*
+ * 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.wicket.protocol.ws.javax;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.security.Principal;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import javax.servlet.AsyncContext;
+import javax.servlet.DispatcherType;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletInputStream;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import javax.servlet.http.Part;
+import javax.websocket.Session;
+
+import org.apache.wicket.util.string.StringValue;
+
+/**
+ * An artificial HttpServletRequest with data collected from the
+ * available WebSocket Session and from the HandshakeRequest
+ */
+public class JavaxUpgradeHttpRequest implements HttpServletRequest
+{
+       private final HttpSession httpSession;
+       private final String queryString;
+       private final Principal userPrincipal;
+       private final String requestUri;
+       private final Map<String, String[]> parametersMap;
+       private final Map<String, List<String>> headers;
+       private final String contextPath = ""; // artificial
+
+       public JavaxUpgradeHttpRequest(final Session session)
+       {
+               Map<String, Object> userProperties = 
session.getUserProperties();
+               this.httpSession = (HttpSession) userProperties.get("session");
+               this.headers = (Map<String, List<String>>) 
userProperties.get("headers");
+               this.queryString = (String) userProperties.get("queryString");
+               this.userPrincipal = (Principal) 
userProperties.get("userPrincipal");
+               this.requestUri = userProperties.get("requestURI").toString();
+
+               this.parametersMap = new HashMap<>();
+
+               Map<String, List<String>> parameters = (Map<String, 
List<String>>) userProperties.get("parameterMap");
+               for (Map.Entry<String, List<String>> entry : 
parameters.entrySet())
+               {
+                       String name = entry.getKey();
+                       List<String> value = entry.getValue();
+                       parametersMap.put(name, value.toArray(new 
String[value.size()]));
+               }
+       }
+
+       @Override
+       public String getAuthType()
+       {
+               return null;
+       }
+
+       @Override
+       public Cookie[] getCookies()
+       {
+               return new Cookie[0];
+       }
+
+       @Override
+       public long getDateHeader(String name)
+       {
+               String headerValue = getHeader(name);
+               return StringValue.valueOf(headerValue).toLong();
+       }
+
+       @Override
+       public String getHeader(String name)
+       {
+               String value = null;
+               if (headers != null)
+               {
+                       List<String> headerValues = headers.get(name);
+                       if (headerValues.isEmpty() == false)
+                       {
+                               value = headerValues.get(0);
+                       }
+               }
+               return value;
+       }
+
+       @Override
+       public Enumeration<String> getHeaders(String name)
+       {
+               Enumeration<String> values = null;
+               if (headers != null)
+               {
+                       List<String> headerValues = headers.get(name);
+                       if (headerValues.isEmpty() == false)
+                       {
+                               final Iterator<String> iterator = 
headerValues.iterator();
+                               values = new Enumeration<String>()
+                               {
+                                       @Override
+                                       public boolean hasMoreElements()
+                                       {
+                                               return iterator.hasNext();
+                                       }
+
+                                       @Override
+                                       public String nextElement()
+                                       {
+                                               return iterator.next();
+                                       }
+                               };
+                       }
+               }
+               return values;
+       }
+
+       @Override
+       public Enumeration<String> getHeaderNames()
+       {
+               Enumeration<String> names = null;
+               if (headers != null)
+               {
+                       Set<String> headerNames = headers.keySet();
+                       if (headerNames.isEmpty() == false)
+                       {
+                               final Iterator<String> iterator = 
headerNames.iterator();
+                               names = new Enumeration<String>()
+                               {
+                                       @Override
+                                       public boolean hasMoreElements()
+                                       {
+                                               return iterator.hasNext();
+                                       }
+
+                                       @Override
+                                       public String nextElement()
+                                       {
+                                               return iterator.next();
+                                       }
+                               };
+                       }
+               }
+               return names;
+       }
+
+       @Override
+       public int getIntHeader(String name)
+       {
+               String headerValue = getHeader(name);
+               return StringValue.valueOf(headerValue).toInt();
+       }
+
+       @Override
+       public String getMethod()
+       {
+               return null;
+       }
+
+       @Override
+       public String getPathInfo()
+       {
+               return null;
+       }
+
+       @Override
+       public String getPathTranslated()
+       {
+               return null;
+       }
+
+       @Override
+       public String getContextPath()
+       {
+               return contextPath;
+       }
+
+       @Override
+       public String getQueryString()
+       {
+               return queryString;
+       }
+
+       @Override
+       public String getRemoteUser()
+       {
+               return null;
+       }
+
+       @Override
+       public boolean isUserInRole(String role)
+       {
+               return false;
+       }
+
+       @Override
+       public Principal getUserPrincipal()
+       {
+               return userPrincipal;
+       }
+
+       @Override
+       public String getRequestedSessionId()
+       {
+               return null;
+       }
+
+       @Override
+       public String getRequestURI()
+       {
+               return requestUri;
+       }
+
+       @Override
+       public StringBuffer getRequestURL()
+       {
+               return null;
+       }
+
+       @Override
+       public String getServletPath()
+       {
+               return null;
+       }
+
+       @Override
+       public HttpSession getSession(boolean create)
+       {
+               return httpSession;
+       }
+
+       @Override
+       public HttpSession getSession()
+       {
+               return httpSession;
+       }
+
+       @Override
+       public boolean isRequestedSessionIdValid()
+       {
+               return false;
+       }
+
+       @Override
+       public boolean isRequestedSessionIdFromCookie()
+       {
+               return false;
+       }
+
+       @Override
+       public boolean isRequestedSessionIdFromURL()
+       {
+               return false;
+       }
+
+       @Override
+       public boolean isRequestedSessionIdFromUrl()
+       {
+               return false;
+       }
+
+       @Override
+       public boolean authenticate(HttpServletResponse response) throws 
IOException, ServletException
+       {
+               return false;
+       }
+
+       @Override
+       public void login(String username, String password) throws 
ServletException
+       {
+       }
+
+       @Override
+       public void logout() throws ServletException
+       {
+       }
+
+       @Override
+       public Collection<Part> getParts() throws IOException, ServletException
+       {
+               return null;
+       }
+
+       @Override
+       public Part getPart(String name) throws IOException, ServletException
+       {
+               return null;
+       }
+
+       @Override
+       public Object getAttribute(String name)
+       {
+               return null;
+       }
+
+       @Override
+       public Enumeration<String> getAttributeNames()
+       {
+               return new Enumeration<String>()
+               {
+                       @Override
+                       public boolean hasMoreElements()
+                       {
+                               return false;
+                       }
+
+                       @Override
+                       public String nextElement()
+                       {
+                               return null;
+                       }
+               };
+       }
+
+       @Override
+       public String getCharacterEncoding()
+       {
+               return null;
+       }
+
+       @Override
+       public void setCharacterEncoding(String env) throws 
UnsupportedEncodingException
+       {
+       }
+
+       @Override
+       public int getContentLength()
+       {
+               return 0;
+       }
+
+       @Override
+       public String getContentType()
+       {
+               return null;
+       }
+
+       @Override
+       public ServletInputStream getInputStream() throws IOException
+       {
+               return null;
+       }
+
+       @Override
+       public String getParameter(String name)
+       {
+               String[] values = parametersMap.get(name);
+               return values != null ? values[0] : null;
+       }
+
+       @Override
+       public Enumeration<String> getParameterNames()
+       {
+               final Iterator<String> iterator = 
parametersMap.keySet().iterator();
+               return new Enumeration<String>()
+               {
+                       @Override
+                       public boolean hasMoreElements()
+                       {
+                               return iterator.hasNext();
+                       }
+
+                       @Override
+                       public String nextElement()
+                       {
+                               return iterator.next();
+                       }
+               };
+       }
+
+       @Override
+       public String[] getParameterValues(String name)
+       {
+               return parametersMap.get(name);
+       }
+
+       @Override
+       public Map<String, String[]> getParameterMap()
+       {
+               return parametersMap;
+       }
+
+       @Override
+       public String getProtocol()
+       {
+               return null;
+       }
+
+       @Override
+       public String getScheme()
+       {
+               return null;
+       }
+
+       @Override
+       public String getServerName()
+       {
+               return null;
+       }
+
+       @Override
+       public int getServerPort()
+       {
+               return 0;
+       }
+
+       @Override
+       public BufferedReader getReader() throws IOException
+       {
+               return null;
+       }
+
+       @Override
+       public String getRemoteAddr()
+       {
+               return null;
+       }
+
+       @Override
+       public String getRemoteHost()
+       {
+               return null;
+       }
+
+       @Override
+       public void setAttribute(String name, Object o)
+       {
+       }
+
+       @Override
+       public void removeAttribute(String name)
+       {
+       }
+
+       @Override
+       public Locale getLocale()
+       {
+               return null;
+       }
+
+       @Override
+       public Enumeration<Locale> getLocales()
+       {
+               return null;
+       }
+
+       @Override
+       public boolean isSecure()
+       {
+               return false;
+       }
+
+       @Override
+       public RequestDispatcher getRequestDispatcher(String path)
+       {
+               return null;
+       }
+
+       @Override
+       public String getRealPath(String path)
+       {
+               return null;
+       }
+
+       @Override
+       public int getRemotePort()
+       {
+               return 0;
+       }
+
+       @Override
+       public String getLocalName()
+       {
+               return null;
+       }
+
+       @Override
+       public String getLocalAddr()
+       {
+               return null;
+       }
+
+       @Override
+       public int getLocalPort()
+       {
+               return 0;
+       }
+
+       @Override
+       public ServletContext getServletContext()
+       {
+               return null;
+       }
+
+       @Override
+       public AsyncContext startAsync() throws IllegalStateException
+       {
+               return null;
+       }
+
+       @Override
+       public AsyncContext startAsync(ServletRequest servletRequest, 
ServletResponse servletResponse) throws IllegalStateException
+       {
+               return null;
+       }
+
+       @Override
+       public boolean isAsyncStarted()
+       {
+               return false;
+       }
+
+       @Override
+       public boolean isAsyncSupported()
+       {
+               return false;
+       }
+
+       @Override
+       public AsyncContext getAsyncContext()
+       {
+               return null;
+       }
+
+       @Override
+       public DispatcherType getDispatcherType()
+       {
+               return null;
+       }
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/36ad94dd/wicket-experimental/wicket-native-websocket/wicket-native-websocket-javax/src/main/java/org/apache/wicket/protocol/ws/javax/JavaxWebSocketConnection.java
----------------------------------------------------------------------
diff --git 
a/wicket-experimental/wicket-native-websocket/wicket-native-websocket-javax/src/main/java/org/apache/wicket/protocol/ws/javax/JavaxWebSocketConnection.java
 
b/wicket-experimental/wicket-native-websocket/wicket-native-websocket-javax/src/main/java/org/apache/wicket/protocol/ws/javax/JavaxWebSocketConnection.java
new file mode 100644
index 0000000..553682a
--- /dev/null
+++ 
b/wicket-experimental/wicket-native-websocket/wicket-native-websocket-javax/src/main/java/org/apache/wicket/protocol/ws/javax/JavaxWebSocketConnection.java
@@ -0,0 +1,119 @@
+/*
+ * 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.wicket.protocol.ws.javax;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+import javax.websocket.CloseReason;
+import javax.websocket.Session;
+
+import org.apache.wicket.protocol.ws.api.AbstractWebSocketConnection;
+import org.apache.wicket.protocol.ws.api.AbstractWebSocketProcessor;
+import org.apache.wicket.protocol.ws.api.IWebSocketConnection;
+import org.apache.wicket.util.lang.Args;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A wrapper around Jetty9's native WebSocketConnection.
+ *
+ * @since 6.2
+ */
+public class JavaxWebSocketConnection extends AbstractWebSocketConnection
+{
+       private static final Logger LOG = 
LoggerFactory.getLogger(JavaxWebSocketConnection.class);
+
+       private final Session session;
+
+       /**
+        * Constructor.
+        *
+        * @param session
+        *            the jetty websocket connection
+        */
+       public JavaxWebSocketConnection(Session session, 
AbstractWebSocketProcessor webSocketProcessor)
+       {
+               super(webSocketProcessor);
+               this.session = Args.notNull(session, "connection");
+       }
+
+       @Override
+       public boolean isOpen()
+       {
+               return session.isOpen();
+       }
+
+       @Override
+       public void close(int code, String reason)
+       {
+               if (isOpen())
+               {
+                       try
+                       {
+                               session.close(new CloseReason(new 
CloseCode(code), reason));
+                       } catch (IOException iox)
+                       {
+                               LOG.error("An error occurred while closing 
WebSocket session", iox);
+                       }
+               }
+       }
+
+       @Override
+       public IWebSocketConnection sendMessage(String message) throws 
IOException
+       {
+               checkClosed();
+
+               session.getBasicRemote().sendText(message);
+               return this;
+       }
+
+       @Override
+       public IWebSocketConnection sendMessage(byte[] message, int offset, int 
length)
+               throws IOException
+       {
+               checkClosed();
+
+               ByteBuffer buf = ByteBuffer.wrap(message, offset, length);
+               session.getBasicRemote().sendBinary(buf);
+               return this;
+       }
+
+       private void checkClosed()
+       {
+               if (!isOpen())
+               {
+                       throw new IllegalStateException("The connection is 
closed.");
+               }
+       }
+
+       private static class CloseCode implements CloseReason.CloseCode
+       {
+               private final int code;
+
+               private CloseCode(int code)
+               {
+                       this.code = code;
+               }
+
+               @Override
+               public int getCode()
+               {
+                       return code;
+               }
+       }
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/36ad94dd/wicket-experimental/wicket-native-websocket/wicket-native-websocket-javax/src/main/java/org/apache/wicket/protocol/ws/javax/JavaxWebSocketFilter.java
----------------------------------------------------------------------
diff --git 
a/wicket-experimental/wicket-native-websocket/wicket-native-websocket-javax/src/main/java/org/apache/wicket/protocol/ws/javax/JavaxWebSocketFilter.java
 
b/wicket-experimental/wicket-native-websocket/wicket-native-websocket-javax/src/main/java/org/apache/wicket/protocol/ws/javax/JavaxWebSocketFilter.java
new file mode 100644
index 0000000..55b202b
--- /dev/null
+++ 
b/wicket-experimental/wicket-native-websocket/wicket-native-websocket-javax/src/main/java/org/apache/wicket/protocol/ws/javax/JavaxWebSocketFilter.java
@@ -0,0 +1,280 @@
+/*
+ * 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.wicket.protocol.ws.javax;
+
+import java.net.URI;
+import java.security.Principal;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.websocket.Decoder;
+import javax.websocket.DeploymentException;
+import javax.websocket.Encoder;
+import javax.websocket.Extension;
+import javax.websocket.HandshakeResponse;
+import javax.websocket.server.HandshakeRequest;
+import javax.websocket.server.ServerContainer;
+import javax.websocket.server.ServerEndpointConfig;
+
+import org.apache.wicket.protocol.http.WicketFilter;
+import org.apache.wicket.protocol.ws.AbstractUpgradeFilter;
+import org.apache.wicket.util.string.Strings;
+
+/**
+ * An upgrade filter that setups javax.websocket
+ */
+public class JavaxWebSocketFilter extends AbstractUpgradeFilter
+{
+       /**
+        * A fake mount path used for WebSocket endpoint.
+        * WicketFilter should not process this path.
+        * @see WicketFilter#ignorePaths
+        */
+       private static final String WICKET_WEB_SOCKET_PATH = 
"/wicket/websocket";
+
+       /**
+        * A key used to store the application object in WebSocket's Endpoint 
user properties
+        */
+       static final String APPLICATION_KEY = "wicket.application";
+
+       @Override
+       public void init(final boolean isServlet, final FilterConfig 
filterConfig) throws ServletException
+       {
+               super.init(isServlet, new 
JavaxWebSocketFilterConfig(filterConfig));
+
+               ServletContext servletContext = 
filterConfig.getServletContext();
+               ServerContainer sc = (ServerContainer) 
servletContext.getAttribute(ServerContainer.class.getName());
+
+               try
+               {
+                       ServerEndpointConfig config = new 
WicketServerEndpointConfig(ServerEndpointConfig.Builder.create(WicketEndpoint.class,
 WICKET_WEB_SOCKET_PATH).build());
+                       config.getUserProperties().put(APPLICATION_KEY, 
getApplication());
+                       sc.addEndpoint(config);
+               }
+               catch (DeploymentException e) {
+                       throw new IllegalStateException(e);
+               }
+       }
+
+       /**
+        * A wrapper of the passed FilterConfig in #init() that adds 
#WICKET_WEB_SOCKET_PATH to
+        * the list of ignored paths
+        */
+       private static class JavaxWebSocketFilterConfig implements FilterConfig
+       {
+               private final FilterConfig delegate;
+
+               private JavaxWebSocketFilterConfig(FilterConfig delegate)
+               {
+                       this.delegate = delegate;
+               }
+
+               @Override
+               public String getFilterName()
+               {
+                       return delegate.getFilterName();
+               }
+
+               @Override
+               public ServletContext getServletContext()
+               {
+                       return delegate.getServletContext();
+               }
+
+               @Override
+               public String getInitParameter(String s)
+               {
+                       String result = delegate.getInitParameter(s);
+
+                       if (WicketFilter.IGNORE_PATHS_PARAM.equalsIgnoreCase(s))
+                       {
+                               if (Strings.isEmpty(result))
+                               {
+                                       result = WICKET_WEB_SOCKET_PATH;
+                               }
+                               else
+                               {
+                                       result = result + ',' + 
WICKET_WEB_SOCKET_PATH;
+                               }
+                       }
+
+                       return result;
+               }
+
+               @Override
+               public Enumeration<String> getInitParameterNames()
+               {
+                       return delegate.getInitParameterNames();
+               }
+       }
+
+       /**
+        * A ServerEndpointConfig that uses custom Configurator to collect
+        * all available information from the passed HandshakeRequest
+        */
+       private static class WicketServerEndpointConfig implements 
ServerEndpointConfig
+       {
+               private final ServerEndpointConfig delegate;
+               private Configurator configurator;
+
+               private WicketServerEndpointConfig(ServerEndpointConfig 
delegate)
+               {
+                       this.delegate = delegate;
+               }
+
+               @Override
+               public Class<?> getEndpointClass()
+               {
+                       return delegate.getEndpointClass();
+               }
+
+               @Override
+               public String getPath()
+               {
+                       return delegate.getPath();
+               }
+
+               @Override
+               public List<String> getSubprotocols()
+               {
+                       return delegate.getSubprotocols();
+               }
+
+               @Override
+               public List<Extension> getExtensions()
+               {
+                       return delegate.getExtensions();
+               }
+
+               @Override
+               public Configurator getConfigurator()
+               {
+                       if (configurator == null)
+                       {
+                               configurator = new 
JavaxWebSocketConfigurator(delegate.getConfigurator());
+                       }
+                       return configurator;
+               }
+
+               @Override
+               public List<Class<? extends Encoder>> getEncoders()
+               {
+                       return delegate.getEncoders();
+               }
+
+               @Override
+               public List<Class<? extends Decoder>> getDecoders()
+               {
+                       return delegate.getDecoders();
+               }
+
+               @Override
+               public Map<String, Object> getUserProperties()
+               {
+                       return delegate.getUserProperties();
+               }
+       }
+
+       /**
+        * A custom Configurator that collects all available information from 
the HandshakeRequest
+        */
+       private static class JavaxWebSocketConfigurator extends 
ServerEndpointConfig.Configurator
+       {
+               private final ServerEndpointConfig.Configurator delegate;
+
+               public 
JavaxWebSocketConfigurator(ServerEndpointConfig.Configurator delegate)
+               {
+                       this.delegate = delegate;
+               }
+
+               @Override
+               public void modifyHandshake(ServerEndpointConfig sec, 
HandshakeRequest request, HandshakeResponse response)
+               {
+                       delegate.modifyHandshake(sec, request, response);
+
+                       // do not store null keys/values because Tomcat 8 uses 
ConcurrentMap for UserProperties
+
+                       Map<String, Object> userProperties = 
sec.getUserProperties();
+                       Object httpSession = request.getHttpSession();
+                       if (httpSession != null)
+                       {
+                               userProperties.put("session", httpSession);
+                       }
+
+                       Map<String, List<String>> headers = 
request.getHeaders();
+                       if (headers != null)
+                       {
+                               userProperties.put("headers", headers);
+                       }
+
+
+                       Map<String, List<String>> parameterMap = 
request.getParameterMap();
+                       if (parameterMap != null)
+                       {
+                               userProperties.put("parameterMap", 
parameterMap);
+                       }
+
+
+                       String queryString = request.getQueryString();
+                       if (queryString != null)
+                       {
+                               userProperties.put("queryString", queryString);
+                       }
+
+
+                       URI requestURI = request.getRequestURI();
+                       if (requestURI != null)
+                       {
+                               userProperties.put("requestURI", requestURI);
+                       }
+
+                       Principal userPrincipal = request.getUserPrincipal();
+                       if (userPrincipal != null)
+                       {
+                               userProperties.put("userPrincipal", 
userPrincipal);
+                       }
+               }
+
+               @Override
+               public String getNegotiatedSubprotocol(List<String> supported, 
List<String> requested)
+               {
+                       return delegate.getNegotiatedSubprotocol(supported, 
requested);
+               }
+
+               @Override
+               public List<Extension> getNegotiatedExtensions(List<Extension> 
installed, List<Extension> requested)
+               {
+                       return delegate.getNegotiatedExtensions(installed, 
requested);
+               }
+
+               @Override
+               public boolean checkOrigin(String originHeaderValue)
+               {
+                       return delegate.checkOrigin(originHeaderValue);
+               }
+
+               @Override
+               public <T> T getEndpointInstance(Class<T> endpointClass) throws 
InstantiationException
+               {
+                       return super.getEndpointInstance(endpointClass);
+               }
+       }
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/36ad94dd/wicket-experimental/wicket-native-websocket/wicket-native-websocket-javax/src/main/java/org/apache/wicket/protocol/ws/javax/JavaxWebSocketProcessor.java
----------------------------------------------------------------------
diff --git 
a/wicket-experimental/wicket-native-websocket/wicket-native-websocket-javax/src/main/java/org/apache/wicket/protocol/ws/javax/JavaxWebSocketProcessor.java
 
b/wicket-experimental/wicket-native-websocket/wicket-native-websocket-javax/src/main/java/org/apache/wicket/protocol/ws/javax/JavaxWebSocketProcessor.java
new file mode 100644
index 0000000..1fa18a9
--- /dev/null
+++ 
b/wicket-experimental/wicket-native-websocket/wicket-native-websocket-javax/src/main/java/org/apache/wicket/protocol/ws/javax/JavaxWebSocketProcessor.java
@@ -0,0 +1,83 @@
+/*
+ * 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.wicket.protocol.ws.javax;
+
+import java.nio.ByteBuffer;
+
+import javax.websocket.MessageHandler;
+import javax.websocket.Session;
+
+import org.apache.wicket.protocol.http.WebApplication;
+import org.apache.wicket.protocol.ws.api.AbstractWebSocketProcessor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * An {@link org.apache.wicket.protocol.ws.api.IWebSocketProcessor processor} 
that integrates with
+ * Jetty 9.x {@link Session web socket} implementation.
+ *
+ * @since 6.2
+ */
+public class JavaxWebSocketProcessor extends AbstractWebSocketProcessor
+{
+       private static final Logger LOG = 
LoggerFactory.getLogger(JavaxWebSocketProcessor.class);
+
+       /**
+        * Constructor.
+        *
+        * @param session
+        *            the WebSocket session
+        * @param application
+        *            the current Wicket Application
+        */
+       public JavaxWebSocketProcessor(final Session session, final 
WebApplication application)
+       {
+               super(new JavaxUpgradeHttpRequest(session), application);
+
+               onConnect(new JavaxWebSocketConnection(session, this));
+
+               session.addMessageHandler(new StringMessageHandler());
+               session.addMessageHandler(new BinaryMessageHandler());
+       }
+
+
+       @Override
+       public void onOpen(Object containerConnection)
+       {
+       }
+
+       private class StringMessageHandler implements 
MessageHandler.Whole<String>
+       {
+               @Override
+               public void onMessage(String message)
+               {
+                       JavaxWebSocketProcessor.this.onMessage(message);
+               }
+       }
+
+       private class BinaryMessageHandler implements 
MessageHandler.Whole<ByteBuffer>
+       {
+               @Override
+               public void onMessage(ByteBuffer message)
+               {
+                       byte[] array = message.array();
+                       JavaxWebSocketProcessor.this.onMessage(array, 0, 
array.length);
+               }
+       }
+
+
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/36ad94dd/wicket-experimental/wicket-native-websocket/wicket-native-websocket-javax/src/main/java/org/apache/wicket/protocol/ws/javax/WicketEndpoint.java
----------------------------------------------------------------------
diff --git 
a/wicket-experimental/wicket-native-websocket/wicket-native-websocket-javax/src/main/java/org/apache/wicket/protocol/ws/javax/WicketEndpoint.java
 
b/wicket-experimental/wicket-native-websocket/wicket-native-websocket-javax/src/main/java/org/apache/wicket/protocol/ws/javax/WicketEndpoint.java
new file mode 100644
index 0000000..57b4e0b
--- /dev/null
+++ 
b/wicket-experimental/wicket-native-websocket/wicket-native-websocket-javax/src/main/java/org/apache/wicket/protocol/ws/javax/WicketEndpoint.java
@@ -0,0 +1,67 @@
+/*
+ * 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.wicket.protocol.ws.javax;
+
+import javax.websocket.CloseReason;
+import javax.websocket.Endpoint;
+import javax.websocket.EndpointConfig;
+import javax.websocket.Session;
+
+import org.apache.wicket.ThreadContext;
+import org.apache.wicket.protocol.http.WebApplication;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class WicketEndpoint extends Endpoint
+{
+       private static final Logger LOG = 
LoggerFactory.getLogger(WicketEndpoint.class);
+
+       private JavaxWebSocketProcessor javaxWebSocketProcessor;
+
+       @Override
+       public void onOpen(Session session, EndpointConfig endpointConfig)
+       {
+               WebApplication app = (WebApplication) 
session.getUserProperties().get(JavaxWebSocketFilter.APPLICATION_KEY);
+
+               try
+               {
+                       ThreadContext.setApplication(app);
+                       javaxWebSocketProcessor = new 
JavaxWebSocketProcessor(session, app);
+               }
+               finally
+               {
+                       ThreadContext.detach();
+               }
+
+       }
+
+       @Override
+       public void onClose(Session session, CloseReason closeReason)
+       {
+               super.onClose(session, closeReason);
+
+               
javaxWebSocketProcessor.onClose(closeReason.getCloseCode().getCode(), 
closeReason.getReasonPhrase());
+       }
+
+       @Override
+       public void onError(Session session, Throwable t)
+       {
+               super.onError(session, t);
+
+               LOG.error("An error occurred in web socket connection with id : 
" + session.getId(), t);
+       }
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/36ad94dd/wicket-experimental/wicket-native-websocket/wicket-native-websocket-javax/src/test/java/log4j.properties
----------------------------------------------------------------------
diff --git 
a/wicket-experimental/wicket-native-websocket/wicket-native-websocket-javax/src/test/java/log4j.properties
 
b/wicket-experimental/wicket-native-websocket/wicket-native-websocket-javax/src/test/java/log4j.properties
new file mode 100644
index 0000000..976b5c8
--- /dev/null
+++ 
b/wicket-experimental/wicket-native-websocket/wicket-native-websocket-javax/src/test/java/log4j.properties
@@ -0,0 +1,16 @@
+log4j.debug=false
+
+log4j.rootLogger=INFO,Stdout
+
+# please keep this setting FATAL to avoid questions from users
+# why there are stacktraces in the test output. You can turn it
+# down if you need to when testing, but don't check it in. (eelco)
+
+# changing back to ERROR. Looks like in some cases the log4j.properties
+# in wicket gets picked which results in not printing the exceptions
+# and that can be a bit dangerous (matej)
+log4j.logger.org.apache.wicket=ERROR
+
+log4j.appender.Stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.Stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.Stdout.layout.conversionPattern=%-5p - %-26.26c{1} - %m\n

http://git-wip-us.apache.org/repos/asf/wicket/blob/36ad94dd/wicket-experimental/wicket-native-websocket/wicket-native-websocket-javax/src/test/java/org/apache/wicket/protocol/ws/util/licence/ApacheLicenceHeaderTest.java
----------------------------------------------------------------------
diff --git 
a/wicket-experimental/wicket-native-websocket/wicket-native-websocket-javax/src/test/java/org/apache/wicket/protocol/ws/util/licence/ApacheLicenceHeaderTest.java
 
b/wicket-experimental/wicket-native-websocket/wicket-native-websocket-javax/src/test/java/org/apache/wicket/protocol/ws/util/licence/ApacheLicenceHeaderTest.java
new file mode 100644
index 0000000..cd3cbf1
--- /dev/null
+++ 
b/wicket-experimental/wicket-native-websocket/wicket-native-websocket-javax/src/test/java/org/apache/wicket/protocol/ws/util/licence/ApacheLicenceHeaderTest.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.wicket.protocol.ws.util.licence;
+
+import org.apache.wicket.util.license.ApacheLicenseHeaderTestCase;
+
+/**
+ * Test that the license headers are in place in this project. The tests are 
run from
+ * {@link org.apache.wicket.util.license.ApacheLicenseHeaderTestCase}, but you 
can add project specific tests here if needed.
+ */
+public class ApacheLicenceHeaderTest extends ApacheLicenseHeaderTestCase
+{
+       /**
+        * Construct.
+        */
+       public ApacheLicenceHeaderTest()
+       {
+               // addHeaders = true;
+       }
+}

Reply via email to