You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by sl...@apache.org on 2009/04/04 20:45:04 UTC
svn commit: r761982 [2/10] - in /myfaces/core/branches/2_0_0/impl/src:
main/java/com/ main/java/org/apache/myfaces/application/
main/java/org/apache/myfaces/config/
main/java/org/apache/myfaces/config/impl/digester/
main/java/org/apache/myfaces/config/...
Modified: myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/util/DebugUtils.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/util/DebugUtils.java?rev=761982&r1=761981&r2=761982&view=diff
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/util/DebugUtils.java (original)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/util/DebugUtils.java Sat Apr 4 18:44:59 2009
@@ -28,6 +28,8 @@
import java.util.HashSet;
import java.util.Map;
+import javax.el.MethodExpression;
+import javax.el.ValueExpression;
import javax.faces.FacesException;
import javax.faces.component.UICommand;
import javax.faces.component.UIComponent;
@@ -35,8 +37,6 @@
import javax.faces.component.UIViewRoot;
import javax.faces.component.ValueHolder;
import javax.faces.context.FacesContext;
-import javax.faces.el.MethodBinding;
-import javax.faces.el.ValueBinding;
import javax.faces.event.FacesListener;
import javax.faces.validator.Validator;
@@ -206,10 +206,10 @@
String name = propDescriptors[i].getName();
if (!"id".equals(name))
{
- ValueBinding vb = comp.getValueBinding(name);
- if (vb != null)
+ ValueExpression ve = comp.getValueExpression(name);
+ if (ve != null)
{
- printAttribute(stream, name, vb.getExpressionString());
+ printAttribute(stream, name, ve.getExpressionString());
}
else
{
@@ -359,9 +359,9 @@
stream.print(((UIComponent)value).getId());
stream.print(']');
}
- else if (value instanceof MethodBinding)
+ else if (value instanceof MethodExpression)
{
- stream.print(((MethodBinding)value).getExpressionString());
+ stream.print(((MethodExpression)value).getExpressionString());
}
else
{
Added: myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/ViewDeclarationLanguageBase.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/ViewDeclarationLanguageBase.java?rev=761982&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/ViewDeclarationLanguageBase.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/ViewDeclarationLanguageBase.java Sat Apr 4 18:44:59 2009
@@ -0,0 +1,99 @@
+/*
+ * 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.myfaces.view;
+
+import javax.faces.application.Application;
+import javax.faces.application.ViewHandler;
+import javax.faces.component.UIViewRoot;
+import javax.faces.context.FacesContext;
+import javax.faces.view.ViewDeclarationLanguage;
+
+import org.apache.myfaces.application.InvalidViewIdException;
+
+/**
+ * @author Simon Lessard (latest modification by $Author: slessard $)
+ * @version $Revision: 696523 $ $Date: 2009-03-22 15:03:20 -0400 (mer., 17 sept. 2008) $
+ *
+ * @since 2.0
+ */
+public abstract class ViewDeclarationLanguageBase extends ViewDeclarationLanguage
+{
+ /**
+ * Process the specification required algorithm that is generic to all PDL.
+ *
+ * @param context
+ * @param viewId
+ */
+ public UIViewRoot createView(FacesContext context, String viewId)
+ {
+ if (context == null)
+ {
+ throw new NullPointerException("context");
+ }
+
+ if (viewId == null)
+ {
+ throw new NullPointerException("viewId");
+ }
+
+ try
+ {
+ viewId = calculateViewId(context, viewId);
+ Application application = context.getApplication();
+
+ // Create a new UIViewRoot object instance using Application.createComponent(UIViewRoot.COMPONENT_TYPE).
+ UIViewRoot newViewRoot = (UIViewRoot) application.createComponent(UIViewRoot.COMPONENT_TYPE);
+ UIViewRoot oldViewRoot = context.getViewRoot();
+ if (oldViewRoot == null)
+ {
+ // If not, this method must call calculateLocale() and calculateRenderKitId(), and store the results
+ // as the values of the locale and renderKitId, proeprties, respectively, of the newly created
+ // UIViewRoot.
+ ViewHandler handler = application.getViewHandler();
+ newViewRoot.setLocale(handler.calculateLocale(context));
+ newViewRoot.setRenderKitId(handler.calculateRenderKitId(context));
+ }
+ else
+ {
+ // If there is an existing UIViewRoot available on the FacesContext, this method must copy its locale
+ // and renderKitId to this new view root
+ newViewRoot.setLocale(oldViewRoot.getLocale());
+ newViewRoot.setRenderKitId(oldViewRoot.getRenderKitId());
+ }
+
+ // TODO: The spec is silent on the following line, but I feel bad if I don't set it
+ newViewRoot.setViewId(viewId);
+
+ return newViewRoot;
+ }
+ catch (InvalidViewIdException e)
+ {
+ // If no viewId could be identified, or the viewId is exactly equal to the servlet mapping,
+ // send the response error code SC_NOT_FOUND with a suitable message to the client.
+ sendSourceNotFound(context, e.getMessage());
+
+ // TODO: Spec is silent on the return value when an error was sent
+ return null;
+ }
+ }
+
+ protected abstract String calculateViewId(FacesContext context, String viewId);
+
+ protected abstract void sendSourceNotFound(FacesContext context, String message);
+}
Added: myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/ViewDeclarationLanguageFactoryImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/ViewDeclarationLanguageFactoryImpl.java?rev=761982&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/ViewDeclarationLanguageFactoryImpl.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/ViewDeclarationLanguageFactoryImpl.java Sat Apr 4 18:44:59 2009
@@ -0,0 +1,111 @@
+/*
+ * 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.myfaces.view;
+
+import javax.faces.FacesException;
+import javax.faces.context.FacesContext;
+import javax.faces.view.ViewDeclarationLanguage;
+import javax.faces.view.ViewDeclarationLanguageFactory;
+
+import org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguageStrategy;
+import org.apache.myfaces.view.jsp.JspViewDeclarationLanguageStrategy;
+
+/**
+ * This is the default PDL factory used as of JSF 2.0, it tries to use Facelet PDL whenever possible,
+ * but fallback on JSP if required.
+ *
+ * @author Simon Lessard (latest modification by $Author: slessard $)
+ * @version $Revision: 696523 $ $Date: 2009-03-21 14:55:54 -0400 (mer., 17 sept. 2008) $
+ *
+ * @since 2.0
+ */
+public class ViewDeclarationLanguageFactoryImpl extends ViewDeclarationLanguageFactory
+{
+ public static final String PARAM_DISABLE_JSF_FACELET = "javax.faces.DISABLE_FACELET_JSF_VIEWHANDLER";
+
+ private boolean _initialized;
+ private ViewDeclarationLanguageStrategy[] _supportedLanguages;
+
+ /**
+ *
+ */
+ public ViewDeclarationLanguageFactoryImpl()
+ {
+ _initialized = false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public ViewDeclarationLanguage getViewDeclarationLanguage(String viewId)
+ {
+ if (viewId == null)
+ {
+ throw new NullPointerException("viewId");
+ }
+
+ initialize();
+
+ for (ViewDeclarationLanguageStrategy strategy : _supportedLanguages)
+ {
+ if (strategy.handles(viewId))
+ {
+ return strategy.getViewDeclarationLanguage();
+ }
+ }
+
+ // FIXME: Notify EG - Cannot throw undeclared ClassNotFoundException like the spec requires
+ throw new FacesException(new ClassNotFoundException("Cannot find a valid PDL for view id " + viewId));
+ }
+
+ private void initialize()
+ {
+ if (!_initialized)
+ {
+ if (isFaceletsEnabled())
+ {
+ _supportedLanguages = new ViewDeclarationLanguageStrategy[2];
+ _supportedLanguages[0] = new FaceletViewDeclarationLanguageStrategy();
+ _supportedLanguages[1] = new JspViewDeclarationLanguageStrategy();
+ }
+ else
+ {
+ _supportedLanguages = new ViewDeclarationLanguageStrategy[1];
+ _supportedLanguages[0] = new JspViewDeclarationLanguageStrategy();
+ }
+
+ _initialized = true;
+ }
+ }
+
+ private boolean isFaceletsEnabled()
+ {
+ FacesContext context = FacesContext.getCurrentInstance();
+ String param = context.getExternalContext().getInitParameter(PARAM_DISABLE_JSF_FACELET);
+ if (param == null)
+ {
+ return true;
+ }
+ else
+ {
+ return !Boolean.parseBoolean(param.toLowerCase());
+ }
+ }
+}
Added: myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/ViewDeclarationLanguageStrategy.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/ViewDeclarationLanguageStrategy.java?rev=761982&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/ViewDeclarationLanguageStrategy.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/ViewDeclarationLanguageStrategy.java Sat Apr 4 18:44:59 2009
@@ -0,0 +1,53 @@
+/*
+ * 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.myfaces.view;
+
+import javax.faces.view.ViewDeclarationLanguage;
+
+/**
+ * This class represents a supported {@link ViewDeclarationLanguage} in the application. Notably,
+ * the default ViewDeclarationLanguageFactory maintains an ordered list of supported languages for
+ * the purpose of determining which one to use for a given view id by calling the {@link #handles}
+ * method of each ofthe registered support and using the first match.
+ *
+ * @author Simon Lessard (latest modification by $Author: slessard $)
+ * @version $Revision: 696523 $ $Date: 2009-03-22 12:25:01 -0400 (mer., 17 sept. 2008) $
+ *
+ * @since 2.0
+ */
+public interface ViewDeclarationLanguageStrategy
+{
+ /**
+ * Gets the {@link ViewDeclarationLanguage} represented by this support.
+ *
+ * @return the {@link ViewDeclarationLanguage} represented by this support
+ */
+ public ViewDeclarationLanguage getViewDeclarationLanguage();
+
+ /**
+ * Determines if the {@link ViewDeclarationLanguage} represented by this support should be used
+ * to handle the specified view identifier.
+ *
+ * @param viewId the view identifier
+ *
+ * @return <code>true</code> if the {@link ViewDeclarationLanguage} represented by this support
+ * should be used to handle the specified view identifier, <code>false</code> otherwise
+ */
+ public boolean handles(String viewId);
+}
Added: myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/Facelet.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/Facelet.java?rev=761982&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/Facelet.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/Facelet.java Sat Apr 4 18:44:59 2009
@@ -0,0 +1,54 @@
+/*
+ * 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.myfaces.view.facelets;
+
+import java.io.IOException;
+
+import javax.el.ELException;
+import javax.faces.FacesException;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.view.facelets.FaceletException;
+
+/**
+ * The parent or root object in a FaceletHandler composition. The Facelet will take care of populating the passed
+ * UIComponent parent in relation to the create/restore lifecycle of JSF.
+ *
+ * @author Jacob Hookom
+ * @version $Id: Facelet.java,v 1.3 2008/07/13 19:01:40 rlubke Exp $
+ */
+public abstract class Facelet
+{
+
+ /**
+ * The passed UIComponent parent will be populated/restored in accordance with the JSF 1.2 specification.
+ *
+ * @param facesContext
+ * The current FacesContext (Should be the same as FacesContext.getInstance())
+ * @param parent
+ * The UIComponent to populate in a compositional fashion. In most cases a Facelet will be base a
+ * UIViewRoot.
+ * @throws IOException
+ * @throws FacesException
+ * @throws FaceletException
+ * @throws ELException
+ */
+ public abstract void apply(FacesContext facesContext, UIComponent parent) throws IOException, FacesException,
+ FaceletException, ELException;
+}
Added: myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletFactory.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletFactory.java?rev=761982&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletFactory.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletFactory.java Sat Apr 4 18:44:59 2009
@@ -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 org.apache.myfaces.view.facelets;
+
+import java.io.IOException;
+
+import javax.el.ELException;
+import javax.faces.FacesException;
+import javax.faces.view.facelets.FaceletException;
+
+/**
+ * FaceletFactory for producing Facelets relative to the context of the underlying implementation.
+ *
+ * @author Jacob Hookom
+ * @version $Id: FaceletFactory.java,v 1.4 2008/07/13 19:01:39 rlubke Exp $
+ */
+public abstract class FaceletFactory
+{
+
+ private static ThreadLocal<FaceletFactory> instance = new ThreadLocal<FaceletFactory>();
+
+ /**
+ * Return a Facelet instance as specified by the file at the passed URI.
+ *
+ * @param uri
+ * @return
+ * @throws IOException
+ * @throws FaceletException
+ * @throws FacesException
+ * @throws ELException
+ */
+ public abstract Facelet getFacelet(String uri) throws IOException;
+
+ /**
+ * Set the static instance
+ *
+ * @param factory
+ */
+ public static final void setInstance(FaceletFactory factory)
+ {
+ instance.set(factory);
+ }
+
+ /**
+ * Get the static instance
+ *
+ * @return
+ */
+ public static final FaceletFactory getInstance()
+ {
+ return instance.get();
+ }
+}
Added: myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java?rev=761982&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java Sat Apr 4 18:44:59 2009
@@ -0,0 +1,155 @@
+/*
+ * 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.myfaces.view.facelets;
+
+import java.beans.BeanInfo;
+import java.io.IOException;
+
+import javax.faces.FacesException;
+import javax.faces.application.Resource;
+import javax.faces.component.UIViewRoot;
+import javax.faces.context.FacesContext;
+import javax.faces.view.ViewMetadata;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.myfaces.application.ViewHandlerSupport;
+import org.apache.myfaces.view.ViewDeclarationLanguageBase;
+
+/**
+ * This class represents the abstraction of Facelets as a ViewDeclarationLanguage.
+ *
+ * @author Simon Lessard (latest modification by $Author: slessard $)
+ * @version $Revision: 696523 $ $Date: 2009-03-21 14:57:08 -0400 (mer., 17 sept. 2008) $
+ *
+ * @since 2.0
+ */
+public class FaceletViewDeclarationLanguage extends ViewDeclarationLanguageBase
+{
+ private ViewHandlerSupport _cachedViewHandlerSupport;
+
+ /**
+ *
+ */
+ public FaceletViewDeclarationLanguage()
+ {
+ // TODO: IMPLEMENT HERE
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void buildView(FacesContext context, UIViewRoot view) throws IOException
+ {
+ // TODO: IMPLEMENT HERE
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public UIViewRoot createView(FacesContext context, String viewId)
+ {
+ UIViewRoot viewRoot = super.createView(context, viewId);
+ context.setViewRoot(viewRoot);
+
+ // TODO: IMPLEMENT HERE
+ /* The implementation must guarantee that the page is executed in such a way that the UIComponent
+ * tree described in the PDL page is completely built and populated, rooted at the new UIViewRoot
+ * instance created previously. See Section 10.2.3 Creating a View.
+ */
+
+ return viewRoot;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public BeanInfo getComponentMetadata(FacesContext context, Resource componentResource)
+ {
+ // TODO: IMPLEMENT HERE
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Resource getScriptComponentResource(FacesContext context, Resource componentResource)
+ {
+ // TODO: IMPLEMENT HERE
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public ViewMetadata getViewMetadata(FacesContext context, String viewId)
+ {
+ // TODO: IMPLEMENT HERE
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void renderView(FacesContext context, UIViewRoot view) throws IOException
+ {
+ // TODO: IMPLEMENT HERE
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public UIViewRoot restoreView(FacesContext context, String viewId)
+ {
+ // TODO: IMPLEMENT HERE
+ return null;
+ }
+
+ @Override
+ protected String calculateViewId(FacesContext context, String viewId)
+ {
+ if (_cachedViewHandlerSupport == null)
+ {
+ _cachedViewHandlerSupport = null; // TODO: IMPLEMENT HERE
+ }
+
+ return _cachedViewHandlerSupport.calculateViewId(context, viewId);
+ }
+
+ @Override
+ protected void sendSourceNotFound(FacesContext context, String message)
+ {
+ HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();
+ try
+ {
+ context.responseComplete();
+ response.sendError(HttpServletResponse.SC_NOT_FOUND, message);
+ }
+ catch (IOException ioe)
+ {
+ throw new FacesException(ioe);
+ }
+ }
+}
Added: myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguageStrategy.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguageStrategy.java?rev=761982&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguageStrategy.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguageStrategy.java Sat Apr 4 18:44:59 2009
@@ -0,0 +1,144 @@
+/*
+ * 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.myfaces.view.facelets;
+
+import java.util.regex.Pattern;
+
+import javax.faces.application.ViewHandler;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+import javax.faces.view.ViewDeclarationLanguage;
+
+import org.apache.myfaces.view.ViewDeclarationLanguageStrategy;
+
+/**
+ * @author Simon Lessard (latest modification by $Author: slessard $)
+ * @version $Revision: 696523 $ $Date: 2009-03-22 13:15:03 -0400 (mer., 17 sept. 2008) $
+ *
+ * @since 2.0
+ */
+public class FaceletViewDeclarationLanguageStrategy implements ViewDeclarationLanguageStrategy
+{
+ private Pattern _acceptPatterns;
+ private String _extension;
+
+ private ViewDeclarationLanguage _language;
+
+ public FaceletViewDeclarationLanguageStrategy()
+ {
+ ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
+
+ _acceptPatterns = loadAcceptPattern(context);
+
+ _extension = loadFaceletExtension(context);
+
+ _language = new FaceletViewDeclarationLanguage();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ViewDeclarationLanguage getViewDeclarationLanguage()
+ {
+ return _language;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean handles(String viewId)
+ {
+ // Check extension first as it's faster than mappings
+ if (viewId.endsWith(_extension))
+ {
+ return true;
+ }
+
+
+ // Try to match the view identifier with the facelet mappings
+ return _acceptPatterns != null && _acceptPatterns.matcher(viewId).matches();
+ }
+
+ private Pattern loadAcceptPattern(ExternalContext context)
+ {
+ assert context != null;
+
+ String mappings = context.getInitParameter(ViewHandler.FACELETS_VIEW_MAPPINGS_PARAM_NAME);
+ if (mappings == null)
+ {
+ return null;
+ }
+
+ // Make sure the mappings contain something
+ mappings = mappings.trim();
+ if (mappings.length() == 0)
+ {
+ return null;
+ }
+
+ return Pattern.compile(toRegex(mappings));
+ }
+
+ private String loadFaceletExtension(ExternalContext context)
+ {
+ assert context != null;
+
+ String suffix = context.getInitParameter(ViewHandler.FACELETS_SUFFIX_PARAM_NAME);
+ if (suffix == null)
+ {
+ suffix = ViewHandler.DEFAULT_FACELETS_SUFFIX;
+ }
+ else
+ {
+ suffix = suffix.trim();
+ if (suffix.length() == 0)
+ {
+ suffix = ViewHandler.DEFAULT_FACELETS_SUFFIX;
+ }
+ }
+
+ return suffix;
+ }
+
+ /**
+ * Convert the specified mapping string to an equivalent regular expression.
+ *
+ * @param mappings le mapping string
+ *
+ * @return an uncompiled regular expression representing the mappings
+ */
+ private String toRegex(String mappings)
+ {
+ assert mappings != null;
+
+ // Get rid of spaces
+ mappings = mappings.replaceAll("\\s", "");
+
+ // Escape '.'
+ mappings = mappings.replaceAll("\\.", "\\\\.");
+
+ // Change '*' to '.*' to represent any match
+ mappings = mappings.replaceAll("\\*", ".*");
+
+ // Split the mappings by changing ';' to '|'
+ mappings = mappings.replaceAll(";", "|");
+
+ return mappings;
+ }
+}
Added: myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewHandler.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewHandler.java?rev=761982&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewHandler.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewHandler.java Sat Apr 4 18:44:59 2009
@@ -0,0 +1,941 @@
+/*
+ * 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.myfaces.view.facelets;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.Writer;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.el.ELException;
+import javax.faces.FacesException;
+import javax.faces.application.StateManager;
+import javax.faces.application.ViewHandler;
+import javax.faces.component.UIViewRoot;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+import javax.faces.render.RenderKit;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.myfaces.view.facelets.compiler.Compiler;
+import org.apache.myfaces.view.facelets.compiler.SAXCompiler;
+import org.apache.myfaces.view.facelets.compiler.TagLibraryConfig;
+import org.apache.myfaces.view.facelets.impl.DefaultFaceletFactory;
+import org.apache.myfaces.view.facelets.impl.DefaultResourceResolver;
+import org.apache.myfaces.view.facelets.impl.ResourceResolver;
+import org.apache.myfaces.view.facelets.tag.TagDecorator;
+import org.apache.myfaces.view.facelets.tag.TagLibrary;
+import org.apache.myfaces.view.facelets.tag.ui.UIDebug;
+import org.apache.myfaces.view.facelets.util.DevTools;
+import org.apache.myfaces.view.facelets.util.ReflectionUtil;
+
+/**
+ * ViewHandler implementation for Facelets
+ *
+ * @author Jacob Hookom
+ * @version $Id: FaceletViewHandler.java,v 1.49.2.6 2006/03/20 07:22:00 jhook Exp $
+ */
+public class FaceletViewHandler extends ViewHandler
+{
+
+ protected final static Logger log = Logger.getLogger("facelets.viewhandler");
+
+ public final static long DEFAULT_REFRESH_PERIOD = 2;
+
+ public final static String PARAM_REFRESH_PERIOD = "facelets.REFRESH_PERIOD";
+
+ /**
+ * Spelling error, We'll remove this in a future release.
+ *
+ * @deprecated
+ */
+ public final static String PARAM_REFRESH_PERIO = PARAM_REFRESH_PERIOD;
+
+ public final static String PARAM_SKIP_COMMENTS = "facelets.SKIP_COMMENTS";
+
+ /**
+ * Context initialization parameter for defining what viewIds should be handled by Facelets, and what should not.
+ * When left unset, all URLs will be handled by Facelets. When set, it must be a semicolon separated list of either
+ * extension mappings or prefix mappings. For example:
+ *
+ * <pre>
+ *
+ *
+ *
+ * <context-param>
+ * <param-name>facelets.VIEW_MAPPINGS</param-name>
+ * <param-value>/demos/*; *.xhtml</param-value>
+ * </context-param>
+ *
+ *
+ *
+ * </pre>
+ *
+ * would use Facelets for processing all viewIds in the "/demos" directory or that end in .xhtml, and use the
+ * standard JSP engine for all other viewIds.
+ * <p>
+ * <strong>NOTE</strong>: when using this parameter, you need to use prefix-mapping for the
+ * <code>FacesServlet</code> (that is, <code>/faces/*</code>, not <code>*.jsf</code>).
+ * </p>
+ */
+ public final static String PARAM_VIEW_MAPPINGS = "facelets.VIEW_MAPPINGS";
+
+ public final static String PARAM_LIBRARIES = "facelets.LIBRARIES";
+
+ public final static String PARAM_DECORATORS = "facelets.DECORATORS";
+
+ public final static String PARAM_DEVELOPMENT = "facelets.DEVELOPMENT";
+
+ public final static String PARAM_RESOURCE_RESOLVER = "facelets.RESOURCE_RESOLVER";
+
+ public final static String PARAM_BUILD_BEFORE_RESTORE = "facelets.BUILD_BEFORE_RESTORE";
+
+ public final static String PARAM_BUFFER_SIZE = "facelets.BUFFER_SIZE";
+
+ private final static String STATE_KEY = "~facelets.VIEW_STATE~";
+
+ private final static int STATE_KEY_LEN = STATE_KEY.length();
+
+ private final ViewHandler parent;
+
+ private boolean developmentMode = false;
+
+ private boolean buildBeforeRestore = false;
+
+ private int bufferSize;
+
+ private String defaultSuffix;
+
+ private FaceletFactory faceletFactory;
+
+ // Array of viewId extensions that should be handled by Facelets
+ private String[] extensionsArray;
+
+ // Array of viewId prefixes that should be handled by Facelets
+ private String[] prefixesArray;
+
+ /**
+ *
+ */
+ public FaceletViewHandler(ViewHandler parent)
+ {
+ this.parent = parent;
+ }
+
+ /**
+ * Initialize the ViewHandler during its first request.
+ */
+ protected void initialize(FacesContext context)
+ {
+ synchronized (this)
+ {
+ if (this.faceletFactory == null)
+ {
+ log.fine("Initializing");
+ Compiler c = this.createCompiler();
+ this.initializeCompiler(c);
+ this.faceletFactory = this.createFaceletFactory(c);
+
+ this.initializeMappings(context);
+ this.initializeMode(context);
+ this.initializeBuffer(context);
+
+ log.fine("Initialization Successful");
+ }
+ }
+ }
+
+ private void initializeMode(FacesContext context)
+ {
+ ExternalContext external = context.getExternalContext();
+ String param = external.getInitParameter(PARAM_DEVELOPMENT);
+ this.developmentMode = "true".equals(param);
+
+ String restoreMode = external.getInitParameter(PARAM_BUILD_BEFORE_RESTORE);
+ this.buildBeforeRestore = "true".equals(restoreMode);
+ }
+
+ private void initializeBuffer(FacesContext context)
+ {
+ ExternalContext external = context.getExternalContext();
+ String param = external.getInitParameter(PARAM_BUFFER_SIZE);
+ this.bufferSize = (param != null && !"".equals(param)) ? Integer.parseInt(param) : -1;
+ }
+
+ /**
+ * Initialize mappings, during the first request.
+ */
+ private void initializeMappings(FacesContext context)
+ {
+ ExternalContext external = context.getExternalContext();
+ String viewMappings = external.getInitParameter(PARAM_VIEW_MAPPINGS);
+ if ((viewMappings != null) && (viewMappings.length() > 0))
+ {
+ String[] mappingsArray = viewMappings.split(";");
+
+ List<String> extensionsList = new ArrayList<String>(mappingsArray.length);
+ List<String> prefixesList = new ArrayList<String>(mappingsArray.length);
+
+ for (int i = 0; i < mappingsArray.length; i++)
+ {
+ String mapping = mappingsArray[i].trim();
+ int mappingLength = mapping.length();
+ if (mappingLength <= 1)
+ {
+ continue;
+ }
+
+ if (mapping.charAt(0) == '*')
+ {
+ extensionsList.add(mapping.substring(1));
+ }
+ else if (mapping.charAt(mappingLength - 1) == '*')
+ {
+ prefixesList.add(mapping.substring(0, mappingLength - 1));
+ }
+ }
+
+ extensionsArray = new String[extensionsList.size()];
+ extensionsList.toArray(extensionsArray);
+
+ prefixesArray = new String[prefixesList.size()];
+ prefixesList.toArray(prefixesArray);
+ }
+ }
+
+ protected FaceletFactory createFaceletFactory(Compiler c)
+ {
+
+ // refresh period
+ long refreshPeriod = DEFAULT_REFRESH_PERIOD;
+ FacesContext ctx = FacesContext.getCurrentInstance();
+ String userPeriod = ctx.getExternalContext().getInitParameter(PARAM_REFRESH_PERIOD);
+ if (userPeriod != null && userPeriod.length() > 0)
+ {
+ refreshPeriod = Long.parseLong(userPeriod);
+ }
+
+ // resource resolver
+ ResourceResolver resolver = new DefaultResourceResolver();
+ String resolverName = ctx.getExternalContext().getInitParameter(PARAM_RESOURCE_RESOLVER);
+ if (resolverName != null && resolverName.length() > 0)
+ {
+ try
+ {
+ resolver = (ResourceResolver) ReflectionUtil.forName(resolverName).newInstance();
+ }
+ catch (Exception e)
+ {
+ throw new FacesException("Error Initializing ResourceResolver[" + resolverName + "]", e);
+ }
+ }
+
+ // Resource.getResourceUrl(ctx,"/")
+ return new DefaultFaceletFactory(c, resolver, refreshPeriod);
+ }
+
+ protected Compiler createCompiler()
+ {
+ return new SAXCompiler();
+ }
+
+ protected void initializeCompiler(Compiler c)
+ {
+ FacesContext ctx = FacesContext.getCurrentInstance();
+ ExternalContext ext = ctx.getExternalContext();
+
+ // load libraries
+ String libParam = ext.getInitParameter(PARAM_LIBRARIES);
+ if (libParam != null)
+ {
+ libParam = libParam.trim();
+ String[] libs = libParam.split(";");
+ URL src;
+ TagLibrary libObj;
+ for (int i = 0; i < libs.length; i++)
+ {
+ try
+ {
+ src = ext.getResource(libs[i].trim());
+ if (src == null)
+ {
+ throw new FileNotFoundException(libs[i]);
+ }
+ libObj = TagLibraryConfig.create(src);
+ c.addTagLibrary(libObj);
+ log.fine("Successfully Loaded Library: " + libs[i]);
+ }
+ catch (IOException e)
+ {
+ log.log(Level.SEVERE, "Error Loading Library: " + libs[i], e);
+ }
+ }
+ }
+
+ // load decorators
+ String decParam = ext.getInitParameter(PARAM_DECORATORS);
+ if (decParam != null)
+ {
+ decParam = decParam.trim();
+ String[] decs = decParam.split(";");
+ TagDecorator decObj;
+ for (int i = 0; i < decs.length; i++)
+ {
+ try
+ {
+ decObj = (TagDecorator) ReflectionUtil.forName(decs[i]).newInstance();
+ c.addTagDecorator(decObj);
+ log.fine("Successfully Loaded Decorator: " + decs[i]);
+ }
+ catch (Exception e)
+ {
+ log.log(Level.SEVERE, "Error Loading Decorator: " + decs[i], e);
+ }
+ }
+ }
+
+ // skip params?
+ String skipParam = ext.getInitParameter(PARAM_SKIP_COMMENTS);
+ if (skipParam != null && "true".equals(skipParam))
+ {
+ c.setTrimmingComments(true);
+ }
+ }
+
+ public UIViewRoot restoreView(FacesContext context, String viewId)
+ {
+ if (UIDebug.debugRequest(context))
+ {
+ return new UIViewRoot();
+ }
+
+ if (!this.buildBeforeRestore || !handledByFacelets(viewId))
+ {
+ return this.parent.restoreView(context, viewId);
+ }
+
+ if (this.faceletFactory == null)
+ {
+ this.initialize(context);
+ }
+
+ // In JSF 1.2, restoreView() will only be called on postback.
+ // But in JSF 1.1, it will be called for an initial request too,
+ // in which case we must return null in order to fall through
+ // to createView()
+
+ ViewHandler outerViewHandler = context.getApplication().getViewHandler();
+ String renderKitId = outerViewHandler.calculateRenderKitId(context);
+
+ UIViewRoot viewRoot = createView(context, viewId);
+ context.setViewRoot(viewRoot);
+ try
+ {
+ this.buildView(context, viewRoot);
+ }
+ catch (IOException ioe)
+ {
+ log.log(Level.SEVERE, "Error Building View", ioe);
+ }
+ context.getApplication().getStateManager().restoreView(context, viewId, renderKitId);
+ return viewRoot;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.faces.application.ViewHandlerWrapper#getWrapped()
+ */
+ protected ViewHandler getWrapped()
+ {
+ return this.parent;
+ }
+
+ protected ResponseWriter createResponseWriter(FacesContext context) throws IOException, FacesException
+ {
+ ExternalContext extContext = context.getExternalContext();
+ RenderKit renderKit = context.getRenderKit();
+ // Avoid a cryptic NullPointerException when the renderkit ID
+ // is incorrectly set
+ if (renderKit == null)
+ {
+ String id = context.getViewRoot().getRenderKitId();
+ throw new IllegalStateException("No render kit was available for id \"" + id + "\"");
+ }
+
+ ServletResponse response = (ServletResponse) extContext.getResponse();
+
+ // set the buffer for content
+ if (this.bufferSize != -1)
+ {
+ response.setBufferSize(this.bufferSize);
+ }
+
+ // get our content type
+ String contentType = (String) extContext.getRequestMap().get("facelets.ContentType");
+
+ // get the encoding
+ String encoding = (String) extContext.getRequestMap().get("facelets.Encoding");
+
+ ResponseWriter writer;
+ // append */* to the contentType so createResponseWriter will succeed no matter
+ // the requested contentType.
+ if (contentType != null && !contentType.equals("*/*"))
+ {
+ contentType += ",*/*";
+ }
+ // Create a dummy ResponseWriter with a bogus writer,
+ // so we can figure out what content type the ReponseWriter
+ // is really going to ask for
+ try
+ {
+ writer = renderKit.createResponseWriter(NullWriter.Instance, contentType, encoding);
+ }
+ catch (IllegalArgumentException e)
+ {
+ // Added because of an RI bug prior to 1.2_05-b3. Might as well leave it in case other
+ // impls have the same problem. https://javaserverfaces.dev.java.net/issues/show_bug.cgi?id=613
+ log.fine("The impl didn't correctly handled '*/*' in the content type list. Trying '*/*' directly.");
+ writer = renderKit.createResponseWriter(NullWriter.Instance, "*/*", encoding);
+ }
+
+ // Override the JSF provided content type if necessary
+ contentType = getResponseContentType(context, writer.getContentType());
+ encoding = getResponseEncoding(context, writer.getCharacterEncoding());
+
+ // apply them to the response
+ response.setContentType(contentType + "; charset=" + encoding);
+
+ // removed 2005.8.23 to comply with J2EE 1.3
+ // response.setCharacterEncoding(encoding);
+
+ // Now, clone with the real writer
+ writer = writer.cloneWithWriter(response.getWriter());
+
+ return writer;
+ }
+
+ /**
+ * Generate the encoding
+ *
+ * @param context
+ * @param orig
+ * @return
+ */
+ protected String getResponseEncoding(FacesContext context, String orig)
+ {
+ String encoding = orig;
+
+ // see if we need to override the encoding
+ Map<String, Object> m = context.getExternalContext().getRequestMap();
+ Map<String, Object> sm = context.getExternalContext().getSessionMap();
+
+ // 1. check the request attribute
+ if (m.containsKey("facelets.Encoding"))
+ {
+ encoding = (String) m.get("facelets.Encoding");
+ if (log.isLoggable(Level.FINEST))
+ {
+ log.finest("Facelet specified alternate encoding '" + encoding + "'");
+ }
+ sm.put(CHARACTER_ENCODING_KEY, encoding);
+ }
+
+ // 2. get it from request
+ Object request = context.getExternalContext().getRequest();
+ if (encoding == null && request instanceof ServletRequest)
+ {
+ encoding = ((ServletRequest) request).getCharacterEncoding();
+ }
+
+ // 3. get it from the session
+ if (encoding == null)
+ {
+ encoding = (String) sm.get(CHARACTER_ENCODING_KEY);
+ if (log.isLoggable(Level.FINEST))
+ {
+ log.finest("Session specified alternate encoding '" + encoding + "'");
+ }
+ }
+
+ // 4. default it
+ if (encoding == null)
+ {
+ encoding = "UTF-8";
+ if (log.isLoggable(Level.FINEST))
+ {
+ log.finest("ResponseWriter created had a null CharacterEncoding, defaulting to UTF-8");
+ }
+ }
+
+ return encoding;
+ }
+
+ /**
+ * Generate the content type
+ *
+ * @param context
+ * @param orig
+ * @return
+ */
+ protected String getResponseContentType(FacesContext context, String orig)
+ {
+ String contentType = orig;
+
+ // see if we need to override the contentType
+ Map<String, Object> m = context.getExternalContext().getRequestMap();
+ if (m.containsKey("facelets.ContentType"))
+ {
+ contentType = (String) m.get("facelets.ContentType");
+ if (log.isLoggable(Level.FINEST))
+ {
+ log.finest("Facelet specified alternate contentType '" + contentType + "'");
+ }
+ }
+
+ // safety check
+ if (contentType == null)
+ {
+ contentType = "text/html";
+ if (log.isLoggable(Level.FINEST))
+ {
+ log.finest("ResponseWriter created had a null ContentType, defaulting to text/html");
+ }
+ }
+
+ return contentType;
+ }
+
+ protected void buildView(FacesContext context, UIViewRoot viewToRender) throws IOException, FacesException
+ {
+ // setup our viewId
+ String renderedViewId = this.getRenderedViewId(context, viewToRender.getViewId());
+ viewToRender.setViewId(renderedViewId);
+
+ if (log.isLoggable(Level.FINE))
+ {
+ log.fine("Building View: " + renderedViewId);
+ }
+
+ // grab our FaceletFactory and create a Facelet
+ Facelet f = null;
+ FaceletFactory.setInstance(this.faceletFactory);
+ try
+ {
+ f = this.faceletFactory.getFacelet(viewToRender.getViewId());
+ }
+ finally
+ {
+ FaceletFactory.setInstance(null);
+ }
+
+ // populate UIViewRoot
+ long time = System.currentTimeMillis();
+ f.apply(context, viewToRender);
+ time = System.currentTimeMillis() - time;
+ if (log.isLoggable(Level.FINE))
+ {
+ log.fine("Took " + time + "ms to build view: " + viewToRender.getViewId());
+ }
+ }
+
+ public void renderView(FacesContext context, UIViewRoot viewToRender) throws IOException, FacesException
+ {
+
+ // lazy initialize so we have a FacesContext to use
+ if (this.faceletFactory == null)
+ {
+ this.initialize(context);
+ }
+
+ // exit if the view is not to be rendered
+ if (!viewToRender.isRendered())
+ {
+ return;
+ }
+
+ // if facelets is not supposed to handle this request
+ if (!handledByFacelets(viewToRender.getViewId()))
+ {
+ this.parent.renderView(context, viewToRender);
+ return;
+ }
+
+ // log request
+ if (log.isLoggable(Level.FINE))
+ {
+ log.fine("Rendering View: " + viewToRender.getViewId());
+ }
+
+ StateWriter stateWriter = null;
+ try
+ {
+ // build view - but not if we're in "buildBeforeRestore"
+ // land and we've already got a populated view. Note
+ // that this optimizations breaks if there's a "c:if" in
+ // the page that toggles as a result of request processing -
+ // should that be handled? Or
+ // is this optimization simply so minor that it should just
+ // be trimmed altogether?
+ if (!this.buildBeforeRestore || viewToRender.getChildren().isEmpty())
+ {
+ this.buildView(context, viewToRender);
+ }
+
+ // setup writer and assign it to the context
+ ResponseWriter origWriter = this.createResponseWriter(context);
+ // QUESTION: should we use bufferSize? Or, since the
+ // StateWriter usually only needs a small bit at the end,
+ // should we always use a much smaller size?
+ stateWriter = new StateWriter(origWriter, this.bufferSize != -1 ? this.bufferSize : 1024);
+
+ ResponseWriter writer = origWriter.cloneWithWriter(stateWriter);
+ context.setResponseWriter(writer);
+
+ // force creation of session if saving state there
+ StateManager stateMgr = context.getApplication().getStateManager();
+ if (!stateMgr.isSavingStateInClient(context))
+ {
+ context.getExternalContext().getSession(true);
+ }
+
+ long time = System.currentTimeMillis();
+
+ // render the view to the response
+ writer.startDocument();
+ viewToRender.encodeAll(context);
+ writer.endDocument();
+
+ // finish writing
+ writer.close();
+
+ boolean writtenState = stateWriter.isStateWritten();
+ // flush to origWriter
+ if (writtenState)
+ {
+ String content = stateWriter.getAndResetBuffer();
+ int end = content.indexOf(STATE_KEY);
+ // See if we can find any trace of the saved state.
+ // If so, we need to perform token replacement
+ if (end >= 0)
+ {
+ // save state
+ Object stateObj = stateMgr.saveSerializedView(context);
+ String stateStr;
+ if (stateObj == null)
+ {
+ stateStr = null;
+ }
+ else
+ {
+ stateMgr.writeState(context, (StateManager.SerializedView) stateObj);
+ stateStr = stateWriter.getAndResetBuffer();
+ }
+
+ int start = 0;
+
+ while (end != -1)
+ {
+ origWriter.write(content, start, end - start);
+ if (stateStr != null)
+ {
+ origWriter.write(stateStr);
+ }
+ start = end + STATE_KEY_LEN;
+ end = content.indexOf(STATE_KEY, start);
+ }
+ origWriter.write(content, start, content.length() - start);
+ // No trace of any saved state, so we just need to flush
+ // the buffer
+ }
+ else
+ {
+ origWriter.write(content);
+ }
+ }
+
+ time = System.currentTimeMillis() - time;
+ if (log.isLoggable(Level.FINE))
+ {
+ log.fine("Took " + time + "ms to render view: " + viewToRender.getViewId());
+ }
+
+ }
+ catch (FileNotFoundException fnfe)
+ {
+ this.handleFaceletNotFound(context, viewToRender.getViewId());
+ }
+ catch (Exception e)
+ {
+ this.handleRenderException(context, e);
+ }
+ finally
+ {
+ if (stateWriter != null)
+ stateWriter.release();
+ }
+ }
+
+ protected void handleRenderException(FacesContext context, Exception e) throws IOException, ELException,
+ FacesException
+ {
+ Object resp = context.getExternalContext().getResponse();
+
+ // always log
+ if (log.isLoggable(Level.SEVERE))
+ {
+ UIViewRoot root = context.getViewRoot();
+ StringBuffer sb = new StringBuffer(64);
+ sb.append("Error Rendering View");
+ if (root != null)
+ {
+ sb.append('[');
+ sb.append(root.getViewId());
+ sb.append(']');
+ }
+ log.log(Level.SEVERE, sb.toString(), e);
+ }
+
+ // handle dev response
+ if (this.developmentMode && !context.getResponseComplete() && resp instanceof HttpServletResponse)
+ {
+ HttpServletResponse httpResp = (HttpServletResponse) resp;
+ if (!httpResp.isCommitted())
+ {
+ httpResp.reset();
+ httpResp.setContentType("text/html; charset=UTF-8");
+ Writer w = httpResp.getWriter();
+ DevTools.debugHtml(w, context, e);
+ w.flush();
+ context.responseComplete();
+ }
+ }
+ else if (e instanceof RuntimeException)
+ {
+ throw (RuntimeException) e;
+ }
+ else if (e instanceof IOException)
+ {
+ throw (IOException) e;
+ }
+ else
+ {
+ throw new FacesException(e.getMessage(), e);
+ }
+ }
+
+ protected void handleFaceletNotFound(FacesContext context, String viewId) throws FacesException, IOException
+ {
+ String actualId = this.getActionURL(context, viewId);
+ Object respObj = context.getExternalContext().getResponse();
+ if (respObj instanceof HttpServletResponse)
+ {
+ HttpServletResponse respHttp = (HttpServletResponse) respObj;
+ respHttp.sendError(HttpServletResponse.SC_NOT_FOUND, actualId);
+ context.responseComplete();
+ }
+ }
+
+ /**
+ * Determine if Facelets needs to handle this request.
+ */
+ private boolean handledByFacelets(String viewId)
+ {
+ // If there's no extensions array or prefixes array, then
+ // just make Facelets handle everything
+ if ((extensionsArray == null) && (prefixesArray == null))
+ {
+ return true;
+ }
+
+ if (extensionsArray != null)
+ {
+ for (int i = 0; i < extensionsArray.length; i++)
+ {
+ String extension = extensionsArray[i];
+ if (viewId.endsWith(extension))
+ {
+ return true;
+ }
+ }
+ }
+
+ if (prefixesArray != null)
+ {
+ for (int i = 0; i < prefixesArray.length; i++)
+ {
+ String prefix = prefixesArray[i];
+ if (viewId.startsWith(prefix))
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ public String getDefaultSuffix(FacesContext context) throws FacesException
+ {
+ if (this.defaultSuffix == null)
+ {
+ ExternalContext extCtx = context.getExternalContext();
+ String viewSuffix = extCtx.getInitParameter(ViewHandler.DEFAULT_SUFFIX_PARAM_NAME);
+ this.defaultSuffix = (viewSuffix != null) ? viewSuffix : ViewHandler.DEFAULT_SUFFIX;
+ }
+ return this.defaultSuffix;
+ }
+
+ protected String getRenderedViewId(FacesContext context, String actionId)
+ {
+ ExternalContext extCtx = context.getExternalContext();
+ String viewId = actionId;
+ if (extCtx.getRequestPathInfo() == null)
+ {
+ String viewSuffix = this.getDefaultSuffix(context);
+ viewId = new StringBuffer(viewId).replace(viewId.lastIndexOf('.'), viewId.length(), viewSuffix).toString();
+ }
+ if (log.isLoggable(Level.FINE))
+ {
+ log.fine("ActionId -> ViewId: " + actionId + " -> " + viewId);
+ }
+ return viewId;
+ }
+
+ public void writeState(FacesContext context) throws IOException
+ {
+ if (handledByFacelets(context.getViewRoot().getViewId()))
+ {
+ // Tell the StateWriter that we're about to write state
+ StateWriter.getCurrentInstance().writingState();
+ // Write the STATE_KEY out. Unfortunately, this will
+ // be wasteful for pure server-side state managers where nothing
+ // is actually written into the output, but this cannot
+ // programatically be discovered
+ context.getResponseWriter().write(STATE_KEY);
+ }
+ else
+ {
+ this.parent.writeState(context);
+ }
+ }
+
+ public Locale calculateLocale(FacesContext context)
+ {
+ return this.parent.calculateLocale(context);
+ }
+
+ public String calculateRenderKitId(FacesContext context)
+ {
+ return this.parent.calculateRenderKitId(context);
+ }
+
+ public UIViewRoot createView(FacesContext context, String viewId)
+ {
+ if (UIDebug.debugRequest(context))
+ {
+ return new UIViewRoot();
+ }
+ return this.parent.createView(context, viewId);
+ }
+
+ public String getActionURL(FacesContext context, String viewId)
+ {
+ return this.parent.getActionURL(context, viewId);
+ }
+
+ public String getResourceURL(FacesContext context, String path)
+ {
+ return this.parent.getResourceURL(context, path);
+ }
+
+ /**
+ * Try to guess if this is a postback request. In JSF 1.2, this method is not needed, since ResponseStateManager can
+ * identify postbacks. We use a simple heuristic: for HttpServletRequests, "POST" and "PUT" are postbacks. For
+ * anything that isn't an HttpServletRequest, just guess that if there's a request parameter, it's probably a
+ * postback.
+ */
+ static private boolean isPostback11(FacesContext context)
+ {
+ Object reqObject = context.getExternalContext().getRequest();
+ if (reqObject instanceof HttpServletRequest)
+ {
+ HttpServletRequest request = (HttpServletRequest) reqObject;
+
+ String method = request.getMethod();
+
+ // Is this a POST or PUT request?
+ if ("POST".equals(method) || "PUT".equals(method))
+ {
+ return true;
+ }
+
+ return false;
+ }
+ else
+ {
+ Map<String, String> paramMap = context.getExternalContext().getRequestParameterMap();
+ return !paramMap.isEmpty();
+ }
+ }
+
+ protected static class NullWriter extends Writer
+ {
+
+ static final NullWriter Instance = new NullWriter();
+
+ public void write(char[] buffer)
+ {
+ }
+
+ public void write(char[] buffer, int off, int len)
+ {
+ }
+
+ public void write(String str)
+ {
+ }
+
+ public void write(int c)
+ {
+ }
+
+ public void write(String str, int off, int len)
+ {
+ }
+
+ public void close()
+ {
+ }
+
+ public void flush()
+ {
+ }
+ }
+}
Added: myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/StateWriter.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/StateWriter.java?rev=761982&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/StateWriter.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/StateWriter.java Sat Apr 4 18:44:59 2009
@@ -0,0 +1,145 @@
+/*
+ * 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.myfaces.view.facelets;
+
+import java.io.IOException;
+import java.io.Writer;
+
+import org.apache.myfaces.view.facelets.util.FastWriter;
+
+/**
+ * A class for handling state insertion. Content is written directly to "out" until an attempt to write state; at that
+ * point, it's redirected into a buffer that can be picked through in theory, this buffer should be very small, since it
+ * only needs to be enough to contain all the content after the close of the first (and, hopefully, only) form.
+ * <p>
+ * Potential optimizations:
+ * <ul>
+ * <li>If we created a new FastWriter at each call to writingState(), and stored a List of them, then we'd know that
+ * state tokens could only possibly be near the start of each buffer (and might not be there at all). (There might be a
+ * close-element before the state token). Then, we'd only need to check the start of the buffer for the state token; if
+ * it's there, write out the real state, then blast the rest of the buffer out. This wouldn't even require toString(),
+ * which for large buffers is expensive. However, this optimization is only going to be especially meaningful for the
+ * multi-form case.</li>
+ * <li>More of a FastWriter optimization than a StateWriter, but: it is far faster to create a set of small 1K buffers
+ * than constantly reallocating one big buffer.</li>
+ * </ul>
+ *
+ * @author Adam Winer
+ * @version $Id: StateWriter.java,v 1.2 2008/07/13 19:01:40 rlubke Exp $
+ */
+final class StateWriter extends Writer
+{
+
+ private int initialSize;
+ private Writer out;
+ private FastWriter fast;
+ private boolean writtenState;
+
+ static public StateWriter getCurrentInstance()
+ {
+ return (StateWriter) CURRENT_WRITER.get();
+ }
+
+ public StateWriter(Writer initialOut, int initialSize)
+ {
+ if (initialSize < 0)
+ {
+ throw new IllegalArgumentException("Initial Size cannot be less than 0");
+ }
+
+ this.initialSize = initialSize;
+ this.out = initialOut;
+
+ CURRENT_WRITER.set(this);
+ }
+
+ /**
+ * Mark that state is about to be written. Contrary to what you'd expect, we cannot and should not assume that this
+ * location is really going to have state; it is perfectly legit to have a ResponseWriter that filters out content,
+ * and ignores an attempt to write out state at this point. So, we have to check after the fact to see if there
+ * really are state markers.
+ */
+ public void writingState()
+ {
+ if (!this.writtenState)
+ {
+ this.writtenState = true;
+ this.out = this.fast = new FastWriter(this.initialSize);
+ }
+ }
+
+ public boolean isStateWritten()
+ {
+ return this.writtenState;
+ }
+
+ public void close() throws IOException
+ {
+ // do nothing
+ }
+
+ public void flush() throws IOException
+ {
+ // do nothing
+ }
+
+ public void write(char[] cbuf, int off, int len) throws IOException
+ {
+ this.out.write(cbuf, off, len);
+ }
+
+ public void write(char[] cbuf) throws IOException
+ {
+ this.out.write(cbuf);
+ }
+
+ public void write(int c) throws IOException
+ {
+ this.out.write(c);
+ }
+
+ public void write(String str, int off, int len) throws IOException
+ {
+ this.out.write(str, off, len);
+ }
+
+ public void write(String str) throws IOException
+ {
+ this.out.write(str);
+ }
+
+ public String getAndResetBuffer()
+ {
+ if (!this.writtenState)
+ {
+ throw new IllegalStateException("Did not write state; no buffer is available");
+ }
+
+ String result = this.fast.toString();
+ this.fast.reset();
+ return result;
+ }
+
+ public void release()
+ {
+ CURRENT_WRITER.remove();
+ }
+
+ static private final ThreadLocal<StateWriter> CURRENT_WRITER = new ThreadLocal<StateWriter>();
+}
\ No newline at end of file
Added: myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/TemplateClient.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/TemplateClient.java?rev=761982&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/TemplateClient.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/TemplateClient.java Sat Apr 4 18:44:59 2009
@@ -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 org.apache.myfaces.view.facelets;
+
+import java.io.IOException;
+
+import javax.el.ELException;
+import javax.faces.FacesException;
+import javax.faces.component.UIComponent;
+import javax.faces.view.facelets.FaceletContext;
+import javax.faces.view.facelets.FaceletException;
+
+/**
+ * FaceletHandlers can implement this contract and push themselves into the FaceletContext for participating in
+ * templating. Templates will attempt to resolve content for a specified name until one of the TemplatClients return
+ * 'true'.
+ *
+ * @author Jacob Hookom
+ * @version $Id: TemplateClient.java,v 1.3 2008/07/13 19:01:39 rlubke Exp $
+ */
+public interface TemplateClient
+{
+
+ /**
+ * This contract is much like the normal FaceletHandler.apply method, but it takes in an optional String name which
+ * tells this instance what fragment/definition it's looking for. If you are a match, apply your logic to the passed
+ * UIComponent and return true, otherwise do nothing and return false.
+ *
+ * @param ctx
+ * the FaceletContext of <i>your</i> instance, not the templates'
+ * @param parent
+ * current UIComponent instance to be applied
+ * @param name
+ * the String name or null if the whole body should be included
+ * @return true if this client matched/applied the definition for the passed name
+ * @throws IOException
+ * @throws FacesException
+ * @throws FaceletException
+ * @throws ELException
+ */
+ public boolean apply(FaceletContext ctx, UIComponent parent, String name) throws IOException, FacesException,
+ FaceletException, ELException;;
+}
Added: myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/AbstractUIHandler.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/AbstractUIHandler.java?rev=761982&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/AbstractUIHandler.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/AbstractUIHandler.java Sat Apr 4 18:44:59 2009
@@ -0,0 +1,50 @@
+/*
+ * 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.myfaces.view.facelets.compiler;
+
+import javax.faces.component.UIComponent;
+import javax.faces.view.facelets.FaceletContext;
+import javax.faces.view.facelets.FaceletHandler;
+import javax.faces.view.facelets.TextHandler;
+
+import org.apache.myfaces.view.facelets.tag.jsf.core.FacetHandler;
+
+public abstract class AbstractUIHandler implements FaceletHandler, TextHandler
+{
+
+ public void addComponent(FaceletContext ctx, UIComponent parent, UIComponent c)
+ {
+ // possible facet scoped
+ String facetName = this.getFacetName(ctx, parent);
+ if (facetName == null)
+ {
+ parent.getChildren().add(c);
+ }
+ else
+ {
+ parent.getFacets().put(facetName, c);
+ }
+ }
+
+ protected final String getFacetName(FaceletContext ctx, UIComponent parent)
+ {
+ return (String) parent.getAttributes().get(FacetHandler.KEY);
+ }
+
+}
Added: myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/AttributeInstruction.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/AttributeInstruction.java?rev=761982&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/AttributeInstruction.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/AttributeInstruction.java Sat Apr 4 18:44:59 2009
@@ -0,0 +1,78 @@
+/*
+ * 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.myfaces.view.facelets.compiler;
+
+import java.io.IOException;
+
+import javax.el.ELContext;
+import javax.el.ELException;
+import javax.el.ExpressionFactory;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+
+import org.apache.myfaces.view.facelets.el.ELText;
+
+final class AttributeInstruction implements Instruction
+{
+ private final String _alias;
+
+ private final String _attr;
+
+ private final ELText _txt;
+
+ public AttributeInstruction(String alias, String attr, ELText txt)
+ {
+ _alias = alias;
+ _attr = attr;
+ _txt = txt;
+ }
+
+ public void write(FacesContext context) throws IOException
+ {
+ ResponseWriter out = context.getResponseWriter();
+ try
+ {
+ out.writeAttribute(_attr, _txt.toString(context.getELContext()), null);
+ }
+ catch (ELException e)
+ {
+ throw new ELException(_alias + ": " + e.getMessage(), e.getCause());
+ }
+ catch (Exception e)
+ {
+ throw new ELException(_alias + ": " + e.getMessage(), e);
+ }
+ }
+
+ public Instruction apply(ExpressionFactory factory, ELContext ctx)
+ {
+ ELText nt = _txt.apply(factory, ctx);
+ if (nt == _txt)
+ {
+ return this;
+ }
+
+ return new AttributeInstruction(_alias, _attr, nt);
+ }
+
+ public boolean isLiteral()
+ {
+ return _txt.isLiteral();
+ }
+}
Added: myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/CommentInstruction.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/CommentInstruction.java?rev=761982&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/CommentInstruction.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/CommentInstruction.java Sat Apr 4 18:44:59 2009
@@ -0,0 +1,52 @@
+/*
+ * 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.myfaces.view.facelets.compiler;
+
+import java.io.IOException;
+
+import javax.el.ELContext;
+import javax.el.ExpressionFactory;
+import javax.faces.context.FacesContext;
+
+import org.apache.myfaces.view.facelets.el.ELText;
+
+final class CommentInstruction implements Instruction
+{
+ private final ELText _text;
+
+ public CommentInstruction(ELText text)
+ {
+ _text = text;
+ }
+
+ public void write(FacesContext context) throws IOException
+ {
+ context.getResponseWriter().writeComment(_text.toString(context.getELContext()));
+ }
+
+ public Instruction apply(ExpressionFactory factory, ELContext ctx)
+ {
+ return new CommentInstruction(_text.apply(factory, ctx));
+ }
+
+ public boolean isLiteral()
+ {
+ return false;
+ }
+}