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.krad.uif.field;
017
018import org.apache.commons.lang.StringUtils;
019import org.apache.log4j.Logger;
020import org.kuali.rice.kim.api.group.Group;
021import org.kuali.rice.kim.api.services.KimApiServiceLocator;
022import org.kuali.rice.krad.datadictionary.parse.BeanTag;
023import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
024import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
025import org.kuali.rice.krad.service.ModuleService;
026import org.kuali.rice.krad.uif.UifConstants;
027import org.kuali.rice.krad.uif.UifParameters;
028import org.kuali.rice.krad.uif.util.LifecycleElement;
029import org.kuali.rice.krad.util.UrlFactory;
030
031import java.util.Map;
032import java.util.Properties;
033
034/**
035 * Field that encloses a link to a group element.
036 *
037 * @author Kuali Rice Team (rice.collab@kuali.org)
038 */
039@BeanTag(name = "groupLinkField", parent = "Uif-GroupLinkField")
040public class GroupLinkField extends LinkField {
041    private static final long serialVersionUID = 6304287260087690284L;
042    private static final Logger LOG = Logger.getLogger(GroupLinkField.class);
043
044    private String groupId;
045    private String groupName;
046    private String groupNamespaceCode;
047    private String dataObjectClassName;
048    private String baseInquiryUrl;
049    private boolean namespaceInLinkText;
050    private boolean disableLink;
051    private Map<String, String> additionalInquiryParameters;
052
053    /**
054     * PerformFinalize override - calls super, corrects the field's Label for attribute to point to this field's
055     * content/
056     *
057     * @param model the model
058     * @param parent the parent component
059     */
060    @Override
061    public void performFinalize(Object model, LifecycleElement parent) {
062        super.performFinalize(model, parent);
063
064        if (StringUtils.isNotBlank(groupId)) {
065            setHref(buildInquiryUrl());
066            setLinkText(getGroupNameByGroupId(groupId));
067        } else {
068            if (StringUtils.isNotBlank(groupName) && StringUtils.isNotBlank(groupNamespaceCode) ) {
069                setHref(buildInquiryUrl());
070                setLinkText(getGroupNameByNamespaceAndName(groupNamespaceCode, groupName));
071            }
072
073            if (StringUtils.isBlank(groupName) && StringUtils.isNotBlank(groupNamespaceCode) ) {
074                setDisableLink(true);
075
076                if (isNamespaceInLinkText()){
077                    setLinkText(groupNamespaceCode);
078                }
079            }
080
081            if (StringUtils.isNotBlank(groupName) && StringUtils.isBlank(groupNamespaceCode) ) {
082                setDisableLink(true);
083                setLinkText(groupName);
084            }
085        }
086
087        if (StringUtils.isBlank(getHref())) {
088            setDisableLink(true);
089        }
090
091        if (StringUtils.isBlank(getLinkText())){
092            setLinkText(UifConstants.KimLink.BLANK_LINK);
093        }
094    }
095
096    protected String buildInquiryUrl() {
097        Class<?> inquiryObjectClass;
098        try {
099            inquiryObjectClass = Class.forName(getDataObjectClassName());
100        } catch (ClassNotFoundException e) {
101            LOG.error("Unable to get class for: " + getDataObjectClassName());
102            throw new RuntimeException(e);
103        }
104
105        Properties urlParameters = new Properties();
106        urlParameters.setProperty(UifParameters.DATA_OBJECT_CLASS_NAME, inquiryObjectClass.getName());
107        urlParameters.setProperty(UifParameters.METHOD_TO_CALL, UifConstants.MethodToCallNames.START);
108
109        if (StringUtils.isNotBlank(groupId)) {
110            urlParameters.setProperty(UifConstants.KimLink.GROUP_ID, groupId);
111        } else {
112            if (StringUtils.isNotBlank(groupName)) {
113                urlParameters.setProperty(UifConstants.KimLink.GROUP_NAME, groupName);
114                urlParameters.setProperty(UifConstants.KimLink.GROUP_NAMESPACE_CODE, groupNamespaceCode);
115            }
116        }
117
118        for (Map.Entry<String, String> inquiryParameter : additionalInquiryParameters.entrySet()) {
119            // add additional inquiry parameter to URL
120            urlParameters.setProperty(inquiryParameter.getKey(), inquiryParameter.getValue());
121        }
122
123        // build inquiry URL
124        String inquiryUrl;
125
126        // check for EBOs for an alternate inquiry URL
127        ModuleService responsibleModuleService =
128                KRADServiceLocatorWeb.getKualiModuleService().getResponsibleModuleService(inquiryObjectClass);
129        if (responsibleModuleService != null && responsibleModuleService.isExternalizable(inquiryObjectClass)) {
130            inquiryUrl = responsibleModuleService.getExternalizableDataObjectInquiryUrl(inquiryObjectClass,
131                    urlParameters);
132        } else {
133            inquiryUrl = UrlFactory.parameterizeUrl(getBaseInquiryUrl(), urlParameters);
134        }
135
136        return inquiryUrl;
137    }
138
139    protected String getGroupNameByGroupId(String groupId) {
140        Group group = KimApiServiceLocator.getGroupService().getGroup(groupId);
141        if (group == null) {
142            // disable link and display groupId
143            setDisableLink(true);
144            return groupId;
145        }
146
147        if (isNamespaceInLinkText()){
148            return group.getNamespaceCode() + " " + group.getName();
149        }
150
151        return group.getName();
152    }
153
154    protected String getGroupNameByNamespaceAndName(String namespaceCode, String groupName) {
155        Group group = KimApiServiceLocator.getGroupService().getGroupByNamespaceCodeAndName(namespaceCode, groupName);
156        if (group == null) {
157            // disable link
158            setDisableLink(true);
159
160            if (isNamespaceInLinkText()){
161                return this.groupNamespaceCode + " " + this.groupName;
162            } else {
163                return this.groupName;
164            }
165        }
166
167        if (isNamespaceInLinkText()){
168            return group.getNamespaceCode() + " " + group.getName();
169        }
170
171        return group.getName();
172    }
173
174    /**
175     * GroupName key used as a parameter of generated inquiry link url
176     *
177     * @return value of GroupName key parameter
178     */
179    @BeanTagAttribute
180    public String getGroupName() {
181        return groupName;
182    }
183
184    public void setGroupName(String groupName) {
185        this.groupName = groupName;
186    }
187
188    /**
189     * GroupNamespaceCode key used as a parameter of generated inquiry link url
190     *
191     * @return value of GroupNamespaceCode key parameter
192     */
193    @BeanTagAttribute
194    public String getGroupNamespaceCode() {
195        return groupNamespaceCode;
196    }
197
198    public void setGroupNamespaceCode(String groupNamespaceCode) {
199        this.groupNamespaceCode = groupNamespaceCode;
200    }
201
202    /**
203     * GroupId key used as a parameter of generated inquiry link url
204     *
205     * @return value of GroupId key parameter
206     */
207    @BeanTagAttribute
208    public String getGroupId() {
209        return groupId;
210    }
211
212    public void setGroupId(String groupId) {
213        this.groupId = groupId;
214    }
215
216    /**
217     * DataObjectClassName used as a parameter of generated inquiry link url
218     *
219     * @return value of DataObjectClassName parameter
220     */
221    @BeanTagAttribute
222    public String getDataObjectClassName() {
223        return dataObjectClassName;
224    }
225
226    public void setDataObjectClassName(String dataObjectClassName) {
227        this.dataObjectClassName = dataObjectClassName;
228    }
229
230    /**
231     * BaseInquiryUrl is the foundation of generated inquiry link url
232     *
233     * @return value of BaseInquiryUrl part of inquiry link url
234     */
235    @BeanTagAttribute
236    public String getBaseInquiryUrl() {
237        return baseInquiryUrl;
238    }
239
240    public void setBaseInquiryUrl(String baseInquiryUrl) {
241        this.baseInquiryUrl = baseInquiryUrl;
242    }
243
244    /**
245     * True if namespaceCode is to be included in this links linkText, false otherwise.
246     *
247     * @return true if namespaceCode is to be included in linkText
248     */
249    @BeanTagAttribute
250    public boolean isNamespaceInLinkText() {
251        return namespaceInLinkText;
252    }
253
254    public void setNamespaceInLinkText(boolean namespaceInLinkText) {
255        this.namespaceInLinkText = namespaceInLinkText;
256    }
257
258    /**
259     * True if this fields link is disabled, false otherwise.
260     *
261     * @return true if link disabled
262     */
263    @BeanTagAttribute
264    public boolean isDisableLink() {
265        return disableLink;
266    }
267
268    public void setDisableLink(boolean disableLink) {
269        this.disableLink = disableLink;
270    }
271
272    /**
273     * Map that determines what additional properties from a calling view will be sent to properties on the inquiry data object.
274     *
275     * <p>
276     * When invoking an inquiry view, a query is done against the inquiries configured data object and the resulting
277     * record is display. The values for the properties configured within the inquiry parameters Map, in addition to the
278     * inquiry key parameters, will be passed along as values for the inquiry data object properties (thus they form the
279     * criteria for the inquiry)
280     * </p>
281     *
282     * @return mapping of calling additional view properties to inquiry data object properties
283     */
284    @BeanTagAttribute
285    public Map<String, String> getAdditionalInquiryParameters() {
286        return additionalInquiryParameters;
287    }
288
289    public void setAdditionalInquiryParameters(Map<String, String> additionalInquiryParameters) {
290        this.additionalInquiryParameters = additionalInquiryParameters;
291    }
292}