[jsr-314-open-mirror] [jsr-314-open] 490-XmlViews Processing JSPX files as Facelets
Alexander Smirnov
asmirnov at exadel.com
Fri Oct 1 13:35:33 EDT 2010
I only worried about xml validation in *-extension elements, because it
supposed to use by any third-party libraries, and RichFaces widely use
these elements to store information required by our tools.
Unfortunately, XML schema doesn't have ability to restrict parent
element. I tried to use xsd:key for that purpose, but without success.
I did not dive deep into proposed code, are you sure what it will not
block third-party elements in <faces-config-extension> ?
On 09/30/2010 08:22 PM, Edward Burns wrote:
>
> https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=490
>
> As a first step towards making JSPX files runable as Facelets, this
> commit introduces a new configuration syntax.
>
> Andy Schwartz requested this feature.
>
> For the first time ever, we are using the faces-config to specify
> context-param like configuration options. In this case, we're
> leveraging the faces-config-extension facility. Andy also suggested
> this config concept.
>
> The automated test for this feature has the following faces-config.
>
> <?xml version='1.0' encoding='UTF-8'?>
> <faces-config
> xmlns="http://java.sun.com/xml/ns/javaee"
> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
> http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
> version="2.0">
>
> <faces-config-extension>
> <facelets-processing>
> <file-extension>.jspx</file-extension>
> <process-as>jspx</process-as>
> </facelets-processing>
> <facelets-processing>
> <file-extension>.view.xml</file-extension>
> <process-as>xml</process-as>
> </facelets-processing>
> </faces-config-extension>
>
> </faces-config>
>
> The <facelets-processing> elements are new.
>
> The sample app also has these context params:
>
> <context-param>
> <param-name>javax.faces.FACELETS_VIEW_MAPPINGS</param-name>
> <param-value>*.xhtml;*.view.xml;*.jspx</param-value>
> </context-param>
>
> <context-param>
> <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
> <param-value>.xhtml .view.xml .jsp .jspx</param-value>
> </context-param>
>
> PENDING(edburns): Currently this feature relies on the existing
> <xsd:any> declaration for the children of faces-config-extension. I
> would like to tighten this up to allow validaiton but will do it after
> the 30 Sept deadline.
>
> The preceding faces-config and web.xml example must cause the
> implementation to behave as follows.
>
> The web.xml says that jspx should be considered as one of the default
> suffixes for JSF. It also says that files with a .jspx extension must
> be treated as facelets, not JSPs.
>
> The faces-config.xml says that files with the .jspx extension should be
> treated as if they are running in Facelets for JSPX mode, as specified
> in the following table. It also says that files ending in .view.xml
> must be handled as if they are running in Facelets for XML mode, also
> specified in the table.
>
>
> XML construct process-as mode
> ------------- ---------------
>
> xhtml xml jspx
> XML Declaration passed through consumed consumed
> Processing Instructions passed through consumed consumed
> CDATA passed through consumed consumed
> Inline text escaping escaped escaped not escaped
> Comments passed through consumed consumed
>
> PENDING(edburns): should the table specified above be the default, even
> if no facelets-processing elements appear? Right now, the
> facelets-processing elements must appear, otherwise the legacy facelets
> format is used in all facelet cases. I think that's correct, but I am
> open to suggestions.
>
> SECTION: Modified Files
> ----------------------------
> M jsf-ri/src/main/java/com/sun/faces/config/WebConfiguration.java
>
> - enhance this class, which previously only handled web.xml style
> configuration, to also handle faces-config.xml style
> configuration. The first manifestation of this is the new pair of
> getFacesConfigOptionValue() methods, one with a boolean create
> parameter.
>
> - To make the intent of the feature more clear, a define a read-only
> singleton helper class, FaceletsConfiguration, which is owned by the
> WebConfiguration.
>
> A
> jsf-ri/src/main/java/com/sun/faces/config/FaceletsConfiguration.java
>
> - A place to hang methods that allow the runtime to query the facelets
> configuration. Currently this only includes config options conveyed
> via the new faces-config-extension/facelets-processing elements.
>
> M
> jsf-ri/src/main/java/com/sun/faces/facelets/compiler/LiteralTextInstruction.java
>
>
> - When writing inline text, use the new config facility to determine if
> the text should be escaped or not.
>
> M
> jsf-ri/src/main/java/com/sun/faces/facelets/compiler/CompilationManager.java
>
>
> - add some ivars and getters.
>
> M jsf-ri/src/main/java/com/sun/faces/facelets/compiler/TextUnit.java
>
> - To ease migration from JSPX to facelets, allow the new <faces-view>
> markup element to exist in XHTML or XML pages, but make sure it gets
> swallowed and does not appear in the output. The startTag() and
> endTag() methods were hit.
>
> M jsf-ri/src/main/java/com/sun/faces/facelets/compiler/SAXCompiler.java
>
> - Take the correct action regarding CDATA, comments,
> processingInstructions, and the XML declaration.
>
> M jsf-ri/src/main/java/com/sun/faces/facelets/tag/xml/XmlLibrary.java
>
> - Clean imports
>
> M jsf-ri/src/main/java/com/sun/faces/config/ConfigManager.java
>
> - Add a new config processor for the faces-config-extension content.
>
> M jsf-ri/src/main/java/com/sun/faces/config/ConfigureListener.java
> M jsf-ri/systest-per-webapp/build.xml
> M jsf-ri/systest-per-webapp/build-tests.xml
>
> - new automated test
>
> A
> jsf-ri/src/main/java/com/sun/faces/config/processor/FacesConfigExtensionProcessor.java
>
>
> - expose xml config to runtime.
>
> A jsf-ri/systest-per-webapp/process-as-jspx
> A jsf-ri/systest-per-webapp/process-as-jspx/src
> A jsf-ri/systest-per-webapp/process-as-jspx/src/java
> A jsf-ri/systest-per-webapp/process-as-jspx/src/java/com
> A jsf-ri/systest-per-webapp/process-as-jspx/src/java/com/sun
> A jsf-ri/systest-per-webapp/process-as-jspx/src/java/com/sun/faces
> A jsf-ri/systest-per-webapp/process-as-jspx/src/java/com/sun/faces/systest
> A
> jsf-ri/systest-per-webapp/process-as-jspx/src/java/com/sun/faces/systest/ProcessAsJspxTestCase.java
>
> A
> jsf-ri/systest-per-webapp/process-as-jspx/src/java/com/sun/faces/systest/ProcessAsJspxBean.java
>
> A jsf-ri/systest-per-webapp/process-as-jspx/web
> A jsf-ri/systest-per-webapp/process-as-jspx/web/jspxview.jspx
> A jsf-ri/systest-per-webapp/process-as-jspx/web/xhtmlview.xhtml
> A jsf-ri/systest-per-webapp/process-as-jspx/web/jspview.jsp
> A jsf-ri/systest-per-webapp/process-as-jspx/web/xmlview.view.xml
> A jsf-ri/systest-per-webapp/process-as-jspx/web/WEB-INF
> A jsf-ri/systest-per-webapp/process-as-jspx/web/WEB-INF/faces-config.xml
> A jsf-ri/systest-per-webapp/process-as-jspx/web/WEB-INF/web.xml
> A jsf-ri/systest-per-webapp/process-as-jspx/web/index.html
>
> - Automated test.
>
>
> SECTION: Diffs
> ----------------------------
> Index:
> jsf-ri/src/main/java/com/sun/faces/facelets/compiler/LiteralTextInstruction.java
>
> ===================================================================
> ---
> jsf-ri/src/main/java/com/sun/faces/facelets/compiler/LiteralTextInstruction.java
> (revision 8624)
> +++
> jsf-ri/src/main/java/com/sun/faces/facelets/compiler/LiteralTextInstruction.java
> (working copy)
> @@ -55,10 +55,11 @@
>
> package com.sun.faces.facelets.compiler;
>
> +import com.sun.faces.config.FaceletsConfiguration;
> +import javax.faces.context.FacesContext;
> +import java.io.IOException;
> import javax.el.ELContext;
> import javax.el.ExpressionFactory;
> -import javax.faces.context.FacesContext;
> -import java.io.IOException;
>
> final class LiteralTextInstruction implements Instruction {
> private final String text;
> @@ -68,7 +69,11 @@
> }
>
> public void write(FacesContext context) throws IOException {
> - context.getResponseWriter().writeText(this.text, null);
> + if
> (FaceletsConfiguration.getInstance(context).isEscapeInlineText(context)) {
> + context.getResponseWriter().writeText(this.text, null);
> + } else {
> + context.getResponseWriter().write(this.text);
> + }
> }
>
> public Instruction apply(ExpressionFactory factory, ELContext ctx) {
> Index:
> jsf-ri/src/main/java/com/sun/faces/facelets/compiler/CompilationManager.java
>
> ===================================================================
> ---
> jsf-ri/src/main/java/com/sun/faces/facelets/compiler/CompilationManager.java
> (revision 8624)
> +++
> jsf-ri/src/main/java/com/sun/faces/facelets/compiler/CompilationManager.java
> (working copy)
> @@ -56,6 +56,7 @@
>
> package com.sun.faces.facelets.compiler;
>
> +import com.sun.faces.config.WebConfiguration;
> import com.sun.faces.facelets.tag.TagAttributesImpl;
> import com.sun.faces.facelets.tag.TagLibrary;
> import com.sun.faces.facelets.tag.composite.CompositeLibrary;
> @@ -102,6 +103,8 @@
> private final String alias;
>
> private CompilationMessageHolder messageHolder = null;
> +
> + private WebConfiguration config;
>
> public CompilationManager(String alias, Compiler compiler) {
>
> @@ -125,6 +128,8 @@
> // our compilationunit stack
> this.units = new Stack<CompilationUnit>();
> this.units.push(new CompilationUnit());
> +
> + config = WebConfiguration.getInstance();
>
> }
>
> @@ -139,6 +144,14 @@
> }
> return messageHolder;
> }
> +
> + public String getAlias() {
> + return alias;
> + }
> +
> + public WebConfiguration getWebConfiguration() {
> + return config;
> + }
>
> public void setCompilationMessageHolder(CompilationMessageHolder
> messageHolder) {
> this.messageHolder = messageHolder;
> Index: jsf-ri/src/main/java/com/sun/faces/facelets/compiler/TextUnit.java
> ===================================================================
> --- jsf-ri/src/main/java/com/sun/faces/facelets/compiler/TextUnit.java
> (revision 8624)
> +++ jsf-ri/src/main/java/com/sun/faces/facelets/compiler/TextUnit.java
> (working copy)
> @@ -54,13 +54,16 @@
>
> package com.sun.faces.facelets.compiler;
>
> +import com.sun.faces.config.FaceletsConfiguration;
> import com.sun.faces.facelets.el.ELText;
>
> import javax.el.ELException;
> import javax.faces.view.facelets.*;
> import java.util.ArrayList;
> import java.util.List;
> +import java.util.Map;
> import java.util.Stack;
> +import java.util.concurrent.ConcurrentHashMap;
>
> /**
> *
> @@ -85,6 +88,14 @@
>
> private final String id;
>
> + private final static Map<String, Boolean> qNamesToSwallow;
> +
> +
> + static {
> + qNamesToSwallow = new ConcurrentHashMap<String, Boolean>(1);
> + qNamesToSwallow.put("faces-view", Boolean.TRUE);
> + }
> +
> public TextUnit(String alias, String id) {
> this.alias = alias;
> this.id = id;
> @@ -168,16 +179,16 @@
> public void writeComment(String text) {
> this.finishStartTag();
>
> - ELText el = ELText.parse(text);
> - if (el.isLiteral()) {
> - this.addInstruction(new LiteralCommentInstruction(text));
> - } else {
> - this.addInstruction(new CommentInstruction(el));
> + ELText el = ELText.parse(text);
> + if (el.isLiteral()) {
> + this.addInstruction(new LiteralCommentInstruction(text));
> + } else {
> + this.addInstruction(new CommentInstruction(el));
> + }
> +
> + this.buffer.append("<!--" + text + "-->");
> }
>
> - this.buffer.append("<!--" + text + "-->");
> - }
> -
> public void startTag(Tag tag) {
>
> // finish any previously written tags
> @@ -185,36 +196,39 @@
>
> // push this tag onto the stack
> this.tags.push(tag);
> + String qName = tag.getQName();
>
> - // write it out
> - this.buffer.append('<');
> - this.buffer.append(tag.getQName());
> + if (!qNamesToSwallow.containsKey(qName)) {
> + // write it out
> + this.buffer.append('<');
> + this.buffer.append(qName);
>
> - this.addInstruction(new StartElementInstruction(tag.getQName()));
> + this.addInstruction(new
> StartElementInstruction(tag.getQName()));
>
> - TagAttribute[] attrs = tag.getAttributes().getAll();
> - if (attrs.length > 0) {
> - for (int i = 0; i < attrs.length; i++) {
> - String qname = attrs[i].getQName();
> - String value = attrs[i].getValue();
> - this.buffer.append('
> ').append(qname).append("=\"").append(
> + TagAttribute[] attrs = tag.getAttributes().getAll();
> + if (attrs.length > 0) {
> + for (int i = 0; i < attrs.length; i++) {
> + String qname = attrs[i].getQName();
> + String value = attrs[i].getValue();
> + this.buffer.append('
> ').append(qname).append("=\"").append(
> value).append("\"");
>
> - ELText txt = ELText.parse(value);
> - if (txt != null) {
> - if (txt.isLiteral()) {
> - this.addInstruction(new
> LiteralAttributeInstruction(
> - qname, txt.toString()));
> - } else {
> - this.addInstruction(new AttributeInstruction(
> - this.alias, qname, txt));
> + ELText txt = ELText.parse(value);
> + if (txt != null) {
> + if (txt.isLiteral()) {
> + this.addInstruction(new
> LiteralAttributeInstruction(
> + qname, txt.toString()));
> + } else {
> + this.addInstruction(new AttributeInstruction(
> + this.alias, qname, txt));
> + }
> }
> }
> }
> + // notify that we have an open tag
> + this.startTagOpen = true;
> }
>
> - // notify that we have an open tag
> - this.startTagOpen = true;
> }
>
> private void finishStartTag() {
> @@ -227,13 +241,17 @@
> public void endTag() {
> Tag tag = (Tag) this.tags.pop();
>
> - this.addInstruction(new EndElementInstruction(tag.getQName()));
> + String qName = tag.getQName();
>
> - if (this.startTagOpen) {
> - this.buffer.append("/>");
> - this.startTagOpen = false;
> - } else {
> - this.buffer.append("</").append(tag.getQName()).append('>');
> + if (!qNamesToSwallow.containsKey(qName)) {
> + this.addInstruction(new EndElementInstruction(qName));
> +
> + if (this.startTagOpen) {
> + this.buffer.append("/>");
> + this.startTagOpen = false;
> + } else {
> + this.buffer.append("</").append(tag.getQName()).append('>');
> + }
> }
> }
>
> Index:
> jsf-ri/src/main/java/com/sun/faces/facelets/compiler/SAXCompiler.java
> ===================================================================
> ---
> jsf-ri/src/main/java/com/sun/faces/facelets/compiler/SAXCompiler.java
> (revision 8624)
> +++
> jsf-ri/src/main/java/com/sun/faces/facelets/compiler/SAXCompiler.java
> (working copy)
> @@ -55,6 +55,7 @@
> package com.sun.faces.facelets.compiler;
>
> import com.sun.faces.RIConstants;
> +import com.sun.faces.config.FaceletsConfiguration;
> import com.sun.faces.config.WebConfiguration;
> import com.sun.faces.facelets.tag.TagAttributeImpl;
> import com.sun.faces.facelets.tag.TagAttributesImpl;
> @@ -71,6 +72,7 @@
> import java.io.IOException;
> import java.io.InputStream;
> import java.net.URL;
> +import java.util.Map;
> import java.util.regex.Matcher;
> import java.util.regex.Pattern;
>
> @@ -96,6 +98,8 @@
> protected Locator locator;
>
> protected final CompilationManager unit;
> +
> + private boolean inSuppressedCDATA;
>
> public CompilationHandler(CompilationManager unit, String alias) {
> this.unit = unit;
> @@ -105,14 +109,18 @@
> public void characters(char[] ch, int start, int length)
> throws SAXException {
> if (this.inDocument) {
> - this.unit.writeText(new String(ch, start, length));
> + if (!inSuppressedCDATA) {
> + this.unit.writeText(new String(ch, start, length));
> + }
> }
> }
>
> public void comment(char[] ch, int start, int length)
> throws SAXException {
> if (this.inDocument) {
> - this.unit.writeComment(new String(ch, start, length));
> + if
> (!unit.getWebConfiguration().getFaceletsConfiguration().isConsumeComments(alias))
> {
> + this.unit.writeComment(new String(ch, start, length));
> + }
> }
> }
>
> @@ -134,7 +142,10 @@
>
> public void endCDATA() throws SAXException {
> if (this.inDocument) {
> - this.unit.writeInstruction("]]>");
> + if
> (!unit.getWebConfiguration().getFaceletsConfiguration().isConsumeCDATA(alias))
> {
> + this.unit.writeInstruction("]]>");
> + }
> + this.inSuppressedCDATA = false;
> }
> }
>
> @@ -192,7 +203,12 @@
>
> public void startCDATA() throws SAXException {
> if (this.inDocument) {
> - this.unit.writeInstruction("<![CDATA[");
> + if
> (!unit.getWebConfiguration().getFaceletsConfiguration().isConsumeCDATA(alias))
> {
> + inSuppressedCDATA = false;
> + this.unit.writeInstruction("<![CDATA[");
> + } else {
> + inSuppressedCDATA = true;
> + }
> }
> }
>
> @@ -241,10 +257,18 @@
> public void processingInstruction(String target, String data)
> throws SAXException {
> if (this.inDocument) {
> - StringBuffer sb = new StringBuffer(64);
> - sb.append("<?").append(target).append('
> ').append(data).append(
> - "?>\n");
> - this.unit.writeInstruction(sb.toString());
> +
> + // If there is a process-as value for the extension,
> only allow
> + // the PI to be written if its value is xhtml
> + boolean processAsXhtml =
> +
> this.unit.getWebConfiguration().getFaceletsConfiguration().isProcessCurrentDocumentAsFaceletsXhtml(alias);
>
> +
> + if (processAsXhtml) {
> + StringBuffer sb = new StringBuffer(64);
> + sb.append("<?").append(target).append('
> ').append(data).append(
> + "?>\n");
> + this.unit.writeInstruction(sb.toString());
> + }
> }
> }
> }
> @@ -418,8 +442,16 @@
> String r = new String(b);
> Matcher m = XmlDeclaration.matcher(r);
> if (m.find()) {
> - WebConfiguration config =
> WebConfiguration.getInstance();
> - if
> (!config.isOptionEnabled(WebConfiguration.BooleanWebContextInitParameter.SuppressXmlDeclaration))
> {
> + WebConfiguration config = mngr.getWebConfiguration();
> + FaceletsConfiguration faceletsConfig =
> config.getFaceletsConfiguration();
> + boolean suppressXmlDeclIsEnabled =
> config.isOptionEnabled(WebConfiguration.BooleanWebContextInitParameter.SuppressXmlDeclaration);
>
> + boolean currentModeIsXhtml =
> faceletsConfig.isProcessCurrentDocumentAsFaceletsXhtml(mngr.getAlias());
> +
> + // We want to write the XML declaration if and only if
> + // The SuppressXmlDeclaration context-param is NOT
> enabled
> + // and the file extension for the current file has
> a mapping
> + // with the value of XHTML
> + if (!suppressXmlDeclIsEnabled && currentModeIsXhtml) {
> mngr.writeInstruction(m.group(0) + "\n");
> if (m.group(3) != null) {
> encoding = m.group(3);
> Index: jsf-ri/src/main/java/com/sun/faces/facelets/tag/xml/XmlLibrary.java
> ===================================================================
> --- jsf-ri/src/main/java/com/sun/faces/facelets/tag/xml/XmlLibrary.java
> (revision 8624)
> +++ jsf-ri/src/main/java/com/sun/faces/facelets/tag/xml/XmlLibrary.java
> (working copy)
> @@ -54,7 +54,6 @@
>
> package com.sun.faces.facelets.tag.xml;
>
> -import com.sun.faces.facelets.tag.composite.*;
> import com.sun.faces.facelets.tag.AbstractTagLibrary;
>
> /**
> Index:
> jsf-ri/src/main/java/com/sun/faces/config/processor/FacesConfigExtensionProcessor.java
>
> ===================================================================
> ---
> jsf-ri/src/main/java/com/sun/faces/config/processor/FacesConfigExtensionProcessor.java
> (revision 0)
> +++
> jsf-ri/src/main/java/com/sun/faces/config/processor/FacesConfigExtensionProcessor.java
> (revision 0)
> @@ -0,0 +1,183 @@
> +/*
> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
> + *
> + * Copyright 1997-2010 Sun Microsystems, Inc. All rights reserved.
> + *
> + * The contents of this file are subject to the terms of either the GNU
> + * General Public License Version 2 only ("GPL") or the Common Development
> + * and Distribution License("CDDL") (collectively, the "License"). You
> + * may not use this file except in compliance with the License. You can
> obtain
> + * a copy of the License at
> https://glassfish.dev.java.net/public/CDDL+GPL.html
> + * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the
> specific
> + * language governing permissions and limitations under the License.
> + *
> + * When distributing the software, include this License Header Notice
> in each
> + * file and include the License file at
> glassfish/bootstrap/legal/LICENSE.txt.
> + * Sun designates this particular file as subject to the "Classpath"
> exception
> + * as provided by Sun in the GPL Version 2 section of the License file
> that
> + * accompanied this code. If applicable, add the following below the
> License
> + * Header, with the fields enclosed by brackets [] replaced by your own
> + * identifying information: "Portions Copyrighted [year]
> + * [name of copyright owner]"
> + *
> + * Contributor(s):
> + *
> + * If you wish your version of this file to be governed by only the
> CDDL or
> + * only the GPL Version 2, indicate your decision by adding "[Contributor]
> + * elects to include this software in this distribution under the [CDDL
> or GPL
> + * Version 2] license." If you don't indicate a single choice of
> license, a
> + * recipient has the option to distribute your version of this file under
> + * either the CDDL, the GPL Version 2 or to extend the choice of
> license to
> + * its licensees as provided above. However, if you add GPL Version 2
> code
> + * and therefore, elected the GPL Version 2 license, then the option
> applies
> + * only if the new code is made subject to such option by the copyright
> + * holder.
> + */
> +
> +package com.sun.faces.config.processor;
> +
> +import com.sun.faces.config.DocumentInfo;
> +import com.sun.faces.config.WebConfiguration;
> +import com.sun.faces.util.FacesLogger;
> +import org.w3c.dom.Element;
> +import org.w3c.dom.Node;
> +import org.w3c.dom.NodeList;
> +import org.w3c.dom.Document;
> +
> +import javax.servlet.ServletContext;
> +
> +import java.text.MessageFormat;
> +import java.util.Map;
> +import java.util.logging.Level;
> +import java.util.logging.Logger;
> +
> +
> +/**
> + * <p>
> + * This <code>ConfigProcessor</code> handles all elements defined under
> + * <code>/faces-config/factory</code>.
> + * </p>
> + */
> +public class FacesConfigExtensionProcessor extends
> AbstractConfigProcessor {
> +
> + private static final Logger LOGGER = FacesLogger.CONFIG.getLogger();
> +
> + /**
> + * <code>/faces-config/faces-config-extension</code>
> + */
> + private static final String FACES_CONFIG_EXTENSION =
> "faces-config-extension";
> +
> + /**
> + *
> <code>/faces-config/faces-config-extension/facelets-processing</code>
> + */
> + private static final String FACELETS_PROCESSING =
> "facelets-processing";
> +
> + /**
> + *
> <code>/faces-config/faces-config-extension/facelets-processing/file-extension</code>
>
> + */
> + private static final String FILE_EXTENSION = "file-extension";
> +
> + /**
> + *
> <code>/faces-config/faces-config-extension/facelets-processing/process-as</code>
>
> + */
> + private static final String PROCESS_AS = "process-as";
> +
> + // ------------------------------------------------------------
> Constructors
> +
> +
> + public FacesConfigExtensionProcessor() { }
> +
> +
> + // -------------------------------------------- Methods from
> ConfigProcessor
> +
> +
> + /**
> + * @see
> ConfigProcessor#process(javax.servlet.ServletContext,com.sun.faces.config.DocumentInfo[])
>
> + */
> + public void process(ServletContext sc, DocumentInfo[] documentInfos)
> + throws Exception {
> +
> + for (int i = 0; i < documentInfos.length; i++) {
> + if (LOGGER.isLoggable(Level.FINE)) {
> + LOGGER.log(Level.FINE,
> + MessageFormat.format(
> + "Processing faces-config-extension
> elements for document: ''{0}''",
> + documentInfos[i].getSourceURL()));
> + }
> + Document document = documentInfos[i].getDocument();
> + String namespace = document.getDocumentElement()
> + .getNamespaceURI();
> + NodeList facesConfigExtensions = document.getDocumentElement()
> + .getElementsByTagNameNS(namespace,
> FACES_CONFIG_EXTENSION);
> + if (facesConfigExtensions != null &&
> facesConfigExtensions.getLength() > 0) {
> + processFacesConfigExtensions(facesConfigExtensions,
> + namespace, documentInfos[i]);
> + }
> + }
> +
> + // invoke the next config processor
> + invokeNext(sc, documentInfos);
> +
> + }
> +
> + // ---------------------------------------------------------
> Private Methods
> +
> +
> + private void processFacesConfigExtensions(NodeList
> facesConfigExtensions,
> + String namespace, DocumentInfo info) {
> + WebConfiguration config = null;
> +
> + for (int i = 0, size = facesConfigExtensions.getLength(); i <
> size; i++) {
> + Node facesConfigExtension = facesConfigExtensions.item(i);
> + NodeList children = ((Element) facesConfigExtension)
> + .getElementsByTagNameNS(namespace, "*");
> + for (int c = 0, csize = children.getLength(); c < csize;
> c++) {
> + Node n = children.item(c);
> + if (FACELETS_PROCESSING.equals(n.getLocalName())) {
> + Node faceletsProcessing = n;
> + NodeList faceletsProcessingChildren = ((Element)
> faceletsProcessing)
> + .getElementsByTagNameNS(namespace, "*");
> + String fileExtension = null, processAs = null;
> + for (int fp = 0, fpsize =
> faceletsProcessingChildren.getLength(); fp < fpsize; fp++) {
> + Node childOfInterset =
> faceletsProcessingChildren.item(fp);
> + if (null == fileExtension &&
> + FILE_EXTENSION.equals(childOfInterset.getLocalName())) {
> + fileExtension = getNodeText(childOfInterset);
> + } else if (null == processAs &&
> + PROCESS_AS.equals(childOfInterset.getLocalName())) {
> + processAs = getNodeText(childOfInterset);
> + } else {
> + if (LOGGER.isLoggable(Level.WARNING)) {
> + LOGGER.log(Level.WARNING,
> + MessageFormat.format(
> + "Processing
> faces-config-extension elements for document: ''{0}'', encountered
> unexpected configuration ''{1}'', ignoring and continuing",
> + info.getSourceURL(),
> getNodeText(childOfInterset)));
> + }
> + }
> +
> + }
> +
> + if (null != fileExtension && null != processAs) {
> + if (null == config) {
> + config = WebConfiguration.getInstance();
> + }
> + Map<String, String> faceletsProcessingMappings =
> +
> config.getFacesConfigOptionValue(WebConfiguration.WebContextInitParameter.FaceletsProcessingFileExtensionProcessAs,
> true);
> + faceletsProcessingMappings.put(fileExtension,
> processAs);
> +
> + } else {
> + if (LOGGER.isLoggable(Level.WARNING)) {
> + LOGGER.log(Level.WARNING,
> + MessageFormat.format(
> + "Processing faces-config-extension
> elements for document: ''{0}'', encountered <facelets-processing>
> elemnet without expected children",
> + info.getSourceURL()));
> + }
> + }
> + }
> + }
> + }
> +
> + }
> +
> +
> +}
> Index: jsf-ri/src/main/java/com/sun/faces/config/ConfigManager.java
> ===================================================================
> --- jsf-ri/src/main/java/com/sun/faces/config/ConfigManager.java
> (revision 8624)
> +++ jsf-ri/src/main/java/com/sun/faces/config/ConfigManager.java
> (working copy)
> @@ -62,6 +62,7 @@
> import com.sun.faces.config.processor.RenderKitConfigProcessor;
> import com.sun.faces.config.processor.ValidatorConfigProcessor;
> import com.sun.faces.config.processor.FaceletTaglibConfigProcessor;
> +import com.sun.faces.config.processor.FacesConfigExtensionProcessor;
> import com.sun.faces.util.FacesLogger;
> import com.sun.faces.util.Timer;
> import org.xml.sax.InputSource;
> @@ -252,6 +253,7 @@
> new RenderKitConfigProcessor(),
> new NavigationConfigProcessor(),
> new BehaviorConfigProcessor(),
> + new FacesConfigExtensionProcessor()
> };
> for (int i = 0; i < configProcessors.length; i++) {
> ConfigProcessor p = configProcessors[i];
> Index: jsf-ri/src/main/java/com/sun/faces/config/WebConfiguration.java
> ===================================================================
> --- jsf-ri/src/main/java/com/sun/faces/config/WebConfiguration.java
> (revision 8624)
> +++ jsf-ri/src/main/java/com/sun/faces/config/WebConfiguration.java
> (working copy)
> @@ -40,7 +40,6 @@
> import java.util.EnumMap;
> import java.util.Enumeration;
> import java.util.HashSet;
> -import java.util.List;
> import java.util.Map;
> import java.util.Set;
> import java.util.logging.Level;
> @@ -59,8 +58,10 @@
>
> import com.sun.faces.util.FacesLogger;
> import com.sun.faces.util.Util;
> +import java.util.Collections;
>
> import java.util.HashMap;
> +import java.util.concurrent.ConcurrentHashMap;
> import javax.faces.component.UIInput;
> import javax.faces.validator.BeanValidator;
> import javax.faces.view.facelets.ResourceResolver;
> @@ -90,6 +91,9 @@
> private Map<WebContextInitParameter, String> contextParameters =
> new EnumMap<WebContextInitParameter,
> String>(WebContextInitParameter.class);
>
> + private Map<WebContextInitParameter, Map<String, String>>
> facesConfigParameters =
> + new EnumMap<WebContextInitParameter, Map<String,
> String>>(WebContextInitParameter.class);
> +
> private Map<WebEnvironmentEntry, String> envEntries =
> new EnumMap<WebEnvironmentEntry,
> String>(WebEnvironmentEntry.class);
>
> @@ -101,7 +105,9 @@
>
> private ArrayList<DeferredLoggingAction> deferredLoggingActions;
>
> + private FaceletsConfiguration faceletsConfig;
>
> +
> // ------------------------------------------------------------
> Constructors
>
>
> @@ -228,6 +234,39 @@
> return result;
>
> }
> +
> + public FaceletsConfiguration getFaceletsConfiguration() {
> +
> + if (null == faceletsConfig) {
> + faceletsConfig = new FaceletsConfiguration(this);
> + }
> + return faceletsConfig;
> +
> + }
> +
> + public Map<String, String>
> getFacesConfigOptionValue(WebContextInitParameter param, boolean create) {
> + Map<String, String> result = null;
> +
> + assert(null != facesConfigParameters);
> +
> + result = facesConfigParameters.get(param);
> + if (null == result) {
> + if (create) {
> + result = new ConcurrentHashMap<String, String>(3);
> + facesConfigParameters.put(param, result);
> + } else {
> + result = Collections.emptyMap();
> + }
> + }
> +
> + return result;
> +
> + }
> +
> + public Map<String, String>
> getFacesConfigOptionValue(WebContextInitParameter param) {
> + return getFacesConfigOptionValue(param, false);
> + }
> +
>
> public String[] getOptionValue(WebContextInitParameter param,
> String sep) {
> String [] result;
> @@ -335,7 +374,7 @@
> }
>
>
> - public void doLoggingActions() {
> + public void doPostBringupActions() {
>
> if (deferredLoggingActions != null) {
> for (DeferredLoggingAction loggingAction :
> deferredLoggingActions) {
> @@ -892,6 +931,10 @@
> FaceletCache(
> "com.sun.faces.faceletCache",
> ""
> + ),
> + FaceletsProcessingFileExtensionProcessAs(
> + "",
> + ""
> );
>
>
> Index: jsf-ri/src/main/java/com/sun/faces/config/FaceletsConfiguration.java
> ===================================================================
> --- jsf-ri/src/main/java/com/sun/faces/config/FaceletsConfiguration.java
> (revision 0)
> +++ jsf-ri/src/main/java/com/sun/faces/config/FaceletsConfiguration.java
> (revision 0)
> @@ -0,0 +1,191 @@
> +
> +/*
> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
> + *
> + * Copyright 1997-2010 Sun Microsystems, Inc. All rights reserved.
> + *
> + * The contents of this file are subject to the terms of either the GNU
> + * General Public License Version 2 only ("GPL") or the Common Development
> + * and Distribution License("CDDL") (collectively, the "License"). You
> + * may not use this file except in compliance with the License. You can
> obtain
> + * a copy of the License at
> https://glassfish.dev.java.net/public/CDDL+GPL.html
> + * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the
> specific
> + * language governing permissions and limitations under the License.
> + *
> + * When distributing the software, include this License Header Notice
> in each
> + * file and include the License file at
> glassfish/bootstrap/legal/LICENSE.txt.
> + * Sun designates this particular file as subject to the "Classpath"
> exception
> + * as provided by Sun in the GPL Version 2 section of the License file
> that
> + * accompanied this code. If applicable, add the following below the
> License
> + * Header, with the fields enclosed by brackets [] replaced by your own
> + * identifying information: "Portions Copyrighted [year]
> + * [name of copyright owner]"
> + *
> + * Contributor(s):
> + *
> + * If you wish your version of this file to be governed by only the
> CDDL or
> + * only the GPL Version 2, indicate your decision by adding "[Contributor]
> + * elects to include this software in this distribution under the [CDDL
> or GPL
> + * Version 2] license." If you don't indicate a single choice of
> license, a
> + * recipient has the option to distribute your version of this file under
> + * either the CDDL, the GPL Version 2 or to extend the choice of
> license to
> + * its licensees as provided above. However, if you add GPL Version 2
> code
> + * and therefore, elected the GPL Version 2 license, then the option
> applies
> + * only if the new code is made subject to such option by the copyright
> + * holder.
> + */
> +
> +package com.sun.faces.config;
> +
> +import java.util.Map;
> +import javax.faces.context.FacesContext;
> +
> +
> +/*
> + * This read-only singleton class is vended by the WebConfiguration.
> + * It is queried from any point in the program that needs to take
> action based
> + * on configuration options pertaining to facelets.
> + *
> + */
> +public class FaceletsConfiguration {
> +
> + public static final String FACELETS_CONFIGURATION_ATTRIBUTE_NAME =
> "com.sun.faces.config.FaceletsConfiguration";
> +
> + private static final String ESCAPE_INLINE_TEXT_ATTRIBUTE_NAME =
> "com.sun.faces.config.EscapeInlineText";
> +
> + private static final String CONSUME_COMMENTS_ATTRIBUTE_NAME =
> "com.sun.faces.config.ConsumeComments";
> +
> + private WebConfiguration config;
> +
> + private Map<String, String> faceletsProcessingMappings;
> +
> +
> + public FaceletsConfiguration(WebConfiguration config) {
> + this.config = config;
> +
> + faceletsProcessingMappings =
> +
> config.getFacesConfigOptionValue(WebConfiguration.WebContextInitParameter.FaceletsProcessingFileExtensionProcessAs);
>
> +
> + }
> +
> + public boolean isProcessCurrentDocumentAsFaceletsXhtml(String alias) {
> + // We want to write the XML declaration if and only if
> + // The SuppressXmlDeclaration context-param is NOT enabled
> + // and the file extension for the current file has a mapping
> + // with the value of XHTML
> + boolean currentModeIsXhtml = true;
> + String extension = alias;
> + if (null == extension) {
> + extension = ".xhtml";
> + }
> + int i = extension.indexOf(".");
> + if (-1 != i && 1 < extension.length()) {
> + extension = extension.substring(i);
> + } else {
> + extension = ".xhtml";
> + }
> +
> + assert (null != faceletsProcessingMappings);
> + if (faceletsProcessingMappings.containsKey(extension)) {
> + String value = faceletsProcessingMappings.get(extension);
> + currentModeIsXhtml = value.equals("xhtml");
> + }
> +
> + return currentModeIsXhtml;
> + }
> +
> + public boolean isConsumeComments(String alias) {
> + boolean consumeComments = false;
> + String extension = alias;
> + if (null == extension) {
> + extension = ".xhtml";
> + }
> + int i = extension.indexOf(".");
> + if (-1 != i && 1 < extension.length()) {
> + extension = extension.substring(i);
> + } else {
> + extension = ".xhtml";
> + }
> +
> + assert (null != faceletsProcessingMappings);
> + if (faceletsProcessingMappings.containsKey(extension)) {
> + String value = faceletsProcessingMappings.get(extension);
> + consumeComments = value.equals("xml") || value.equals("jspx");
> + }
> +
> + return consumeComments;
> +
> + }
> +
> + public boolean isConsumeCDATA(String alias) {
> + boolean consumeCDATA = false;
> + String extension = alias;
> + if (null == extension) {
> + extension = ".xhtml";
> + }
> + int i = extension.indexOf(".");
> + if (-1 != i && 1 < extension.length()) {
> + extension = extension.substring(i);
> + } else {
> + extension = ".xhtml";
> + }
> +
> + assert (null != faceletsProcessingMappings);
> + if (faceletsProcessingMappings.containsKey(extension)) {
> + String value = faceletsProcessingMappings.get(extension);
> + consumeCDATA = value.equals("jspx") || value.equals("xml");
> + }
> +
> + return consumeCDATA;
> +
> + }
> +
> + public boolean isEscapeInlineText(FacesContext context) {
> + Boolean result = Boolean.TRUE;
> +
> + result = (Boolean)
> context.getAttributes().get(ESCAPE_INLINE_TEXT_ATTRIBUTE_NAME);
> + if (null == result) {
> + String extension = context.getViewRoot().getViewId();
> + if (null == extension) {
> + extension = ".xhtml";
> + }
> + int i = extension.indexOf(".");
> + if (-1 != i && 1 < extension.length()) {
> + extension = extension.substring(i);
> + } else {
> + extension = ".xhtml";
> + }
> +
> + assert (null != faceletsProcessingMappings);
> + if (faceletsProcessingMappings.containsKey(extension)) {
> + String value = faceletsProcessingMappings.get(extension);
> + result = value.equals("xml") || value.equals("xhtml");
> + } else {
> + result = Boolean.TRUE;
> + }
> + context.getAttributes().put(ESCAPE_INLINE_TEXT_ATTRIBUTE_NAME,
> + result);
> + }
> +
> + return result;
> + }
> +
> + public static FaceletsConfiguration getInstance(FacesContext
> context) {
> + FaceletsConfiguration result = null;
> + Map<Object, Object> attrs = context.getAttributes();
> + result = (FaceletsConfiguration)
> attrs.get(FaceletsConfiguration.FACELETS_CONFIGURATION_ATTRIBUTE_NAME);
> + if (null == result) {
> + WebConfiguration config =
> WebConfiguration.getInstance(context.getExternalContext());
> + result = config.getFaceletsConfiguration();
> + attrs.put(FaceletsConfiguration.FACELETS_CONFIGURATION_ATTRIBUTE_NAME,
> result);
> + }
> + return result;
> + }
> +
> + public static FaceletsConfiguration getInstance() {
> + FacesContext context = FacesContext.getCurrentInstance();
> + return FaceletsConfiguration.getInstance(context);
> + }
> +
> +
> +}
> Index: jsf-ri/src/main/java/com/sun/faces/config/ConfigureListener.java
> ===================================================================
> --- jsf-ri/src/main/java/com/sun/faces/config/ConfigureListener.java
> (revision 8624)
> +++ jsf-ri/src/main/java/com/sun/faces/config/ConfigureListener.java
> (working copy)
> @@ -266,7 +266,7 @@
> UIViewRoot.class,
> webAppListener);
>
> - webConfig.doLoggingActions();
> + webConfig.doPostBringupActions();
>
> } catch (Throwable t) {
> if (LOGGER.isLoggable(Level.SEVERE)) {
> Index: jsf-ri/systest-per-webapp/build.xml
> ===================================================================
> --- jsf-ri/systest-per-webapp/build.xml (revision 8624)
> +++ jsf-ri/systest-per-webapp/build.xml (working copy)
> @@ -106,7 +106,8 @@
> flash,
> jsp-flash,
> suppress-xml-decl,
> - replace-vdl"/>
> + replace-vdl,
> + process-as-jspx"/>
> <!--
>
> EXCLUDED APPLICATIONS:
> Index: jsf-ri/systest-per-webapp/build-tests.xml
> ===================================================================
> --- jsf-ri/systest-per-webapp/build-tests.xml (revision 8624)
> +++ jsf-ri/systest-per-webapp/build-tests.xml (working copy)
> @@ -123,6 +123,8 @@
>
> value="com/sun/faces/systest/replacevdl/ReplaceViewDeclarationLanguageTestCase.class"
> />
> <property name="myfaces-uidata-component-state-test"
>
> value="com/sun/faces/systest/myfaces_uidata_component_state_test/MyFacesUIDataTestCase.class"
> />
> + <property name="process-as-jspx"
> +
> value="com/sun/faces/systest/ProcessAsJspxTestCase.class" />
>
> <!--
> EXCLUDED APPLICATIONS:
> Index:
> jsf-ri/systest-per-webapp/process-as-jspx/src/java/com/sun/faces/systest/ProcessAsJspxTestCase.java
>
> ===================================================================
> ---
> jsf-ri/systest-per-webapp/process-as-jspx/src/java/com/sun/faces/systest/ProcessAsJspxTestCase.java
> (revision 0)
> +++
> jsf-ri/systest-per-webapp/process-as-jspx/src/java/com/sun/faces/systest/ProcessAsJspxTestCase.java
> (revision 0)
> @@ -0,0 +1,132 @@
> +/*
> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
> + *
> + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
> + *
> + * The contents of this file are subject to the terms of either the GNU
> + * General Public License Version 2 only ("GPL") or the Common Development
> + * and Distribution License("CDDL") (collectively, the "License"). You
> + * may not use this file except in compliance with the License. You can
> obtain
> + * a copy of the License at
> https://glassfish.dev.java.net/public/CDDL+GPL.html
> + * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the
> specific
> + * language governing permissions and limitations under the License.
> + *
> + * When distributing the software, include this License Header Notice
> in each
> + * file and include the License file at
> glassfish/bootstrap/legal/LICENSE.txt.
> + * Sun designates this particular file as subject to the "Classpath"
> exception
> + * as provided by Sun in the GPL Version 2 section of the License file
> that
> + * accompanied this code. If applicable, add the following below the
> License
> + * Header, with the fields enclosed by brackets [] replaced by your own
> + * identifying information: "Portions Copyrighted [year]
> + * [name of copyright owner]"
> + *
> + * Contributor(s):
> + *
> + * If you wish your version of this file to be governed by only the
> CDDL or
> + * only the GPL Version 2, indicate your decision by adding "[Contributor]
> + * elects to include this software in this distribution under the [CDDL
> or GPL
> + * Version 2] license." If you don't indicate a single choice of
> license, a
> + * recipient has the option to distribute your version of this file under
> + * either the CDDL, the GPL Version 2 or to extend the choice of
> license to
> + * its licensees as provided above. However, if you add GPL Version 2
> code
> + * and therefore, elected the GPL Version 2 license, then the option
> applies
> + * only if the new code is made subject to such option by the copyright
> + * holder.
> + */
> +
> +package com.sun.faces.systest;
> +
> +
> +import com.gargoylesoftware.htmlunit.html.HtmlPage;
> +import com.sun.faces.htmlunit.AbstractTestCase;
> +import java.io.BufferedReader;
> +import java.io.InputStreamReader;
> +import java.net.URL;
> +import java.util.regex.Pattern;
> +import junit.framework.Test;
> +import junit.framework.TestSuite;
> +
> +
> +public class ProcessAsJspxTestCase extends AbstractTestCase {
> +
> + private final static Pattern XmlDeclaration =
> Pattern.compile("(?s)^<\\?xml(\\s)*version=.*\\?>.*");
> + private final static Pattern XmlPI =
> Pattern.compile("(?s).*<\\?xml-stylesheet.*\\?>.*");
> + private final static Pattern CDATASection =
> Pattern.compile("(?s).*<!\\[CDATA\\[ .*\\]\\]>.*");
> + private final static Pattern Comment =
> Pattern.compile("(?s).*<!--.*-->.*");
> + private final static Pattern EscapedText =
> Pattern.compile("(?s).*&lt;context-param&gt;.*");
> + private final static Pattern NotEscapedText =
> Pattern.compile("(?s).*<context-param>.*");
> +
> +
> + public ProcessAsJspxTestCase(String name) {
> + super(name);
> + }
> +
> + /**
> + * Set up instance variables required by this test case.
> + */
> + public void setUp() throws Exception {
> + super.setUp();
> + }
> +
> +
> + /**
> + * Return the tests included in this test suite.
> + */
> + public static Test suite() {
> + return (new TestSuite(ProcessAsJspxTestCase.class));
> + }
> +
> +
> + /**
> + * Tear down instance variables required by this test case.
> + */
> + public void tearDown() {
> + super.tearDown();
> + }
> +
> + private String getRawMarkup(String path) throws Exception {
> + URL url = getURL(path);
> + BufferedReader reader = new BufferedReader(new
> InputStreamReader(url.openStream()));
> + StringBuilder builder = new StringBuilder();
> + String cur;
> + while (null != (cur = reader.readLine())) {
> + builder.append(cur);
> + }
> +
> + String xml = builder.toString();
> + return xml;
> + }
> +
> + // ------------------------------------------------------------
> Test Methods
> +
> + public void testProcessAsXhtml() throws Exception {
> +
> + String xml = getRawMarkup("/faces/xhtmlview.xhtml");
> + assertTrue(XmlDeclaration.matcher(xml).matches());
> + assertTrue(XmlPI.matcher(xml).matches());
> + assertTrue(CDATASection.matcher(xml).matches());
> + assertTrue(EscapedText.matcher(xml).matches());
> + assertTrue(Comment.matcher(xml).matches());
> + }
> +
> + public void testProcessAsXml() throws Exception {
> +
> + String xml = getRawMarkup("/faces/xmlview.view.xml");
> + assertFalse(XmlDeclaration.matcher(xml).matches());
> + assertFalse(XmlPI.matcher(xml).matches());
> + assertFalse(CDATASection.matcher(xml).matches());
> + assertTrue(EscapedText.matcher(xml).matches());
> + assertFalse(Comment.matcher(xml).matches());
> + }
> +
> + public void testProcessAsJspx() throws Exception {
> +
> + String xml = getRawMarkup("/faces/jspxview.jspx");
> + assertFalse(XmlDeclaration.matcher(xml).matches());
> + assertFalse(XmlPI.matcher(xml).matches());
> + assertFalse(CDATASection.matcher(xml).matches());
> + assertTrue(NotEscapedText.matcher(xml).matches());
> + assertFalse(Comment.matcher(xml).matches());
> + }
> +
> +}
> Index:
> jsf-ri/systest-per-webapp/process-as-jspx/src/java/com/sun/faces/systest/ProcessAsJspxBean.java
>
> ===================================================================
> ---
> jsf-ri/systest-per-webapp/process-as-jspx/src/java/com/sun/faces/systest/ProcessAsJspxBean.java
> (revision 0)
> +++
> jsf-ri/systest-per-webapp/process-as-jspx/src/java/com/sun/faces/systest/ProcessAsJspxBean.java
> (revision 0)
> @@ -0,0 +1,14 @@
> +package com.sun.faces.systest;
> +
> +import javax.faces.bean.ManagedBean;
> +import javax.faces.bean.RequestScoped;
> +
> + at ManagedBean
> + at RequestScoped
> +public class ProcessAsJspxBean {
> +
> + public String getProp() {
> + return "Hello < World";
> + }
> +
> +}
> Index: jsf-ri/systest-per-webapp/process-as-jspx/web/jspxview.jspx
> ===================================================================
> --- jsf-ri/systest-per-webapp/process-as-jspx/web/jspxview.jspx
> (revision 0)
> +++ jsf-ri/systest-per-webapp/process-as-jspx/web/jspxview.jspx
> (revision 0)
> @@ -0,0 +1,67 @@
> +<?xml version='1.0' encoding='utf-8'?>
> +<!-- Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights
> reserved. -->
> +<jsp:root xmlns="http://www.w3.org/1999/xhtml"
> + xmlns:jsp="http://java.sun.com/JSP/Page"
> + xmlns:f="http://java.sun.com/jsf/core"
> + xmlns:h="http://java.sun.com/jsf/html"
> + version="1.2">
> + <jsp:directive.page contentType="text/html;charset=utf-8"/>
> + <f:view>
> +
> +
> + <f:attribute name="mode" value="index"/>
> +
> +<h2>XML declaration: consumed</h2>
> +
> +<h2>Processing instruction: consumed</h2>
> +
> +<?xml-stylesheet href="funky.xsl" type="text/xml" alternate="yes"?>
> +
> +<h2>CDATA section: consumed</h2>
> +
> +<![CDATA[ <p>This is CDATA</p> ]]>
> +
> +<h2>Inline text escaping: not escaped</h2>
> +
> +
> + <code>
> + <br/>
> + &lt;context-param&gt;
> + <br/>
> +
> +&nbsp;&nbsp;&lt;param-name&gt;javax.faces.PARTIAL_STATE_SAVING
>
> +
> +&lt;/param-name&gt;
> + <br/>
> +
> +&nbsp;&nbsp;&lt;param-value&gt;true&lt;/param-value&gt
>
> +
> +;
> + <br/>
> + &lt;/context-param&gt;
> + </code>
> +
> +<h2>Comments: consumed</h2>
> +
> +
> +<p>HTML Template Text</p>
> +
> +
> +
> +<p><h:outputText value="#{processAsJspxBean.prop}" /></p>
> +
> +<h:form prependId="false">
> +
> +<h:commandButton value="reload" />
> +
> +</h:form>
> +
> +
> +<!-- comments consumed -->
> +
> +
> +
> +
> +
> + </f:view>
> +</jsp:root>
> Index: jsf-ri/systest-per-webapp/process-as-jspx/web/xhtmlview.xhtml
> ===================================================================
> --- jsf-ri/systest-per-webapp/process-as-jspx/web/xhtmlview.xhtml
> (revision 0)
> +++ jsf-ri/systest-per-webapp/process-as-jspx/web/xhtmlview.xhtml
> (revision 0)
> @@ -0,0 +1,103 @@
> +<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
> +<!--
> + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
> +
> + Copyright 2009 Sun Microsystems, Inc. All rights reserved.
> +
> + The contents of this file are subject to the terms of either the GNU
> + General Public License Version 2 only ("GPL") or the Common Development
> + and Distribution License("CDDL") (collectively, the "License"). You
> + may not use this file except in compliance with the License. You can
> obtain
> + a copy of the License at
> https://glassfish.dev.java.net/public/CDDL+GPL.html
> + or glassfish/bootstrap/legal/LICENSE.txt. See the License for the
> specific
> + language governing permissions and limitations under the License.
> +
> + When distributing the software, include this License Header Notice in
> each
> + file and include the License file at
> glassfish/bootstrap/legal/LICENSE.txt.
> + Sun designates this particular file as subject to the "Classpath"
> exception
> + as provided by Sun in the GPL Version 2 section of the License file that
> + accompanied this code. If applicable, add the following below the
> License
> + Header, with the fields enclosed by brackets [] replaced by your own
> + identifying information: "Portions Copyrighted [year]
> + [name of copyright owner]"
> +
> + Contributor(s):
> +
> + If you wish your version of this file to be governed by only the CDDL or
> + only the GPL Version 2, indicate your decision by adding "[Contributor]
> + elects to include this software in this distribution under the [CDDL
> or GPL
> + Version 2] license." If you don't indicate a single choice of license, a
> + recipient has the option to distribute your version of this file under
> + either the CDDL, the GPL Version 2 or to extend the choice of license to
> + its licensees as provided above. However, if you add GPL Version 2 code
> + and therefore, elected the GPL Version 2 license, then the option applies
> + only if the new code is made subject to such option by the copyright
> + holder.
> +-->
> +
> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
> "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
> +<html xmlns="http://www.w3.org/1999/xhtml"
> + xmlns:h="http://java.sun.com/jsf/html">
> +<h:head>
> + <title>Process JSPX as Facelets for JSPX mode</title>
> +</h:head>
> +<h:body bgcolor="white">
> +
> +<h2>XML declaration: passed through</h2>
> +
> +<h2>Processing instruction: passed through</h2>
> +
> +<?xml-stylesheet href="funky.xsl" type="text/xml" alternate="yes"?>
> +
> +<h2>CDATA section: passed through</h2>
> +
> +<![CDATA[ <h2>This is CDATA</h2> ]]>
> +
> +<h2>Inline text escaping: escaped</h2>
> +
> + <code>
> + <br/>
> + &lt;context-param&gt;
> + <br/>
> +
> +&nbsp;&nbsp;&lt;param-name&gt;javax.faces.PARTIAL_STATE_SAVING
>
> +
> +&lt;/param-name&gt;
> + <br/>
> +
> +&nbsp;&nbsp;&lt;param-value&gt;true&lt;/param-value&gt
>
> +
> +;
> + <br/>
> + &lt;/context-param&gt;
> + </code>
> +
> +<h2>Comments: passed through</h2>
> +
> +<!-- comments pass through -->
> +
> +<hr />
> +
> + <h:form prependId="false" id="form1">
> +
> + <h:panelGrid columns="2" border="1" width="600">
> +
> + <h:outputText value="column1" />
> +
> + <h:outputText value="column2" />
> +
> + </h:panelGrid>
> +
> + <h2><h:messages id="messages"/></h2>
> +
> +
> +
> + #{processAsJspxBean.prop}
> +
> +
> +
> +
> + </h:form>
> +
> +</h:body>
> +</html>
> Index: jsf-ri/systest-per-webapp/process-as-jspx/web/jspview.jsp
> ===================================================================
> --- jsf-ri/systest-per-webapp/process-as-jspx/web/jspview.jsp
> (revision 0)
> +++ jsf-ri/systest-per-webapp/process-as-jspx/web/jspview.jsp
> (revision 0)
> @@ -0,0 +1,86 @@
> +<%--
> + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
> +
> + Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
> +
> + The contents of this file are subject to the terms of either the GNU
> + General Public License Version 2 only ("GPL") or the Common Development
> + and Distribution License("CDDL") (collectively, the "License"). You
> + may not use this file except in compliance with the License. You can
> obtain
> + a copy of the License at
> https://glassfish.dev.java.net/public/CDDL+GPL.html
> + or glassfish/bootstrap/legal/LICENSE.txt. See the License for the
> specific
> + language governing permissions and limitations under the License.
> +
> + When distributing the software, include this License Header Notice in
> each
> + file and include the License file at
> glassfish/bootstrap/legal/LICENSE.txt.
> + Sun designates this particular file as subject to the "Classpath"
> exception
> + as provided by Sun in the GPL Version 2 section of the License file that
> + accompanied this code. If applicable, add the following below the
> License
> + Header, with the fields enclosed by brackets [] replaced by your own
> + identifying information: "Portions Copyrighted [year]
> + [name of copyright owner]"
> +
> + Contributor(s):
> +
> + If you wish your version of this file to be governed by only the CDDL or
> + only the GPL Version 2, indicate your decision by adding "[Contributor]
> + elects to include this software in this distribution under the [CDDL
> or GPL
> + Version 2] license." If you don't indicate a single choice of license, a
> + recipient has the option to distribute your version of this file under
> + either the CDDL, the GPL Version 2 or to extend the choice of license to
> + its licensees as provided above. However, if you add GPL Version 2 code
> + and therefore, elected the GPL Version 2 license, then the option applies
> + only if the new code is made subject to such option by the copyright
> + holder.
> +--%>
> +
> +<!--
> + Copyright 2004 Sun Microsystems, Inc. All rights reserved.
> + SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
> +-->
> +
> +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
> +<html>
> + <head>
> + <title>JSP view</title>
> + <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
> + <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
> + </head>
> +
> + <body>
> +<f:view>
> +
> +<p>HTML Template Text</p>
> +
> +<p><h:outputText value="#{processAsJspxBean.prop}" /></p>
> +
> +<h:form prependId="false">
> +
> +<h:commandButton value="reload" />
> +
> +</h:form>
> +
> + <code>
> + <br/>
> + &lt;context-param&gt;
> + <br/>
> +
> +&nbsp;&nbsp;&lt;param-name&gt;javax.faces.PARTIAL_STATE_SAVING
>
> +
> +&lt;/param-name&gt;
> + <br/>
> +
> +&nbsp;&nbsp;&lt;param-value&gt;true&lt;/param-value&gt
>
> +
> +;
> + <br/>
> + &lt;/context-param&gt;
> + </code>
> +
> +
> +
> +</f:view>
> +
> + <hr>
> + </body>
> +</html>
> Index: jsf-ri/systest-per-webapp/process-as-jspx/web/xmlview.view.xml
> ===================================================================
> --- jsf-ri/systest-per-webapp/process-as-jspx/web/xmlview.view.xml
> (revision 0)
> +++ jsf-ri/systest-per-webapp/process-as-jspx/web/xmlview.view.xml
> (revision 0)
> @@ -0,0 +1,103 @@
> +<?xml version="1.0" encoding="UTF-8"?>
> +<!--
> + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
> +
> + Copyright 2010 Sun Microsystems, Inc. All rights reserved.
> +
> + The contents of this file are subject to the terms of either the GNU
> + General Public License Version 2 only ("GPL") or the Common Development
> + and Distribution License("CDDL") (collectively, the "License"). You
> + may not use this file except in compliance with the License. You can
> obtain
> + a copy of the License at
> https://glassfish.dev.java.net/public/CDDL+GPL.html
> + or glassfish/bootstrap/legal/LICENSE.txt. See the License for the
> specific
> + language governing permissions and limitations under the License.
> +
> + When distributing the software, include this License Header Notice in
> each
> + file and include the License file at
> glassfish/bootstrap/legal/LICENSE.txt.
> + Sun designates this particular file as subject to the "Classpath"
> exception
> + as provided by Sun in the GPL Version 2 section of the License file that
> + accompanied this code. If applicable, add the following below the
> License
> + Header, with the fields enclosed by brackets [] replaced by your own
> + identifying information: "Portions Copyrighted [year]
> + [name of copyright owner]"
> +
> + Contributor(s):
> +
> + If you wish your version of this file to be governed by only the CDDL or
> + only the GPL Version 2, indicate your decision by adding "[Contributor]
> + elects to include this software in this distribution under the [CDDL
> or GPL
> + Version 2] license." If you don't indicate a single choice of license, a
> + recipient has the option to distribute your version of this file under
> + either the CDDL, the GPL Version 2 or to extend the choice of license to
> + its licensees as provided above. However, if you add GPL Version 2 code
> + and therefore, elected the GPL Version 2 license, then the option applies
> + only if the new code is made subject to such option by the copyright
> + holder.
> +-->
> +<faces-view xmlns="http://www.w3.org/1999/xhtml"
> + xmlns:h="http://java.sun.com/jsf/html">
> +
> + <h:html>
> +
> + <h:head><h:title>Raw XML View</h:title></h:head>
> +
> + <h:body>
> +
> +<h2>XML declaration: consumed</h2>
> +
> +<h2>Processing instruction: consumed</h2>
> +
> +<?xml-stylesheet href="funky.xsl" type="text/xml" alternate="yes"?>
> +
> +<h2>CDATA section: consumed</h2>
> +
> +<![CDATA[ <p>This is CDATA</p> ]]>
> +
> +<h2>Inline text escaping: escaped</h2>
> +
> + <code>
> + <br/>
> + &lt;context-param&gt;
> + <br/>
> +
> +&nbsp;&nbsp;&lt;param-name&gt;javax.faces.PARTIAL_STATE_SAVING
>
> +
> +&lt;/param-name&gt;
> + <br/>
> +
> +&nbsp;&nbsp;&lt;param-value&gt;true&lt;/param-value&gt
>
> +
> +;
> + <br/>
> + &lt;/context-param&gt;
> + </code>
> +
> +<h2>Comments: consumed</h2>
> +
> +<!-- comments consumed -->
> +
> + <h:form prependId="false" id="form">
> +
> + <h:panelGrid id="grid" column="2">
> +
> + <h:outputText id="text" value="hello"></h:outputText>
> +
> + <h:commandButton id="button"
> value="reload"></h:commandButton>
> +
> +
> + </h:panelGrid>
> +
> + #{processAsJspxBean.prop}
> +
> +<p>html template text</p>
> +
> +
> + </h:form>
> +
> + </h:body>
> +
> + </h:html>
> +
> +</faces-view>
> +
> +
> Index:
> jsf-ri/systest-per-webapp/process-as-jspx/web/WEB-INF/faces-config.xml
> ===================================================================
> ---
> jsf-ri/systest-per-webapp/process-as-jspx/web/WEB-INF/faces-config.xml
> (revision 0)
> +++
> jsf-ri/systest-per-webapp/process-as-jspx/web/WEB-INF/faces-config.xml
> (revision 0)
> @@ -0,0 +1,19 @@
> +<?xml version='1.0' encoding='UTF-8'?>
> +<faces-config
> + xmlns="http://java.sun.com/xml/ns/javaee"
> + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> + xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
> http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
> + version="2.0">
> +
> + <faces-config-extension>
> + <facelets-processing>
> + <file-extension>.jspx</file-extension>
> + <process-as>jspx</process-as>
> + </facelets-processing>
> + <facelets-processing>
> + <file-extension>.view.xml</file-extension>
> + <process-as>xml</process-as>
> + </facelets-processing>
> + </faces-config-extension>
> +
> +</faces-config>
> Index: jsf-ri/systest-per-webapp/process-as-jspx/web/WEB-INF/web.xml
> ===================================================================
> --- jsf-ri/systest-per-webapp/process-as-jspx/web/WEB-INF/web.xml
> (revision 0)
> +++ jsf-ri/systest-per-webapp/process-as-jspx/web/WEB-INF/web.xml
> (revision 0)
> @@ -0,0 +1,72 @@
> +<?xml version="1.0" encoding="ISO-8859-1"?>
> +
> +<!--
> + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
> +
> + Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
> +
> + The contents of this file are subject to the terms of either the GNU
> + General Public License Version 2 only ("GPL") or the Common Development
> + and Distribution License("CDDL") (collectively, the "License"). You
> + may not use this file except in compliance with the License. You can
> obtain
> + a copy of the License at
> https://glassfish.dev.java.net/public/CDDL+GPL.html
> + or glassfish/bootstrap/legal/LICENSE.txt. See the License for the
> specific
> + language governing permissions and limitations under the License.
> +
> + When distributing the software, include this License Header Notice in
> each
> + file and include the License file at
> glassfish/bootstrap/legal/LICENSE.txt.
> + Sun designates this particular file as subject to the "Classpath"
> exception
> + as provided by Sun in the GPL Version 2 section of the License file that
> + accompanied this code. If applicable, add the following below the
> License
> + Header, with the fields enclosed by brackets [] replaced by your own
> + identifying information: "Portions Copyrighted [year]
> + [name of copyright owner]"
> +
> + Contributor(s):
> +
> + If you wish your version of this file to be governed by only the CDDL or
> + only the GPL Version 2, indicate your decision by adding "[Contributor]
> + elects to include this software in this distribution under the [CDDL
> or GPL
> + Version 2] license." If you don't indicate a single choice of license, a
> + recipient has the option to distribute your version of this file under
> + either the CDDL, the GPL Version 2 or to extend the choice of license to
> + its licensees as provided above. However, if you add GPL Version 2 code
> + and therefore, elected the GPL Version 2 license, then the option applies
> + only if the new code is made subject to such option by the copyright
> + holder.
> +-->
> +
> +<web-app version="2.5"
> + xmlns="http://java.sun.com/xml/ns/javaee"
> + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> + xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
> http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
> +
> + <description>
> + JSPX Compatibility
> + </description>
> + <display-name>JSPX Compatibility</display-name>
> +
> + <context-param>
> + <param-name>javax.faces.FACELETS_VIEW_MAPPINGS</param-name>
> + <param-value>*.xhtml;*.view.xml;*.jspx</param-value>
> + </context-param>
> +
> + <context-param>
> + <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
> + <param-value>.xhtml .view.xml .jsp .jspx</param-value>
> + </context-param>
> +
> + <!-- Faces Servlet -->
> + <servlet>
> + <servlet-name>Faces Servlet</servlet-name>
> + <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
> + <load-on-startup> 1 </load-on-startup>
> + </servlet>
> +
> + <!-- Faces Servlet Mapping -->
> + <servlet-mapping>
> + <servlet-name>Faces Servlet</servlet-name>
> + <url-pattern>/faces/*</url-pattern>
> + </servlet-mapping>
> +
> +</web-app>
> Index: jsf-ri/systest-per-webapp/process-as-jspx/web/index.html
> ===================================================================
> --- jsf-ri/systest-per-webapp/process-as-jspx/web/index.html
> (revision 0)
> +++ jsf-ri/systest-per-webapp/process-as-jspx/web/index.html
> (revision 0)
> @@ -0,0 +1,124 @@
> +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
> +<html>
> + <head>
> + <title>Test all permutations of facelets processing modes</title>
> + </head>
> +
> + <body>
> + <h1>Test all permutations of facelets processing modes</h1>
> +
> +<table border="1">
> +
> +<tr>
> +
> +<td>
> +</td>
> +
> +<th>xhtml
> +</th>
> +
> +<th>xml
> +</th>
> +
> +<th>jspx
> +</th>
> +
> +</tr>
> +
> +<tr>
> +
> +<th>XML Declaration
> +</th>
> +
> +<td>passed through
> +</td>
> +
> +<td>consumed
> +</td>
> +
> +<td>consumed
> +</td>
> +
> +</tr>
> +
> +<tr>
> +
> +<th>Processing Instructions
> +</th>
> +
> +<td>passed through
> +</td>
> +
> +<td>consumed
> +</td>
> +
> +<td>consumed
> +</td>
> +
> +</tr>
> +
> +<tr>
> +
> +<th>CDATA
> +</th>
> +
> +<td>passed through
> +</td>
> +
> +<td>consumed
> +</td>
> +
> +<td>consumed
> +</td>
> +
> +</tr>
> +
> +<tr>
> +
> +<th>Inline text escaping
> +</th>
> +
> +<td>escaped
> +</td>
> +
> +<td>escaped
> +</td>
> +
> +<td>not escaped
> +</td>
> +
> +</tr>
> +
> +<tr>
> +
> +<th>Comments
> +</th>
> +
> +<td>passed through
> +</td>
> +
> +<td>consumed
> +</td>
> +
> +<td>consumed
> +</td>
> +
> +</tr>
> +
> +
> +</table>
> +
> +
> +
> +<p><a href="/jsf-process-as-jspx/faces/xhtmlview.xhtml">Classic
> Facelets processed as Facelets in XHTML mode</a></p>
> +<p><a href="/jsf-process-as-jspx/faces/xmlview.view.xml">XML processed
> as Facelets in XML mode</a></p>
> +<p><a href="/jsf-process-as-jspx/faces/jspxview.jspx">JSPX processed as
> Facelets in JSPX mode</a></p>
> +<p><a href="/jsf-process-as-jspx/faces/jspview.jsp">JSP processed as
> JSP</a></p>
> +
> + <hr>
> +<!-- Created: Wed Sep 29 12:17:11 EDT 2010 -->
> +<!-- hhmts start -->
> +Last modified: Thu Sep 30 17:01:18 EDT 2010
> +<!-- hhmts end -->
> + </body>
> +</html>
More information about the jsr-314-open-mirror
mailing list