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.form;
017
018import java.util.ArrayList;
019import java.util.HashMap;
020import java.util.List;
021import java.util.Map;
022
023import javax.servlet.ServletRequest;
024import javax.servlet.http.HttpServletRequest;
025
026import org.apache.commons.lang.StringUtils;
027import org.apache.struts.action.ActionMapping;
028import org.kuali.rice.core.web.format.Formatter;
029import org.kuali.rice.coreservice.framework.CoreFrameworkServiceLocator;
030import org.kuali.rice.kns.datadictionary.HeaderNavigation;
031import org.kuali.rice.kns.util.ActionFormUtilMap;
032import org.kuali.rice.kns.util.WebUtils;
033import org.kuali.rice.kns.web.struts.form.pojo.PojoFormBase;
034import org.kuali.rice.kns.web.ui.ExtraButton;
035import org.kuali.rice.kns.web.ui.HeaderField;
036import org.kuali.rice.krad.util.KRADConstants;
037import org.kuali.rice.krad.util.ObjectUtils;
038import org.springframework.util.AutoPopulatingList;
039
040/**
041 * This class common properites for all action forms.
042 *
043 * @deprecated Use {@link org.kuali.rice.krad.web.form.UifFormBase}.
044 */
045@Deprecated
046public class KualiForm extends PojoFormBase {
047    /**
048     * Tab state UI literals
049     */
050    public static enum TabState {
051        OPEN,
052        CLOSE
053    }
054
055    private static final long serialVersionUID = 1L;
056
057    private static final String literalPrefixAndDelimiter =
058        KRADConstants.LOOKUP_PARAMETER_LITERAL_PREFIX+ KRADConstants.LOOKUP_PARAMETER_LITERAL_DELIMITER;
059
060    private String backLocation;
061    private String methodToCall;
062    private String refreshCaller;
063    private String anchor;
064    private Map<String, String> tabStates;
065    private Map actionFormUtilMap;
066    private Map displayedErrors = new HashMap();
067    private Map<String, Object> displayedWarnings = new HashMap<String, Object>();
068    private Map<String, Object> displayedInfo = new HashMap<String, Object>();
069    private int currentTabIndex = 0;
070    private int arbitrarilyHighIndex = 1000000;
071
072    private String navigationCss;
073    private HeaderNavigation[] headerNavigationTabs;
074    protected List<ExtraButton> extraButtons = new AutoPopulatingList( ExtraButton.class ) ;
075
076    private boolean fieldLevelHelpEnabled;
077    
078    private List<HeaderField> docInfo;
079    private int numColumns = 2;
080    
081    private String fieldNameToFocusOnAfterSubmit;
082    
083    /**
084     * @see org.kuali.rice.krad.web.struts.pojo.PojoFormBase#addRequiredNonEditableProperties()
085     */
086    @Override
087    public void addRequiredNonEditableProperties(){
088        super.addRequiredNonEditableProperties();
089        registerRequiredNonEditableProperty(KRADConstants.REFRESH_CALLER);
090    }
091    
092    public int getNumColumns() {
093        return this.numColumns;
094    }
095
096    public void setNumColumns(int numColumns) {
097        this.numColumns = numColumns;
098    }
099
100    public List<HeaderField> getDocInfo() {
101        return this.docInfo;
102    }
103
104    public void setDocInfo(List<HeaderField> docInfo) {
105        this.docInfo = docInfo;
106    }
107
108    /**
109     * no args constructor which must init our tab states list
110     */
111    public KualiForm() {
112        this.tabStates = new HashMap<String, String>();
113        this.actionFormUtilMap = new ActionFormUtilMap();
114        this.docInfo = new ArrayList<HeaderField>();
115    }
116
117    /**
118     * Checks for methodToCall parameter, and if not populated in form calls utility method to parse the string from the request.
119     */
120    public void populate(HttpServletRequest request) {
121        setMethodToCall(WebUtils.parseMethodToCall(this, request));
122        
123        super.populate(request);
124
125        populateBackLocation(request);
126        populateFieldLevelHelpEnabled(request);
127        
128        if (actionFormUtilMap instanceof ActionFormUtilMap) {
129            ((ActionFormUtilMap) actionFormUtilMap).setCacheValueFinderResults(true);
130        }
131    }
132        
133    private static Boolean ENABLE_FIELD_LEVEL_HELP_IND;
134
135    protected void populateBackLocation(HttpServletRequest request){
136        if (getParameter(request, "returnLocation") != null) {
137            setBackLocation(getParameter(request, "returnLocation"));
138        }
139    }
140    
141    /**
142     * Populates whether the each field will have field-level help associated with it.  Depending on how the jsp/tags are implemented, the value
143     * populated by this method may be overruled by other settings
144     * 
145     * @param request
146     */
147    protected void populateFieldLevelHelpEnabled(HttpServletRequest request) {
148        boolean fieldLevelHelpEnabled = CoreFrameworkServiceLocator.getParameterService().getParameterValueAsBoolean(
149                KRADConstants.KNS_NAMESPACE, KRADConstants.DetailTypes.ALL_DETAIL_TYPE,
150                KRADConstants.SystemGroupParameterNames.ENABLE_FIELD_LEVEL_HELP_IND, Boolean.FALSE);
151        setFieldLevelHelpEnabled(fieldLevelHelpEnabled);
152    }
153
154    public Map getDisplayedErrors() {
155        return displayedErrors;
156    }
157
158    /**
159         * @return the displayedWarnings
160         */
161        public Map<String, Object> getDisplayedWarnings() {
162                return this.displayedWarnings;
163        }
164
165        /**
166         * @return the displayedInfo
167         */
168        public Map<String, Object> getDisplayedInfo() {
169                return this.displayedInfo;
170        }
171
172        /**
173     * Used by the dispatch action to determine which action method to call into.
174     *
175     * @return Returns the methodToCall.
176     */
177    public String getMethodToCall() {
178        return methodToCall;
179    }
180
181
182    /**
183     * @param methodToCall The methodToCall to set.
184     */
185    public void setMethodToCall(String methodToCall) {
186        this.methodToCall = methodToCall;
187    }
188
189
190    /**
191     * Can be used by actions refresh method to determine what called the the refresh method.
192     *
193     * @return Returns the refreshCaller.
194     */
195    public String getRefreshCaller() {
196        return refreshCaller;
197    }
198
199
200    /**
201     * @param refreshCaller The refreshCaller to set.
202     */
203    public void setRefreshCaller(String refreshCaller) {
204        this.refreshCaller = refreshCaller;
205    }
206
207    /**
208     * @return the tab state list
209     */
210    public Map<String, String> getTabStates() {
211        return tabStates;
212    }
213
214    /**
215     * simple setter for the tab state Map
216     *
217     * @param tabStates
218     */
219    public void setTabStates(Map<String, String> tabStates) {
220        this.tabStates = tabStates;
221    }
222
223    /**
224     * Special getter based on key to work with multi rows for tab state objects
225     */
226    public String getTabState(String key) {
227        String state = KRADConstants.EMPTY_STRING;
228        if (tabStates.containsKey(key)) {
229            if (tabStates.get(key) instanceof String) {
230                state = tabStates.get(key);
231            }
232            else {
233                //This is the case where the value is an Array of String,
234                //so we'll have to get the first element
235                Object result = tabStates.get(key);
236                result.getClass();
237                state = ((String[])result)[0];
238            }
239        }
240
241        return state;
242    }
243
244    public int getCurrentTabIndex() {
245        return currentTabIndex;
246    }
247
248    public void setCurrentTabIndex(int currentTabIndex) {
249        this.currentTabIndex = currentTabIndex;
250    }
251
252    public void incrementTabIndex() {
253        this.currentTabIndex++;
254    }
255
256    public int getNextArbitrarilyHighIndex() {
257        return this.arbitrarilyHighIndex++;
258    }
259    
260        public String getFieldNameToFocusOnAfterSubmit() {
261                return this.fieldNameToFocusOnAfterSubmit;
262        }
263
264        public void setFieldNameToFocusOnAfterSubmit(String fieldNameToFocusOnAfterSubmit) {
265                this.fieldNameToFocusOnAfterSubmit = fieldNameToFocusOnAfterSubmit;
266        }
267
268        /**
269     * @return Returns the validOptionsMap.
270     */
271    public Map getActionFormUtilMap() {
272        return actionFormUtilMap;
273    }
274
275    /**
276     * @param validOptionsMap The validOptionsMap to set.
277     */
278    public void setActionFormUtilMap(Map validOptionsMap) {
279        this.actionFormUtilMap = validOptionsMap;
280    }
281
282    /**
283     * Gets the headerNavigationTabs attribute.
284     *
285     * @return Returns the headerNavigationTabs.
286     */
287    public HeaderNavigation[] getHeaderNavigationTabs() {
288        return headerNavigationTabs;
289    }
290
291    /**
292     * Sets the headerNavigationTabs attribute value.
293     *
294     * @param headerNavigationTabs The headerNavigationTabs to set.
295     */
296    public void setHeaderNavigationTabs(HeaderNavigation[] headerNavigationTabs) {
297        this.headerNavigationTabs = headerNavigationTabs;
298    }
299
300    /**
301     * Gets the navigationCss attribute.
302     *
303     * @return Returns the navigationCss.
304     */
305    public String getNavigationCss() {
306        return navigationCss;
307    }
308
309    /**
310     * Sets the navigationCss attribute value.
311     *
312     * @param navigationCss The navigationCss to set.
313     */
314    public void setNavigationCss(String navigationCss) {
315        this.navigationCss = navigationCss;
316    }
317
318    public String getAnchor() {
319        return anchor;
320    }
321
322    public void setAnchor(String anchor) {
323        this.anchor = anchor;
324    }
325
326    public List<ExtraButton> getExtraButtons() {
327        return extraButtons;
328    }
329
330    public void setExtraButtons(List<ExtraButton> extraButtons) {
331        if ( extraButtons instanceof AutoPopulatingList ) {
332            this.extraButtons = extraButtons;
333        } else {
334            this.extraButtons.clear();
335            this.extraButtons.addAll( extraButtons );
336        }
337    }
338
339    public ExtraButton getExtraButton( int index ) {
340        return extraButtons.get( index );
341    }
342
343    public void setExtraButton( int index, ExtraButton extraButton ) {
344        extraButtons.set( index, extraButton );
345    }
346
347    /**
348     * Returns whether field level help is enabled for this form.
349     * 
350     * @return
351     */
352    public boolean isFieldLevelHelpEnabled() {
353        return this.fieldLevelHelpEnabled;
354    }
355
356    public void setFieldLevelHelpEnabled(boolean fieldLevelHelpEnabled) {
357        this.fieldLevelHelpEnabled = fieldLevelHelpEnabled;
358    }
359    
360    
361    /**
362     * Retrieves a value from the form for the purposes of passing it as a parameter into the lookup or inquiry frameworks 
363     * 
364     * @param parameterName the name of the parameter, as expected by the lookup or inquiry frameworks
365     * @param parameterValueLocation the name of the property containing the value of the parameter
366     * @return the value of the parameter
367     */
368    public String retrieveFormValueForLookupInquiryParameters(String parameterName, String parameterValueLocation) {
369        // dereference literal values by simply trimming of the prefix
370        if (parameterValueLocation.startsWith(literalPrefixAndDelimiter)) {
371                return parameterValueLocation.substring(literalPrefixAndDelimiter.length());
372        }
373
374        Object value = ObjectUtils.getPropertyValue(this, parameterValueLocation);
375                if (value == null) {
376                        return null;
377                }
378                if (value instanceof String) {
379                        return (String) value;
380                }
381                Formatter formatter = Formatter.getFormatter(value.getClass());
382                return (String) formatter.format(value);        
383    }
384
385        /**
386         * This overridden method ...
387         * 
388         * @see org.kuali.rice.krad.web.struts.pojo.PojoFormBase#shouldPropertyBePopulatedInForm(java.lang.String, javax.servlet.http.HttpServletRequest)
389         */
390        @Override
391        public boolean shouldPropertyBePopulatedInForm(
392                        String requestParameterName, HttpServletRequest request) {
393                if (requestParameterName.startsWith(KRADConstants.TAB_STATES)) {
394                        return true;
395                }
396                
397                if (requestParameterName.equals(KRADConstants.DISPATCH_REQUEST_PARAMETER)) {
398                        String methodToCallParameterName = request.getParameter(KRADConstants.DISPATCH_REQUEST_PARAMETER);
399                        if(StringUtils.equals(methodToCallParameterName, KRADConstants.RETURN_METHOD_TO_CALL)){
400                                return true;
401                        }
402                }
403                
404                return super.shouldPropertyBePopulatedInForm(requestParameterName, request);
405        }
406    
407    public boolean shouldMethodToCallParameterBeUsed(String methodToCallParameterName, String methodToCallParameterValue, HttpServletRequest request) {
408        if ("GET".equalsIgnoreCase(request.getMethod())) {
409                return true;
410        }
411        if (shouldPropertyBePopulatedInForm(methodToCallParameterName, request)) {
412                return true;
413        }
414        if (methodToCallParameterName != null && WebUtils.endsWithCoordinates(methodToCallParameterName)) {
415                methodToCallParameterName = methodToCallParameterName.substring(0, WebUtils.getIndexOfCoordinateExtension(methodToCallParameterName));
416                if (shouldPropertyBePopulatedInForm(methodToCallParameterName, request)) {
417                        return true;
418                }
419        }
420        if (KRADConstants.METHOD_TO_CALL_PATH.equals(methodToCallParameterName)) {
421                if (shouldPropertyBePopulatedInForm(methodToCallParameterValue, request)) {
422                        return true;
423                }
424                if (methodToCallParameterValue != null && WebUtils.endsWithCoordinates(methodToCallParameterName)) {
425                        methodToCallParameterValue = methodToCallParameterValue.substring(0, WebUtils
426                        .getIndexOfCoordinateExtension(methodToCallParameterName));
427                        if (shouldPropertyBePopulatedInForm(methodToCallParameterValue, request)) {
428                                return true;
429                        }
430                }
431        }
432        return false;
433    }
434
435        /**
436         * @see org.kuali.rice.krad.web.struts.pojo.PojoFormBase#clearEditablePropertyInformation()
437         */
438        @Override
439        public void clearEditablePropertyInformation() {
440                super.clearEditablePropertyInformation();
441        }
442        
443        public void setDerivedValuesOnForm(HttpServletRequest request) {
444        }
445
446        /**
447         * @see org.apache.struts.action.ActionForm#reset(org.apache.struts.action.ActionMapping, javax.servlet.http.HttpServletRequest)
448         */
449        @Override
450        public void reset(ActionMapping mapping, HttpServletRequest request) {
451                super.reset(mapping, request);
452                if (extraButtons != null) {
453                        extraButtons.clear();
454                }
455                //fieldNameToFocusOnAfterSubmit = "";
456                clearDisplayedMessages();
457        }
458
459        /**
460         * @see org.apache.struts.action.ActionForm#reset(org.apache.struts.action.ActionMapping, javax.servlet.ServletRequest)
461         */
462        @Override
463        public void reset(ActionMapping mapping, ServletRequest request) {
464                super.reset(mapping, request);
465                if (extraButtons != null) {
466                        extraButtons.clear();
467                }
468                //fieldNameToFocusOnAfterSubmit = "";
469                clearDisplayedMessages();
470        }
471        
472        private void clearDisplayedMessages() {
473                if (displayedErrors != null) {
474                        displayedErrors.clear();
475                }
476                if (displayedWarnings != null) {
477                        displayedWarnings.clear();
478                }
479                if (displayedInfo != null) {
480                        displayedInfo.clear();
481                }
482        }
483        
484    /**
485         * @return the backLocation
486         */
487        public String getBackLocation() {
488                return WebUtils.sanitizeBackLocation(this.backLocation);
489        }
490
491        /**
492         * @param backLocation the backLocation to set
493         */
494        public void setBackLocation(String backLocation) {
495                this.backLocation = backLocation;
496        }
497
498}