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.view;
017
018import org.apache.commons.lang.StringUtils;
019import org.kuali.rice.core.api.CoreApiServiceLocator;
020import org.kuali.rice.core.api.util.RiceKeyConstants;
021import org.kuali.rice.kew.api.KewApiServiceLocator;
022import org.kuali.rice.kew.api.doctype.DocumentType;
023import org.kuali.rice.krad.bo.Note;
024import org.kuali.rice.krad.datadictionary.DocumentEntry;
025import org.kuali.rice.krad.datadictionary.parse.BeanTag;
026import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
027import org.kuali.rice.krad.document.Document;
028import org.kuali.rice.krad.document.DocumentRequestAuthorizationCache;
029import org.kuali.rice.krad.document.DocumentViewAuthorizerBase;
030import org.kuali.rice.krad.document.DocumentViewPresentationControllerBase;
031import org.kuali.rice.krad.keyvalues.KeyValuesFinder;
032import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
033import org.kuali.rice.krad.uif.UifConstants;
034import org.kuali.rice.krad.uif.util.LifecycleElement;
035import org.kuali.rice.krad.util.KRADConstants;
036
037/**
038 * View type for KRAD documents.
039 *
040 * <p>
041 * Provides commons configuration and default behavior applicable to documents
042 * in the KRAD module.
043 * </p>
044 *
045 * @author Kuali Rice Team (rice.collab@kuali.org)
046 */
047@BeanTag(name = "documentView", parent = "Uif-DocumentView")
048public class DocumentView extends FormView {
049        private static final long serialVersionUID = 2251983409572774175L;
050
051        private Class<? extends Document> documentClass;
052
053        private boolean allowsNoteAttachments = true;
054        private boolean allowsNoteFYI = false;
055        private boolean displayTopicFieldInNotes = false;
056    private boolean superUserView = false;
057
058    private Class<? extends KeyValuesFinder> attachmentTypesValuesFinderClass;
059
060        public DocumentView() {
061                super();
062
063        setRequestAuthorizationCacheClass(DocumentRequestAuthorizationCache.class);
064        }
065
066    /**
067     * The following initialization is performed:
068     *
069     * <ul>
070     * <li>Retrieve the document entry</li>
071     * <li>Makes sure that the header is set.</li>
072     * <li>Set up the document view authorizer and presentation controller</li>
073     * </ul>
074     *
075     * {@inheritDoc}
076     */
077    @Override
078    public void performInitialization(Object model) {
079        super.performInitialization(model);
080
081        // get document entry
082        DocumentEntry documentEntry = getDocumentEntryForView();
083        pushObjectToContext(UifConstants.ContextVariableNames.DOCUMENT_ENTRY, documentEntry);
084
085        // default document type on the header
086        String documentTypeName = documentEntry.getDocumentTypeName();
087        DocumentType documentType = KewApiServiceLocator.getDocumentTypeService().getDocumentTypeByName(documentTypeName);
088
089        if (getHeader() != null && StringUtils.isBlank(getHeaderText())) {
090            setHeaderText(documentType.getLabel());
091        }
092
093        // setup authorizer and presentation controller using the configured authorizer and pc for document
094        if (getAuthorizer() == null) {
095            setAuthorizer(new DocumentViewAuthorizerBase());
096        }
097
098        if (getAuthorizer() instanceof DocumentViewAuthorizerBase) {
099            DocumentViewAuthorizerBase documentViewAuthorizerBase = (DocumentViewAuthorizerBase) getAuthorizer();
100            if (documentViewAuthorizerBase.getDocumentAuthorizer() == null) {
101                documentViewAuthorizerBase.setDocumentAuthorizerClass(documentEntry.getDocumentAuthorizerClass());
102            }
103        }
104
105        if (getPresentationController() == null) {
106            setPresentationController(new DocumentViewPresentationControllerBase());
107        }
108
109        if (getPresentationController() instanceof DocumentViewPresentationControllerBase) {
110            DocumentViewPresentationControllerBase documentViewPresentationControllerBase =
111                    (DocumentViewPresentationControllerBase) getPresentationController();
112            if (documentViewPresentationControllerBase.getDocumentPresentationController() == null) {
113                documentViewPresentationControllerBase.setDocumentPresentationControllerClass(
114                        documentEntry.getDocumentPresentationControllerClass());
115            }
116        }
117
118        getObjectPathToConcreteClassMapping().put(getDefaultBindingObjectPath(), getDocumentClass());
119    }
120
121    /**
122     * Retrieves the associated {@link DocumentEntry} for the document view
123     *
124     * @return DocumentEntry entry (exception thrown if one is not found)
125     */
126    protected DocumentEntry getDocumentEntryForView() {
127        DocumentEntry documentEntry = KRADServiceLocatorWeb.getDocumentDictionaryService().getDocumentEntryByClass(
128                getDocumentClass());
129
130        if (documentEntry == null) {
131            throw new RuntimeException(
132                    "Unable to find document entry for document class: " + getDocumentClass().getName());
133        }
134
135        return documentEntry;
136    }
137
138    /**
139     * Returns the maximum allowed length for explanation notes within the document
140     *
141     * <p>
142     *     The max length for the explanation data is calculated as the difference between the max length of
143     *     the entire note and the length of the introduction message plus a whitespace.
144     * </p>
145     *
146     * @return int
147     */
148    @BeanTagAttribute(name = "explanationDataMaxLength")
149    public int getExplanationDataMaxLength() {
150        return KRADServiceLocatorWeb.getDataDictionaryService().getAttributeMaxLength(Note.class,
151                KRADConstants.NOTE_TEXT_PROPERTY_NAME) -
152                (CoreApiServiceLocator.getKualiConfigurationService().getPropertyValueAsString(
153                        RiceKeyConstants.MESSAGE_DISAPPROVAL_NOTE_TEXT_INTRO) + KRADConstants.BLANK_SPACE).length();
154    }
155
156    /**
157     * Gets the document class
158     *
159     * @return Class<? extends Document> the document class.
160     */
161    @BeanTagAttribute
162        public Class<? extends Document> getDocumentClass() {
163                return this.documentClass;
164        }
165
166    /**
167     * Sets the document class
168     *
169     * @param documentClass
170     */
171        public void setDocumentClass(Class<? extends Document> documentClass) {
172                this.documentClass = documentClass;
173        }
174
175    /**
176     * Gets boolean that indicates if the document view allows note attachments
177     *
178     * @return true if the document view allows note attachments
179     */
180    @BeanTagAttribute
181        public boolean isAllowsNoteAttachments() {
182                return this.allowsNoteAttachments;
183        }
184
185    /**
186     * Sets boolean that indicates if the document view allows note attachments
187     *
188     * @param allowsNoteAttachments
189     */
190        public void setAllowsNoteAttachments(boolean allowsNoteAttachments) {
191                this.allowsNoteAttachments = allowsNoteAttachments;
192        }
193
194    /**
195     * Gets boolean that indicates if the document view allows note FYI
196     *
197     * @return true if the document view allows note FYI
198     */
199    @BeanTagAttribute
200        public boolean isAllowsNoteFYI() {
201                return this.allowsNoteFYI;
202        }
203
204    /**
205     * Sets boolean that indicates if the document view allows note FYI
206     *
207     * @param allowsNoteFYI
208     */
209        public void setAllowsNoteFYI(boolean allowsNoteFYI) {
210                this.allowsNoteFYI = allowsNoteFYI;
211        }
212
213    /**
214     * Gets boolean that indicates if the document view displays the topic field in notes
215     *
216     * @return true if the document view displays the topic field in notes
217     */
218    @BeanTagAttribute
219        public boolean isDisplayTopicFieldInNotes() {
220                return this.displayTopicFieldInNotes;
221        }
222
223    /**
224     * Sets boolean that indicates if the document view displays the topic field in notes
225     *
226     * @param displayTopicFieldInNotes
227     */
228        public void setDisplayTopicFieldInNotes(boolean displayTopicFieldInNotes) {
229                this.displayTopicFieldInNotes = displayTopicFieldInNotes;
230        }
231
232    /**
233     * Gets attachment types values finder classs
234     *
235     * @return attachment types values finder class
236     */
237    @BeanTagAttribute
238        public Class<? extends KeyValuesFinder> getAttachmentTypesValuesFinderClass() {
239                return this.attachmentTypesValuesFinderClass;
240        }
241
242    /**
243     * Sets attachment types values finder classs
244     *
245     * @param attachmentTypesValuesFinderClass
246     */
247        public void setAttachmentTypesValuesFinderClass(Class<? extends KeyValuesFinder> attachmentTypesValuesFinderClass) {
248                this.attachmentTypesValuesFinderClass = attachmentTypesValuesFinderClass;
249        }
250
251    /**
252     * Indicates whether the view is a super user view, used for
253     * KEW functionality
254     *
255     * @return true if the view is a super user viwe
256     */
257    public boolean isSuperUserView() {
258        return superUserView;
259    }
260
261    /**
262     * @see DocumentView#isSuperUserView()
263     */
264    public void setSuperUserView(boolean superUserView) {
265        checkMutable(true);
266        this.superUserView = superUserView;
267    }
268
269}