001    /**
002     * Copyright 2005-2013 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     */
016    package org.kuali.rice.kns.web.struts.action;
017    
018    import org.apache.commons.beanutils.ConvertUtils;
019    import org.apache.commons.beanutils.converters.BigDecimalConverter;
020    import org.apache.commons.beanutils.converters.BigIntegerConverter;
021    import org.apache.commons.beanutils.converters.BooleanConverter;
022    import org.apache.commons.beanutils.converters.ByteConverter;
023    import org.apache.commons.beanutils.converters.CharacterConverter;
024    import org.apache.commons.beanutils.converters.DoubleConverter;
025    import org.apache.commons.beanutils.converters.FloatConverter;
026    import org.apache.commons.beanutils.converters.IntegerConverter;
027    import org.apache.commons.beanutils.converters.LongConverter;
028    import org.apache.commons.beanutils.converters.ShortConverter;
029    import org.apache.commons.collections.iterators.IteratorEnumeration;
030    import org.apache.commons.lang.StringUtils;
031    import org.apache.log4j.Logger;
032    import org.apache.struts.action.ActionServlet;
033    import org.kuali.rice.core.api.config.ConfigurationException;
034    import org.kuali.rice.core.api.config.property.ConfigContext;
035    import org.kuali.rice.core.framework.config.module.ModuleConfigurer;
036    import org.kuali.rice.core.framework.config.module.WebModuleConfiguration;
037    
038    import java.io.IOException;
039    import javax.servlet.http.HttpServletRequest;
040    import javax.servlet.http.HttpServletResponse;
041    import javax.servlet.ServletConfig;
042    import javax.servlet.ServletContext;
043    import javax.servlet.ServletException;
044    import java.math.BigDecimal;
045    import java.math.BigInteger;
046    import java.util.Collection;
047    import java.util.Enumeration;
048    import java.util.HashMap;
049    import java.util.Map;
050    
051    public 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    }