src/share/jaxws_classes/com/sun/xml/internal/bind/v2/schemagen/Tree.java

Thu, 12 Oct 2017 19:44:07 +0800

author
aoqi
date
Thu, 12 Oct 2017 19:44:07 +0800
changeset 760
e530533619ec
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.xml.internal.bind.v2.schemagen;
    28 import java.util.ArrayList;
    29 import java.util.Arrays;
    30 import java.util.List;
    32 import com.sun.xml.internal.bind.v2.schemagen.xmlschema.ContentModelContainer;
    33 import com.sun.xml.internal.bind.v2.schemagen.xmlschema.Particle;
    34 import com.sun.xml.internal.bind.v2.schemagen.xmlschema.TypeDefParticle;
    35 import com.sun.xml.internal.bind.v2.schemagen.xmlschema.Occurs;
    37 /**
    38  * Normalized representation of the content model.
    39  *
    40  * <p>
    41  * This is built from bottom up so that we can eliminate redundant constructs,
    42  * and produce the most concise content model definition in XML.
    43  *
    44  * @author Kohsuke Kawaguchi
    45  */
    46 abstract class Tree {
    48     /**
    49      * Returns "T?" from "T".
    50      *
    51      * @param really
    52      *      if false this method becomes no-op. This is so that we can write
    53      *      the caller fluently.
    54      */
    55     Tree makeOptional(boolean really) {
    56         return really?new Optional(this) :this;
    57     }
    59     /**
    60      * Returns "T+" from "T".
    61      *
    62      * @param really
    63      *      if false this method becomes no-op. This is so that we can write
    64      *      the caller fluently.
    65      */
    66     Tree makeRepeated(boolean really) {
    67         return really?new Repeated(this) :this;
    68     }
    70     /**
    71      * Returns a group tree.
    72      */
    73     static Tree makeGroup(GroupKind kind, List<Tree> children ) {
    74         // pointless binary operator.
    75         if(children.size()==1)
    76             return children.get(0);
    78         // we neither have epsilon or emptySet, so can't handle children.length==0 nicely
    80         // eliminated nesting groups of the same kind.
    81         // this is where binary tree would have shined.
    82         List<Tree> normalizedChildren = new ArrayList<Tree>(children.size());
    83         for (Tree t : children) {
    84             if (t instanceof Group) {
    85                 Group g = (Group) t;
    86                 if(g.kind==kind) {
    87                     normalizedChildren.addAll(Arrays.asList(g.children));
    88                     continue;
    89                 }
    90             }
    91             normalizedChildren.add(t);
    92         }
    94         return new Group(kind,normalizedChildren.toArray(new Tree[normalizedChildren.size()]));
    95     }
    97     /**
    98      * Returns true if this tree accepts empty sequence.
    99      */
   100     abstract boolean isNullable();
   102     /**
   103      * Returns true if the top node of this tree can
   104      * appear as a valid top-level content model in XML Schema.
   105      *
   106      * <p>
   107      * Model groups and occurrences that have model group in it can.
   108      */
   109     boolean canBeTopLevel() { return false; }
   111     /**
   112      * Writes out the content model.
   113      *
   114      * Normall this runs recursively until we write out the whole content model.
   115      */
   116     protected abstract void write(ContentModelContainer parent, boolean isOptional, boolean repeated);
   118     /**
   119      * Writes inside the given complex type.
   120      */
   121     protected void write(TypeDefParticle ct) {
   122         if(canBeTopLevel())
   123             write(ct._cast(ContentModelContainer.class), false, false);
   124         else
   125             // need a dummy wrapper
   126             new Group(GroupKind.SEQUENCE,this).write(ct);
   127     }
   129     /**
   130      * Convenience method to write occurrence constraints.
   131      */
   132     protected final void writeOccurs(Occurs o, boolean isOptional, boolean repeated) {
   133         if(isOptional)
   134             o.minOccurs(0);
   135         if(repeated)
   136             o.maxOccurs("unbounded");
   137     }
   139     /**
   140      * Represents a terminal tree node, such as element, wildcard, etc.
   141      */
   142     abstract static class Term extends Tree {
   143         boolean isNullable() {
   144             return false;
   145         }
   146     }
   148     /**
   149      * "T?"
   150      */
   151     private static final class Optional extends Tree {
   152         private final Tree body;
   154         private Optional(Tree body) {
   155             this.body = body;
   156         }
   158         @Override
   159         boolean isNullable() {
   160             return true;
   161         }
   163         @Override
   164         Tree makeOptional(boolean really) {
   165             return this;
   166         }
   168         @Override
   169         protected void write(ContentModelContainer parent, boolean isOptional, boolean repeated) {
   170             body.write(parent,true,repeated);
   171         }
   172     }
   174     /**
   175      * "T+"
   176      */
   177     private static final class Repeated extends Tree {
   178         private final Tree body;
   180         private Repeated(Tree body) {
   181             this.body = body;
   182         }
   184         @Override
   185         boolean isNullable() {
   186             return body.isNullable();
   187         }
   189         @Override
   190         Tree makeRepeated(boolean really) {
   191             return this;
   192         }
   194         @Override
   195         protected void write(ContentModelContainer parent, boolean isOptional, boolean repeated) {
   196             body.write(parent,isOptional,true);
   197         }
   198     }
   200     /**
   201      * "S|T", "S,T", and "S&amp;T".
   202      */
   203     private static final class Group extends Tree {
   204         private final GroupKind kind;
   205         private final Tree[] children;
   207         private Group(GroupKind kind, Tree... children) {
   208             this.kind = kind;
   209             this.children = children;
   210         }
   212         @Override
   213         boolean canBeTopLevel() {
   214             return true;
   215         }
   217         @Override
   218         boolean isNullable() {
   219             if(kind== GroupKind.CHOICE) {
   220                 for (Tree t : children) {
   221                     if(t.isNullable())
   222                         return true;
   223                 }
   224                 return false;
   225             } else {
   226                 for (Tree t : children) {
   227                     if(!t.isNullable())
   228                         return false;
   229                 }
   230                 return true;
   231             }
   232         }
   234         @Override
   235         protected void write(ContentModelContainer parent, boolean isOptional, boolean repeated) {
   236             Particle c = kind.write(parent);
   237             writeOccurs(c,isOptional,repeated);
   239             for (Tree child : children) {
   240                 child.write(c,false,false);
   241             }
   242         }
   243     }
   244 }

mercurial