1 /*
   2  * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
   3  * @LastModified: Nov 2017
   4  */
   5 /*
   6  * Licensed to the Apache Software Foundation (ASF) under one or more
   7  * contributor license agreements.  See the NOTICE file distributed with
   8  * this work for additional information regarding copyright ownership.
   9  * The ASF licenses this file to You under the Apache License, Version 2.0
  10  * (the "License"); you may not use this file except in compliance with
  11  * the License.  You may obtain a copy of the License at
  12  *
  13  *      http://www.apache.org/licenses/LICENSE-2.0
  14  *
  15  * Unless required by applicable law or agreed to in writing, software
  16  * distributed under the License is distributed on an "AS IS" BASIS,
  17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18  * See the License for the specific language governing permissions and
  19  * limitations under the License.
  20  */
  21 
  22 package com.sun.org.apache.xerces.internal.impl.xs;
  23 
  24 import com.sun.org.apache.xerces.internal.impl.dv.ValidatedInfo;
  25 import com.sun.org.apache.xerces.internal.impl.xs.util.StringListImpl;
  26 import com.sun.org.apache.xerces.internal.xs.ElementPSVI;
  27 import com.sun.org.apache.xerces.internal.xs.ItemPSVI;
  28 import com.sun.org.apache.xerces.internal.xs.ShortList;
  29 import com.sun.org.apache.xerces.internal.xs.StringList;
  30 import com.sun.org.apache.xerces.internal.xs.XSConstants;
  31 import com.sun.org.apache.xerces.internal.xs.XSElementDeclaration;
  32 import com.sun.org.apache.xerces.internal.xs.XSModel;
  33 import com.sun.org.apache.xerces.internal.xs.XSNotationDeclaration;
  34 import com.sun.org.apache.xerces.internal.xs.XSSimpleTypeDefinition;
  35 import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition;
  36 import com.sun.org.apache.xerces.internal.xs.XSValue;
  37 
  38 /**
  39  * Element PSV infoset augmentations implementation.
  40  * The following information will be available at the startElement call:
  41  * name, namespace, type, notation, validation context
  42  *
  43  * The following information will be available at the endElement call:
  44  * nil, specified, normalized value, member type, validity, error codes,
  45  * default
  46  *
  47  * @xerces.internal
  48  *
  49  * @author Elena Litani IBM
  50  */
  51 public class ElementPSVImpl implements ElementPSVI {
  52 
  53     /** element declaration */
  54     protected XSElementDeclaration fDeclaration = null;
  55 
  56     /** type of element, could be xsi:type */
  57     protected XSTypeDefinition fTypeDecl = null;
  58 
  59     /** true if clause 3.2 of Element Locally Valid (Element) (3.3.4)
  60       * is satisfied, otherwise false
  61       */
  62     protected boolean fNil = false;
  63 
  64     /** true if the element value was provided by the schema; false otherwise.
  65      */
  66     protected boolean fSpecified = false;
  67 
  68     /** Schema value */
  69     protected ValidatedInfo fValue = new ValidatedInfo();
  70 
  71     /** http://www.w3.org/TR/xmlschema-1/#e-notation*/
  72     protected XSNotationDeclaration fNotation = null;
  73 
  74     /** validation attempted: none, partial, full */
  75     protected short fValidationAttempted = ElementPSVI.VALIDATION_NONE;
  76 
  77     /** validity: valid, invalid, unknown */
  78     protected short fValidity = ElementPSVI.VALIDITY_NOTKNOWN;
  79 
  80     /** error codes and error messages */
  81     protected String[] fErrors = null;
  82 
  83     /** validation context: could be QName or XPath expression*/
  84     protected String fValidationContext = null;
  85 
  86     /** deferred XSModel **/
  87     protected SchemaGrammar[] fGrammars = null;
  88 
  89     /** the schema information property */
  90     protected XSModel fSchemaInformation = null;
  91 
  92     /** true if this object is immutable **/
  93     protected boolean fIsConstant;
  94 
  95     public ElementPSVImpl() {}
  96 
  97     public ElementPSVImpl(boolean isConstant, ElementPSVI elementPSVI) {
  98         fDeclaration = elementPSVI.getElementDeclaration();
  99         fTypeDecl = elementPSVI.getTypeDefinition();
 100         fNil = elementPSVI.getNil();
 101         fSpecified = elementPSVI.getIsSchemaSpecified();
 102         fValue.copyFrom(elementPSVI.getSchemaValue());
 103         fNotation = elementPSVI.getNotation();
 104         fValidationAttempted = elementPSVI.getValidationAttempted();
 105         fValidity = elementPSVI.getValidity();
 106         fValidationContext = elementPSVI.getValidationContext();
 107         if (elementPSVI instanceof ElementPSVImpl) {
 108             final ElementPSVImpl elementPSVIImpl = (ElementPSVImpl) elementPSVI;
 109             fErrors = (elementPSVIImpl.fErrors != null) ? elementPSVIImpl.fErrors.clone() : null;
 110             elementPSVIImpl.copySchemaInformationTo(this);
 111         }
 112         else {
 113             final StringList errorCodes = elementPSVI.getErrorCodes();
 114             final int length = errorCodes.getLength();
 115             if (length > 0) {
 116                 final StringList errorMessages = elementPSVI.getErrorMessages();
 117                 final String[] errors = new String[length << 1];
 118                 for (int i = 0, j = 0; i < length; ++i) {
 119                     errors[j++] = errorCodes.item(i);
 120                     errors[j++] = errorMessages.item(i);
 121                 }
 122                 fErrors = errors;
 123             }
 124             fSchemaInformation = elementPSVI.getSchemaInformation();
 125         }
 126         fIsConstant = isConstant;
 127     }
 128 
 129     //
 130     // ElementPSVI methods
 131     //
 132 
 133     /* (non-Javadoc)
 134      * @see org.apache.xerces.xs.ItemPSVI#constant()
 135      */
 136     public ItemPSVI constant() {
 137         if (isConstant()) {
 138             return this;
 139         }
 140         return new ElementPSVImpl(true, this);
 141     }
 142 
 143     /* (non-Javadoc)
 144      * @see org.apache.xerces.xs.ItemPSVI#isConstant()
 145      */
 146     public boolean isConstant() {
 147         return fIsConstant;
 148     }
 149 
 150     /**
 151      * [schema default]
 152      *
 153      * @return The canonical lexical representation of the declaration's {value constraint} value.
 154      * @see <a href="http://www.w3.org/TR/xmlschema-1/#e-schema_default>XML Schema Part 1: Structures [schema default]</a>
 155      */
 156     @SuppressWarnings("deprecation")
 157     public String getSchemaDefault() {
 158         return fDeclaration == null ? null : fDeclaration.getConstraintValue();
 159     }
 160 
 161     /**
 162      * [schema normalized value]
 163      *
 164      *
 165      * @see <a href="http://www.w3.org/TR/xmlschema-1/#e-schema_normalized_value>XML Schema Part 1: Structures [schema normalized value]</a>
 166      * @return the normalized value of this item after validation
 167      */
 168     @Deprecated
 169     public String getSchemaNormalizedValue() {
 170         return fValue.getNormalizedValue();
 171     }
 172 
 173     /**
 174      * [schema specified]
 175      * @see <a href="http://www.w3.org/TR/xmlschema-1/#e-schema_specified">XML Schema Part 1: Structures [schema specified]</a>
 176      * @return true - value was specified in schema, false - value comes from the infoset
 177      */
 178     public boolean getIsSchemaSpecified() {
 179         return fSpecified;
 180     }
 181 
 182     /**
 183      * Determines the extent to which the document has been validated
 184      *
 185      * @return return the [validation attempted] property. The possible values are
 186      *         NO_VALIDATION, PARTIAL_VALIDATION and FULL_VALIDATION
 187      */
 188     public short getValidationAttempted() {
 189         return fValidationAttempted;
 190     }
 191 
 192     /**
 193      * Determine the validity of the node with respect
 194      * to the validation being attempted
 195      *
 196      * @return return the [validity] property. Possible values are:
 197      *         UNKNOWN_VALIDITY, INVALID_VALIDITY, VALID_VALIDITY
 198      */
 199     public short getValidity() {
 200         return fValidity;
 201     }
 202 
 203     /**
 204      * A list of error codes generated from validation attempts.
 205      * Need to find all the possible subclause reports that need reporting
 206      *
 207      * @return Array of error codes
 208      */
 209     public StringList getErrorCodes() {
 210         if (fErrors == null || fErrors.length == 0) {
 211             return StringListImpl.EMPTY_LIST;
 212         }
 213         return new PSVIErrorList(fErrors, true);
 214     }
 215 
 216     /**
 217      * A list of error messages generated from the validation attempt or
 218      * an empty <code>StringList</code> if no errors occurred during the
 219      * validation attempt. The indices of error messages in this list are
 220      * aligned with those in the <code>[schema error code]</code> list.
 221      */
 222     public StringList getErrorMessages() {
 223         if (fErrors == null || fErrors.length == 0) {
 224             return StringListImpl.EMPTY_LIST;
 225         }
 226         return new PSVIErrorList(fErrors, false);
 227     }
 228 
 229     // This is the only information we can provide in a pipeline.
 230     public String getValidationContext() {
 231         return fValidationContext;
 232     }
 233 
 234     /**
 235      * [nil]
 236      * @see <a href="http://www.w3.org/TR/xmlschema-1/#e-nil>XML Schema Part 1: Structures [nil]</a>
 237      * @return true if clause 3.2 of Element Locally Valid (Element) (3.3.4) above is satisfied, otherwise false
 238      */
 239     public boolean getNil() {
 240         return fNil;
 241     }
 242 
 243     /**
 244      * [notation]
 245      * @see <a href="http://www.w3.org/TR/xmlschema-1/#e-notation>XML Schema Part 1: Structures [notation]</a>
 246      * @return The notation declaration.
 247      */
 248     public XSNotationDeclaration getNotation() {
 249         return fNotation;
 250     }
 251 
 252     /**
 253      * An item isomorphic to the type definition used to validate this element.
 254      *
 255      * @return  a type declaration
 256      */
 257     public XSTypeDefinition getTypeDefinition() {
 258         return fTypeDecl;
 259     }
 260 
 261     /**
 262      * If and only if that type definition is a simple type definition
 263      * with {variety} union, or a complex type definition whose {content type}
 264      * is a simple thype definition with {variety} union, then an item isomorphic
 265      * to that member of the union's {member type definitions} which actually
 266      * validated the element item's normalized value.
 267      *
 268      * @return  a simple type declaration
 269      */
 270     public XSSimpleTypeDefinition getMemberTypeDefinition() {
 271         return fValue.getMemberTypeDefinition();
 272     }
 273 
 274     /**
 275      * An item isomorphic to the element declaration used to validate
 276      * this element.
 277      *
 278      * @return  an element declaration
 279      */
 280     public XSElementDeclaration getElementDeclaration() {
 281         return fDeclaration;
 282     }
 283 
 284     /**
 285      * [schema information]
 286      * @see <a href="http://www.w3.org/TR/xmlschema-1/#e-schema_information">XML Schema Part 1: Structures [schema information]</a>
 287      * @return The schema information property if it's the validation root,
 288      *         null otherwise.
 289      */
 290     public synchronized XSModel getSchemaInformation() {
 291         if (fSchemaInformation == null && fGrammars != null) {
 292             fSchemaInformation = new XSModelImpl(fGrammars);
 293         }
 294         return fSchemaInformation;
 295     }
 296 
 297     /* (non-Javadoc)
 298      * @see com.sun.org.apache.xerces.internal.xs.ItemPSVI#getActualNormalizedValue()
 299      */
 300     @Deprecated
 301     public Object getActualNormalizedValue() {
 302         return fValue.getActualValue();
 303     }
 304 
 305     /* (non-Javadoc)
 306      * @see com.sun.org.apache.xerces.internal.xs.ItemPSVI#getActualNormalizedValueType()
 307      */
 308     @Deprecated
 309     public short getActualNormalizedValueType() {
 310         return fValue.getActualValueType();
 311     }
 312 
 313     /* (non-Javadoc)
 314      * @see com.sun.org.apache.xerces.internal.xs.ItemPSVI#getItemValueTypes()
 315      */
 316     @Deprecated
 317     public ShortList getItemValueTypes() {
 318         return fValue.getListValueTypes();
 319     }
 320 
 321     /* (non-Javadoc)
 322      * @see com.sun.org.apache.xerces.internal.xs.ItemPSVI#getSchemaValue()
 323      */
 324     public XSValue getSchemaValue() {
 325         return fValue;
 326     }
 327 
 328     /**
 329      * Reset() should be called in validator startElement(..) method.
 330      */
 331     public void reset() {
 332         fDeclaration = null;
 333         fTypeDecl = null;
 334         fNil = false;
 335         fSpecified = false;
 336         fNotation = null;
 337         fValidationAttempted = ElementPSVI.VALIDATION_NONE;
 338         fValidity = ElementPSVI.VALIDITY_NOTKNOWN;
 339         fErrors = null;
 340         fValidationContext = null;
 341         fValue.reset();
 342     }
 343 
 344     public void copySchemaInformationTo(ElementPSVImpl target) {
 345         target.fGrammars = fGrammars;
 346         target.fSchemaInformation = fSchemaInformation;
 347     }
 348 }