You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by da...@apache.org on 2006/03/13 00:23:13 UTC

svn commit: r385390 - in /cocoon/trunk/cocoon-blocks-fw: cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/util/ cocoon-blocks-fw-osgi-impl/META-INF/ cocoon-blocks-fw-osgi-impl/src/main/java/org/apache/cocoon/blocks/osgi/

Author: danielf
Date: Sun Mar 12 15:23:11 2006
New Revision: 385390

URL: http://svn.apache.org/viewcvs?rev=385390&view=rev
Log:
Added OSGi based block protocol. It is globally registered through the OSGi URL service and available with java.net.URL, see TestServlet2 for examples. It is not working completely yet. Other blocks and the own block are called through the protocol but something goes wrong with the output stream, so there is no output yet.

Added:
    cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/util/BlockCallHttpServletRequest.java   (with props)
    cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/util/BlockCallHttpServletResponse.java   (with props)
    cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/util/RequestParameters.java
      - copied, changed from r384269, cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/environment/wrapper/RequestParameters.java
    cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-osgi-impl/src/main/java/org/apache/cocoon/blocks/osgi/BlockConnection.java
      - copied, changed from r384337, cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-servlet-impl/src/main/java/org/apache/cocoon/components/source/impl/BlockSource.java
    cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-osgi-impl/src/main/java/org/apache/cocoon/blocks/osgi/BlockProtocol.java   (with props)
Modified:
    cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-osgi-impl/META-INF/MANIFEST.MF
    cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-osgi-impl/META-INF/components.xml
    cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-osgi-impl/src/main/java/org/apache/cocoon/blocks/osgi/BlockServlet.java
    cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-osgi-impl/src/main/java/org/apache/cocoon/blocks/osgi/TestServlet.java
    cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-osgi-impl/src/main/java/org/apache/cocoon/blocks/osgi/TestServlet2.java

Added: cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/util/BlockCallHttpServletRequest.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/util/BlockCallHttpServletRequest.java?rev=385390&view=auto
==============================================================================
--- cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/util/BlockCallHttpServletRequest.java (added)
+++ cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/util/BlockCallHttpServletRequest.java Sun Mar 12 15:23:11 2006
@@ -0,0 +1,425 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ * Licensed  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.cocoon.blocks.util;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.security.Principal;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.Map;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+
+
+/**
+ * Create a HttpServletRequest from an URL, that is used while calling e.g. a block.
+ * 
+ * @version $Id$
+ */
+public class BlockCallHttpServletRequest implements HttpServletRequest{
+    
+    private URI uri;
+    private Hashtable attributes = new Hashtable();
+    private RequestParameters parameters;
+    private String encoding;
+
+    public BlockCallHttpServletRequest(URI uri) {
+        this.uri = uri;
+        this.parameters = new RequestParameters(this.uri.getQuery());
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletRequestWrapper#getAttribute(java.lang.String)
+     */
+    public Object getAttribute(String name) {
+        return this.attributes.get(name);
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletRequestWrapper#getAttributeNames()
+     */
+    public Enumeration getAttributeNames() {
+        return this.attributes.keys();
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServletRequest#getAuthType()
+     */
+    public String getAuthType() {
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletRequest#getCharacterEncoding()
+     */
+    public String getCharacterEncoding() {
+        return this.encoding;
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletRequest#getContentLength()
+     */
+    public int getContentLength() {
+        // TODO Doesn't handle input streams yet
+        return -1;
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletRequest#getContentType()
+     */
+    public String getContentType() {
+        // TODO Doesn't handle input streams yet
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServletRequestWrapper#getContextPath()
+     */
+    public String getContextPath() {
+        return "";
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServletRequest#getCookies()
+     */
+    public Cookie[] getCookies() {
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServletRequest#getDateHeader(java.lang.String)
+     */
+    public long getDateHeader(String name) {
+        return -1;
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServletRequest#getHeader(java.lang.String)
+     */
+    public String getHeader(String name) {
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServletRequest#getHeaderNames()
+     */
+    public Enumeration getHeaderNames() {
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServletRequest#getHeaders(java.lang.String)
+     */
+    public Enumeration getHeaders(String name) {
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletRequest#getInputStream()
+     */
+    public ServletInputStream getInputStream() throws IOException {
+        // TODO Doesn't handle input streams yet
+        throw new UnsupportedOperationException();
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServletRequest#getIntHeader(java.lang.String)
+     */
+    public int getIntHeader(String name) {
+        return -1;
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletRequest#getLocale()
+     */
+    public Locale getLocale() {
+        // TODO Implement this
+        throw new UnsupportedOperationException();
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletRequest#getLocales()
+     */
+    public Enumeration getLocales() {
+        // TODO Implement this
+        throw new UnsupportedOperationException();
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServletRequest#getMethod()
+     */
+    public String getMethod() {
+        // TODO Only implements GET yet
+        return "GET";
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletRequestWrapper#getParameter(java.lang.String)
+     */
+    public String getParameter(String name) {
+        return this.parameters.getParameter(name);
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletRequestWrapper#getParameterMap()
+     */
+    public Map getParameterMap() {
+        // TODO Implement this
+        throw new UnsupportedOperationException();
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletRequestWrapper#getParameterNames()
+     */
+    public Enumeration getParameterNames() {
+        return this.parameters.getParameterNames();
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletRequestWrapper#getParameterValues(java.lang.String)
+     */
+    public String[] getParameterValues(String name) {
+        return this.parameters.getParameterValues(name);
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServletRequestWrapper#getPathInfo()
+     */
+    public String getPathInfo() {
+        return this.uri.getPath();
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServletRequest#getPathTranslated()
+     */
+    public String getPathTranslated() {
+        // TODO This is legal but more info might be possible
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletRequest#getProtocol()
+     */
+    public String getProtocol() {
+        // TODO Implement this
+        throw new UnsupportedOperationException();
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServletRequestWrapper#getQueryString()
+     */
+    public String getQueryString() {
+        return this.uri.getQuery();
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletRequest#getReader()
+     */
+    public BufferedReader getReader() throws IOException {
+        // TODO No input handling yet
+        throw new UnsupportedOperationException();
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletRequest#getRealPath(java.lang.String)
+     */
+    public String getRealPath(String path) {
+        // Deprecated
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletRequest#getRemoteAddr()
+     */
+    public String getRemoteAddr() {
+        // TODO The URI of the current block might be an appropriate choice.
+        throw new UnsupportedOperationException();
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletRequest#getRemoteHost()
+     */
+    public String getRemoteHost() {
+        // TODO Local host might be an appropriate choice
+        throw new UnsupportedOperationException();
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServletRequest#getRemoteUser()
+     */
+    public String getRemoteUser() {
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletRequest#getRequestDispatcher(java.lang.String)
+     */
+    public RequestDispatcher getRequestDispatcher(String path) {
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServletRequest#getRequestedSessionId()
+     */
+    public String getRequestedSessionId() {
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServletRequestWrapper#getRequestURI()
+     */
+    public String getRequestURI() {
+        return this.getContextPath() + this.getServletPath() + this.getPathInfo();
+    }
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServletRequestWrapper#getRequestURL()
+     */
+    public StringBuffer getRequestURL() {
+        return new StringBuffer(this.getScheme()).append(':').append(this.getRequestURI());
+    }
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletRequest#getScheme()
+     */
+    public String getScheme() {
+        return this.uri.getScheme();
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletRequest#getServerName()
+     */
+    public String getServerName() {
+        return this.getServerName();
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletRequest#getServerPort()
+     */
+    public int getServerPort() {
+        return this.getServerPort();
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServletRequestWrapper#getServletPath()
+     */
+    public String getServletPath() {
+        return "";
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServletRequest#getSession()
+     */
+    public HttpSession getSession() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServletRequest#getSession(boolean)
+     */
+    public HttpSession getSession(boolean create) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServletRequest#getUserPrincipal()
+     */
+    public Principal getUserPrincipal() {
+        // TODO No authentication handling between blocks yet
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromCookie()
+     */
+    public boolean isRequestedSessionIdFromCookie() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromUrl()
+     */
+    public boolean isRequestedSessionIdFromUrl() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromURL()
+     */
+    public boolean isRequestedSessionIdFromURL() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdValid()
+     */
+    public boolean isRequestedSessionIdValid() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletRequest#isSecure()
+     */
+    public boolean isSecure() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServletRequest#isUserInRole(java.lang.String)
+     */
+    public boolean isUserInRole(String role) {
+        // TODO No authentication handling between blocks yet
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletRequestWrapper#removeAttribute(java.lang.String)
+     */
+    public void removeAttribute(String name) {
+        this.attributes.remove(name);
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletRequestWrapper#setAttribute(java.lang.String, java.lang.Object)
+     */
+    public void setAttribute(String name, Object value) {
+        if (value != null)
+            this.attributes.put(name, value);
+        else
+            this.removeAttribute(name);
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletRequest#setCharacterEncoding(java.lang.String)
+     */
+    public void setCharacterEncoding(String encoding) throws UnsupportedEncodingException {
+        this.encoding = encoding;
+    }
+}
\ No newline at end of file

Propchange: cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/util/BlockCallHttpServletRequest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/util/BlockCallHttpServletRequest.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/util/BlockCallHttpServletResponse.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/util/BlockCallHttpServletResponse.java?rev=385390&view=auto
==============================================================================
--- cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/util/BlockCallHttpServletResponse.java (added)
+++ cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/util/BlockCallHttpServletResponse.java Sun Mar 12 15:23:11 2006
@@ -0,0 +1,280 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ * Licensed  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.cocoon.blocks.util;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.util.Locale;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Creates a HttpServletResponse object that is usable for internal block calls.
+ * 
+ * @version $Id:$
+ */
+public class BlockCallHttpServletResponse implements HttpServletResponse {
+
+    private OutputStream outputStream;
+    private ServletOutputStream servletStream;
+    private OutputStreamWriter writer;
+    private boolean committed;
+    private Locale locale;
+
+    public BlockCallHttpServletResponse() {
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServletResponse#addCookie(javax.servlet.http.Cookie)
+     */
+    public void addCookie(Cookie cookie) {
+        // Ignore
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServletResponseWrapper#addDateHeader(java.lang.String, long)
+     */
+    public void addDateHeader(String name, long date) {
+        // Ignore
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServletResponseWrapper#addHeader(java.lang.String, java.lang.String)
+     */
+    public void addHeader(String name, String value) {
+        // Ignore
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServletResponseWrapper#addIntHeader(java.lang.String, int)
+     */
+    public void addIntHeader(String name, int value) {
+        // Ignore
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServletResponse#containsHeader(java.lang.String)
+     */
+    public boolean containsHeader(String name) {
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServletResponse#encodeRedirectUrl(java.lang.String)
+     */
+    public String encodeRedirectUrl(String url) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServletResponse#encodeRedirectURL(java.lang.String)
+     */
+    public String encodeRedirectURL(String url) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServletResponse#encodeUrl(java.lang.String)
+     */
+    public String encodeUrl(String url) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServletResponse#encodeURL(java.lang.String)
+     */
+    public String encodeURL(String url) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletResponseWrapper#flushBuffer()
+     */
+    public void flushBuffer() throws IOException {
+        this.committed = true;
+    }
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletResponseWrapper#getBufferSize()
+     */
+    public int getBufferSize() {
+        return 0;
+    }
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletResponse#getCharacterEncoding()
+     */
+    public String getCharacterEncoding() {
+        // TODO Let it depend on the actual response body
+        return "ISO-8859-1";
+    }
+    
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletResponse#getLocale()
+     */
+    public Locale getLocale() {
+        return this.locale;
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletResponseWrapper#getOutputStream()
+     */
+    public ServletOutputStream getOutputStream() throws IOException {
+        if (this.writer != null)
+            throw new IllegalStateException( "Tried to create output stream; writer already exists" );
+
+        return new ServletOutputStream() {
+
+            /* (non-Javadoc)
+             * @see java.io.OutputStream#write(int)
+             */
+            public void write(int b) throws IOException {
+                BlockCallHttpServletResponse.this.outputStream.write(b);
+            }
+        };
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletResponseWrapper#getWriter()
+     */
+    public PrintWriter getWriter() throws IOException {
+        if (this.servletStream != null)
+            throw new IllegalStateException( "Tried to create writer; output stream already exists" );
+
+        return new PrintWriter(new OutputStreamWriter(this.outputStream, this.getCharacterEncoding()));
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletResponseWrapper#isCommitted()
+     */
+    public boolean isCommitted() {
+        return this.committed;
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletResponseWrapper#reset()
+     */
+    public void reset() {
+        this.resetBuffer();
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletResponseWrapper#resetBuffer()
+     */
+    public void resetBuffer() {
+        if (this.committed)
+            throw new IllegalStateException( "May not resetBuffer after response is committed" );
+        this.outputStream = null;
+        this.servletStream = null;
+        this.writer = null;
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServletResponse#sendError(int)
+     */
+    public void sendError(int sc) throws IOException {
+        // TODO Auto-generated method stub
+        
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServletResponse#sendError(int, java.lang.String)
+     */
+    public void sendError(int sc, String msg) throws IOException {
+        // TODO Auto-generated method stub
+        
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServletResponse#sendRedirect(java.lang.String)
+     */
+    public void sendRedirect(String location) throws IOException {
+        // TODO Auto-generated method stub
+        
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletResponseWrapper#setBufferSize(int)
+     */
+    public void setBufferSize(int size) {
+        // TODO Implement buffering, for the moment ignore.
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletResponseWrapper#setContentLength(int)
+     */
+    public void setContentLength(int len) {
+        // Ignore
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletResponse#setContentType(java.lang.String)
+     */
+    public void setContentType(String type) {
+        // Ignore
+    }
+    
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServletResponseWrapper#setDateHeader(java.lang.String, long)
+     */
+    public void setDateHeader(String name, long date) {
+        // Ignore
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServletResponseWrapper#setHeader(java.lang.String, java.lang.String)
+     */
+    public void setHeader(String name, String value) {
+        // Ignore
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServletResponseWrapper#setIntHeader(java.lang.String, int)
+     */
+    public void setIntHeader(String name, int value) {
+        // Ignore
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletResponse#setLocale(java.util.Locale)
+     */
+    public void setLocale(Locale loc) {
+        this.locale = loc;
+    }
+
+    public void setOutputStream(OutputStream outputStream) {
+        this.outputStream = outputStream;        }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServletResponseWrapper#setStatus(int)
+     */
+    public void setStatus(int sc) {
+        // Ignore
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServletResponseWrapper#setStatus(int, java.lang.String)
+     */
+    public void setStatus(int sc, String sm) {
+        // Ignore
+    }
+}

Propchange: cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/util/BlockCallHttpServletResponse.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/util/BlockCallHttpServletResponse.java
------------------------------------------------------------------------------
    svn:keywords = Id

Copied: cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/util/RequestParameters.java (from r384269, cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/environment/wrapper/RequestParameters.java)
URL: http://svn.apache.org/viewcvs/cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/util/RequestParameters.java?p2=cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/util/RequestParameters.java&p1=cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/environment/wrapper/RequestParameters.java&r1=384269&r2=385390&rev=385390&view=diff
==============================================================================
--- cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/environment/wrapper/RequestParameters.java (original)
+++ cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/util/RequestParameters.java Sun Mar 12 15:23:11 2006
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.cocoon.environment.wrapper;
+package org.apache.cocoon.blocks.util;
 
 import java.io.Serializable;
 import java.util.ArrayList;

Modified: cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-osgi-impl/META-INF/MANIFEST.MF
URL: http://svn.apache.org/viewcvs/cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-osgi-impl/META-INF/MANIFEST.MF?rev=385390&r1=385389&r2=385390&view=diff
==============================================================================
--- cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-osgi-impl/META-INF/MANIFEST.MF (original)
+++ cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-osgi-impl/META-INF/MANIFEST.MF Sun Mar 12 15:23:11 2006
@@ -12,4 +12,5 @@
  org.osgi.framework;version="1.3.0",
  org.osgi.service.component;version="1.0.0",
  org.osgi.service.http,
- org.osgi.service.log
+ org.osgi.service.log,
+ org.osgi.service.url

Modified: cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-osgi-impl/META-INF/components.xml
URL: http://svn.apache.org/viewcvs/cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-osgi-impl/META-INF/components.xml?rev=385390&r1=385389&r2=385390&view=diff
==============================================================================
--- cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-osgi-impl/META-INF/components.xml (original)
+++ cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-osgi-impl/META-INF/components.xml Sun Mar 12 15:23:11 2006
@@ -16,6 +16,19 @@
                    unbind="unsetServlet"/>
   </scr:component>
   
+  <scr:component name="cocoon.protocol.block">
+    <scr:implementation class="org.apache.cocoon.blocks.osgi.BlockProtocol"/>
+    <scr:service>
+      <scr:provide interface="org.osgi.service.url.URLStreamHandlerService"/>
+	</scr:service>
+	<scr:property name="url.handler.protocol">
+	  block
+	</scr:property>
+    <scr:reference name="LOG"
+                   interface="org.osgi.service.log.LogService"
+                   bind="setLog"/>
+  </scr:component>
+  
   <scr:component name="cocoon.blockServlet1">
     <scr:implementation class="org.apache.cocoon.blocks.osgi.BlockServlet"/>
     <scr:service>

Copied: cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-osgi-impl/src/main/java/org/apache/cocoon/blocks/osgi/BlockConnection.java (from r384337, cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-servlet-impl/src/main/java/org/apache/cocoon/components/source/impl/BlockSource.java)
URL: http://svn.apache.org/viewcvs/cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-osgi-impl/src/main/java/org/apache/cocoon/blocks/osgi/BlockConnection.java?p2=cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-osgi-impl/src/main/java/org/apache/cocoon/blocks/osgi/BlockConnection.java&p1=cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-servlet-impl/src/main/java/org/apache/cocoon/components/source/impl/BlockSource.java&r1=384337&r2=385390&rev=385390&view=diff
==============================================================================
--- cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-servlet-impl/src/main/java/org/apache/cocoon/components/source/impl/BlockSource.java (original)
+++ cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-osgi-impl/src/main/java/org/apache/cocoon/blocks/osgi/BlockConnection.java Sun Mar 12 15:23:11 2006
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.cocoon.components.source.impl;
+package org.apache.cocoon.blocks.osgi;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
@@ -22,38 +22,34 @@
 import java.net.MalformedURLException;
 import java.net.URI;
 import java.net.URISyntaxException;
-import java.util.Map;
+import java.net.URL;
+import java.net.URLConnection;
 
 import javax.servlet.RequestDispatcher;
 import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
 
-import org.apache.avalon.framework.logger.Logger;
-import org.apache.avalon.framework.service.ServiceManager;
 import org.apache.cocoon.blocks.BlockCallStack;
-import org.apache.cocoon.environment.Environment;
-import org.apache.cocoon.environment.http.HttpEnvironment;
-import org.apache.cocoon.environment.internal.EnvironmentHelper;
-import org.apache.excalibur.source.Source;
-import org.apache.excalibur.source.SourceException;
-import org.apache.excalibur.source.impl.AbstractSource;
+import org.apache.cocoon.blocks.util.BlockCallHttpServletRequest;
+import org.apache.cocoon.blocks.util.BlockCallHttpServletResponse;
+import org.osgi.service.log.LogService;
 
 /**
- * Implementation of a {@link Source} that gets its content by
+ * Implementation of a {@link URLConnection} that gets its content by
  * invoking the Block. 
+ * 
+ * TODO Plenty of work left to have a meaningfull implementation of all methods
  *
  * @version $Id$
  */
-public final class BlockSource
-    extends AbstractSource {
+public final class BlockConnection
+    extends URLConnection {
 
     /** Wrapped request */
-    private BlockHttpServletRequestWrapper wrappedRequest;
+    private BlockCallHttpServletRequest request;
     
     /** Wrapped response */
-    private BlockHttpServletResponseWrapper wrappedResponse;
+    private BlockCallHttpServletResponse response;
 
     /** The name of the called block */
     private String blockName;
@@ -63,150 +59,85 @@
     
     private String systemId;
     
-    private Logger logger;
+    private LogService logger;
 
     /**
      * Construct a new object
      */
-    public BlockSource(ServiceManager manager,
-                       String         uri,
-                       Map            parameters,
-                       Logger         logger)
+    public BlockConnection(URL url, LogService logger)
         throws MalformedURLException {
 
+        super(url);
         this.logger = logger;
         
-        Environment env = EnvironmentHelper.getCurrentEnvironment();
-        if (env == null) {
-            throw new MalformedURLException("The block protocol can not be used outside an environment.");
-        }
         this.context = BlockCallStack.getCurrentBlockContext();
         if (this.context == null)
-            throw new MalformedURLException("Must be used in a block context " + this.getURI());
+            throw new MalformedURLException("Must be used in a block context " + this.getURL());
 
         URI blockURI = null;
         try {
-            blockURI = parseBlockURI(env, uri);
+            blockURI = parseBlockURI(url.toURI());
         } catch (URISyntaxException e) {
             throw new MalformedURLException("Malformed URI in block source " +
                                             e.getMessage());
         }
-        setScheme(blockURI.getScheme());
-        setSystemId(this.systemId);
-
-        // wrap the request
-        HttpServletRequest originalRequest =
-            (HttpServletRequest) env.getObjectModel().get(HttpEnvironment.HTTP_REQUEST_OBJECT);
-        if (originalRequest == null)
-            throw new MalformedURLException("Blocks only work in an HttpEnvironment");
-        
-        this.wrappedRequest = new BlockHttpServletRequestWrapper(originalRequest, blockURI);
 
-        // wrap the response
-        HttpServletResponse originalResponse =
-            (HttpServletResponse) env.getObjectModel().get(HttpEnvironment.HTTP_RESPONSE_OBJECT);
-        if (originalResponse == null)
-            throw new MalformedURLException("Blocks only work in an HttpEnvironment");
-        
-        this.wrappedResponse = new BlockHttpServletResponseWrapper(originalResponse);
+        this.request = new BlockCallHttpServletRequest(blockURI);
+        this.response = new BlockCallHttpServletResponse();
     }
+    
+    public void connect() throws IOException {}
 
     /**
      * Return an <code>InputStream</code> object to read from the source.
      */
-    public InputStream getInputStream()
-        throws IOException, SourceException {
+    public InputStream getInputStream() throws IOException {
 
         ByteArrayOutputStream os = new ByteArrayOutputStream();
-        this.wrappedResponse.setOutputStream(os);
+        this.response.setOutputStream(os);
+        RequestDispatcher dispatcher = null;
         
         try {
             if (this.blockName == null) {
                 // FIXME Should be called with path + queryString,
                 // but the argument is ignored so it doesn't matter
-                RequestDispatcher dispatcher =
-                    this.context.getRequestDispatcher(this.systemId);
-                if (dispatcher == null)
-                    throw new ServletException("No dispatcher for " + this.systemId);
-                dispatcher.forward(this.wrappedRequest, this.wrappedResponse);
+                dispatcher = this.context.getRequestDispatcher(this.systemId);
             } else {
-                RequestDispatcher dispatcher =
-                    this.context.getNamedDispatcher(this.blockName);
-                if (dispatcher == null)
-                    throw new ServletException("No dispatcher for " + this.blockName);
-                dispatcher.forward(this.wrappedRequest, this.wrappedResponse);
+                dispatcher = this.context.getNamedDispatcher(this.blockName);
             }
-            this.wrappedResponse.flushBuffer();
+            if (dispatcher == null)
+                throw new ServletException("No dispatcher for " + this.systemId);
+            dispatcher.forward(this.request, this.response);
+            this.response.flushBuffer();
             
-            return new ByteArrayInputStream(os.toByteArray());
-
-        } catch (Exception e) {
-            throw new SourceException("Exception during processing of " + this.getURI(), e);
+            byte[] out = os.toByteArray();
+            System.out.print("BlockConnection:" + out.length + "[");
+            System.out.write(out, 0, out.length);
+            System.out.println("]");
+            
+            return new ByteArrayInputStream(out);
+        } catch (ServletException e) {
+            throw new IOException("BlockConnection " + e.getMessage());
         }
     }
 
-    /**
-     * Returns true always.
-     * @see org.apache.excalibur.source.Source#exists()
-     */
-    public boolean exists() {
-        return true;
-    }
-    
-    protected final Logger getLogger() {
+    protected final LogService getLogger() {
         return this.logger;
     }
 
-    /**
-     * Recyclable
-     */
-    public void recycle() {
-    }
-
-    /**
-     * Parses and resolves the scheme specific part of a block URI
-     * with respect to the base URI of the current sitemap. The scheme
-     * specific part of the block URI has the form
-     * <code>foo:/bar</code> when refering to another block, in this
-     * case only an absolute path is allowed. For reference to the own
-     * block, both absolute <code>/bar</code> and relative
-     * <code>./foo</code> paths are allowed.
-     */
-    public static URI resolveURI(URI uri, URI base) throws URISyntaxException {
-        if (uri.getPath() != null && uri.getPath().length() >= 2 &&
-            uri.getPath().startsWith("./")) {
-            // self reference relative to the current sitemap, e.g. ./foo
-            if (uri.isAbsolute())
-                throw new URISyntaxException(uri.toString(), "When the protocol refers to other blocks the path must be absolute");
-            URI resolvedURI = base.resolve(uri);
-            uri = resolvedURI;
-        }
-        return uri;
-    }
-    
     // Parse the block protocol.
-    private URI parseBlockURI(Environment env, String blockURI) 
-        throws URISyntaxException {
-
-        URI uri = new URI(blockURI);
-
+    private URI parseBlockURI(URI uri) throws URISyntaxException {
         // Can't happen
         if (!uri.isAbsolute()) {
-            throw new URISyntaxException(blockURI,
+            throw new URISyntaxException(uri.toString(),
                                          "Only absolute URIs are allowed for the block protocol.");
         }
         String scheme = uri.getScheme();
 
-        String baseURI = env.getURIPrefix();
-        if (baseURI.length() == 0 || !baseURI.startsWith("/"))
-            baseURI = "/" + baseURI;
-        
-        this.getLogger().debug("BlockSource: resolving " + uri.toString() + " with scheme " +
+        this.getLogger().log(LogService.LOG_DEBUG, "BlockSource: resolving " + uri.toString() + " with scheme " +
                         uri.getScheme() + " and ssp " + uri.getSchemeSpecificPart());
-        uri = BlockSource.resolveURI(new URI(uri.getSchemeSpecificPart()),
-                        new URI(null, null, baseURI, null));
-        this.getLogger().debug("BlockSource: resolved to " + uri.toString() +
-                        " with base URI " + baseURI.toString());
+        uri = new URI(uri.getSchemeSpecificPart());
+        this.getLogger().log(LogService.LOG_DEBUG, "BlockSource: resolved to " + uri.toString());
         
         this.blockName = uri.getScheme();
         String path = uri.getPath();

Added: cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-osgi-impl/src/main/java/org/apache/cocoon/blocks/osgi/BlockProtocol.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-osgi-impl/src/main/java/org/apache/cocoon/blocks/osgi/BlockProtocol.java?rev=385390&view=auto
==============================================================================
--- cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-osgi-impl/src/main/java/org/apache/cocoon/blocks/osgi/BlockProtocol.java (added)
+++ cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-osgi-impl/src/main/java/org/apache/cocoon/blocks/osgi/BlockProtocol.java Sun Mar 12 15:23:11 2006
@@ -0,0 +1,44 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.blocks.osgi;
+
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLConnection;
+
+import org.osgi.service.log.LogService;
+import org.osgi.service.url.AbstractURLStreamHandlerService;
+
+/**
+ * Factory for block protocol
+ * 
+ * @version $Id$
+ */
+public class BlockProtocol extends AbstractURLStreamHandlerService {
+
+    private LogService log;
+    
+    protected void setLog(LogService log) {
+        this.log = log;
+    }
+    /* (non-Javadoc)
+     * @see org.osgi.service.url.AbstractURLStreamHandlerService#openConnection(java.net.URL)
+     */
+    public URLConnection openConnection(URL url) throws IOException {
+        return new BlockConnection(url, this.log);
+    }
+
+}

Propchange: cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-osgi-impl/src/main/java/org/apache/cocoon/blocks/osgi/BlockProtocol.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-osgi-impl/src/main/java/org/apache/cocoon/blocks/osgi/BlockProtocol.java
------------------------------------------------------------------------------
    svn:keywords = Id

Modified: cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-osgi-impl/src/main/java/org/apache/cocoon/blocks/osgi/BlockServlet.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-osgi-impl/src/main/java/org/apache/cocoon/blocks/osgi/BlockServlet.java?rev=385390&r1=385389&r2=385390&view=diff
==============================================================================
--- cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-osgi-impl/src/main/java/org/apache/cocoon/blocks/osgi/BlockServlet.java (original)
+++ cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-osgi-impl/src/main/java/org/apache/cocoon/blocks/osgi/BlockServlet.java Sun Mar 12 15:23:11 2006
@@ -26,6 +26,7 @@
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import org.apache.cocoon.blocks.BlockCallStack;
 import org.apache.cocoon.blocks.util.ServletConfigurationWrapper;
 import org.osgi.service.component.ComponentContext;
 
@@ -75,7 +76,12 @@
     throws ServletException, IOException {
         RequestDispatcher dispatcher =
             this.blockContext.getRequestDispatcher(request.getPathInfo());
-        dispatcher.forward(request, response);
+        try {
+            BlockCallStack.enterBlock(this.blockContext);
+            dispatcher.forward(request, response);
+        } finally {
+            BlockCallStack.leaveBlock();
+        }
     }
 
     /**

Modified: cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-osgi-impl/src/main/java/org/apache/cocoon/blocks/osgi/TestServlet.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-osgi-impl/src/main/java/org/apache/cocoon/blocks/osgi/TestServlet.java?rev=385390&r1=385389&r2=385390&view=diff
==============================================================================
--- cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-osgi-impl/src/main/java/org/apache/cocoon/blocks/osgi/TestServlet.java (original)
+++ cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-osgi-impl/src/main/java/org/apache/cocoon/blocks/osgi/TestServlet.java Sun Mar 12 15:23:11 2006
@@ -28,6 +28,8 @@
 public class TestServlet extends HttpServlet {
 
     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+        System.out.println("TestServlet:");
+        
         response.setContentType("text/plain");
         String attr = this.getInitParameter("attr");
         response.getWriter().println("Test! " + attr);

Modified: cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-osgi-impl/src/main/java/org/apache/cocoon/blocks/osgi/TestServlet2.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-osgi-impl/src/main/java/org/apache/cocoon/blocks/osgi/TestServlet2.java?rev=385390&r1=385389&r2=385390&view=diff
==============================================================================
--- cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-osgi-impl/src/main/java/org/apache/cocoon/blocks/osgi/TestServlet2.java (original)
+++ cocoon/trunk/cocoon-blocks-fw/cocoon-blocks-fw-osgi-impl/src/main/java/org/apache/cocoon/blocks/osgi/TestServlet2.java Sun Mar 12 15:23:11 2006
@@ -16,9 +16,12 @@
 package org.apache.cocoon.blocks.osgi;
 
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.net.URLConnection;
 
 import javax.servlet.RequestDispatcher;
-import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
@@ -30,10 +33,52 @@
 public class TestServlet2 extends HttpServlet {
 
     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
-        System.out.println("TestServlet2: context=" + this.getServletContext());
-        RequestDispatcher block1 = this.getServletContext().getNamedDispatcher("block1");
-        System.out.println("TestServlet2: dispatcher=" + block1);
-        block1.forward(request, response);
+        String path = request.getPathInfo();
+        
+        System.out.println("TestServlet2: " + path);
+        if ("/test1".equals(path)) {
+            response.setContentType("text/plain");
+            String attr = this.getInitParameter("attr");
+            response.getWriter().println("Test! " + attr);
+            response.getWriter().flush();
+        } else if ("/test2".equals(path)) {
+            System.out.println("TestServlet2: context=" + this.getServletContext());
+            RequestDispatcher block1 = this.getServletContext().getNamedDispatcher("block1");
+            System.out.println("TestServlet2: dispatcher=" + block1);
+            block1.forward(request, response);
+        } else if ("/test3".equals(path)) {
+            URL url = new URL("block:/test1");
+            URLConnection conn = url.openConnection();
+            InputStream is = conn.getInputStream();
+
+            response.setContentType("text/plain");
+            OutputStream os = response.getOutputStream();
+            
+            copy(is, os);
+        } else if ("/test4".equals(path)) {
+            URL url = new URL("block:block1:/any");
+            URLConnection conn = url.openConnection();
+            InputStream is = conn.getInputStream();
+
+            response.setContentType("text/plain");
+            OutputStream os = response.getOutputStream();
+            
+            copy(is, os);
+        } else {
+            throw new ServletException("Unknown path " + path);
+        }
     }
+    
+    private static void copy(InputStream is, OutputStream os) throws IOException {
+        int bytesRead = 0;
+        byte buffer[] = new byte[512];
+        System.out.print('[');
+        while ((bytesRead = is.read(buffer)) != -1) {
+            System.out.write(buffer, 0, bytesRead);
+            os.write(buffer, 0, bytesRead);
+        }
+        System.out.println(']');
 
+        is.close();
+    }
 }