<commit_before>/**
 *  Copyright (C) 2006 Orbeon, Inc.
 *
 *  This program is free software; you can redistribute it and/or modify it under the terms of the
 *  GNU Lesser General Public License as published by the Free Software Foundation; either version
 *  2.1 of the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *  See the GNU Lesser General Public License for more details.
 *
 *  The full text of the license is available at http://www.gnu.org/copyleft/lesser.html
 */
package org.orbeon.oxf.xforms.control.controls;

import org.dom4j.Element;
import org.dom4j.QName;
import org.orbeon.oxf.pipeline.api.PipelineContext;
import org.orbeon.oxf.xforms.XFormsConstants;
import org.orbeon.oxf.xforms.XFormsContainingDocument;
import org.orbeon.oxf.xforms.XFormsItemUtils;
import org.orbeon.oxf.xforms.XFormsProperties;
import org.orbeon.oxf.xforms.control.XFormsControl;
import org.orbeon.oxf.xforms.control.XFormsValueControl;
import org.orbeon.oxf.xml.XMLConstants;
import org.orbeon.oxf.util.XPathCache;
import org.orbeon.saxon.om.NodeInfo;

import java.util.Map;
import java.util.HashMap;

/**
 * Represents an xforms:input control.
 */
public class XFormsInputControl extends XFormsValueControl {

    // Optional display format
    private String format;

    public XFormsInputControl(XFormsContainingDocument containingDocument, XFormsControl parent, Element element, String name, String id) {
        super(containingDocument, parent, element, name, id);
        this.format = element.attributeValue(new QName("format", XFormsConstants.XXFORMS_NAMESPACE));
    }

    public String getFormat() {
        return format;
    }

//    public void evaluateDisplayValue(PipelineContext pipelineContext) {
//        getValueUseFormat(pipelineContext, format);
//    }

    protected void evaluateExternalValue(PipelineContext pipelineContext) {

        final String internalValue = getValue(pipelineContext);
        final String updatedValue;

        final String typeName = getBuiltinTypeName();
        if (typeName != null) {
            if (typeName.equals("boolean")) {
                // xs:boolean

                if (internalValue != null && !internalValue.equals("true")) {
                    // This so we don't send "false" to the client but ""
                    updatedValue = "";
                } else {
                    if (XFormsProperties.isEncryptItemValues(containingDocument)) {
                        // Encrypt outgoing value if needed
                        updatedValue = XFormsItemUtils.encryptValue(pipelineContext, internalValue);
                    } else {
                        // For open selection, values sent to client are the internal values
                        updatedValue = internalValue;
                    }
                }
            } else {
                // Other types
            updatedValue = internalValue;
            }
        } else {
            // No type
            updatedValue = internalValue;
        }

        setExternalValue(updatedValue);
    }

    public void storeExternalValue(PipelineContext pipelineContext, String value, String type) {
        super.storeExternalValue(pipelineContext, convertFromExternalValue(pipelineContext, value), type);
    }

    private String convertFromExternalValue(PipelineContext pipelineContext, String externalValue) {
        final String typeName = getBuiltinTypeName();
        if (typeName != null && typeName.equals("boolean")) {
            // xs:boolean input

            // Decrypt incoming value if needed. With open selection, values are sent to the client.
            if (XFormsProperties.isEncryptItemValues(containingDocument))
                externalValue = XFormsItemUtils.decryptValue(pipelineContext, externalValue);

            // Anything but "true" is "false"
            if (!externalValue.equals("true"))
                externalValue = "false";
        }

        return externalValue;
    }

    /**
     * Convenience method for handler: return the value of the first input field.
     *
     * @param pipelineContext   pipeline context
     * @return                  value to store in the first input field
     */
    public String getFirstValueUseFormat(PipelineContext pipelineContext) {
        final String result;

        final String typeName = getBuiltinTypeName();
        if ("date".equals(typeName) || "time".equals(typeName) || "dateTime".equals(typeName)) {
            // Format value specially

            // Assume xs: prefix for default formats
            final Map prefixToURIMap = new HashMap();
            prefixToURIMap.put(XMLConstants.XSD_PREFIX, XMLConstants.XSD_URI);

            final NodeInfo boundNode = getBoundNode();
            if (boundNode == null) {
                result = null;
            } else {

                final String xpathExpression =
                        "if (. castable as xs:dateTime) then format-dateTime(xs:dateTime(.), '"
                                + XFormsProperties.getTypeInputFormat(containingDocument, getFirstValueType())
                                + "', 'en', (), ()) else .";

                result = XPathCache.evaluateAsString(pipelineContext, boundNode,
                        xpathExpression,
                        prefixToURIMap, getContextStack().getCurrentVariables(),
                        XFormsContainingDocument.getFunctionLibrary(),
                        getContextStack().getFunctionContext(), null, getLocationData());
            }

        } else {
            // Regular case, use external value
            result = getExternalValue(pipelineContext);
        }

        return (result != null) ? result : "";
    }

    /**
     * Convenience method for handler: return the value of the second input field.
     *
     * @param pipelineContext   pipeline context
     * @return                  value to store in the second input field
     */
    public String getSecondValueUseFormat(PipelineContext pipelineContext) {
        final String result;

        final String typeName = getBuiltinTypeName();
        if ("dateTime".equals(typeName)) {
            // Format value specially

            // Assume xs: prefix for default formats
            final Map prefixToURIMap = new HashMap();
            prefixToURIMap.put(XMLConstants.XSD_PREFIX, XMLConstants.XSD_URI);

            final NodeInfo boundNode = getBoundNode();
            if (boundNode == null) {
                result = null;
            } else {

                final String xpathExpression =
                        "if (. castable as xs:dateTime) then format-dateTime(xs:dateTime(.), '"
                                + XFormsProperties.getTypeInputFormat(containingDocument, getSecondValueType())
                                + "', 'en', (), ()) else .";

                result = XPathCache.evaluateAsString(pipelineContext, boundNode,
                        xpathExpression,
                        prefixToURIMap, getContextStack().getCurrentVariables(),
                        XFormsContainingDocument.getFunctionLibrary(),
                        getContextStack().getFunctionContext(), null, getLocationData());
            }

        } else {
            // N/A
            result = null;
        }

        return (result != null) ? result : "";
    }

    public String getFirstValueType() {
        final String typeName = getBuiltinTypeName();
        if ("dateTime".equals(typeName)) {
            return "date";
        } else {<commit_msg>Fixed formatting.<commit_after>/**
 *  Copyright (C) 2006 Orbeon, Inc.
 *
 *  This program is free software; you can redistribute it and/or modify it under the terms of the
 *  GNU Lesser General Public License as published by the Free Software Foundation; either version
 *  2.1 of the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *  See the GNU Lesser General Public License for more details.
 *
 *  The full text of the license is available at http://www.gnu.org/copyleft/lesser.html
 */
package org.orbeon.oxf.xforms.control.controls;

import org.dom4j.Element;
import org.dom4j.QName;
import org.orbeon.oxf.pipeline.api.PipelineContext;
import org.orbeon.oxf.xforms.XFormsConstants;
import org.orbeon.oxf.xforms.XFormsContainingDocument;
import org.orbeon.oxf.xforms.XFormsItemUtils;
import org.orbeon.oxf.xforms.XFormsProperties;
import org.orbeon.oxf.xforms.control.XFormsControl;
import org.orbeon.oxf.xforms.control.XFormsValueControl;
import org.orbeon.oxf.xml.XMLConstants;
import org.orbeon.oxf.util.XPathCache;
import org.orbeon.saxon.om.NodeInfo;

import java.util.Map;
import java.util.HashMap;

/**
 * Represents an xforms:input control.
 */
public class XFormsInputControl extends XFormsValueControl {

    // Optional display format
    private String format;

    public XFormsInputControl(XFormsContainingDocument containingDocument, XFormsControl parent, Element element, String name, String id) {
        super(containingDocument, parent, element, name, id);
        this.format = element.attributeValue(new QName("format", XFormsConstants.XXFORMS_NAMESPACE));
    }

    public String getFormat() {
        return format;
    }

//    public void evaluateDisplayValue(PipelineContext pipelineContext) {
//        getValueUseFormat(pipelineContext, format);
//    }

    protected void evaluateExternalValue(PipelineContext pipelineContext) {

        final String internalValue = getValue(pipelineContext);
        final String updatedValue;

        final String typeName = getBuiltinTypeName();
        if (typeName != null) {
            if (typeName.equals("boolean")) {
                // xs:boolean

                if (internalValue != null && !internalValue.equals("true")) {
                    // This so we don't send "false" to the client but ""
                    updatedValue = "";
                } else {
                    if (XFormsProperties.isEncryptItemValues(containingDocument)) {
                        // Encrypt outgoing value if needed
                        updatedValue = XFormsItemUtils.encryptValue(pipelineContext, internalValue);
                    } else {
                        // For open selection, values sent to client are the internal values
                        updatedValue = internalValue;
                    }
                }
            } else {
                // Other types
            updatedValue = internalValue;
            }
        } else {
            // No type
            updatedValue = internalValue;
        }

        setExternalValue(updatedValue);
    }

    public void storeExternalValue(PipelineContext pipelineContext, String value, String type) {
        super.storeExternalValue(pipelineContext, convertFromExternalValue(pipelineContext, value), type);
    }

    private String convertFromExternalValue(PipelineContext pipelineContext, String externalValue) {
        final String typeName = getBuiltinTypeName();
        if (typeName != null && typeName.equals("boolean")) {
            // xs:boolean input

            // Decrypt incoming value if needed. With open selection, values are sent to the client.
            if (XFormsProperties.isEncryptItemValues(containingDocument))
                externalValue = XFormsItemUtils.decryptValue(pipelineContext, externalValue);

            // Anything but "true" is "false"
            if (!externalValue.equals("true"))
                externalValue = "false";
        }

        return externalValue;
    }

    /**
     * Convenience method for handler: return the value of the first input field.
     *
     * @param pipelineContext   pipeline context
     * @return                  value to store in the first input field
     */
    public String getFirstValueUseFormat(PipelineContext pipelineContext) {
        final String result;

        final String typeName = getBuiltinTypeName();
        if ("date".equals(typeName) || "time".equals(typeName) || "dateTime".equals(typeName)) {
            // Format value specially
            result = format(pipelineContext, typeName, getFirstValueType());
        } else {
            // Regular case, use external value
            result = getExternalValue(pipelineContext);
        }

        return (result != null) ? result : "";
    }

    /**
     * Convenience method for handler: return the value of the second input field.
     *
     * @param pipelineContext   pipeline context
     * @return                  value to store in the second input field
     */
    public String getSecondValueUseFormat(PipelineContext pipelineContext) {
        final String result;

        final String typeName = getBuiltinTypeName();
        if ("dateTime".equals(typeName)) {
            // Format value specially
            result = format(pipelineContext, typeName, getSecondValueType());
        } else {
            // N/A
            result = null;
        }

        return (result != null) ? result : "";
    }

    private String format(PipelineContext pipelineContext, String typeName, String formatName) {
        // Assume xs: prefix for default formats
        final Map prefixToURIMap = new HashMap();
        prefixToURIMap.put(XMLConstants.XSD_PREFIX, XMLConstants.XSD_URI);

        final NodeInfo boundNode = getBoundNode();
        if (boundNode == null) {
            // Can't format
            return null;
        } else {
            // Format
            final String xpathExpression =
                    "if (. castable as xs:" + typeName + ") then format-" + typeName + "(xs:" + typeName + "(.), '"
                            + XFormsProperties.getTypeInputFormat(containingDocument, formatName)
                            + "', 'en', (), ()) else .";

            return XPathCache.evaluateAsString(pipelineContext, boundNode,
                    xpathExpression,
                    prefixToURIMap, getContextStack().getCurrentVariables(),
                    XFormsContainingDocument.getFunctionLibrary(),
                    getContextStack().getFunctionContext(), null, getLocationData());
        }
    }

    public String getFirstValueType() {
        final String typeName = getBuiltinTypeName();
        if ("dateTime".equals(typeName)) {
            return "date";
        } else {
{'fraction_non_alphanumeric': 0.08684354485776805, 'fraction_numerical': 0.0010940919037199124, 'mean_word_length': 2.2114624505928853, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 5, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4334363', 'n_tokens_mistral': 3674, 'n_tokens_neox': 3550, 'n_words': 1000}