1 |
// Jericho HTML Parser - Java based library for analysing and manipulating HTML
|
2 |
// Version 3.2
|
3 |
// Copyright (C) 2004-2009 Martin Jericho
|
4 |
// http://jericho.htmlparser.net/
|
5 |
//
|
6 |
// This library is free software; you can redistribute it and/or
|
7 |
// modify it under the terms of either one of the following licences:
|
8 |
//
|
9 |
// 1. The Eclipse Public License (EPL) version 1.0,
|
10 |
// included in this distribution in the file licence-epl-1.0.html
|
11 |
// or available at http://www.eclipse.org/legal/epl-v10.html
|
12 |
//
|
13 |
// 2. The GNU Lesser General Public License (LGPL) version 2.1 or later,
|
14 |
// included in this distribution in the file licence-lgpl-2.1.txt
|
15 |
// or available at http://www.gnu.org/licenses/lgpl.txt
|
16 |
//
|
17 |
// This library is distributed on an "AS IS" basis,
|
18 |
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
|
19 |
// See the individual licence texts for more details.
|
20 |
|
21 |
package net.htmlparser.jericho;
|
22 |
|
23 |
import java.util.*;
|
24 |
|
25 |
/**
|
26 |
* Defines the syntax for an end tag type.
|
27 |
* <p>
|
28 |
* An end tag type is a {@link TagType} that {@linkplain #getStartDelimiter() starts} with the characters '<code></</code>'.
|
29 |
* <p>
|
30 |
* The singleton instances of all the <a href="TagType.html#Standard">standard</a> end tag types are available in this class as static
|
31 |
* <a href="#field_summary">fields</a>.
|
32 |
* <p>
|
33 |
* Because all <code>EndTagType</code> instaces must be singletons, the '<code>==</code>' operator can be used to test for a particular tag type
|
34 |
* instead of the <code>equals(Object)</code> method.
|
35 |
*
|
36 |
* @see StartTagType
|
37 |
*/
|
38 |
public abstract class EndTagType extends TagType {
|
39 |
static final String START_DELIMITER_PREFIX="</";
|
40 |
|
41 |
/**
|
42 |
* The tag type given to an {@linkplain Tag#isUnregistered() unregistered} {@linkplain EndTag end tag} (<code></<var> ... </var>></code>).
|
43 |
* <p>
|
44 |
* See the documentation of the {@link Tag#isUnregistered()} method for details.
|
45 |
* <p>
|
46 |
* <dl>
|
47 |
* <dt>Properties:</dt>
|
48 |
* <dd>
|
49 |
* <table class="bordered" style="margin: 15px" cellspacing="0">
|
50 |
* <tr><th>Property/Method<th>Value
|
51 |
* <tr><td>{@link #getDescription() Description}<td>/unregistered
|
52 |
* <tr><td>{@link #getStartDelimiter() StartDelimiter}<td><code></</code>
|
53 |
* <tr><td>{@link #getClosingDelimiter() ClosingDelimiter}<td><code>></code>
|
54 |
* <tr><td>{@link #isServerTag() IsServerTag}<td><code>false</code>
|
55 |
* <tr><td>{@link #getNamePrefix() NamePrefix}<td><i>(empty string)</i>
|
56 |
* <tr><td>{@link #getCorrespondingStartTagType() CorrespondingStartTagType}<td><code>null</code>
|
57 |
* <tr><td>{@link #generateHTML(String) generateHTML}<code>("<var>StartTagName</var>")</code><td><code></<var>StartTagName</var>></code>
|
58 |
* </table>
|
59 |
* <dt>Example:</dt>
|
60 |
* <dd><code></ "This is not recognised as any of the predefined end tag types in this library"></code></dd>
|
61 |
* </dl>
|
62 |
* @see StartTagType#UNREGISTERED
|
63 |
*/
|
64 |
public static final EndTagType UNREGISTERED=EndTagTypeUnregistered.INSTANCE;
|
65 |
|
66 |
/**
|
67 |
* The tag type given to a normal HTML or XML {@linkplain EndTag end tag} (<code></<var>name</var>></code>).
|
68 |
* <p>
|
69 |
* <dl>
|
70 |
* <dt>Properties:</dt>
|
71 |
* <dd>
|
72 |
* <table class="bordered" style="margin: 15px" cellspacing="0">
|
73 |
* <tr><th>Property/Method<th>Value
|
74 |
* <tr><td>{@link #getDescription() Description}<td>/normal
|
75 |
* <tr><td>{@link #getStartDelimiter() StartDelimiter}<td><code></</code>
|
76 |
* <tr><td>{@link #getClosingDelimiter() ClosingDelimiter}<td><code>></code>
|
77 |
* <tr><td>{@link #isServerTag() IsServerTag}<td><code>false</code>
|
78 |
* <tr><td>{@link #getNamePrefix() NamePrefix}<td><i>(empty string)</i>
|
79 |
* <tr><td>{@link #getCorrespondingStartTagType() CorrespondingStartTagType}<td>{@link StartTagType#NORMAL}
|
80 |
* <tr><td>{@link #generateHTML(String) generateHTML}<code>("<var>StartTagName</var>")</code><td><code></<var>StartTagName</var>></code>
|
81 |
* </table>
|
82 |
* <dt>Example:</dt>
|
83 |
* <dd><code></div></code></dd>
|
84 |
* </dl>
|
85 |
*/
|
86 |
public static final EndTagType NORMAL=EndTagTypeNormal.INSTANCE;
|
87 |
|
88 |
/**
|
89 |
* Constructs a new <code>EndTagType</code> object with the specified properties.
|
90 |
* <br />(<a href="TagType.html#ImplementationAssistance">implementation assistance</a> method)
|
91 |
* <p>
|
92 |
* As <code>EndTagType</code> is an abstract class, this constructor is only called from sub-class constructors.
|
93 |
*
|
94 |
* @param description a {@linkplain #getDescription() description} of the new end tag type useful for debugging purposes.
|
95 |
* @param startDelimiter the {@linkplain #getStartDelimiter() start delimiter} of the new end tag type.
|
96 |
* @param closingDelimiter the {@linkplain #getClosingDelimiter() closing delimiter} of the new end tag type.
|
97 |
* @param isServerTag indicates whether the new end tag type is a {@linkplain #isServerTag() server tag}.
|
98 |
*/
|
99 |
protected EndTagType(final String description, final String startDelimiter, final String closingDelimiter, final boolean isServerTag) {
|
100 |
super(description,startDelimiter.toLowerCase(),closingDelimiter,isServerTag,START_DELIMITER_PREFIX);
|
101 |
if (!getStartDelimiter().startsWith(START_DELIMITER_PREFIX)) throw new IllegalArgumentException("startDelimiter of an end tag must start with \""+START_DELIMITER_PREFIX+'"');
|
102 |
}
|
103 |
|
104 |
/**
|
105 |
* Returns the {@linkplain StartTagType type} of {@linkplain StartTag start tag} that is <i>usually</i> paired with an
|
106 |
* {@linkplain EndTag end tag} of this type to form an {@link Element}.
|
107 |
* <br />(<a href="TagType.html#DefaultImplementation">default implementation</a> method)
|
108 |
* <p>
|
109 |
* The default implementation returns <code>null</code>.
|
110 |
* <p>
|
111 |
* This property is informational only and is not used by the parser in any way.
|
112 |
* <p>
|
113 |
* The mapping of end tag type to the corresponding start tag type is in any case one-to-many, which is why the definition
|
114 |
* emphasises the word "usually".
|
115 |
* An example of this is the {@link PHPTagTypes#PHP_SCRIPT} start tag type,
|
116 |
* whose {@linkplain StartTagType#getCorrespondingEndTagType() corresponding end tag type} is {@link #NORMAL EndTagType.NORMAL},
|
117 |
* while the converse is not true.
|
118 |
* <p>
|
119 |
* The only <a href="TagType.html#Predefined">predefined</a> end tag type that returns <code>null</code> for this property is the
|
120 |
* special {@link #UNREGISTERED} end tag type.
|
121 |
* <p>
|
122 |
* Although this method is used like a <a href="TagType.html#Property">property</a> method, it is implemented as a
|
123 |
* <a href="TagType.html#DefaultImplementation">default implementation</a> method to avoid cyclic references between statically
|
124 |
* instantiated {@link StartTagType} and <code>EndTagType</code> objects.
|
125 |
* <p>
|
126 |
* <dl>
|
127 |
* <dt>Standard Tag Type Values:</dt>
|
128 |
* <dd>
|
129 |
* <table class="bordered" style="margin: 15px" cellspacing="0">
|
130 |
* <tr><th>End Tag Type<th>Corresponding Start Tag Type
|
131 |
* <tr><td>{@link EndTagType#UNREGISTERED}<td><code>null</code>
|
132 |
* <tr><td>{@link EndTagType#NORMAL}<td>{@link StartTagType#NORMAL}
|
133 |
* </table>
|
134 |
* </dl>
|
135 |
* <dl>
|
136 |
* <dt>Extended Tag Type Values:</dt>
|
137 |
* <dd>
|
138 |
* <table class="bordered" style="margin: 15px" cellspacing="0">
|
139 |
* <tr><th>End Tag Type<th>Corresponding Start Tag Type
|
140 |
* <tr><td>{@link MasonTagTypes#MASON_COMPONENT_CALLED_WITH_CONTENT_END}<td>{@link MasonTagTypes#MASON_COMPONENT_CALLED_WITH_CONTENT}
|
141 |
* <tr><td>{@link MasonTagTypes#MASON_NAMED_BLOCK_END}<td>{@link MasonTagTypes#MASON_NAMED_BLOCK}
|
142 |
* </table>
|
143 |
* </dl>
|
144 |
*
|
145 |
* @return the {@linkplain StartTagType type} of {@linkplain StartTag start tag} that is <i>usually</i> paired with an {@linkplain EndTag end tag} of this type to form an {@link Element}.
|
146 |
* @see StartTagType#getCorrespondingEndTagType()
|
147 |
*/
|
148 |
public StartTagType getCorrespondingStartTagType() {
|
149 |
return null;
|
150 |
}
|
151 |
|
152 |
/**
|
153 |
* Returns the end tag {@linkplain EndTag#getName() name} that is required to match a {@linkplain #getCorrespondingStartTagType() corresponding} {@linkplain StartTag start tag} with the specified {@linkplain StartTag#getName() name}.
|
154 |
* <br />(<a href="TagType.html#Property">property</a> method)
|
155 |
* <p>
|
156 |
* This default implementation simply returns <code>startTagName</code>.
|
157 |
* <p>
|
158 |
* Note that the <code>startTagName</code> parameter should include the start tag's {@linkplain TagType#getNamePrefix() name prefix} if it has one.
|
159 |
*
|
160 |
* @param startTagName the {@linkplain StartTag#getName() name} of a {@linkplain #getCorrespondingStartTagType() corresponding} {@linkplain StartTag start tag}, including its {@linkplain TagType#getNamePrefix() name prefix}.
|
161 |
* @return the end tag {@linkplain EndTag#getName() name} that is required to match a {@linkplain #getCorrespondingStartTagType() corresponding} {@linkplain StartTag start tag} with the specified {@linkplain StartTag#getName() name}.
|
162 |
*/
|
163 |
public String getEndTagName(final String startTagName) {
|
164 |
return startTagName;
|
165 |
}
|
166 |
|
167 |
/**
|
168 |
* Generates the HTML text of an {@linkplain EndTag end tag} of this type given the {@linkplain StartTag#getName() name} of a {@linkplain #getCorrespondingStartTagType() corresponding} {@linkplain StartTag start tag}.
|
169 |
* <br />(<a href="TagType.html#Property">property</a> method)
|
170 |
* <p>
|
171 |
* This default implementation returns <code>"</"+</code>{@link #getEndTagName(String) getEndTagName}<code>(startTagName)+</code>{@link #getClosingDelimiter()}.
|
172 |
* <p>
|
173 |
* Note that the <code>startTagName</code> parameter should include the start tag's {@linkplain TagType#getNamePrefix() name prefix} if it has one.
|
174 |
*
|
175 |
* @param startTagName the {@linkplain StartTag#getName() name} of a {@linkplain #getCorrespondingStartTagType() corresponding} {@linkplain StartTag start tag}, including its {@linkplain TagType#getNamePrefix() name prefix}.
|
176 |
* @return the HTML text of an {@linkplain EndTag end tag} of this type given the {@linkplain StartTag#getName() name} of a {@linkplain #getCorrespondingStartTagType() corresponding} {@linkplain StartTag start tag}.
|
177 |
*/
|
178 |
public String generateHTML(final String startTagName) {
|
179 |
return START_DELIMITER_PREFIX+getEndTagName(startTagName)+getClosingDelimiter();
|
180 |
}
|
181 |
|
182 |
/**
|
183 |
* Internal method for the construction of an {@link EndTag} object of this type.
|
184 |
* <br />(<a href="TagType.html#ImplementationAssistance">implementation assistance</a> method)
|
185 |
* <p>
|
186 |
* Intended for use from within the {@link #constructTagAt(Source,int) constructTagAt(Source, int pos)} method.
|
187 |
*
|
188 |
* @param source the {@link Source} document.
|
189 |
* @param begin the character position in the source document where this tag {@linkplain Segment#getBegin() begins}.
|
190 |
* @param end the character position in the source document where this tag {@linkplain Segment#getEnd() ends}.
|
191 |
* @param name the {@linkplain Tag#getName() name} of the tag.
|
192 |
* @return the new {@link EndTag} object.
|
193 |
*/
|
194 |
protected final EndTag constructEndTag(final Source source, final int begin, final int end, final String name) {
|
195 |
return new EndTag(source,begin,end,this,name);
|
196 |
}
|
197 |
}
|