You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by pa...@apache.org on 2017/05/22 00:01:17 UTC

svn commit: r1795755 - in /sling/whiteboard/pauls: ./ gush/ gush/launchpad/ gush/launchpad/src/ gush/launchpad/src/main/ gush/launchpad/src/main/provisioning/ gush/servlet/ gush/servlet/.settings/ gush/servlet/src/ gush/servlet/src/main/ gush/servlet/s...

Author: pauls
Date: Mon May 22 00:01:17 2017
New Revision: 1795755

URL: http://svn.apache.org/viewvc?rev=1795755&view=rev
Log:
Initial commit of a gush servlet.

Added:
    sling/whiteboard/pauls/
    sling/whiteboard/pauls/gush/
    sling/whiteboard/pauls/gush/launchpad/
    sling/whiteboard/pauls/gush/launchpad/pom.xml
    sling/whiteboard/pauls/gush/launchpad/src/
    sling/whiteboard/pauls/gush/launchpad/src/main/
    sling/whiteboard/pauls/gush/launchpad/src/main/provisioning/
    sling/whiteboard/pauls/gush/launchpad/src/main/provisioning/model.txt
    sling/whiteboard/pauls/gush/servlet/
    sling/whiteboard/pauls/gush/servlet/.classpath
    sling/whiteboard/pauls/gush/servlet/.project
    sling/whiteboard/pauls/gush/servlet/.settings/
    sling/whiteboard/pauls/gush/servlet/.settings/org.eclipse.core.resources.prefs
    sling/whiteboard/pauls/gush/servlet/.settings/org.eclipse.jdt.core.prefs
    sling/whiteboard/pauls/gush/servlet/pom.xml
    sling/whiteboard/pauls/gush/servlet/src/
    sling/whiteboard/pauls/gush/servlet/src/main/
    sling/whiteboard/pauls/gush/servlet/src/main/java/
    sling/whiteboard/pauls/gush/servlet/src/main/java/org/
    sling/whiteboard/pauls/gush/servlet/src/main/java/org/apache/
    sling/whiteboard/pauls/gush/servlet/src/main/java/org/apache/sling/
    sling/whiteboard/pauls/gush/servlet/src/main/java/org/apache/sling/whiteboard/
    sling/whiteboard/pauls/gush/servlet/src/main/java/org/apache/sling/whiteboard/pauls/
    sling/whiteboard/pauls/gush/servlet/src/main/java/org/apache/sling/whiteboard/pauls/gush/
    sling/whiteboard/pauls/gush/servlet/src/main/java/org/apache/sling/whiteboard/pauls/gush/servlet/
    sling/whiteboard/pauls/gush/servlet/src/main/java/org/apache/sling/whiteboard/pauls/gush/servlet/GushServlet.java

Added: sling/whiteboard/pauls/gush/launchpad/pom.xml
URL: http://svn.apache.org/viewvc/sling/whiteboard/pauls/gush/launchpad/pom.xml?rev=1795755&view=auto
==============================================================================
--- sling/whiteboard/pauls/gush/launchpad/pom.xml (added)
+++ sling/whiteboard/pauls/gush/launchpad/pom.xml Mon May 22 00:01:17 2017
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+    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.sling</groupId>
+        <artifactId>sling</artifactId>
+        <version>30</version>
+        <relativePath/>
+    </parent>
+
+    <artifactId>org.apache.sling.whiteboard.pauls.gush.launchpad</artifactId>
+    <packaging>slingstart</packaging>
+    <version>0.1.0-SNAPSHOT</version>
+
+    <name>Apache Sling Whiteboard Pauls Gush Launchpad</name>
+    <description>
+       A gush launchpad for Sling
+    </description>
+
+    <scm>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/whiteboard/pauls/gush/launchpad</connection>
+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/whiteboard/pauls/gush/launchpad</developerConnection>
+        <url>http://svn.apache.org/viewvc/sling/whiteboard/pauls/gush/launchpad</url>
+    </scm>
+
+    <properties>
+        <sling.java.version>8</sling.java.version>
+        
+        <sling.default.vm.options>-Xmx1024m -XX:MaxPermSize=256m -Djava.awt.headless=true</sling.default.vm.options>
+
+        <!-- path suffix for HTTP access to Sling -->
+        <http.base.path />
+
+        <!-- path suffix for WebDAV access to the repository -->
+        <webdav.workspace.path />
+
+        <!-- hostname -->
+        <test.host>localhost</test.host>
+
+        <slf4j.version>1.7.6</slf4j.version>
+        <logback.version>1.1.2</logback.version>
+    </properties>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.sling</groupId>
+                <artifactId>slingstart-maven-plugin</artifactId>
+                <version>1.7.0</version>
+                <extensions>true</extensions>
+            </plugin>
+        </plugins>
+    </build>
+
+    <profiles>
+        <profile>
+             <id>debug</id>
+             <activation>
+                <property>
+                    <name>debug</name>
+                </property>
+             </activation>
+             <properties>
+                <sling.vm.options>${sling.default.vm.options} -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000</sling.vm.options>
+             </properties>
+        </profile>
+        <profile>
+             <id>no-debug</id>
+             <activation>
+                <property>
+                    <name>!debug</name>
+                </property>
+             </activation>
+             <properties>
+                <sling.vm.options>${sling.default.vm.options}</sling.vm.options>
+             </properties>
+        </profile>
+    </profiles>
+    
+    <dependencies>
+    </dependencies>
+</project>

Added: sling/whiteboard/pauls/gush/launchpad/src/main/provisioning/model.txt
URL: http://svn.apache.org/viewvc/sling/whiteboard/pauls/gush/launchpad/src/main/provisioning/model.txt?rev=1795755&view=auto
==============================================================================
--- sling/whiteboard/pauls/gush/launchpad/src/main/provisioning/model.txt (added)
+++ sling/whiteboard/pauls/gush/launchpad/src/main/provisioning/model.txt Mon May 22 00:01:17 2017
@@ -0,0 +1,37 @@
+#
+#  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.
+#
+[feature name=launchpad-testing]
+# Dependencies
+[artifacts]
+  org.apache.sling/org.apache.sling.launchpad/9-SNAPSHOT/slingstart
+  org.apache.sling/org.apache.sling.commons.json/2.0.20
+  org.apache.sling/org.apache.sling.whiteboard.pauls.gush.servlet/0.1.0-SNAPSHOT
+
+# additional configuration for testing
+[configurations]
+  integrationTestsConfig
+    message="This test config should be loaded at startup"
+
+  org.apache.sling.jcr.base.internal.LoginAdminWhitelist [mode=merge]
+    whitelist.bundles.regexp="org.apache.sling.(launchpad|junit).*"
+
+[settings]
+  org.apache.sling.commons.log.julenabled=true
+
+

Added: sling/whiteboard/pauls/gush/servlet/.classpath
URL: http://svn.apache.org/viewvc/sling/whiteboard/pauls/gush/servlet/.classpath?rev=1795755&view=auto
==============================================================================
--- sling/whiteboard/pauls/gush/servlet/.classpath (added)
+++ sling/whiteboard/pauls/gush/servlet/.classpath Mon May 22 00:01:17 2017
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/classes" path="src/main/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" output="target/test-classes" path="src/test/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>

Added: sling/whiteboard/pauls/gush/servlet/.project
URL: http://svn.apache.org/viewvc/sling/whiteboard/pauls/gush/servlet/.project?rev=1795755&view=auto
==============================================================================
--- sling/whiteboard/pauls/gush/servlet/.project (added)
+++ sling/whiteboard/pauls/gush/servlet/.project Mon May 22 00:01:17 2017
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>servlet</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+	</natures>
+</projectDescription>

Added: sling/whiteboard/pauls/gush/servlet/.settings/org.eclipse.core.resources.prefs
URL: http://svn.apache.org/viewvc/sling/whiteboard/pauls/gush/servlet/.settings/org.eclipse.core.resources.prefs?rev=1795755&view=auto
==============================================================================
--- sling/whiteboard/pauls/gush/servlet/.settings/org.eclipse.core.resources.prefs (added)
+++ sling/whiteboard/pauls/gush/servlet/.settings/org.eclipse.core.resources.prefs Mon May 22 00:01:17 2017
@@ -0,0 +1,3 @@
+eclipse.preferences.version=1
+encoding//src/main/java=UTF-8
+encoding/<project>=UTF-8

Added: sling/whiteboard/pauls/gush/servlet/.settings/org.eclipse.jdt.core.prefs
URL: http://svn.apache.org/viewvc/sling/whiteboard/pauls/gush/servlet/.settings/org.eclipse.jdt.core.prefs?rev=1795755&view=auto
==============================================================================
--- sling/whiteboard/pauls/gush/servlet/.settings/org.eclipse.jdt.core.prefs (added)
+++ sling/whiteboard/pauls/gush/servlet/.settings/org.eclipse.jdt.core.prefs Mon May 22 00:01:17 2017
@@ -0,0 +1,13 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.8

Added: sling/whiteboard/pauls/gush/servlet/pom.xml
URL: http://svn.apache.org/viewvc/sling/whiteboard/pauls/gush/servlet/pom.xml?rev=1795755&view=auto
==============================================================================
--- sling/whiteboard/pauls/gush/servlet/pom.xml (added)
+++ sling/whiteboard/pauls/gush/servlet/pom.xml Mon May 22 00:01:17 2017
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+    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.sling</groupId>
+        <artifactId>sling</artifactId>
+        <version>30</version>
+        <relativePath />
+    </parent>
+
+    <artifactId>org.apache.sling.whiteboard.pauls.gush.servlet</artifactId>
+    <version>0.1.0-SNAPSHOT</version>
+    <packaging>bundle</packaging>
+
+    <name>Apache Sling Whiteboard Pauls Gush Servlet</name>
+    <description>
+         A gush servlet for Sling.
+    </description>
+
+    <scm>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/whiteboard/pauls/gush/servlet</connection>
+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/whiteboard/pauls/gush/servlet</developerConnection>
+        <url>http://svn.apache.org/viewvc/sling/whiteboard/pauls/gush/servlet</url>
+    </scm>
+
+    <properties>
+        <sling.java.version>8</sling.java.version>
+    </properties>
+
+    <build>
+        <plugins>
+            <!-- Create the bundle of the Sling API -->
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <Export-Package></Export-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.rat</groupId>
+                <artifactId>apache-rat-plugin</artifactId>
+                <configuration>
+                    <excludes>
+                        <exclude>target/*</exclude>
+                    </excludes>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+    <dependencies>
+    <dependency>
+    <groupId>org.apache.sling</groupId>
+    <artifactId>org.apache.sling.api</artifactId>
+    <version>2.16.2</version>
+    </dependency>
+    <dependency>
+    <groupId>org.apache.sling</groupId>
+    <artifactId>org.apache.sling.engine</artifactId>
+    <version>2.6.6</version>
+    </dependency>
+    <dependency>
+    <groupId>org.apache.sling</groupId>
+    <artifactId>org.apache.sling.auth.core</artifactId>
+    <version>1.3.26</version>
+    </dependency>
+    <dependency>
+    <groupId>javax.servlet</groupId>
+    <artifactId>javax.servlet-api</artifactId>
+    </dependency>
+    <dependency>
+    <groupId>org.osgi</groupId>
+    <artifactId>osgi.core</artifactId>
+    </dependency>
+    <dependency>
+    <groupId>org.osgi</groupId>
+    <artifactId>osgi.cmpn</artifactId>
+    </dependency>
+    <dependency>
+    <groupId>org.osgi</groupId>
+    <artifactId>osgi.annotation</artifactId>
+    </dependency>
+    <dependency>
+    <groupId>org.osgi</groupId>
+    <artifactId>org.osgi.service.component.annotations</artifactId>
+    </dependency>
+    <dependency>
+    <groupId>org.osgi</groupId>
+    <artifactId>org.osgi.service.metatype.annotations</artifactId>
+    </dependency>
+    </dependencies>
+</project>

Added: sling/whiteboard/pauls/gush/servlet/src/main/java/org/apache/sling/whiteboard/pauls/gush/servlet/GushServlet.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/pauls/gush/servlet/src/main/java/org/apache/sling/whiteboard/pauls/gush/servlet/GushServlet.java?rev=1795755&view=auto
==============================================================================
--- sling/whiteboard/pauls/gush/servlet/src/main/java/org/apache/sling/whiteboard/pauls/gush/servlet/GushServlet.java (added)
+++ sling/whiteboard/pauls/gush/servlet/src/main/java/org/apache/sling/whiteboard/pauls/gush/servlet/GushServlet.java Mon May 22 00:01:17 2017
@@ -0,0 +1,264 @@
+/*
+ * 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.sling.whiteboard.pauls.gush.servlet;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.UncheckedIOException;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.AsyncContext;
+import javax.servlet.AsyncEvent;
+import javax.servlet.AsyncListener;
+import javax.servlet.Servlet;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.WriteListener;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletResponseWrapper;
+
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.observation.ExternalResourceChangeListener;
+import org.apache.sling.api.resource.observation.ResourceChange;
+import org.apache.sling.api.resource.observation.ResourceChangeListener;
+import org.apache.sling.auth.core.AuthenticationSupport;
+import org.apache.sling.engine.SlingRequestProcessor;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ServiceScope;
+import org.osgi.service.http.whiteboard.HttpWhiteboardConstants;
+
+@Component
+(
+    service = {Servlet.class}, 
+    property = 
+    { 
+        HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN + "=" + "/gush/*",
+        HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_ASYNC_SUPPORTED + ":Boolean=" + "true",
+        HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT + "=" + "(" +  HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + "=" + "org.apache.sling" + ")",
+        Constants.SERVICE_RANKING + ":Integer=" + "1000"
+    },
+    scope = ServiceScope.PROTOTYPE
+)
+@SuppressWarnings("serial")
+public class GushServlet extends HttpServlet
+{
+    @Reference
+    SlingRequestProcessor m_requestProcessor;
+    
+    volatile BundleContext m_context;
+    
+    private final Map<Listener, ServiceRegistration<Listener>> m_listeners = new HashMap<>();
+    
+    @Activate
+    synchronized void activate(BundleContext context) {
+        m_context = context;
+    }
+    
+    @Deactivate
+    synchronized void deactivate(BundleContext context) {
+        m_context = null;
+        m_listeners.forEach((v, reg) -> reg.unregister());
+        m_listeners.clear();
+    }
+
+    synchronized void registerListener(String pattern, Listener listener) {
+        if (m_context != null)
+        {
+            Hashtable<String, Object> props = new Hashtable<>();
+            props.put(ResourceChangeListener.PATHS, pattern);
+            ServiceRegistration<Listener> reg = m_context.registerService(Listener.class, listener, props);
+            m_listeners.put(listener, reg);
+        }
+    }
+
+    synchronized void unregisterListener(Listener listener) {
+        ServiceRegistration<Listener> reg = m_listeners.remove(listener);
+        if (reg != null)
+        {
+            reg.unregister();
+        }
+    }
+
+    private final class Listener implements AsyncListener, ResourceChangeListener, ExternalResourceChangeListener{
+        AsyncContext m_ac;
+        Listener(AsyncContext ac) {
+            m_ac = ac;
+        }
+        @Override
+        public void onChange(List<ResourceChange> changes) {
+            try {
+                dispatch((HttpServletRequest) m_ac.getRequest(), (HttpServletResponse) m_ac.getResponse());
+            } catch (ServletException | IOException e) {
+                e.printStackTrace();
+            }
+        }
+        
+        @Override
+        public void onComplete(AsyncEvent event) throws IOException {
+            unregisterListener(this);
+        }
+        @Override
+        public void onTimeout(AsyncEvent event) throws IOException {
+            unregisterListener(this);
+        }
+        @Override
+        public void onError(AsyncEvent event) throws IOException {
+            unregisterListener(this);
+        }
+        @Override
+        public void onStartAsync(AsyncEvent event) throws IOException {
+            
+        }
+
+    }
+    
+    private void dispatch(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+        final ByteArrayOutputStream output = new ByteArrayOutputStream();
+        output.write(("id: " + (new Date()).getTime() + "\ndata: ").getBytes("UTF-8"));
+        HttpServletResponseWrapper respWrapper = new HttpServletResponseWrapper(resp) {
+            
+            @Override
+            public ServletOutputStream getOutputStream() throws IOException
+            {
+                return new ServletOutputStream()
+                {
+                    @Override
+                    public void write(byte[] b) throws IOException
+                    {
+                        output.write(b);
+                    }
+                    
+                    @Override
+                    public void write(byte[] b, int off, int len) throws IOException
+                    {
+                        output.write(b, off, len);
+                    }
+                    
+                    @Override
+                    public void write(int b) throws IOException
+                    {
+                        output.write(b);
+                    }
+                    
+                    @Override
+                    public void setWriteListener(WriteListener writeListener)
+                    {
+                        try
+                        {
+                            writeListener.onWritePossible();
+                        } catch (IOException e)
+                        {
+                            throw new UncheckedIOException(e);
+                        }
+                    }
+                    
+                    @Override
+                    public boolean isReady()
+                    {
+                        return true;
+                    }
+                };
+            }
+            
+            @Override
+            public PrintWriter getWriter() throws IOException
+            {
+                return new PrintWriter(new OutputStreamWriter(getOutputStream(), getCharacterEncoding()));
+            }
+            
+            @Override
+            public void flushBuffer() throws IOException
+            {
+            }
+        };
+        
+        m_requestProcessor.processRequest(req, resp, (ResourceResolver) req.getAttribute(AuthenticationSupport.REQUEST_ATTRIBUTE_RESOLVER));
+        
+        output.write("\n\n".getBytes("UTF-8"));
+        resp.getOutputStream().write(output.toByteArray());
+        
+        resp.flushBuffer();
+    }
+
+    @Override
+    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
+    {
+        HttpServletRequestWrapper reqWrapper = new HttpServletRequestWrapper(req) {
+            @Override
+            public String getServletPath()
+            {
+                return "";
+            }
+            
+            @Override
+            public String getPathInfo()
+            {
+                String path = super.getPathInfo();
+                return path != null && path.startsWith("/next/") ? path.substring("/next".length()) : path;
+            }
+        };
+        
+        if (req.getHeader("Accept") == null || !req.getHeader("Accept").contains("text/event-stream"))
+        {
+            m_requestProcessor.processRequest(reqWrapper, resp, (ResourceResolver) req.getAttribute(AuthenticationSupport.REQUEST_ATTRIBUTE_RESOLVER));
+            return;
+        }
+        
+        resp.setContentType("text/event-stream");
+        resp.setCharacterEncoding("UTF-8");
+        
+        dispatch(reqWrapper, resp);
+        
+        AsyncContext ac = req.startAsync(reqWrapper, resp);
+        ac.setTimeout(60 * 60 * 1000);
+        
+        Listener listener = new Listener(ac);
+       
+        String pattern = reqWrapper.getPathInfo();
+        if (pattern == null) {
+            pattern = "/content/";
+        }
+        else if (!pattern.endsWith("/")){
+           pattern = pattern + "/";
+        }
+        
+        pattern = "=glob:" + pattern + "**";
+        
+        registerListener(pattern, listener);
+        
+        ac.addListener(listener);
+        
+        dispatch(reqWrapper, resp);
+    }
+}