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.identity.Person;
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 person element.
036 *
037 * @author Kuali Rice Team (rice.collab@kuali.org)
038 */
039@BeanTag(name = "userLinkField", parent = "Uif-UserLinkField")
040public class UserLinkField extends LinkField {
041    private static final long serialVersionUID = -6328858502087834L;
042    private static final Logger LOG = Logger.getLogger(UserLinkField.class);
043
044    private String principalId;
045    private String principalName;
046    private String dataObjectClassName;
047    private String baseInquiryUrl;
048    private boolean disableLink;
049    private Map<String, String> additionalInquiryParameters;
050
051    /**
052     * The following initialization is performed:
053     *
054     * <ul>
055     * <li>Set the linkLabel if blank to the Field label</li>
056     * </ul>
057     *
058     * {@inheritDoc}
059     */
060    @Override
061    public void performInitialization(Object model) {
062        super.performInitialization(model);
063    }
064
065    /**
066     * PerformFinalize override - calls super, corrects the field's Label for attribute to point to this field's
067     * content
068     *
069     * @param model the model
070     * @param parent the parent component
071     */
072    @Override
073    public void performFinalize(Object model, LifecycleElement parent) {
074        super.performFinalize(model, parent);
075
076        if (StringUtils.isNotBlank(principalId)) {
077            setHref(buildInquiryUrl());
078            setLinkText(getPersonNameByPrincipalId(principalId));
079        } else {
080            if (StringUtils.isNotBlank(principalName)) {
081                setHref(buildInquiryUrl());
082                setLinkText(getPersonNameByPrincipalName(principalName));
083            }
084        }
085
086        if (StringUtils.isBlank(getHref())) {
087            setDisableLink(true);
088        }
089
090        if (StringUtils.isBlank(getLinkText())){
091            setLinkText(UifConstants.KimLink.BLANK_LINK);
092        }
093    }
094
095    protected String buildInquiryUrl() {
096        Class<?> inquiryObjectClass;
097        try {
098            inquiryObjectClass = Class.forName(getDataObjectClassName());
099        } catch (ClassNotFoundException e) {
100            LOG.error("Unable to get class for: " + getDataObjectClassName());
101            throw new RuntimeException(e);
102        }
103
104        Properties urlParameters = new Properties();
105        urlParameters.setProperty(UifParameters.DATA_OBJECT_CLASS_NAME, inquiryObjectClass.getName());
106        urlParameters.setProperty(UifParameters.METHOD_TO_CALL, UifConstants.MethodToCallNames.START);
107
108        if (StringUtils.isNotBlank(principalId)) {
109            urlParameters.setProperty(UifConstants.KimLink.PRINCIPAL_ID, principalId);
110        } else {
111            if (StringUtils.isNotBlank(principalName)) {
112                urlParameters.setProperty(UifConstants.KimLink.PRINCIPAL_NAME, principalName);
113            }
114        }
115
116        for (Map.Entry<String, String> inquiryParameter : additionalInquiryParameters.entrySet()) {
117            // add inquiry parameter to URL
118            urlParameters.setProperty(inquiryParameter.getKey(), inquiryParameter.getValue());
119        }
120
121        /* build inquiry URL */
122        String inquiryUrl;
123
124        // check for EBOs for an alternate inquiry URL
125        ModuleService responsibleModuleService =
126                KRADServiceLocatorWeb.getKualiModuleService().getResponsibleModuleService(inquiryObjectClass);
127        if (responsibleModuleService != null && responsibleModuleService.isExternalizable(inquiryObjectClass)) {
128            inquiryUrl = responsibleModuleService.getExternalizableDataObjectInquiryUrl(inquiryObjectClass,
129                    urlParameters);
130        } else {
131            inquiryUrl = UrlFactory.parameterizeUrl(getBaseInquiryUrl(), urlParameters);
132        }
133
134        return inquiryUrl;
135    }
136
137    protected String getPersonNameByPrincipalId(String principalId) {
138        Person person = KimApiServiceLocator.getPersonService().getPerson(principalId);
139        if (person == null) {
140            // disable link and display principalId
141            setDisableLink(true);
142            return principalId;
143        }
144
145        return person.getName();
146    }
147
148    protected String getPersonNameByPrincipalName(String principalName) {
149        Person person = KimApiServiceLocator.getPersonService().getPersonByPrincipalName(principalName);
150        if (person == null) {
151            // disable link and display principalName
152            setDisableLink(true);
153            return principalName;
154        }
155
156        return person.getName();
157    }
158
159    /**
160     * PrincipalName key used as a parameter of generated inquiry link url.
161     *
162     * @return value of PrincipalName key parameter
163     */
164    @BeanTagAttribute
165    public String getPrincipalName() {
166        return principalName;
167    }
168
169    public void setPrincipalName(String principalName) {
170        this.principalName = principalName;
171    }
172
173    /**
174     * PrincipalId key used as a parameter of generated inquiry link url.
175     *
176     * @return value of PrincipalId key parameter
177     */
178    @BeanTagAttribute
179    public String getPrincipalId() {
180        return principalId;
181    }
182
183    public void setPrincipalId(String principalId) {
184        this.principalId = principalId;
185    }
186
187    /**
188     * DataObjectClassName used as a parameter of generated inquiry link url.
189     *
190     * @return value of DataObjectClassName parameter
191     */
192    @BeanTagAttribute
193    public String getDataObjectClassName() {
194        return dataObjectClassName;
195    }
196
197    public void setDataObjectClassName(String dataObjectClassName) {
198        this.dataObjectClassName = dataObjectClassName;
199    }
200
201    /**
202     * BaseInquiryUrl is the foundation of generated inquiry link url.
203     *
204     * @return value of BaseInquiryUrl part of inquiry link url
205     */
206    @BeanTagAttribute
207    public String getBaseInquiryUrl() {
208        return baseInquiryUrl;
209    }
210
211    public void setBaseInquiryUrl(String baseInquiryUrl) {
212        this.baseInquiryUrl = baseInquiryUrl;
213    }
214
215    /**
216     * True if this fields link is disabled, false otherwise.
217     *
218     * @return true if link disabled
219     */
220    @BeanTagAttribute
221    public boolean isDisableLink() {
222        return disableLink;
223    }
224
225    public void setDisableLink(boolean disableLink) {
226        this.disableLink = disableLink;
227    }
228
229    /**
230     * Map that determines what additional properties from a calling view will be sent to properties on the inquiry data object.
231     *
232     * <p>
233     * When invoking an inquiry view, a query is done against the inquiries configured data object and the resulting
234     * record is display. The values for the properties configured within the inquiry parameters Map, in addition to the
235     * inquiry key parameters, will be passed along as values for the inquiry data object properties (thus they form the
236     * criteria for the inquiry)
237     * </p>
238     *
239     * @return mapping of calling additional view properties to inquiry data object properties
240     */
241    @BeanTagAttribute
242    public Map<String, String> getAdditionalInquiryParameters() {
243        return additionalInquiryParameters;
244    }
245
246    public void setAdditionalInquiryParameters(Map<String, String> additionalInquiryParameters) {
247        this.additionalInquiryParameters = additionalInquiryParameters;
248    }
249
250}