You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by jb...@apache.org on 2015/03/02 18:15:47 UTC

svn commit: r1663366 - in /tomcat/sandbox/functional: ./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/jsp/ src/main/java/org/apache/jsp/functional/ src/test/ src/test/java/ src/test/java/samples/ s...

Author: jboynes
Date: Mon Mar  2 17:15:46 2015
New Revision: 1663366

URL: http://svn.apache.org/r1663366
Log:
Strawman for using Java 8 functional interfaces in JSPs

Added:
    tomcat/sandbox/functional/   (with props)
    tomcat/sandbox/functional/pom.xml   (with props)
    tomcat/sandbox/functional/src/
    tomcat/sandbox/functional/src/main/
    tomcat/sandbox/functional/src/main/java/
    tomcat/sandbox/functional/src/main/java/org/
    tomcat/sandbox/functional/src/main/java/org/apache/
    tomcat/sandbox/functional/src/main/java/org/apache/jsp/
    tomcat/sandbox/functional/src/main/java/org/apache/jsp/functional/
    tomcat/sandbox/functional/src/main/java/org/apache/jsp/functional/AbortException.java   (with props)
    tomcat/sandbox/functional/src/main/java/org/apache/jsp/functional/Context.java   (with props)
    tomcat/sandbox/functional/src/main/java/org/apache/jsp/functional/Fragment.java   (with props)
    tomcat/sandbox/functional/src/main/java/org/apache/jsp/functional/Page.java   (with props)
    tomcat/sandbox/functional/src/main/java/org/apache/jsp/functional/TagLibrary.java   (with props)
    tomcat/sandbox/functional/src/test/
    tomcat/sandbox/functional/src/test/java/
    tomcat/sandbox/functional/src/test/java/samples/
    tomcat/sandbox/functional/src/test/java/samples/basic/
    tomcat/sandbox/functional/src/test/java/samples/basic/BasicTagLibrary.java   (with props)
    tomcat/sandbox/functional/src/test/java/samples/basic/CoreTagLibrary.java   (with props)
    tomcat/sandbox/functional/src/test/java/samples/jsp/
    tomcat/sandbox/functional/src/test/java/samples/jsp/ContextImpl.java   (with props)
    tomcat/sandbox/functional/src/test/java/samples/jsp/PageImpl.java   (with props)
    tomcat/sandbox/functional/src/test/java/samples/servlet/
    tomcat/sandbox/functional/src/test/java/samples/servlet/FragmentStream.java   (with props)
    tomcat/sandbox/functional/src/test/java/samples/servlet/MultipleFragmentsAcceptContext.java   (with props)
    tomcat/sandbox/functional/src/test/java/samples/servlet/PageConsumesFragment.java   (with props)
    tomcat/sandbox/functional/src/test/java/samples/servlet/SingleFragmentAcceptsContext.java   (with props)

Propchange: tomcat/sandbox/functional/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Mon Mar  2 17:15:46 2015
@@ -0,0 +1,3 @@
+.idea
+*.iml
+target

Added: tomcat/sandbox/functional/pom.xml
URL: http://svn.apache.org/viewvc/tomcat/sandbox/functional/pom.xml?rev=1663366&view=auto
==============================================================================
--- tomcat/sandbox/functional/pom.xml (added)
+++ tomcat/sandbox/functional/pom.xml Mon Mar  2 17:15:46 2015
@@ -0,0 +1,70 @@
+<?xml version="1.0"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+<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.taglibs</groupId>
+    <artifactId>taglibs-parent</artifactId>
+    <version>3</version>
+  </parent>
+
+  <packaging>pom</packaging>
+
+  <artifactId>taglibs-functional</artifactId>
+  <version>0.1-SNAPSHOT</version>
+  <name>Apache Functional Taglib</name>
+
+  <inceptionYear>2001</inceptionYear>
+  <description>
+    An experimental implementation of functional tags.
+  </description>
+
+  <url>http://tomcat.apache.org/taglibs</url>
+
+  <scm>
+    <connection>scm:svn:http://svn.apache.org/repos/asf/tomcat/taglibs/sandbox/functional</connection>
+    <developerConnection>scm:svn:https://svn.apache.org/repos/asf/tomcat/taglibs/sandbox/functional</developerConnection>
+    <url>http://svn.apache.org/viewvc/tomcat/taglibs/sandbox/functional</url>
+  </scm>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>3.2</version>
+        <configuration>
+          <source>1.8</source>
+          <target>1.8</target>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.tomcat</groupId>
+      <artifactId>tomcat-jsp-api</artifactId>
+      <version>8.0.20</version>
+    </dependency>
+    <dependency>
+      <groupId>javax.inject</groupId>
+      <artifactId>javax.inject</artifactId>
+      <version>1</version>
+    </dependency>
+  </dependencies>
+</project>

Propchange: tomcat/sandbox/functional/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tomcat/sandbox/functional/src/main/java/org/apache/jsp/functional/AbortException.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/functional/src/main/java/org/apache/jsp/functional/AbortException.java?rev=1663366&view=auto
==============================================================================
--- tomcat/sandbox/functional/src/main/java/org/apache/jsp/functional/AbortException.java (added)
+++ tomcat/sandbox/functional/src/main/java/org/apache/jsp/functional/AbortException.java Mon Mar  2 17:15:46 2015
@@ -0,0 +1,33 @@
+/*
+ * 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.jsp.functional;
+
+import java.util.Objects;
+
+/**
+ * Exception used to tunnel exceptions from JSP through the functional APIs (which don't accept
+ * checked Exceptions).
+ */
+public class AbortException extends RuntimeException {
+    public AbortException() {
+        this(null);
+    }
+
+    public AbortException(Throwable cause) {
+        super(Objects.requireNonNull(cause));
+    }
+}

Propchange: tomcat/sandbox/functional/src/main/java/org/apache/jsp/functional/AbortException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tomcat/sandbox/functional/src/main/java/org/apache/jsp/functional/Context.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/functional/src/main/java/org/apache/jsp/functional/Context.java?rev=1663366&view=auto
==============================================================================
--- tomcat/sandbox/functional/src/main/java/org/apache/jsp/functional/Context.java (added)
+++ tomcat/sandbox/functional/src/main/java/org/apache/jsp/functional/Context.java Mon Mar  2 17:15:46 2015
@@ -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.jsp.functional;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.jsp.PageContext;
+
+/**
+ * A simplified view of a PageContext.
+ */
+public interface Context extends AutoCloseable {
+    PageContext getPageContext();
+
+    void write(String text);
+
+    @Override
+    void close() throws ServletException, IOException;
+}

Propchange: tomcat/sandbox/functional/src/main/java/org/apache/jsp/functional/Context.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tomcat/sandbox/functional/src/main/java/org/apache/jsp/functional/Fragment.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/functional/src/main/java/org/apache/jsp/functional/Fragment.java?rev=1663366&view=auto
==============================================================================
--- tomcat/sandbox/functional/src/main/java/org/apache/jsp/functional/Fragment.java (added)
+++ tomcat/sandbox/functional/src/main/java/org/apache/jsp/functional/Fragment.java Mon Mar  2 17:15:46 2015
@@ -0,0 +1,55 @@
+/*
+ * 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.jsp.functional;
+
+import java.util.function.Consumer;
+
+import javax.el.ELContext;
+import javax.el.ExpressionFactory;
+import javax.el.ValueExpression;
+import javax.servlet.jsp.JspFactory;
+import javax.servlet.jsp.PageContext;
+
+/**
+ * Represents JSP fragment. This is a functional equivalent to {@code JSPFragment}.
+ */
+@FunctionalInterface
+public interface Fragment extends Consumer<Context> {
+
+    default Fragment andThen(Fragment after) {
+        return (Context context) -> {
+            accept(context);
+            after.accept(context);
+        };
+    }
+
+    static Fragment write(String text) {
+        return (Context context) -> context.write(text);
+    }
+
+    static Fragment evaluate(String expression) {
+        return (Context context) -> {
+            PageContext pageContext = context.getPageContext();
+            ExpressionFactory factory = JspFactory.getDefaultFactory()
+                    .getJspApplicationContext(pageContext.getServletContext())
+                    .getExpressionFactory();
+            ELContext elContext = pageContext.getELContext();
+            ValueExpression expr = factory.createValueExpression(elContext, expression, String.class);
+            context.write((String) expr.getValue(elContext));
+        };
+    }
+}

Propchange: tomcat/sandbox/functional/src/main/java/org/apache/jsp/functional/Fragment.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tomcat/sandbox/functional/src/main/java/org/apache/jsp/functional/Page.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/functional/src/main/java/org/apache/jsp/functional/Page.java?rev=1663366&view=auto
==============================================================================
--- tomcat/sandbox/functional/src/main/java/org/apache/jsp/functional/Page.java (added)
+++ tomcat/sandbox/functional/src/main/java/org/apache/jsp/functional/Page.java Mon Mar  2 17:15:46 2015
@@ -0,0 +1,30 @@
+/*
+ * 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.jsp.functional;
+
+import java.io.IOException;
+import java.util.function.Consumer;
+
+import javax.servlet.ServletException;
+
+/**
+ * A simplified view of a JSP page.
+ */
+public interface Page extends AutoCloseable, Consumer<Fragment> {
+    @Override
+    void close() throws ServletException, IOException;
+}

Propchange: tomcat/sandbox/functional/src/main/java/org/apache/jsp/functional/Page.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tomcat/sandbox/functional/src/main/java/org/apache/jsp/functional/TagLibrary.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/functional/src/main/java/org/apache/jsp/functional/TagLibrary.java?rev=1663366&view=auto
==============================================================================
--- tomcat/sandbox/functional/src/main/java/org/apache/jsp/functional/TagLibrary.java (added)
+++ tomcat/sandbox/functional/src/main/java/org/apache/jsp/functional/TagLibrary.java Mon Mar  2 17:15:46 2015
@@ -0,0 +1,65 @@
+/*
+ * 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.jsp.functional;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Indicates that a Class defines a tag library.
+ *
+ * The tag library is defined by all public methods with return values of type
+ * {@link org.apache.jsp.functional.Fragment} or subclass. The tag's attributes are defined by
+ * the method parameters:
+ * <ul>
+ *     <li>A parameter with an {@link javax.inject.Named} annotation defines a named attribute.
+ *     The type will be inferred from the parameter type. </li>
+ *     <li>Optional attributes may be declared using an {@link java.util.Optional} parameter,
+ *     in which case the attribute type will be inferred from the Optional's type parameter. </li>
+ *     <li>A un-named parameter of type Fragment may be specified to receive the tag's body.
+ *     If no such parameter is present, no body will be permitted at translate time. An
+ *     {@code Optional<Fragment>} parameter may be used to indicate the body is optional. </li>
+ *     <li>A parameter of type {@code Map<QName, Object>} indicates an dynamic tag. Any
+ *     attributes not mapped to a @Named parameter will be passed in the map.</li>
+ * </ul>
+ *
+ * A tag may expose additional functionality to nested tags by returning a value that extends
+ * {@code Fragment}. A child tag declares a reference to a parent using a parameter with that type.
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface TagLibrary {
+
+    /**
+     * Defines the unique identifier for the library.
+     *
+     * If omitted, the URI will in the form {@code "urn:taglib:<className>"} will be derived from
+     * this Class's fully qualified name.
+     *
+     * @return the unique identifier for this library
+     */
+    String uri() default "";
+
+    /**
+     * Defines the version of the library.
+     *
+     * @return the library version, defaults to {@code "1.0"}
+     */
+    String version() default "1.0";
+}

Propchange: tomcat/sandbox/functional/src/main/java/org/apache/jsp/functional/TagLibrary.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tomcat/sandbox/functional/src/test/java/samples/basic/BasicTagLibrary.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/functional/src/test/java/samples/basic/BasicTagLibrary.java?rev=1663366&view=auto
==============================================================================
--- tomcat/sandbox/functional/src/test/java/samples/basic/BasicTagLibrary.java (added)
+++ tomcat/sandbox/functional/src/test/java/samples/basic/BasicTagLibrary.java Mon Mar  2 17:15:46 2015
@@ -0,0 +1,124 @@
+/*
+ * 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 samples.basic;
+
+import java.util.Map;
+import java.util.Optional;
+
+import javax.inject.Named;
+import javax.xml.namespace.QName;
+
+import org.apache.jsp.functional.Context;
+import org.apache.jsp.functional.Fragment;
+import org.apache.jsp.functional.TagLibrary;
+
+/**
+ * Illustration of the basic tag library functionality.
+ * The tags in here illustrate how different patterns would be represented.
+ */
+@TagLibrary
+public class BasicTagLibrary {
+
+    /**
+     * A simple tag with only attribute inputs e.g.
+     * {@code <simpleTag text="hello" primitive="1"/>}
+     *
+     * @param text an Object reference
+     * @param x    a primitive value
+     * @return a Fragment for invoking this tag
+     */
+    Fragment simpleTag(@Named("text") String text, @Named("primitive") int x) {
+        return context -> {
+        };
+    }
+
+    /**
+     * A simple tag with an optional attribute.
+     * {@link java.util.Optional#isPresent()} would be used to determine if a value was present.
+     * One issue here is whether to allow null to be passed as a value to an attribute
+     * i.e. where an ELExpression evaluates to null.
+     *
+     * @param text an optional attribute
+     * @return a Fragment for invoking this tag
+     */
+    Fragment optionalAttribute(@Named("text") Optional<String> text) {
+        return context -> {
+        };
+    }
+
+    /**
+     * A tag that processes body content (in this case just by invoking it.
+     *
+     * @param body a Fragment representing the tag's body
+     * @return a Fragment for invoking this tag
+     */
+    Fragment bodyTag(Fragment body) {
+        return body::accept;
+    }
+
+    /**
+     * A tag with dynamic attributes.
+     *
+     * @param attributes all attributes present on the tag
+     * @param body       the tag body
+     * @return a Fragment for invoking this tag
+     */
+    Fragment dynamicTag(Map<QName, Object> attributes, Fragment body) {
+        return body::accept;
+    }
+
+    /**
+     * A parent tag extends Fragment with the operations it wishes to expose to its children.
+     */
+    interface Parent extends Fragment {
+        Object someValueFromParent();
+    }
+
+    /**
+     * A tag that sets up extra context for child tags.
+     *
+     * @param text the context value to pass down
+     * @param body a Fragment representing the tag's body
+     * @return a Fragment for invoking this tag
+     */
+    Parent parentTag(@Named("text") String text, Fragment body) {
+        return new Parent() {
+            Object value;
+
+            @Override
+            public Object someValueFromParent() {
+                return value;
+            }
+
+            @Override
+            public void accept(Context context) {
+                this.value = text;
+                body.accept(context);
+            }
+        };
+    }
+
+    /**
+     * A tag that references a parent containing tag.
+     *
+     * @param parent a reference to the parent tag
+     * @return a Fragment for invoking this tag
+     */
+    Fragment parentReference(Optional<Parent> parent) {
+        return context -> context.write(String.valueOf(parent.get().someValueFromParent()));
+    }
+}

Propchange: tomcat/sandbox/functional/src/test/java/samples/basic/BasicTagLibrary.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tomcat/sandbox/functional/src/test/java/samples/basic/CoreTagLibrary.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/functional/src/test/java/samples/basic/CoreTagLibrary.java?rev=1663366&view=auto
==============================================================================
--- tomcat/sandbox/functional/src/test/java/samples/basic/CoreTagLibrary.java (added)
+++ tomcat/sandbox/functional/src/test/java/samples/basic/CoreTagLibrary.java Mon Mar  2 17:15:46 2015
@@ -0,0 +1,46 @@
+/*
+ * 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 samples.basic;
+
+import java.util.Optional;
+
+import javax.inject.Named;
+
+import org.apache.jsp.functional.Fragment;
+import org.apache.jsp.functional.TagLibrary;
+
+/**
+ * A TagLibrary with common functionality similar to JSTL.
+ */
+@TagLibrary
+public class CoreTagLibrary {
+
+    /**
+     * Example {@code <out>} tag for writing escaped text.
+     * May be replaced by some form of escaping context.
+     */
+    public Fragment out(@Named("value") Optional<Object> value, Optional<Fragment> body) {
+        return context -> {
+            if (value.isPresent()) {
+                // TODO perform escaping
+                context.write(String.valueOf(value.get()));
+            } else if (body.isPresent()) {
+                body.get().accept(context);
+            }
+        };
+    }
+}

Propchange: tomcat/sandbox/functional/src/test/java/samples/basic/CoreTagLibrary.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tomcat/sandbox/functional/src/test/java/samples/jsp/ContextImpl.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/functional/src/test/java/samples/jsp/ContextImpl.java?rev=1663366&view=auto
==============================================================================
--- tomcat/sandbox/functional/src/test/java/samples/jsp/ContextImpl.java (added)
+++ tomcat/sandbox/functional/src/test/java/samples/jsp/ContextImpl.java Mon Mar  2 17:15:46 2015
@@ -0,0 +1,60 @@
+/*
+ * 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 samples.jsp;
+
+import java.io.IOException;
+
+import javax.servlet.Servlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.jsp.JspFactory;
+import javax.servlet.jsp.JspWriter;
+import javax.servlet.jsp.PageContext;
+
+import org.apache.jsp.functional.AbortException;
+import org.apache.jsp.functional.Context;
+
+/**
+ *
+ */
+public class ContextImpl implements Context {
+    private static final JspFactory JSP_FACTORY = JspFactory.getDefaultFactory();
+    private final PageContext pageContext;
+
+    public ContextImpl(Servlet servlet, HttpServletRequest req, HttpServletResponse resp) {
+        pageContext = JSP_FACTORY.getPageContext(servlet, req, resp, null, false, JspWriter.DEFAULT_BUFFER, true);
+    }
+
+    @Override
+    public PageContext getPageContext() {
+        return pageContext;
+    }
+
+    @Override
+    public void write(String text) {
+        try {
+            pageContext.getOut().write(text);
+        } catch (IOException e) {
+            throw new AbortException(e);
+        }
+    }
+
+    @Override
+    public void close() {
+        JSP_FACTORY.releasePageContext(pageContext);
+    }
+}

Propchange: tomcat/sandbox/functional/src/test/java/samples/jsp/ContextImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tomcat/sandbox/functional/src/test/java/samples/jsp/PageImpl.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/functional/src/test/java/samples/jsp/PageImpl.java?rev=1663366&view=auto
==============================================================================
--- tomcat/sandbox/functional/src/test/java/samples/jsp/PageImpl.java (added)
+++ tomcat/sandbox/functional/src/test/java/samples/jsp/PageImpl.java Mon Mar  2 17:15:46 2015
@@ -0,0 +1,69 @@
+/*
+ * 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 samples.jsp;
+
+import java.io.IOException;
+
+import javax.servlet.Servlet;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.jsp.SkipPageException;
+
+import org.apache.jsp.functional.AbortException;
+import org.apache.jsp.functional.Context;
+import org.apache.jsp.functional.Fragment;
+import org.apache.jsp.functional.Page;
+
+/**
+ *
+ */
+public class PageImpl implements Page {
+
+    private final Context context;
+    private AbortException pageError;
+
+    public PageImpl(Servlet servlet, HttpServletRequest req, HttpServletResponse resp) {
+        this.context = new ContextImpl(servlet, req, resp);
+    }
+
+    @Override
+    public void accept(Fragment fragment) {
+        try {
+            fragment.accept(context);
+        } catch (AbortException e) {
+            pageError = e;
+        } catch (Throwable t) {
+            pageError = new AbortException(t);
+            throw pageError;
+        }
+    }
+
+    @Override
+    public void close() throws ServletException, IOException {
+        try {
+            if (pageError != null) {
+                Throwable cause = pageError.getCause();
+                if (!(cause instanceof SkipPageException)) {
+                    context.getPageContext().handlePageException(cause);
+                }
+            }
+        } finally {
+            context.close();
+        }
+    }
+}

Propchange: tomcat/sandbox/functional/src/test/java/samples/jsp/PageImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tomcat/sandbox/functional/src/test/java/samples/servlet/FragmentStream.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/functional/src/test/java/samples/servlet/FragmentStream.java?rev=1663366&view=auto
==============================================================================
--- tomcat/sandbox/functional/src/test/java/samples/servlet/FragmentStream.java (added)
+++ tomcat/sandbox/functional/src/test/java/samples/servlet/FragmentStream.java Mon Mar  2 17:15:46 2015
@@ -0,0 +1,75 @@
+/*
+ * 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 samples.servlet;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Optional;
+
+import javax.inject.Inject;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.jsp.SkipPageException;
+
+import org.apache.jsp.functional.AbortException;
+import org.apache.jsp.functional.Fragment;
+import static org.apache.jsp.functional.Fragment.evaluate;
+import static org.apache.jsp.functional.Fragment.write;
+import org.apache.jsp.functional.Page;
+import samples.basic.CoreTagLibrary;
+import samples.jsp.PageImpl;
+
+/**
+ * Alternative that uses a List to contain all the fragments comprising a page rather than using
+ * .andThen() to chain them. This pattern may be useful to a JSP engine that does not rely on code
+ * generation to build the page. On the other hand it might just be able to perform the chaining
+ * dynamically where it would otherwise construct the array.
+ */
+public class FragmentStream extends HttpServlet {
+
+    private final Collection<Fragment> pageBody;
+
+    @Inject
+    public FragmentStream(CoreTagLibrary core) {
+        pageBody = Arrays.asList(
+                write("Hello World"),
+                evaluate("${x}"),
+                core.out(Optional.of("Value param"), Optional.empty()),
+                write("Goodbye World"));
+    }
+
+    @Override
+    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+        try (Page page = new PageImpl(this, req, resp)) {
+            pageBody.stream().forEachOrdered(page);
+        } catch (AbortException e) {
+            Throwable cause = e.getCause();
+            if (cause != null) {
+                if (cause instanceof ServletException) {
+                    throw (ServletException) cause;
+                } else if (cause instanceof IOException) {
+                    throw (IOException) cause;
+                } else if (!(cause instanceof SkipPageException)) {
+                    throw new ServletException(cause);
+                }
+            }
+        }
+    }
+}

Propchange: tomcat/sandbox/functional/src/test/java/samples/servlet/FragmentStream.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tomcat/sandbox/functional/src/test/java/samples/servlet/MultipleFragmentsAcceptContext.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/functional/src/test/java/samples/servlet/MultipleFragmentsAcceptContext.java?rev=1663366&view=auto
==============================================================================
--- tomcat/sandbox/functional/src/test/java/samples/servlet/MultipleFragmentsAcceptContext.java (added)
+++ tomcat/sandbox/functional/src/test/java/samples/servlet/MultipleFragmentsAcceptContext.java Mon Mar  2 17:15:46 2015
@@ -0,0 +1,59 @@
+/*
+ * 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 samples.servlet;
+
+import java.io.IOException;
+import java.util.Optional;
+
+import javax.inject.Inject;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.jsp.functional.Context;
+import static org.apache.jsp.functional.Fragment.evaluate;
+import static org.apache.jsp.functional.Fragment.write;
+import samples.basic.CoreTagLibrary;
+import samples.jsp.ContextImpl;
+
+/**
+ * Version of JSP page code where multiple fragments represent the page and the implementation
+ * invokes them with the context. This form may make it possible to insert scriptlet blocks
+ * containing raw Java code between fragment invocations.
+ */
+public class MultipleFragmentsAcceptContext extends HttpServlet {
+
+
+    private final CoreTagLibrary core;
+
+
+    @Inject
+    public MultipleFragmentsAcceptContext(CoreTagLibrary core) {
+        this.core = core;
+    }
+
+    @Override
+    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+        try (Context context = new ContextImpl(this, req, resp)) {
+            write("Hello World").accept(context);
+            evaluate("${x}").accept(context);
+            core.out(Optional.of("Value param"), Optional.empty()).accept(context);
+            write("Goodbye World").accept(context);
+        }
+    }
+}

Propchange: tomcat/sandbox/functional/src/test/java/samples/servlet/MultipleFragmentsAcceptContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tomcat/sandbox/functional/src/test/java/samples/servlet/PageConsumesFragment.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/functional/src/test/java/samples/servlet/PageConsumesFragment.java?rev=1663366&view=auto
==============================================================================
--- tomcat/sandbox/functional/src/test/java/samples/servlet/PageConsumesFragment.java (added)
+++ tomcat/sandbox/functional/src/test/java/samples/servlet/PageConsumesFragment.java Mon Mar  2 17:15:46 2015
@@ -0,0 +1,55 @@
+/*
+ * 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 samples.servlet;
+
+import java.io.IOException;
+import java.util.Optional;
+
+import javax.inject.Inject;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.jsp.functional.Fragment;
+import static org.apache.jsp.functional.Fragment.evaluate;
+import static org.apache.jsp.functional.Fragment.write;
+import samples.basic.CoreTagLibrary;
+import samples.jsp.PageImpl;
+
+/**
+ * Alternative where the Page consumes a Fragment representing its body.
+ */
+public class PageConsumesFragment extends HttpServlet {
+
+    private final Fragment pageBody;
+
+    @Inject
+    public PageConsumesFragment(CoreTagLibrary core) {
+        this.pageBody = write("Hello World")
+                .andThen(evaluate("${x}"))
+                .andThen(core.out(Optional.of("Value param"), Optional.empty()))
+                .andThen(write("Goodbye World"));
+    }
+
+    @Override
+    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+        try (PageImpl page = new PageImpl(this, req, resp)) {
+            page.accept(pageBody);
+        }
+    }
+}

Propchange: tomcat/sandbox/functional/src/test/java/samples/servlet/PageConsumesFragment.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tomcat/sandbox/functional/src/test/java/samples/servlet/SingleFragmentAcceptsContext.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/functional/src/test/java/samples/servlet/SingleFragmentAcceptsContext.java?rev=1663366&view=auto
==============================================================================
--- tomcat/sandbox/functional/src/test/java/samples/servlet/SingleFragmentAcceptsContext.java (added)
+++ tomcat/sandbox/functional/src/test/java/samples/servlet/SingleFragmentAcceptsContext.java Mon Mar  2 17:15:46 2015
@@ -0,0 +1,63 @@
+/*
+ * 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 samples.servlet;
+
+import java.io.IOException;
+import java.util.Optional;
+
+import javax.inject.Inject;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.jsp.functional.Context;
+import org.apache.jsp.functional.Fragment;
+import static org.apache.jsp.functional.Fragment.evaluate;
+import static org.apache.jsp.functional.Fragment.write;
+import samples.basic.CoreTagLibrary;
+import samples.jsp.ContextImpl;
+
+/**
+ * Version of JSP page code that uses a single Fragment to represent the page content which then accepts
+ * the context.
+ */
+public class SingleFragmentAcceptsContext extends HttpServlet {
+
+
+    private Fragment pageBody;
+
+
+    @Inject
+    public SingleFragmentAcceptsContext(CoreTagLibrary core) {
+        this.pageBody = write("Hello World")
+                .andThen(evaluate("${x}"))
+                .andThen(core.out(Optional.of("Value param"), Optional.empty()))
+                .andThen(write("Goodbye World"));
+    }
+
+    @Override
+    public void init() throws ServletException {
+    }
+
+    @Override
+    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+        try (Context context = new ContextImpl(this, req, resp)) {
+            pageBody.accept(context);
+        }
+    }
+}

Propchange: tomcat/sandbox/functional/src/test/java/samples/servlet/SingleFragmentAcceptsContext.java
------------------------------------------------------------------------------
    svn:eol-style = native



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org