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