1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
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
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
246 if (attr != null)
247 {
248
249
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
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 }