📄 htmlvalidator.java
字号:
/* tagStack.java -- The HTML tag stack. Copyright (C) 2005 Free Software Foundation, Inc.This file is part of GNU Classpath.GNU Classpath is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.GNU Classpath is distributed in the hope that it will be useful, butWITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNUGeneral Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU Classpath; see the file COPYING. If not, write to theFree Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA02110-1301 USA.Linking this library statically or dynamically with other modules ismaking a combined work based on this library. Thus, the terms andconditions of the GNU General Public License cover the wholecombination.As a special exception, the copyright holders of this library give youpermission to link this library with independent modules to produce anexecutable, regardless of the license terms of these independentmodules, and to copy and distribute the resulting executable underterms of your choice, provided that you also meet, for each linkedindependent module, the terms and conditions of the license of thatmodule. An independent module is a module which is not derived fromor based on this library. If you modify this library, you may extendthis exception to your version of the library, but you are notobligated to do so. If you do not wish to do so, delete thisexception statement from your version. */package gnu.javax.swing.text.html.parser;import gnu.javax.swing.text.html.parser.models.node;import gnu.javax.swing.text.html.parser.models.transformer;import java.util.BitSet;import java.util.Enumeration;import java.util.LinkedList;import java.util.ListIterator;import javax.swing.text.SimpleAttributeSet;import javax.swing.text.html.HTML;import javax.swing.text.html.parser.*;/** * <p>The HTML content validator, is responsible for opening and * closing elements with optional start/end tags, detecting * the wrongly placed html tags and reporting errors. The working instance * is the inner class inside the {@link javax.swing.text.html.parser.Parser } * </p> * <p>This class could potentially * provide basis for automated closing and insertion of the html tags, * correcting the found html errors. * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) */public abstract class htmlValidator{ /** * The tag reference, holding additional information that the tag * has been forcibly closed. */ protected class hTag { protected final Element element; protected final HTML.Tag tag; protected final TagElement tgElement; protected boolean forcibly_closed; protected node validationTrace; protected hTag(TagElement an_element) { element = an_element.getElement(); tag = an_element.getHTMLTag(); tgElement = an_element; if (element.content != null) validationTrace = transformer.transform(element.content, dtd); } /** * This is called when the tag must be forcibly closed because * it would make the newly appearing tag invalid. * The parser is not notified about such event (just the error * is reported). For such tags, the closing message does not * appear when later reaching the end of stream. The exception is * the <head> tag: the parser is notified about its silent closing * when <body> or other html content appears. */ protected void forciblyCloseDueContext() { forcibly_closed = true; } /** * This is called when the tag must be forcibly closed after * reaching the end of stream. The parser is notified as if * closing the tag explicitly. */ protected void forciblyCloseDueEndOfStream() { forcibly_closed = true; handleSupposedEndTag(element); } } /** * The DTD, providing information about the valid document structure. */ protected final DTD dtd; /** * The stack, holding the current tag context. */ protected final LinkedList stack = new LinkedList(); /** * Creates a new tag stack, using the given DTD. * @param a_dtd A DTD, providing the information about the valid * tag content. */ public htmlValidator(DTD a_dtd) { dtd = a_dtd; } /** * Close all opened tags (called at the end of parsing). */ public void closeAll() { hTag h; while (!stack.isEmpty()) { h = (hTag) stack.getLast(); if (!h.forcibly_closed && !h.element.omitEnd()) s_error("Unclosed <" + h.tag + ">, closing at the end of stream"); handleSupposedEndTag(h.element); closeTag(h.tgElement); } } /** * Remove the given tag from the stack or (if found) from the list * of the forcibly closed tags. */ public void closeTag(TagElement tElement) { HTML.Tag tag = tElement.getHTMLTag(); hTag x; hTag close; if (!stack.isEmpty()) { ListIterator iter = stack.listIterator(stack.size()); while (iter.hasPrevious()) { x = (hTag) iter.previous(); if (tag.equals(x.tag)) { if (x.forcibly_closed && !x.element.omitEnd()) s_error("The tag <" + x.tag + "> has already been forcibly closed" ); // If the tag has a content model defined, forcibly close all // tags that were opened after the tag being currently closed. closing: if (x.element.content != null) { iter = stack.listIterator(stack.size()); while (iter.hasPrevious()) { close = (hTag) iter.previous(); if (close == x) break closing; handleSupposedEndTag(close.element); iter.remove(); } } stack.remove(x); return; } } } s_error("Closing unopened <" + tag + ">"); } /** * Add the given HTML tag to the stack of the opened tags. Forcibly closes * all tags in the stack that does not allow this tag in they content (error * is reported). * @param element */ public void openTag(TagElement tElement, htmlAttributeSet parameters) { // If this is a fictional call, the message from the parser // has recursively returned - ignore. if (tElement.fictional()) return; validateParameters(tElement, parameters); // If the stack is empty, start from HTML if (stack.isEmpty() && tElement.getHTMLTag() != HTML.Tag.HTML) { Element html = dtd.getElement(HTML.Tag.HTML.toString()); openFictionalTag(html); } Object v = tagIsValidForContext(tElement); if (v != Boolean.TRUE) { // The tag is not valid for context, the content // model suggest to open another tag. if (v instanceof Element) { int n = 0; while (v instanceof Element && (n++ < 100)) { Element fe = (Element) v; // notify the content model that we add the proposed tag getCurrentContentModel().show(fe); openFictionalTag(fe); Object vv = tagIsValidForContext(tElement); if (vv instanceof Element) // One level of nesting is supported. { openFictionalTag((Element) vv); Object vx = tagIsValidForContext(tElement); if (vx instanceof Element) openFictionalTag((Element) vx); } else if (vv == Boolean.FALSE) { // The tag is still not valid for the current // content after opening a fictional element. if (fe.omitEnd()) { // close the previously opened fictional tag. closeLast(); vv = tagIsValidForContext(tElement); if (vv instanceof Element) // another tag was suggested by the content model openFictionalTag((Element) vv); } } v = tagIsValidForContext(tElement); } } else // If the current element has the optional end tag, close it. { if (!stack.isEmpty()) { closing: do { hTag last = (hTag) stack.getLast(); if (last.element.omitEnd()) { closeLast(); v = tagIsValidForContext(tElement); if (v instanceof Element) // another tag was suggested by the content model { openFictionalTag((Element) v); break closing; } } else break closing; } while (v == Boolean.FALSE && !stack.isEmpty()); } } } stack.add(new hTag(tElement)); } /** * Clear the stack. */ public void restart() { stack.clear(); } /** * Check if this tag is valid for the current context. * Return Boolean.True if it is OK, Boolean.False * if it is surely not OK or the Element that the
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -