public final HttpTagType next()

in wicket-core/src/main/java/org/apache/wicket/markup/parser/XmlPullParser.java [167:324]


	public final HttpTagType next() throws ParseException
	{
		// Reached end of markup file?
		if (input.getPosition() >= input.size())
		{
			return HttpTagType.NOT_INITIALIZED;
		}

		if (skipUntilText != null)
		{
			skipUntil();
			return lastType;
		}

		// Any more tags in the markup?
		final int openBracketIndex = input.find('<');

		// Tag or Body?
		if (input.charAt(input.getPosition()) != '<')
		{
			// It's a BODY
			if (openBracketIndex == -1)
			{
				// There is no next matching tag.
				lastText = input.getSubstring(-1);
				input.setPosition(input.size());
				lastType = HttpTagType.BODY;
				return lastType;
			}

			lastText = input.getSubstring(openBracketIndex);
			input.setPosition(openBracketIndex);
			lastType = HttpTagType.BODY;
			return lastType;
		}

		// Determine the line number
		input.countLinesTo(openBracketIndex);

		// Get index of closing tag and advance past the tag
		int closeBracketIndex = -1;

		if (openBracketIndex != -1 && openBracketIndex < input.size() - 1)
		{
			char nextChar = input.charAt(openBracketIndex + 1);

			if ((nextChar == '!') || (nextChar == '?'))
				closeBracketIndex = input.find('>', openBracketIndex);
			else
				closeBracketIndex = input.findOutOfQuotes('>', openBracketIndex);
		}

		if (closeBracketIndex == -1)
		{
			throw new ParseException("No matching close bracket at" + getLineAndColumnText(),
				input.getPosition());
		}

		// Get the complete tag text
		lastText = input.getSubstring(openBracketIndex, closeBracketIndex + 1);

		// Get the tagtext between open and close brackets
		String tagText = lastText.subSequence(1, lastText.length() - 1).toString();
		if (tagText.length() == 0)
		{
			throw new ParseException("Found empty tag: '<>' at" + getLineAndColumnText(),
				input.getPosition());
		}

		// Type of the tag, to be determined next
		final TagType type;

		// If the tag ends in '/', it's a "simple" tag like <foo/>
		if (tagText.endsWith("/"))
		{
			type = TagType.OPEN_CLOSE;
			tagText = tagText.substring(0, tagText.length() - 1);
		}
		else if (tagText.startsWith("/"))
		{
			// The tag text starts with a '/', it's a simple close tag
			type = TagType.CLOSE;
			tagText = tagText.substring(1);
		}
		else
		{
			// It must be an open tag
			type = TagType.OPEN;

			// If open tag and starts with "s" like "script" or "style", than ...
			if ((tagText.length() > STYLE.length()) &&
				((tagText.charAt(0) == 's') || (tagText.charAt(0) == 'S')))
			{
				final String lowerCase = tagText.toLowerCase(Locale.ROOT);
				if (lowerCase.startsWith(SCRIPT))
				{
					String typeAttr = "type=";
					int idxOfType = lowerCase.indexOf(typeAttr);
					if (idxOfType > 0)
					{
						// +1 to remove the ' or "
						String typePrefix = lowerCase.substring(idxOfType + typeAttr.length() + 1);
						if (typePrefix.startsWith("text/javascript") || typePrefix.startsWith("module")
						        || typePrefix.startsWith("importmap"))
						{
							// prepare to skip everything between the open and close tag
							skipUntilText = SCRIPT;
						}
						// any other type is assumed to be a template so it can contain child nodes.
						// See WICKET-5288
					}
					else
					{
						// no type attribute so it is 'text/javascript'
						// prepare to skip everything between the open and close tag
						skipUntilText = SCRIPT;
					}
				}
				else if (lowerCase.startsWith(STYLE))
				{
					// prepare to skip everything between the open and close tag
					skipUntilText = STYLE;
				}
			}
		}

		// Handle special tags like <!-- and <![CDATA ...
		final char firstChar = tagText.charAt(0);
		if ((firstChar == '!') || (firstChar == '?'))
		{
			specialTagHandling(tagText, openBracketIndex, closeBracketIndex);

			input.countLinesTo(openBracketIndex);
			TextSegment text = new TextSegment(lastText, openBracketIndex, input.getLineNumber(),
				input.getColumnNumber());
			lastTag = new XmlTag(text, type);

			return lastType;
		}

		TextSegment text = new TextSegment(lastText, openBracketIndex, input.getLineNumber(),
			input.getColumnNumber());
		XmlTag tag = new XmlTag(text, type);
		lastTag = tag;

		// Parse the tag text and populate tag attributes
		if (parseTagText(tag, tagText))
		{
			// Move to position after the tag
			input.setPosition(closeBracketIndex + 1);
			lastType = HttpTagType.TAG;
			return lastType;
		}
		else
		{
			throw new ParseException("Malformed tag" + getLineAndColumnText(), openBracketIndex);
		}
	}