You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by ta...@apache.org on 2022/08/16 12:06:33 UTC
[myfaces] branch 2.3.x updated: MYFACES-4441
This is an automated email from the ASF dual-hosted git repository.
tandraschko pushed a commit to branch 2.3.x
in repository https://gitbox.apache.org/repos/asf/myfaces.git
The following commit(s) were added to refs/heads/2.3.x by this push:
new d97065c23 MYFACES-4441
d97065c23 is described below
commit d97065c23c4e0cba531b8c41a3393d63ed413075
Author: Thomas Andraschko <ta...@apache.org>
AuthorDate: Tue Aug 16 14:06:26 2022 +0200
MYFACES-4441
---
.../context/servlet/StartupFacesContextImpl.java | 3 +-
.../application/FacesServletMappingUtils.java | 933 +++++++++++----------
.../shared/context/StartupFacesContext.java | 25 +
3 files changed, 494 insertions(+), 467 deletions(-)
diff --git a/impl/src/main/java/org/apache/myfaces/context/servlet/StartupFacesContextImpl.java b/impl/src/main/java/org/apache/myfaces/context/servlet/StartupFacesContextImpl.java
index 5fa735622..7a73edaed 100644
--- a/impl/src/main/java/org/apache/myfaces/context/servlet/StartupFacesContextImpl.java
+++ b/impl/src/main/java/org/apache/myfaces/context/servlet/StartupFacesContextImpl.java
@@ -30,6 +30,7 @@ import javax.faces.context.ResponseWriter;
import javax.faces.event.PhaseId;
import org.apache.myfaces.context.ReleaseableExternalContext;
+import org.apache.myfaces.shared.context.StartupFacesContext;
/**
* A FacesContext implementation which will be set as the current instance
@@ -39,7 +40,7 @@ import org.apache.myfaces.context.ReleaseableExternalContext;
* @author Jakob Korherr (latest modification by $Author$)
* @version $Revision$ $Date$
*/
-public class StartupFacesContextImpl extends FacesContextImplBase
+public class StartupFacesContextImpl extends FacesContextImplBase implements StartupFacesContext
{
public static final String EXCEPTION_TEXT = "This method is not supported during ";
diff --git a/shared/src/main/java/org/apache/myfaces/shared/application/FacesServletMappingUtils.java b/shared/src/main/java/org/apache/myfaces/shared/application/FacesServletMappingUtils.java
index 1c85a1f28..91271fc77 100644
--- a/shared/src/main/java/org/apache/myfaces/shared/application/FacesServletMappingUtils.java
+++ b/shared/src/main/java/org/apache/myfaces/shared/application/FacesServletMappingUtils.java
@@ -1,466 +1,467 @@
-/*
- * 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.shared.application;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import javax.faces.context.ExternalContext;
-import javax.faces.context.FacesContext;
-import javax.faces.webapp.FacesServlet;
-import javax.servlet.ServletContext;
-import javax.servlet.ServletRegistration;
-import org.apache.myfaces.shared.config.MyfacesConfig;
-import org.apache.myfaces.shared.util.ClassUtils;
-import org.apache.myfaces.shared.util.ExternalContextUtils;
-import org.apache.myfaces.shared.webapp.webxml.DelegatedFacesServlet;
-
-public class FacesServletMappingUtils
-{
- private static final String FACES_SERVLET_REGISTRATION = "org.apache.myfaces.FACES_SERVLET_REGISTRATION";
- private static final String SERVLET_REGISTRATIONS = "org.apache.myfaces.SERVLET_REGISTRATIONS";
-
- private static final String CURRENT_REQUEST_FACES_SERVLET = "org.apache.myfaces.CURRENT_FACES_SERVLET_MAPPING";
-
- /**
- * Wrapper for better performance
- */
- public static class ServletRegistrationInfo
- {
- private String className;
- private String[] mappings;
- private boolean facesServlet;
- private ServletRegistration registration;
-
- public ServletRegistrationInfo(ServletRegistration registration, boolean facesServlet)
- {
- this.className = registration.getClassName();
- this.facesServlet = facesServlet;
- this.registration = registration;
-
- Collection<String> mappingsCollection = registration.getMappings();
- mappings = mappingsCollection.toArray(new String[mappingsCollection.size()]);
- if (mappings == null)
- {
- mappings = new String[]{ };
- }
- }
-
- public String getClassName()
- {
- return className;
- }
-
- public String[] getMappings()
- {
- return mappings;
- }
-
- public boolean isFacesServlet()
- {
- return facesServlet;
- }
-
- public ServletRegistration getRegistration()
- {
- return registration;
- }
- }
-
- public static FacesServletMapping getCurrentRequestFacesServletMapping(FacesContext context)
- {
- Map<Object, Object> attributes = context.getAttributes();
-
- // Has the mapping already been determined during this request?
- FacesServletMapping mapping = (FacesServletMapping) attributes.get(CURRENT_REQUEST_FACES_SERVLET);
- if (mapping == null)
- {
- ExternalContext externalContext = context.getExternalContext();
- mapping = calculateFacesServletMapping(
- context,
- externalContext.getRequestServletPath(),
- externalContext.getRequestPathInfo(),
- true);
-
- attributes.put(CURRENT_REQUEST_FACES_SERVLET, mapping);
- }
- return mapping;
- }
-
- public static List<ServletRegistrationInfo> getServletRegistrations(FacesContext facesContext,
- ServletContext servletContext, boolean cache)
- {
- Map<String, Object> applicationMap = facesContext.getExternalContext().getApplicationMap();
-
- List<ServletRegistrationInfo> infos =
- (List<ServletRegistrationInfo>) applicationMap.get(SERVLET_REGISTRATIONS);
- if (infos == null)
- {
- infos = new ArrayList<>();
-
- Map<String, ? extends ServletRegistration> registrations = servletContext.getServletRegistrations();
- if (registrations != null)
- {
- for (ServletRegistration servletRegistration : registrations.values())
- {
- ServletRegistrationInfo info = new ServletRegistrationInfo(servletRegistration,
- isFacesServlet(facesContext, servletRegistration.getClassName()));
-
- infos.add(info);
- }
- }
-
- infos = Collections.unmodifiableList(infos);
- if (cache)
- {
- applicationMap.put(SERVLET_REGISTRATIONS, infos);
- }
- }
-
- return infos;
- }
-
- public static ServletRegistrationInfo getFacesServletRegistration(FacesContext facesContext,
- ServletContext servletContext, boolean cache)
- {
- Map<String, Object> applicationMap = facesContext.getExternalContext().getApplicationMap();
-
- ServletRegistrationInfo facesServletRegistration = (ServletRegistrationInfo)
- applicationMap.get(FACES_SERVLET_REGISTRATION);
- if (facesServletRegistration == null)
- {
- for (ServletRegistrationInfo info : getServletRegistrations(facesContext, servletContext, cache))
- {
- if (info.isFacesServlet())
- {
- facesServletRegistration = info;
- break;
- }
- }
-
- if (facesServletRegistration != null && cache)
- {
- applicationMap.put(FACES_SERVLET_REGISTRATION, facesServletRegistration);
- }
- }
-
- return facesServletRegistration;
- }
-
- public static boolean isFacesServlet(FacesContext facesContext, String servletClassName)
- {
- // shortcut to avoid class lookup
- if (FacesServlet.class.getName().equals(servletClassName))
- {
- return true;
- }
-
- Class servletClass = ClassUtils.simpleClassForName(servletClassName, false);
- if (servletClass != null)
- {
- MyfacesConfig config = MyfacesConfig.getCurrentInstance(facesContext.getExternalContext());
-
- return FacesServlet.class.isAssignableFrom(servletClass)
- || DelegatedFacesServlet.class.isAssignableFrom(servletClass)
- || servletClass.getName().equals(config.getDelegateFacesServlet());
- }
- return false;
- }
-
-
-
-
-
- public static FacesServletMapping calculateFacesServletMapping(
- FacesContext facesContext, String servletPath, String pathInfo, boolean allowExactMapping)
- {
- if (ExternalContextUtils.isPortlet(facesContext.getExternalContext()))
- {
- return calculateFacesServletMapping(servletPath, pathInfo);
- }
- else
- {
- Object context = facesContext.getExternalContext().getContext();
- if (context instanceof ServletContext)
- {
- if (pathInfo != null)
- {
- // If there is a "extra path", it's definitely no extension mapping.
- // Now we just have to determine the path which has been specified
- // in the url-pattern, but that's easy as it's the same as the
- // current servletPath. It doesn't even matter if "/*" has been used
- // as in this case the servletPath is just an empty string according
- // to the Servlet Specification (SRV 4.4).
- return createMappingFromServletRegistration(facesContext,
- (ServletContext)context, servletPath, pathInfo, allowExactMapping);
- }
- else
- {
- // In the case of extension mapping, no "extra path" is available.
- // Still it's possible that prefix-based mapping has been used.
- // Actually, if there was an exact match no "extra path"
- // is available (e.g. if the url-pattern is "/faces/*"
- // and the request-uri is "/context/faces").
- String extension = extractExtensionFromUrl(servletPath);
- if (extension != null)
- {
- return FacesServletMapping.createExtensionMapping(extension);
- }
- else
- {
- // There is no extension in the given servletPath and therefore
- // we assume that it's an exact match using prefix-based mapping.
- return createMappingFromServletRegistration(facesContext,
- (ServletContext)context, servletPath, pathInfo, allowExactMapping);
- }
- }
- }
- else
- {
- return calculateFacesServletMapping(servletPath, pathInfo);
- }
- }
- }
-
- private static FacesServletMapping createMappingFromServletRegistration(FacesContext facesContext,
- ServletContext servletContext, String servletPath, String pathInfo, boolean allowExactMatch)
- {
- try
- {
- List<ServletRegistrationInfo> servletRegistrations =
- getServletRegistrations(facesContext, servletContext, true);
- if (servletRegistrations != null)
- {
- FacesServletMapping facesExtensionMapping = null;
- FacesServletMapping facesPrefixMapping = null;
- FacesServletMapping facesExactMapping = null;
-
- for (ServletRegistrationInfo servletRegistration : servletRegistrations)
- {
- try
- {
- if (servletRegistration.isFacesServlet())
- {
- for (String mapping : servletRegistration.getMappings())
- {
- if (isExtensionMapping(mapping))
- {
- facesExtensionMapping = FacesServletMapping.createExtensionMapping(
- extractExtension(mapping));
- }
- else if (isPrefixMapping(mapping))
- {
- facesPrefixMapping = FacesServletMapping.createPrefixMapping(
- extractPrefix(mapping));
- }
- else if (allowExactMatch && mapping.startsWith("/") && mapping.equals(servletPath))
- {
- facesExactMapping = FacesServletMapping.createExactMapping(servletPath);
- }
- }
- }
- else
- {
- //This is not a FacesServlet mapping.
- //It could be a non-faces request, we need to look for exact mapping to servletPath
- //this happens with richfaces resources
- for (String mapping : servletRegistration.getMappings())
- {
- if (mapping.startsWith("/") && mapping.endsWith("/*"))
- {
- mapping = mapping.substring(0, mapping.length()-2);
- }
- if (mapping.equals(servletPath))
- {
- return FacesServletMapping.createPrefixMapping(mapping);
- }
- }
- }
- }
- catch (Exception ex)
- {
- //No op
- }
- }
-
- // Choose exact mapping if preferred.
- if (allowExactMatch && facesExactMapping != null)
- {
- return facesExactMapping;
- }
- else if (facesPrefixMapping != null)
- {
- return facesPrefixMapping;
- }
- else if (facesExtensionMapping != null)
- {
- return facesExtensionMapping;
- }
- else
- {
- return FacesServletMapping.createPrefixMapping(servletPath);
- }
- }
- else
- {
- return FacesServletMapping.createPrefixMapping(servletPath);
- }
- }
- catch(Exception ex)
- {
- return FacesServletMapping.createPrefixMapping(servletPath);
- }
- }
-
- /**
- * Determines the mapping of the FacesServlet in the web.xml configuration
- * file. However, there is no need to actually parse this configuration file
- * as runtime information is sufficient.
- *
- * @param servletPath The servletPath of the current request
- * @param pathInfo The pathInfo of the current request
- * @return the mapping of the FacesServlet in the web.xml configuration file
- */
- private static FacesServletMapping calculateFacesServletMapping(String servletPath, String pathInfo)
- {
- if (pathInfo != null)
- {
- // If there is a "extra path", it's definitely no extension mapping.
- // Now we just have to determine the path which has been specified
- // in the url-pattern, but that's easy as it's the same as the
- // current servletPath. It doesn't even matter if "/*" has been used
- // as in this case the servletPath is just an empty string according
- // to the Servlet Specification (SRV 4.4).
- return FacesServletMapping.createPrefixMapping(servletPath);
- }
- else
- {
- // In the case of extension mapping, no "extra path" is available.
- // Still it's possible that prefix-based mapping has been used.
- // Actually, if there was an exact match no "extra path"
- // is available (e.g. if the url-pattern is "/faces/*"
- // and the request-uri is "/context/faces").
- String extension = extractExtensionFromUrl(servletPath);
- if (extension != null)
- {
- return FacesServletMapping.createExtensionMapping(extension);
- }
- else
- {
- // There is no extension in the given servletPath and therefore
- // we assume that it's an exact match using prefix-based mapping.
- return FacesServletMapping.createExactMapping(servletPath);
- }
- }
- }
-
- public static FacesServletMapping getExactMapping(FacesContext facesContext, String prefixedExactMappingViewId)
- {
- if (!ExternalContextUtils.isPortlet(facesContext.getExternalContext()))
- {
- Object context = facesContext.getExternalContext().getContext();
- if (context instanceof ServletContext)
- {
- ServletRegistrationInfo facesServletRegistration =
- getFacesServletRegistration(facesContext, (ServletContext) context, true);
- if (facesServletRegistration != null)
- {
- for (String mapping : facesServletRegistration.getMappings())
- {
- if (!mapping.contains("*") && prefixedExactMappingViewId.equals(mapping))
- {
- return FacesServletMapping.createExactMapping(prefixedExactMappingViewId);
- }
- }
- }
- }
- }
-
- return null;
- }
-
-
- public static FacesServletMapping getGenericPrefixOrSuffixMapping(FacesContext facesContext)
- {
- if (!ExternalContextUtils.isPortlet(facesContext.getExternalContext()))
- {
- Object context = facesContext.getExternalContext().getContext();
- if (context instanceof ServletContext)
- {
- ServletRegistrationInfo facesServletRegistration =
- getFacesServletRegistration(facesContext, (ServletContext) context, true);
- if (facesServletRegistration != null)
- {
- for (String mapping : facesServletRegistration.getMappings())
- {
- if (isExtensionMapping(mapping))
- {
- String extension = extractExtension(mapping);
- return FacesServletMapping.createExtensionMapping(extension);
- }
- else if (isPrefixMapping(mapping))
- {
- String prefix = extractPrefix(mapping);
- return FacesServletMapping.createPrefixMapping(prefix);
- }
- }
- }
- }
- }
-
- return null;
- }
-
-
-
- private static String extractExtensionFromUrl(String url)
- {
- int slashPos = url.lastIndexOf('/');
- int extensionPos = url.lastIndexOf('.');
- if (extensionPos > -1 && extensionPos > slashPos)
- {
- return url.substring(extensionPos);
- }
-
- return null;
- }
-
- private static boolean isExtensionMapping(String mapping)
- {
- return mapping.startsWith("*.");
- }
-
- private static String extractExtension(String mapping)
- {
- return mapping.substring(1);
- }
-
- private static boolean isPrefixMapping(String mapping)
- {
- return mapping.startsWith("/") && mapping.endsWith("/*");
- }
-
- private static String extractPrefix(String mapping)
- {
- return mapping.substring(0, mapping.length() - 2);
- }
-}
+/*
+ * 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.shared.application;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+import javax.faces.webapp.FacesServlet;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletRegistration;
+import org.apache.myfaces.shared.config.MyfacesConfig;
+import org.apache.myfaces.shared.context.StartupFacesContext;
+import org.apache.myfaces.shared.util.ClassUtils;
+import org.apache.myfaces.shared.util.ExternalContextUtils;
+import org.apache.myfaces.shared.webapp.webxml.DelegatedFacesServlet;
+
+public class FacesServletMappingUtils
+{
+ private static final String FACES_SERVLET_REGISTRATION = "org.apache.myfaces.FACES_SERVLET_REGISTRATION";
+ private static final String SERVLET_REGISTRATIONS = "org.apache.myfaces.SERVLET_REGISTRATIONS";
+
+ private static final String CURRENT_REQUEST_FACES_SERVLET = "org.apache.myfaces.CURRENT_FACES_SERVLET_MAPPING";
+
+ /**
+ * Wrapper for better performance
+ */
+ public static class ServletRegistrationInfo
+ {
+ private String className;
+ private String[] mappings;
+ private boolean facesServlet;
+ private ServletRegistration registration;
+
+ public ServletRegistrationInfo(ServletRegistration registration, boolean facesServlet)
+ {
+ this.className = registration.getClassName();
+ this.facesServlet = facesServlet;
+ this.registration = registration;
+
+ Collection<String> mappingsCollection = registration.getMappings();
+ mappings = mappingsCollection.toArray(new String[mappingsCollection.size()]);
+ if (mappings == null)
+ {
+ mappings = new String[]{ };
+ }
+ }
+
+ public String getClassName()
+ {
+ return className;
+ }
+
+ public String[] getMappings()
+ {
+ return mappings;
+ }
+
+ public boolean isFacesServlet()
+ {
+ return facesServlet;
+ }
+
+ public ServletRegistration getRegistration()
+ {
+ return registration;
+ }
+ }
+
+ public static FacesServletMapping getCurrentRequestFacesServletMapping(FacesContext context)
+ {
+ Map<Object, Object> attributes = context.getAttributes();
+
+ // Has the mapping already been determined during this request?
+ FacesServletMapping mapping = (FacesServletMapping) attributes.get(CURRENT_REQUEST_FACES_SERVLET);
+ if (mapping == null)
+ {
+ ExternalContext externalContext = context.getExternalContext();
+ mapping = calculateFacesServletMapping(
+ context,
+ externalContext.getRequestServletPath(),
+ externalContext.getRequestPathInfo(),
+ true);
+
+ attributes.put(CURRENT_REQUEST_FACES_SERVLET, mapping);
+ }
+ return mapping;
+ }
+
+ public static List<ServletRegistrationInfo> getServletRegistrations(FacesContext facesContext,
+ ServletContext servletContext)
+ {
+ Map<String, Object> applicationMap = facesContext.getExternalContext().getApplicationMap();
+
+ List<ServletRegistrationInfo> infos =
+ (List<ServletRegistrationInfo>) applicationMap.get(SERVLET_REGISTRATIONS);
+ if (infos == null)
+ {
+ infos = new ArrayList<>();
+
+ Map<String, ? extends ServletRegistration> registrations = servletContext.getServletRegistrations();
+ if (registrations != null)
+ {
+ for (ServletRegistration servletRegistration : registrations.values())
+ {
+ ServletRegistrationInfo info = new ServletRegistrationInfo(servletRegistration,
+ isFacesServlet(facesContext, servletRegistration.getClassName()));
+
+ infos.add(info);
+ }
+ }
+
+ infos = Collections.unmodifiableList(infos);
+ if (!(facesContext instanceof StartupFacesContext))
+ {
+ applicationMap.put(SERVLET_REGISTRATIONS, infos);
+ }
+ }
+
+ return infos;
+ }
+
+ public static ServletRegistrationInfo getFacesServletRegistration(FacesContext facesContext,
+ ServletContext servletContext)
+ {
+ Map<String, Object> applicationMap = facesContext.getExternalContext().getApplicationMap();
+
+ ServletRegistrationInfo facesServletRegistration = (ServletRegistrationInfo)
+ applicationMap.get(FACES_SERVLET_REGISTRATION);
+ if (facesServletRegistration == null)
+ {
+ for (ServletRegistrationInfo info : getServletRegistrations(facesContext, servletContext))
+ {
+ if (info.isFacesServlet())
+ {
+ facesServletRegistration = info;
+ break;
+ }
+ }
+
+ if (facesServletRegistration != null && !(facesContext instanceof StartupFacesContext))
+ {
+ applicationMap.put(FACES_SERVLET_REGISTRATION, facesServletRegistration);
+ }
+ }
+
+ return facesServletRegistration;
+ }
+
+ public static boolean isFacesServlet(FacesContext facesContext, String servletClassName)
+ {
+ // shortcut to avoid class lookup
+ if (FacesServlet.class.getName().equals(servletClassName))
+ {
+ return true;
+ }
+
+ Class servletClass = ClassUtils.simpleClassForName(servletClassName, false);
+ if (servletClass != null)
+ {
+ MyfacesConfig config = MyfacesConfig.getCurrentInstance(facesContext.getExternalContext());
+
+ return FacesServlet.class.isAssignableFrom(servletClass)
+ || DelegatedFacesServlet.class.isAssignableFrom(servletClass)
+ || servletClass.getName().equals(config.getDelegateFacesServlet());
+ }
+ return false;
+ }
+
+
+
+
+
+ public static FacesServletMapping calculateFacesServletMapping(
+ FacesContext facesContext, String servletPath, String pathInfo, boolean allowExactMapping)
+ {
+ if (ExternalContextUtils.isPortlet(facesContext.getExternalContext()))
+ {
+ return calculateFacesServletMapping(servletPath, pathInfo);
+ }
+ else
+ {
+ Object context = facesContext.getExternalContext().getContext();
+ if (context instanceof ServletContext)
+ {
+ if (pathInfo != null)
+ {
+ // If there is a "extra path", it's definitely no extension mapping.
+ // Now we just have to determine the path which has been specified
+ // in the url-pattern, but that's easy as it's the same as the
+ // current servletPath. It doesn't even matter if "/*" has been used
+ // as in this case the servletPath is just an empty string according
+ // to the Servlet Specification (SRV 4.4).
+ return createMappingFromServletRegistration(facesContext,
+ (ServletContext)context, servletPath, pathInfo, allowExactMapping);
+ }
+ else
+ {
+ // In the case of extension mapping, no "extra path" is available.
+ // Still it's possible that prefix-based mapping has been used.
+ // Actually, if there was an exact match no "extra path"
+ // is available (e.g. if the url-pattern is "/faces/*"
+ // and the request-uri is "/context/faces").
+ String extension = extractExtensionFromUrl(servletPath);
+ if (extension != null)
+ {
+ return FacesServletMapping.createExtensionMapping(extension);
+ }
+ else
+ {
+ // There is no extension in the given servletPath and therefore
+ // we assume that it's an exact match using prefix-based mapping.
+ return createMappingFromServletRegistration(facesContext,
+ (ServletContext)context, servletPath, pathInfo, allowExactMapping);
+ }
+ }
+ }
+ else
+ {
+ return calculateFacesServletMapping(servletPath, pathInfo);
+ }
+ }
+ }
+
+ private static FacesServletMapping createMappingFromServletRegistration(FacesContext facesContext,
+ ServletContext servletContext, String servletPath, String pathInfo, boolean allowExactMatch)
+ {
+ try
+ {
+ List<ServletRegistrationInfo> servletRegistrations =
+ getServletRegistrations(facesContext, servletContext);
+ if (servletRegistrations != null)
+ {
+ FacesServletMapping facesExtensionMapping = null;
+ FacesServletMapping facesPrefixMapping = null;
+ FacesServletMapping facesExactMapping = null;
+
+ for (ServletRegistrationInfo servletRegistration : servletRegistrations)
+ {
+ try
+ {
+ if (servletRegistration.isFacesServlet())
+ {
+ for (String mapping : servletRegistration.getMappings())
+ {
+ if (isExtensionMapping(mapping))
+ {
+ facesExtensionMapping = FacesServletMapping.createExtensionMapping(
+ extractExtension(mapping));
+ }
+ else if (isPrefixMapping(mapping))
+ {
+ facesPrefixMapping = FacesServletMapping.createPrefixMapping(
+ extractPrefix(mapping));
+ }
+ else if (allowExactMatch && mapping.startsWith("/") && mapping.equals(servletPath))
+ {
+ facesExactMapping = FacesServletMapping.createExactMapping(servletPath);
+ }
+ }
+ }
+ else
+ {
+ //This is not a FacesServlet mapping.
+ //It could be a non-faces request, we need to look for exact mapping to servletPath
+ //this happens with richfaces resources
+ for (String mapping : servletRegistration.getMappings())
+ {
+ if (mapping.startsWith("/") && mapping.endsWith("/*"))
+ {
+ mapping = mapping.substring(0, mapping.length()-2);
+ }
+ if (mapping.equals(servletPath))
+ {
+ return FacesServletMapping.createPrefixMapping(mapping);
+ }
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ //No op
+ }
+ }
+
+ // Choose exact mapping if preferred.
+ if (allowExactMatch && facesExactMapping != null)
+ {
+ return facesExactMapping;
+ }
+ else if (facesPrefixMapping != null)
+ {
+ return facesPrefixMapping;
+ }
+ else if (facesExtensionMapping != null)
+ {
+ return facesExtensionMapping;
+ }
+ else
+ {
+ return FacesServletMapping.createPrefixMapping(servletPath);
+ }
+ }
+ else
+ {
+ return FacesServletMapping.createPrefixMapping(servletPath);
+ }
+ }
+ catch(Exception ex)
+ {
+ return FacesServletMapping.createPrefixMapping(servletPath);
+ }
+ }
+
+ /**
+ * Determines the mapping of the FacesServlet in the web.xml configuration
+ * file. However, there is no need to actually parse this configuration file
+ * as runtime information is sufficient.
+ *
+ * @param servletPath The servletPath of the current request
+ * @param pathInfo The pathInfo of the current request
+ * @return the mapping of the FacesServlet in the web.xml configuration file
+ */
+ private static FacesServletMapping calculateFacesServletMapping(String servletPath, String pathInfo)
+ {
+ if (pathInfo != null)
+ {
+ // If there is a "extra path", it's definitely no extension mapping.
+ // Now we just have to determine the path which has been specified
+ // in the url-pattern, but that's easy as it's the same as the
+ // current servletPath. It doesn't even matter if "/*" has been used
+ // as in this case the servletPath is just an empty string according
+ // to the Servlet Specification (SRV 4.4).
+ return FacesServletMapping.createPrefixMapping(servletPath);
+ }
+ else
+ {
+ // In the case of extension mapping, no "extra path" is available.
+ // Still it's possible that prefix-based mapping has been used.
+ // Actually, if there was an exact match no "extra path"
+ // is available (e.g. if the url-pattern is "/faces/*"
+ // and the request-uri is "/context/faces").
+ String extension = extractExtensionFromUrl(servletPath);
+ if (extension != null)
+ {
+ return FacesServletMapping.createExtensionMapping(extension);
+ }
+ else
+ {
+ // There is no extension in the given servletPath and therefore
+ // we assume that it's an exact match using prefix-based mapping.
+ return FacesServletMapping.createExactMapping(servletPath);
+ }
+ }
+ }
+
+ public static FacesServletMapping getExactMapping(FacesContext facesContext, String prefixedExactMappingViewId)
+ {
+ if (!ExternalContextUtils.isPortlet(facesContext.getExternalContext()))
+ {
+ Object context = facesContext.getExternalContext().getContext();
+ if (context instanceof ServletContext)
+ {
+ ServletRegistrationInfo facesServletRegistration =
+ getFacesServletRegistration(facesContext, (ServletContext) context);
+ if (facesServletRegistration != null)
+ {
+ for (String mapping : facesServletRegistration.getMappings())
+ {
+ if (!mapping.contains("*") && prefixedExactMappingViewId.equals(mapping))
+ {
+ return FacesServletMapping.createExactMapping(prefixedExactMappingViewId);
+ }
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+
+ public static FacesServletMapping getGenericPrefixOrSuffixMapping(FacesContext facesContext)
+ {
+ if (!ExternalContextUtils.isPortlet(facesContext.getExternalContext()))
+ {
+ Object context = facesContext.getExternalContext().getContext();
+ if (context instanceof ServletContext)
+ {
+ ServletRegistrationInfo facesServletRegistration =
+ getFacesServletRegistration(facesContext, (ServletContext) context);
+ if (facesServletRegistration != null)
+ {
+ for (String mapping : facesServletRegistration.getMappings())
+ {
+ if (isExtensionMapping(mapping))
+ {
+ String extension = extractExtension(mapping);
+ return FacesServletMapping.createExtensionMapping(extension);
+ }
+ else if (isPrefixMapping(mapping))
+ {
+ String prefix = extractPrefix(mapping);
+ return FacesServletMapping.createPrefixMapping(prefix);
+ }
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+
+
+ private static String extractExtensionFromUrl(String url)
+ {
+ int slashPos = url.lastIndexOf('/');
+ int extensionPos = url.lastIndexOf('.');
+ if (extensionPos > -1 && extensionPos > slashPos)
+ {
+ return url.substring(extensionPos);
+ }
+
+ return null;
+ }
+
+ private static boolean isExtensionMapping(String mapping)
+ {
+ return mapping.startsWith("*.");
+ }
+
+ private static String extractExtension(String mapping)
+ {
+ return mapping.substring(1);
+ }
+
+ private static boolean isPrefixMapping(String mapping)
+ {
+ return mapping.startsWith("/") && mapping.endsWith("/*");
+ }
+
+ private static String extractPrefix(String mapping)
+ {
+ return mapping.substring(0, mapping.length() - 2);
+ }
+}
diff --git a/shared/src/main/java/org/apache/myfaces/shared/context/StartupFacesContext.java b/shared/src/main/java/org/apache/myfaces/shared/context/StartupFacesContext.java
new file mode 100644
index 000000000..8142858d0
--- /dev/null
+++ b/shared/src/main/java/org/apache/myfaces/shared/context/StartupFacesContext.java
@@ -0,0 +1,25 @@
+/*
+ * 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.shared.context;
+
+// Hack because StartupFacesContextImpl isnt available in shared
+public interface StartupFacesContext
+{
+
+}