alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Struts example source code file (ServletUrlRenderer.java)

This example Struts source code file (ServletUrlRenderer.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Struts tags/keywords

actioninvocation, actioninvocation, actionmapping, actionmapping, form, io, ioerror, ioexception, iterator, map, map, object, string, string, strutsexception, util

The Struts ServletUrlRenderer.java source code

/*
 * $Id: ServletUrlRenderer.java 1076544 2011-03-03 07:19:37Z lukaszlenart $
 *
 * 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.struts2.components;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.config.entities.ActionConfig;
import com.opensymphony.xwork2.inject.Inject;
import com.opensymphony.xwork2.util.logging.Logger;
import com.opensymphony.xwork2.util.logging.LoggerFactory;
import org.apache.struts2.StrutsException;
import org.apache.struts2.dispatcher.mapper.ActionMapper;
import org.apache.struts2.dispatcher.mapper.ActionMapping;
import org.apache.struts2.views.util.UrlHelper;
import org.apache.commons.lang.StringUtils;

import java.io.IOException;
import java.io.Writer;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * Implementation of the {@link UrlRenderer} interface that creates URLs suitable in a servlet environment.
 * 
 */
public class ServletUrlRenderer implements UrlRenderer {
    /**
     * Provide a logging instance.
     */
    private static final Logger LOG = LoggerFactory.getLogger(ServletUrlRenderer.class);

    private ActionMapper actionMapper;

    @Inject
    public void setActionMapper(ActionMapper mapper) {
        this.actionMapper = mapper;
    }


    /**
	 * {@inheritDoc}
	 */
	public void renderUrl(Writer writer, UrlProvider urlComponent) {
		String scheme = urlComponent.getHttpServletRequest().getScheme();

		if (urlComponent.getScheme() != null) {
			scheme = urlComponent.getScheme();
		}

	       String result;
	       ActionInvocation ai = (ActionInvocation) ActionContext.getContext().get(ActionContext.ACTION_INVOCATION);
	        if (urlComponent.getValue() == null && urlComponent.getAction() != null) {
	                result = urlComponent.determineActionURL(urlComponent.getAction(), urlComponent.getNamespace(), urlComponent.getMethod(), urlComponent.getHttpServletRequest(), urlComponent.getHttpServletResponse(), urlComponent.getParameters(), scheme, urlComponent.isIncludeContext(), urlComponent.isEncode(), urlComponent.isForceAddSchemeHostAndPort(), urlComponent.isEscapeAmp());
	        } else if (urlComponent.getValue() == null && urlComponent.getAction() == null && ai != null) {
	                // both are null, we will default to the current action

	                final String action = ai.getProxy().getActionName();
	                final String namespace = ai.getProxy().getNamespace();
	                result = urlComponent.determineActionURL(action, namespace, urlComponent.getMethod(),urlComponent.getHttpServletRequest(), urlComponent.getHttpServletResponse(), urlComponent.getParameters(), scheme, urlComponent.isIncludeContext(), urlComponent.isEncode(), urlComponent.isForceAddSchemeHostAndPort(), urlComponent.isEscapeAmp());
	        } else {
	                String _value = urlComponent.getValue();

	                // We don't include the request parameters cause they would have been
	                // prioritised before this [in start(Writer) method]
	                if (_value != null && _value.indexOf("?") > 0) {
	                    _value = _value.substring(0, _value.indexOf("?"));
	                }
	                result = UrlHelper.buildUrl(_value, urlComponent.getHttpServletRequest(), urlComponent.getHttpServletResponse(), urlComponent.getParameters(), scheme, urlComponent.isIncludeContext(), urlComponent.isEncode(), urlComponent.isForceAddSchemeHostAndPort(), urlComponent.isEscapeAmp());
	        }
            String anchor = urlComponent.getAnchor();
	        if (StringUtils.isNotEmpty(anchor)) {
	        	result += '#' + urlComponent.findString(anchor);
	        }

        if (urlComponent.isPutInContext()) {
            String var = urlComponent.getVar();
            if (StringUtils.isNotEmpty(var)) {
                urlComponent.putInContext(result);

                // add to the request and page scopes as well
                urlComponent.getHttpServletRequest().setAttribute(var, result);
            } else {
                try {
                    writer.write(result);
                } catch (IOException e) {
                    throw new StrutsException("IOError: " + e.getMessage(), e);
                }
            }
        } else {
            try {
                writer.write(result);
            } catch (IOException e) {
                throw new StrutsException("IOError: " + e.getMessage(), e);
            }
        }
	}

	/**
	 * {@inheritDoc}
	 */
	public void renderFormUrl(Form formComponent) {
		String namespace = formComponent.determineNamespace(formComponent.namespace, formComponent.getStack(),
				formComponent.request);
		String action;

		if(formComponent.action != null) {
			action = formComponent.findString(formComponent.action);
		} else {
			// no action supplied? ok, then default to the current request
			// (action or general URL)
			ActionInvocation ai = (ActionInvocation) formComponent.getStack().getContext().get(
					ActionContext.ACTION_INVOCATION);
			if (ai != null) {
				action = ai.getProxy().getActionName();
				namespace = ai.getProxy().getNamespace();
			} else {
				// hmm, ok, we need to just assume the current URL cut down
				String uri = formComponent.request.getRequestURI();
				action = uri.substring(uri.lastIndexOf('/'));
			}
		}

        ActionMapping nameMapping = actionMapper.getMappingFromActionName(action);
        String actionName = nameMapping.getName();
        String actionMethod = nameMapping.getMethod();

		final ActionConfig actionConfig = formComponent.configuration.getRuntimeConfiguration().getActionConfig(
				namespace, actionName);
		if (actionConfig != null) {

			ActionMapping mapping = new ActionMapping(actionName, namespace, actionMethod, formComponent.parameters);
			String result = UrlHelper.buildUrl(formComponent.actionMapper.getUriFromActionMapping(mapping),
					formComponent.request, formComponent.response, null, null, formComponent.includeContext, true);
			formComponent.addParameter("action", result);

			// let's try to get the actual action class and name
			// this can be used for getting the list of validators
			formComponent.addParameter("actionName", actionName);
			try {
				Class clazz = formComponent.objectFactory.getClassInstance(actionConfig.getClassName());
				formComponent.addParameter("actionClass", clazz);
			} catch (ClassNotFoundException e) {
				// this is OK, we'll just move on
			}

			formComponent.addParameter("namespace", namespace);

			// if the name isn't specified, use the action name
			if (formComponent.name == null) {
				formComponent.addParameter("name", actionName);
			}

			// if the id isn't specified, use the action name
			if (formComponent.getId() == null  && actionName!=null ) {
				formComponent.addParameter("id", formComponent.escape(actionName));
			}
		} else if (action != null) {
			// Since we can't find an action alias in the configuration, we just
			// assume the action attribute supplied is the path to be used as
			// the URI this form is submitting to.

            // Warn user that the specified namespace/action combo
            // was not found in the configuration.
            if (namespace != null) {
              LOG.warn("No configuration found for the specified action: '" + actionName + "' in namespace: '" + namespace + "'. Form action defaulting to 'action' attribute's literal value.");
            }

			String result = UrlHelper.buildUrl(action, formComponent.request, formComponent.response, null, null, formComponent.includeContext, true);
			formComponent.addParameter("action", result);

			// namespace: cut out anything between the start and the last /
			int slash = result.lastIndexOf('/');
			if (slash != -1) {
				formComponent.addParameter("namespace", result.substring(0, slash));
			} else {
				formComponent.addParameter("namespace", "");
			}

			// name/id: cut out anything between / and . should be the id and
			// name
			String id = formComponent.getId();
			if (id == null) {
				slash = result.lastIndexOf('/');
				int dot = result.indexOf('.', slash);
				if (dot != -1) {
					id = result.substring(slash + 1, dot);
				} else {
					id = result.substring(slash + 1);
				}
				formComponent.addParameter("id", formComponent.escape(id));
			}
		}

		// WW-1284
		// evaluate if client-side js is to be enabled. (if validation
		// interceptor does allow validation eg. method is not filtered out)
		formComponent.evaluateClientSideJsEnablement(actionName, namespace, actionMethod);
	}


	public void beforeRenderUrl(UrlProvider urlComponent) {
		if (urlComponent.getValue() != null) {
            urlComponent.setValue(urlComponent.findString(urlComponent.getValue()));
        }

        // no explicit url set so attach params from current url, do
        // this at start so body params can override any of these they wish.
        try {
            // ww-1266
            String includeParams = (urlComponent.getUrlIncludeParams() != null ? urlComponent.getUrlIncludeParams().toLowerCase() : UrlProvider.GET);

            if (urlComponent.getIncludeParams() != null) {
                includeParams = urlComponent.findString(urlComponent.getIncludeParams());
            }

            if (UrlProvider.NONE.equalsIgnoreCase(includeParams)) {
                mergeRequestParameters(urlComponent.getValue(), urlComponent.getParameters(), Collections.EMPTY_MAP);
            } else if (UrlProvider.ALL.equalsIgnoreCase(includeParams)) {
                mergeRequestParameters(urlComponent.getValue(), urlComponent.getParameters(), urlComponent.getHttpServletRequest().getParameterMap());

                // for ALL also include GET parameters
                includeGetParameters(urlComponent);
                includeExtraParameters(urlComponent);
            } else if (UrlProvider.GET.equalsIgnoreCase(includeParams) || (includeParams == null && urlComponent.getValue() == null && urlComponent.getAction() == null)) {
                includeGetParameters(urlComponent);
                includeExtraParameters(urlComponent);
            } else if (includeParams != null) {
                LOG.warn("Unknown value for includeParams parameter to URL tag: " + includeParams);
            }
        } catch (Exception e) {
            LOG.warn("Unable to put request parameters (" + urlComponent.getHttpServletRequest().getQueryString() + ") into parameter map.", e);
        }

		
	}
	
    private void includeExtraParameters(UrlProvider urlComponent) {
        if (urlComponent.getExtraParameterProvider() != null) {
            mergeRequestParameters(urlComponent.getValue(), urlComponent.getParameters(), urlComponent.getExtraParameterProvider().getExtraParameters());
        }
    }
    private void includeGetParameters(UrlProvider urlComponent) {
    	String query = extractQueryString(urlComponent);
    	mergeRequestParameters(urlComponent.getValue(), urlComponent.getParameters(), UrlHelper.parseQueryString(query));
    }

    private String extractQueryString(UrlProvider urlComponent) {
        // Parse the query string to make sure that the parameters come from the query, and not some posted data
        String query = urlComponent.getHttpServletRequest().getQueryString();
        if (query == null) {
            query = (String) urlComponent.getHttpServletRequest().getAttribute("javax.servlet.forward.query_string");
        }

        if (query != null) {
            // Remove possible #foobar suffix
            int idx = query.lastIndexOf('#');

            if (idx != -1) {
                query = query.substring(0, idx);
            }
        }
        return query;
    }
    
    /**
     * Merge request parameters into current parameters. If a parameter is
     * already present, than the request parameter in the current request and value atrribute
     * will not override its value.
     *
     * The priority is as follows:-
     * <ul>
     *  <li>parameter from the current request (least priority)
     *  <li>parameter form the value attribute (more priority)
     *  <li>parameter from the param tag (most priority)
     * </ul>
     *
     * @param value the value attribute (url to be generated by this component)
     * @param parameters component parameters
     * @param contextParameters request parameters
     */
    protected void mergeRequestParameters(String value, Map parameters, Map contextParameters){

        Map mergedParams = new LinkedHashMap(contextParameters);

        // Merge contextParameters (from current request) with parameters specified in value attribute
        // eg. value="someAction.action?id=someId&venue=someVenue"
        // where the parameters specified in value attribute takes priority.

        if (value != null && value.trim().length() > 0 && value.indexOf("?") > 0) {
            String queryString = value.substring(value.indexOf("?")+1);

            mergedParams = UrlHelper.parseQueryString(queryString);
            for (Iterator iterator = contextParameters.entrySet().iterator(); iterator.hasNext();) {
                Map.Entry entry = (Map.Entry) iterator.next();
                Object key = entry.getKey();

                if (!mergedParams.containsKey(key)) {
                    mergedParams.put(key, entry.getValue());
                }
            }
        }


        // Merge parameters specified in value attribute
        // eg. value="someAction.action?id=someId&venue=someVenue"
        // with parameters specified though param tag
        // eg. <param name="id" value="%{'someId'}" />
        // where parameters specified through param tag takes priority.

        for (Iterator iterator = mergedParams.entrySet().iterator(); iterator.hasNext();) {
            Map.Entry entry = (Map.Entry) iterator.next();
            Object key = entry.getKey();

            if (!parameters.containsKey(key)) {
                parameters.put(key, entry.getValue());
            }
        }
    }
}

Other Struts examples (source code examples)

Here is a short list of links related to this Struts ServletUrlRenderer.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.