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-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org