feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
172
jdkSrc/jdk8/javax/swing/text/html/parser/AttributeList.java
Normal file
172
jdkSrc/jdk8/javax/swing/text/html/parser/AttributeList.java
Normal file
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.text.html.parser;
|
||||
|
||||
import java.util.Vector;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Enumeration;
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* This class defines the attributes of an SGML element
|
||||
* as described in a DTD using the ATTLIST construct.
|
||||
* An AttributeList can be obtained from the Element
|
||||
* class using the getAttributes() method.
|
||||
* <p>
|
||||
* It is actually an element in a linked list. Use the
|
||||
* getNext() method repeatedly to enumerate all the attributes
|
||||
* of an element.
|
||||
*
|
||||
* @see Element
|
||||
* @author Arthur Van Hoff
|
||||
*
|
||||
*/
|
||||
public final
|
||||
class AttributeList implements DTDConstants, Serializable {
|
||||
public String name;
|
||||
public int type;
|
||||
public Vector<?> values;
|
||||
public int modifier;
|
||||
public String value;
|
||||
public AttributeList next;
|
||||
|
||||
AttributeList() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an attribute list element.
|
||||
*/
|
||||
public AttributeList(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an attribute list element.
|
||||
*/
|
||||
public AttributeList(String name, int type, int modifier, String value, Vector<?> values, AttributeList next) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.modifier = modifier;
|
||||
this.value = value;
|
||||
this.values = values;
|
||||
this.next = next;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return attribute name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return attribute type
|
||||
* @see DTDConstants
|
||||
*/
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return attribute modifier
|
||||
* @see DTDConstants
|
||||
*/
|
||||
public int getModifier() {
|
||||
return modifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return possible attribute values
|
||||
*/
|
||||
public Enumeration<?> getValues() {
|
||||
return (values != null) ? values.elements() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return default attribute value
|
||||
*/
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the next attribute in the list
|
||||
*/
|
||||
public AttributeList getNext() {
|
||||
return next;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string representation
|
||||
*/
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a hashtable of attribute types.
|
||||
*/
|
||||
static Hashtable<Object, Object> attributeTypes = new Hashtable<Object, Object>();
|
||||
|
||||
static void defineAttributeType(String nm, int val) {
|
||||
Integer num = Integer.valueOf(val);
|
||||
attributeTypes.put(nm, num);
|
||||
attributeTypes.put(num, nm);
|
||||
}
|
||||
|
||||
static {
|
||||
defineAttributeType("CDATA", CDATA);
|
||||
defineAttributeType("ENTITY", ENTITY);
|
||||
defineAttributeType("ENTITIES", ENTITIES);
|
||||
defineAttributeType("ID", ID);
|
||||
defineAttributeType("IDREF", IDREF);
|
||||
defineAttributeType("IDREFS", IDREFS);
|
||||
defineAttributeType("NAME", NAME);
|
||||
defineAttributeType("NAMES", NAMES);
|
||||
defineAttributeType("NMTOKEN", NMTOKEN);
|
||||
defineAttributeType("NMTOKENS", NMTOKENS);
|
||||
defineAttributeType("NOTATION", NOTATION);
|
||||
defineAttributeType("NUMBER", NUMBER);
|
||||
defineAttributeType("NUMBERS", NUMBERS);
|
||||
defineAttributeType("NUTOKEN", NUTOKEN);
|
||||
defineAttributeType("NUTOKENS", NUTOKENS);
|
||||
|
||||
attributeTypes.put("fixed", Integer.valueOf(FIXED));
|
||||
attributeTypes.put("required", Integer.valueOf(REQUIRED));
|
||||
attributeTypes.put("current", Integer.valueOf(CURRENT));
|
||||
attributeTypes.put("conref", Integer.valueOf(CONREF));
|
||||
attributeTypes.put("implied", Integer.valueOf(IMPLIED));
|
||||
}
|
||||
|
||||
public static int name2type(String nm) {
|
||||
Integer i = (Integer)attributeTypes.get(nm);
|
||||
return (i == null) ? CDATA : i.intValue();
|
||||
}
|
||||
|
||||
public static String type2name(int tp) {
|
||||
return (String)attributeTypes.get(Integer.valueOf(tp));
|
||||
}
|
||||
}
|
||||
254
jdkSrc/jdk8/javax/swing/text/html/parser/ContentModel.java
Normal file
254
jdkSrc/jdk8/javax/swing/text/html/parser/ContentModel.java
Normal file
@@ -0,0 +1,254 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.text.html.parser;
|
||||
|
||||
import java.util.Vector;
|
||||
import java.util.Enumeration;
|
||||
import java.io.*;
|
||||
|
||||
|
||||
/**
|
||||
* A representation of a content model. A content model is
|
||||
* basically a restricted BNF expression. It is restricted in
|
||||
* the sense that it must be deterministic. This means that you
|
||||
* don't have to represent it as a finite state automaton.<p>
|
||||
* See Annex H on page 556 of the SGML handbook for more information.
|
||||
*
|
||||
* @author Arthur van Hoff
|
||||
*
|
||||
*/
|
||||
public final class ContentModel implements Serializable {
|
||||
/**
|
||||
* Type. Either '*', '?', '+', ',', '|', '&'.
|
||||
*/
|
||||
public int type;
|
||||
|
||||
/**
|
||||
* The content. Either an Element or a ContentModel.
|
||||
*/
|
||||
public Object content;
|
||||
|
||||
/**
|
||||
* The next content model (in a ',', '|' or '&' expression).
|
||||
*/
|
||||
public ContentModel next;
|
||||
|
||||
public ContentModel() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a content model for an element.
|
||||
*/
|
||||
public ContentModel(Element content) {
|
||||
this(0, content, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a content model of a particular type.
|
||||
*/
|
||||
public ContentModel(int type, ContentModel content) {
|
||||
this(type, content, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a content model of a particular type.
|
||||
*/
|
||||
public ContentModel(int type, Object content, ContentModel next) {
|
||||
this.type = type;
|
||||
this.content = content;
|
||||
this.next = next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the content model could
|
||||
* match an empty input stream.
|
||||
*/
|
||||
public boolean empty() {
|
||||
switch (type) {
|
||||
case '*':
|
||||
case '?':
|
||||
return true;
|
||||
|
||||
case '+':
|
||||
case '|':
|
||||
for (ContentModel m = (ContentModel)content ; m != null ; m = m.next) {
|
||||
if (m.empty()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
case ',':
|
||||
case '&':
|
||||
for (ContentModel m = (ContentModel)content ; m != null ; m = m.next) {
|
||||
if (!m.empty()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update elemVec with the list of elements that are
|
||||
* part of the this contentModel.
|
||||
*/
|
||||
public void getElements(Vector<Element> elemVec) {
|
||||
switch (type) {
|
||||
case '*':
|
||||
case '?':
|
||||
case '+':
|
||||
((ContentModel)content).getElements(elemVec);
|
||||
break;
|
||||
case ',':
|
||||
case '|':
|
||||
case '&':
|
||||
for (ContentModel m=(ContentModel)content; m != null; m=m.next){
|
||||
m.getElements(elemVec);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
elemVec.addElement((Element)content);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean valSet[];
|
||||
private boolean val[];
|
||||
// A cache used by first(). This cache was found to speed parsing
|
||||
// by about 10% (based on measurements of the 4-12 code base after
|
||||
// buffering was fixed).
|
||||
|
||||
/**
|
||||
* Return true if the token could potentially be the
|
||||
* first token in the input stream.
|
||||
*/
|
||||
public boolean first(Object token) {
|
||||
switch (type) {
|
||||
case '*':
|
||||
case '?':
|
||||
case '+':
|
||||
return ((ContentModel)content).first(token);
|
||||
|
||||
case ',':
|
||||
for (ContentModel m = (ContentModel)content ; m != null ; m = m.next) {
|
||||
if (m.first(token)) {
|
||||
return true;
|
||||
}
|
||||
if (!m.empty()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
case '|':
|
||||
case '&': {
|
||||
Element e = (Element) token;
|
||||
if (valSet == null || valSet.length <= Element.getMaxIndex()) {
|
||||
valSet = new boolean[Element.getMaxIndex() + 1];
|
||||
val = new boolean[valSet.length];
|
||||
}
|
||||
if (valSet[e.index]) {
|
||||
return val[e.index];
|
||||
}
|
||||
for (ContentModel m = (ContentModel)content ; m != null ; m = m.next) {
|
||||
if (m.first(token)) {
|
||||
val[e.index] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
valSet[e.index] = true;
|
||||
return val[e.index];
|
||||
}
|
||||
|
||||
default:
|
||||
return (content == token);
|
||||
// PENDING: refer to comment in ContentModelState
|
||||
/*
|
||||
if (content == token) {
|
||||
return true;
|
||||
}
|
||||
Element e = (Element)content;
|
||||
if (e.omitStart() && e.content != null) {
|
||||
return e.content.first(token);
|
||||
}
|
||||
return false;
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the element that must be next.
|
||||
*/
|
||||
public Element first() {
|
||||
switch (type) {
|
||||
case '&':
|
||||
case '|':
|
||||
case '*':
|
||||
case '?':
|
||||
return null;
|
||||
|
||||
case '+':
|
||||
case ',':
|
||||
return ((ContentModel)content).first();
|
||||
|
||||
default:
|
||||
return (Element)content;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert to a string.
|
||||
*/
|
||||
public String toString() {
|
||||
switch (type) {
|
||||
case '*':
|
||||
return content + "*";
|
||||
case '?':
|
||||
return content + "?";
|
||||
case '+':
|
||||
return content + "+";
|
||||
|
||||
case ',':
|
||||
case '|':
|
||||
case '&':
|
||||
char data[] = {' ', (char)type, ' '};
|
||||
String str = "";
|
||||
for (ContentModel m = (ContentModel)content ; m != null ; m = m.next) {
|
||||
str = str + m;
|
||||
if (m.next != null) {
|
||||
str += new String(data);
|
||||
}
|
||||
}
|
||||
return "(" + str + ")";
|
||||
|
||||
default:
|
||||
return content.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
295
jdkSrc/jdk8/javax/swing/text/html/parser/ContentModelState.java
Normal file
295
jdkSrc/jdk8/javax/swing/text/html/parser/ContentModelState.java
Normal file
@@ -0,0 +1,295 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2000, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.text.html.parser;
|
||||
|
||||
/**
|
||||
* A content model state. This is basically a list of pointers to
|
||||
* the BNF expression representing the model (the ContentModel).
|
||||
* Each element in a DTD has a content model which describes the
|
||||
* elements that may occur inside, and the order in which they can
|
||||
* occur.
|
||||
* <p>
|
||||
* Each time a token is reduced a new state is created.
|
||||
* <p>
|
||||
* See Annex H on page 556 of the SGML handbook for more information.
|
||||
*
|
||||
* @see Parser
|
||||
* @see DTD
|
||||
* @see Element
|
||||
* @see ContentModel
|
||||
* @author Arthur van Hoff
|
||||
*/
|
||||
class ContentModelState {
|
||||
ContentModel model;
|
||||
long value;
|
||||
ContentModelState next;
|
||||
|
||||
/**
|
||||
* Create a content model state for a content model.
|
||||
*/
|
||||
public ContentModelState(ContentModel model) {
|
||||
this(model, null, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a content model state for a content model given the
|
||||
* remaining state that needs to be reduce.
|
||||
*/
|
||||
ContentModelState(Object content, ContentModelState next) {
|
||||
this(content, next, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a content model state for a content model given the
|
||||
* remaining state that needs to be reduce.
|
||||
*/
|
||||
ContentModelState(Object content, ContentModelState next, long value) {
|
||||
this.model = (ContentModel)content;
|
||||
this.next = next;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the content model that is relevant to the current state.
|
||||
*/
|
||||
public ContentModel getModel() {
|
||||
ContentModel m = model;
|
||||
for (int i = 0; i < value; i++) {
|
||||
if (m.next != null) {
|
||||
m = m.next;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the state can be terminated. That is there are no more
|
||||
* tokens required in the input stream.
|
||||
* @return true if the model can terminate without further input
|
||||
*/
|
||||
public boolean terminate() {
|
||||
switch (model.type) {
|
||||
case '+':
|
||||
if ((value == 0) && !(model).empty()) {
|
||||
return false;
|
||||
}
|
||||
case '*':
|
||||
case '?':
|
||||
return (next == null) || next.terminate();
|
||||
|
||||
case '|':
|
||||
for (ContentModel m = (ContentModel)model.content ; m != null ; m = m.next) {
|
||||
if (m.empty()) {
|
||||
return (next == null) || next.terminate();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
case '&': {
|
||||
ContentModel m = (ContentModel)model.content;
|
||||
|
||||
for (int i = 0 ; m != null ; i++, m = m.next) {
|
||||
if ((value & (1L << i)) == 0) {
|
||||
if (!m.empty()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (next == null) || next.terminate();
|
||||
}
|
||||
|
||||
case ',': {
|
||||
ContentModel m = (ContentModel)model.content;
|
||||
for (int i = 0 ; i < value ; i++, m = m.next);
|
||||
|
||||
for (; (m != null) && m.empty() ; m = m.next);
|
||||
if (m != null) {
|
||||
return false;
|
||||
}
|
||||
return (next == null) || next.terminate();
|
||||
}
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the state can be terminated. That is there are no more
|
||||
* tokens required in the input stream.
|
||||
* @return the only possible element that can occur next
|
||||
*/
|
||||
public Element first() {
|
||||
switch (model.type) {
|
||||
case '*':
|
||||
case '?':
|
||||
case '|':
|
||||
case '&':
|
||||
return null;
|
||||
|
||||
case '+':
|
||||
return model.first();
|
||||
|
||||
case ',': {
|
||||
ContentModel m = (ContentModel)model.content;
|
||||
for (int i = 0 ; i < value ; i++, m = m.next);
|
||||
return m.first();
|
||||
}
|
||||
|
||||
default:
|
||||
return model.first();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Advance this state to a new state. An exception is thrown if the
|
||||
* token is illegal at this point in the content model.
|
||||
* @return next state after reducing a token
|
||||
*/
|
||||
public ContentModelState advance(Object token) {
|
||||
switch (model.type) {
|
||||
case '+':
|
||||
if (model.first(token)) {
|
||||
return new ContentModelState(model.content,
|
||||
new ContentModelState(model, next, value + 1)).advance(token);
|
||||
}
|
||||
if (value != 0) {
|
||||
if (next != null) {
|
||||
return next.advance(token);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case '*':
|
||||
if (model.first(token)) {
|
||||
return new ContentModelState(model.content, this).advance(token);
|
||||
}
|
||||
if (next != null) {
|
||||
return next.advance(token);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
case '?':
|
||||
if (model.first(token)) {
|
||||
return new ContentModelState(model.content, next).advance(token);
|
||||
}
|
||||
if (next != null) {
|
||||
return next.advance(token);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
case '|':
|
||||
for (ContentModel m = (ContentModel)model.content ; m != null ; m = m.next) {
|
||||
if (m.first(token)) {
|
||||
return new ContentModelState(m, next).advance(token);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ',': {
|
||||
ContentModel m = (ContentModel)model.content;
|
||||
for (int i = 0 ; i < value ; i++, m = m.next);
|
||||
|
||||
if (m.first(token) || m.empty()) {
|
||||
if (m.next == null) {
|
||||
return new ContentModelState(m, next).advance(token);
|
||||
} else {
|
||||
return new ContentModelState(m,
|
||||
new ContentModelState(model, next, value + 1)).advance(token);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case '&': {
|
||||
ContentModel m = (ContentModel)model.content;
|
||||
boolean complete = true;
|
||||
|
||||
for (int i = 0 ; m != null ; i++, m = m.next) {
|
||||
if ((value & (1L << i)) == 0) {
|
||||
if (m.first(token)) {
|
||||
return new ContentModelState(m,
|
||||
new ContentModelState(model, next, value | (1L << i))).advance(token);
|
||||
}
|
||||
if (!m.empty()) {
|
||||
complete = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (complete) {
|
||||
if (next != null) {
|
||||
return next.advance(token);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
if (model.content == token) {
|
||||
if (next == null && (token instanceof Element) &&
|
||||
((Element)token).content != null) {
|
||||
return new ContentModelState(((Element)token).content);
|
||||
}
|
||||
return next;
|
||||
}
|
||||
// PENDING: Currently we don't correctly deal with optional start
|
||||
// tags. This can most notably be seen with the 4.01 spec where
|
||||
// TBODY's start and end tags are optional.
|
||||
// Uncommenting this and the PENDING in ContentModel will
|
||||
// correctly skip the omit tags, but the delegate is not notified.
|
||||
// Some additional API needs to be added to track skipped tags,
|
||||
// and this can then be added back.
|
||||
/*
|
||||
if ((model.content instanceof Element)) {
|
||||
Element e = (Element)model.content;
|
||||
|
||||
if (e.omitStart() && e.content != null) {
|
||||
return new ContentModelState(e.content, next).advance(
|
||||
token);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// We used to throw this exception at this point. However, it
|
||||
// was determined that throwing this exception was more expensive
|
||||
// than returning null, and we could not justify to ourselves why
|
||||
// it was necessary to throw an exception, rather than simply
|
||||
// returning null. I'm leaving it in a commented out state so
|
||||
// that it can be easily restored if the situation ever arises.
|
||||
//
|
||||
// throw new IllegalArgumentException("invalid token: " + token);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
466
jdkSrc/jdk8/javax/swing/text/html/parser/DTD.java
Normal file
466
jdkSrc/jdk8/javax/swing/text/html/parser/DTD.java
Normal file
@@ -0,0 +1,466 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.text.html.parser;
|
||||
|
||||
import sun.awt.AppContext;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Vector;
|
||||
import java.util.BitSet;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Properties;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* The representation of an SGML DTD. DTD describes a document
|
||||
* syntax and is used in parsing of HTML documents. It contains
|
||||
* a list of elements and their attributes as well as a list of
|
||||
* entities defined in the DTD.
|
||||
*
|
||||
* @see Element
|
||||
* @see AttributeList
|
||||
* @see ContentModel
|
||||
* @see Parser
|
||||
* @author Arthur van Hoff
|
||||
*/
|
||||
public
|
||||
class DTD implements DTDConstants {
|
||||
public String name;
|
||||
public Vector<Element> elements = new Vector<Element>();
|
||||
public Hashtable<String,Element> elementHash
|
||||
= new Hashtable<String,Element>();
|
||||
public Hashtable<Object,Entity> entityHash
|
||||
= new Hashtable<Object,Entity>();
|
||||
public final Element pcdata = getElement("#pcdata");
|
||||
public final Element html = getElement("html");
|
||||
public final Element meta = getElement("meta");
|
||||
public final Element base = getElement("base");
|
||||
public final Element isindex = getElement("isindex");
|
||||
public final Element head = getElement("head");
|
||||
public final Element body = getElement("body");
|
||||
public final Element applet = getElement("applet");
|
||||
public final Element param = getElement("param");
|
||||
public final Element p = getElement("p");
|
||||
public final Element title = getElement("title");
|
||||
final Element style = getElement("style");
|
||||
final Element link = getElement("link");
|
||||
final Element script = getElement("script");
|
||||
|
||||
public static final int FILE_VERSION = 1;
|
||||
|
||||
/**
|
||||
* Creates a new DTD with the specified name.
|
||||
* @param name the name, as a <code>String</code> of the new DTD
|
||||
*/
|
||||
protected DTD(String name) {
|
||||
this.name = name;
|
||||
defEntity("#RE", GENERAL, '\r');
|
||||
defEntity("#RS", GENERAL, '\n');
|
||||
defEntity("#SPACE", GENERAL, ' ');
|
||||
defineElement("unknown", EMPTY, false, true, null, null, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the DTD.
|
||||
* @return the name of the DTD
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an entity by name.
|
||||
* @return the <code>Entity</code> corresponding to the
|
||||
* <code>name</code> <code>String</code>
|
||||
*/
|
||||
public Entity getEntity(String name) {
|
||||
return entityHash.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a character entity.
|
||||
* @return the <code>Entity</code> corresponding to the
|
||||
* <code>ch</code> character
|
||||
*/
|
||||
public Entity getEntity(int ch) {
|
||||
return entityHash.get(Integer.valueOf(ch));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the element is part of the DTD,
|
||||
* otherwise returns <code>false</code>.
|
||||
*
|
||||
* @param name the requested <code>String</code>
|
||||
* @return <code>true</code> if <code>name</code> exists as
|
||||
* part of the DTD, otherwise returns <code>false</code>
|
||||
*/
|
||||
boolean elementExists(String name) {
|
||||
return !"unknown".equals(name) && (elementHash.get(name) != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an element by name. A new element is
|
||||
* created if the element doesn't exist.
|
||||
*
|
||||
* @param name the requested <code>String</code>
|
||||
* @return the <code>Element</code> corresponding to
|
||||
* <code>name</code>, which may be newly created
|
||||
*/
|
||||
public Element getElement(String name) {
|
||||
Element e = elementHash.get(name);
|
||||
if (e == null) {
|
||||
e = new Element(name, elements.size());
|
||||
elements.addElement(e);
|
||||
elementHash.put(name, e);
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an element by index.
|
||||
*
|
||||
* @param index the requested index
|
||||
* @return the <code>Element</code> corresponding to
|
||||
* <code>index</code>
|
||||
*/
|
||||
public Element getElement(int index) {
|
||||
return elements.elementAt(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines an entity. If the <code>Entity</code> specified
|
||||
* by <code>name</code>, <code>type</code>, and <code>data</code>
|
||||
* exists, it is returned; otherwise a new <code>Entity</code>
|
||||
* is created and is returned.
|
||||
*
|
||||
* @param name the name of the <code>Entity</code> as a <code>String</code>
|
||||
* @param type the type of the <code>Entity</code>
|
||||
* @param data the <code>Entity</code>'s data
|
||||
* @return the <code>Entity</code> requested or a new <code>Entity</code>
|
||||
* if not found
|
||||
*/
|
||||
public Entity defineEntity(String name, int type, char data[]) {
|
||||
Entity ent = entityHash.get(name);
|
||||
if (ent == null) {
|
||||
ent = new Entity(name, type, data);
|
||||
entityHash.put(name, ent);
|
||||
if (((type & GENERAL) != 0) && (data.length == 1)) {
|
||||
switch (type & ~GENERAL) {
|
||||
case CDATA:
|
||||
case SDATA:
|
||||
entityHash.put(Integer.valueOf(data[0]), ent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>Element</code> which matches the
|
||||
* specified parameters. If one doesn't exist, a new
|
||||
* one is created and returned.
|
||||
*
|
||||
* @param name the name of the <code>Element</code>
|
||||
* @param type the type of the <code>Element</code>
|
||||
* @param omitStart <code>true</code> if start should be omitted
|
||||
* @param omitEnd <code>true</code> if end should be omitted
|
||||
* @param content the <code>ContentModel</code>
|
||||
* @param atts the <code>AttributeList</code> specifying the
|
||||
* <code>Element</code>
|
||||
* @return the <code>Element</code> specified
|
||||
*/
|
||||
public Element defineElement(String name, int type,
|
||||
boolean omitStart, boolean omitEnd, ContentModel content,
|
||||
BitSet exclusions, BitSet inclusions, AttributeList atts) {
|
||||
Element e = getElement(name);
|
||||
e.type = type;
|
||||
e.oStart = omitStart;
|
||||
e.oEnd = omitEnd;
|
||||
e.content = content;
|
||||
e.exclusions = exclusions;
|
||||
e.inclusions = inclusions;
|
||||
e.atts = atts;
|
||||
return e;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines attributes for an {@code Element}.
|
||||
*
|
||||
* @param name the name of the <code>Element</code>
|
||||
* @param atts the <code>AttributeList</code> specifying the
|
||||
* <code>Element</code>
|
||||
*/
|
||||
public void defineAttributes(String name, AttributeList atts) {
|
||||
Element e = getElement(name);
|
||||
e.atts = atts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns a character <code>Entity</code>.
|
||||
* @param name the entity's name
|
||||
* @return the new character <code>Entity</code>
|
||||
*/
|
||||
public Entity defEntity(String name, int type, int ch) {
|
||||
char data[] = {(char)ch};
|
||||
return defineEntity(name, type, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns an <code>Entity</code>.
|
||||
* @param name the entity's name
|
||||
* @return the new <code>Entity</code>
|
||||
*/
|
||||
protected Entity defEntity(String name, int type, String str) {
|
||||
int len = str.length();
|
||||
char data[] = new char[len];
|
||||
str.getChars(0, len, data, 0);
|
||||
return defineEntity(name, type, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns an <code>Element</code>.
|
||||
* @param name the element's name
|
||||
* @return the new <code>Element</code>
|
||||
*/
|
||||
protected Element defElement(String name, int type,
|
||||
boolean omitStart, boolean omitEnd, ContentModel content,
|
||||
String[] exclusions, String[] inclusions, AttributeList atts) {
|
||||
BitSet excl = null;
|
||||
if (exclusions != null && exclusions.length > 0) {
|
||||
excl = new BitSet();
|
||||
for (String str : exclusions) {
|
||||
if (str.length() > 0) {
|
||||
excl.set(getElement(str).getIndex());
|
||||
}
|
||||
}
|
||||
}
|
||||
BitSet incl = null;
|
||||
if (inclusions != null && inclusions.length > 0) {
|
||||
incl = new BitSet();
|
||||
for (String str : inclusions) {
|
||||
if (str.length() > 0) {
|
||||
incl.set(getElement(str).getIndex());
|
||||
}
|
||||
}
|
||||
}
|
||||
return defineElement(name, type, omitStart, omitEnd, content, excl, incl, atts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns an <code>AttributeList</code>.
|
||||
* @param name the attribute list's name
|
||||
* @return the new <code>AttributeList</code>
|
||||
*/
|
||||
protected AttributeList defAttributeList(String name, int type, int modifier, String value, String values, AttributeList atts) {
|
||||
Vector<String> vals = null;
|
||||
if (values != null) {
|
||||
vals = new Vector<String>();
|
||||
for (StringTokenizer s = new StringTokenizer(values, "|") ; s.hasMoreTokens() ;) {
|
||||
String str = s.nextToken();
|
||||
if (str.length() > 0) {
|
||||
vals.addElement(str);
|
||||
}
|
||||
}
|
||||
}
|
||||
return new AttributeList(name, type, modifier, value, vals, atts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns a new content model.
|
||||
* @param type the type of the new content model
|
||||
* @return the new <code>ContentModel</code>
|
||||
*/
|
||||
protected ContentModel defContentModel(int type, Object obj, ContentModel next) {
|
||||
return new ContentModel(type, obj, next);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this DTD.
|
||||
* @return the string representation of this DTD
|
||||
*/
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* The hashtable key of DTDs in AppContext.
|
||||
*/
|
||||
private static final Object DTD_HASH_KEY = new Object();
|
||||
|
||||
public static void putDTDHash(String name, DTD dtd) {
|
||||
getDtdHash().put(name, dtd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a DTD with the specified <code>name</code>. If
|
||||
* a DTD with that name doesn't exist, one is created
|
||||
* and returned. Any uppercase characters in the name
|
||||
* are converted to lowercase.
|
||||
*
|
||||
* @param name the name of the DTD
|
||||
* @return the DTD which corresponds to <code>name</code>
|
||||
*/
|
||||
public static DTD getDTD(String name) throws IOException {
|
||||
name = name.toLowerCase();
|
||||
DTD dtd = getDtdHash().get(name);
|
||||
if (dtd == null)
|
||||
dtd = new DTD(name);
|
||||
|
||||
return dtd;
|
||||
}
|
||||
|
||||
private static Hashtable<String, DTD> getDtdHash() {
|
||||
AppContext appContext = AppContext.getAppContext();
|
||||
|
||||
Hashtable<String, DTD> result = (Hashtable<String, DTD>) appContext.get(DTD_HASH_KEY);
|
||||
|
||||
if (result == null) {
|
||||
result = new Hashtable<String, DTD>();
|
||||
|
||||
appContext.put(DTD_HASH_KEY, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recreates a DTD from an archived format.
|
||||
* @param in the <code>DataInputStream</code> to read from
|
||||
*/
|
||||
public void read(DataInputStream in) throws IOException {
|
||||
if (in.readInt() != FILE_VERSION) {
|
||||
}
|
||||
|
||||
//
|
||||
// Read the list of names
|
||||
//
|
||||
String[] names = new String[in.readShort()];
|
||||
for (int i = 0; i < names.length; i++) {
|
||||
names[i] = in.readUTF();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Read the entities
|
||||
//
|
||||
int num = in.readShort();
|
||||
for (int i = 0; i < num; i++) {
|
||||
short nameId = in.readShort();
|
||||
int type = in.readByte();
|
||||
String name = in.readUTF();
|
||||
defEntity(names[nameId], type | GENERAL, name);
|
||||
}
|
||||
|
||||
// Read the elements
|
||||
//
|
||||
num = in.readShort();
|
||||
for (int i = 0; i < num; i++) {
|
||||
short nameId = in.readShort();
|
||||
int type = in.readByte();
|
||||
byte flags = in.readByte();
|
||||
ContentModel m = readContentModel(in, names);
|
||||
String[] exclusions = readNameArray(in, names);
|
||||
String[] inclusions = readNameArray(in, names);
|
||||
AttributeList atts = readAttributeList(in, names);
|
||||
defElement(names[nameId], type,
|
||||
((flags & 0x01) != 0), ((flags & 0x02) != 0),
|
||||
m, exclusions, inclusions, atts);
|
||||
}
|
||||
}
|
||||
|
||||
private ContentModel readContentModel(DataInputStream in, String[] names)
|
||||
throws IOException {
|
||||
byte flag = in.readByte();
|
||||
switch(flag) {
|
||||
case 0: // null
|
||||
return null;
|
||||
case 1: { // content_c
|
||||
int type = in.readByte();
|
||||
ContentModel m = readContentModel(in, names);
|
||||
ContentModel next = readContentModel(in, names);
|
||||
return defContentModel(type, m, next);
|
||||
}
|
||||
case 2: { // content_e
|
||||
int type = in.readByte();
|
||||
Element el = getElement(names[in.readShort()]);
|
||||
ContentModel next = readContentModel(in, names);
|
||||
return defContentModel(type, el, next);
|
||||
}
|
||||
default:
|
||||
throw new IOException("bad bdtd");
|
||||
}
|
||||
}
|
||||
|
||||
private String[] readNameArray(DataInputStream in, String[] names)
|
||||
throws IOException {
|
||||
int num = in.readShort();
|
||||
if (num == 0) {
|
||||
return null;
|
||||
}
|
||||
String[] result = new String[num];
|
||||
for (int i = 0; i < num; i++) {
|
||||
result[i] = names[in.readShort()];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private AttributeList readAttributeList(DataInputStream in, String[] names)
|
||||
throws IOException {
|
||||
AttributeList result = null;
|
||||
for (int num = in.readByte(); num > 0; --num) {
|
||||
short nameId = in.readShort();
|
||||
int type = in.readByte();
|
||||
int modifier = in.readByte();
|
||||
short valueId = in.readShort();
|
||||
String value = (valueId == -1) ? null : names[valueId];
|
||||
Vector<String> values = null;
|
||||
short numValues = in.readShort();
|
||||
if (numValues > 0) {
|
||||
values = new Vector<String>(numValues);
|
||||
for (int i = 0; i < numValues; i++) {
|
||||
values.addElement(names[in.readShort()]);
|
||||
}
|
||||
}
|
||||
result = new AttributeList(names[nameId], type, modifier, value,
|
||||
values, result);
|
||||
// We reverse the order of the linked list by doing this, but
|
||||
// that order isn't important.
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
82
jdkSrc/jdk8/javax/swing/text/html/parser/DTDConstants.java
Normal file
82
jdkSrc/jdk8/javax/swing/text/html/parser/DTDConstants.java
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 1999, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.text.html.parser;
|
||||
|
||||
/**
|
||||
* SGML constants used in a DTD. The names of the
|
||||
* constants correspond the the equivalent SGML constructs
|
||||
* as described in "The SGML Handbook" by Charles F. Goldfarb.
|
||||
*
|
||||
* @see DTD
|
||||
* @see Element
|
||||
* @author Arthur van Hoff
|
||||
*/
|
||||
public
|
||||
interface DTDConstants {
|
||||
// Attribute value types
|
||||
int CDATA = 1;
|
||||
int ENTITY = 2;
|
||||
int ENTITIES = 3;
|
||||
int ID = 4;
|
||||
int IDREF = 5;
|
||||
int IDREFS = 6;
|
||||
int NAME = 7;
|
||||
int NAMES = 8;
|
||||
int NMTOKEN = 9;
|
||||
int NMTOKENS = 10;
|
||||
int NOTATION = 11;
|
||||
int NUMBER = 12;
|
||||
int NUMBERS = 13;
|
||||
int NUTOKEN = 14;
|
||||
int NUTOKENS = 15;
|
||||
|
||||
// Content model types
|
||||
int RCDATA = 16;
|
||||
int EMPTY = 17;
|
||||
int MODEL = 18;
|
||||
int ANY = 19;
|
||||
|
||||
// Attribute value modifiers
|
||||
int FIXED = 1;
|
||||
int REQUIRED = 2;
|
||||
int CURRENT = 3;
|
||||
int CONREF = 4;
|
||||
int IMPLIED = 5;
|
||||
|
||||
// Entity types
|
||||
int PUBLIC = 10;
|
||||
int SDATA = 11;
|
||||
int PI = 12;
|
||||
int STARTTAG = 13;
|
||||
int ENDTAG = 14;
|
||||
int MS = 15;
|
||||
int MD = 16;
|
||||
int SYSTEM = 17;
|
||||
|
||||
int GENERAL = 1<<16;
|
||||
int DEFAULT = 1<<17;
|
||||
int PARAMETER = 1<<18;
|
||||
}
|
||||
281
jdkSrc/jdk8/javax/swing/text/html/parser/DocumentParser.java
Normal file
281
jdkSrc/jdk8/javax/swing/text/html/parser/DocumentParser.java
Normal file
@@ -0,0 +1,281 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.text.html.parser;
|
||||
|
||||
import javax.swing.text.SimpleAttributeSet;
|
||||
import javax.swing.text.html.HTMLEditorKit;
|
||||
import javax.swing.text.html.HTML;
|
||||
import javax.swing.text.ChangedCharSetException;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
|
||||
/**
|
||||
* A Parser for HTML Documents (actually, you can specify a DTD, but
|
||||
* you should really only use this class with the html dtd in swing).
|
||||
* Reads an InputStream of HTML and
|
||||
* invokes the appropriate methods in the ParserCallback class. This
|
||||
* is the default parser used by HTMLEditorKit to parse HTML url's.
|
||||
* <p>This will message the callback for all valid tags, as well as
|
||||
* tags that are implied but not explicitly specified. For example, the
|
||||
* html string (<p>blah) only has a p tag defined. The callback
|
||||
* will see the following methods:
|
||||
* <ol><li><i>handleStartTag(html, ...)</i></li>
|
||||
* <li><i>handleStartTag(head, ...)</i></li>
|
||||
* <li><i>handleEndTag(head)</i></li>
|
||||
* <li><i>handleStartTag(body, ...)</i></li>
|
||||
* <li><i>handleStartTag(p, ...)</i></li>
|
||||
* <li><i>handleText(...)</i></li>
|
||||
* <li><i>handleEndTag(p)</i></li>
|
||||
* <li><i>handleEndTag(body)</i></li>
|
||||
* <li><i>handleEndTag(html)</i></li>
|
||||
* </ol>
|
||||
* The items in <i>italic</i> are implied, that is, although they were not
|
||||
* explicitly specified, to be correct html they should have been present
|
||||
* (head isn't necessary, but it is still generated). For tags that
|
||||
* are implied, the AttributeSet argument will have a value of
|
||||
* <code>Boolean.TRUE</code> for the key
|
||||
* <code>HTMLEditorKit.ParserCallback.IMPLIED</code>.
|
||||
* <p>HTML.Attributes defines a type safe enumeration of html attributes.
|
||||
* If an attribute key of a tag is defined in HTML.Attribute, the
|
||||
* HTML.Attribute will be used as the key, otherwise a String will be used.
|
||||
* For example <p foo=bar class=neat> has two attributes. foo is
|
||||
* not defined in HTML.Attribute, where as class is, therefore the
|
||||
* AttributeSet will have two values in it, HTML.Attribute.CLASS with
|
||||
* a String value of 'neat' and the String key 'foo' with a String value of
|
||||
* 'bar'.
|
||||
* <p>The position argument will indicate the start of the tag, comment
|
||||
* or text. Similar to arrays, the first character in the stream has a
|
||||
* position of 0. For tags that are
|
||||
* implied the position will indicate
|
||||
* the location of the next encountered tag. In the first example,
|
||||
* the implied start body and html tags will have the same position as the
|
||||
* p tag, and the implied end p, html and body tags will all have the same
|
||||
* position.
|
||||
* <p>As html skips whitespace the position for text will be the position
|
||||
* of the first valid character, eg in the string '\n\n\nblah'
|
||||
* the text 'blah' will have a position of 3, the newlines are skipped.
|
||||
* <p>
|
||||
* For attributes that do not have a value, eg in the html
|
||||
* string <code><foo blah></code> the attribute <code>blah</code>
|
||||
* does not have a value, there are two possible values that will be
|
||||
* placed in the AttributeSet's value:
|
||||
* <ul>
|
||||
* <li>If the DTD does not contain an definition for the element, or the
|
||||
* definition does not have an explicit value then the value in the
|
||||
* AttributeSet will be <code>HTML.NULL_ATTRIBUTE_VALUE</code>.
|
||||
* <li>If the DTD contains an explicit value, as in:
|
||||
* <code><!ATTLIST OPTION selected (selected) #IMPLIED></code>
|
||||
* this value from the dtd (in this case selected) will be used.
|
||||
* </ul>
|
||||
* <p>
|
||||
* Once the stream has been parsed, the callback is notified of the most
|
||||
* likely end of line string. The end of line string will be one of
|
||||
* \n, \r or \r\n, which ever is encountered the most in parsing the
|
||||
* stream.
|
||||
*
|
||||
* @author Sunita Mani
|
||||
*/
|
||||
public class DocumentParser extends javax.swing.text.html.parser.Parser {
|
||||
|
||||
private int inbody;
|
||||
private int intitle;
|
||||
private int inhead;
|
||||
private int instyle;
|
||||
private int inscript;
|
||||
private boolean seentitle;
|
||||
private HTMLEditorKit.ParserCallback callback = null;
|
||||
private boolean ignoreCharSet = false;
|
||||
private static final boolean debugFlag = false;
|
||||
|
||||
public DocumentParser(DTD dtd) {
|
||||
super(dtd);
|
||||
}
|
||||
|
||||
public void parse(Reader in, HTMLEditorKit.ParserCallback callback, boolean ignoreCharSet) throws IOException {
|
||||
this.ignoreCharSet = ignoreCharSet;
|
||||
this.callback = callback;
|
||||
parse(in);
|
||||
// end of line
|
||||
callback.handleEndOfLineString(getEndOfLineString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle Start Tag.
|
||||
*/
|
||||
protected void handleStartTag(TagElement tag) {
|
||||
|
||||
Element elem = tag.getElement();
|
||||
if (elem == dtd.body) {
|
||||
inbody++;
|
||||
} else if (elem == dtd.html) {
|
||||
} else if (elem == dtd.head) {
|
||||
inhead++;
|
||||
} else if (elem == dtd.title) {
|
||||
intitle++;
|
||||
} else if (elem == dtd.style) {
|
||||
instyle++;
|
||||
} else if (elem == dtd.script) {
|
||||
inscript++;
|
||||
}
|
||||
if (debugFlag) {
|
||||
if (tag.fictional()) {
|
||||
debug("Start Tag: " + tag.getHTMLTag() + " pos: " + getCurrentPos());
|
||||
} else {
|
||||
debug("Start Tag: " + tag.getHTMLTag() + " attributes: " +
|
||||
getAttributes() + " pos: " + getCurrentPos());
|
||||
}
|
||||
}
|
||||
if (tag.fictional()) {
|
||||
SimpleAttributeSet attrs = new SimpleAttributeSet();
|
||||
attrs.addAttribute(HTMLEditorKit.ParserCallback.IMPLIED,
|
||||
Boolean.TRUE);
|
||||
callback.handleStartTag(tag.getHTMLTag(), attrs,
|
||||
getBlockStartPosition());
|
||||
} else {
|
||||
callback.handleStartTag(tag.getHTMLTag(), getAttributes(),
|
||||
getBlockStartPosition());
|
||||
flushAttributes();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void handleComment(char text[]) {
|
||||
if (debugFlag) {
|
||||
debug("comment: ->" + new String(text) + "<-"
|
||||
+ " pos: " + getCurrentPos());
|
||||
}
|
||||
callback.handleComment(text, getBlockStartPosition());
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle Empty Tag.
|
||||
*/
|
||||
protected void handleEmptyTag(TagElement tag) throws ChangedCharSetException {
|
||||
|
||||
Element elem = tag.getElement();
|
||||
if (elem == dtd.meta && !ignoreCharSet) {
|
||||
SimpleAttributeSet atts = getAttributes();
|
||||
if (atts != null) {
|
||||
String content = (String)atts.getAttribute(HTML.Attribute.CONTENT);
|
||||
if (content != null) {
|
||||
if ("content-type".equalsIgnoreCase((String)atts.getAttribute(HTML.Attribute.HTTPEQUIV))) {
|
||||
if (!content.equalsIgnoreCase("text/html") &&
|
||||
!content.equalsIgnoreCase("text/plain")) {
|
||||
throw new ChangedCharSetException(content, false);
|
||||
}
|
||||
} else if ("charset" .equalsIgnoreCase((String)atts.getAttribute(HTML.Attribute.HTTPEQUIV))) {
|
||||
throw new ChangedCharSetException(content, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (inbody != 0 || elem == dtd.meta || elem == dtd.base || elem == dtd.isindex || elem == dtd.style || elem == dtd.link) {
|
||||
if (debugFlag) {
|
||||
if (tag.fictional()) {
|
||||
debug("Empty Tag: " + tag.getHTMLTag() + " pos: " + getCurrentPos());
|
||||
} else {
|
||||
debug("Empty Tag: " + tag.getHTMLTag() + " attributes: "
|
||||
+ getAttributes() + " pos: " + getCurrentPos());
|
||||
}
|
||||
}
|
||||
if (tag.fictional()) {
|
||||
SimpleAttributeSet attrs = new SimpleAttributeSet();
|
||||
attrs.addAttribute(HTMLEditorKit.ParserCallback.IMPLIED,
|
||||
Boolean.TRUE);
|
||||
callback.handleSimpleTag(tag.getHTMLTag(), attrs,
|
||||
getBlockStartPosition());
|
||||
} else {
|
||||
callback.handleSimpleTag(tag.getHTMLTag(), getAttributes(),
|
||||
getBlockStartPosition());
|
||||
flushAttributes();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle End Tag.
|
||||
*/
|
||||
protected void handleEndTag(TagElement tag) {
|
||||
Element elem = tag.getElement();
|
||||
if (elem == dtd.body) {
|
||||
inbody--;
|
||||
} else if (elem == dtd.title) {
|
||||
intitle--;
|
||||
seentitle = true;
|
||||
} else if (elem == dtd.head) {
|
||||
inhead--;
|
||||
} else if (elem == dtd.style) {
|
||||
instyle--;
|
||||
} else if (elem == dtd.script) {
|
||||
inscript--;
|
||||
}
|
||||
if (debugFlag) {
|
||||
debug("End Tag: " + tag.getHTMLTag() + " pos: " + getCurrentPos());
|
||||
}
|
||||
callback.handleEndTag(tag.getHTMLTag(), getBlockStartPosition());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle Text.
|
||||
*/
|
||||
protected void handleText(char data[]) {
|
||||
if (data != null) {
|
||||
if (inscript != 0) {
|
||||
callback.handleComment(data, getBlockStartPosition());
|
||||
return;
|
||||
}
|
||||
if (inbody != 0 || ((instyle != 0) ||
|
||||
((intitle != 0) && !seentitle))) {
|
||||
if (debugFlag) {
|
||||
debug("text: ->" + new String(data) + "<-" + " pos: " + getCurrentPos());
|
||||
}
|
||||
callback.handleText(data, getBlockStartPosition());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Error handling.
|
||||
*/
|
||||
protected void handleError(int ln, String errorMsg) {
|
||||
if (debugFlag) {
|
||||
debug("Error: ->" + errorMsg + "<-" + " pos: " + getCurrentPos());
|
||||
}
|
||||
/* PENDING: need to improve the error string. */
|
||||
callback.handleError(errorMsg, getCurrentPos());
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* debug messages
|
||||
*/
|
||||
private void debug(String msg) {
|
||||
System.out.println(msg);
|
||||
}
|
||||
}
|
||||
185
jdkSrc/jdk8/javax/swing/text/html/parser/Element.java
Normal file
185
jdkSrc/jdk8/javax/swing/text/html/parser/Element.java
Normal file
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.text.html.parser;
|
||||
|
||||
import java.util.Hashtable;
|
||||
import java.util.BitSet;
|
||||
import java.io.*;
|
||||
import sun.awt.AppContext;
|
||||
|
||||
/**
|
||||
* An element as described in a DTD using the ELEMENT construct.
|
||||
* This is essential the description of a tag. It describes the
|
||||
* type, content model, attributes, attribute types etc. It is used
|
||||
* to correctly parse a document by the Parser.
|
||||
*
|
||||
* @see DTD
|
||||
* @see AttributeList
|
||||
* @author Arthur van Hoff
|
||||
*/
|
||||
public final
|
||||
class Element implements DTDConstants, Serializable {
|
||||
public int index;
|
||||
public String name;
|
||||
public boolean oStart;
|
||||
public boolean oEnd;
|
||||
public BitSet inclusions;
|
||||
public BitSet exclusions;
|
||||
public int type = ANY;
|
||||
public ContentModel content;
|
||||
public AttributeList atts;
|
||||
|
||||
/**
|
||||
* A field to store user data. Mostly used to store
|
||||
* style sheets.
|
||||
*/
|
||||
public Object data;
|
||||
|
||||
Element() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new element.
|
||||
*/
|
||||
Element(String name, int index) {
|
||||
this.name = name;
|
||||
this.index = index;
|
||||
if (index > getMaxIndex()) {
|
||||
AppContext.getAppContext().put(MAX_INDEX_KEY, index);
|
||||
}
|
||||
}
|
||||
|
||||
private static final Object MAX_INDEX_KEY = new Object();
|
||||
|
||||
static int getMaxIndex() {
|
||||
Integer value = (Integer) AppContext.getAppContext().get(MAX_INDEX_KEY);
|
||||
return (value != null)
|
||||
? value.intValue()
|
||||
: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the element.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the start tag can be omitted.
|
||||
*/
|
||||
public boolean omitStart() {
|
||||
return oStart;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the end tag can be omitted.
|
||||
*/
|
||||
public boolean omitEnd() {
|
||||
return oEnd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get type.
|
||||
*/
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get content model
|
||||
*/
|
||||
public ContentModel getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attributes.
|
||||
*/
|
||||
public AttributeList getAttributes() {
|
||||
return atts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get index.
|
||||
*/
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if empty
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return type == EMPTY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert to a string.
|
||||
*/
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an attribute by name.
|
||||
*/
|
||||
public AttributeList getAttribute(String name) {
|
||||
for (AttributeList a = atts ; a != null ; a = a.next) {
|
||||
if (a.name.equals(name)) {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an attribute by value.
|
||||
*/
|
||||
public AttributeList getAttributeByValue(String name) {
|
||||
for (AttributeList a = atts ; a != null ; a = a.next) {
|
||||
if ((a.values != null) && a.values.contains(name)) {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
static Hashtable<String, Integer> contentTypes = new Hashtable<String, Integer>();
|
||||
|
||||
static {
|
||||
contentTypes.put("CDATA", Integer.valueOf(CDATA));
|
||||
contentTypes.put("RCDATA", Integer.valueOf(RCDATA));
|
||||
contentTypes.put("EMPTY", Integer.valueOf(EMPTY));
|
||||
contentTypes.put("ANY", Integer.valueOf(ANY));
|
||||
}
|
||||
|
||||
public static int name2type(String nm) {
|
||||
Integer val = contentTypes.get(nm);
|
||||
return (val != null) ? val.intValue() : 0;
|
||||
}
|
||||
}
|
||||
139
jdkSrc/jdk8/javax/swing/text/html/parser/Entity.java
Normal file
139
jdkSrc/jdk8/javax/swing/text/html/parser/Entity.java
Normal file
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.text.html.parser;
|
||||
|
||||
import java.util.Hashtable;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.io.CharArrayReader;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* An entity is described in a DTD using the ENTITY construct.
|
||||
* It defines the type and value of the the entity.
|
||||
*
|
||||
* @see DTD
|
||||
* @author Arthur van Hoff
|
||||
*/
|
||||
public final
|
||||
class Entity implements DTDConstants {
|
||||
public String name;
|
||||
public int type;
|
||||
public char data[];
|
||||
|
||||
/**
|
||||
* Creates an entity.
|
||||
* @param name the name of the entity
|
||||
* @param type the type of the entity
|
||||
* @param data the char array of data
|
||||
*/
|
||||
public Entity(String name, int type, char data[]) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the entity.
|
||||
* @return the name of the entity, as a <code>String</code>
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type of the entity.
|
||||
* @return the type of the entity
|
||||
*/
|
||||
public int getType() {
|
||||
return type & 0xFFFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if it is a parameter entity.
|
||||
* @return <code>true</code> if it is a parameter entity
|
||||
*/
|
||||
public boolean isParameter() {
|
||||
return (type & PARAMETER) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if it is a general entity.
|
||||
* @return <code>true</code> if it is a general entity
|
||||
*/
|
||||
public boolean isGeneral() {
|
||||
return (type & GENERAL) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>data</code>.
|
||||
* @return the <code>data</code>
|
||||
*/
|
||||
public char getData()[] {
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data as a <code>String</code>.
|
||||
* @return the data as a <code>String</code>
|
||||
*/
|
||||
public String getString() {
|
||||
return new String(data, 0, data.length);
|
||||
}
|
||||
|
||||
|
||||
static Hashtable<String, Integer> entityTypes = new Hashtable<String, Integer>();
|
||||
|
||||
static {
|
||||
entityTypes.put("PUBLIC", Integer.valueOf(PUBLIC));
|
||||
entityTypes.put("CDATA", Integer.valueOf(CDATA));
|
||||
entityTypes.put("SDATA", Integer.valueOf(SDATA));
|
||||
entityTypes.put("PI", Integer.valueOf(PI));
|
||||
entityTypes.put("STARTTAG", Integer.valueOf(STARTTAG));
|
||||
entityTypes.put("ENDTAG", Integer.valueOf(ENDTAG));
|
||||
entityTypes.put("MS", Integer.valueOf(MS));
|
||||
entityTypes.put("MD", Integer.valueOf(MD));
|
||||
entityTypes.put("SYSTEM", Integer.valueOf(SYSTEM));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts <code>nm</code> string to the corresponding
|
||||
* entity type. If the string does not have a corresponding
|
||||
* entity type, returns the type corresponding to "CDATA".
|
||||
* Valid entity types are: "PUBLIC", "CDATA", "SDATA", "PI",
|
||||
* "STARTTAG", "ENDTAG", "MS", "MD", "SYSTEM".
|
||||
*
|
||||
* @param nm the string to be converted
|
||||
* @return the corresponding entity type, or the type corresponding
|
||||
* to "CDATA", if none exists
|
||||
*/
|
||||
public static int name2type(String nm) {
|
||||
Integer i = entityTypes.get(nm);
|
||||
return (i == null) ? CDATA : i.intValue();
|
||||
}
|
||||
}
|
||||
2353
jdkSrc/jdk8/javax/swing/text/html/parser/Parser.java
Normal file
2353
jdkSrc/jdk8/javax/swing/text/html/parser/Parser.java
Normal file
File diff suppressed because it is too large
Load Diff
129
jdkSrc/jdk8/javax/swing/text/html/parser/ParserDelegator.java
Normal file
129
jdkSrc/jdk8/javax/swing/text/html/parser/ParserDelegator.java
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package javax.swing.text.html.parser;
|
||||
|
||||
import sun.awt.AppContext;
|
||||
|
||||
import javax.swing.text.html.HTMLEditorKit;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.Reader;
|
||||
import java.io.Serializable;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
/**
|
||||
* Responsible for starting up a new DocumentParser
|
||||
* each time its parse method is invoked. Stores a
|
||||
* reference to the dtd.
|
||||
*
|
||||
* @author Sunita Mani
|
||||
*/
|
||||
|
||||
public class ParserDelegator extends HTMLEditorKit.Parser implements Serializable {
|
||||
|
||||
private static final Object DTD_KEY = new Object();
|
||||
|
||||
protected static void setDefaultDTD() {
|
||||
getDefaultDTD();
|
||||
}
|
||||
|
||||
private static synchronized DTD getDefaultDTD() {
|
||||
AppContext appContext = AppContext.getAppContext();
|
||||
|
||||
DTD dtd = (DTD) appContext.get(DTD_KEY);
|
||||
|
||||
if (dtd == null) {
|
||||
DTD _dtd = null;
|
||||
// (PENDING) Hate having to hard code!
|
||||
String nm = "html32";
|
||||
try {
|
||||
_dtd = DTD.getDTD(nm);
|
||||
} catch (IOException e) {
|
||||
// (PENDING) UGLY!
|
||||
System.out.println("Throw an exception: could not get default dtd: " + nm);
|
||||
}
|
||||
dtd = createDTD(_dtd, nm);
|
||||
|
||||
appContext.put(DTD_KEY, dtd);
|
||||
}
|
||||
|
||||
return dtd;
|
||||
}
|
||||
|
||||
protected static DTD createDTD(DTD dtd, String name) {
|
||||
|
||||
InputStream in = null;
|
||||
boolean debug = true;
|
||||
try {
|
||||
String path = name + ".bdtd";
|
||||
in = getResourceAsStream(path);
|
||||
if (in != null) {
|
||||
dtd.read(new DataInputStream(new BufferedInputStream(in)));
|
||||
dtd.putDTDHash(name, dtd);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println(e);
|
||||
}
|
||||
return dtd;
|
||||
}
|
||||
|
||||
|
||||
public ParserDelegator() {
|
||||
setDefaultDTD();
|
||||
}
|
||||
|
||||
public void parse(Reader r, HTMLEditorKit.ParserCallback cb, boolean ignoreCharSet) throws IOException {
|
||||
new DocumentParser(getDefaultDTD()).parse(r, cb, ignoreCharSet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a resource relative to the ParserDelegator classfile.
|
||||
* If this is called on 1.2 the loading will occur under the
|
||||
* protection of a doPrivileged call to allow the ParserDelegator
|
||||
* to function when used in an applet.
|
||||
*
|
||||
* @param name the name of the resource, relative to the
|
||||
* ParserDelegator class.
|
||||
* @returns a stream representing the resource
|
||||
*/
|
||||
static InputStream getResourceAsStream(final String name) {
|
||||
return AccessController.doPrivileged(
|
||||
new PrivilegedAction<InputStream>() {
|
||||
public InputStream run() {
|
||||
return ParserDelegator.class.getResourceAsStream(name);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream s)
|
||||
throws ClassNotFoundException, IOException {
|
||||
s.defaultReadObject();
|
||||
setDefaultDTD();
|
||||
}
|
||||
}
|
||||
74
jdkSrc/jdk8/javax/swing/text/html/parser/TagElement.java
Normal file
74
jdkSrc/jdk8/javax/swing/text/html/parser/TagElement.java
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.text.html.parser;
|
||||
|
||||
import javax.swing.text.html.HTML;
|
||||
/**
|
||||
* A generic HTML TagElement class. The methods define how white
|
||||
* space is interpreted around the tag.
|
||||
*
|
||||
* @author Sunita Mani
|
||||
*/
|
||||
|
||||
public class TagElement {
|
||||
|
||||
Element elem;
|
||||
HTML.Tag htmlTag;
|
||||
boolean insertedByErrorRecovery;
|
||||
|
||||
public TagElement ( Element elem ) {
|
||||
this(elem, false);
|
||||
}
|
||||
|
||||
public TagElement (Element elem, boolean fictional) {
|
||||
this.elem = elem;
|
||||
htmlTag = HTML.getTag(elem.getName());
|
||||
if (htmlTag == null) {
|
||||
htmlTag = new HTML.UnknownTag(elem.getName());
|
||||
}
|
||||
insertedByErrorRecovery = fictional;
|
||||
}
|
||||
|
||||
public boolean breaksFlow() {
|
||||
return htmlTag.breaksFlow();
|
||||
}
|
||||
|
||||
public boolean isPreformatted() {
|
||||
return htmlTag.isPreformatted();
|
||||
}
|
||||
|
||||
public Element getElement() {
|
||||
return elem;
|
||||
}
|
||||
|
||||
public HTML.Tag getHTMLTag() {
|
||||
return htmlTag;
|
||||
}
|
||||
|
||||
public boolean fictional() {
|
||||
return insertedByErrorRecovery;
|
||||
}
|
||||
}
|
||||
204
jdkSrc/jdk8/javax/swing/text/html/parser/TagStack.java
Normal file
204
jdkSrc/jdk8/javax/swing/text/html/parser/TagStack.java
Normal file
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.swing.text.html.parser;
|
||||
|
||||
import java.util.BitSet;
|
||||
import java.util.Vector;
|
||||
import java.io.*;
|
||||
|
||||
|
||||
/**
|
||||
* A stack of tags. Used while parsing an HTML document.
|
||||
* It, together with the ContentModelStates, defines the
|
||||
* complete state of the parser while reading a document.
|
||||
* When a start tag is encountered an element is pushed onto
|
||||
* the stack, when an end tag is enountered an element is popped
|
||||
* of the stack.
|
||||
*
|
||||
* @see Parser
|
||||
* @see DTD
|
||||
* @see ContentModelState
|
||||
* @author Arthur van Hoff
|
||||
*/
|
||||
final
|
||||
class TagStack implements DTDConstants {
|
||||
TagElement tag;
|
||||
Element elem;
|
||||
ContentModelState state;
|
||||
TagStack next;
|
||||
BitSet inclusions;
|
||||
BitSet exclusions;
|
||||
boolean net;
|
||||
boolean pre;
|
||||
|
||||
/**
|
||||
* Construct a stack element.
|
||||
*/
|
||||
TagStack(TagElement tag, TagStack next) {
|
||||
this.tag = tag;
|
||||
this.elem = tag.getElement();
|
||||
this.next = next;
|
||||
|
||||
Element elem = tag.getElement();
|
||||
if (elem.getContent() != null) {
|
||||
this.state = new ContentModelState(elem.getContent());
|
||||
}
|
||||
|
||||
if (next != null) {
|
||||
inclusions = next.inclusions;
|
||||
exclusions = next.exclusions;
|
||||
pre = next.pre;
|
||||
}
|
||||
if (tag.isPreformatted()) {
|
||||
pre = true;
|
||||
}
|
||||
|
||||
if (elem.inclusions != null) {
|
||||
if (inclusions != null) {
|
||||
inclusions = (BitSet)inclusions.clone();
|
||||
inclusions.or(elem.inclusions);
|
||||
} else {
|
||||
inclusions = elem.inclusions;
|
||||
}
|
||||
}
|
||||
if (elem.exclusions != null) {
|
||||
if (exclusions != null) {
|
||||
exclusions = (BitSet)exclusions.clone();
|
||||
exclusions.or(elem.exclusions);
|
||||
} else {
|
||||
exclusions = elem.exclusions;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the element that must come next in the
|
||||
* input stream.
|
||||
*/
|
||||
public Element first() {
|
||||
return (state != null) ? state.first() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the ContentModel that must be satisfied by
|
||||
* what comes next in the input stream.
|
||||
*/
|
||||
public ContentModel contentModel() {
|
||||
if (state == null) {
|
||||
return null;
|
||||
} else {
|
||||
return state.getModel();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the element that is contained at
|
||||
* the index specified by the parameter is part of
|
||||
* the exclusions specified in the DTD for the element
|
||||
* currently on the TagStack.
|
||||
*/
|
||||
boolean excluded(int elemIndex) {
|
||||
return (exclusions != null) && exclusions.get(elem.getIndex());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Advance the state by reducing the given element.
|
||||
* Returns false if the element is not legal and the
|
||||
* state is not advanced.
|
||||
*/
|
||||
boolean advance(Element elem) {
|
||||
if ((exclusions != null) && exclusions.get(elem.getIndex())) {
|
||||
return false;
|
||||
}
|
||||
if (state != null) {
|
||||
ContentModelState newState = state.advance(elem);
|
||||
if (newState != null) {
|
||||
state = newState;
|
||||
return true;
|
||||
}
|
||||
} else if (this.elem.getType() == ANY) {
|
||||
return true;
|
||||
}
|
||||
return (inclusions != null) && inclusions.get(elem.getIndex());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the current state can be terminated.
|
||||
*/
|
||||
boolean terminate() {
|
||||
return (state == null) || state.terminate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert to a string.
|
||||
*/
|
||||
public String toString() {
|
||||
return (next == null) ?
|
||||
"<" + tag.getElement().getName() + ">" :
|
||||
next + " <" + tag.getElement().getName() + ">";
|
||||
}
|
||||
}
|
||||
|
||||
class NPrintWriter extends PrintWriter {
|
||||
|
||||
private int numLines = 5;
|
||||
private int numPrinted = 0;
|
||||
|
||||
public NPrintWriter (int numberOfLines) {
|
||||
super(System.out);
|
||||
numLines = numberOfLines;
|
||||
}
|
||||
|
||||
public void println(char[] array) {
|
||||
if (numPrinted >= numLines) {
|
||||
return;
|
||||
}
|
||||
|
||||
char[] partialArray = null;
|
||||
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
if (array[i] == '\n') {
|
||||
numPrinted++;
|
||||
}
|
||||
|
||||
if (numPrinted == numLines) {
|
||||
System.arraycopy(array, 0, partialArray, 0, i);
|
||||
}
|
||||
}
|
||||
|
||||
if (partialArray != null) {
|
||||
super.print(partialArray);
|
||||
}
|
||||
|
||||
if (numPrinted == numLines) {
|
||||
return;
|
||||
}
|
||||
|
||||
super.println(array);
|
||||
numPrinted++;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user