<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache 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.apache.org/licenses/LICENSE-2.0
 *
 * 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.apache.jackrabbit.spi2dav;

import org.w3c.dom.Element;
import org.apache.jackrabbit.name.NamespaceResolver;
import org.apache.jackrabbit.name.QName;
import org.apache.jackrabbit.spi.QPropertyDefinition;
import org.apache.jackrabbit.webdav.xml.DomUtil;
import org.apache.jackrabbit.webdav.xml.ElementIterator;
import org.apache.jackrabbit.value.ValueFormat;

import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;
import java.io.InputStream;

/**
 * This class implements the <code>QPropertyDefinition</code> interface and additionally
 * provides setter methods for the various property definition attributes.
 */
public class QPropertyDefinitionImpl extends QItemDefinitionImpl implements QPropertyDefinition {

    /**
     * The required type.
     */
    private final int requiredType;

    /**
     * The value constraints.
     */
    private final String[] valueConstraints;

    /**
     * The default values.
     */
    private final String[] defaultValues;

    /**
     * The 'multiple' flag
     */
    private final boolean multiple;

    /**
     * Default constructor.
     */
    QPropertyDefinitionImpl(QName declaringNodeType, Element pdefElement, NamespaceResolver nsResolver)
        throws RepositoryException {
        // TODO: webdav server sends jcr names -> nsResolver required. improve this.
        // NOTE: the server should send the namespace-mappings as addition ns-defininitions
        super(declaringNodeType, pdefElement, nsResolver);

        if (pdefElement.hasAttribute(REQUIREDTYPE_ATTRIBUTE)) {
            requiredType = PropertyType.valueFromName(pdefElement.getAttribute(REQUIREDTYPE_ATTRIBUTE));
        } else {
            requiredType = PropertyType.UNDEFINED;
        }

        if (pdefElement.hasAttribute(MULTIPLE_ATTRIBUTE)) {
            multiple = Boolean.valueOf(pdefElement.getAttribute(MULTIPLE_ATTRIBUTE)).booleanValue();
        } else {
            multiple = false;
        }

        Element child = DomUtil.getChildElement(pdefElement, DEFAULTVALUES_ELEMENT, null);
        if (child == null) {
            defaultValues = new String[0];
        } else {
            List vs = new ArrayList();
            ElementIterator it = DomUtil.getChildren(child, DEFAULTVALUE_ELEMENT, null);
            while (it.hasNext()) {
                String qValue = ValueFormat.getQValue(DomUtil.getText(it.nextElement()), requiredType, nsResolver).getString();
                vs.add(qValue);
            }
            defaultValues = (String[]) vs.toArray(new String[vs.size()]);
        }

        child = DomUtil.getChildElement(pdefElement, VALUECONSTRAINTS_ELEMENT, null);
        if (child == null) {
            valueConstraints = new String[0];
        } else {
            List vc = new ArrayList();
            ElementIterator it = DomUtil.getChildren(child, VALUECONSTRAINT_ELEMENT, null);
            while (it.hasNext()) {
                int constType = (requiredType == PropertyType.REFERENCE) ?  PropertyType.NAME : requiredType;
                String qValue = DomUtil.getText(it.nextElement());
                if (constType == PropertyType.NAME || constType == PropertyType.PATH) {
                   qValue = ValueFormat.getQValue(qValue, constType, nsResolver).getString();
                }
                vc.add(qValue);
            }
            valueConstraints = (String[]) vc.toArray(new String[vc.size()]);
        }
    }
    
    //------------------------------------------------< QPropertyDefinition >---
    /**
     * {@inheritDoc}
     */
    public int getRequiredType() {
        return requiredType;
    }

    /**
     * {@inheritDoc}
     */
    public String[] getValueConstraints() {
        return valueConstraints;
    }

    /**
     * {@inheritDoc}
     */
    public String[] getDefaultValues() {
        return defaultValues;
    }

    public InputStream[] getDefaultValuesAsStream() {
        // todo: implementation missing
        return null;
    }

    /**
     * {@inheritDoc}
     */
    public boolean isMultiple() {
        return multiple;
    }

    /**
     * {@inheritDoc}
     *
     * @return always <code>false</code>
     */
    public boolean definesNode() {
        return false;
    }

    //-------------------------------------------< java.lang.Object overrides >
    /**
     * Compares two property definitions for equality. Returns <code>true</code>
     * if the given object is a property defintion and has the same attributes
     * as this property definition.
     *
     * @param obj the object to compare this property definition with
     * @return <code>true</code> if the object is equal to this property definition,
     *         <code>false</code> otherwise
     * @see Object#equals(Object)
     */
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj instanceof QPropertyDefinition) {
            QPropertyDefinition other = (QPropertyDefinition) obj;
            return super.equals(obj)
                    && requiredType == other.getRequiredType()
                    && Arrays.equals(valueConstraints, other.getValueConstraints())
                    && Arrays.equals(defaultValues, other.getDefaultValues())
                    && multiple == other.isMultiple();
        }
        return false;
    }

    /**
     * Overwrites {@link QItemDefinitionImpl#hashCode()}.
     * 
     * @return
     */
    public int hashCode() {
        if (hashCode == 0) {
            // build hashCode (format: <declaringNodeType>/<name>/<requiredType>/<multiple>)
            StringBuffer sb = new StringBuffer();

            sb.append(getDeclaringNodeType().toString());
            sb.append('/');
            if (definesResidual()) {
                sb.append('*');
            } else {
                sb.append(getQName().toString());
            }
            sb.append('/');
            sb.append(getRequiredType());
            sb.append('/');
            sb.append(isMultiple() ? 1 : 0);

            hashCode = sb.toString().hashCode();
        }
        return hashCode;
    }
}
<commit_msg>work in progress<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache 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.apache.org/licenses/LICENSE-2.0
 *
 * 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.apache.jackrabbit.spi2dav;

import org.w3c.dom.Element;
import org.apache.jackrabbit.name.NamespaceResolver;
import org.apache.jackrabbit.name.QName;
import org.apache.jackrabbit.spi.QPropertyDefinition;
import org.apache.jackrabbit.webdav.xml.DomUtil;
import org.apache.jackrabbit.webdav.xml.ElementIterator;
import org.apache.jackrabbit.value.ValueFormat;
import org.apache.jackrabbit.value.QValue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;
import java.io.InputStream;

/**
 * This class implements the <code>QPropertyDefinition</code> interface and additionally
 * provides setter methods for the various property definition attributes.
 */
public class QPropertyDefinitionImpl extends QItemDefinitionImpl implements QPropertyDefinition {

    /**
     * Logger instance for this class
     */
    private static Logger log = LoggerFactory.getLogger(QPropertyDefinitionImpl.class);

    /**
     * The required type.
     */
    private final int requiredType;

    /**
     * The value constraints.
     */
    private final String[] valueConstraints;

    /**
     * The default values.
     */
    private final QValue[] defaultValues;

    /**
     * The 'multiple' flag
     */
    private final boolean multiple;

    /**
     * Default constructor.
     */
    QPropertyDefinitionImpl(QName declaringNodeType, Element pdefElement, NamespaceResolver nsResolver)
        throws RepositoryException {
        // TODO: webdav server sends jcr names -> nsResolver required. improve this.
        // NOTE: the server should send the namespace-mappings as addition ns-defininitions
        super(declaringNodeType, pdefElement, nsResolver);

        if (pdefElement.hasAttribute(REQUIREDTYPE_ATTRIBUTE)) {
            requiredType = PropertyType.valueFromName(pdefElement.getAttribute(REQUIREDTYPE_ATTRIBUTE));
        } else {
            requiredType = PropertyType.UNDEFINED;
        }

        if (pdefElement.hasAttribute(MULTIPLE_ATTRIBUTE)) {
            multiple = Boolean.valueOf(pdefElement.getAttribute(MULTIPLE_ATTRIBUTE)).booleanValue();
        } else {
            multiple = false;
        }

        Element child = DomUtil.getChildElement(pdefElement, DEFAULTVALUES_ELEMENT, null);
        if (child == null) {
            defaultValues = new QValue[0];
        } else {
            List vs = new ArrayList();
            ElementIterator it = DomUtil.getChildren(child, DEFAULTVALUE_ELEMENT, null);
            while (it.hasNext()) {
                QValue qValue = ValueFormat.getQValue(DomUtil.getText(it.nextElement()), requiredType, nsResolver);
                vs.add(qValue);
            }
            defaultValues = (QValue[]) vs.toArray(new QValue[vs.size()]);
        }

        child = DomUtil.getChildElement(pdefElement, VALUECONSTRAINTS_ELEMENT, null);
        if (child == null) {
            valueConstraints = new String[0];
        } else {
            List vc = new ArrayList();
            ElementIterator it = DomUtil.getChildren(child, VALUECONSTRAINT_ELEMENT, null);
            while (it.hasNext()) {
                int constType = (requiredType == PropertyType.REFERENCE) ?  PropertyType.NAME : requiredType;
                String qValue = DomUtil.getText(it.nextElement());
                if (constType == PropertyType.NAME || constType == PropertyType.PATH) {
                   qValue = ValueFormat.getQValue(qValue, constType, nsResolver).getString();
                }
                vc.add(qValue);
            }
            valueConstraints = (String[]) vc.toArray(new String[vc.size()]);
        }
    }
    
    //------------------------------------------------< QPropertyDefinition >---
    /**
     * {@inheritDoc}
     */
    public int getRequiredType() {
        return requiredType;
    }

    /**
     * {@inheritDoc}
     */
    public String[] getValueConstraints() {
        return valueConstraints;
    }

    /**
     * {@inheritDoc}
     */
    public String[] getDefaultValues() {
        String[] strs = new String[defaultValues.length];
        for (int i = 0; i < defaultValues.length; i++) {
            try {
                strs[i] = defaultValues[i].getString();
            } catch (RepositoryException e) {
                log.error("Internal error while retrieving default values.", e);
            }
        }
        return strs;
    }

    public InputStream[] getDefaultValuesAsStream() {
        InputStream[] ins = new InputStream[defaultValues.length];
        for (int i = 0; i < defaultValues.length; i++) {
            try {
                ins[i] = defaultValues[i].getStream();
            } catch (RepositoryException e) {
                log.error("Internal error while retrieving default values.", e);
            }
        }
        return ins;
    }

    /**
     * {@inheritDoc}
     */
    public boolean isMultiple() {
        return multiple;
    }

    /**
     * {@inheritDoc}
     *
     * @return always <code>false</code>
     */
    public boolean definesNode() {
        return false;
    }

    //-------------------------------------------< java.lang.Object overrides >
    /**
     * Compares two property definitions for equality. Returns <code>true</code>
     * if the given object is a property defintion and has the same attributes
     * as this property definition.
     *
     * @param obj the object to compare this property definition with
     * @return <code>true</code> if the object is equal to this property definition,
     *         <code>false</code> otherwise
     * @see Object#equals(Object)
     */
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj instanceof QPropertyDefinition) {
            QPropertyDefinition other = (QPropertyDefinition) obj;
            return super.equals(obj)
                    && requiredType == other.getRequiredType()
                    && Arrays.equals(valueConstraints, other.getValueConstraints())
                    && Arrays.equals(defaultValues, other.getDefaultValues())
                    && multiple == other.isMultiple();
        }
        return false;
    }

    /**
     * Overwrites {@link QItemDefinitionImpl#hashCode()}.
     * 
     * @return
     */
    public int hashCode() {
        if (hashCode == 0) {
            // build hashCode (format: <declaringNodeType>/<name>/<requiredType>/<multiple>)
            StringBuffer sb = new StringBuffer();

            sb.append(getDeclaringNodeType().toString());
            sb.append('/');
            if (definesResidual()) {
                sb.append('*');
            } else {
                sb.append(getQName().toString());
            }
            sb.append('/');
            sb.append(getRequiredType());
            sb.append('/');
            sb.append(isMultiple() ? 1 : 0);

            hashCode = sb.toString().hashCode();
        }
        return hashCode;
    }
}

{'fraction_non_alphanumeric': 0.11515761234071094, 'fraction_numerical': 0.001743796109993293, 'mean_word_length': 2.212885154061625, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 4}, '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': '4560273', 'n_tokens_mistral': 3897, 'n_tokens_neox': 3799, 'n_words': 1015}