<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.xerces.impl.xs;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import org.apache.xerces.impl.Constants;
import org.apache.xerces.impl.xs.assertion.XMLAssertHandler;
import org.apache.xerces.impl.xs.assertion.XSAssert;
import org.apache.xerces.impl.xs.assertion.XSAssertImpl;
import org.apache.xerces.impl.xs.util.XSObjectListImpl;
import org.apache.xerces.impl.xs.util.XSTypeHelper;
import org.apache.xerces.util.AugmentationsImpl;
import org.apache.xerces.util.NamespaceSupport;
import org.apache.xerces.xni.Augmentations;
import org.apache.xerces.xni.QName;
import org.apache.xerces.xni.XMLAttributes;
import org.apache.xerces.xni.XMLString;
import org.apache.xerces.xni.XNIException;
import org.apache.xerces.xs.XSComplexTypeDefinition;
import org.apache.xerces.xs.XSMultiValueFacet;
import org.apache.xerces.xs.XSObjectList;
import org.apache.xerces.xs.XSSimpleTypeDefinition;
import org.apache.xerces.xs.XSTypeDefinition;

/**
 * An XML Schema validator subcomponent handling assertions processing.
 * 
 * @xerces.internal
 * 
 * @author <NAME>
 * 
 * @version $Id$
 */
public class XSDAssertionValidator {
    
    // XMLSchemaValidator instance that acts as context for the present assertion validator subcomponent.
    // Passed into the constructor of this object.
    XMLSchemaValidator fXmlSchemaValidator = null;
    
    // assertion processor object reference
    XMLAssertHandler fAssertionProcessor = null;
    
    // control variable to track if attributes on current element, have assertions.
    boolean fAttributesHaveAsserts = false;
    
    
    /*
     * Class constructor.
     */
    public XSDAssertionValidator(XMLSchemaValidator xmlSchemaValidator) {
       this.fXmlSchemaValidator = xmlSchemaValidator; 
    }

    
    /*
     * Assertions processing interface during the XNI event, 'handleCharacters' in XMLSchemaValidator. 
     */
    public void characterDataHandler(XMLString text) {
        
        if (fAssertionProcessor != null) {
           fAssertionProcessor.characters(text);
        }
        
    } // characterDataHandler
    
    
    /*
     * Assertions processing interface during the XNI event, 'handleStartElement' in XMLSchemaValidator.
     */
    public void handleStartElement(QName element, XMLAttributes attributes) throws Exception {
       
        // get list of assertions for processing
        List assertionList = getAssertsForEvaluation(element, attributes);
        
        // instantiate the assertions processor
        if (assertionList != null && fAssertionProcessor == null) {
            // construct parameter values for the assertion processor
            NamespaceSupport xpathNamespaceContext = null;
            if (assertionList instanceof XSObjectList) {
                xpathNamespaceContext = ((XSAssertImpl)((XSObjectList) assertionList).item(0)).getXPath2NamespaceContext();    
            }
            else {
                Vector assertVector = (Vector) assertionList;
                xpathNamespaceContext = ((XSAssertImpl)assertVector.get(0)).getXPath2NamespaceContext();
            }

            Map assertProcessorParams = new HashMap();
            assertProcessorParams.put("XPATH2_NS_CONTEXT", xpathNamespaceContext);
            // initialize the assertions processor
            initializeAssertProcessor(assertProcessorParams);
        }
       
        // invoke the assertions processor method
        if (fAssertionProcessor != null) {
            // construct the augmentations object, for assertions
            AugmentationsImpl assertAugs = new AugmentationsImpl();
            assertAugs.putItem("ASSERT", assertionList);
            assertAugs.putItem("ATTRIBUTES-HAVE-ASSERTS", Boolean.valueOf(fAttributesHaveAsserts));
            fAttributesHaveAsserts = false;
            fAssertionProcessor.startElement(element, attributes, assertAugs);
        }
        
    } // handleStartElement
    
    
    /*
     * Assertions processing interface during the XNI event, 'handleEndElement' in XMLSchemaValidator.
     */
    public void handleEndElement(QName element, Augmentations augs) {
        
        if (fAssertionProcessor != null) {
            try {
                fAssertionProcessor.endElement(element, augs);
            } catch (Exception ex) {
                throw new XNIException(ex.getMessage(), ex);
            }
        }
          
    } // handleEndElement
    
    
    /*
     * Accumulate a list of assertions (get from the underlying XSModel instance) to be processed
     * for the current context. Return the assertions list.
     */
    private List getAssertsForEvaluation(QName element, XMLAttributes attributes) {
        
       XSTypeDefinition typeDefn = fXmlSchemaValidator.fCurrentPSVI.getTypeDefinition();

       List assertionList = null;            
       if (typeDefn.getTypeCategory() == XSTypeDefinition.COMPLEX_TYPE) {
           // if element's schema type is a "complex type"               
           XSObjectListImpl complexTypeAsserts = getAssertsFromComplexType((XSComplexTypeDefinition) typeDefn, attributes);
           if (complexTypeAsserts.size() > 0) {
               assertionList = complexTypeAsserts;             
           }
       }
       else if (typeDefn.getTypeCategory() == XSTypeDefinition.SIMPLE_TYPE) {
           // if element's schema type is a "simple type"
           assertionList = getAssertsFromSimpleType((XSSimpleTypeDefinition) typeDefn);            
       }
               
       return assertionList;
         
    } // getAssertsForEvaluation


    /*
     * Accumulate assertions from a complex type.
     */
    private XSObjectListImpl getAssertsFromComplexType(XSComplexTypeDefinition complexTypeDef, XMLAttributes attributes) {
        
        XSObjectListImpl complexTypeAsserts = new XSObjectListImpl();

        XSObjectList primaryAssertions = complexTypeDef.getAssertions();

        if (primaryAssertions.getLength() > 0) {
            for (int assertIdx = 0; assertIdx < primaryAssertions.getLength(); assertIdx++) {
                complexTypeAsserts.addXSObject((XSAssert) primaryAssertions.get(assertIdx));
            }
        }

        // add assertion facets from "complexType -> simpleContent -> restriction"
        XSSimpleTypeDefinition simpleContentType = complexTypeDef.getSimpleType();
        if (simpleContentType != null) {            
            Vector simpleContentAsserts = XSTypeHelper.getAssertsFromSimpleType(simpleContentType);
            for (int assertIdx = 0; assertIdx < simpleContentAsserts.size(); assertIdx++) {
                XSAssert simpleContentAssert = (XSAssert) simpleContentAsserts.get(assertIdx);
                complexTypeAsserts.addXSObject(simpleContentAssert);
            }
        }

        // find assertions from attributes of a complex type, and add them to the parent assertions list
        XSObjectListImpl attrAsserts = getAssertsFromAttributes(attributes);
        final int attrAssertCount = attrAsserts.getLength(); 
        for (int attrAssertIdx = 0; attrAssertIdx < attrAssertCount; attrAssertIdx++) {
            complexTypeAsserts.addXSObject(attrAsserts.item(attrAssertIdx)); 
        }        
        if (attrAssertCount > 0) {
           fAttributesHaveAsserts = true;  
        }

        return complexTypeAsserts;<commit_msg>committing a slight fix for schema 1.1 assertions. when complexType's with simpleContent are derived by extension, the earlier codebase in SVN evaluated certain assertions twice. this commit solves this problem. <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.xerces.impl.xs;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import org.apache.xerces.impl.Constants;
import org.apache.xerces.impl.xs.assertion.XMLAssertHandler;
import org.apache.xerces.impl.xs.assertion.XSAssert;
import org.apache.xerces.impl.xs.assertion.XSAssertImpl;
import org.apache.xerces.impl.xs.util.XSObjectListImpl;
import org.apache.xerces.impl.xs.util.XSTypeHelper;
import org.apache.xerces.util.AugmentationsImpl;
import org.apache.xerces.util.NamespaceSupport;
import org.apache.xerces.xni.Augmentations;
import org.apache.xerces.xni.QName;
import org.apache.xerces.xni.XMLAttributes;
import org.apache.xerces.xni.XMLString;
import org.apache.xerces.xni.XNIException;
import org.apache.xerces.xs.XSComplexTypeDefinition;
import org.apache.xerces.xs.XSConstants;
import org.apache.xerces.xs.XSMultiValueFacet;
import org.apache.xerces.xs.XSObjectList;
import org.apache.xerces.xs.XSSimpleTypeDefinition;
import org.apache.xerces.xs.XSTypeDefinition;

/**
 * An XML Schema validator subcomponent handling assertions processing.
 * 
 * @xerces.internal
 * 
 * @author <NAME>
 * 
 * @version $Id$
 */
public class XSDAssertionValidator {
    
    // XMLSchemaValidator instance that acts as context for the present assertion validator subcomponent.
    // Passed into the constructor of this object.
    XMLSchemaValidator fXmlSchemaValidator = null;
    
    // assertion processor object reference
    XMLAssertHandler fAssertionProcessor = null;
    
    // control variable to track if attributes on current element, have assertions.
    boolean fAttributesHaveAsserts = false;
    
    
    /*
     * Class constructor.
     */
    public XSDAssertionValidator(XMLSchemaValidator xmlSchemaValidator) {
       this.fXmlSchemaValidator = xmlSchemaValidator; 
    }

    
    /*
     * Assertions processing interface during the XNI event, 'handleCharacters' in XMLSchemaValidator. 
     */
    public void characterDataHandler(XMLString text) {
        
        if (fAssertionProcessor != null) {
           fAssertionProcessor.characters(text);
        }
        
    } // characterDataHandler
    
    
    /*
     * Assertions processing interface during the XNI event, 'handleStartElement' in XMLSchemaValidator.
     */
    public void handleStartElement(QName element, XMLAttributes attributes) throws Exception {
       
        // get list of assertions for processing
        List assertionList = getAssertsForEvaluation(element, attributes);
        
        // instantiate the assertions processor
        if (assertionList != null && fAssertionProcessor == null) {
            // construct parameter values for the assertion processor
            NamespaceSupport xpathNamespaceContext = null;
            if (assertionList instanceof XSObjectList) {
                xpathNamespaceContext = ((XSAssertImpl)((XSObjectList) assertionList).item(0)).getXPath2NamespaceContext();    
            }
            else {
                Vector assertVector = (Vector) assertionList;
                xpathNamespaceContext = ((XSAssertImpl)assertVector.get(0)).getXPath2NamespaceContext();
            }

            Map assertProcessorParams = new HashMap();
            assertProcessorParams.put("XPATH2_NS_CONTEXT", xpathNamespaceContext);
            // initialize the assertions processor
            initializeAssertProcessor(assertProcessorParams);
        }
       
        // invoke the assertions processor method
        if (fAssertionProcessor != null) {
            // construct the augmentations object, for assertions
            AugmentationsImpl assertAugs = new AugmentationsImpl();
            assertAugs.putItem("ASSERT", assertionList);
            assertAugs.putItem("ATTRIBUTES-HAVE-ASSERTS", Boolean.valueOf(fAttributesHaveAsserts));
            fAttributesHaveAsserts = false;
            fAssertionProcessor.startElement(element, attributes, assertAugs);
        }
        
    } // handleStartElement
    
    
    /*
     * Assertions processing interface during the XNI event, 'handleEndElement' in XMLSchemaValidator.
     */
    public void handleEndElement(QName element, Augmentations augs) {
        
        if (fAssertionProcessor != null) {
            try {
                fAssertionProcessor.endElement(element, augs);
            } catch (Exception ex) {
                throw new XNIException(ex.getMessage(), ex);
            }
        }
          
    } // handleEndElement
    
    
    /*
     * Accumulate a list of assertions (get from the underlying XSModel instance) to be processed
     * for the current context. Return the assertions list.
     */
    private List getAssertsForEvaluation(QName element, XMLAttributes attributes) {
        
       XSTypeDefinition typeDefn = fXmlSchemaValidator.fCurrentPSVI.getTypeDefinition();

       List assertionList = null;            
       if (typeDefn.getTypeCategory() == XSTypeDefinition.COMPLEX_TYPE) {
           // if element's schema type is a "complex type"               
           XSObjectListImpl complexTypeAsserts = getAssertsFromComplexType((XSComplexTypeDefinition) typeDefn, attributes);
           if (complexTypeAsserts.size() > 0) {
               assertionList = complexTypeAsserts;             
           }
       }
       else if (typeDefn.getTypeCategory() == XSTypeDefinition.SIMPLE_TYPE) {
           // if element's schema type is a "simple type"
           assertionList = getAssertsFromSimpleType((XSSimpleTypeDefinition) typeDefn);            
       }
               
       return assertionList;
         
    } // getAssertsForEvaluation


    /*
     * Accumulate assertions from a complex type.
     */
    private XSObjectListImpl getAssertsFromComplexType(XSComplexTypeDefinition complexTypeDef, XMLAttributes attributes) {
        
        XSObjectListImpl complexTypeAsserts = new XSObjectListImpl();

        XSObjectList primaryAssertions = complexTypeDef.getAssertions();

        if (primaryAssertions.getLength() > 0) {
            for (int assertIdx = 0; assertIdx < primaryAssertions.getLength(); assertIdx++) {
                complexTypeAsserts.addXSObject((XSAssert) primaryAssertions.get(assertIdx));
            }
        }

        // add assertion facets from "complexType -> simpleContent -> restriction"
        XSSimpleTypeDefinition simpleContentType = complexTypeDef.getSimpleType();
        if (simpleContentType != null && complexTypeDef.getDerivationMethod() == XSConstants.DERIVATION_RESTRICTION) {
            Vector simpleContentAsserts = XSTypeHelper.getAssertsFromSimpleType(simpleContentType);
            for (int assertIdx = 0; assertIdx < simpleContentAsserts.size(); assertIdx++) {
                XSAssert simpleContentAssert = (XSAssert) simpleContentAsserts.get(assertIdx);
                complexTypeAsserts.addXSObject(simpleContentAssert);
            } 
        }
        

        // find assertions from attributes of a complex type, and add them to the parent assertions list
        XSObjectListImpl attrAsserts = getAssertsFromAttributes(attributes);
        final int attrAssertCount = attrAsserts.getLength(); 
        for (int attrAssertIdx = 0; attrAssertIdx < attrAssertCount; attrAssertIdx++) {
            complexTypeAsserts.addXSObject(attrAsserts.item(attrAssertIdx)); 
        }
        if (attrAssertCount > 0) {
           fAttributesHaveAsserts = true;  
        }

        return complexTypeAsserts;
{'fraction_non_alphanumeric': 0.07693678707224334, 'fraction_numerical': 0.0019011406844106464, 'mean_word_length': 2.8092328581126953, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 15, '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': '5625634', 'n_tokens_mistral': 4446, 'n_tokens_neox': 4290, 'n_words': 1129}