001/**
002 * Copyright 2005-2016 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.rice.kns.web.struts.action;
017
018import org.apache.commons.beanutils.ConvertUtils;
019import org.apache.commons.beanutils.converters.BigDecimalConverter;
020import org.apache.commons.beanutils.converters.BigIntegerConverter;
021import org.apache.commons.beanutils.converters.BooleanConverter;
022import org.apache.commons.beanutils.converters.ByteConverter;
023import org.apache.commons.beanutils.converters.CharacterConverter;
024import org.apache.commons.beanutils.converters.DoubleConverter;
025import org.apache.commons.beanutils.converters.FloatConverter;
026import org.apache.commons.beanutils.converters.IntegerConverter;
027import org.apache.commons.beanutils.converters.LongConverter;
028import org.apache.commons.beanutils.converters.ShortConverter;
029import org.apache.commons.collections.iterators.IteratorEnumeration;
030import org.apache.commons.lang.StringUtils;
031import org.apache.log4j.Logger;
032import org.apache.struts.action.ActionServlet;
033import org.kuali.rice.core.api.config.ConfigurationException;
034import org.kuali.rice.core.api.config.property.ConfigContext;
035import org.kuali.rice.core.framework.config.module.ModuleConfigurer;
036import org.kuali.rice.core.framework.config.module.WebModuleConfiguration;
037
038import java.io.IOException;
039import javax.servlet.http.HttpServletRequest;
040import javax.servlet.http.HttpServletResponse;
041import javax.servlet.ServletConfig;
042import javax.servlet.ServletContext;
043import javax.servlet.ServletException;
044import java.math.BigDecimal;
045import java.math.BigInteger;
046import java.util.Collection;
047import java.util.Enumeration;
048import java.util.HashMap;
049import java.util.Map;
050
051public class KualiActionServlet extends ActionServlet {
052    private static final Logger LOG = Logger.getLogger(KualiActionServlet.class);
053    
054    // KULRICE-8176: KFS Notes/Attachments Tab Functionality for Note Text Error - Visible/Special characters, spaces, or tabs
055    private String parameterEncoding = "";
056
057    /**
058     * <p>Initialize other global characteristics of the controller servlet.</p>
059     * Overridden to remove the ConvertUtils.deregister() command that caused problems
060     * with the concurrent data dictionary load.  (KULRNE-4405)
061     *
062     * @exception ServletException if we cannot initialize these resources
063     */
064    @Override
065        protected void initOther() throws ServletException {
066
067        String value = null;
068        value = getServletConfig().getInitParameter("config");
069        if (value != null) {
070            config = value;
071        }
072
073        // Backwards compatibility for form beans of Java wrapper classes
074        // Set to true for strict Struts 1.0 compatibility
075        value = getServletConfig().getInitParameter("convertNull");
076        if ("true".equalsIgnoreCase(value)
077            || "yes".equalsIgnoreCase(value)
078            || "on".equalsIgnoreCase(value)
079            || "y".equalsIgnoreCase(value)
080            || "1".equalsIgnoreCase(value)) {
081
082            convertNull = true;
083        }
084
085        if (convertNull) {
086            ConvertUtils.register(new BigDecimalConverter(null), BigDecimal.class);
087            ConvertUtils.register(new BigIntegerConverter(null), BigInteger.class);
088            ConvertUtils.register(new BooleanConverter(null), Boolean.class);
089            ConvertUtils.register(new ByteConverter(null), Byte.class);
090            ConvertUtils.register(new CharacterConverter(null), Character.class);
091            ConvertUtils.register(new DoubleConverter(null), Double.class);
092            ConvertUtils.register(new FloatConverter(null), Float.class);
093            ConvertUtils.register(new IntegerConverter(null), Integer.class);
094            ConvertUtils.register(new LongConverter(null), Long.class);
095            ConvertUtils.register(new ShortConverter(null), Short.class);
096        }
097
098        // KULRICE-8176: KFS Notes/Attachments Tab Functionality for Note Text Error - Visible/Special characters, spaces, or tabs
099        parameterEncoding = getServletConfig().getInitParameter("PARAMETER_ENCODING");
100    }
101
102    KualiActionServletConfig serverConfigOverride = null;
103
104    @Override
105    public ServletConfig getServletConfig() {
106        if ( serverConfigOverride == null ) {
107            ServletConfig sConfig = super.getServletConfig();
108
109            if ( sConfig == null ) {
110                return null;
111            }
112            serverConfigOverride = new KualiActionServletConfig(sConfig);
113        }
114        return serverConfigOverride;
115    }
116
117    /**
118     * A custom ServletConfig implementation which dynamically includes web content based on the installed modules in the RiceConfigurer object.
119     *   Accomplishes this by implementing custom
120     * {@link #getInitParameter(String)} and {@link #getInitParameterNames()} methods.
121     */
122    private class KualiActionServletConfig implements ServletConfig {
123
124        private ServletConfig wrapped;
125        private Map<String,String> initParameters = new HashMap<String, String>();
126
127        public KualiActionServletConfig(ServletConfig wrapped) {
128            this.wrapped = wrapped;
129            // copy out all the init parameters so they can be augmented
130            @SuppressWarnings("unchecked")
131                        final Enumeration<String> initParameterNames = wrapped.getInitParameterNames();
132            while ( initParameterNames.hasMoreElements() ) {
133                String paramName = initParameterNames.nextElement();
134                initParameters.put( paramName, wrapped.getInitParameter(paramName) );
135            }
136            // loop over the installed modules, adding their struts configuration to the servlet
137            // if they have a web interface
138                        final Collection<ModuleConfigurer> riceModules = ModuleConfigurer.getCurrentContextConfigurers();
139            
140            if ( LOG.isInfoEnabled() ) {
141                LOG.info( "Configuring init parameters of the KualiActionServlet from riceModules: " + riceModules );
142            }
143            for ( ModuleConfigurer module : riceModules ) {
144                // only install the web configuration if the module has web content
145                // and it is running in a "local" mode
146                // in "embedded" or "remote" modes, the UIs are hosted on a central server
147                if ( module.shouldRenderWebInterface() ) {
148                    WebModuleConfiguration webModuleConfiguration = module.getWebModuleConfiguration();
149                    if (webModuleConfiguration == null) {
150                        throw new ConfigurationException("Attempting to load WebModuleConfiguration for module '" + module.getModuleName() + "' but no configuration was provided!");
151                    }
152                        if ( LOG.isInfoEnabled() ) {
153                                LOG.info( "Configuring Web Content for Module: " + webModuleConfiguration.getModuleName()
154                                                + " / " + webModuleConfiguration.getWebModuleStrutsConfigName()
155                                                + " / " + webModuleConfiguration.getWebModuleStrutsConfigurationFiles()
156                                                + " / Base URL: " + webModuleConfiguration.getWebModuleBaseUrl() );
157                        }
158                    if ( !initParameters.containsKey( webModuleConfiguration.getWebModuleStrutsConfigName() ) ) {
159                        initParameters.put( webModuleConfiguration.getWebModuleStrutsConfigName(), webModuleConfiguration.getWebModuleStrutsConfigurationFiles() );
160                    }
161                }
162            }
163        }
164
165        @Override
166                public String getInitParameter(String name) {
167            return initParameters.get(name);
168        }
169
170        @Override
171                @SuppressWarnings("unchecked")
172                public Enumeration<String> getInitParameterNames() {
173            return new IteratorEnumeration( initParameters.keySet().iterator() );
174        }
175
176        @Override
177                public ServletContext getServletContext() {
178            return wrapped.getServletContext();
179        }
180        @Override
181                public String getServletName() {
182            return wrapped.getServletName();
183        }
184    }
185
186    /**
187     *  KULRICE-8176: KFS Notes/Attachments Tab Functionality for Note Text Error - Visible/Special characters, spaces, or tabs
188     * 
189     * @see org.apache.struts.action.ActionServlet#process(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
190     */
191     @Override
192     protected void process(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
193         if (StringUtils.isNotBlank(parameterEncoding)) {
194                 request.setCharacterEncoding(parameterEncoding);
195                 response.setCharacterEncoding(parameterEncoding);
196         }
197    
198         super.process(request, response);
199     }
200}