KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > htmlparser > nodes > TagNode


1 // HTMLParser Library $Name: v1_5_20050313 $ - A java-based parser for HTML
2
// http://sourceforge.org/projects/htmlparser
3
// Copyright (C) 2004 Derrick Oswald
4
//
5
// Revision Control Information
6
//
7
// $Source: /cvsroot/htmlparser/htmlparser/src/org/htmlparser/nodes/TagNode.java,v $
8
// $Author: derrickoswald $
9
// $Date: 2004/07/31 16:42:35 $
10
// $Revision: 1.5 $
11
//
12
// This library is free software; you can redistribute it and/or
13
// modify it under the terms of the GNU Lesser General Public
14
// License as published by the Free Software Foundation; either
15
// version 2.1 of the License, or (at your option) any later version.
16
//
17
// This library is distributed in the hope that it will be useful,
18
// but WITHOUT ANY WARRANTY; without even the implied warranty of
19
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20
// Lesser General Public License for more details.
21
//
22
// You should have received a copy of the GNU Lesser General Public
23
// License along with this library; if not, write to the Free Software
24
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
//
26

27 package org.htmlparser.nodes;
28
29 import java.util.Enumeration JavaDoc;
30 import java.util.Hashtable JavaDoc;
31 import java.util.Locale JavaDoc;
32 import java.util.Vector JavaDoc;
33
34 import org.htmlparser.Attribute;
35 import org.htmlparser.Tag;
36 import org.htmlparser.lexer.Cursor;
37 import org.htmlparser.lexer.Lexer;
38 import org.htmlparser.lexer.Page;
39 import org.htmlparser.scanners.Scanner;
40 import org.htmlparser.scanners.TagScanner;
41 import org.htmlparser.util.ParserException;
42 import org.htmlparser.util.SpecialHashtable;
43 import org.htmlparser.visitors.NodeVisitor;
44
45 /**
46  * TagNode represents a generic tag.
47  * If no scanner is registered for a given tag name, this is what you get.
48  * This is also the base class for all tags created by the parser.
49  */

50 public class TagNode
51     extends
52         AbstractNode
53     implements
54         Tag
55 {
56     /**
57      * An empty set of tag names.
58      */

59     private final static String JavaDoc[] NONE = new String JavaDoc[0];
60     
61     /**
62      * The scanner for this tag.
63      */

64     private Scanner mScanner;
65     
66     /**
67      * The default scanner for non-composite tags.
68      */

69     protected final static Scanner mDefaultScanner = new TagScanner ();
70
71     /**
72      * The tag attributes.
73      * Objects of type {@link Attribute}.
74      * The first element is the tag name, subsequent elements being either
75      * whitespace or real attributes.
76      */

77     protected Vector JavaDoc mAttributes;
78
79     /**
80      * Set of tags that breaks the flow.
81      */

82     protected static Hashtable JavaDoc breakTags;
83     static
84     {
85         breakTags = new Hashtable JavaDoc (30);
86         breakTags.put ("BLOCKQUOTE", Boolean.TRUE);
87         breakTags.put ("BODY", Boolean.TRUE);
88         breakTags.put ("BR", Boolean.TRUE);
89         breakTags.put ("CENTER", Boolean.TRUE);
90         breakTags.put ("DD", Boolean.TRUE);
91         breakTags.put ("DIR", Boolean.TRUE);
92         breakTags.put ("DIV", Boolean.TRUE);
93         breakTags.put ("DL", Boolean.TRUE);
94         breakTags.put ("DT", Boolean.TRUE);
95         breakTags.put ("FORM", Boolean.TRUE);
96         breakTags.put ("H1", Boolean.TRUE);
97         breakTags.put ("H2", Boolean.TRUE);
98         breakTags.put ("H3", Boolean.TRUE);
99         breakTags.put ("H4", Boolean.TRUE);
100         breakTags.put ("H5", Boolean.TRUE);
101         breakTags.put ("H6", Boolean.TRUE);
102         breakTags.put ("HEAD", Boolean.TRUE);
103         breakTags.put ("HR", Boolean.TRUE);
104         breakTags.put ("HTML", Boolean.TRUE);
105         breakTags.put ("ISINDEX", Boolean.TRUE);
106         breakTags.put ("LI", Boolean.TRUE);
107         breakTags.put ("MENU", Boolean.TRUE);
108         breakTags.put ("NOFRAMES", Boolean.TRUE);
109         breakTags.put ("OL", Boolean.TRUE);
110         breakTags.put ("P", Boolean.TRUE);
111         breakTags.put ("PRE", Boolean.TRUE);
112         breakTags.put ("TD", Boolean.TRUE);
113         breakTags.put ("TH", Boolean.TRUE);
114         breakTags.put ("TITLE", Boolean.TRUE);
115         breakTags.put ("UL", Boolean.TRUE);
116     }
117
118     /**
119      * Create an empty tag.
120      */

121     public TagNode ()
122     {
123         this (null, -1, -1, new Vector JavaDoc ());
124     }
125
126     /**
127      * Create a tag with the location and attributes provided
128      * @param page The page this tag was read from.
129      * @param start The starting offset of this node within the page.
130      * @param end The ending offset of this node within the page.
131      * @param attributes The list of attributes that were parsed in this tag.
132      * @see Attribute
133      */

134     public TagNode (Page page, int start, int end, Vector JavaDoc attributes)
135     {
136         super (page, start, end);
137
138         mScanner = mDefaultScanner;
139         mAttributes = attributes;
140         if ((null == mAttributes) || (0 == mAttributes.size ()))
141         {
142             String JavaDoc[] names;
143
144             names = getIds ();
145             if ((null != names) && (0 != names.length))
146                 setTagName (names[0]);
147             else
148                 setTagName (""); // make sure it's not null
149
}
150     }
151
152     /**
153      * Create a tag like the one provided.
154      * @param tag The tag to emulate.
155      * @param scanner The scanner for this tag.
156      */

157     public TagNode (TagNode tag, TagScanner scanner)
158     {
159         this (tag.getPage (), tag.getTagBegin (), tag.getTagEnd (), tag.getAttributesEx ());
160         setThisScanner (scanner);
161     }
162
163     /**
164      * Returns the value of an attribute.
165      * @param name Name of attribute, case insensitive.
166      * @return The value associated with the attribute or null if it does
167      * not exist, or is a stand-alone or
168      */

169     public String JavaDoc getAttribute (String JavaDoc name)
170     {
171         Attribute attribute;
172         String JavaDoc ret;
173
174         ret = null;
175
176         if (name.equalsIgnoreCase (SpecialHashtable.TAGNAME))
177             ret = ((Attribute)getAttributesEx ().elementAt (0)).getName ();
178         else
179         {
180             attribute = getAttributeEx (name);
181             if (null != attribute)
182                 ret = attribute.getValue ();
183         }
184
185         return (ret);
186     }
187
188     /**
189      * Set attribute with given key, value pair.
190      * Figures out a quote character to use if necessary.
191      * @param key The name of the attribute.
192      * @param value The value of the attribute.
193      */

194     public void setAttribute (String JavaDoc key, String JavaDoc value)
195     {
196         char ch;
197         boolean needed;
198         boolean singleq;
199         boolean doubleq;
200         String JavaDoc ref;
201         StringBuffer JavaDoc buffer;
202         char quote;
203         Attribute attribute;
204
205         // first determine if there's whitespace in the value
206
// and while we'return at it find a suitable quote character
207
needed = false;
208         singleq = true;
209         doubleq = true;
210         if (null != value)
211             for (int i = 0; i < value.length (); i++)
212             {
213                 ch = value.charAt (i);
214                 if (Character.isWhitespace (ch))
215                     needed = true;
216                 else if ('\'' == ch)
217                     singleq = false;
218                 else if ('"' == ch)
219                     doubleq = false;
220             }
221
222         // now apply quoting
223
if (needed)
224         {
225             if (doubleq)
226                 quote = '"';
227             else if (singleq)
228                 quote = '\'';
229             else
230             {
231                 // uh-oh, we need to convert some quotes into character references
232
// convert all double quotes into &#34;
233
quote = '"';
234                 ref = "&quot;"; // Translate.encode (quote);
235
// JDK 1.4: value = value.replaceAll ("\"", ref);
236
buffer = new StringBuffer JavaDoc (value.length() * 5);
237                 for (int i = 0; i < value.length (); i++)
238                 {
239                     ch = value.charAt (i);
240                     if (quote == ch)
241                         buffer.append (ref);
242                     else
243                         buffer.append (ch);
244                 }
245                 value = buffer.toString ();
246             }
247         }
248         else
249             quote = 0;
250         attribute = getAttributeEx (key);
251         if (null != attribute)
252         { // see if we can splice it in rather than replace it
253
attribute.setValue (value);
254             if (0 != quote)
255                 attribute.setQuote (quote);
256         }
257         else
258             setAttribute (key, value, quote);
259     }
260
261     /**
262      * Remove the attribute with the given key, if it exists.
263      * @param key The name of the attribute.
264      */

265     public void removeAttribute (String JavaDoc key)
266     {
267         Attribute attribute;
268
269         attribute = getAttributeEx (key);
270         if (null != attribute)
271             getAttributesEx ().remove (attribute);
272     }
273
274     /**
275      * Set attribute with given key, value pair where the value is quoted by quote.
276      * @param key The name of the attribute.
277      * @param value The value of the attribute.
278      * @param quote The quote character to be used around value.
279      * If zero, it is an unquoted value.
280      */

281     public void setAttribute (String JavaDoc key, String JavaDoc value, char quote)
282     {
283         setAttribute (new Attribute (key, value, quote));
284     }
285
286     /**
287      * Returns the attribute with the given name.
288      * @param name Name of attribute, case insensitive.
289      * @return The attribute or null if it does
290      * not exist.
291      */

292     public Attribute getAttributeEx (String JavaDoc name)
293     {
294         Vector JavaDoc attributes;
295         int size;
296         Attribute attribute;
297         String JavaDoc string;
298         Attribute ret;
299
300         ret = null;
301
302         attributes = getAttributesEx ();
303         if (null != attributes)
304         {
305             size = attributes.size ();
306             for (int i = 0; i < size; i++)
307             {
308                 attribute = (Attribute)attributes.elementAt (i);
309                 string = attribute.getName ();
310                 if ((null != string) && name.equalsIgnoreCase (string))
311                 {
312                     ret = attribute;
313                     i = size; // exit fast
314
}
315             }
316         }
317
318         return (ret);
319     }
320
321     /*
322      * Sets the attributes.
323      * @param attribs The attribute collection to set.
324      * Each element is an {@link Attribute Attribute}.
325      * The first attribute in the list must be the tag name (
326      * <code>isStandalone()</code> returns <code>true</code>).
327      */

328     public void setAttributeEx (Attribute attribute)
329     {
330         setAttribute (attribute);
331     }
332
333     /**
334      * Set an attribute.
335      * This replaces an attribute of the same name.
336      * To set the zeroth attribute (the tag name), use setTagName().
337      * @param attribute The attribute to set.
338      */

339     public void setAttribute (Attribute attribute)
340     {
341         boolean replaced;
342         Vector JavaDoc attributes;
343         int length;
344         String JavaDoc name;
345         Attribute test;
346         String JavaDoc test_name;
347
348         replaced = false;
349         attributes = getAttributesEx ();
350         length = attributes.size ();
351         if (0 < length)
352         {
353             name = attribute.getName ();
354             for (int i = 1; i < attributes.size (); i++)
355             {
356                 test = (Attribute)attributes.elementAt (i);
357                 test_name = test.getName ();
358                 if (null != test_name)
359                     if (test_name.equalsIgnoreCase (name))
360                     {
361                         attributes.setElementAt (attribute, i);
362                         replaced = true;
363                     }
364             }
365         }
366         if (!replaced)
367         {
368             // add whitespace between attributes
369
if ((0 != length) && !((Attribute)attributes.elementAt (length - 1)).isWhitespace ())
370                 attributes.addElement (new Attribute (" "));
371             attributes.addElement (attribute);
372         }
373     }
374
375     /**
376      * Eqivalent to <code>getAttribute (name)</code>.
377      * @param name Name of attribute.
378      * @deprecated use getAttribute instead
379      */

380     public String JavaDoc getParameter (String JavaDoc name)
381     {
382         return (getAttribute (name));
383     }
384
385     /**
386      * Gets the attributes in the tag.
387      * @return Returns the list of {@link Attribute Attributes} in the tag.
388      * The first element is the tag name, subsequent elements being either
389      * whitespace or real attributes.
390      */

391     public Vector JavaDoc getAttributesEx ()
392     {
393         return (mAttributes);
394     }
395
396     /**
397      * Gets the attributes in the tag.
398      * This is not the preferred method to get attributes, see {@link
399      * #getAttributesEx getAttributesEx} which returns a list of {@link
400      * Attribute} objects, which offer more information than the simple
401      * <code>String</code> objects available from this <code>Hashtable</code>.
402      * @return Returns a list of name/value pairs representing the attributes.
403      * These are not in order, the keys (names) are converted to uppercase and the values
404      * are not quoted, even if they need to be. The table <em>will</em> return
405      * <code>null</code> if there was no value for an attribute (no equals
406      * sign or nothing to the right of the equals sign). A special entry with
407      * a key of SpecialHashtable.TAGNAME ("$<TAGNAME>$") holds the tag name.
408      * The conversion to uppercase is performed with an ENGLISH locale.
409      */

410     public Hashtable JavaDoc getAttributes ()
411     {
412         Vector JavaDoc attributes;
413         Attribute attribute;
414         String JavaDoc value;
415         Hashtable JavaDoc ret;
416
417         ret = new SpecialHashtable ();
418         attributes = getAttributesEx ();
419         if (0 < attributes.size ())
420         {
421             // special handling for the node name
422
attribute = (Attribute)attributes.elementAt (0);
423             ret.put (SpecialHashtable.TAGNAME, attribute.getName ().toUpperCase (Locale.ENGLISH));
424             // the rest
425
for (int i = 1; i < attributes.size (); i++)
426             {
427                 attribute = (Attribute)attributes.elementAt (i);
428                 if (!attribute.isWhitespace ())
429                 {
430                     value = attribute.getValue ();
431                     if (attribute.isEmpty ())
432                         value = SpecialHashtable.NOTHING;
433                     if (null == value)
434                         value = SpecialHashtable.NULLVALUE;
435                     ret.put (attribute.getName ().toUpperCase (Locale.ENGLISH), value);
436                 }
437             }
438         }
439         else
440             ret.put (SpecialHashtable.TAGNAME, "");
441
442         return (ret);
443     }
444
445     /**
446      * Return the name of this tag.
447      * <p>
448      * <em>
449      * Note: This value is converted to uppercase and does not
450      * begin with "/" if it is an end tag. Nor does it end with
451      * a slash in the case of an XML type tag.
452      * To get at the original text of the tag name use
453      * {@link #getRawTagName getRawTagName()}.
454      * The conversion to uppercase is performed with an ENGLISH locale.
455      * </em>
456      * @return The tag name.
457      */

458     public String JavaDoc getTagName ()
459     {
460         String JavaDoc ret;
461
462         ret = getRawTagName ();
463         if (null != ret)
464         {
465             ret = ret.toUpperCase (Locale.ENGLISH);
466             if (ret.startsWith ("/"))
467                 ret = ret.substring (1);
468             if (ret.endsWith ("/"))
469                 ret = ret.substring (0, ret.length () - 1);
470         }
471
472         return (ret);
473     }
474
475     /**
476      * Return the name of this tag.
477      * @return The tag name or null if this tag contains nothing or only
478      * whitespace.
479      */

480     public String JavaDoc getRawTagName ()
481     {
482         Vector JavaDoc attributes;
483         String JavaDoc ret;
484
485         ret = null;
486         
487         attributes = getAttributesEx ();
488         if (0 != attributes.size ())
489             ret = ((Attribute)attributes.elementAt (0)).getName ();
490
491         return (ret);
492     }
493
494     /**
495      * Set the name of this tag.
496      * This creates or replaces the first attribute of the tag (the
497      * zeroth element of the attribute vector).
498      * @param name The tag name.
499      */

500     public void setTagName (String JavaDoc name)
501     {
502         Attribute attribute;
503         Vector JavaDoc attributes;
504         Attribute zeroth;
505
506         attribute = new Attribute (name, null, (char)0);
507         attributes = getAttributesEx ();
508         if (null == attributes)
509         {
510             attributes = new Vector JavaDoc ();
511             setAttributesEx (attributes);
512         }
513         if (0 == attributes.size ())
514             // nothing added yet
515
attributes.addElement (attribute);
516         else
517         {
518             zeroth = (Attribute)attributes.elementAt (0);
519             // check for attribute that looks like a name
520
if ((null == zeroth.getValue ()) && (0 == zeroth.getQuote ()))
521                 attributes.setElementAt (attribute, 0);
522             else
523                 attributes.insertElementAt (attribute, 0);
524         }
525     }
526
527     /**
528      * Return the text contained in this tag.
529      * @return The complete contents of the tag (within the angle brackets).
530      */

531     public String JavaDoc getText ()
532     {
533         String JavaDoc ret;
534         
535         //ret = mPage.getText (elementBegin () + 1, elementEnd () - 1);
536
ret = toHtml ();
537         ret = ret.substring (1, ret.length () - 1);
538         
539         return (ret);
540     }
541
542     /**
543      * Sets the attributes.
544      * A special entry with a key of SpecialHashtable.TAGNAME ("$<TAGNAME>$")
545      * sets the tag name.
546      * @param attributes The attribute collection to set.
547      */

548     public void setAttributes (Hashtable JavaDoc attributes)
549     {
550         Vector JavaDoc att;
551         String JavaDoc key;
552         String JavaDoc value;
553         char quote;
554         Attribute attribute;
555
556         att = new Vector JavaDoc ();
557         for (Enumeration JavaDoc e = attributes.keys (); e.hasMoreElements (); )
558         {
559             key = (String JavaDoc)e.nextElement ();
560             value = (String JavaDoc)attributes.get (key);
561             if (value.startsWith ("'") && value.endsWith ("'") && (2 <= value.length ()))
562             {
563                 quote = '\'';
564                 value = value.substring (1, value.length () - 1);
565             }
566             else if (value.startsWith ("\"") && value.endsWith ("\"") && (2 <= value.length ()))
567             {
568                 quote = '"';
569                 value = value.substring (1, value.length () - 1);
570             }
571             else
572                 quote = (char)0;
573             if (key.equals (SpecialHashtable.TAGNAME))
574             {
575                 attribute = new Attribute (value, null, quote);
576                 att.insertElementAt (attribute, 0);
577             }
578             else
579             {
580                 // add whitespace between attributes
581
attribute = new Attribute (" ");
582                 att.addElement (attribute);
583                 attribute = new Attribute (key, value, quote);
584                 att.addElement (attribute);
585             }
586         }
587         this.mAttributes = att;
588     }
589
590     /**
591      * Sets the attributes.
592      * NOTE: Values of the extended hashtable are two element arrays of String,
593      * with the first element being the original name (not uppercased),
594      * and the second element being the value.
595      * @param attribs The attribute collection to set.
596      */

597     public void setAttributesEx (Vector JavaDoc attribs)
598     {
599         mAttributes = attribs;
600     }
601
602     /**
603      * Sets the nodeBegin.
604      * @param tagBegin The nodeBegin to set
605      */

606     public void setTagBegin (int tagBegin)
607     {
608         nodeBegin = tagBegin;
609     }
610
611     /**
612      * Gets the nodeBegin.
613      * @return The nodeBegin value.
614      */

615     public int getTagBegin ()
616     {
617         return (nodeBegin);
618     }
619
620     /**
621      * Sets the nodeEnd.
622      * @param tagEnd The nodeEnd to set
623      */

624     public void setTagEnd (int tagEnd)
625     {
626         nodeEnd = tagEnd;
627     }
628
629     /**
630      * Gets the nodeEnd.
631      * @return The nodeEnd value.
632      */

633     public int getTagEnd ()
634     {
635         return (nodeEnd);
636     }
637
638     /**
639      * Parses the given text to create the tag contents.
640      * @param text A string of the form &lt;TAGNAME xx="yy"&gt;.
641      */

642     public void setText (String JavaDoc text)
643     {
644         Lexer lexer;
645         TagNode output;
646         
647         lexer = new Lexer (text);
648         try
649         {
650             output = (TagNode)lexer.nextNode ();
651             mPage = output.getPage ();
652             nodeBegin = output.getStartPosition ();
653             nodeEnd = output.getEndPosition ();
654             mAttributes = output.getAttributesEx ();
655         }
656         catch (ParserException pe)
657         {
658             throw new IllegalArgumentException JavaDoc (pe.getMessage ());
659         }
660     }
661
662     /**
663      * Get the plain text from this node.
664      * @return An empty string (tag contents do not display in a browser).
665      * If you want this tags HTML equivalent, use {@link #toHtml toHtml()}.
666      */

667     public String JavaDoc toPlainTextString ()
668     {
669         return ("");
670     }
671
672     /**
673      * Render the tag as HTML.
674      * A call to a tag's <code>toHtml()</code> method will render it in HTML.
675      * @return The tag as an HTML fragment.
676      * @see org.htmlparser.Node#toHtml()
677      */

678     public String JavaDoc toHtml ()
679     {
680         int length;
681         int size;
682         Vector JavaDoc attributes;
683         Attribute attribute;
684         StringBuffer JavaDoc ret;
685
686         length = 2;
687         attributes = getAttributesEx ();
688         size = attributes.size ();
689         for (int i = 0; i < size; i++)
690         {
691             attribute = (Attribute)attributes.elementAt (i);
692             length += attribute.getLength ();
693         }
694         ret = new StringBuffer JavaDoc (length);
695         ret.append ("<");
696         for (int i = 0; i < size; i++)
697         {
698             attribute = (Attribute)attributes.elementAt (i);
699             attribute.toString (ret);
700         }
701         ret.append (">");
702
703         return (ret.toString ());
704     }
705
706     /**
707      * Print the contents of the tag.
708      * @return An string describing the tag. For text that looks like HTML use #toHtml().
709      */

710     public String JavaDoc toString ()
711     {
712         String JavaDoc text;
713         String JavaDoc type;
714         Cursor start;
715         Cursor end;
716         StringBuffer JavaDoc ret;
717
718         text = getText ();
719         ret = new StringBuffer JavaDoc (20 + text.length ());
720         if (isEndTag ())
721             type = "End";
722         else
723             type = "Tag";
724         start = new Cursor (getPage (), getStartPosition ());
725         end = new Cursor (getPage (), getEndPosition ());
726         ret.append (type);
727         ret.append (" (");
728         ret.append (start);
729         ret.append (",");
730         ret.append (end);
731         ret.append ("): ");
732         if (80 < ret.length () + text.length ())
733         {
734             text = text.substring (0, 77 - ret.length ());
735             ret.append (text);
736             ret.append ("...");
737         }
738         else
739             ret.append (text);
740         
741         return (ret.toString ());
742     }
743
744     /**
745      * Determines if the given tag breaks the flow of text.
746      * @return <code>true</code> if following text would start on a new line,
747      * <code>false</code> otherwise.
748      */

749     public boolean breaksFlow ()
750     {
751         return (breakTags.containsKey (getTagName ()));
752     }
753
754     /**
755      * Returns table of attributes in the tag
756      * @return Hashtable
757      * @deprecated This method is deprecated. Use getAttributes() instead.
758      */

759     public Hashtable JavaDoc getParsed ()
760     {
761         return getAttributes ();
762     }
763
764     /**
765      * Default tag visiting code.
766      * Based on <code>isEndTag()</code>, calls either <code>visitTag()</code> or
767      * <code>visitEndTag()</code>.
768      */

769     public void accept (NodeVisitor visitor)
770     {
771         if (isEndTag ())
772             visitor.visitEndTag (this);
773         else
774             visitor.visitTag (this);
775     }
776
777     /**
778      * Is this an empty xml tag of the form &lt;tag/&gt;.
779      * @return true if the last character of the last attribute is a '/'.
780      */

781     public boolean isEmptyXmlTag ()
782     {
783         Vector JavaDoc attributes;
784         int size;
785         Attribute attribute;
786         String JavaDoc name;
787         int length;
788         boolean ret;
789
790         ret = false;
791
792         attributes = getAttributesEx ();
793         size = attributes.size ();
794         if (0 < size)
795         {
796             attribute = (Attribute)attributes.elementAt (size - 1);
797             name = attribute.getName ();
798             if (null != name)
799             {
800                 length = name.length ();
801                 ret = name.charAt (length - 1) == '/';
802             }
803         }
804
805         return (ret);
806     }
807
808     /**
809      * Set this tag to be an empty xml node, or not.
810      * Adds or removes an ending slash on the tag.
811      * @param emptyXmlTag If true, ensures there is an ending slash in the node,
812      * i.e. &lt;tag/&gt;, otherwise removes it.
813      */

814     public void setEmptyXmlTag (boolean emptyXmlTag)
815     {
816         Vector JavaDoc attributes;
817         int size;
818         Attribute attribute;
819         String JavaDoc name;
820         String JavaDoc value;
821         int length;
822         
823         attributes = getAttributesEx ();
824         size = attributes.size ();
825         if (0 < size)
826         {
827             attribute = (Attribute)attributes.elementAt (size - 1);
828             name = attribute.getName ();
829             if (null != name)
830             {
831                 length = name.length ();
832                 value = attribute.getValue ();
833                 if (null == value)
834                     if (name.charAt (length - 1) == '/')
835                     {
836                         // already exists, remove if requested
837
if (!emptyXmlTag)
838                             if (1 == length)
839                                 attributes.removeElementAt (size - 1);
840                             else
841                             {
842                                 // this shouldn't happen, but covers the case
843
// where no whitespace separates the slash
844
// from the previous attribute
845
name = name.substring (0, length - 1);
846                                 attribute = new Attribute (name, null);
847                                 attributes.removeElementAt (size - 1);
848                                 attributes.addElement (attribute);
849                             }
850                     }
851                     else
852                     {
853                         // ends with attribute, add whitespace + slash if requested
854
if (emptyXmlTag)
855                         {
856                             attribute = new Attribute (" ");
857                             attributes.addElement (attribute);
858                             attribute = new Attribute ("/", null);
859                             attributes.addElement (attribute);
860                         }
861                     }
862                 else
863                 {
864                     // some valued attribute, add whitespace + slash if requested
865
if (emptyXmlTag)
866                     {
867                         attribute = new Attribute (" ");
868                         attributes.addElement (attribute);
869                         attribute = new Attribute ("/", null);
870                         attributes.addElement (attribute);
871                     }
872                 }
873             }
874             else
875             {
876                 // ends with whitespace, add if requested
877
if (emptyXmlTag)
878                 {
879                     attribute = new Attribute ("/", null);
880                     attributes.addElement (attribute);
881                 }
882             }
883         }
884         else
885             // nothing there, add if requested
886
if (emptyXmlTag)
887             {
888                 attribute = new Attribute ("/", null);
889                 attributes.addElement (attribute);
890             }
891     }
892
893     /**
894      * Predicate to determine if this tag is an end tag (i.e. &lt;/HTML&gt;).
895      * @return <code>true</code> if this tag is an end tag.
896      */

897     public boolean isEndTag ()
898     {
899         String JavaDoc raw;
900         
901         raw = getRawTagName ();
902
903         return ((null == raw) ? false : ((0 != raw.length ()) && ('/' == raw.charAt (0))));
904     }
905
906     /**
907      * Get the line number where this tag starts.
908      * @return The (zero based) line number in the page where this tag starts.
909      */

910     public int getStartingLineNumber ()
911     {
912         return (getPage ().row (getStartPosition ()));
913     }
914
915     /**
916      * Get the line number where this tag ends.
917      * @return The (zero based) line number in the page where this tag ends.
918      */

919     public int getEndingLineNumber ()
920     {
921         return (getPage ().row (getEndPosition ()));
922     }
923
924     /**
925      * Return the set of names handled by this tag.
926      * Since this a a generic tag, it has no ids.
927      * @return The names to be matched that create tags of this type.
928      */

929     public String JavaDoc[] getIds ()
930     {
931         return (NONE);
932     }
933
934     /**
935      * Return the set of tag names that cause this tag to finish.
936      * These are the normal (non end tags) that if encountered while
937      * scanning (a composite tag) will cause the generation of a virtual
938      * tag.
939      * Since this a a non-composite tag, the default is no enders.
940      * @return The names of following tags that stop further scanning.
941      */

942     public String JavaDoc[] getEnders ()
943     {
944         return (NONE);
945     }
946
947     /**
948      * Return the set of end tag names that cause this tag to finish.
949      * These are the end tags that if encountered while
950      * scanning (a composite tag) will cause the generation of a virtual
951      * tag.
952      * Since this a a non-composite tag, it has no end tag enders.
953      * @return The names of following end tags that stop further scanning.
954      */

955     public String JavaDoc[] getEndTagEnders ()
956     {
957         return (NONE);
958     }
959
960     /**
961      * Return the scanner associated with this tag.
962      * @return The scanner associated with this tag.
963      */

964     public Scanner getThisScanner ()
965     {
966         return (mScanner);
967     }
968
969     /**
970      * Set the scanner associated with this tag.
971      * @param scanner The scanner for this tag.
972      */

973     public void setThisScanner (Scanner scanner)
974     {
975         mScanner = scanner;
976     }
977
978     /**
979      * Get the end tag for this (composite) tag.
980      * For a non-composite tag this always returns <code>null</code>.
981      * @return The tag that terminates this composite tag, i.e. &lt;/HTML&gt;.
982      */

983     public Tag getEndTag ()
984     {
985         return (null);
986     }
987
988     /**
989      * Set the end tag for this (composite) tag.
990      * For a non-composite tag this is a no-op.
991      * @param end The tag that terminates this composite tag, i.e. &lt;/HTML&gt;.
992      */

993     public void setEndTag (Tag end)
994     {
995     }
996 }
997
Popular Tags