KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > ws > jaxme > generator > sg > impl > JAXBComplexContentTypeSG


1 /*
2  * Copyright 2003, 2004 The Apache Software Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.ws.jaxme.generator.sg.impl;
17
18 import java.util.ArrayList JavaDoc;
19 import java.util.List JavaDoc;
20
21 import org.apache.ws.jaxme.generator.sg.ComplexContentSG;
22 import org.apache.ws.jaxme.generator.sg.ComplexContentSGChain;
23 import org.apache.ws.jaxme.generator.sg.ComplexTypeSG;
24 import org.apache.ws.jaxme.generator.sg.Context;
25 import org.apache.ws.jaxme.generator.sg.GroupSG;
26 import org.apache.ws.jaxme.generator.sg.ObjectSG;
27 import org.apache.ws.jaxme.generator.sg.ParticleSG;
28 import org.apache.ws.jaxme.generator.sg.SGFactory;
29 import org.apache.ws.jaxme.logging.Logger;
30 import org.apache.ws.jaxme.logging.LoggerAccess;
31 import org.apache.ws.jaxme.xs.XSGroup;
32 import org.apache.ws.jaxme.xs.XSParticle;
33 import org.apache.ws.jaxme.xs.XSType;
34 import org.apache.ws.jaxme.xs.types.XSAnyType;
35 import org.xml.sax.Locator JavaDoc;
36 import org.xml.sax.SAXException JavaDoc;
37 import org.xml.sax.SAXParseException JavaDoc;
38
39
40 /** Default implementation of
41  * {@link org.apache.ws.jaxme.generator.sg.ComplexContentSG}.
42  */

43 public class JAXBComplexContentTypeSG implements ComplexContentSGChain {
44     private static final Logger log = LoggerAccess.getLogger(JAXBComplexContentTypeSG.class);
45
46     private static class Particle {
47         private final GroupSG[] stack;
48         private final ParticleSG particle;
49         Particle(GroupSG[] pStack, ParticleSG pParticle) {
50             stack = pStack;
51             particle = pParticle;
52         }
53         ParticleSG getParticleSG() { return particle; }
54         Object JavaDoc[] getStack() { return stack; }
55         GroupSG getClosestCommonAnchestor(Particle pParticle) {
56             int len = Math.min(stack.length, pParticle.stack.length);
57             GroupSG anchestor = stack[0];
58             for (int i = 1; i < len; i++) {
59                 if (stack[i] != pParticle.stack[i]) {
60                     break;
61                 }
62             }
63             return anchestor;
64         }
65     }
66
67     private final boolean isEmpty, isMixed;
68     private final ParticleSG rootParticle;
69
70     private boolean isInitialized;
71     private final Locator JavaDoc locator;
72     private final List JavaDoc elementParticles = new ArrayList JavaDoc();
73     private Particle[] elementParticleArray;
74     private final List JavaDoc mixedContentParticles = new ArrayList JavaDoc();
75     private final List JavaDoc groupParticlesWithMultiplicityGreaterOne = new ArrayList JavaDoc();
76     private final List JavaDoc wildcardParticles = new ArrayList JavaDoc();
77     private final List JavaDoc stack = new ArrayList JavaDoc();
78
79     protected JAXBComplexContentTypeSG(ComplexTypeSG pComplexTypeSG, XSType pType) throws SAXException JavaDoc {
80         if (pType == XSAnyType.getInstance()) {
81             throw new SAXException JavaDoc("The type xs:anyType is not supported.");
82         }
83         locator = pType.getLocator();
84         if (pType.getComplexType().isEmpty()) {
85             isEmpty = true;
86             isMixed = false;
87             rootParticle = null;
88         } else {
89             XSParticle particle = pType.getComplexType().getParticle();
90             if (particle == null) {
91                 throw new NullPointerException JavaDoc("Missing group particle for type = " + pType.getName());
92             }
93             if (particle.isGroup()) {
94                 rootParticle = newParticleSG(pComplexTypeSG.getTypeSG().getFactory(), particle, pComplexTypeSG.getClassContext());
95             } else {
96                 throw new IllegalStateException JavaDoc("Expected internal group");
97             }
98             isEmpty = false;
99             isMixed = pType.getComplexType().isMixed();
100         }
101     }
102
103     protected ParticleSG newParticleSG(SGFactory pFactory, XSParticle pParticle, Context pContext) throws SAXException JavaDoc {
104         JAXBParticleSG chain = new JAXBParticleSG(pFactory, pParticle, pContext);
105         ParticleSGImpl result = new ParticleSGImpl(chain);
106         result.init();
107         return result;
108     }
109
110     public Locator JavaDoc getLocator(ComplexContentSG pController) { return locator; }
111
112     public void init(ComplexContentSG pController) throws SAXException JavaDoc {
113     }
114
115     private void initialize(ComplexContentSG pController) throws SAXException JavaDoc {
116         if (!isInitialized && !isEmpty) {
117             isInitialized = true;
118             verify(pController);
119         }
120     }
121
122     private Particle[] getLocalElementParticles(ComplexContentSG pController)
123             throws SAXException JavaDoc {
124         initialize(pController);
125         return elementParticleArray;
126     }
127
128     public ParticleSG[] getElementParticles(ComplexContentSG pController)
129             throws SAXException JavaDoc {
130         Particle[] particles = getLocalElementParticles(pController);
131         if (particles == null) {
132             return new ParticleSG[0];
133         }
134         ParticleSG[] result = new ParticleSG[particles.length];
135         for (int i = 0; i < result.length; i++) {
136             result[i] = particles[i].getParticleSG();
137         }
138         return result;
139     }
140
141     public ParticleSG getRootParticle(ComplexContentSG pController) {
142         return rootParticle;
143     }
144     
145     public boolean isEmpty(ComplexContentSG pController) {
146         return isEmpty;
147     }
148     
149     public boolean isMixed(ComplexContentSG pController) {
150         return isMixed;
151     }
152
153     
154     private void findParticles(GroupSG[] pStack, ParticleSG pParticle) throws SAXException JavaDoc {
155         if (pParticle.isGroup()) {
156             if (pParticle.isMultiple()) {
157                 groupParticlesWithMultiplicityGreaterOne.add(new Particle(pStack, pParticle));
158             } else if (isMixed) {
159                 mixedContentParticles.add(new Particle(pStack, pParticle));
160             } else {
161                 findParticles(pParticle.getGroupSG());
162             }
163         } else if (pParticle.isWildcard()) {
164             wildcardParticles.add(new Particle(pStack, pParticle));
165         } else if (pParticle.isElement()) {
166             Particle p = new Particle(pStack, pParticle);
167             elementParticles.add(p);
168         } else {
169             throw new SAXParseException JavaDoc("Invalid particle type", pParticle.getLocator());
170         }
171     }
172
173     private void findParticles(GroupSG pGroup) throws SAXException JavaDoc {
174         stack.add(pGroup);
175         ParticleSG[] particles = pGroup.getParticles();
176         GroupSG[] groups = (GroupSG[]) stack.toArray(new GroupSG[stack.size()]);
177         for (int i = 0; i < particles.length; i++) {
178             findParticles(groups, particles[i]);
179         }
180         stack.remove(stack.size()-1);
181     }
182
183     /** Verifies the contents of a complex type with complex content, according
184      * to the JAXB 1.0 specification, 5.9.7.
185      */

186     private void verify(ComplexContentSG pController) throws SAXException JavaDoc {
187         findParticles(new GroupSG[0], pController.getRootParticle());
188
189         /* 5.9.7, 1) If {content type} is mixed, bind the entire content model
190          * to a general content property with the content-property name "content".
191          * See Section 5.9.4, "Bind mixed content" for more details.
192          */

193         if (pController.isMixed()) {
194             // Make sure, that all groups have the "general content property"
195
}
196         /* 5.9.7, 2) If (1) a particle has {max occurs} > 1 and (2) its term
197          * is a model group, then that particle and its descendants are mapped
198          * to one general content property that represents them. See Section
199          * 5.9.6, "Bind a repeating occurrence model group" for details.
200          */

201         if (groupParticlesWithMultiplicityGreaterOne.size() > 0) {
202             Particle particle = (Particle) groupParticlesWithMultiplicityGreaterOne.get(0);
203             throw new SAXParseException JavaDoc("Model groups with maxOccurs > 1 are not yet supported.",
204                                         particle.getParticleSG().getLocator());
205         }
206         /* 5.9.7, 3) Process all remaining particles 1) whose {term} are
207          * wildcard particles and (2) that did not belong to a repeating
208          * occurrence model group bound in step 2. If there is only one
209          * wildcard, bind it as specified in Section 5.9.5, "Bind wildcard
210          * schema component". If there is more than one, then fallback to
211          * representing the entire content model as a single general
212          * content property.
213          */

214         if (wildcardParticles.size() > 0) {
215             Particle particle = (Particle) wildcardParticles.get(0);
216             throw new SAXParseException JavaDoc("Wildcards are unsupported",
217                                         particle.getParticleSG().getLocator());
218         }
219         /* 5.9.7, 4) Process all particles (1) whose {term} are element
220          * declarations and (2) that do not belong to a repeating occurrence
221          * model group bound in step 2
222          *
223          * First we say a particle has a label L, if it refers to an element
224          * declaration whose {name} is L. Then, for all the possible pair of
225          * particles P and Q in this set, ensure the following constraints are
226          * met:
227          * a) If P and Q have the same label, then they must refer to the same
228          * element declaration.
229          * b) If P and Q refer to the same element reference, then its closest
230          * common ancestor particle may not have sequence as its {term}.
231          *
232          * If either of the above constraints are violated, then the binding
233          * compiler must report a property naming collision, that can be
234          * corrected via customization.
235          */

236         elementParticleArray = (Particle[]) elementParticles.toArray(new Particle[elementParticles.size()]);
237         for (int i = 0; i < elementParticleArray.length; i++) {
238             Particle pParticle = elementParticleArray[i];
239             ParticleSG p = pParticle.getParticleSG();
240             String JavaDoc name = p.getPropertySG().getXMLFieldName();
241             for (int j = i+1; j < elementParticles.size(); j++) {
242                 Particle qParticle = elementParticleArray[j];
243                 ParticleSG q = qParticle.getParticleSG();
244                 if (name.equals(q.getPropertySG().getXMLFieldName())) {
245                     ObjectSG pObject = p.getObjectSG();
246                     ObjectSG qObject = q.getObjectSG();
247                     if (!pObject.isGlobal() || !qObject.isGlobal() ||
248                         pObject != qObject) {
249                         throw new SAXParseException JavaDoc("Multiple element particles named " + name
250                                                     + ", which aren't references to "
251                                                     + " a common global element, are present in a common"
252                                                     + " complex type. (JAXB 1.0, 5.9.7.4.a) Use jaxb:property/@name"
253                                                     + " for customization.", pController.getLocator());
254                     }
255                     GroupSG group = pParticle.getClosestCommonAnchestor(pParticle);
256                     if (group.isSequence()) {
257                         throw new SAXParseException JavaDoc("Multiple element particles named " + name
258                                                     + " are contained in a common sequence."
259                                                     + " (JAXB 1.0, 5.9.7.4.b) Use jaxb:property/@name"
260                                                     + " for customization.", pController.getLocator());
261                     }
262                 }
263             }
264         }
265     }
266 }
267
Popular Tags