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.element;
017
018import org.apache.commons.lang.StringUtils;
019import org.kuali.rice.krad.datadictionary.parse.BeanTag;
020import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
021import org.kuali.rice.krad.uif.component.Component;
022import org.kuali.rice.krad.uif.container.PageGroup;
023import org.kuali.rice.krad.uif.lifecycle.LifecycleEventListener;
024import org.kuali.rice.krad.uif.lifecycle.ViewLifecycle;
025import org.kuali.rice.krad.uif.util.LifecycleElement;
026import org.kuali.rice.krad.uif.view.View;
027import org.kuali.rice.krad.util.GlobalVariables;
028import org.kuali.rice.krad.util.MessageMap;
029
030import java.util.HashSet;
031import java.util.Set;
032
033/**
034 * ValidationMessages for logic and options specific to pages.
035 *
036 * @author Kuali Rice Team (rice.collab@kuali.org)
037 */
038@BeanTag(name = "pageValidationMessages", parent = "Uif-PageValidationMessages")
039public class PageValidationMessages extends GroupValidationMessages implements LifecycleEventListener {
040    private static final long serialVersionUID = 6387432156428507958L;
041
042    private boolean showPageSummaryHeader;
043
044    /**
045     * {@inheritDoc}
046     */
047    @Override
048    public void generateMessages(View view, Object model, Component parent) {
049        super.generateMessages(view, model, parent);
050
051        ViewLifecycle viewLifecycle = ViewLifecycle.getActiveLifecycle();
052        viewLifecycle.registerLifecycleCompleteListener(view, this);
053    }
054
055    /**
056     * Overridding to prevent the initial writing of data attributes until the view has been processed and
057     * we collection unmatched messages (through the lifecycle event).
058     *
059     * {@inheritDoc}
060     */
061    @Override
062    protected void addValidationMessageDataAttributes(Component parent) {
063        // do nothing
064    }
065
066    /**
067     * Check for message keys that are not matched anywhere on the page, these unmatched messages must still be
068     * displayed at the page level.
069     *
070     * {@inheritDoc}
071     */
072    @Override
073    public void processEvent(ViewLifecycle.LifecycleEvent lifecycleEvent, View view, Object model,
074            LifecycleElement eventElement) {
075        View eventComponent = (View) eventElement;
076        PageGroup currentPage = eventComponent.getCurrentPage();
077
078        Set<String> allPossibleKeys = new HashSet<String>();
079
080        Set<String> renderedPropertyPaths = ViewLifecycle.getViewPostMetadata().getAllRenderedPropertyPaths();
081        if (renderedPropertyPaths != null) {
082            allPossibleKeys.addAll(renderedPropertyPaths);
083        }
084
085        addNestedGroupKeys(allPossibleKeys, currentPage);
086
087        if (getAdditionalKeysToMatch() != null) {
088            allPossibleKeys.addAll(getAdditionalKeysToMatch());
089        }
090
091        if (StringUtils.isNotBlank(currentPage.getId())) {
092            allPossibleKeys.add(currentPage.getId());
093        }
094
095        MessageMap messageMap = GlobalVariables.getMessageMap();
096
097        Set<String> messageKeys = new HashSet<String>();
098
099        messageKeys.addAll(messageMap.getAllPropertiesWithErrors());
100        messageKeys.addAll(messageMap.getAllPropertiesWithWarnings());
101        messageKeys.addAll(messageMap.getAllPropertiesWithInfo());
102
103        messageKeys.removeAll(allPossibleKeys);
104
105        for (String key : messageKeys) {
106            getErrors().addAll(getMessages(view, key, messageMap.getErrorMessagesForProperty(key, true)));
107            getWarnings().addAll(getMessages(view, key, messageMap.getWarningMessagesForProperty(key, true)));
108            getInfos().addAll(getMessages(view, key, messageMap.getInfoMessagesForProperty(key, true)));
109        }
110
111        super.addValidationMessageDataAttributes(currentPage);
112    }
113
114    /**
115     * If true, shows the page summary header (message count header message in the message block).  Otherwise, this
116     * header is not rendered.
117     *
118     * @return true if the header will show, false otherwise
119     */
120    @BeanTagAttribute
121    public boolean isShowPageSummaryHeader() {
122        return showPageSummaryHeader;
123    }
124
125    /**
126     * Set the page summary header to show or not show.
127     *
128     * @param showPageSummaryHeader
129     */
130    public void setShowPageSummaryHeader(boolean showPageSummaryHeader) {
131        this.showPageSummaryHeader = showPageSummaryHeader;
132    }
133}