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

changeset 0
373ffda63c9a
equal deleted inserted replaced
-1:000000000000 0:373ffda63c9a
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 */
25
26 package com.sun.tools.internal.xjc.reader.xmlschema;
27
28 import java.text.ParseException;
29 import java.util.Collection;
30 import java.util.Collections;
31
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;
45
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 {
53
54 protected final BGMBuilder builder = Ring.get(BGMBuilder.class);
55
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 }
60
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 }
69
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 );
75
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 );
85
86
87 //
88 //
89 // convenient utility methods
90 //
91 //
92
93 protected final CClassInfo getCurrentBean() {
94 return getClassSelector().getCurrentBean();
95 }
96
97
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 }
104
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;
109
110 // if not, the term might have one.
111 cust = builder.getBindInfo(p.getTerm()).get(type);
112 if(cust!=null) return cust;
113
114 return null;
115 }
116
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);
127
128 // no explicit property name is given. Compute one.
129
130 XSTerm t = p.getTerm();
131
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 // }
137
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 }
158
159 // there are only four types of XSTerm.
160 throw new AssertionError();
161 }
162
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 }
170
171 protected final String makeJavaName( XSParticle p, String xmlName ) {
172 return makeJavaName(p.isRepeated(),xmlName);
173 }
174
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 {
189
190 final StringBuilder name = new StringBuilder();
191
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;
198
199 /**
200 * Is the current particple/term repeated?
201 */
202 private boolean rep = repeated;
203
204 public void wildcard(XSWildcard wc) {
205 append("any");
206 }
207
208 public void modelGroupDecl(XSModelGroupDecl mgd) {
209 modelGroup(mgd.getModelGroup());
210 }
211
212 public void modelGroup(XSModelGroup mg) {
213 String operator;
214 if(mg.getCompositor()==XSModelGroup.CHOICE) operator = "Or";
215 else operator = "And";
216
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;
224
225 if(count==3) return; // we have enough
226 if(i!=size-1) name.append(operator);
227 }
228 }
229
230 public void elementDecl(XSElementDecl ed) {
231 append(ed.getName());
232 }
233
234 private void append(String token) {
235 if( count<3 ) {
236 name.append(makeJavaName(rep,token));
237 count++;
238 }
239 }
240 });
241
242 if(name.length()==0) throw new ParseException("no element",-1);
243
244 return name.toString();
245 }
246
247
248
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