1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/jaxws_classes/com/sun/tools/internal/xjc/reader/xmlschema/ParticleBinder.java Wed Apr 27 01:27:09 2016 +0800 1.3 @@ -0,0 +1,255 @@ 1.4 +/* 1.5 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. Oracle designates this 1.11 + * particular file as subject to the "Classpath" exception as provided 1.12 + * by Oracle in the LICENSE file that accompanied this code. 1.13 + * 1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.17 + * version 2 for more details (a copy is included in the LICENSE file that 1.18 + * accompanied this code). 1.19 + * 1.20 + * You should have received a copy of the GNU General Public License version 1.21 + * 2 along with this work; if not, write to the Free Software Foundation, 1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.23 + * 1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.25 + * or visit www.oracle.com if you need additional information or have any 1.26 + * questions. 1.27 + */ 1.28 + 1.29 +package com.sun.tools.internal.xjc.reader.xmlschema; 1.30 + 1.31 +import java.text.ParseException; 1.32 +import java.util.Collection; 1.33 +import java.util.Collections; 1.34 + 1.35 +import com.sun.codemodel.internal.JJavaName; 1.36 +import com.sun.tools.internal.xjc.model.CClassInfo; 1.37 +import com.sun.tools.internal.xjc.model.CPropertyInfo; 1.38 +import com.sun.tools.internal.xjc.reader.Ring; 1.39 +import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIDeclaration; 1.40 +import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIProperty; 1.41 +import com.sun.xml.internal.xsom.XSElementDecl; 1.42 +import com.sun.xml.internal.xsom.XSModelGroup; 1.43 +import com.sun.xml.internal.xsom.XSModelGroupDecl; 1.44 +import com.sun.xml.internal.xsom.XSParticle; 1.45 +import com.sun.xml.internal.xsom.XSTerm; 1.46 +import com.sun.xml.internal.xsom.XSWildcard; 1.47 +import com.sun.xml.internal.xsom.visitor.XSTermVisitor; 1.48 + 1.49 +/** 1.50 + * Binds the content models of {@link XSParticle} as properties of the class that's being built. 1.51 + * 1.52 + * @author 1.53 + * Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com) 1.54 + */ 1.55 +public abstract class ParticleBinder { 1.56 + 1.57 + protected final BGMBuilder builder = Ring.get(BGMBuilder.class); 1.58 + 1.59 + protected ParticleBinder() { 1.60 + // make sure that this object is available as ParticleBinder, not as their actual implementation classes 1.61 + Ring.add(ParticleBinder.class,this); 1.62 + } 1.63 + 1.64 + /** 1.65 + * Builds the {@link CPropertyInfo}s from the given particle 1.66 + * (and its descendants), and set them to the class returned by 1.67 + * {@link ClassSelector#getCurrentBean()}. 1.68 + */ 1.69 + public final void build( XSParticle p ) { 1.70 + build(p, Collections.<XSParticle>emptySet()); 1.71 + } 1.72 + 1.73 + /** 1.74 + * The version of the build method that forces a specified set of particles 1.75 + * to become a property. 1.76 + */ 1.77 + public abstract void build( XSParticle p, Collection<XSParticle> forcedProps ); 1.78 + 1.79 + /** 1.80 + * Similar to the build method but this method only checks if 1.81 + * the BGM that will be built by the build method will 1.82 + * do the fallback (map all the properties into one list) or not. 1.83 + * 1.84 + * @return 1.85 + * false if the fallback will not happen. 1.86 + */ 1.87 + public abstract boolean checkFallback( XSParticle p ); 1.88 + 1.89 + 1.90 +// 1.91 +// 1.92 +// convenient utility methods 1.93 +// 1.94 +// 1.95 + 1.96 + protected final CClassInfo getCurrentBean() { 1.97 + return getClassSelector().getCurrentBean(); 1.98 + } 1.99 + 1.100 + 1.101 + /** 1.102 + * Gets the BIProperty object that applies to the given particle. 1.103 + */ 1.104 + protected final BIProperty getLocalPropCustomization( XSParticle p ) { 1.105 + return getLocalCustomization(p,BIProperty.class); 1.106 + } 1.107 + 1.108 + protected final <T extends BIDeclaration> T getLocalCustomization( XSParticle p, Class<T> type ) { 1.109 + // check the property customization of this component first 1.110 + T cust = builder.getBindInfo(p).get(type); 1.111 + if(cust!=null) return cust; 1.112 + 1.113 + // if not, the term might have one. 1.114 + cust = builder.getBindInfo(p.getTerm()).get(type); 1.115 + if(cust!=null) return cust; 1.116 + 1.117 + return null; 1.118 + } 1.119 + 1.120 + /** 1.121 + * Computes the label of a given particle. 1.122 + * Usually, the getLabel method should be used instead. 1.123 + */ 1.124 + protected final String computeLabel( XSParticle p ) { 1.125 + // if the particle carries a customization, use that value. 1.126 + // since we are binding content models, it's always non-constant properties. 1.127 + BIProperty cust = getLocalPropCustomization(p); 1.128 + if(cust!=null && cust.getPropertyName(false)!=null) 1.129 + return cust.getPropertyName(false); 1.130 + 1.131 + // no explicit property name is given. Compute one. 1.132 + 1.133 + XSTerm t = p.getTerm(); 1.134 + 1.135 +// // first, check if a term is going to be a class, if so, use that name. 1.136 +// ClassItem ci = owner.selector.select(t); 1.137 +// if(ci!=null) { 1.138 +// return makeJavaName(ci.getTypeAsDefined().name()); 1.139 +// } 1.140 + 1.141 + // if it fails, compute the default name according to the spec. 1.142 + if(t.isElementDecl()) 1.143 + // for element, take the element name. 1.144 + return makeJavaName(p,t.asElementDecl().getName()); 1.145 + if(t.isModelGroupDecl()) 1.146 + // for named model groups, take that name 1.147 + return makeJavaName(p,t.asModelGroupDecl().getName()); 1.148 + if(t.isWildcard()) 1.149 + // the spec says it will map to "any" by default. 1.150 + return makeJavaName(p,"Any"); 1.151 + if(t.isModelGroup()) { 1.152 + try { 1.153 + return getSpecDefaultName(t.asModelGroup(),p.isRepeated()); 1.154 + } catch( ParseException e ) { 1.155 + // unable to generate a name. 1.156 + getErrorReporter().error(t.getLocator(), 1.157 + Messages.ERR_UNABLE_TO_GENERATE_NAME_FROM_MODELGROUP); 1.158 + return "undefined"; // recover from error by assuming something 1.159 + } 1.160 + } 1.161 + 1.162 + // there are only four types of XSTerm. 1.163 + throw new AssertionError(); 1.164 + } 1.165 + 1.166 + /** Converts an XML name to the corresponding Java name. */ 1.167 + protected final String makeJavaName( boolean isRepeated, String xmlName ) { 1.168 + String name = builder.getNameConverter().toPropertyName(xmlName); 1.169 + if(builder.getGlobalBinding().isSimpleMode() && isRepeated ) 1.170 + name = JJavaName.getPluralForm(name); 1.171 + return name; 1.172 + } 1.173 + 1.174 + protected final String makeJavaName( XSParticle p, String xmlName ) { 1.175 + return makeJavaName(p.isRepeated(),xmlName); 1.176 + } 1.177 + 1.178 + /** 1.179 + * Computes a name from unnamed model group by following the spec. 1.180 + * 1.181 + * Taking first three elements and combine them. 1.182 + * 1.183 + * @param repeated 1.184 + * if the said model group is repeated more than once 1.185 + * 1.186 + * @exception ParseException 1.187 + * If the method cannot generate a name. For example, when 1.188 + * a model group doesn't contain any element reference/declaration 1.189 + * at all. 1.190 + */ 1.191 + protected final String getSpecDefaultName( XSModelGroup mg, final boolean repeated ) throws ParseException { 1.192 + 1.193 + final StringBuilder name = new StringBuilder(); 1.194 + 1.195 + mg.visit(new XSTermVisitor() { 1.196 + /** 1.197 + * Count the number of tokens we combined. 1.198 + * We will concat up to 3. 1.199 + */ 1.200 + private int count=0; 1.201 + 1.202 + /** 1.203 + * Is the current particple/term repeated? 1.204 + */ 1.205 + private boolean rep = repeated; 1.206 + 1.207 + public void wildcard(XSWildcard wc) { 1.208 + append("any"); 1.209 + } 1.210 + 1.211 + public void modelGroupDecl(XSModelGroupDecl mgd) { 1.212 + modelGroup(mgd.getModelGroup()); 1.213 + } 1.214 + 1.215 + public void modelGroup(XSModelGroup mg) { 1.216 + String operator; 1.217 + if(mg.getCompositor()==XSModelGroup.CHOICE) operator = "Or"; 1.218 + else operator = "And"; 1.219 + 1.220 + int size = mg.getSize(); 1.221 + for( int i=0; i<size; i++ ) { 1.222 + XSParticle p = mg.getChild(i); 1.223 + boolean oldRep = rep; 1.224 + rep |= p.isRepeated(); 1.225 + p.getTerm().visit(this); 1.226 + rep = oldRep; 1.227 + 1.228 + if(count==3) return; // we have enough 1.229 + if(i!=size-1) name.append(operator); 1.230 + } 1.231 + } 1.232 + 1.233 + public void elementDecl(XSElementDecl ed) { 1.234 + append(ed.getName()); 1.235 + } 1.236 + 1.237 + private void append(String token) { 1.238 + if( count<3 ) { 1.239 + name.append(makeJavaName(rep,token)); 1.240 + count++; 1.241 + } 1.242 + } 1.243 + }); 1.244 + 1.245 + if(name.length()==0) throw new ParseException("no element",-1); 1.246 + 1.247 + return name.toString(); 1.248 + } 1.249 + 1.250 + 1.251 + 1.252 + protected final ErrorReporter getErrorReporter() { 1.253 + return Ring.get(ErrorReporter.class); 1.254 + } 1.255 + protected final ClassSelector getClassSelector() { 1.256 + return Ring.get(ClassSelector.class); 1.257 + } 1.258 +}