KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > au > id > jericho > lib > html > StartTagType


1 // Jericho HTML Parser - Java based library for analysing and manipulating HTML
2
// Version 2.2
3
// Copyright (C) 2006 Martin Jericho
4
// http://sourceforge.net/projects/jerichohtml/
5
//
6
// This library is free software; you can redistribute it and/or
7
// modify it under the terms of the GNU Lesser General Public
8
// License as published by the Free Software Foundation; either
9
// version 2.1 of the License, or (at your option) any later version.
10
// http://www.gnu.org/copyleft/lesser.html
11
//
12
// This library is distributed in the hope that it will be useful,
13
// but WITHOUT ANY WARRANTY; without even the implied warranty of
14
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
// Lesser General Public License for more details.
16
//
17
// You should have received a copy of the GNU Lesser General Public
18
// License along with this library; if not, write to the Free Software
19
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20

21 package au.id.jericho.lib.html;
22
23 import java.util.*;
24
25 /**
26  * Defines the syntax for a start tag type.
27  * <p>
28  * A start tag type is any {@link TagType} that {@linkplain #getStartDelimiter() starts} with the character '<code>&lt;</code>'
29  * (as with all tag types), but whose second character is <b>not</b> '<code>/</code>'.
30  * <p>
31  * This includes types for many tags which stand alone, without a {@linkplain #getCorrespondingEndTagType() corresponding end tag},
32  * and would not intuitively be categorised as a "start tag". For example, an HTML {@linkplain #COMMENT comment} in a document
33  * is represented as a single start tag that spans the whole comment, and does not have an end tag at all.
34  * <p>
35  * Instances of all the <a HREF="TagType.html#Standard">standard</a> start tag types are available in this class as static
36  * <a HREF="#field_summary">fields</a>.
37  *
38  * @see EndTagType
39  */

40 public abstract class StartTagType extends TagType {
41     private final EndTagType correspondingEndTagType;
42     private final boolean hasAttributes;
43     private final boolean isNameAfterPrefixRequired;
44
45     static final String JavaDoc START_DELIMITER_PREFIX="<";
46
47     /**
48      * The tag type given to an {@linkplain Tag#isUnregistered() unregistered} {@linkplain StartTag start tag} (<code>&lt; </code>&#46;&#46;&#46;<code> &gt;</code>).
49      * <p>
50      * See the documentation of the {@link Tag#isUnregistered()} method for details.
51      * <p>
52      * <dl>
53      * <dt>Properties:</dt>
54      * <dd>
55      * <table class="bordered" style="margin: 15px" cellspacing="0">
56      * <tr><th>Property<th>Value
57      * <tr><td>{@link #getDescription() Description}<td>unregistered
58      * <tr><td>{@link #getStartDelimiter() StartDelimiter}<td><code>&lt;</code>
59      * <tr><td>{@link #getClosingDelimiter() ClosingDelimiter}<td><code>&gt;</code>
60      * <tr><td>{@link #isServerTag() IsServerTag}<td><code>false</code>
61      * <tr><td>{@link #getNamePrefix() NamePrefix}<td><i>(empty string)</i>
62      * <tr><td>{@link #getCorrespondingEndTagType() CorrespondingEndTagType}<td><code>null</code>
63      * <tr><td>{@link #hasAttributes() HasAttributes}<td><code>false</code>
64      * <tr><td>{@link #isNameAfterPrefixRequired() IsNameAfterPrefixRequired}<td><code>false</code>
65      * </table>
66      * <dt>Example:</dt>
67      * <dd><code>&lt;"This is not recognised as any of the predefined tag types in this library"&gt;</code></dd>
68      * </dl>
69      * @see EndTagType#UNREGISTERED
70      */

71     public static final StartTagType UNREGISTERED=StartTagTypeUnregistered.INSTANCE;
72
73     /**
74      * The tag type given to a normal HTML or XML {@linkplain StartTag start tag} (<code>&lt;</code><i>name</i><code> </code>&#46;&#46;&#46;<code> &gt;</code>).
75      * <p>
76      * <dl>
77      * <dt>Properties:</dt>
78      * <dd>
79      * <table class="bordered" style="margin: 15px" cellspacing="0">
80      * <tr><th>Property<th>Value
81      * <tr><td>{@link #getDescription() Description}<td>normal
82      * <tr><td>{@link #getStartDelimiter() StartDelimiter}<td><code>&lt;</code>
83      * <tr><td>{@link #getClosingDelimiter() ClosingDelimiter}<td><code>&gt;</code>
84      * <tr><td>{@link #isServerTag() IsServerTag}<td><code>false</code>
85      * <tr><td>{@link #getNamePrefix() NamePrefix}<td><i>(empty string)</i>
86      * <tr><td>{@link #getCorrespondingEndTagType() CorrespondingEndTagType}<td>{@link EndTagType#NORMAL}
87      * <tr><td>{@link #hasAttributes() HasAttributes}<td><code>true</code>
88      * <tr><td>{@link #isNameAfterPrefixRequired() IsNameAfterPrefixRequired}<td><code>true</code>
89      * </table>
90      * <dt>Example:</dt>
91      * <dd><code>&lt;div class="NormalDivTag"&gt;</code></dd>
92      * </dl>
93      */

94     public static final StartTagType NORMAL=StartTagTypeNormal.INSTANCE;
95
96     /**
97      * The tag type given to an HTML <a target="_blank" HREF="http://www.w3.org/TR/html401/intro/sgmltut.html#h-3.2.4">comment</a> (<code>&lt;&#33;-- </code>&#46;&#46;&#46;<code> --&gt;</code>).
98      * <p>
99      * An HTML comment is an area of the source document enclosed by the delimiters
100      * <code>&lt;!--</code> on the left and <code>--&gt;</code> on the right.
101      * <p>
102      * The <a target="_blank" HREF="http://www.w3.org/TR/html401/intro/sgmltut.html#h-3.2.4">HTML 4.01 specification section 3.2.4</a>
103      * states that the end of comment delimiter may contain white space between the "<code>--</code>" and "<code>&gt;</code>" characters,
104      * but this library does not recognise end of comment delimiters containing white space.
105      * <p>
106      * In the default configuration, any non-{@linkplain #isServerTag() server} tag appearing within an HTML comment is ignored
107      * by the parser.
108      * See the documentation of the <a HREF="Tag.html#ParsingProcess">tag parsing process</a> for more information.
109      * <p>
110      * <dl>
111      * <dt>Properties:</dt>
112      * <dd>
113      * <table class="bordered" style="margin: 15px" cellspacing="0">
114      * <tr><th>Property<th>Value
115      * <tr><td>{@link #getDescription() Description}<td>comment
116      * <tr><td>{@link #getStartDelimiter() StartDelimiter}<td><code>&lt;!--</code>
117      * <tr><td>{@link #getClosingDelimiter() ClosingDelimiter}<td><code>--&gt;</code>
118      * <tr><td>{@link #isServerTag() IsServerTag}<td><code>false</code>
119      * <tr><td>{@link #getNamePrefix() NamePrefix}<td><code>!--</code>
120      * <tr><td>{@link #getCorrespondingEndTagType() CorrespondingEndTagType}<td><code>null</code>
121      * <tr><td>{@link #hasAttributes() HasAttributes}<td><code>false</code>
122      * <tr><td>{@link #isNameAfterPrefixRequired() IsNameAfterPrefixRequired}<td><code>false</code>
123      * </table>
124      * <dt>Example:</dt>
125      * <dd><code>&lt;!-- This is a comment --&gt;</code></dd>
126      * </dl>
127      */

128     public static final StartTagType COMMENT=StartTagTypeComment.INSTANCE;
129
130     /**
131      * The tag type given to an <a target="_blank" HREF="http://www.w3.org/TR/REC-xml/#sec-prolog-dtd">XML declaration</a> (<code>&lt;&#63;xml </code>&#46;&#46;&#46;<code> &#63;&gt;</code>).
132      * <p>
133      * An XML declaration is often referred to in texts as a special type of processing instruction with the reserved
134      * <a target="_blank" HREF="http://www.w3.org/TR/REC-xml/#NT-PITarget">PITarget</a> name of "<code>xml</code>".
135      * Technically it is not an {@linkplain #XML_PROCESSING_INSTRUCTION XML processing instruction} at all, but is still a type of
136      * <a target="_blank" HREF="http://www.w3.org/TR/html401/appendix/notes.html#h-B.3.6">SGML processing instruction</a>.
137      * <p>
138      * According to section <a target="_blank" HREF="http://www.w3.org/TR/REC-xml/#sec-prolog-dtd">2.8</a> of the XML 1.0 specification,
139      * a valid XML declaration can specify only "version", "encoding" and "standalone" attributes in that order.
140      * This library parses the {@linkplain Attributes attributes} of an XML declaration in the same way as those of a
141      * {@linkplain #NORMAL normal} tag, without checking that they conform to the specification.
142      * <p>
143      * <dl>
144      * <dt>Properties:</dt>
145      * <dd>
146      * <table class="bordered" style="margin: 15px" cellspacing="0">
147      * <tr><th>Property<th>Value
148      * <tr><td>{@link #getDescription() Description}<td>XML declaration
149      * <tr><td>{@link #getStartDelimiter() StartDelimiter}<td><code>&lt;?xml</code>
150      * <tr><td>{@link #getClosingDelimiter() ClosingDelimiter}<td><code>?&gt;</code>
151      * <tr><td>{@link #isServerTag() IsServerTag}<td><code>false</code>
152      * <tr><td>{@link #getNamePrefix() NamePrefix}<td><code>?xml</code>
153      * <tr><td>{@link #getCorrespondingEndTagType() CorrespondingEndTagType}<td><code>null</code>
154      * <tr><td>{@link #hasAttributes() HasAttributes}<td><code>true</code>
155      * <tr><td>{@link #isNameAfterPrefixRequired() IsNameAfterPrefixRequired}<td><code>false</code>
156      * </table>
157      * <dt>Example:</dt>
158      * <dd><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;</code></dd>
159      * </dl>
160      */

161     public static final StartTagType XML_DECLARATION=StartTagTypeXMLDeclaration.INSTANCE;
162
163     /**
164      * The tag type given to an <a target="_blank" HREF="http://www.w3.org/TR/REC-xml#sec-pi">XML processing instruction</a> (<code>&lt;&#63;</code><i>PITarget</i> &#46;&#46;&#46; <code>&#63;&gt;</code>).
165      * <p>
166      * An XML processing instruction is a specific form of
167      * <a target="_blank" HREF="http://www.w3.org/TR/html401/appendix/notes.html#h-B.3.6">SGML processing instruction</a> with the following
168      * two additional constraints:
169      * <ul>
170      * <li>it must be {@linkplain #getClosingDelimiter() closed} with '<code>?&gt;</code>' instead of just a single
171      * '<code>&gt;</code>' character.
172      * <li>it requires a <a target="_blank" HREF="http://www.w3.org/TR/REC-xml/#NT-PITarget">PITarget</a>
173      * (essentially a {@linkplain Tag#getName() name} following the '<code>&lt;?</code>' {@linkplain #getStartDelimiter() start delimiter}).
174      * </ul>
175      * <p>
176      * This library does not include a <a HREF="TagType.html#Predefined">predefined</a> generic tag type for SGML processing instructions
177      * as the only forms in which they are found in HTML documents are the more specific XML processing instruction and
178      * the {@linkplain #XML_DECLARATION XML declaration}, both of which have their own dedicated predefined tag type.
179      * <p>
180      * There is no restriction on the contents of an XML processing instruction. In particular, it can not be assumed that the
181      * processing instruction contains {@linkplain Attributes attributes}, in contrast to the {@linkplain #XML_DECLARATION XML declaration}.
182      * <p>
183      * Note that {@linkplain #register() registering} the {@link PHPTagTypes#PHP_SHORT} tag type overrides this tag type.
184      * This is because they both have the same {@linkplain #getStartDelimiter start delimiter},
185      * so the one registered latest takes <a HREF="TagType.html#Precedence">precedence</a> over the other.
186      * See the documentation of the {@link PHPTagTypes} class for more information.
187      * <p>
188      * <dl>
189      * <dt>Properties:</dt>
190      * <dd>
191      * <table class="bordered" style="margin: 15px" cellspacing="0">
192      * <tr><th>Property<th>Value
193      * <tr><td>{@link #getDescription() Description}<td>XML processing instruction
194      * <tr><td>{@link #getStartDelimiter() StartDelimiter}<td><code>&lt;?</code>
195      * <tr><td>{@link #getClosingDelimiter() ClosingDelimiter}<td><code>?&gt;</code>
196      * <tr><td>{@link #isServerTag() IsServerTag}<td><code>false</code>
197      * <tr><td>{@link #getNamePrefix() NamePrefix}<td><code>?</code>
198      * <tr><td>{@link #getCorrespondingEndTagType() CorrespondingEndTagType}<td><code>null</code>
199      * <tr><td>{@link #hasAttributes() HasAttributes}<td><code>false</code>
200      * <tr><td>{@link #isNameAfterPrefixRequired() IsNameAfterPrefixRequired}<td><code>true</code>
201      * </table>
202      * <dt>Example:</dt>
203      * <dd><code>&lt;?xml-stylesheet HREF="standardstyle.css" type="text/css"?&gt;</code></dd>
204      * </dl>
205      */

206     public static final StartTagType XML_PROCESSING_INSTRUCTION=StartTagTypeXMLProcessingInstruction.INSTANCE;
207
208     /**
209      * The tag type given to a <a target="_blank" HREF="http://www.w3.org/TR/html401/struct/global.html#h-7.2">document type declaration</a> (<code>&lt;&#33;DOCTYPE </code>&#46;&#46;&#46;<code> &gt;</code>).
210      * <p>
211      * Information about the document type declaration can be found in the
212      * <a target="_blank" HREF="http://www.w3.org/TR/html401/struct/global.html#h-7.2">HTML 4.01 specification section 7.2</a>, and the
213      * <a target="_blank" HREF="http://www.w3.org/TR/REC-xml#dt-doctype">XML 1.0 specification section 2.8</a>.
214      * <p>
215      * The "<code>!DOCTYPE</code>" tag name is required to be in upper case in the source document,
216      * but all tag properties are stored in lower case because this library performs all parsing in lower case.
217      * <p>
218      * <dl>
219      * <dt>Properties:</dt>
220      * <dd>
221      * <table class="bordered" style="margin: 15px" cellspacing="0">
222      * <tr><th>Property<th>Value
223      * <tr><td>{@link #getDescription() Description}<td>document type declaration
224      * <tr><td>{@link #getStartDelimiter() StartDelimiter}<td><code>&lt;!doctype</code>
225      * <tr><td>{@link #getClosingDelimiter() ClosingDelimiter}<td><code>&gt;</code>
226      * <tr><td>{@link #isServerTag() IsServerTag}<td><code>false</code>
227      * <tr><td>{@link #getNamePrefix() NamePrefix}<td><code>!doctype</code>
228      * <tr><td>{@link #getCorrespondingEndTagType() CorrespondingEndTagType}<td><code>null</code>
229      * <tr><td>{@link #hasAttributes() HasAttributes}<td><code>false</code>
230      * <tr><td>{@link #isNameAfterPrefixRequired() IsNameAfterPrefixRequired}<td><code>false</code>
231      * </table>
232      * <dt>Example:</dt>
233      * <dd><code>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;</code></dd>
234      * </dl>
235      */

236     public static final StartTagType DOCTYPE_DECLARATION=StartTagTypeDoctypeDeclaration.INSTANCE;
237
238     /**
239      * The tag type given to a <a target="_blank" HREF="http://www.w3.org/TR/REC-xml/#dt-markupdecl">markup declaration</a> (<code>&lt;&#33; </code>&#46;&#46;&#46;<code> &gt;</code>).
240      * <p>
241      * The {@linkplain Tag#getName() name} of a markup declaration tag is must be one of
242      * "<code>!element</code>", "<code>!attlist</code>", "<code>!entity</code>" or "<code>!notation</code>".
243      * These tag names are required to be in upper case in the source document,
244      * but all tag properties are stored in lower case because this library performs all parsing in lower case.
245      * <p>
246      * Markup declarations usually appear inside a
247      * <a target="_blank" HREF="http://www.w3.org/TR/REC-xml#dt-doctype">document type definition</a> (DTD), which is usually an external
248      * document to the HTML or XML document, but they can also appear directly within the
249      * {@linkplain #DOCTYPE_DECLARATION document type declaration} which is why they must be recognised by the parser.
250      * <p>
251      * <dl>
252      * <dt>Properties:</dt>
253      * <dd>
254      * <table class="bordered" style="margin: 15px" cellspacing="0">
255      * <tr><th>Property<th>Value
256      * <tr><td>{@link #getDescription() Description}<td>markup declaration
257      * <tr><td>{@link #getStartDelimiter() StartDelimiter}<td><code>&lt;!</code>
258      * <tr><td>{@link #getClosingDelimiter() ClosingDelimiter}<td><code>&gt;</code>
259      * <tr><td>{@link #isServerTag() IsServerTag}<td><code>false</code>
260      * <tr><td>{@link #getNamePrefix() NamePrefix}<td><code>!</code>
261      * <tr><td>{@link #getCorrespondingEndTagType() CorrespondingEndTagType}<td><code>null</code>
262      * <tr><td>{@link #hasAttributes() HasAttributes}<td><code>false</code>
263      * <tr><td>{@link #isNameAfterPrefixRequired() IsNameAfterPrefixRequired}<td><code>true</code>
264      * </table>
265      * <dt>Example:</dt>
266      * <dd><code>&lt;!ELEMENT BODY O O (%flow;)* +(INS|DEL) -- document body --&gt;</code></dd>
267      * </dl>
268      */

269     public static final StartTagType MARKUP_DECLARATION=StartTagTypeMarkupDeclaration.INSTANCE;
270
271     /**
272      * The tag type given to a <a target="_blank" HREF="http://www.w3.org/TR/html401/appendix/notes.html#h-B.3.5">CDATA section</a> (<code>&lt;&#33;[CDATA[ </code>&#46;&#46;&#46;<code> ]]&gt;</code>).
273      * <p>
274      * A CDATA section is a specific form of a
275      * <a target="_blank" HREF="http://www.w3.org/TR/html401/appendix/notes.html#h-B.3.5">marked section</a>.
276      * <p>
277      * This library does not include a <a HREF="TagType.html#Predefined">predefined</a> generic tag type for marked sections,
278      * as the only form in which they are found in HTML documents are CDATA sections.
279      * <p>
280      * The <a target="_blank" HREF="http://www.w3.org/TR/html401/appendix/notes.html#h-B.3.5">HTML 4.01 specification section B.3.5</a>
281      * and the <a target="_blank" HREF="http://www.w3.org/TR/REC-xml/#sec-cdata-sect">XML 1.0 specification section 2.7</a>
282      * contain definitions for a CDATA section.
283      * <p>
284      * There is inconsistency between the SGML and HTML/XML specifications in the definition of a marked section.
285      * SGML requires the presence of a space between the "<code>&lt;![</code>" prefix and the keyword, and allows a space after the keyword.
286      * The XML specification forbids these spaces, and the examples given in the HTML specification do not include them either.
287      * This library only recognises CDATA sections that do not include the spaces.
288      * <p>
289      * The "<code>![CDATA[</code>" tag name is required to be in upper case in the source document according to the HTML/XML specifications,
290      * but all tag properties are stored in lower case because this makes it more efficient for the library to perform case-insensitive
291      * parsing of all tags.
292      * <p>
293      * In the default configuration, any non-{@linkplain #isServerTag() server} tag appearing within a CDATA section is ignored
294      * by the parser.
295      * See the documentation of the <a HREF="Tag.html#ParsingProcess">tag parsing process</a> for more information.
296      * <p>
297      * <dl>
298      * <dt>Properties:</dt>
299      * <dd>
300      * <table class="bordered" style="margin: 15px" cellspacing="0">
301      * <tr><th>Property<th>Value
302      * <tr><td>{@link #getDescription() Description}<td>CDATA section
303      * <tr><td>{@link #getStartDelimiter() StartDelimiter}<td><code>&lt;![cdata[</code>
304      * <tr><td>{@link #getClosingDelimiter() ClosingDelimiter}<td><code>]]&gt;</code>
305      * <tr><td>{@link #isServerTag() IsServerTag}<td><code>false</code>
306      * <tr><td>{@link #getNamePrefix() NamePrefix}<td><code>![cdata[</code>
307      * <tr><td>{@link #getCorrespondingEndTagType() CorrespondingEndTagType}<td><code>null</code>
308      * <tr><td>{@link #hasAttributes() HasAttributes}<td><code>false</code>
309      * <tr><td>{@link #isNameAfterPrefixRequired() IsNameAfterPrefixRequired}<td><code>false</code>
310      * </table>
311      * <dt>Example:</dt>
312      * <dd>This example shows the recommended practice of enclosing scripts inside a CDATA section:
313      * <div style="margin-top: 0.5em"><code>&lt;script&gt;&lt;![CDATA[ function min(a,b) {return a&lt;b ? a : b;} ]]&gt;&lt;/script&gt;</code></div>
314      * </dl>
315      */

316     public static final StartTagType CDATA_SECTION=StartTagTypeCDATASection.INSTANCE;
317     
318     /**
319      * The tag type given to a common server tag (<code>&lt;% </code>&#46;&#46;&#46;<code> %&gt;</code>).
320      * <p>
321      * Common server tags include
322      * <a target="_blank" HREF="http://msdn.microsoft.com/asp/">ASP</a>,
323      * <a target="_blank" HREF="http://java.sun.com/products/jsp/">JSP</a>,
324      * <a target="_blank" HREF="http://www.modpython.org/">PSP</a>,
325      * <a target="_blank" HREF="http://au2.php.net/manual/en/configuration.directives.php#ini.asp-tags">ASP-style PHP</a>,
326      * <a target="_blank" HREF="http://www.rubycentral.com/book/web.html#S2">eRuby</a>, and
327      * <a target="_blank" HREF="http://www.masonbook.com/book/chapter-2.mhtml#CHP-2-SECT-3.1">Mason substitution</a> tags.
328      * <p>
329      * This is the only <a HREF="TagType.html#Standard">standard</a> tag type that defines a {@linkplain #isServerTag() server tag}.
330      * It is included as a standard tag type because of its widespread use in many platforms, including those listed above.
331      * <p>
332      * <dl>
333      * <dt>Properties:</dt>
334      * <dd>
335      * <table class="bordered" style="margin: 15px" cellspacing="0">
336      * <tr><th>Property<th>Value
337      * <tr><td>{@link #getDescription() Description}<td>common server tag
338      * <tr><td>{@link #getStartDelimiter() StartDelimiter}<td><code>&lt;%</code>
339      * <tr><td>{@link #getClosingDelimiter() ClosingDelimiter}<td><code>%&gt;</code>
340      * <tr><td>{@link #isServerTag() IsServerTag}<td><code>true</code>
341      * <tr><td>{@link #getNamePrefix() NamePrefix}<td><code>%</code>
342      * <tr><td>{@link #getCorrespondingEndTagType() CorrespondingEndTagType}<td><code>null</code>
343      * <tr><td>{@link #hasAttributes() HasAttributes}<td><code>false</code>
344      * <tr><td>{@link #isNameAfterPrefixRequired() IsNameAfterPrefixRequired}<td><code>false</code>
345      * </table>
346      * <dt>Example:</dt>
347      * <dd><code>&lt;%@ include file="header.html" %&gt;</code></dd>
348      * </dl>
349      */

350     public static final StartTagType SERVER_COMMON=StartTagTypeServerCommon.INSTANCE;
351
352     /**
353      * Constructs a new <code>StartTagType</code> object with the specified properties.
354      * <br />(<a HREF="TagType.html#ImplementationAssistance">implementation assistance</a> method)
355      * <p>
356      * As <code>StartTagType</code> is an abstract class, this constructor is only called from sub-class constructors.
357      *
358      * @param description a {@linkplain #getDescription() description} of the new start tag type useful for debugging purposes.
359      * @param startDelimiter the {@linkplain #getStartDelimiter() start delimiter} of the new start tag type.
360      * @param closingDelimiter the {@linkplain #getClosingDelimiter() closing delimiter} of the new start tag type.
361      * @param correspondingEndTagType the {@linkplain #getCorrespondingEndTagType() corresponding end tag type} of the new start tag type.
362      * @param isServerTag indicates whether the new start tag type is a {@linkplain #isServerTag() server tag}.
363      * @param hasAttributes indicates whether the new start tag type {@linkplain #hasAttributes() has attributes}.
364      * @param isNameAfterPrefixRequired indicates whether a {@linkplain #isNameAfterPrefixRequired() name is required after the prefix}.
365      */

366     protected StartTagType(final String JavaDoc description, final String JavaDoc startDelimiter, final String JavaDoc closingDelimiter, final EndTagType correspondingEndTagType, final boolean isServerTag, final boolean hasAttributes, final boolean isNameAfterPrefixRequired) {
367         super(description,startDelimiter.toLowerCase(),closingDelimiter,isServerTag,START_DELIMITER_PREFIX);
368         if (!getStartDelimiter().startsWith(START_DELIMITER_PREFIX)) throw new IllegalArgumentException JavaDoc("startDelimiter of a start tag must start with \""+START_DELIMITER_PREFIX+'"');
369         this.correspondingEndTagType=correspondingEndTagType;
370         this.hasAttributes=hasAttributes;
371         this.isNameAfterPrefixRequired=isNameAfterPrefixRequired;
372     }
373
374     /**
375      * Returns the {@linkplain EndTagType type} of {@linkplain EndTag end tag} required to pair with a
376      * {@linkplain StartTag start tag} of this type to form an {@linkplain Element element}.
377      * <br />(<a HREF="TagType.html#Property">property</a> method)
378      * <p>
379      * This can be represented by the following expression that is always <code>true</code> given an arbitrary {@linkplain Element element}
380      * that has an end tag:
381      * <p>
382      * <code>element.</code>{@link Element#getStartTag() getStartTag()}<code>.</code>{@link StartTag#getStartTagType() getStartTagType()}<code>.</code>{@link #getCorrespondingEndTagType()}<code>==element.</code>{@link Element#getEndTag() getEndTag()}<code>.</code>{@link EndTag#getEndTagType() getEndTagType()}
383      * <p>
384      * <dl>
385      * <dt>Standard Tag Type Values:</dt>
386      * <dd>
387      * <table class="bordered" style="margin: 15px" cellspacing="0">
388      * <tr><th>Start Tag Type<th>Corresponding End Tag Type
389      * <tr><td>{@link StartTagType#UNREGISTERED}<td><code>null</code>
390      * <tr><td>{@link StartTagType#NORMAL}<td>{@link EndTagType#NORMAL}
391      * <tr><td>{@link StartTagType#COMMENT}<td><code>null</code>
392      * <tr><td>{@link StartTagType#XML_DECLARATION}<td><code>null</code>
393      * <tr><td>{@link StartTagType#XML_PROCESSING_INSTRUCTION}<td><code>null</code>
394      * <tr><td>{@link StartTagType#DOCTYPE_DECLARATION}<td><code>null</code>
395      * <tr><td>{@link StartTagType#MARKUP_DECLARATION}<td><code>null</code>
396      * <tr><td>{@link StartTagType#CDATA_SECTION}<td><code>null</code>
397      * <tr><td>{@link StartTagType#SERVER_COMMON}<td><code>null</code>
398      * </table>
399      * </dl>
400      * <dl>
401      * <dt>Extended Tag Type Values:</dt>
402      * <dd>
403      * <table class="bordered" style="margin: 15px" cellspacing="0">
404      * <tr><th>Start Tag Type<th>Corresponding End Tag Type
405      * <tr><td>{@link PHPTagTypes#PHP_SCRIPT}<td>{@link EndTagType#NORMAL}
406      * <tr><td>{@link PHPTagTypes#PHP_SHORT}<td><code>null</code>
407      * <tr><td>{@link PHPTagTypes#PHP_STANDARD}<td><code>null</code>
408      * <tr><td>{@link MasonTagTypes#MASON_COMPONENT_CALL}<td><code>null</code>
409      * <tr><td>{@link MasonTagTypes#MASON_COMPONENT_CALLED_WITH_CONTENT}<td>{@link MasonTagTypes#MASON_COMPONENT_CALLED_WITH_CONTENT_END}
410      * <tr><td>{@link MasonTagTypes#MASON_NAMED_BLOCK}<td>{@link MasonTagTypes#MASON_NAMED_BLOCK_END}
411      * </table>
412      * </dl>
413      *
414      * @return the {@linkplain EndTagType type} of {@linkplain EndTag end tag} required to pair with a {@linkplain StartTag start tag} of this type to form an {@link Element}.
415      * @see EndTagType#getCorrespondingStartTagType()
416      */

417     public final EndTagType getCorrespondingEndTagType() {
418         return correspondingEndTagType;
419     }
420
421     /**
422      * Indicates whether a start tag of this type contains {@linkplain Attributes attributes}.
423      * <br />(<a HREF="TagType.html#Property">property</a> method)
424      * <p>
425      * The attributes start at the end of the {@linkplain Tag#getName() name} and continue until the
426      * {@linkplain #getClosingDelimiter() closing delimiter} is encountered. If the character sequence representing the
427      * closing delimiter occurs within a quoted attribute value it is not recognised as the end of the tag.
428      * <p>
429      * The {@link #atEndOfAttributes(Source, int pos, boolean isClosingSlashIgnored)} method can be overridden to provide more control
430      * over where the attributes end.
431      * <p>
432      * <dl>
433      * <dt>Standard Tag Type Values:</dt>
434      * <dd>
435      * <table class="bordered" style="margin: 15px" cellspacing="0">
436      * <tr><th>Start Tag Type<th>Has Attributes
437      * <tr><td>{@link StartTagType#UNREGISTERED}<td><code>false</code>
438      * <tr><td>{@link StartTagType#NORMAL}<td><code>true</code>
439      * <tr><td>{@link StartTagType#COMMENT}<td><code>false</code>
440      * <tr><td>{@link StartTagType#XML_DECLARATION}<td><code>true</code>
441      * <tr><td>{@link StartTagType#XML_PROCESSING_INSTRUCTION}<td><code>false</code>
442      * <tr><td>{@link StartTagType#DOCTYPE_DECLARATION}<td><code>false</code>
443      * <tr><td>{@link StartTagType#MARKUP_DECLARATION}<td><code>false</code>
444      * <tr><td>{@link StartTagType#CDATA_SECTION}<td><code>false</code>
445      * <tr><td>{@link StartTagType#SERVER_COMMON}<td><code>false</code>
446      * </table>
447      * </dl>
448      * <dl>
449      * <dt>Extended Tag Type Values:</dt>
450      * <dd>
451      * <table class="bordered" style="margin: 15px" cellspacing="0">
452      * <tr><th>Start Tag Type<th>Has Attributes
453      * <tr><td>{@link PHPTagTypes#PHP_SCRIPT}<td><code>true</code>
454      * <tr><td>{@link PHPTagTypes#PHP_SHORT}<td><code>false</code>
455      * <tr><td>{@link PHPTagTypes#PHP_STANDARD}<td><code>false</code>
456      * <tr><td>{@link MasonTagTypes#MASON_COMPONENT_CALL}<td><code>false</code>
457      * <tr><td>{@link MasonTagTypes#MASON_COMPONENT_CALLED_WITH_CONTENT}<td><code>false</code>
458      * <tr><td>{@link MasonTagTypes#MASON_NAMED_BLOCK}<td><code>false</code>
459      * </table>
460      * </dl>
461      *
462      * @return <code>true</code> if a start tag of this type contains {@linkplain Attributes attributes}, otherwise <code>false</code>.
463      */

464     public final boolean hasAttributes() {
465         return hasAttributes;
466     }
467
468     /**
469      * Indicates whether a valid {@linkplain Tag#isXMLName(CharSequence) XML tag name} is required directly after the {@linkplain #getNamePrefix() prefix}.
470      * <br />(<a HREF="TagType.html#Property">property</a> method)
471      * <p>
472      * If this property is <code>true</code>, the {@linkplain Tag#getName() name} of the tag consists of the
473      * {@linkplain #getNamePrefix() prefix} followed by an {@linkplain Tag#isXMLName(CharSequence) XML tag name}.
474      * <p>
475      * If this property is <code>false</code>, the {@linkplain Tag#getName() name} of the tag consists of only the
476      * {@linkplain #getNamePrefix() prefix}.
477      * <p>
478      * <dl>
479      * <dt>Standard Tag Type Values:</dt>
480      * <dd>
481      * <table class="bordered" style="margin: 15px" cellspacing="0">
482      * <tr><th>Start Tag Type<th>Name After Prefix Required
483      * <tr><td>{@link StartTagType#UNREGISTERED}<td><code>false</code>
484      * <tr><td>{@link StartTagType#NORMAL}<td><code>true</code>
485      * <tr><td>{@link StartTagType#COMMENT}<td><code>false</code>
486      * <tr><td>{@link StartTagType#XML_DECLARATION}<td><code>false</code>
487      * <tr><td>{@link StartTagType#XML_PROCESSING_INSTRUCTION}<td><code>true</code>
488      * <tr><td>{@link StartTagType#DOCTYPE_DECLARATION}<td><code>false</code>
489      * <tr><td>{@link StartTagType#MARKUP_DECLARATION}<td><code>true</code>
490      * <tr><td>{@link StartTagType#CDATA_SECTION}<td><code>false</code>
491      * <tr><td>{@link StartTagType#SERVER_COMMON}<td><code>false</code>
492      * </table>
493      * </dl>
494      * <dl>
495      * <dt>Extended Tag Type Values:</dt>
496      * <dd>
497      * <table class="bordered" style="margin: 15px" cellspacing="0">
498      * <tr><th>Start Tag Type<th>Name After Prefix Required
499      * <tr><td>{@link PHPTagTypes#PHP_SCRIPT}<td><code>false</code>
500      * <tr><td>{@link PHPTagTypes#PHP_SHORT}<td><code>false</code>
501      * <tr><td>{@link PHPTagTypes#PHP_STANDARD}<td><code>false</code>
502      * <tr><td>{@link MasonTagTypes#MASON_COMPONENT_CALL}<td><code>false</code>
503      * <tr><td>{@link MasonTagTypes#MASON_COMPONENT_CALLED_WITH_CONTENT}<td><code>false</code>
504      * <tr><td>{@link MasonTagTypes#MASON_NAMED_BLOCK}<td><code>true</code>
505      * </table>
506      * </dl>
507      *
508      * @return <code>true</code> if a valid {@linkplain Tag#isXMLName(CharSequence) XML tag name} is required directly after the {@linkplain #getNamePrefix() prefix}, otherwise <code>false</code>.
509      */

510     public final boolean isNameAfterPrefixRequired() {
511         return isNameAfterPrefixRequired;
512     }
513
514     /**
515      * Indicates whether the specified source document position is at the end of a tag's {@linkplain Attributes attributes}.
516      * <br />(<a HREF="TagType.html#DefaultImplementation">default implementation</a> method)
517      * <p>
518      * This method is called internally while parsing {@linkplain Attributes attributes} to detect where they should end.
519      * <p>
520      * It can be assumed that the specified position is not inside a quoted attribute value.
521      * <p>
522      * The default implementation simply compares the {@linkplain ParseText parse text} at the specified
523      * position with the {@linkplain #getClosingDelimiter() closing delimiter}, and is equivalent to:<br />
524      * <code>source.</code>{@link Source#getParseText() getParseText()}<code>.containsAt(</code>{@link #getClosingDelimiter() getClosingDelimiter()}<code>,pos)</code>
525      * <p>
526      * The <code>isClosingSlashIgnored</code> parameter is only relevant in the {@link #NORMAL} start tag type,
527      * which makes use of it to cater for the '<code>/</code>' character that can occur before the
528      * {@linkplain #getClosingDelimiter() closing delimiter} in {@linkplain StartTag#isEmptyElementTag() empty-element tags}.
529      * It's value is always <code>false</code> when passed to other start tag types.
530      *
531      * @param source the {@link Source} document.
532      * @param pos the character position in the source document.
533      * @param isClosingSlashIgnored indicates whether the {@linkplain StartTag#getName() name} of the {@linkplain StartTag start tag} being tested is incompatible with an {@linkplain Element#isEmptyElementTag() empty-element tag}.
534      * @return <code>true</code> if the specified source document position is at the end of a tag's {@linkplain Attributes attributes}, otherwise <code>false</code>.
535      */

536     public boolean atEndOfAttributes(final Source source, final int pos, final boolean isClosingSlashIgnored) {
537         return source.getParseText().containsAt(getClosingDelimiter(),pos);
538     }
539
540     /**
541      * Internal method for the construction of a {@link StartTag} object if this type.
542      * <br />(<a HREF="TagType.html#ImplementationAssistance">implementation assistance</a> method)
543      * <p>
544      * Intended for use from within the {@link #constructTagAt(Source,int) constructTagAt(Source, int pos)} method.
545      *
546      * @param source the {@link Source} document.
547      * @param begin the character position in the source document where the tag {@linkplain Segment#getBegin() begins}.
548      * @param end the character position in the source document where the tag {@linkplain Segment#getEnd() ends}.
549      * @param name the {@linkplain Tag#getName() name} of the tag.
550      * @param attributes the {@linkplain StartTag#getAttributes() attributes} of the tag.
551      * @return the new {@link StartTag} object.
552      */

553     protected final StartTag constructStartTag(final Source source, final int begin, final int end, final String JavaDoc name, final Attributes attributes) {
554         return new StartTag(source,begin,end,this,name,attributes);
555     }
556     
557     /**
558      * Internal method for the parsing of {@link Attributes}.
559      * <br />(<a HREF="TagType.html#ImplementationAssistance">implementation assistance</a> method)
560      * <p>
561      * Intended for use from within the {@link #constructTagAt(Source,int) constructTagAt(Source, int pos)} method.
562      * <p>
563      * The returned {@link Attributes} segment begins at <code>startTagBegin+1+tagName.length()</code>,
564      * and ends straight after the last attribute found before the tag's {@linkplain #getClosingDelimiter() closing delimiter}.
565      * <p>
566      * Only returns <code>null</code> if the segment contains a major syntactical error
567      * or more than the {@linkplain Attributes#getDefaultMaxErrorCount() default maximum} number of
568      * minor syntactical errors.
569      *
570      * @param source the {@link Source} document.
571      * @param startTagBegin the position in the source document at which the start tag is to begin.
572      * @param tagName the {@linkplain StartTag#getName() name} of the start tag to be constructed.
573      * @return the {@link Attributes} of the start tag to be constructed, or <code>null</code> if too many errors occur while parsing.
574      */

575     protected final Attributes parseAttributes(final Source source, final int startTagBegin, final String JavaDoc tagName) {
576         return Attributes.construct(source,startTagBegin,this,tagName);
577     }
578 }
579
580
Popular Tags