src/share/jaxws_classes/com/sun/tools/internal/xjc/reader/xmlschema/ct/AbstractExtendedComplexTypeBuilder.java

Thu, 31 Aug 2017 15:18:52 +0800

author
aoqi
date
Thu, 31 Aug 2017 15:18:52 +0800
changeset 637
9c07ef4934dd
parent 408
b0610cd08440
parent 0
373ffda63c9a
permissions
-rw-r--r--

merge

     1 /*
     2  * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    26 package com.sun.tools.internal.xjc.reader.xmlschema.ct;
    28 import java.util.HashMap;
    29 import java.util.Iterator;
    30 import java.util.Map;
    32 import com.sun.tools.internal.xjc.reader.xmlschema.WildcardNameClassBuilder;
    33 import com.sun.xml.internal.xsom.XSAttributeUse;
    34 import com.sun.xml.internal.xsom.XSComplexType;
    35 import com.sun.xml.internal.xsom.XSContentType;
    36 import com.sun.xml.internal.xsom.XSDeclaration;
    37 import com.sun.xml.internal.xsom.XSElementDecl;
    38 import com.sun.xml.internal.xsom.XSModelGroup;
    39 import com.sun.xml.internal.xsom.XSModelGroupDecl;
    40 import com.sun.xml.internal.xsom.XSParticle;
    41 import com.sun.xml.internal.xsom.XSType;
    42 import com.sun.xml.internal.xsom.XSWildcard;
    43 import com.sun.xml.internal.xsom.visitor.XSTermFunction;
    44 import javax.xml.namespace.QName;
    46 import com.sun.xml.internal.rngom.nc.ChoiceNameClass;
    47 import com.sun.xml.internal.rngom.nc.NameClass;
    48 import com.sun.xml.internal.rngom.nc.SimpleNameClass;
    50 /**
    51  * Binds a complex type derived from another complex type by extension.
    52  *
    53  * @author
    54  *     Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
    55  */
    56 abstract class AbstractExtendedComplexTypeBuilder extends CTBuilder {
    58     /**
    59      * Map from {@link XSComplexType} to {@link NameClass}[2] that
    60      * represents the names used in its child elements [0] and
    61      * attributes [1].
    62      */
    63     protected final Map<XSComplexType, NameClass[]> characteristicNameClasses = new HashMap<XSComplexType, NameClass[]>();
    65     /**
    66      * Computes a name class that represents everything in a given content model.
    67      */
    68     protected final XSTermFunction<NameClass> contentModelNameClassBuilder = new XSTermFunction<NameClass>() {
    69         @Override
    70         public NameClass wildcard(XSWildcard wc) {
    71             return WildcardNameClassBuilder.build(wc);
    72         }
    74         @Override
    75         public NameClass modelGroupDecl(XSModelGroupDecl decl) {
    76             return modelGroup(decl.getModelGroup());
    77         }
    79         @Override
    80         public NameClass modelGroup(XSModelGroup group) {
    81             NameClass nc = NameClass.NULL;
    82             for( int i=0; i<group.getSize(); i++ )
    83                 nc = new ChoiceNameClass(nc, group.getChild(i).getTerm().apply(this));
    84             return nc;
    85         }
    87         public NameClass elementDecl(XSElementDecl decl) {
    88             return getNameClass(decl);
    89         }
    90     };
    92     /**
    93      * Checks if the particles/attributes defined in the type parameter
    94      * collides with the name classes of anc/enc.
    95      *
    96      * @return true if there's a collision.
    97      */
    98     protected boolean checkCollision(NameClass anc, NameClass enc, XSComplexType type) {
    99         NameClass[] chnc = characteristicNameClasses.get(type);
   100         if (chnc == null) {
   101             chnc = new NameClass[2];
   102             chnc[0] = getNameClass(type.getContentType());
   104             // build attribute name classes
   105             NameClass nc = NameClass.NULL;
   106             Iterator itr = type.iterateAttributeUses();
   107             while( itr.hasNext() )
   108                 anc = new ChoiceNameClass(anc, getNameClass(((XSAttributeUse) itr.next()).getDecl()));
   109             XSWildcard wc = type.getAttributeWildcard();
   110             if(wc!=null)
   111                 nc = new ChoiceNameClass(nc, WildcardNameClassBuilder.build(wc));
   112             chnc[1] = nc;
   114             characteristicNameClasses.put(type, chnc);
   115         }
   117         return chnc[0].hasOverlapWith(enc) || chnc[1].hasOverlapWith(anc);
   118     }
   120     /**
   121      * Looks for the derivation chain t_1 > t_2 > ... > t
   122      * and find t_i such that t_i derives by restriction but
   123      * for every j>i, t_j derives by extension.
   124      *
   125      * @return null
   126      *      If there's no such t_i or if t_i is any type.
   127      */
   128     protected XSComplexType getLastRestrictedType(XSComplexType t) {
   129         if (t.getBaseType() == schemas.getAnyType()) {
   130             return null;   // we don't count the restriction from anyType
   131         }
   132         if (t.getDerivationMethod() == XSType.RESTRICTION) {
   133             return t;
   134         }
   136         XSComplexType baseType = t.getBaseType().asComplexType();
   137         if (baseType != null) {
   138             return getLastRestrictedType(baseType);
   139         } else {
   140             return null;
   141         }
   142     }
   144     /**
   145      * Checks if this new extension is safe.
   146      *
   147      * UGLY.
   148      * <p>
   149      * If you have ctA extending ctB and ctB restricting ctC, our
   150      * Java classes will look like CtAImpl extending CtBImpl
   151      * extending CtCImpl.
   152      *
   153      * <p>
   154      * Since a derived class unmarshaller uses the base class unmarshaller,
   155      * this could potentially result in incorrect unmarshalling.
   156      * We used to just reject such a case, but then we found that
   157      * there are schemas that are using it.
   158      *
   159      * <p>
   160      * One generalized observation that we reached is that if the extension
   161      * is only adding new elements/attributes which has never been used
   162      * in any of its base class (IOW, if none of the particle / attribute use /
   163      * attribute wildcard can match the name of newly added elements/attributes)
   164      * then it is safe to add them.
   165      *
   166      * <p>
   167      * This function checks if the derivation chain to this type is
   168      * not using restriction, and if it is, then checks if it is safe
   169      * according to the above condition.
   170      *
   171      * @return false
   172      *      If this complex type needs to be rejected.
   173      */
   174     protected boolean checkIfExtensionSafe(XSComplexType baseType, XSComplexType thisType) {
   175         XSComplexType lastType = getLastRestrictedType(baseType);
   177         if (lastType == null) {
   178             return true;    // no restriction in derivation chain
   179         }
   180         NameClass anc = NameClass.NULL;
   181         // build name class for attributes in new complex type
   182         Iterator itr = thisType.iterateDeclaredAttributeUses();
   183         while (itr.hasNext()) {
   184             anc = new ChoiceNameClass(anc, getNameClass(((XSAttributeUse) itr.next()).getDecl()));
   185         }
   186         // TODO: attribute wildcard
   188         NameClass enc = getNameClass(thisType.getExplicitContent());
   190         // check against every base type ... except the root anyType
   191         while (lastType != lastType.getBaseType()) {
   192             if (checkCollision(anc, enc, lastType)) {
   193                 return false;
   194             }
   196             if (lastType.getBaseType().isSimpleType()) // if the base type is a simple type, there won't be
   197             // any further name collision.
   198             {
   199                 return true;
   200             }
   202             lastType = lastType.getBaseType().asComplexType();
   203         }
   205         return true;    // OK
   206     }
   208     /**
   209      * Gets a {@link NameClass} that represents all the terms in the given content type.
   210      * If t is not a particle, just return an empty name class.
   211      */
   212     private NameClass getNameClass(XSContentType t) {
   213         if(t==null) return NameClass.NULL;
   214         XSParticle p = t.asParticle();
   215         if(p==null) return NameClass.NULL;
   216         else        return p.getTerm().apply(contentModelNameClassBuilder);
   217     }
   219     /**
   220      * Gets a {@link SimpleNameClass} from the name of a {@link XSDeclaration}.
   221      */
   222     private NameClass getNameClass(XSDeclaration decl) {
   223         return new SimpleNameClass(new QName(decl.getTargetNamespace(), decl.getName()));
   224     }
   226 }

mercurial