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.krad.uif.widget;
017
018import java.util.HashMap;
019import java.util.Map;
020
021import org.apache.commons.lang.StringUtils;
022import org.kuali.rice.krad.datadictionary.parse.BeanTag;
023import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
024import org.kuali.rice.krad.uif.component.Component;
025import org.kuali.rice.krad.uif.util.LifecycleElement;
026import org.kuali.rice.krad.uif.util.ScriptUtils;
027import org.kuali.rice.krad.util.KRADUtils;
028
029/**
030 * LocationSuggest widget for providing suggestions that represent locations.  When the suggestion is clicked, the
031 * navigation occurs immediately.
032 */
033@BeanTag(name = "locationSuggest", parent = "Uif-LocationSuggest")
034public class LocationSuggest extends Suggest {
035    private static final long serialVersionUID = 5940714417896326889L;
036
037    private String baseUrl;
038    private String additionalUrlPathPropertyName;
039    private String hrefPropertyName;
040    private String objectIdPropertyName;
041    private Map<String, String> requestParameterPropertyNames;
042    private Map<String, String> additionalRequestParameters;
043
044    /**
045     * Process the objectIdPropertyName, if set
046     *
047     * {@inheritDoc}
048     */
049    @Override
050    public void performFinalize(Object model, LifecycleElement parent) {
051        super.performFinalize(model, parent);
052
053        if (requestParameterPropertyNames == null) {
054            requestParameterPropertyNames = new HashMap<String, String>();
055        }
056
057        if (StringUtils.isNotBlank(objectIdPropertyName)) {
058            requestParameterPropertyNames.put(objectIdPropertyName, objectIdPropertyName);
059        }
060    }
061
062    /**
063     * {@inheritDoc}
064     */
065    @Override
066    public LocationSuggestPostData getPostData() {
067        return new LocationSuggestPostData(this);
068    }
069
070    /**
071     * BaseUrl for the suggestions.  Unless the suggestion contains an href, baseUrl + additionalUrlPath value +
072     * request parameters is used to generate the url.
073     *
074     * @return the baseUrl
075     */
076    @BeanTagAttribute
077    public String getBaseUrl() {
078        return baseUrl;
079    }
080
081    /**
082     * Set the baseUrl
083     *
084     * @param baseUrl
085     */
086    public void setBaseUrl(String baseUrl) {
087        this.baseUrl = baseUrl;
088    }
089
090    /**
091     * AdditionalUrlPathProperty specifies the property on the retrieved suggestion result that contains a url
092     * appendage
093     * to be appended to the baseUrl when this selection is chosen.
094     *
095     * <p>One use case for setting this is to retrieve a controllerMapping that changes based on selection.  Note:
096     * for suggestions that all point to the same controllerMapping, simply set it as part of the baseUrl.</p>
097     *
098     * @return the additionalUrlPathPropertyName
099     */
100    @BeanTagAttribute
101    public String getAdditionalUrlPathPropertyName() {
102        return additionalUrlPathPropertyName;
103    }
104
105    /**
106     * Set additionalUrlPathProperty
107     *
108     * @param additionalUrlPathPropertyName
109     */
110    public void setAdditionalUrlPathPropertyName(String additionalUrlPathPropertyName) {
111        this.additionalUrlPathPropertyName = additionalUrlPathPropertyName;
112    }
113
114    /**
115     * The hrefPropertyName specifies the property on the retrieved suggestion result that contains the href
116     * value (full url).
117     *
118     * <p>This property must contain a full url if it exists on the object.  If this property name is matched on
119     * the suggestion result, it takes precedence over any other settings set on this locationSuggest
120     * and is used as the navigation url.  If the property name does not exist on the object, the suggest will fall
121     * back to building the url dynamically with baseUrl.</p>
122     *
123     * @return the hrefPropertyName
124     */
125    @BeanTagAttribute
126    public String getHrefPropertyName() {
127        return hrefPropertyName;
128    }
129
130    /**
131     * Set the hrefPropertyName
132     *
133     * @param hrefPropertyName
134     */
135    public void setHrefPropertyName(String hrefPropertyName) {
136        this.hrefPropertyName = hrefPropertyName;
137    }
138
139    /**
140     * The objectIdPropertyName that represents the key for getting the object as a request parameter.  The property
141     * will be added to the request parameters by the name given with the value pulled from the result object.
142     *
143     * <p>
144     *     This convenience method is essentially equivalent to having a property by objectIdPropertyName as a
145     *     key and value in the requestParameterPropertyNames.
146     * </p>
147     *
148     * @return the objectIdPropertyName which represents which property is the "key" of the object
149     */
150    @BeanTagAttribute
151    public String getObjectIdPropertyName() {
152        return objectIdPropertyName;
153    }
154
155    /**
156     * Set the objectIdPropertyName
157     *
158     * @param objectIdPropertyName
159     */
160    public void setObjectIdPropertyName(String objectIdPropertyName) {
161        this.objectIdPropertyName = objectIdPropertyName;
162    }
163
164    /**
165     * RequestParameterPropertyNames specify the properties that should be included in the request parameters.
166     *
167     * <p>The key is used as the key of the request parameter and the value is used as the property name to look for in
168     * the suggestion result object.  If the property name specified exists on the result object, the request
169     * parameter in the url will appear as key=propertyValue in the request parameters.</p>
170     *
171     * @return the RequestParameterPropertyNames map with key and property names
172     */
173    @BeanTagAttribute
174    public Map<String, String> getRequestParameterPropertyNames() {
175        return requestParameterPropertyNames;
176    }
177
178    /**
179     * Set the requestParameterPropertyNames
180     *
181     * @param requestParameterPropertyNames
182     */
183    public void setRequestParameterPropertyNames(Map<String, String> requestParameterPropertyNames) {
184        this.requestParameterPropertyNames = requestParameterPropertyNames;
185    }
186
187    /**
188     * AdditionalRequestParameters specify the static(constant) request parameters that should be appended to the url.
189     *
190     * <p>The key represents the key of the request parameter and the value represents the value of the
191     * request parameter.  This will be used on each suggestion which uses a generated url (using baseUrl
192     * construction).
193     * </p>
194     *
195     * @return mapping of additional request parameters
196     */
197    @BeanTagAttribute
198    public Map<String, String> getAdditionalRequestParameters() {
199        return additionalRequestParameters;
200    }
201
202    /**
203     * Get the additionalRequestParameters
204     *
205     * @param additionalRequestParameters
206     */
207    public void setAdditionalRequestParameters(Map<String, String> additionalRequestParameters) {
208        this.additionalRequestParameters = additionalRequestParameters;
209    }
210
211    /**
212     * Gets an object translated to js for the requestParameterPropertyNames.  Used to construct the url on the client.
213     *
214     * @return the requestParameterPropertyNames js map object
215     */
216    public String getRequestParameterPropertyNameJsObject() {
217        if (requestParameterPropertyNames != null && !requestParameterPropertyNames.isEmpty()) {
218            return ScriptUtils.translateValue(requestParameterPropertyNames);
219        } else {
220            return "{}";
221        }
222    }
223
224    /**
225     * Gets the constant additionalRequestParameters as a request string value to use as part of the url
226     *
227     * @return the request parameter string for additionalRequestParameters
228     */
229    public String getAdditionalRequestParameterString() {
230        if (additionalRequestParameters != null) {
231            return KRADUtils.getRequestStringFromMap(additionalRequestParameters);
232        } else {
233            return "";
234        }
235    }
236
237    /**
238     * Holds post data for the location suggest component.
239     */
240    public static class LocationSuggestPostData extends SuggestPostData {
241        private static final long serialVersionUID = -4326794621463438438L;
242
243        private String baseUrl;
244        private String additionalUrlPathPropertyName;
245        private String hrefPropertyName;
246        private String objectIdPropertyName;
247        private Map<String, String> requestParameterPropertyNames;
248        private Map<String, String> additionalRequestParameters;
249
250        /**
251         * Constructor taking suggest widget to pull post data from.
252         *
253         * @param suggest component instance to pull data
254         */
255        public LocationSuggestPostData(LocationSuggest suggest) {
256            super(suggest);
257
258            this.baseUrl = suggest.getBaseUrl();
259            this.additionalUrlPathPropertyName = suggest.getAdditionalUrlPathPropertyName();
260            this.hrefPropertyName = suggest.getHrefPropertyName();
261            this.objectIdPropertyName = suggest.getObjectIdPropertyName();
262            this.requestParameterPropertyNames = suggest.getRequestParameterPropertyNames();
263            this.additionalRequestParameters = suggest.getAdditionalRequestParameters();
264        }
265
266        /**
267         * @see LocationSuggest#getBaseUrl()
268         */
269        public String getBaseUrl() {
270            return baseUrl;
271        }
272
273        /**
274         * @see LocationSuggest#getAdditionalUrlPathPropertyName()
275         */
276        public String getAdditionalUrlPathPropertyName() {
277            return additionalUrlPathPropertyName;
278        }
279
280        /**
281         * @see LocationSuggest#getHrefPropertyName()
282         */
283        public String getHrefPropertyName() {
284            return hrefPropertyName;
285        }
286
287        /**
288         * @see LocationSuggest#getObjectIdPropertyName()
289         */
290        public String getObjectIdPropertyName() {
291            return objectIdPropertyName;
292        }
293
294        /**
295         * @see LocationSuggest#getRequestParameterPropertyNames()
296         */
297        public Map<String, String> getRequestParameterPropertyNames() {
298            return requestParameterPropertyNames;
299        }
300
301        /**
302         * @see LocationSuggest#getAdditionalRequestParameters()
303         */
304        public Map<String, String> getAdditionalRequestParameters() {
305            return additionalRequestParameters;
306        }
307    }
308}