jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/SubstitutionGroupHandler.java
changeset 27111 7a491d709b83
parent 25868 686eef1e7a79
child 33349 975138b77cff
equal deleted inserted replaced
26996:a137992d750c 27111:7a491d709b83
     1 /*
     1 /*
     2  * reserved comment block
     2  * reserved comment block
     3  * DO NOT REMOVE OR ALTER!
     3  * DO NOT REMOVE OR ALTER!
     4  */
     4  */
     5 /*
     5 /*
     6  * Copyright 2001-2005 The Apache Software Foundation.
     6  * Licensed to the Apache Software Foundation (ASF) under one or more
     7  *
     7  * contributor license agreements.  See the NOTICE file distributed with
     8  * Licensed under the Apache License, Version 2.0 (the "License");
     8  * this work for additional information regarding copyright ownership.
     9  * you may not use this file except in compliance with the License.
     9  * The ASF licenses this file to You under the Apache License, Version 2.0
    10  * You may obtain a copy of the License at
    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
    11  *
    12  *
    12  *      http://www.apache.org/licenses/LICENSE-2.0
    13  *      http://www.apache.org/licenses/LICENSE-2.0
    13  *
    14  *
    14  * Unless required by applicable law or agreed to in writing, software
    15  * Unless required by applicable law or agreed to in writing, software
    15  * distributed under the License is distributed on an "AS IS" BASIS,
    16  * distributed under the License is distributed on an "AS IS" BASIS,
    38  */
    39  */
    39 public class SubstitutionGroupHandler {
    40 public class SubstitutionGroupHandler {
    40 
    41 
    41     private static final XSElementDecl[] EMPTY_GROUP = new XSElementDecl[0];
    42     private static final XSElementDecl[] EMPTY_GROUP = new XSElementDecl[0];
    42 
    43 
    43     // grammar resolver
    44     // global element declaration resolver
    44     XSGrammarBucket fGrammarBucket;
    45     private final XSElementDeclHelper fXSElementDeclHelper;
    45 
    46 
    46     /**
    47     /**
    47      * Default constructor
    48      * Default constructor
    48      */
    49      */
    49     public SubstitutionGroupHandler(XSGrammarBucket grammarBucket) {
    50     public SubstitutionGroupHandler(XSElementDeclHelper elementDeclHelper) {
    50         fGrammarBucket = grammarBucket;
    51         fXSElementDeclHelper = elementDeclHelper;
    51     }
    52     }
    52 
    53 
    53     // 3.9.4 Element Sequence Locally Valid (Particle) 2.3.3
    54     // 3.9.4 Element Sequence Locally Valid (Particle) 2.3.3
    54     // check whether one element decl matches an element with the given qname
    55     // check whether one element decl matches an element with the given qname
    55     public XSElementDecl getMatchingElemDecl(QName element, XSElementDecl exemplar) {
    56     public XSElementDecl getMatchingElemDecl(QName element, XSElementDecl exemplar) {
    58             return exemplar;
    59             return exemplar;
    59         }
    60         }
    60 
    61 
    61         // if the exemplar is not a global element decl, then it's not possible
    62         // if the exemplar is not a global element decl, then it's not possible
    62         // to be substituted by another element.
    63         // to be substituted by another element.
    63         if (exemplar.fScope != XSConstants.SCOPE_GLOBAL)
    64         if (exemplar.fScope != XSConstants.SCOPE_GLOBAL) {
    64             return null;
    65             return null;
       
    66         }
    65 
    67 
    66         // if the decl blocks substitution, return false
    68         // if the decl blocks substitution, return false
    67         if ((exemplar.fBlock & XSConstants.DERIVATION_SUBSTITUTION) != 0)
    69         if ((exemplar.fBlock & XSConstants.DERIVATION_SUBSTITUTION) != 0) {
    68             return null;
    70             return null;
    69 
    71         }
    70         // get grammar of the element
    72 
    71         SchemaGrammar sGrammar = fGrammarBucket.getGrammar(element.uri);
    73         // get the decl for the element
    72         if (sGrammar == null)
    74         XSElementDecl eDecl = fXSElementDeclHelper.getGlobalElementDecl(element);
       
    75         if (eDecl == null) {
    73             return null;
    76             return null;
    74 
    77         }
    75         // get the decl for the element
       
    76         XSElementDecl eDecl = sGrammar.getGlobalElementDecl(element.localpart);
       
    77         if (eDecl == null)
       
    78             return null;
       
    79 
    78 
    80         // and check by using substitutionGroup information
    79         // and check by using substitutionGroup information
    81         if (substitutionGroupOK(eDecl, exemplar, exemplar.fBlock))
    80         if (substitutionGroupOK(eDecl, exemplar, exemplar.fBlock)) {
    82             return eDecl;
    81             return eDecl;
       
    82         }
    83 
    83 
    84         return null;
    84         return null;
    85     }
    85     }
    86 
    86 
    87     // 3.3.6 Substitution Group OK (Transitive)
    87     // 3.3.6 Substitution Group OK (Transitive)
    88     // check whether element can substitute exemplar
    88     // check whether element can substitute exemplar
    89     protected boolean substitutionGroupOK(XSElementDecl element, XSElementDecl exemplar, short blockingConstraint) {
    89     protected boolean substitutionGroupOK(XSElementDecl element, XSElementDecl exemplar, short blockingConstraint) {
    90         // For an element declaration (call it D) to be validly substitutable for another element declaration (call it C) subject to a blocking constraint (a subset of {substitution, extension, restriction}, the value of a {disallowed substitutions}) one of the following must be true:
    90         // For an element declaration (call it D) to be validly substitutable for another element declaration (call it C) subject to a blocking constraint (a subset of {substitution, extension, restriction}, the value of a {disallowed substitutions}) one of the following must be true:
    91         // 1. D and C are the same element declaration.
    91         // 1. D and C are the same element declaration.
    92         if (element == exemplar)
    92         if (element == exemplar) {
    93             return true;
    93             return true;
       
    94         }
    94 
    95 
    95         // 2 All of the following must be true:
    96         // 2 All of the following must be true:
    96         // 2.1 The blocking constraint does not contain substitution.
    97         // 2.1 The blocking constraint does not contain substitution.
    97         if ((blockingConstraint & XSConstants.DERIVATION_SUBSTITUTION) != 0)
    98         if ((blockingConstraint & XSConstants.DERIVATION_SUBSTITUTION) != 0) {
    98             return false;
    99             return false;
       
   100         }
    99 
   101 
   100         // 2.2 There is a chain of {substitution group affiliation}s from D to C, that is, either D's {substitution group affiliation} is C, or D's {substitution group affiliation}'s {substitution group affiliation} is C, or . . .
   102         // 2.2 There is a chain of {substitution group affiliation}s from D to C, that is, either D's {substitution group affiliation} is C, or D's {substitution group affiliation}'s {substitution group affiliation} is C, or . . .
   101         XSElementDecl subGroup = element.fSubGroup;
   103         XSElementDecl subGroup = element.fSubGroup;
   102         while (subGroup != null && subGroup != exemplar) {
   104         while (subGroup != null && subGroup != exemplar) {
   103             subGroup = subGroup.fSubGroup;
   105             subGroup = subGroup.fSubGroup;
   104         }
   106         }
   105 
   107 
   106         if (subGroup == null)
   108         if (subGroup == null) {
   107             return false;
   109             return false;
       
   110         }
   108 
   111 
   109         // 2.3 The set of all {derivation method}s involved in the derivation of D's {type definition} from C's {type definition} does not intersect with the union of the blocking constraint, C's {prohibited substitutions} (if C is complex, otherwise the empty set) and the {prohibited substitutions} (respectively the empty set) of any intermediate {type definition}s in the derivation of D's {type definition} from C's {type definition}.
   112         // 2.3 The set of all {derivation method}s involved in the derivation of D's {type definition} from C's {type definition} does not intersect with the union of the blocking constraint, C's {prohibited substitutions} (if C is complex, otherwise the empty set) and the {prohibited substitutions} (respectively the empty set) of any intermediate {type definition}s in the derivation of D's {type definition} from C's {type definition}.
   110         // prepare the combination of {derivation method} and
   113         // prepare the combination of {derivation method} and
   111         // {disallowed substitution}
   114         // {disallowed substitution}
   112         return typeDerivationOK(element.fType, exemplar.fType, blockingConstraint);
   115         return typeDerivationOK(element.fType, exemplar.fType, blockingConstraint);
   113     }
   116     }
       
   117 
   114     private boolean typeDerivationOK(XSTypeDefinition derived, XSTypeDefinition base, short blockingConstraint) {
   118     private boolean typeDerivationOK(XSTypeDefinition derived, XSTypeDefinition base, short blockingConstraint) {
   115 
   119 
   116         short devMethod = 0, blockConstraint = blockingConstraint;
   120         short devMethod = 0, blockConstraint = blockingConstraint;
   117 
   121 
   118         // "derived" should be derived from "base"
   122         // "derived" should be derived from "base"