KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > xml > xmlc > compiler > ElementInfo


1 /*
2  * Enhydra Java Application Server Project
3  *
4  * The contents of this file are subject to the Enhydra Public License
5  * Version 1.1 (the "License"); you may not use this file except in
6  * compliance with the License. You may obtain a copy of the License on
7  * the Enhydra web site ( http://www.enhydra.org/ ).
8  *
9  * Software distributed under the License is distributed on an "AS IS"
10  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
11  * the License for the specific terms governing rights and limitations
12  * under the License.
13  *
14  * The Initial Developer of the Enhydra Application Server is Lutris
15  * Technologies, Inc. The Enhydra Application Server and portions created
16  * by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
17  * All Rights Reserved.
18  *
19  * Contributor(s):
20  *
21  * $Id: ElementInfo.java,v 1.3 2005/01/26 08:29:24 jkjome Exp $
22  */

23
24 package org.enhydra.xml.xmlc.compiler;
25
26 import org.enhydra.xml.xmlc.codegen.JavaLang;
27 import org.enhydra.xml.xmlc.dom.XMLCDocument;
28 import org.enhydra.xml.xmlc.metadata.DocumentClass;
29 import org.enhydra.xml.xmlc.metadata.MetaData;
30 import org.w3c.dom.Attr JavaDoc;
31 import org.w3c.dom.Element JavaDoc;
32 import org.w3c.dom.html.HTMLElement;
33
34 //FIXME: this is designed to evolve forward to something that provides
35
//information taken from both the DOM and metadata.
36
//FIXME: Maybe really need a clientdata instead of adjust size & buildMethodFlags.
37
//FIXME: are sizes still needed??
38

39 // jrk_20040703 - I think the setText fixme is solved (see comment in the constructor
40
// for details), but leaving the note here for posterity.
41
//FIXME: `accessor' terminology is broken; sometimes accessor includes
42
// setText and sometimes it doesn.
43

44 /**
45  * Information about a particular Element. Several fields are also
46  * kept for code generators, although this is not do in a general
47  * way.
48  */

49 public final class ElementInfo {
50     /**
51      * Information about an accessor method (getElementXXX, getTagXXX) to
52      * create for this element.
53      */

54     public class AccessorInfo {
55         /** Name of the method to create */
56         public final String JavaDoc fName;
57
58         /** Return type of accessor */
59         public final String JavaDoc fReturnType;
60
61         /**
62          * Constructor.
63          */

64         public AccessorInfo(String JavaDoc name,
65                             String JavaDoc returnType) {
66             fName = name;
67             fReturnType = returnType;
68         }
69     }
70
71     /**
72      * Container for DOM.
73      */

74     private XMLCDocument fXmlcDoc;
75
76     /**
77      * The element this object is associated with.
78      */

79     private Element JavaDoc fElement;
80
81     /**
82      * The interface or class name to use in referencing the element.
83      */

84     private String JavaDoc fReferenceName;
85
86     /**
87      * The XML id for the element (value of the id field).
88      */

89     private String JavaDoc fXmlId;
90
91     /**
92      * The java id for element. Will be null if a valid Java id could not
93      * be formed.
94      */

95     private String JavaDoc fJavaId;
96
97     /**
98      * List of accessors to create, or null if none.
99      */

100     private AccessorInfo[] fAccessorInfo;;
101
102     /**
103      * Should a setText method be generated for this element?
104      */

105     private boolean fCreateSetText;
106
107     /**
108      * Size of the element, in nodes, excluding children
109      */

110     private int fNodeSize;
111
112     /**
113      * Size of the subtree of this element, in number of nodes.
114      */

115     private int fSubTreeNodeSize;
116
117     /**
118      * Adjusted size of subtree. This is used by the code generators
119      * to store a size that is used in optimizing subtree creation.
120      * Initialized to the subtree node-size.
121      */

122     private int fAdjustedSubTreeNodeSize;
123
124     /**
125      * Constructor.
126      */

127     public ElementInfo(Element JavaDoc element,
128                        int nodeSize,
129                        int subTreeNodeSize,
130                        MetaData metaData,
131                        XMLCDocument xmlcDoc) {
132         if (element == null) {
133             throw new IllegalArgumentException JavaDoc("element null");
134         }
135         fElement = element;
136         fNodeSize = nodeSize;
137         fSubTreeNodeSize = subTreeNodeSize;
138         fAdjustedSubTreeNodeSize = subTreeNodeSize;
139         fXmlcDoc = xmlcDoc;
140
141         determineIds();
142         initAccessorInfo(metaData);
143
144         // Create setTextXXX() if there is a legal Java id, #PCDATA is in the
145
// content model
146
fCreateSetText = (fJavaId != null)
147             && fXmlcDoc.hasPCDataInContentModel(fElement);
148             //&& (XMLCUtil.findFirstText(fElement) != null); //jrk_20040703 - XMLObjectImpl.doSetText() now creates a text node if it doesn't already exist, so no need to avoid setText*() creation!
149
}
150
151     /**
152      * Translate the accessor return type from the MetaData to a actual return
153      * type. They translates various short-cuts to actual class names.
154      */

155     private String JavaDoc getAccessorReturnType(String JavaDoc typeSpec) {
156         if (typeSpec.equals(DocumentClass.ACCESSOR_TYPE_INTERFACE)) {
157             return fXmlcDoc.getDomFactory().nodeClassToInterface(fElement);
158         } else if (typeSpec.equals(DocumentClass.ACCESSOR_TYPE_CLASS)) {
159             return fElement.getClass().getName();
160         } else if (typeSpec.equals(DocumentClass.ACCESSOR_TYPE_ELEMENT)) {
161             return Element JavaDoc.class.getName();
162         } else if (typeSpec.equals(DocumentClass.ACCESSOR_TYPE_HTML_ELEMENT)) {
163             return HTMLElement.class.getName();
164         } else {
165             return typeSpec;
166         }
167     }
168
169     /**
170      * Initialize the information of the accessors to create.
171      */

172     private void initAccessorInfo(MetaData metaData) {
173         boolean createGetElement = (fJavaId != null);
174         boolean createGetTag = (fJavaId != null)
175             && metaData.getDocumentClass().getCreateGetTagMethods();
176         
177         int numAccessors = (createGetElement ? 1 : 0)
178             + (createGetTag ? 1 : 0);
179         if (numAccessors == 0) {
180             return;
181         }
182         fAccessorInfo = new AccessorInfo[numAccessors];
183         int idx = 0;
184     
185         fReferenceName = metaData.getDocumentClass().getGetTagReturnType();
186         if (createGetElement) {
187         fReferenceName =
188         fXmlcDoc.getDomFactory().nodeClassToInterface(fElement);
189             fAccessorInfo[idx++]
190                 = new AccessorInfo("getElement" + fJavaId, fReferenceName);
191                                    
192                                                  
193         }
194         if (createGetTag) {
195             fAccessorInfo[idx++]
196                 = new AccessorInfo("getTag" + fJavaId,
197                    getAccessorReturnType(metaData.getDocumentClass().getGetTagReturnType()));
198         }
199     }
200
201     /**
202      * Adjust an element id to conform to the Java naming convention.
203      * Upshifts the first character.
204      */

205     private String JavaDoc adjustElementId(String JavaDoc id) {
206         return id.substring(0, 1).toUpperCase() + id.substring(1);
207     }
208
209     /**
210      * Determine the XML and Java ids for the element.
211      */

212     private void determineIds() {
213         // Get id attribute
214
String JavaDoc idAttrName = fXmlcDoc.getIdAttrName(fElement);
215         if (idAttrName != null) {
216             Attr JavaDoc idAttr = fElement.getAttributeNode(idAttrName);
217             if (idAttr != null) {
218                 fXmlId = idAttr.getNodeValue();
219                 if (JavaLang.legalJavaIdentifier(fXmlId)) {
220                     fJavaId = adjustElementId(fXmlId);
221                 }
222             }
223         }
224     }
225
226     /**
227      * Get the element.
228      */

229     public Element JavaDoc getElement() {
230         return fElement;
231     }
232
233     /**
234      * Get the Java class name of the element.
235      */

236     public String JavaDoc getClassName() {
237         return fElement.getClass().getName();
238     }
239
240     /**
241      * Get the reference name for this element. In general, this is
242      * the name of the return type for the "getElementXXX()" accessor.
243      */

244     public String JavaDoc getReferenceName() {
245         return fReferenceName;
246     }
247
248     /**
249      * Get the XML id, or null if there isn't one.
250      */

251     public String JavaDoc getXmlId() {
252         return fXmlId;
253     }
254
255     /**
256      * Get the Java id, or null if there isn't one.
257      */

258     public String JavaDoc getJavaId() {
259         return fJavaId;
260     }
261
262     /**
263      * Get the element class (attribute) names
264      */

265     public String JavaDoc[] getElementClassNames() {
266         return fXmlcDoc.getElementClassNames(fElement);
267     }
268
269     /**
270      * Get the element name (name attribute in HTML).
271      */

272     public String JavaDoc getElementName() {
273         return fXmlcDoc.getElementName(fElement);
274     }
275
276     /**
277      * Is the element id an invalid Java identifier?
278      */

279     public boolean hasInvalidJavaId() {
280         return (fXmlId != null) && (fJavaId == null);
281     }
282
283     /**
284      * Get the total number of access methods for this element.
285      */

286     public int getNumAccessMethods() {
287         return ((fAccessorInfo != null) ? fAccessorInfo.length : 0)
288             + (fCreateSetText ? 1 : 0);
289     }
290
291     /**
292      * Get the list of accessors to create.
293      */

294     public AccessorInfo[] getAccessors() {
295         return fAccessorInfo;
296     }
297
298     /**
299      * Should a setText method be generated for this element?
300      */

301     public boolean createSetText() {
302         return fCreateSetText;
303     }
304
305     /*
306      * Get the size of the element, in nodes. This includes the element
307      * itself, and attributes and their descendents, but not children.
308      */

309     public int getNodeSize() {
310         return fNodeSize;
311     }
312
313     /*
314      * Get the size of the subtree, in nodes, rooted at this element.
315      */

316     public int getSubTreeNodeSize() {
317         return fSubTreeNodeSize;
318     }
319
320     /*
321      * Get the adjusted size of the subtree. This value is initially
322      * the same as the subtree node-size, but can be adjusted by a
323      * code generator for it's own purposes.
324      */

325     public int getAdjustedSubTreeNodeSize() {
326         return fAdjustedSubTreeNodeSize;
327     }
328
329     /*
330      * Set the adjusted size of the subtree.
331      */

332     public void setAdjustedSubTreeNodeSize(int size) {
333         fAdjustedSubTreeNodeSize = size;
334     }
335 }
336
Popular Tags