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.util;
017
018import org.apache.commons.lang.StringUtils;
019import org.kuali.rice.core.api.CoreApiServiceLocator;
020import org.kuali.rice.krad.keyvalues.KeyValuesFinder;
021import org.kuali.rice.krad.keyvalues.PersistableBusinessObjectValuesFinder;
022import org.kuali.rice.krad.util.KRADConstants;
023
024import java.lang.reflect.Method;
025import java.security.GeneralSecurityException;
026import java.util.ArrayList;
027import java.util.HashMap;
028import java.util.List;
029
030/**
031 * Utility map for the action form to provide a way for calling functions through jstl.
032 *
033 * @deprecated Only used in KNS classes, use KRAD.
034 */
035@Deprecated
036@SuppressWarnings("unchecked")
037public class ActionFormUtilMap extends HashMap {
038    private static final long serialVersionUID = 1L;
039        private boolean cacheValueFinderResults;
040
041    /**
042     * This method parses from the key the actual method to run.
043     *
044     * @see java.util.Map#get(java.lang.Object)
045     */
046    @Override
047        public Object get(Object key) {
048        if (cacheValueFinderResults) {
049            if (super.containsKey(key)) {
050                // doing a 2 step retrieval allows us to also cache the null key correctly
051                Object cachedObject = super.get(key);
052                return cachedObject;
053            }
054        }
055        String[] methodKey = StringUtils.split((String) key, KRADConstants.ACTION_FORM_UTIL_MAP_METHOD_PARM_DELIMITER);
056
057        String methodToCall = methodKey[0];
058
059        // handle method calls with more than one parameter
060        Object[] methodParms = new Object[methodKey.length - 1];
061        Class[] methodParmsPrototype = new Class[methodKey.length - 1];
062        for (int i=1;i<methodKey.length;i++) {
063            methodParms[i-1] = methodKey[i];
064            methodParmsPrototype[i-1] = Object.class;
065        }
066
067        Method method = null;
068        try {
069            method = ActionFormUtilMap.class.getMethod(methodToCall, methodParmsPrototype);
070        }
071        catch (SecurityException e) {
072            throw new RuntimeException("Unable to object handle on method given to ActionFormUtilMap: " + e.getMessage());
073        }
074        catch (NoSuchMethodException e1) {
075            throw new RuntimeException("Unable to object handle on method given to ActionFormUtilMap: " + e1.getMessage());
076        }
077
078        Object methodValue = null;
079        try {
080            methodValue = method.invoke(this, methodParms);
081        }
082        catch (Exception e) {
083            throw new RuntimeException("Unable to invoke method " + methodToCall,e);
084        }
085
086        if (cacheValueFinderResults) {
087            super.put(key, methodValue);
088        }
089
090        return methodValue;
091    }
092
093    /*
094     * Will take in a class name parameter and attempt to create a KeyValueFinder instance, then call the finder to return a list of
095     * KeyValue pairs. This is used by the htmlControlAttribute.tag to render select options from a given finder class specified in
096     * the data dictionary.
097     */
098        public Object getOptionsMap(Object key) {
099        List optionsList = new ArrayList();
100
101        if (StringUtils.isBlank((String) key)) {
102            return optionsList;
103        }
104
105        /*
106         * the class name has . replaced with | in the jsp to prevent struts from treating each part of the class name as a property
107         * substitute back here to get the correct name
108         */
109        key = StringUtils.replace((String) key, "|", ".");
110
111        KeyValuesFinder finder;
112        try {
113            Class finderClass = Class.forName((String) key);
114            finder = (KeyValuesFinder) finderClass.newInstance();
115            optionsList = finder.getKeyValues();
116        }
117        catch (ClassNotFoundException e) {
118            throw new RuntimeException(e.getMessage());
119        }
120        catch (InstantiationException e) {
121            throw new RuntimeException(e.getMessage());
122        }
123        catch (IllegalAccessException e) {
124            throw new RuntimeException(e.getMessage());
125        }
126
127        return optionsList;
128    }
129
130    // Method added to keep backward compatibility for non-kimTypeId cases
131    public Object getOptionsMap(Object key, Object boClass, Object keyAttribute, Object labelAttribute, Object includeKeyInLabel) {
132        return getOptionsMap(key, boClass, keyAttribute, labelAttribute, null, includeKeyInLabel );
133    }
134
135    /**
136     * This method will take in a key parameter (values finder class name - in this case the generic
137     * PersistableObjectValuesFinder) along with the related parameters required by this ValuesFinder,
138     * and attempt to create a KeyValueFinder instance, then call the finder to return a list of
139     * KeyValue pairs. This is used by the htmlControlAttribute.tag to render select options from
140     * a given finder class specified in the data dictionary.
141     *
142     * @param key values finder class name
143     * @param boClass BO class name
144     * @param keyAttribute name of BO attribute for key
145     * @param labelAttribute name of BO attribute for label
146     * @param includeKeyInLabel whether to include the key in the label or not
147     * @return list of KeyValue pairs
148     */
149        public Object getOptionsMap(Object key, Object boClass, Object keyAttribute, Object labelAttribute, Object includeBlankRow, Object includeKeyInLabel) {
150        List optionsList = new ArrayList();
151
152        if (StringUtils.isBlank((String) key)) {
153            return optionsList;
154        }
155
156        /*
157         * the class name has . replaced with | in the jsp to prevent struts from treating each part of the class name as a property
158         * substitute back here to get the correct name
159         */
160        key = StringUtils.replace((String) key, "|", ".");
161
162        KeyValuesFinder finder;
163        try {
164                Class finderClass = Class.forName((String) key);
165            finder = (KeyValuesFinder) finderClass.newInstance();
166            if (finder instanceof PersistableBusinessObjectValuesFinder) {
167                String businessObjectClassName = StringUtils.replace((String) boClass, "|", ".");
168                Class businessObjectClass = Class.forName((String) businessObjectClassName);
169                ((PersistableBusinessObjectValuesFinder) finder).setBusinessObjectClass(businessObjectClass);
170                ((PersistableBusinessObjectValuesFinder) finder).setKeyAttributeName((String)keyAttribute);
171                ((PersistableBusinessObjectValuesFinder) finder).setLabelAttributeName((String)labelAttribute);
172                ((PersistableBusinessObjectValuesFinder) finder).setIncludeBlankRow(Boolean.parseBoolean((String)includeBlankRow));
173                ((PersistableBusinessObjectValuesFinder) finder).setIncludeKeyInDescription(Boolean.parseBoolean((String)includeKeyInLabel));
174            }
175
176            optionsList = finder.getKeyValues();
177        }
178        catch (ClassNotFoundException e) {
179            throw new RuntimeException(e.getMessage(),e);
180        }
181        catch (InstantiationException e) {
182            throw new RuntimeException(e.getMessage(),e);
183        }
184        catch (IllegalAccessException e) {
185            throw new RuntimeException(e.getMessage(),e);
186        }
187
188        return optionsList;
189    }
190
191    /**
192     * Encrypts a value passed from the ui.
193     * @param value - clear text
194     * @return String - encrypted text
195     */
196    public String encryptValue(Object value) {
197        String encrypted = "";
198        if (value != null) {
199            encrypted = value.toString();
200        }
201
202        try {
203            if(CoreApiServiceLocator.getEncryptionService().isEnabled()) {
204                encrypted = CoreApiServiceLocator.getEncryptionService().encrypt(value);
205            }
206        }
207        catch (GeneralSecurityException e) {
208            throw new RuntimeException("Unable to encrypt value in action form: " + e.getMessage());
209        }
210
211        return encrypted;
212    }
213
214    public void setCacheValueFinderResults(boolean cacheValueFinderResults) {
215        this.cacheValueFinderResults = cacheValueFinderResults;
216    }
217
218
219}