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

Tue, 09 Apr 2013 14:51:13 +0100

author
alanb
date
Tue, 09 Apr 2013 14:51:13 +0100
changeset 368
0989ad8c0860
parent 0
373ffda63c9a
permissions
-rw-r--r--

8010393: Update JAX-WS RI to 2.2.9-b12941
Reviewed-by: alanb, erikj
Contributed-by: miroslav.kos@oracle.com, martin.grebac@oracle.com

     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;
    28 import java.text.ParseException;
    29 import java.util.Collection;
    30 import java.util.Collections;
    32 import com.sun.codemodel.internal.JJavaName;
    33 import com.sun.tools.internal.xjc.model.CClassInfo;
    34 import com.sun.tools.internal.xjc.model.CPropertyInfo;
    35 import com.sun.tools.internal.xjc.reader.Ring;
    36 import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIDeclaration;
    37 import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIProperty;
    38 import com.sun.xml.internal.xsom.XSElementDecl;
    39 import com.sun.xml.internal.xsom.XSModelGroup;
    40 import com.sun.xml.internal.xsom.XSModelGroupDecl;
    41 import com.sun.xml.internal.xsom.XSParticle;
    42 import com.sun.xml.internal.xsom.XSTerm;
    43 import com.sun.xml.internal.xsom.XSWildcard;
    44 import com.sun.xml.internal.xsom.visitor.XSTermVisitor;
    46 /**
    47  * Binds the content models of {@link XSParticle} as properties of the class that's being built.
    48  *
    49  * @author
    50  *     Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
    51  */
    52 public abstract class ParticleBinder {
    54     protected final BGMBuilder builder = Ring.get(BGMBuilder.class);
    56     protected ParticleBinder() {
    57         // make sure that this object is available as ParticleBinder, not as their actual implementation classes
    58         Ring.add(ParticleBinder.class,this);
    59     }
    61     /**
    62      * Builds the {@link CPropertyInfo}s from the given particle
    63      * (and its descendants), and set them to the class returned by
    64      * {@link ClassSelector#getCurrentBean()}.
    65      */
    66     public final void build( XSParticle p ) {
    67         build(p, Collections.<XSParticle>emptySet());
    68     }
    70     /**
    71      * The version of the build method that forces a specified set of particles
    72      * to become a property.
    73      */
    74     public abstract void build( XSParticle p, Collection<XSParticle> forcedProps );
    76     /**
    77      * Similar to the build method but this method only checks if
    78      * the BGM that will be built by the build method will
    79      * do the fallback (map all the properties into one list) or not.
    80      *
    81      * @return
    82      *      false if the fallback will not happen.
    83      */
    84     public abstract boolean checkFallback( XSParticle p );
    87 //
    88 //
    89 // convenient utility methods
    90 //
    91 //
    93     protected final CClassInfo getCurrentBean() {
    94         return getClassSelector().getCurrentBean();
    95     }
    98     /**
    99      * Gets the BIProperty object that applies to the given particle.
   100      */
   101     protected final BIProperty getLocalPropCustomization( XSParticle p ) {
   102         return getLocalCustomization(p,BIProperty.class);
   103     }
   105     protected final <T extends BIDeclaration> T getLocalCustomization( XSParticle p, Class<T> type ) {
   106         // check the property customization of this component first
   107         T cust = builder.getBindInfo(p).get(type);
   108         if(cust!=null)  return cust;
   110         // if not, the term might have one.
   111         cust = builder.getBindInfo(p.getTerm()).get(type);
   112         if(cust!=null)  return cust;
   114         return null;
   115     }
   117     /**
   118      * Computes the label of a given particle.
   119      * Usually, the getLabel method should be used instead.
   120      */
   121     protected final String computeLabel( XSParticle p ) {
   122         // if the particle carries a customization, use that value.
   123         // since we are binding content models, it's always non-constant properties.
   124         BIProperty cust = getLocalPropCustomization(p);
   125         if(cust!=null && cust.getPropertyName(false)!=null)
   126             return cust.getPropertyName(false);
   128         // no explicit property name is given. Compute one.
   130         XSTerm t = p.getTerm();
   132 //        // first, check if a term is going to be a class, if so, use that name.
   133 //        ClassItem ci = owner.selector.select(t);
   134 //        if(ci!=null) {
   135 //            return makeJavaName(ci.getTypeAsDefined().name());
   136 //        }
   138         // if it fails, compute the default name according to the spec.
   139         if(t.isElementDecl())
   140             // for element, take the element name.
   141             return makeJavaName(p,t.asElementDecl().getName());
   142         if(t.isModelGroupDecl())
   143             // for named model groups, take that name
   144             return makeJavaName(p,t.asModelGroupDecl().getName());
   145         if(t.isWildcard())
   146             // the spec says it will map to "any" by default.
   147             return makeJavaName(p,"Any");
   148         if(t.isModelGroup()) {
   149             try {
   150                 return getSpecDefaultName(t.asModelGroup(),p.isRepeated());
   151             } catch( ParseException e ) {
   152                 // unable to generate a name.
   153                 getErrorReporter().error(t.getLocator(),
   154                     Messages.ERR_UNABLE_TO_GENERATE_NAME_FROM_MODELGROUP);
   155                 return "undefined"; // recover from error by assuming something
   156             }
   157         }
   159         // there are only four types of XSTerm.
   160         throw new AssertionError();
   161     }
   163     /** Converts an XML name to the corresponding Java name. */
   164     protected final String makeJavaName( boolean isRepeated, String xmlName ) {
   165         String name = builder.getNameConverter().toPropertyName(xmlName);
   166         if(builder.getGlobalBinding().isSimpleMode() && isRepeated )
   167             name = JJavaName.getPluralForm(name);
   168         return name;
   169     }
   171     protected final String makeJavaName( XSParticle p, String xmlName ) {
   172         return makeJavaName(p.isRepeated(),xmlName);
   173     }
   175     /**
   176      * Computes a name from unnamed model group by following the spec.
   177      *
   178      * Taking first three elements and combine them.
   179      *
   180      * @param repeated
   181      *      if the said model group is repeated more than once
   182      *
   183      * @exception ParseException
   184      *      If the method cannot generate a name. For example, when
   185      *      a model group doesn't contain any element reference/declaration
   186      *      at all.
   187      */
   188     protected final String getSpecDefaultName( XSModelGroup mg, final boolean repeated ) throws ParseException {
   190         final StringBuilder name = new StringBuilder();
   192         mg.visit(new XSTermVisitor() {
   193             /**
   194              * Count the number of tokens we combined.
   195              * We will concat up to 3.
   196              */
   197             private int count=0;
   199             /**
   200              * Is the current particple/term repeated?
   201              */
   202             private boolean rep = repeated;
   204             public void wildcard(XSWildcard wc) {
   205                 append("any");
   206             }
   208             public void modelGroupDecl(XSModelGroupDecl mgd) {
   209                 modelGroup(mgd.getModelGroup());
   210             }
   212             public void modelGroup(XSModelGroup mg) {
   213                 String operator;
   214                 if(mg.getCompositor()==XSModelGroup.CHOICE)     operator = "Or";
   215                 else                                            operator = "And";
   217                 int size = mg.getSize();
   218                 for( int i=0; i<size; i++ ) {
   219                     XSParticle p = mg.getChild(i);
   220                     boolean oldRep = rep;
   221                     rep |= p.isRepeated();
   222                     p.getTerm().visit(this);
   223                     rep = oldRep;
   225                     if(count==3)    return; // we have enough
   226                     if(i!=size-1)   name.append(operator);
   227                 }
   228             }
   230             public void elementDecl(XSElementDecl ed) {
   231                 append(ed.getName());
   232             }
   234             private void append(String token) {
   235                 if( count<3 ) {
   236                     name.append(makeJavaName(rep,token));
   237                     count++;
   238                 }
   239             }
   240         });
   242         if(name.length()==0) throw new ParseException("no element",-1);
   244         return name.toString();
   245     }
   249     protected final ErrorReporter getErrorReporter() {
   250         return Ring.get(ErrorReporter.class);
   251     }
   252     protected final ClassSelector getClassSelector() {
   253         return Ring.get(ClassSelector.class);
   254     }
   255 }

mercurial