KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * Copyright 2005 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.ccsg;
17
18 import java.util.HashMap JavaDoc;
19 import java.util.Iterator JavaDoc;
20 import java.util.List JavaDoc;
21 import java.util.Map JavaDoc;
22
23 import org.apache.ws.jaxme.JMManager;
24 import org.apache.ws.jaxme.generator.sg.ComplexContentSG;
25 import org.apache.ws.jaxme.generator.sg.ComplexTypeSG;
26 import org.apache.ws.jaxme.generator.sg.Context;
27 import org.apache.ws.jaxme.generator.sg.GroupSG;
28 import org.apache.ws.jaxme.generator.sg.ObjectSG;
29 import org.apache.ws.jaxme.generator.sg.ParticleSG;
30 import org.apache.ws.jaxme.generator.sg.TypeSG;
31 import org.apache.ws.jaxme.impl.JMSAXElementParser;
32 import org.apache.ws.jaxme.impl.JMSAXGroupParser;
33 import org.apache.ws.jaxme.impl.JMUnmarshallerHandlerImpl;
34 import org.apache.ws.jaxme.js.DirectAccessible;
35 import org.apache.ws.jaxme.js.JavaField;
36 import org.apache.ws.jaxme.js.JavaInnerClass;
37 import org.apache.ws.jaxme.js.JavaMethod;
38 import org.apache.ws.jaxme.js.JavaQName;
39 import org.apache.ws.jaxme.js.JavaSource;
40 import org.apache.ws.jaxme.js.LocalJavaField;
41 import org.apache.ws.jaxme.js.Parameter;
42 import org.apache.ws.jaxme.js.TypedValue;
43 import org.apache.ws.jaxme.xs.xml.XsQName;
44 import org.xml.sax.SAXException JavaDoc;
45
46
47 /** An instance of <code>GroupHandlerSG</code> is
48  * responsible for creating an instance of
49  * {@link org.apache.ws.jaxme.impl.JMSAXGroupParser},
50  * or {@link org.apache.ws.jaxme.impl.JMSAXElementParser}.<br>
51  * The {@link org.apache.ws.jaxme.generator.sg.ComplexContentSG}
52  * creates a <code>GroupHandlerSG</code> for any group,
53  * contained in the element.
54  */

55 public abstract class GroupHandlerSG extends HandlerSGImpl {
56     protected final ComplexContentSG ccSG;
57     protected final GroupSG group;
58     protected final ParticleSG[] particles;
59     private final Map JavaDoc groups = new HashMap JavaDoc();
60     private JavaField stateField;
61     private final boolean isMixed;
62     protected final GroupHandlerSG outerHandler;
63
64     /** Creates a new instance, which generates a handler for
65      * the complex type <code>pTypeSG</code> by adding methods
66      * and fields to the Java class <code>pJs</code>.
67      */

68     protected GroupHandlerSG(ComplexTypeSG pType, JavaSource pJs) throws SAXException JavaDoc {
69         super(pType, pJs);
70         outerHandler = this;
71         ccSG = pType.getComplexContentSG();
72         group = ccSG.getRootParticle().getGroupSG();
73         particles = group.getParticles();
74         isMixed = ccSG.isMixed();
75         findGroups(particles);
76     }
77
78     /** Creates a new instance, which generates a handler for
79      * the group <code>pGroupSG</code> by adding methods and
80      * fields to the Java class <code>pJs</code>.
81      */

82     protected GroupHandlerSG(GroupHandlerSG pOuterHandler, ComplexTypeSG pType,
83                              GroupSG pGroup, JavaSource pJs) throws SAXException JavaDoc {
84         super(pType, pJs);
85         outerHandler = pOuterHandler;
86         if (!pJs.isInnerClass()) {
87             throw new IllegalStateException JavaDoc("Expected inner class");
88         }
89         ccSG = null;
90         group = pGroup;
91         particles = pGroup.getParticles();
92         isMixed = pType.getComplexContentSG().isMixed();
93         findGroups(particles);
94     }
95
96     protected abstract JavaField newStateField() throws SAXException JavaDoc;
97
98     protected JavaField getStateField() throws SAXException JavaDoc {
99         if (stateField == null) {
100             stateField = newStateField();
101         }
102         return stateField;
103     }
104
105     protected GroupHandlerSG getGroupHandlerSG(GroupSG pGroup) {
106         return (GroupHandlerSG) groups.get(pGroup);
107     }
108
109     private GroupHandlerSG newGroupHandlerSG(GroupSG pGroup, String JavaDoc pName) throws SAXException JavaDoc {
110         JavaSource js = getJavaSource();
111         JavaInnerClass jic = js.newJavaInnerClass(pName, JavaSource.PUBLIC);
112         jic.addExtends(JMSAXGroupParser.class);
113         if (pGroup.isSequence()) {
114             return new SequenceHandlerSG(outerHandler, ctSG, pGroup, jic);
115         } else if (pGroup.isChoice()) {
116             return new ChoiceHandlerSG(outerHandler, ctSG, pGroup, jic);
117         } else if (pGroup.isAll()) {
118             return new AllHandlerSG(outerHandler, ctSG, pGroup, jic);
119         } else {
120             throw new IllegalStateException JavaDoc("Invalid group type");
121         }
122     }
123
124     private GroupHandlerSG newGroupHandlerSG(GroupSG pGroup) throws SAXException JavaDoc {
125         JavaSource js = getJavaSource();
126         String JavaDoc name = GroupUtil.getGroupName(pGroup);
127         for (int i = 0; ; i++) {
128             String JavaDoc n = name;
129             if (i > 0) {
130                 name += i;
131             }
132             n += "Handler";
133             if (js.getInnerClass(n) == null) {
134                 GroupHandlerSG result = newGroupHandlerSG(pGroup, n);
135                 result.newGetHandlerMethod(js);
136                 return result;
137             }
138         }
139     }
140
141     public JavaMethod newAddAttributeMethod() throws SAXException JavaDoc {
142         if (ccSG == null) {
143             return null;
144         } else {
145             return super.newAddAttributeMethod();
146         }
147     }
148
149     private void findGroups(ParticleSG[] pParticles) throws SAXException JavaDoc {
150         for (int i = 0; i < pParticles.length; i++) {
151             ParticleSG particle = pParticles[i];
152             if (particle.isGroup()) {
153                 GroupSG group = particle.getGroupSG();
154                 if (!groups.containsKey(group)) {
155                     GroupHandlerSG handler = newGroupHandlerSG(group);
156                     groups.put(group, handler);
157                 }
158             } else if (particle.isElement()) {
159                 TypeSG tSG = particle.getObjectSG().getTypeSG();
160                 if (tSG.isComplex() && !tSG.isGlobalClass()) {
161                     tSG.getComplexTypeSG().getXMLHandler(outerHandler.getJavaSource());
162                 }
163             }
164         }
165     }
166
167     protected boolean isRequiredParticle(ParticleSG particleSG) {
168         return particleSG.getMinOccurs() > 0;
169     }
170
171     protected void handleStartOfChildElement(Object JavaDoc pUnmarshallerHandler,
172                                              JavaMethod pJm, ParticleSG pParticle) {
173         ObjectSG oSG = pParticle.getObjectSG();
174         TypeSG tSG = oSG.getTypeSG();
175         if (tSG.isComplex()) {
176             JavaQName elementInterfaceClass = pParticle.getObjectSG().getClassContext().getXMLInterfaceName();
177             Object JavaDoc[] o, h;
178             if (oSG.getClassContext().isGlobal()) {
179                 LocalJavaField manager = pJm.newJavaField(JMManager.class);
180                 manager.addLine("getHandler().getJMUnmarshaller().getJAXBContextImpl().getManagerS(",
181                         elementInterfaceClass, ".class)");
182                 o = new Object JavaDoc[]{manager, ".getElementS();"};
183                 h = new Object JavaDoc[]{manager, ".getHandler();"};
184             } else {
185                 Context context = oSG.getClassContext();
186                 o = new Object JavaDoc[]{" new ", context.getXMLImplementationName(), "()"};
187                 h = new Object JavaDoc[]{" new ", context.getXMLHandlerName(), "()"};
188             }
189             LocalJavaField oField = pJm.newJavaField(Object JavaDoc.class);
190             oField.addLine(o);
191             LocalJavaField hField = pJm.newJavaField(JMSAXElementParser.class);
192             hField.addLine(h);
193             XsQName name = oSG.getName();
194             pJm.addLine(hField, ".init(", pUnmarshallerHandler, ", ", oField, ", ",
195                     JavaSource.getQuoted(name.getNamespaceURI()), ", ",
196                     JavaSource.getQuoted(name.getLocalName()),
197             ", ", pUnmarshallerHandler, ".getLevel());");
198             pJm.addLine(hField, ".setAttributes(", getParamAttrs(), ");");
199             pJm.addLine(pUnmarshallerHandler, ".addElementParser(", hField, ");");
200         } else {
201             pJm.addLine(pUnmarshallerHandler, ".addSimpleAtomicState();");
202         }
203     }
204
205     protected abstract void acceptParticle(JavaMethod pJm, int pNum) throws SAXException JavaDoc;
206
207     protected void handleStartElementStates(Object JavaDoc pUnmarshallerHandler,
208                                             JavaMethod pJm, int pFrom,
209                                             int pTo) throws SAXException JavaDoc {
210         if (pFrom < 0 || pFrom >= particles.length ||
211             pTo < 0 || pTo >= particles.length || pTo < pFrom) {
212             return;
213         }
214         for (int i = pFrom; i <= pTo; i++) {
215             ParticleSG particle = particles[i];
216             if (particle.isElement()) {
217                 ObjectSG oSG = particle.getObjectSG();
218                 XsQName name = oSG.getName();
219                 Object JavaDoc uriCondition;
220                 if ("".equals(name.getNamespaceURI())) {
221                     uriCondition = new Object JavaDoc[]{"(", getParamNamespaceURI(),
222                             " == null || ",
223                             getParamNamespaceURI(),
224                     ".length() == 0)"};
225                 } else {
226                     uriCondition = new Object JavaDoc[]{JavaSource.getQuoted(name.getNamespaceURI()),
227                             ".equals(", getParamNamespaceURI(), ")"};
228                 }
229                 pJm.addIf(i == pFrom, uriCondition, " && ",
230                           JavaSource.getQuoted(name.getLocalName()),
231                           ".equals(", getParamLocalName(), ")");
232                 acceptParticle(pJm, i);
233                 handleStartOfChildElement(pUnmarshallerHandler, pJm, particle);
234                 pJm.addLine("return true;");
235             } else if (particle.isGroup()) {
236                 GroupSG gSG = particle.getGroupSG();
237                 GroupHandlerSG handlerSG = getGroupHandlerSG(gSG);
238                 pJm.addIf(i == pFrom,
239                           pUnmarshallerHandler, ".testGroupParser(new ",
240                           handlerSG.getJavaSource().getQName(), "(), ",
241                           getParamNamespaceURI(), ", ", getParamLocalName(),
242                           ", ", getParamQName(), ", ", getParamAttrs(), ")");
243                 acceptParticle(pJm, i);
244                 pJm.addLine("return true;");
245             } else if (particle.isWildcard()) {
246                 throw new IllegalStateException JavaDoc("TODO: Add support for wildcards");
247             } else {
248                 throw new IllegalStateException JavaDoc("Invalid particle type");
249             }
250         }
251         pJm.addEndIf();
252     }
253
254     protected abstract int getState(int pParticleNum);
255     protected abstract DirectAccessible getEndElementState() throws SAXException JavaDoc;
256
257     public JavaMethod newEndElementMethod() throws SAXException JavaDoc {
258         JavaMethod result = super.newEndElementMethod();
259         JavaQName elementInterface = ctSG.getClassContext().getXMLInterfaceName();
260         LocalJavaField element = result.newJavaField(elementInterface);
261         element.addLine("(", elementInterface, ") result");
262         result.addSwitch(getEndElementState());
263         for (int i = 0; i < particles.length; i++) {
264             result.addCase(new Integer JavaDoc(getState(i)));
265             ParticleSG particle = particles[i];
266             handleEndElementState(result, element, particle);
267         }
268         result.addDefault();
269         result.addThrowNew(IllegalStateException JavaDoc.class,
270                            JavaSource.getQuoted("Illegal state: "), " + ",
271                            getEndElementState());
272         result.addEndSwitch();
273         return result;
274     }
275
276     private void handleEndElementState(JavaMethod pJm, LocalJavaField pElement,
277                                        ParticleSG pParticle) throws SAXException JavaDoc {
278         if (pParticle.isElement()) {
279             ObjectSG oSG = pParticle.getObjectSG();
280             TypeSG childType = oSG.getTypeSG();
281             XsQName name = oSG.getName();
282             Object JavaDoc[] uriCondition;
283             if ("".equals(name.getNamespaceURI())) {
284                 uriCondition = new Object JavaDoc[]{
285                     getParamNamespaceURI(), " == null || ",
286                     getParamNamespaceURI(), ".length() == 0"
287                 };
288             } else {
289                 uriCondition = new Object JavaDoc[]{
290                     JavaSource.getQuoted(name.getNamespaceURI()), ".equals(",
291                     getParamNamespaceURI(), ")"
292                 };
293             }
294             pJm.addIf(uriCondition, " && ", JavaSource.getQuoted(name.getLocalName()),
295                     ".equals(", getParamLocalName(), ")");
296             JavaQName type;
297             TypedValue v = getParamResult();
298             if (childType.isComplex()) {
299                 type = childType.getComplexTypeSG().getClassContext().getXMLInterfaceName();
300             } else {
301                 v = createSimpleTypeConversion(pJm, childType, v, oSG.getName().toString());
302                 type = null;
303                 if (isMixed) {
304                     LocalJavaField f = pJm.newJavaField(GroupUtil.getContentClass(group, pParticle, ctSG.getClassContext().getXMLInterfaceName()));
305                     f.addLine("new ", GroupUtil.getContentClass(group, pParticle, ctSG.getClassContext().getXMLImplementationName()), "()");
306                     pJm.addLine(f, ".setValue(", v, ");");
307                     v = f;
308                 }
309             }
310             if (isMixed) {
311                 pJm.addLine(pElement, ".getContent().add(", v, ");");
312             } else {
313                 pParticle.getPropertySG().addValue(pJm, pElement, v, type);
314             }
315             pJm.addLine("return;");
316             pJm.addEndIf();
317             pJm.addBreak();
318         } else if (pParticle.isGroup()) {
319             pJm.addThrowNew(IllegalStateException JavaDoc.class,
320                             JavaSource.getQuoted("This case should be handled by a nested group parser."));
321         } else if (pParticle.isWildcard()) {
322             throw new IllegalStateException JavaDoc("TODO: Add support for wildcards.");
323         } else {
324             throw new IllegalStateException JavaDoc("Invalid particle type");
325         }
326     }
327
328     public JavaMethod newIsAtomicMethod() throws SAXException JavaDoc {
329         return null;
330     }
331
332     public JavaMethod newIsEmptyMethod() throws SAXException JavaDoc {
333         return null;
334     }
335
336     protected JavaMethod newIsMixedMethod() throws SAXException JavaDoc {
337         if (!isMixed) {
338             return null;
339         }
340         JavaMethod jm = getJavaSource().newJavaMethod("isMixed", boolean.class, JavaSource.PUBLIC);
341         jm.addLine("return true;");
342         return jm;
343     }
344
345     protected JavaMethod newAddTextMethod() throws SAXException JavaDoc {
346         if (!isMixed) {
347             return null;
348         }
349         JavaMethod jm = getJavaSource().newJavaMethod("addText", void.class, JavaSource.PUBLIC);
350         Parameter buffer = jm.addParam(char[].class, "pBuffer");
351         Parameter offset = jm.addParam(int.class, "pOffset");
352         Parameter length = jm.addParam(int.class, "pLength");
353         if (ccSG == null) {
354             jm.addLine(outerHandler.getJavaSource().getQName(), ".this.addText(",
355                        buffer, ", ", offset, ", ", length, ");");
356         } else {
357             JavaQName elementInterface = ctSG.getClassContext().getXMLInterfaceName();
358             LocalJavaField element = jm.newJavaField(elementInterface);
359             element.addLine("(", elementInterface, ") result");
360             Object JavaDoc s = new Object JavaDoc[]{"new ", String JavaDoc.class, "(", buffer, ", ",
361                                     offset, ", ", length, ")"};
362             LocalJavaField list = jm.newJavaField(List JavaDoc.class);
363             list.addLine(element, ".getContent()");
364             jm.addIf(list, ".size() > 0");
365             LocalJavaField o = jm.newJavaField(Object JavaDoc.class);
366             o.addLine(list, ".get(", list, ".size()-1)");
367             jm.addIf(o, " instanceof ", String JavaDoc.class);
368             jm.addLine(list, ".set(", list, ".size()-1, ",
369                        "((", String JavaDoc.class, ") ", o, ") + ", s, ");");
370             jm.addLine("return;");
371             jm.addEndIf();
372             jm.addEndIf();
373             jm.addLine(list, ".add(", s, ");");
374         }
375         return jm;
376     }
377
378     private JavaMethod newGetHandlerMethod(JavaSource pOuter) throws SAXException JavaDoc {
379         JavaMethod result = getJavaSource().newJavaMethod("getHandler", JMUnmarshallerHandlerImpl.class, JavaSource.PUBLIC);
380         result.addLine("return ", pOuter.getQName(), ".this.getHandler();");
381         return result;
382     }
383
384     public void generate() throws SAXException JavaDoc {
385         super.generate();
386         newAddTextMethod();
387         newIsMixedMethod();
388         for (Iterator JavaDoc iter = groups.values().iterator(); iter.hasNext(); ) {
389             HandlerSG handler = (HandlerSG) iter.next();
390             handler.generate();
391         }
392     }
393 }
Popular Tags