<commit_before>/**
 * Copyright 2005-2014 The Kuali Foundation
 *
 * Licensed under the Educational Community License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.opensource.org/licenses/ecl2.php
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.kuali.rice.krad.uif.field;

import java.beans.PropertyEditor;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Queue;

import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
import org.kuali.rice.core.api.exception.RiceRuntimeException;
import org.kuali.rice.core.api.util.type.TypeUtils;
import org.kuali.rice.krad.bo.DataObjectRelationship;
import org.kuali.rice.krad.bo.KualiCode;
import org.kuali.rice.krad.datadictionary.AttributeDefinition;
import org.kuali.rice.krad.datadictionary.mask.MaskFormatter;
import org.kuali.rice.krad.datadictionary.parse.BeanTag;
import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
import org.kuali.rice.krad.datadictionary.parse.BeanTags;
import org.kuali.rice.krad.datadictionary.validator.ValidationTrace;
import org.kuali.rice.krad.datadictionary.validator.Validator;
import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
import org.kuali.rice.krad.uif.UifConstants;
import org.kuali.rice.krad.uif.component.BindingInfo;
import org.kuali.rice.krad.uif.component.ComponentSecurity;
import org.kuali.rice.krad.uif.lifecycle.LifecycleTaskFactory;
import org.kuali.rice.krad.uif.lifecycle.ViewLifecycle;
import org.kuali.rice.krad.uif.lifecycle.ViewLifecyclePhase;
import org.kuali.rice.krad.uif.lifecycle.ViewLifecycleTask;
import org.kuali.rice.krad.uif.lifecycle.ViewPostMetadata;
import org.kuali.rice.krad.uif.util.ComponentFactory;
import org.kuali.rice.krad.uif.util.LifecycleAwareList;
import org.kuali.rice.krad.uif.util.LifecycleElement;
import org.kuali.rice.krad.uif.util.ObjectPropertyUtils;
import org.kuali.rice.krad.uif.util.ViewModelUtils;
import org.kuali.rice.krad.uif.view.View;
import org.kuali.rice.krad.uif.widget.Help;
import org.kuali.rice.krad.uif.widget.Inquiry;
import org.kuali.rice.krad.uif.widget.Tooltip;
import org.kuali.rice.krad.util.KRADPropertyConstants;
import org.kuali.rice.krad.util.KRADUtils;
import org.kuali.rice.krad.valuefinder.ValueFinder;

/**
 * Field that renders data from the application, such as the value of a data object property
 *
 * @author Kuali Rice Team (<EMAIL>)
 */
@BeanTags({@BeanTag(name = "dataField-bean", parent = "Uif-DataField"),
        @BeanTag(name = "dataField-labelTop-bean", parent = "Uif-DataField-LabelTop"),
        @BeanTag(name = "dataField-labelRight-bean", parent = "Uif-DataField-LabelRight"),
        @BeanTag(name = "dataField-withoutLabel-bean", parent = "Uif-DataField-withoutLabel")})
public class DataFieldBase extends FieldBase implements DataField {
    private static final long serialVersionUID = -4129678891948564724L;

    // binding
    private String propertyName;
    private BindingInfo bindingInfo;

    private String dictionaryAttributeName;
    private String dictionaryObjectEntry;

    // value props
    private Object defaultValue;
    private Class<? extends ValueFinder> defaultValueFinderClass;
    private Object[] defaultValues;
    private String forcedValue;

    private PropertyEditor propertyEditor;

    private boolean addHiddenWhenReadOnly;

    // read only display properties
    protected String readOnlyDisplayReplacementPropertyName;
    protected String readOnlyDisplaySuffixPropertyName;

    private String readOnlyDisplayReplacement;
    private String readOnlyDisplaySuffix;

    private String readOnlyListDisplayType;
    private String readOnlyListDelimiter;

    private boolean applyMask;
    private MaskFormatter maskFormatter;

    private List<String> additionalHiddenPropertyNames;
    private List<String> propertyNamesForAdditionalDisplay;

    private boolean escapeHtmlInPropertyValue;
    private boolean multiLineReadOnlyDisplay;

    // widgets
    private Inquiry inquiry;
    private boolean enableAutoInquiry;

    private Help help;

    // Optional span render flags
    private boolean renderInfoMessageSpan;
    private boolean renderMarkerIconSpan;

    public DataFieldBase() {
        super();

        enableAutoInquiry = true;
        escapeHtmlInPropertyValue = true;

        additionalHiddenPropertyNames = Collections.emptyList();
        propertyNamesForAdditionalDisplay = Collections.emptyList();
    }

    /**
     * The following initialization is performed:
     *
     * <ul>
     * <li>Set defaults for binding</li>
     * <li>Default the model path if not set</li>
     * </ul>
     *
     * {@inheritDoc}
     */
    @Override
    public void performInitialization(Object model) {
        super.performInitialization(model);

        if (bindingInfo != null) {
            bindingInfo.setDefaults(ViewLifecycle.getView(), getPropertyName());
        }
    }

    /**
     * The following updates are done here:
     *
     * <ul>
     * <li>If readOnlyHidden set to true, set field to readonly and add to hidden property names</li>
     * </ul>
     */
    @Override
    public void performApplyModel(Object model, LifecycleElement parent) {
        super.performApplyModel(model, parent);

        if (this.enableAutoInquiry && (this.inquiry == null) && isReadOnly()) {
            buildAutomaticInquiry(model, false);
        }

        if (isAddHiddenWhenReadOnly()) {
            setReadOnly(true);
            getAdditionalHiddenPropertyNames().add(getPropertyName());
        }
    }

    /**
     * The following actions are performed:
     *
     * <ul>
     * <li>Set the ids for the various attribute components</li>
     * <li>Sets up the client side validation for constraints on this field. In
     * addition, it sets up the messages applied to this field</li>
     * <li>If this field is of type list and readOnly, generates the appropriate readOnly output.  Handles other
     * readOnlyReplacement cases, as well.</li>
     * </ul>
     *
     * {@inheritDoc}
     */
    @Override
    public void performFinalize(Object model, LifecycleElement parent) {
        super.performFinalize(model, parent);

        // adjust the path for hidden fields
        // TODO: should this check the view#readOnly?
        List<String> hiddenPropertyPaths = new ArrayList<String>();
        for (String hiddenPropertyName : getAdditionalHiddenPropertyNames()) {
            String hiddenPropertyPath = getBindingInfo().getPropertyAdjustedBindingPath(hiddenPropertyName);
            hiddenPropertyPaths.add(hiddenPropertyPath);
        }
        this.additionalHiddenPropertyNames = hiddenPropertyPaths;

        // adjust paths on informational property names
        List<String> informationalPropertyPaths = new ArrayList<String>();
        for (String infoPropertyName : getPropertyNamesForAdditionalDisplay()) {
            String infoPropertyPath = getBindingInfo().getPropertyAdjustedBindingPath(infoPropertyName);
            informationalPropertyPaths.add(infoPropertyPath);
        }
        this.propertyNamesForAdditionalDisplay = informationalPropertyPaths;

        // special processing for List<?> readOnly
        String bindingPath = getBindingInfo().getBindingPath();
        Class<?> type = StringUtils.isNotEmpty(bindingPath) ? ObjectPropertyUtils.getPropertyType(model, bindingPath) :
                null;
        if (this.isReadOnly() && type != null && List.class.isAssignableFrom(type) && StringUtils.isBlank(
                getReadOnlyDisplayReplacement()) && StringUtils.isBlank(getReadOnlyDisplayReplacementPropertyName())) {
            //get the list
            Object fieldValue = ObjectPropertyUtils.getPropertyValue(model, getBindingInfo().getBindingPath());

            //check for null, empty or non-simple type content (not supported by DataField)
            if (fieldValue != null && fieldValue instanceof List<?> && !((List) fieldValue).isEmpty()) {
                List<?> list = (List<?>) fieldValue;
                processReadOnlyListDisplay(model, list);
            } else {
                this.setReadOnlyDisplayReplacement("&nbsp;");
            }

        } else {
            // Additional and Alternate display value
            setAlternateAndAdditionalDisplayValue(ViewLifecycle.getView(), model);
        }

        if (this.getFieldLabel() != null && StringUtils.isNotBlank(this.getId())) {
            this.getFieldLabel().setLabelForComponentId(this.getId() + UifConstants.IdSuffixes.CONTROL);
        }

        if (this.getDefaultValue()!=null) {
            ObjectPropertyUtils.setPropertyValue(model, this.getBindingInfo().getBindingName(), this.getDefaultValue());
        }

        ViewPostMetadata viewPostMetadata = ViewLifecycle.getViewPostMetadata();
        if (isRender() && viewPostMetadata != null) {
            viewPostMetadata.addRenderedPropertyPath(getBindingInfo().getBindingPath());
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void initializePendingTasks(ViewLifecyclePhase phase, Queue<ViewLifecycleTask<?>> pendingTasks) {
        if (phase.getViewPhase().equals(UifConstants.ViewPhases.INITIALIZE)) {
            pendingTasks.offer(LifecycleTaskFactory.getTask(InitializeDataFieldFromDictionaryTask.class, phase));
        }
        
        super.initializePendingTasks(phase, pendingTasks);
    }
<commit_msg>KULRICE-11996 modification so that the default value is populated correctly, using the bindingpath rather than the binding name<commit_after>/**
 * Copyright 2005-2014 The Kuali Foundation
 *
 * Licensed under the Educational Community License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.opensource.org/licenses/ecl2.php
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.kuali.rice.krad.uif.field;

import java.beans.PropertyEditor;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Queue;

import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
import org.kuali.rice.core.api.exception.RiceRuntimeException;
import org.kuali.rice.core.api.util.type.TypeUtils;
import org.kuali.rice.krad.bo.DataObjectRelationship;
import org.kuali.rice.krad.bo.KualiCode;
import org.kuali.rice.krad.datadictionary.AttributeDefinition;
import org.kuali.rice.krad.datadictionary.mask.MaskFormatter;
import org.kuali.rice.krad.datadictionary.parse.BeanTag;
import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
import org.kuali.rice.krad.datadictionary.parse.BeanTags;
import org.kuali.rice.krad.datadictionary.validator.ValidationTrace;
import org.kuali.rice.krad.datadictionary.validator.Validator;
import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
import org.kuali.rice.krad.uif.UifConstants;
import org.kuali.rice.krad.uif.component.BindingInfo;
import org.kuali.rice.krad.uif.component.ComponentSecurity;
import org.kuali.rice.krad.uif.lifecycle.LifecycleTaskFactory;
import org.kuali.rice.krad.uif.lifecycle.ViewLifecycle;
import org.kuali.rice.krad.uif.lifecycle.ViewLifecyclePhase;
import org.kuali.rice.krad.uif.lifecycle.ViewLifecycleTask;
import org.kuali.rice.krad.uif.lifecycle.ViewPostMetadata;
import org.kuali.rice.krad.uif.util.ComponentFactory;
import org.kuali.rice.krad.uif.util.LifecycleAwareList;
import org.kuali.rice.krad.uif.util.LifecycleElement;
import org.kuali.rice.krad.uif.util.ObjectPropertyUtils;
import org.kuali.rice.krad.uif.util.ViewModelUtils;
import org.kuali.rice.krad.uif.view.View;
import org.kuali.rice.krad.uif.widget.Help;
import org.kuali.rice.krad.uif.widget.Inquiry;
import org.kuali.rice.krad.uif.widget.Tooltip;
import org.kuali.rice.krad.util.KRADPropertyConstants;
import org.kuali.rice.krad.util.KRADUtils;
import org.kuali.rice.krad.valuefinder.ValueFinder;

/**
 * Field that renders data from the application, such as the value of a data object property
 *
 * @author Kuali Rice Team (<EMAIL>)
 */
@BeanTags({@BeanTag(name = "dataField-bean", parent = "Uif-DataField"),
        @BeanTag(name = "dataField-labelTop-bean", parent = "Uif-DataField-LabelTop"),
        @BeanTag(name = "dataField-labelRight-bean", parent = "Uif-DataField-LabelRight"),
        @BeanTag(name = "dataField-withoutLabel-bean", parent = "Uif-DataField-withoutLabel")})
public class DataFieldBase extends FieldBase implements DataField {
    private static final long serialVersionUID = -4129678891948564724L;

    // binding
    private String propertyName;
    private BindingInfo bindingInfo;

    private String dictionaryAttributeName;
    private String dictionaryObjectEntry;

    // value props
    private Object defaultValue;
    private Class<? extends ValueFinder> defaultValueFinderClass;
    private Object[] defaultValues;
    private String forcedValue;

    private PropertyEditor propertyEditor;

    private boolean addHiddenWhenReadOnly;

    // read only display properties
    protected String readOnlyDisplayReplacementPropertyName;
    protected String readOnlyDisplaySuffixPropertyName;

    private String readOnlyDisplayReplacement;
    private String readOnlyDisplaySuffix;

    private String readOnlyListDisplayType;
    private String readOnlyListDelimiter;

    private boolean applyMask;
    private MaskFormatter maskFormatter;

    private List<String> additionalHiddenPropertyNames;
    private List<String> propertyNamesForAdditionalDisplay;

    private boolean escapeHtmlInPropertyValue;
    private boolean multiLineReadOnlyDisplay;

    // widgets
    private Inquiry inquiry;
    private boolean enableAutoInquiry;

    private Help help;

    // Optional span render flags
    private boolean renderInfoMessageSpan;
    private boolean renderMarkerIconSpan;

    public DataFieldBase() {
        super();

        enableAutoInquiry = true;
        escapeHtmlInPropertyValue = true;

        additionalHiddenPropertyNames = Collections.emptyList();
        propertyNamesForAdditionalDisplay = Collections.emptyList();
    }

    /**
     * The following initialization is performed:
     *
     * <ul>
     * <li>Set defaults for binding</li>
     * <li>Default the model path if not set</li>
     * </ul>
     *
     * {@inheritDoc}
     */
    @Override
    public void performInitialization(Object model) {
        super.performInitialization(model);

        if (bindingInfo != null) {
            bindingInfo.setDefaults(ViewLifecycle.getView(), getPropertyName());
        }
    }

    /**
     * The following updates are done here:
     *
     * <ul>
     * <li>If readOnlyHidden set to true, set field to readonly and add to hidden property names</li>
     * </ul>
     */
    @Override
    public void performApplyModel(Object model, LifecycleElement parent) {
        super.performApplyModel(model, parent);

        if (this.enableAutoInquiry && (this.inquiry == null) && isReadOnly()) {
            buildAutomaticInquiry(model, false);
        }

        if (isAddHiddenWhenReadOnly()) {
            setReadOnly(true);
            getAdditionalHiddenPropertyNames().add(getPropertyName());
        }
    }

    /**
     * The following actions are performed:
     *
     * <ul>
     * <li>Set the ids for the various attribute components</li>
     * <li>Sets up the client side validation for constraints on this field. In
     * addition, it sets up the messages applied to this field</li>
     * <li>If this field is of type list and readOnly, generates the appropriate readOnly output.  Handles other
     * readOnlyReplacement cases, as well.</li>
     * </ul>
     *
     * {@inheritDoc}
     */
    @Override
    public void performFinalize(Object model, LifecycleElement parent) {
        super.performFinalize(model, parent);

        // adjust the path for hidden fields
        // TODO: should this check the view#readOnly?
        List<String> hiddenPropertyPaths = new ArrayList<String>();
        for (String hiddenPropertyName : getAdditionalHiddenPropertyNames()) {
            String hiddenPropertyPath = getBindingInfo().getPropertyAdjustedBindingPath(hiddenPropertyName);
            hiddenPropertyPaths.add(hiddenPropertyPath);
        }
        this.additionalHiddenPropertyNames = hiddenPropertyPaths;

        // adjust paths on informational property names
        List<String> informationalPropertyPaths = new ArrayList<String>();
        for (String infoPropertyName : getPropertyNamesForAdditionalDisplay()) {
            String infoPropertyPath = getBindingInfo().getPropertyAdjustedBindingPath(infoPropertyName);
            informationalPropertyPaths.add(infoPropertyPath);
        }
        this.propertyNamesForAdditionalDisplay = informationalPropertyPaths;

        // special processing for List<?> readOnly
        String bindingPath = getBindingInfo().getBindingPath();
        Class<?> type = StringUtils.isNotEmpty(bindingPath) ? ObjectPropertyUtils.getPropertyType(model, bindingPath) :
                null;
        if (this.isReadOnly() && type != null && List.class.isAssignableFrom(type) && StringUtils.isBlank(
                getReadOnlyDisplayReplacement()) && StringUtils.isBlank(getReadOnlyDisplayReplacementPropertyName())) {
            //get the list
            Object fieldValue = ObjectPropertyUtils.getPropertyValue(model, getBindingInfo().getBindingPath());

            //check for null, empty or non-simple type content (not supported by DataField)
            if (fieldValue != null && fieldValue instanceof List<?> && !((List) fieldValue).isEmpty()) {
                List<?> list = (List<?>) fieldValue;
                processReadOnlyListDisplay(model, list);
            } else {
                this.setReadOnlyDisplayReplacement("&nbsp;");
            }

        } else {
            // Additional and Alternate display value
            setAlternateAndAdditionalDisplayValue(ViewLifecycle.getView(), model);
        }

        if (this.getFieldLabel() != null && StringUtils.isNotBlank(this.getId())) {
            this.getFieldLabel().setLabelForComponentId(this.getId() + UifConstants.IdSuffixes.CONTROL);
        }

        if (this.getDefaultValue()!=null) {
            ObjectPropertyUtils.setPropertyValue(model, this.getBindingInfo().getBindingPath(), this.getDefaultValue());
        }

        ViewPostMetadata viewPostMetadata = ViewLifecycle.getViewPostMetadata();
        if (isRender() && viewPostMetadata != null) {
            viewPostMetadata.addRenderedPropertyPath(getBindingInfo().getBindingPath());
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void initializePendingTasks(ViewLifecyclePhase phase, Queue<ViewLifecycleTask<?>> pendingTasks) {
        if (phase.getViewPhase().equals(UifConstants.ViewPhases.INITIALIZE)) {
            pendingTasks.offer(LifecycleTaskFactory.getTask(InitializeDataFieldFromDictionaryTask.class, phase));
        }
        
        super.initializePendingTasks(phase, pendingTasks);
    }

{'fraction_non_alphanumeric': 0.09615579673394868, 'fraction_numerical': 0.0032964803732630082, 'mean_word_length': 3.5237439779766, 'pattern_counts': {'":': 0, '<': 69, '<?xml version=': 0, '>': 69, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7326084', 'n_tokens_mistral': 5514, 'n_tokens_neox': 5409, 'n_words': 1227}