View Javadoc

1   /*
2    *  Java HTML Tidy - JTidy
3    *  HTML parser and pretty printer
4    *
5    *  Copyright (c) 1998-2000 World Wide Web Consortium (Massachusetts
6    *  Institute of Technology, Institut National de Recherche en
7    *  Informatique et en Automatique, Keio University). All Rights
8    *  Reserved.
9    *
10   *  Contributing Author(s):
11   *
12   *     Dave Raggett <dsr@w3.org>
13   *     Andy Quick <ac.quick@sympatico.ca> (translation to Java)
14   *     Gary L Peskin <garyp@firstech.com> (Java development)
15   *     Sami Lempinen <sami@lempinen.net> (release management)
16   *     Fabrizio Giustina <fgiust at users.sourceforge.net>
17   *
18   *  The contributing author(s) would like to thank all those who
19   *  helped with testing, bug fixes, and patience.  This wouldn't
20   *  have been possible without all of you.
21   *
22   *  COPYRIGHT NOTICE:
23   * 
24   *  This software and documentation is provided "as is," and
25   *  the copyright holders and contributing author(s) make no
26   *  representations or warranties, express or implied, including
27   *  but not limited to, warranties of merchantability or fitness
28   *  for any particular purpose or that the use of the software or
29   *  documentation will not infringe any third party patents,
30   *  copyrights, trademarks or other rights. 
31   *
32   *  The copyright holders and contributing author(s) will not be
33   *  liable for any direct, indirect, special or consequential damages
34   *  arising out of any use of the software or documentation, even if
35   *  advised of the possibility of such damage.
36   *
37   *  Permission is hereby granted to use, copy, modify, and distribute
38   *  this source code, or portions hereof, documentation and executables,
39   *  for any purpose, without fee, subject to the following restrictions:
40   *
41   *  1. The origin of this source code must not be misrepresented.
42   *  2. Altered versions must be plainly marked as such and must
43   *     not be misrepresented as being the original source.
44   *  3. This Copyright notice may not be removed or altered from any
45   *     source or altered source distribution.
46   * 
47   *  The copyright holders and contributing author(s) specifically
48   *  permit, without fee, and encourage the use of this source code
49   *  as a component for supporting the Hypertext Markup Language in
50   *  commercial products. If you use this source code in a product,
51   *  acknowledgment is not required but would be appreciated.
52   *
53   */
54  package org.w3c.tidy;
55  
56  import org.w3c.dom.Attr;
57  
58  
59  /**
60   * Attribute/Value linked list node.
61   * @author Dave Raggett <a href="mailto:dsr@w3.org">dsr@w3.org </a>
62   * @author Andy Quick <a href="mailto:ac.quick@sympatico.ca">ac.quick@sympatico.ca </a> (translation to Java)
63   * @author Fabrizio Giustina
64   * @version $Revision: 779 $ ($Author: fgiust $)
65   */
66  public class AttVal extends Object implements Cloneable
67  {
68  
69      /**
70       * next AttVal.
71       */
72      protected AttVal next;
73  
74      /**
75       * Attribute definition.
76       */
77      protected Attribute dict;
78  
79      /**
80       * Asp node.
81       */
82      protected Node asp;
83  
84      /**
85       * Php node.
86       */
87      protected Node php;
88  
89      /**
90       * Delimiter (" or ').
91       */
92      protected int delim;
93  
94      /**
95       * Attribute name.
96       */
97      protected String attribute;
98  
99      /**
100      * Attribute value.
101      */
102     protected String value;
103 
104     /**
105      * DOM adapter.
106      */
107     protected Attr adapter;
108 
109     /**
110      * Instantiates a new empty AttVal.
111      */
112     public AttVal()
113     {
114         super();
115     }
116 
117     /**
118      * Instantiates a new AttVal.
119      * @param next next linked AttVal
120      * @param dict Attribute from dictionary
121      * @param delim delimitator for attribute value
122      * @param attribute attribute name
123      * @param value attribute value
124      */
125     public AttVal(AttVal next, Attribute dict, int delim, String attribute, String value)
126     {
127         this.next = next;
128         this.dict = dict;
129         this.delim = delim;
130         this.attribute = attribute;
131         this.value = value;
132     }
133 
134     /**
135      * Instantiates a new AttVal.
136      * @param next next linked AttVal
137      * @param dict Attribute from dictionary
138      * @param asp contained asp node
139      * @param php contained php node
140      * @param delim delimitator for attribute value
141      * @param attribute attribute name
142      * @param value attribute value
143      */
144     public AttVal(AttVal next, Attribute dict, Node asp, Node php, int delim, String attribute, String value)
145     {
146         this.next = next;
147         this.dict = dict;
148         this.asp = asp;
149         this.php = php;
150         this.delim = delim;
151         this.attribute = attribute;
152         this.value = value;
153     }
154 
155     /**
156      * @see java.lang.Object#clone()
157      */
158     protected Object clone()
159     {
160         AttVal av = null;
161         try
162         {
163             av = (AttVal) super.clone();
164         }
165         catch (CloneNotSupportedException e)
166         {
167             // should never happen
168         }
169 
170         if (this.next != null)
171         {
172             av.next = (AttVal) this.next.clone();
173         }
174         if (this.asp != null)
175         {
176             av.asp = (Node) this.asp.clone();
177         }
178         if (this.php != null)
179         {
180             av.php = (Node) this.php.clone();
181         }
182 
183         return av;
184     }
185 
186     /**
187      * Is this a boolean attribute.
188      * @return <code>true</code> if this is a boolean attribute
189      */
190     public boolean isBoolAttribute()
191     {
192         Attribute attr = this.dict;
193         if (attr != null)
194         {
195             if (attr.getAttrchk() == AttrCheckImpl.BOOL)
196             {
197                 return true;
198             }
199         }
200 
201         return false;
202     }
203 
204     /**
205      * Check the attribute value for uppercase letters (only if the value should be lowercase, required for literal
206      * values in xhtml).
207      * @param lexer Lexer
208      * @param node Node which contains this attribute
209      */
210     void checkLowerCaseAttrValue(Lexer lexer, Node node)
211     {
212         if (this.value == null)
213         {
214             return;
215         }
216 
217         String lowercase = this.value.toLowerCase();
218 
219         if (!this.value.equals(lowercase))
220         {
221             if (lexer.isvoyager)
222             {
223                 lexer.report.attrError(lexer, node, this, Report.ATTR_VALUE_NOT_LCASE);
224             }
225 
226             if (lexer.isvoyager || lexer.configuration.lowerLiterals)
227             {
228                 this.value = lowercase;
229             }
230         }
231     }
232 
233     /**
234      * Check attribute name/value and report errors.
235      * @param lexer Lexer
236      * @param node node which contains this attribute
237      * @return Attribute
238      */
239     public Attribute checkAttribute(Lexer lexer, Node node)
240     {
241         TagTable tt = lexer.configuration.tt;
242 
243         Attribute attr = this.dict;
244 
245         // ignore unknown attributes for proprietary elements
246         if (attr != null)
247         {
248 
249             // if attribute looks like <foo/> check XML is ok
250             if (TidyUtils.toBoolean(attr.getVersions() & Dict.VERS_XML))
251             {
252                 if (!(lexer.configuration.xmlTags || lexer.configuration.xmlOut))
253                 {
254                     lexer.report.attrError(lexer, node, this, Report.XML_ATTRIBUTE_VALUE);
255                 }
256             }
257             // title first appeared in HTML 4.0 except for a/link
258             else if (attr != AttributeTable.attrTitle || !(node.tag == tt.tagA || node.tag == tt.tagLink))
259             {
260                 lexer.constrainVersion(attr.getVersions());
261             }
262 
263             if (attr.getAttrchk() != null)
264             {
265                 attr.getAttrchk().check(lexer, node, this);
266             }
267             else if (TidyUtils.toBoolean(this.dict.getVersions() & Dict.VERS_PROPRIETARY))
268             {
269                 lexer.report.attrError(lexer, node, this, Report.PROPRIETARY_ATTRIBUTE);
270             }
271 
272         }
273         else if (!lexer.configuration.xmlTags
274             && !(node.tag == null)
275             && this.asp == null
276             && !(node.tag != null && (TidyUtils.toBoolean(node.tag.versions & Dict.VERS_PROPRIETARY))))
277         {
278             lexer.report.attrError(lexer, node, this, Report.UNKNOWN_ATTRIBUTE);
279         }
280 
281         return attr;
282     }
283 
284     /**
285      * Return the org.w3c.dom.Attr adapter.
286      * @return org.w3c.dom.Attr adapter
287      */
288     protected org.w3c.dom.Attr getAdapter()
289     {
290         if (this.adapter == null)
291         {
292             this.adapter = new DOMAttrImpl(this);
293         }
294         return this.adapter;
295     }
296 
297     /**
298      * Getter for <code>asp</code>.
299      * @return Returns the asp.
300      */
301     public Node getAsp()
302     {
303         return this.asp;
304     }
305 
306     /**
307      * Setter for <code>asp</code>.
308      * @param asp The asp to set.
309      */
310     public void setAsp(Node asp)
311     {
312         this.asp = asp;
313     }
314 
315     /**
316      * Getter for <code>attribute</code>.
317      * @return Returns the attribute.
318      */
319     public String getAttribute()
320     {
321         return this.attribute;
322     }
323 
324     /**
325      * Setter for <code>attribute</code>.
326      * @param attribute The attribute to set.
327      */
328     public void setAttribute(String attribute)
329     {
330         this.attribute = attribute;
331     }
332 
333     /**
334      * Getter for <code>delim</code>.
335      * @return Returns the delim.
336      */
337     public int getDelim()
338     {
339         return this.delim;
340     }
341 
342     /**
343      * Setter for <code>delim</code>.
344      * @param delim The delim to set.
345      */
346     public void setDelim(int delim)
347     {
348         this.delim = delim;
349     }
350 
351     /**
352      * Getter for <code>dict</code>.
353      * @return Returns the dict.
354      */
355     public Attribute getDict()
356     {
357         return this.dict;
358     }
359 
360     /**
361      * Setter for <code>dict</code>.
362      * @param dict The dict to set.
363      */
364     public void setDict(Attribute dict)
365     {
366         this.dict = dict;
367     }
368 
369     /**
370      * Getter for <code>next</code>.
371      * @return Returns the next.
372      */
373     public AttVal getNext()
374     {
375         return this.next;
376     }
377 
378     /**
379      * Setter for <code>next</code>.
380      * @param next The next to set.
381      */
382     public void setNext(AttVal next)
383     {
384         this.next = next;
385     }
386 
387     /**
388      * Getter for <code>php</code>.
389      * @return Returns the php.
390      */
391     public Node getPhp()
392     {
393         return this.php;
394     }
395 
396     /**
397      * Setter for <code>php</code>.
398      * @param php The php to set.
399      */
400     public void setPhp(Node php)
401     {
402         this.php = php;
403     }
404 
405     /**
406      * Getter for <code>value</code>.
407      * @return Returns the value.
408      */
409     public String getValue()
410     {
411         return this.value;
412     }
413 
414     /**
415      * Setter for <code>value</code>.
416      * @param value The value to set.
417      */
418     public void setValue(String value)
419     {
420         this.value = value;
421     }
422 
423 }