JdbcMapper/beehive-netui-tags/src/main/java/org/apache/beehive/netui/tags/internal/PageFlowTagUtils.java

243 lines
11 KiB
Java

/*
* 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.
*
* $Header:$
*/
package org.apache.beehive.netui.tags.internal;
import org.apache.beehive.netui.core.urls.URLType;
import org.apache.beehive.netui.pageflow.FlowController;
import org.apache.beehive.netui.pageflow.PageFlowConstants;
import org.apache.beehive.netui.pageflow.PageFlowUtils;
import org.apache.beehive.netui.pageflow.config.PageFlowActionMapping;
import org.apache.beehive.netui.pageflow.internal.InternalConstants;
import org.apache.beehive.netui.tags.rendering.TagRenderingBase;
import org.apache.struts.Globals;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.config.ActionConfig;
import org.apache.struts.util.TokenProcessor;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.jsp.PageContext;
import java.net.URISyntaxException;
import java.util.Map;
/**
* This is a utility class for the beehive tags with routines for helping with URL rewriting.
*
* <p> Includes methods to create a fully-rewritten url based on an initial url with query
* parameters and an anchor (location on page), checking if it needs to be secure and
* rewriting. There's also a method to check if a url is an action. </p>
*/
public class PageFlowTagUtils
{
/**
* Create a fully-rewritten url from an initial action url with query parameters
* and an anchor (location on page), checking if it needs to be secure then call
* the rewriter service using a type of {@link org.apache.beehive.netui.core.urls.URLType#ACTION}.
* @param pageContext the current PageContext.
* @param action the action url to rewrite.
* @param params the query parameters for this url.
* @param location the location (anchor or fragment) for this url.
* @return a uri that has been run through the URL rewriter service.
*/
public static String rewriteActionURL(PageContext pageContext, String action, Map params, String location)
throws URISyntaxException
{
ServletContext servletContext = pageContext.getServletContext();
HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
HttpServletResponse response = (HttpServletResponse) pageContext.getResponse();
boolean forXML = TagRenderingBase.Factory.isXHTML(request);
if (action.length() > 0 && action.charAt(0) == '/') action = action.substring(1);
return PageFlowUtils.getRewrittenActionURI(servletContext, request, response, action, params, location, forXML);
}
/**
* Create a fully-rewritten url from an initial href url with query parameters
* and an anchor (location on page), checking if it needs to be secure then call
* the rewriter service using a type of {@link org.apache.beehive.netui.core.urls.URLType#ACTION}.
* @param pageContext the current PageContext.
* @param url the href url to rewrite.
* @param params the query parameters for this url.
* @param location the location (anchor or fragment) for this url.
* @return a url that has been run through the URL rewriter service.
* @see PageFlowUtils#getRewrittenHrefURI(javax.servlet.ServletContext, javax.servlet.http.HttpServletRequest,
* javax.servlet.http.HttpServletResponse, String, java.util.Map, String, boolean)
*/
public static String rewriteHrefURL(PageContext pageContext, String url, Map params, String location)
throws URISyntaxException
{
ServletContext servletContext = pageContext.getServletContext();
HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
HttpServletResponse response = (HttpServletResponse) pageContext.getResponse();
boolean forXML = TagRenderingBase.Factory.isXHTML(request);
return PageFlowUtils.getRewrittenHrefURI(servletContext, request, response, url, params, location, forXML);
}
/**
* Create a fully-rewritten url from an initial resource url with query parameters
* and an anchor (location on page), checking if it needs to be secure then call
* the rewriter service using a type of {@link org.apache.beehive.netui.core.urls.URLType#RESOURCE}.
* @param pageContext the current PageContext.
* @param url the resource url to rewrite.
* @param params the query parameters for this url.
* @param location the location (anchor or fragment) for this url.
* @return a url that has been run through the URL rewriter service.
* @see PageFlowUtils#getRewrittenResourceURI(javax.servlet.ServletContext, javax.servlet.http.HttpServletRequest,
* javax.servlet.http.HttpServletResponse, String, java.util.Map, String, boolean)
*/
public static String rewriteResourceURL(PageContext pageContext, String url, Map params, String location)
throws URISyntaxException
{
ServletContext servletContext = pageContext.getServletContext();
HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
HttpServletResponse response = (HttpServletResponse) pageContext.getResponse();
boolean forXML = TagRenderingBase.Factory.isXHTML(request);
return PageFlowUtils.getRewrittenResourceURI(servletContext, request, response, url, params, location, forXML);
}
/**
* Determine whether a given URI is an Action.
* @param request the current HttpServletRequest.
* @param action the URI to check.
* @return <code>true</code> if the action is defined in the current page flow
* or in a shared flow. Otherwise, return <code>false</code>.
*/
public static boolean isAction(HttpServletRequest request, String action)
{
FlowController flowController = PageFlowUtils.getCurrentPageFlow(request);
if (flowController != null) {
if (action.endsWith(PageFlowConstants.ACTION_EXTENSION)) {
action = action.substring(0, action.length() - PageFlowConstants.ACTION_EXTENSION.length());
}
if (getActionMapping(request, flowController, action) != null) return true;
FlowController globalApp = PageFlowUtils.getSharedFlow(InternalConstants.GLOBALAPP_CLASSNAME, request);
return getActionMapping(request, globalApp, action) != null;
}
return true;
}
/**
* Get or generate a token used to prevent double submits to an action. The token is stored in the session,
* and checked (and removed) when processing an action with the <code>preventDoubleSubmit</code> attribute
* set to <code>true</code>.
*/
public static String getToken(HttpServletRequest request, String action)
{
FlowController flowController = PageFlowUtils.getCurrentPageFlow(request);
if (flowController != null) {
MappingAndController mac = getActionMapping(request, flowController, action);
if (mac != null) return getToken(request, mac.mapping);
}
return null;
}
/**
* Get or generate a token used to prevent double submits to an action. The token is stored in the session,
* and checked (and removed) when processing an action with the <code>preventDoubleSubmit</code> attribute
* set to <code>true</code>.
*/
public static String getToken(HttpServletRequest request, ActionMapping mapping)
{
if (mapping instanceof PageFlowActionMapping && ((PageFlowActionMapping) mapping).isPreventDoubleSubmit()) {
HttpSession session = request.getSession();
String token = (String) session.getAttribute(Globals.TRANSACTION_TOKEN_KEY);
if (token != null) return token;
token = TokenProcessor.getInstance().generateToken(request);
request.getSession().setAttribute(Globals.TRANSACTION_TOKEN_KEY, token);
return token;
}
return null;
}
public static class MappingAndController
{
public ActionMapping mapping;
public FlowController controller;
}
public static MappingAndController getActionMapping(HttpServletRequest request, FlowController flowController, String action)
{
ActionConfig mapping = null;
FlowController fc = null;
if (flowController != null) {
//
// If there's a '.' delimiter, it's a shared flow action.
//
int dot = action.indexOf('.');
if (dot == -1) {
//
// It's an action in the current page flow, or in the (deprecated) Global.app.
//
if (action.charAt(0) != '/') action = '/' + action;
mapping = flowController.theModuleConfig().findActionConfig(action);
fc = flowController;
//
// If we don't find it in the current page flow, look in Global.app.
//
if (mapping == null) {
FlowController globalApp =
PageFlowUtils.getSharedFlow(InternalConstants.GLOBALAPP_CLASSNAME, request);
if (globalApp != null) {
mapping = globalApp.theModuleConfig().findActionConfig(action);
fc = globalApp;
}
}
}
else if (dot < action.length() - 1) {
//
// It's an action in a shared flow.
//
String sharedFlowName = action.substring(0, dot);
if (sharedFlowName.length() > 0 && sharedFlowName.charAt(0) == '/') {
sharedFlowName = sharedFlowName.substring(1);
}
FlowController sharedFlow = (FlowController) PageFlowUtils.getSharedFlows(request).get(sharedFlowName);
if (sharedFlow != null) {
String actionPath = '/' + action.substring(dot + 1);
mapping = sharedFlow.theModuleConfig().findActionConfig(actionPath);
fc = sharedFlow;
}
}
}
assert mapping == null || mapping instanceof ActionMapping : mapping.getClass().getName();
if (mapping != null) {
MappingAndController mac = new MappingAndController();
mac.mapping = (ActionMapping) mapping;
mac.controller = fc;
return mac;
}
return null;
}
}