View Javadoc
1   /*
2    * The MIT License
3    * Copyright © 2004-2014 Fabrizio Giustina
4    * Copyright © 2022-2022 Web-Legacy
5    *
6    * Permission is hereby granted, free of charge, to any person obtaining a copy
7    * of this software and associated documentation files (the "Software"), to deal
8    * in the Software without restriction, including without limitation the rights
9    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10   * copies of the Software, and to permit persons to whom the Software is
11   * furnished to do so, subject to the following conditions:
12   *
13   * The above copyright notice and this permission notice shall be included in
14   * all copies or substantial portions of the Software.
15   *
16   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22   * THE SOFTWARE.
23   */
24  package net.sf.maventaglib.checker;
25  
26  import java.util.Set;
27  import java.util.TreeSet;
28  
29  import org.apache.commons.lang3.StringUtils;
30  import org.w3c.dom.Document;
31  import org.w3c.dom.Node;
32  import org.w3c.dom.NodeList;
33  
34  import net.sf.maventaglib.util.XmlHelper;
35  
36  
37  /**
38   * Reads a tld file and generates a Tld object. This "manual" parser takes in account different versions of the tlds
39   * @author Fabrizio Giustina
40   * @version $Revision: 217 $ ($Author: fgiust $)
41   */
42  public final class TldParser
43  {
44  
45      /**
46       * don't instantiate.
47       */
48      private TldParser()
49      {
50          // unused
51      }
52  
53      /**
54       * Parse a Tld object from a document.
55       * @param tldDoc Document for the parsed tld
56       * @param tldName of the tld file
57       * @return Tld instance
58       */
59      public static Tld parse(Document tldDoc, String tldName)
60      {
61  
62          Tld tld = new Tld();
63          tld.setFilename(tldName);
64          Set<Tag> tags = new TreeSet<>();
65          Set<ELFunction> functions = new TreeSet<>();
66          Set<TagFile> tagfiles = new TreeSet<>();
67  
68          NodeList tagList = tldDoc.getElementsByTagName("taglib").item(0).getChildNodes(); //$NON-NLS-1$
69  
70          for (int i = 0; i < tagList.getLength(); i++)
71          {
72              Node tagNode = tagList.item(i);
73  
74              if ("shortname".equals(tagNode.getNodeName()) || "short-name".equals(tagNode.getNodeName())) //$NON-NLS-1$ //$NON-NLS-2$
75              {
76                  Node child = tagNode.getFirstChild();
77                  if (child != null)
78                  {
79                      tld.setShortname(child.getNodeValue());
80                  }
81              }
82              else if ("display-name".equals(tagNode.getNodeName())) //$NON-NLS-1$
83              {
84                  Node child = tagNode.getFirstChild();
85                  if (child != null)
86                  {
87                      tld.setName(child.getNodeValue());
88                  }
89              }
90              else if ("info".equals(tagNode.getNodeName()) || "description".equals(tagNode.getNodeName())) //$NON-NLS-1$ //$NON-NLS-2$
91              {
92                  tld.setInfo(XmlHelper.getTextContent(tagNode));
93              }
94              else if ("tlib-version".equals(tagNode.getNodeName()) || "tlibversion".equals(tagNode.getNodeName())) //$NON-NLS-1$ //$NON-NLS-2$
95              {
96                  Node child = tagNode.getFirstChild();
97                  if (child != null)
98                  {
99                      tld.setTlibversion(child.getNodeValue());
100                 }
101             }
102             else if ("uri".equals(tagNode.getNodeName())) //$NON-NLS-1$
103             {
104                 Node child = tagNode.getFirstChild();
105                 if (child != null)
106                 {
107                     tld.setUri(child.getNodeValue());
108                 }
109             }
110             else if ("tag".equals(tagNode.getNodeName())) //$NON-NLS-1$
111             {
112                 Tag tag = parseTag(tagNode);
113                 tags.add(tag);
114             }
115             else if ("function".equals(tagNode.getNodeName())) //$NON-NLS-1$
116             {
117                 ELFunction tag = parseFunction(tagNode);
118                 functions.add(tag);
119             }
120             else if ("tag-file".equals(tagNode.getNodeName())) //$NON-NLS-1$
121             {
122                 TagFile tag = parseTagFile(tagNode);
123                 tagfiles.add(tag);
124             }
125 
126             tld.setTags(tags.toArray(new Tag[tags.size()]));
127             tld.setFunctions(functions.toArray(new ELFunction[functions.size()]));
128             tld.setTagfiles(tagfiles.toArray(new TagFile[tagfiles.size()]));
129         }
130 
131         return tld;
132     }
133 
134     /**
135      * @param tagNode
136      * @return
137      */
138     private static TagFile parseTagFile(Node tagNode)
139     {
140         TagFile tag = new TagFile();
141 
142         NodeList tagAttributes = tagNode.getChildNodes();
143 
144         for (int k = 0; k < tagAttributes.getLength(); k++)
145         {
146             Node tagAttribute = tagAttributes.item(k);
147             String nodeName = tagAttribute.getNodeName();
148 
149             if ("name".equals(nodeName)) //$NON-NLS-1$
150             {
151                 // tag class name
152                 tag.setName(tagAttribute.getFirstChild().getNodeValue());
153             }
154             else if ("description".equals(nodeName)) //$NON-NLS-1$ //$NON-NLS-2$
155             {
156                 tag.setDescription(XmlHelper.getTextContent(tagAttribute));
157             }
158             else if ("path".equals(nodeName)) //$NON-NLS-1$ //$NON-NLS-2$
159             {
160                 tag.setPath(tagAttribute.getFirstChild().getNodeValue());
161             }
162             else if ("example".equals(nodeName)) //$NON-NLS-1$
163             {
164                 tag.setExample(XmlHelper.getTextContent(tagAttribute));
165             }
166 
167         }
168 
169         tag.setDeprecated(StringUtils.contains(tag.getDescription(), "@deprecated")); //$NON-NLS-1$
170 
171         return tag;
172     }
173 
174     /**
175      * @param tagNode
176      * @return
177      */
178     private static ELFunction parseFunction(Node tagNode)
179     {
180         ELFunction tag = new ELFunction();
181         NodeList tagAttributes = tagNode.getChildNodes();
182 
183         for (int k = 0; k < tagAttributes.getLength(); k++)
184         {
185             Node tagAttribute = tagAttributes.item(k);
186             String nodeName = tagAttribute.getNodeName();
187 
188             if ("name".equals(nodeName)) //$NON-NLS-1$
189             {
190                 tag.setName(tagAttribute.getFirstChild().getNodeValue());
191             }
192             else if ("description".equals(nodeName)) //$NON-NLS-1$ //$NON-NLS-2$
193             {
194                 tag.setDescription(XmlHelper.getTextContent(tagAttribute));
195             }
196             else if ("example".equals(nodeName)) //$NON-NLS-1$
197             {
198                 tag.setExample(XmlHelper.getTextContent(tagAttribute));
199             }
200             else if ("function-class".equals(nodeName)) //$NON-NLS-1$
201             {
202                 tag.setFunctionClass(StringUtils.trim(XmlHelper.getTextContent(tagAttribute)));
203             }
204             else if ("function-signature".equals(nodeName)) //$NON-NLS-1$
205             {
206                 String signature = XmlHelper.getTextContent(tagAttribute);
207                 tag.setFunctionSignature(signature);
208                 tag.setParameters(StringUtils.substringBetween(signature, "(", ")"));
209             }
210         }
211 
212         tag.setDeprecated(StringUtils.contains(tag.getDescription(), "@deprecated")); //$NON-NLS-1$
213 
214         return tag;
215     }
216 
217     /**
218      * Parse a <code>tag</code> element.
219      * @param tagNode Node
220      * @return a Tag instance
221      */
222     private static Tag parseTag(Node tagNode)
223     {
224         Tag tag = new Tag();
225         Set<TagAttribute> attributes = new TreeSet<>();
226         Set<TagVariable> variables = new TreeSet<>();
227         NodeList tagAttributes = tagNode.getChildNodes();
228 
229         for (int k = 0; k < tagAttributes.getLength(); k++)
230         {
231             Node tagAttribute = tagAttributes.item(k);
232             String nodeName = tagAttribute.getNodeName();
233 
234             if ("name".equals(nodeName)) //$NON-NLS-1$
235             {
236                 // tag class name
237                 tag.setName(tagAttribute.getFirstChild().getNodeValue());
238             }
239             else if ("description".equals(nodeName) || "info".equals(nodeName)) //$NON-NLS-1$ //$NON-NLS-2$
240             {
241                 tag.setDescription(XmlHelper.getTextContent(tagAttribute));
242             }
243             else if ("tag-class".equals(nodeName) || "tagclass".equals(nodeName)) //$NON-NLS-1$ //$NON-NLS-2$
244             {
245                 tag.setTagClass(StringUtils.trim(tagAttribute.getFirstChild().getNodeValue()));
246             }
247             else if ("body-content".equals(nodeName) || "bodycontent".equals(nodeName)) //$NON-NLS-1$ //$NON-NLS-2$
248             {
249                 tag.setBodycontent(tagAttribute.getFirstChild().getNodeValue());
250             }
251             else if ("example".equals(nodeName)) //$NON-NLS-1$
252             {
253                 tag.setExample(XmlHelper.getTextContent(tagAttribute));
254             }
255             else if ("tei-class".equals(nodeName) || "teiclass".equals(nodeName)) //$NON-NLS-1$ //$NON-NLS-2$
256             {
257                 // tei class name
258                 tag.setTeiClass(StringUtils.trim(tagAttribute.getFirstChild().getNodeValue()));
259             }
260             else if ("attribute".equals(nodeName)) //$NON-NLS-1$
261             {
262                 TagAttribute attribute = parseTagAttribute(tagAttribute);
263                 attributes.add(attribute);
264             }
265             else if ("variable".equals(nodeName)) //$NON-NLS-1$
266             {
267                 TagVariable variable = parseTagVariable(tagAttribute);
268                 variables.add(variable);
269             }
270             tag.setAttributes(attributes.toArray(new TagAttribute[attributes.size()]));
271             tag.setVariables(variables.toArray(new TagVariable[variables.size()]));
272         }
273 
274         tag.setDeprecated(StringUtils.contains(tag.getDescription(), "@deprecated")); //$NON-NLS-1$
275 
276         return tag;
277     }
278 
279     /**
280      * Parse an <code>attribute</code> element.
281      * @param tagAttribute Node
282      * @return TagAttribute instance
283      */
284     private static TagAttribute parseTagAttribute(Node tagAttribute)
285     {
286         TagAttribute attribute = new TagAttribute();
287 
288         NodeList attributeParams = tagAttribute.getChildNodes();
289         for (int z = 0; z < attributeParams.getLength(); z++)
290         {
291             Node param = attributeParams.item(z);
292             if (param.getNodeType() != Node.TEXT_NODE && param.hasChildNodes())
293             {
294                 if ("name".equals(param.getNodeName())) //$NON-NLS-1$
295                 {
296                     attribute.setName(param.getFirstChild().getNodeValue());
297                 }
298                 else if ("type".equals(param.getNodeName())) //$NON-NLS-1$
299                 {
300                     attribute.setType(StringUtils.trim(param.getFirstChild().getNodeValue()));
301                 }
302                 else if ("description".equals(param.getNodeName())) //$NON-NLS-1$
303                 {
304                     attribute.setDescription(XmlHelper.getTextContent(param));
305                 }
306                 else if ("required".equals(param.getNodeName())) //$NON-NLS-1$
307                 {
308                     attribute.setRequired(StringUtils.contains(StringUtils.lowerCase(param
309                         .getFirstChild()
310                         .getNodeValue()), "true")); //$NON-NLS-1$
311                 }
312                 else if ("rtexprvalue".equals(param.getNodeName())) //$NON-NLS-1$
313                 {
314                     attribute.setRtexprvalue(StringUtils.contains(StringUtils.lowerCase(param
315                         .getFirstChild()
316                         .getNodeValue()), "true")); //$NON-NLS-1$
317                 }
318             }
319         }
320 
321         attribute.setDeprecated(StringUtils.contains(attribute.getDescription(), "@deprecated")); //$NON-NLS-1$
322 
323         return attribute;
324     }
325 
326     /**
327      * Parse an <code>attribute</code> element.
328      * @param node Node
329      * @return TagAttribute instance
330      */
331     private static TagVariable parseTagVariable(Node node)
332     {
333         TagVariable variable = new TagVariable();
334 
335         NodeList attributeParams = node.getChildNodes();
336         for (int z = 0; z < attributeParams.getLength(); z++)
337         {
338             Node param = attributeParams.item(z);
339             if (param.getNodeType() != Node.TEXT_NODE && param.hasChildNodes())
340             {
341                 if ("name-given".equals(param.getNodeName())) //$NON-NLS-1$
342                 {
343                     variable.setNameGiven(param.getFirstChild().getNodeValue());
344                 }
345                 if ("name-from-attribute".equals(param.getNodeName())) //$NON-NLS-1$
346                 {
347                     variable.setNameFromAttribute(param.getFirstChild().getNodeValue());
348                 }
349                 else if ("variable-class".equals(param.getNodeName())) //$NON-NLS-1$
350                 {
351                     variable.setType(param.getFirstChild().getNodeValue());
352                 }
353                 else if ("scope".equals(param.getNodeName())) //$NON-NLS-1$
354                 {
355                     variable.setScope(param.getFirstChild().getNodeValue());
356                 }
357                 else if ("description".equals(param.getNodeName()) || "info".equals(param.getNodeName())) //$NON-NLS-1$ //$NON-NLS-2$
358                 {
359                     variable.setDescription(XmlHelper.getTextContent(param));
360                 }
361 
362             }
363         }
364 
365         variable.setDeprecated(StringUtils.contains(variable.getDescription(), "@deprecated")); //$NON-NLS-1$
366 
367         return variable;
368     }
369 
370 }