You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by ml...@apache.org on 2006/07/31 16:08:55 UTC
svn commit: r427121 [9/29] - in
/incubator/harmony/enhanced/classlib/trunk/modules/swing: make/
src/main/java/common/javax/swing/ src/main/java/common/javax/swing/text/
src/main/java/common/javax/swing/text/html/
src/main/java/common/javax/swing/text/h...
Added: incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/TableTagView.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/TableTagView.java?rev=427121&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/TableTagView.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/TableTagView.java Mon Jul 31 07:08:47 2006
@@ -0,0 +1,514 @@
+/*
+ * Copyright 2005 - 2006 The Apache Software Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @author Vadim L. Bogdanov
+ * @version $Revision$
+ */
+package javax.swing.text.html;
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.util.BitSet;
+
+import javax.swing.SizeRequirements;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentEvent.ElementChange;
+import javax.swing.text.AttributeSet;
+import javax.swing.text.BoxView;
+import javax.swing.text.Element;
+import javax.swing.text.SimpleAttributeSet;
+import javax.swing.text.View;
+import javax.swing.text.ViewFactory;
+import javax.swing.text.html.CSS.FloatValue;
+
+import org.apache.harmony.x.swing.Utilities;
+
+class TableTagView extends BlockView implements ViewFactory {
+ private int[] columnWidths = new int[5];
+ private AttributeSet cachedAttributes;
+ private boolean areColumnSizeRequirementsValid;
+ private SizeRequirements[] columnSizeRequirements = new SizeRequirements[5];
+
+ private class TableRowView extends BlockView {
+ private BitSet isColumnOccupied = new BitSet(16);
+
+ public TableRowView(final Element elem) {
+ super(elem, X_AXIS);
+ }
+
+ protected SizeRequirements calculateMajorAxisRequirements(final int axis,
+ final SizeRequirements r) {
+ SizeRequirements size = r == null ? new SizeRequirements() : r;
+ SizeRequirements[] widths = calculateColumnSizeRequirements();
+ size.minimum = 0;
+ size.preferred = 0;
+ for (int i = 0; i < getColumnCount(); i++) {
+ size.minimum += widths[i].minimum;
+ size.preferred += widths[i].preferred;
+ size.maximum = Utilities.safeIntSum(size.maximum, widths[i].maximum);
+ }
+ return size;
+ }
+
+ protected SizeRequirements calculateMinorAxisRequirements(
+ int axis, SizeRequirements r) {
+ SizeRequirements size = super.calculateMinorAxisRequirements(axis, r);
+ size.maximum = size.preferred;
+ return size;
+ }
+
+ protected void layoutMajorAxis(final int targetSpan, final int axis,
+ final int[] offsets, final int[] spans) {
+ int[] widths = getColumnWidths();
+
+ int currentOffset = 0;
+ int widthsIndex = 0;
+ for (int i = 0; i < spans.length; i++) {
+ // take row spans of cells on previous rows into account
+ for (int j = 0; isColumnOccupied.get(widthsIndex + j); j++) {
+ currentOffset += widths[widthsIndex + j];
+ widthsIndex++;
+ }
+
+ offsets[i] = currentOffset;
+ int colSpan = getColumnSpan(i);
+ spans[i] = 0;
+ for (int j = 0; j < colSpan; j++) {
+ spans[i] += widths[widthsIndex + j];
+ }
+ widthsIndex += colSpan;
+ currentOffset += spans[i];
+ }
+ }
+
+ protected void layoutMinorAxis(int targetSpan, int axis,
+ int[] offsets, int[] spans) {
+ for (int viewIndex = 0; viewIndex < getViewCount(); viewIndex++) {
+ int rowSpan = getRowSpan(getView(viewIndex));
+ offsets[viewIndex] = 0;
+ if (rowSpan == 1) {
+ spans[viewIndex] = (int)getView(viewIndex).getPreferredSpan(axis);
+ } else {
+ spans[viewIndex] = targetSpan;
+ }
+ }
+ }
+
+ public int getColumnSpan(final int viewIndex) {
+ String strSpan = (String)getView(viewIndex).getElement().getAttributes()
+ .getAttribute(HTML.Attribute.COLSPAN);
+ return strSpan == null ? 1 : Integer.parseInt(strSpan);
+ }
+
+ public int getMaxRowSpan() {
+ int maxRowSpan = 1;
+ for (int viewIndex = 0; viewIndex < getViewCount(); viewIndex++) {
+ maxRowSpan = Math.max(maxRowSpan, getRowSpan(getView(viewIndex)));
+ }
+
+ return maxRowSpan;
+ }
+
+ private int getRowSpan(final View v) {
+ String strSpan = (String)v.getElement().getAttributes()
+ .getAttribute(HTML.Attribute.ROWSPAN);
+ return strSpan == null ? 1 : Integer.parseInt(strSpan);
+ }
+
+ public int getColumnCount() {
+ int count = 0;
+ for (int i = 0; i < getViewCount(); i++) {
+ count += getColumnSpan(i);
+ }
+ count += isColumnOccupied.cardinality();
+ return count;
+ }
+
+ public void setColumnOccupied(final int column) {
+ isColumnOccupied.set(column);
+ }
+
+ public boolean isColumnOccupied(final int column) {
+ return isColumnOccupied.get(column);
+ }
+
+ public int[] updateRowMarkup(final int[] prevRowRowSpans) {
+ isColumnOccupied.clear();
+
+ int col = 0;
+ int[] spans = prevRowRowSpans;
+ for (int viewIndex = 0; viewIndex < getViewCount(); viewIndex++) {
+ spans = enshureCapacity(spans, col + 1);
+ boolean occupied = spans[col] > 0;
+ if (occupied) {
+ setColumnOccupied(col);
+ spans[col]--;
+ } else {
+ int rowSpan = getRowSpan(getView(viewIndex));
+ int colSpan = getColumnSpan(viewIndex);
+ enshureCapacity(spans, col + colSpan);
+ for (; colSpan > 0; colSpan--) {
+ if (rowSpan > 1) {
+ spans[col] = rowSpan - 1;
+ }
+ }
+ }
+
+ col++;
+ }
+
+ return spans;
+ }
+
+ private int[] enshureCapacity(final int[] arr, final int len) {
+ if (len > arr.length) {
+ int[] newArr = new int[len + 16];
+ System.arraycopy(arr, 0, newArr, 0, arr.length);
+ return newArr;
+ }
+ return arr;
+ }
+ }
+
+ private class TableCellView extends BlockView {
+ private AttributeSet attrs;
+
+ public TableCellView(final Element elem) {
+ super(elem, Y_AXIS);
+ }
+
+ public AttributeSet getAttributes() {
+ if (attrs == null) {
+ attrs = new CompositeAttributeSet(
+ super.getAttributes(), getAdditionalCellAttrs());
+ }
+ return attrs;
+ }
+
+ public void changedUpdate(final DocumentEvent e, final Shape s,
+ final ViewFactory f) {
+ attrs = null;
+ super.changedUpdate(e, s, f);
+ }
+ }
+
+ // THEAD, TFOOT, TBODY are not supported
+ private static class RowViewIterator {
+ private View currentParent;
+ private TableRowView currentRowView;
+ private int currentIndex;
+
+ public RowViewIterator(final View root) {
+ currentParent = root;
+ next();
+ }
+
+ public boolean isValid() {
+ return currentRowView != null;
+ }
+
+ public void next() {
+ while (currentIndex < currentParent.getViewCount()) {
+ if (currentParent.getView(currentIndex) instanceof TableRowView) {
+ currentRowView = (TableRowView)currentParent.getView(currentIndex);
+ currentIndex++;
+ return;
+ }
+ currentIndex++;
+ }
+
+ if (currentIndex >= currentParent.getViewCount()) {
+ currentRowView = null;
+ }
+ }
+
+ public TableRowView getView() {
+ return currentRowView;
+ }
+ }
+
+ public TableTagView(final Element elem) {
+ super(elem, Y_AXIS);
+ }
+
+ public View create(final Element elem) {
+ HTML.Tag tag = HTMLEditorKit.getHTMLTagByElement(elem);
+
+ if (HTML.Tag.TR.equals(tag)) {
+ return createTableRow(elem);
+ } else if (HTML.Tag.TD.equals(tag) || HTML.Tag.TH.equals(tag)) {
+ return createTableCell(elem);
+ } else if (HTML.Tag.CAPTION.equals(tag)) {
+ return new BlockView(elem, BlockView.Y_AXIS);
+ } else if (HTML.Tag.COLGROUP.equals(tag)) {
+ return new InvisibleTagView(elem);
+ } else if (HTML.Tag.COL.equals(tag)) {
+ return new InvisibleTagView(elem);
+ }
+
+ return super.getViewFactory().create(elem);
+ }
+
+ public void changedUpdate(final DocumentEvent e, final Shape s,
+ final ViewFactory f) {
+ cachedAttributes = null;
+ super.changedUpdate(e, s, f);
+ }
+
+ public AttributeSet getAttributes() {
+ if (cachedAttributes == null) {
+ cachedAttributes = new CompositeAttributeSet(
+ super.getAttributes(), getAdditionalTableAttrs());
+ }
+
+ return cachedAttributes;
+ }
+
+ public ViewFactory getViewFactory() {
+ return this;
+ }
+
+ public void preferenceChanged(View child, boolean width, boolean height) {
+ areColumnSizeRequirementsValid = false;
+
+ super.preferenceChanged(this, width, height);
+
+ for (int i = 0; i < getViewCount(); i++) {
+ if (getView(i) instanceof BoxView) {
+ ((BoxView)getView(i)).layoutChanged(X_AXIS);
+ }
+ }
+ }
+
+ protected void layoutMajorAxis(int targetSpan, int axis, int[] offsets, int[] spans) {
+ super.layoutMajorAxis(targetSpan, axis, offsets, spans);
+ int row = 0;
+
+ for (RowViewIterator rowIt = new RowViewIterator(this); rowIt.isValid();
+ rowIt.next()) {
+ int maxRowSpan = rowIt.getView().getMaxRowSpan();
+ maxRowSpan = Math.min(maxRowSpan - 1, spans.length - row);
+ for (; maxRowSpan > 0; maxRowSpan--) {
+ spans[row] += spans[row + maxRowSpan];
+ }
+
+ row++;
+ }
+ }
+
+ protected void forwardUpdate(ElementChange change, DocumentEvent event, Shape shape, ViewFactory factory) {
+ boolean xValid = isLayoutValid(X_AXIS);
+
+ super.forwardUpdate(change, event, shape, factory);
+
+ if (xValid && !isLayoutValid(X_AXIS)) {
+ Rectangle rc = shape.getBounds();
+ getContainer().repaint(rc.x, rc.y, ((BoxView)getParent()).getWidth(), rc.height);
+ }
+ }
+
+ protected TableRowView createTableRow(final Element elem) {
+ return new TableRowView(elem);
+ }
+
+ protected TableCellView createTableCell(final Element elem) {
+ return new TableCellView(elem);
+ }
+
+ protected SizeRequirements calculateMajorAxisRequirements(
+ final int axis, final SizeRequirements r) {
+ SizeRequirements size = super.calculateMajorAxisRequirements(axis, r);
+ size.maximum = size.preferred;
+ return size;
+ }
+
+ protected SizeRequirements calculateMinorAxisRequirements(
+ final int axis, final SizeRequirements r) {
+ areColumnSizeRequirementsValid = isLayoutValid(X_AXIS);
+ SizeRequirements size = super.calculateMinorAxisRequirements(axis, r);
+ size.maximum = size.preferred;
+ return size;
+ }
+
+ int getCaptionHeight() {
+ View captionView = getView(0);
+ if (captionView != null && HTML.Tag.CAPTION.equals
+ (HTMLEditorKit.getHTMLTagByElement(captionView.getElement()))) {
+ return (int)captionView.getPreferredSpan(Y_AXIS);
+ }
+ return 0;
+ }
+
+ private int getColumnCount() {
+ if (!areColumnSizeRequirementsValid) {
+ updateRowViewColumnOccupied();
+ }
+
+ int count = 0;
+ for (RowViewIterator rowIt = new RowViewIterator(this);
+ rowIt.isValid(); rowIt.next()) {
+ count = Math.max(count, rowIt.getView().getColumnCount());
+ }
+ return count;
+ }
+
+ private void updateRowViewColumnOccupied() {
+ int[] rowSpans = new int[1];
+
+ for (RowViewIterator rowIt = new RowViewIterator(this); rowIt.isValid();
+ rowIt.next()) {
+ rowSpans = rowIt.getView().updateRowMarkup(rowSpans);
+ }
+ }
+
+ /*
+ * This function is based on the autolayout algorithm described here:
+ * http://www.w3.org/TR/html4/appendix/notes.html#h-B.5.2
+ */
+ private int[] getColumnWidths() {
+// if (isLayoutValid(X_AXIS)) {
+// return columnWidths;
+// }
+
+ int columnCount = getColumnCount();
+ if (columnCount > columnWidths.length) {
+ columnWidths = new int[columnCount];
+ }
+
+ SizeRequirements[] sizes = calculateColumnSizeRequirements();
+ int minTableWidth = 0;
+ int maxTableWidth = 0;
+ for (int col = 0; col < getColumnCount(); col++) {
+ columnWidths[col] = sizes[col].minimum;
+ minTableWidth += columnWidths[col];
+ maxTableWidth += sizes[col].maximum;
+ }
+
+ int delta = maxTableWidth - minTableWidth;
+
+ if (delta > 0) {
+ for (int col = 0; col < getColumnCount(); col++) {
+ columnWidths[col] += (double)(sizes[col].maximum - columnWidths[col])
+ / (double)delta
+ * (double)(getWidth() - minTableWidth);
+ }
+ }
+
+ return columnWidths;
+ }
+
+ private SizeRequirements[] calculateColumnSizeRequirements() {
+ if (areColumnSizeRequirementsValid) {
+ return columnSizeRequirements;
+ }
+
+ int columnCount = getColumnCount();
+ if (columnSizeRequirements.length < columnCount) {
+ SizeRequirements[] oldSizeReqs = columnSizeRequirements;
+ columnSizeRequirements = new SizeRequirements[columnCount];
+ System.arraycopy(oldSizeReqs, 0, columnSizeRequirements, 0,
+ oldSizeReqs.length);
+ }
+
+ for (int col = 0; col < columnCount; col++) {
+ if (columnSizeRequirements[col] == null) {
+ columnSizeRequirements[col] = new SizeRequirements();
+ } else {
+ columnSizeRequirements[col].minimum = 0;
+ columnSizeRequirements[col].maximum = 0;
+ columnSizeRequirements[col].preferred = 0;
+ }
+ }
+
+ for (RowViewIterator rowIt = new RowViewIterator(this); rowIt.isValid(); rowIt.next()) {
+ int spansCount = 0;
+ TableRowView rowView = rowIt.getView();
+ for (int col = 0; col < rowView.getViewCount(); col++) {
+ while (rowView.isColumnOccupied(col + spansCount)) {
+ spansCount++;
+ }
+ int colSpan = rowView.getColumnSpan(col);
+ for (int i = 0; i < colSpan; i++) {
+ joinSizeRequirements(columnSizeRequirements[col + spansCount + i],
+ (int)rowView.getView(col).getMinimumSpan(X_AXIS) / colSpan,
+ (int)rowView.getView(col).getPreferredSpan(X_AXIS) / colSpan,
+ (int)rowView.getView(col).getMaximumSpan(X_AXIS) / colSpan);
+ }
+ spansCount += colSpan - 1;
+ }
+ }
+
+ areColumnSizeRequirementsValid = true;
+ return columnSizeRequirements;
+ }
+
+ private void joinSizeRequirements(final SizeRequirements size, final int min,
+ final int pref, final int max) {
+ size.minimum = Math.max(size.minimum, min);
+ size.preferred = Math.max(size.preferred, pref);
+
+ if (size.maximum > 0) {
+ size.maximum = Math.min(size.maximum, max);
+ } else {
+ size.maximum = Math.max(size.maximum, max);
+ }
+ // getColumnWidths() fails without this
+ size.maximum = Math.min(size.maximum, Short.MAX_VALUE);
+ }
+
+ private Object getCellSpacingAttr() {
+ Object cellSpacing = getElement().getAttributes()
+ .getAttribute(HTML.Attribute.CELLSPACING);
+ if (cellSpacing == null) {
+ cellSpacing = "1";
+ }
+ return FloatValue.factory.toCSS(Float.valueOf((String)cellSpacing));
+ }
+
+ private AttributeSet getAdditionalCellAttrs() {
+ SimpleAttributeSet attrs = new SimpleAttributeSet();
+
+ Object v = getCellSpacingAttr();
+ if (v != null) {
+ attrs.addAttribute(CSS.Attribute.MARGIN_LEFT, v);
+ attrs.addAttribute(CSS.Attribute.MARGIN_TOP, v);
+ }
+
+ v = getElement().getAttributes().getAttribute(HTML.Attribute.BORDER);
+ if (v != null) {
+ getStyleSheet().addCSSAttribute(attrs, CSS.Attribute.BORDER, "inset 1px");
+ }
+ return attrs;
+ }
+
+ private AttributeSet getAdditionalTableAttrs() {
+ SimpleAttributeSet attrs = new SimpleAttributeSet();
+
+ Object v = getCellSpacingAttr();
+ if (v != null) {
+ attrs.addAttribute(CSS.Attribute.PADDING_RIGHT, v);
+ attrs.addAttribute(CSS.Attribute.PADDING_BOTTOM, v);
+ }
+
+ v = getElement().getAttributes().getAttribute(HTML.Attribute.BORDER);
+ if (v instanceof String) {
+ String strValue = (String)v;
+ getStyleSheet().addCSSAttribute(attrs, CSS.Attribute.BORDER,
+ "inset " + strValue + "pt");
+ }
+ return attrs;
+ }
+}
Added: incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/TagIterator.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/TagIterator.java?rev=427121&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/TagIterator.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/TagIterator.java Mon Jul 31 07:08:47 2006
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2005 - 2006 The Apache Software Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+* @author Alexander T. Simbirtsev
+* @version $Revision$
+*/
+package javax.swing.text.html;
+
+import javax.swing.text.AttributeSet;
+import javax.swing.text.Document;
+import javax.swing.text.Element;
+import javax.swing.text.ElementIterator;
+import javax.swing.text.html.HTML.Tag;
+import javax.swing.text.html.HTMLDocument.Iterator;
+
+class TagIterator extends Iterator {
+
+ private final Tag tag;
+ private final ElementIterator it;
+ private Element current;
+
+ public TagIterator(final Tag tag, final Document document) {
+ this.tag = tag;
+ it = new ElementIterator(document);
+ next();
+ }
+
+ public AttributeSet getAttributes() {
+ return (current != null) ? current.getAttributes() : null;
+ }
+
+ public int getEndOffset() {
+ return (current != null) ? current.getEndOffset() : -1;
+ }
+
+ public int getStartOffset() {
+ return (current != null) ? current.getStartOffset() : -1;
+ }
+
+ public Tag getTag() {
+ return tag;
+ }
+
+ public boolean isValid() {
+ return (current != null);
+ }
+
+ public void next() {
+ current = it.next();
+ while (current != null) {
+ if (tag.toString().equals(current.getName())) {
+ break;
+ }
+ current = it.next();
+ }
+ }
+}
Added: incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/ViewAttributeSet.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/ViewAttributeSet.java?rev=427121&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/ViewAttributeSet.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/ViewAttributeSet.java Mon Jul 31 07:08:47 2006
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2005 - 2006 The Apache Software Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @author Alexey A. Ivanov
+ * @version $Revision$
+ */
+package javax.swing.text.html;
+
+import javax.swing.text.AttributeSet;
+import javax.swing.text.Element;
+import javax.swing.text.View;
+import javax.swing.text.html.CSS.RelativeValueResolver;
+
+class ViewAttributeSet extends CompositeAttributeSet {
+ final View view;
+
+ ViewAttributeSet(final StyleSheet ss, final View view) {
+ super(calculateElementAttr(ss, view),
+ calculateCSSRules(ss, view));
+ this.view = view;
+ }
+
+ public AttributeSet getResolveParent() {
+ final View parent = view.getParent();
+ return parent != null ? parent.getAttributes() : null;
+ }
+
+ public Object getAttribute(final Object key) {
+ if (key == ResolveAttribute) {
+ return getResolveParent();
+ }
+
+ Object result = getElementAttr().getAttribute(key);
+ if (result != null) {
+ return result;
+ }
+
+ if (getCssRules().getAttributeCount() > 0) {
+ result =
+ ((CascadedStyle)getCssRules()).getAttribute(key, view.getElement());
+ if (result != null) {
+ return result;
+ }
+ }
+
+ final AttributeSet resolver = getResolveParent();
+ if (resolver == null) {
+ return null;
+ }
+
+ if (key instanceof CSS.Attribute) {
+ CSS.Attribute cssKey = (CSS.Attribute)key;
+ if (cssKey.isInherited()) {
+ result = resolver.getAttribute(key);
+ if (result instanceof RelativeValueResolver) {
+ return ((RelativeValueResolver)result)
+ .getComputedValue(view.getParent());
+ }
+ return result;
+ }
+ return null;
+ }
+ return resolver.getAttribute(key);
+ }
+
+ private static AttributeSet calculateElementAttr(final StyleSheet ss,
+ final View view) {
+ final Element element = view.getElement();
+ return ss.translateHTMLToCSS(element.getAttributes());
+ }
+
+ private static AttributeSet calculateCSSRules(final StyleSheet ss,
+ final View view) {
+ HTML.Tag tag = SelectorMatcher.getTag(view.getElement());
+ return tag != null ? ss.getRule(tag, view.getElement()) : ss.getEmptySet();
+ }
+
+ private AttributeSet getElementAttr() {
+ return getPrimarySet();
+ }
+
+ private AttributeSet getCssRules() {
+ return getSecondarySet();
+ }
+}
Added: incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/default.css
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/default.css?rev=427121&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/default.css (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/default.css Mon Jul 31 07:08:47 2006
@@ -0,0 +1,88 @@
+/*
+ Copyright 2005 - 2006 The Apache Software Software Foundation or its licensors, as applicable.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+/*
+ * @author Vadim L. Bogdanov, Alexey A. Ivanov
+ * @version $Revision$
+ */
+
+body {
+ font-family: serif;
+ font-size: 14pt;
+ padding: 0.5em;
+}
+
+h1, h2, h3, h4, h5, h6, p {
+ margin-top: 0.75em;
+}
+
+h1 {
+ font-size: x-large;
+ font-weight: bold;
+}
+
+h2 {
+ font-size: large;
+ font-weight: bold;
+}
+
+h3 {
+ font-weight: bold;
+}
+
+b, strong {
+ font-weight: bolder;
+}
+
+i, em {
+ font-style: italic;
+}
+
+ol {
+ list-style-type: decimal;
+ padding-left: 40px;
+ margin-top: 0.25em;
+}
+
+ul {
+ list-style-type: disc;
+ padding-left: 40px;
+ margin-top: 0.25em;
+}
+
+a {
+ color: blue;
+ text-decoration: underline
+}
+
+code, tt, pre, kbd {
+ font-family: monospace;
+}
+
+th {
+ font-weight: bold;
+}
+
+td, th {
+ padding: 1px 2px;
+}
+
+small {
+ font-size: smaller;
+}
+
+big {
+ font-size: larger;
+}
\ No newline at end of file
Added: incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/parser/AttributeList.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/parser/AttributeList.java?rev=427121&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/parser/AttributeList.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/parser/AttributeList.java Mon Jul 31 07:08:47 2006
@@ -0,0 +1,188 @@
+/*
+ * Copyright 2005 - 2006 The Apache Software Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @author Evgeniya G. Maenkova
+ * @version $Revision$
+ */
+package javax.swing.text.html.parser;
+
+import java.io.Serializable;
+import java.util.Enumeration;
+import java.util.Vector;
+
+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;
+ //TODO It need check type FIXED, IMPLIED, REQUIRED?
+ public AttributeList(final String name,
+ final int type,
+ final int modifier,
+ final String value,
+ final Vector values,
+ final AttributeList next) {
+ this.name = name;
+ this.type = type;
+ this.modifier = modifier;
+ this.value = value;
+ this.values = values;
+ this.next = next;
+ }
+
+ public static String type2name(final int type) {
+ init();
+ return type < names.length ? names[type] : null;
+ }
+
+ public static int name2type(final String name) {
+ init();
+ for (int i = 0; i < names.length; i++) {
+ if (name.equals(names[i])) {
+ return i;
+ }
+ }
+ return 1;
+ }
+
+ static int nameToModifier(final String name) {
+ if ("#IMPLIED".equals(name)) {
+ return DTDConstants.IMPLIED;
+ } else if ("#REQUIRED".equals(name)) {
+ return DTDConstants.REQUIRED;
+ } else if ("#FIXED".equals(name)) {
+ return DTDConstants.FIXED;
+ } else {
+ return DTDConstants.DEFAULT;
+ }
+ }
+
+ static String modifierToName(final int modifier) {
+ if (modifier == DTDConstants.IMPLIED) {
+ return "#IMPLIED";
+ } else if (modifier == DTDConstants.REQUIRED) {
+ return "#REQUIRED";
+ } else if (modifier == DTDConstants.FIXED) {
+ return "#FIXED";
+ } else {
+ return "#DEFAULT";
+ }
+ }
+
+ public AttributeList(final String name) {
+ this.name = name;
+ }
+
+
+ AttributeList() {
+ }
+
+ public String toString() {
+ return "AttributeList["
+ + "name=" + name + ", "
+ + "type=" + type + ", "
+ + "modifier=" + modifier + ", "
+ + "value=" + value + ", "
+ + "values=" + values + ", "
+ + "next=" + next + "]";
+ }
+
+ final String paramString() {
+ //name type modifier,next.name next.type next.modifier
+ String name = this.name;
+ String type = values == null ? type2name(this.type) : valuesToString();
+ String modifier = modifierToName(this.modifier);
+ modifier = "#DEFAULT".equals(modifier) ? value : modifier;
+ String result = name + " " + type + " " + modifier;
+ return next == null ? result : result + "," + next.paramString();
+ }
+
+ final String valuesToString() {
+ if (values != null) {
+ String result = "";
+ for (int i = 0; i < values.size(); i++) {
+ result += "|" + values.get(i);
+ }
+ return result.substring(1, result.length());
+ }
+ return null;
+ }
+
+ public AttributeList getNext() {
+ return next;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public Enumeration getValues() {
+ return values.elements();
+ }
+
+ public int getModifier() {
+ return modifier;
+ }
+
+ public int getType() {
+ return type;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ private static String[] names;
+
+ private static void init() {
+ if (names == null) {
+ names = new String[] {null,
+ "CDATA",
+ "ENTITY",
+ "ENTITIES",
+ "ID",
+ "IDREF",
+ "IDREFS",
+ "NAME",
+ "NAMES",
+ "NMTOKEN",
+ "NMTOKENS",
+ "NOTATION",
+ "NUMBER",
+ "NUMBERS",
+ "NUTOKEN",
+ "NUTOKENS"
+ };
+ }
+ }
+
+ //TODO correct a bit: Do we check an instance or just equals?
+ final boolean containsValue(final String value) {
+ if (value == this.value) {
+ return true;
+ }
+
+ return values.contains(value);
+ }
+}
+
Added: incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/parser/ContentModel.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/parser/ContentModel.java?rev=427121&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/parser/ContentModel.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/parser/ContentModel.java Mon Jul 31 07:08:47 2006
@@ -0,0 +1,340 @@
+/*
+ * Copyright 2005 - 2006 The Apache Software Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @author Evgeniya G. Maenkova
+ * @version $Revision$
+ */
+package javax.swing.text.html.parser;
+
+import java.io.Serializable;
+import java.util.Vector;
+
+/**
+ *
+ * Element's content representation. That's unary or binary expression.
+ * Operands can be null (matched with null object), instance of Element,
+ * instance of ContentType.
+ * Valid operations can be unary operations (types):
+ * 1)'+' - (e+) - e must occur one or more times;
+ * 2)'*' - (e*) - e must occur zero or more times;
+ * 3)'?' - (e?) - e must occur zero or one time;
+ * 4)(0) - (e) - e must occur one time only
+ * and binary operations (types):
+ * 1)'|' - (e1|e2) means either e1 or e2 must occur, but not both;
+ * 2)',' - (e1,e2) means both A and B must occur, in that order;
+ * 3)'&' - (e1 & e2) means both e1 and e2 must occur, in any order *
+ * (Operation interpretation corresponds to HTML 4.01 Specification (3.3.3))
+ * As content model is using for dtd presentation here is some ambiguity
+ * what null object can be matched with. So null shouldn't be passed to
+ * constructor.
+ * No resursion is allowed.
+ * Content, next, type fields has the following limitation:
+ * 1) if type is one from {'+', '*', '?'} content hasn't to be null;
+ * 2) if type is one from {'|', ',', '&'} content and next have not to be
+ * null;
+ * 3) content can be null if and only if type is 0;
+ * 4) content can be null, instance of Element or instance of ContentModel;
+ * 5) type can be one from the following '*', '+', '?', '|', '&', ','.
+ */
+
+public final class ContentModel implements Serializable {
+ public int type;
+
+ public Object content;
+
+ public ContentModel next;
+
+ private static final char DEFAULT_TYPE = 0;
+ private static final char PLUS_TYPE = '+';
+ private static final char STAR_TYPE = '*';
+ private static final char QUESTION_TYPE = '?';
+ private static final char LINE_TYPE = '|';
+ private static final char COMMA_TYPE = ',';
+ private static final char AMPER_TYPE = '&';
+
+ /**
+ * @throws IllegalArgumentException in the following cases:
+ * 2) content model isn't instance of Element or Content Model
+ * (in particular, content equals to null);
+ * 3) types isn't binary type mentioned above;
+ * 4) next equals to null.
+ */
+ public ContentModel(final int type,
+ final Object content,
+ final ContentModel next) {
+ checkBinaryType(type);
+ checkObjectParameter(content);
+ checkObjectParameter(next);
+ this.type = type;
+ this.content = content;
+ this.next = next;
+ }
+
+ /**
+ * @throws IllegalArgumentException in the following cases:
+ * 1) type isn't unary type;
+ * 2) next equals to null
+ */
+
+ public ContentModel(final int type,
+ final ContentModel content) {
+ checkObjectParameter(content);
+ checkUnaryType(type);
+ this.type = type;
+ this.content = content;
+ }
+
+ /**
+ * That content model will be mathed with exactly one element.
+ * Type will be 0.
+ * Element can be equals to null. in such case contentModel will be matched
+ * with an empty input stream.
+ */
+ public ContentModel(final Element element) {
+ content = element;
+ }
+
+ public ContentModel() {
+ }
+
+ public String toString() {
+ if (type == DEFAULT_TYPE) {
+ return content == null ? "null" : ((Element)content).getName();
+ } else if (isUnaryType(type)) {
+ ContentModel content = (ContentModel)this.content;
+ boolean need = !(content.content instanceof Element
+ && isExtUnaryType(content.type));
+ return getBracket("(", need) + content.toString()
+ + getBracket(")", need) + (char)type;
+ } else {
+ String contentToString = content instanceof Element
+ ? ((Element)content).getName() : content.toString();
+ boolean needLeft = (content instanceof ContentModel)
+ && ((ContentModel)content).type != type
+ && isBinaryType(((ContentModel)content).type);
+ boolean needRight = next != null && next.type != type
+ && isBinaryType(next.type);
+ return getBracket("(", needLeft) + contentToString
+ + getBracket(")", needLeft)
+ + (char) type
+ + getBracket("(", needRight) + next + getBracket(")", needRight);
+ }
+ }
+
+ private String getBracket(final String s, final boolean need) {
+ return need ? s : "";
+ }
+
+ /**
+ *
+ * @return first Element from 'next' contentModel. if type equals one of
+ * unary operations that'll be null.
+ */
+ public Element first() {
+ return isExtUnaryType(type) || next == null ? null
+ : next.getFirstElement();
+ }
+
+ private Element getFirstElement() {
+
+ if (content == null) {
+ return null;
+ }
+ return content instanceof Element ? (Element)content
+ : ((ContentModel)content).getFirstElement();
+ }
+
+
+ /**
+ * @return
+ * 1) Returns true if token is null or equals to content or this content
+ * model equals to token;
+ * 2) if type equals to 0 return true if token equals to content and false
+ * otherwise;
+ * 3) If type is one from the unary types returns false if token isn't
+ * istance of Element or ContentModel. Otherwise, returns true if and
+ * only if one of the following conditions is true:
+ * a) content is instance of Element, token is instance of Element and
+ * token equals to content
+ * b) content is instance of ContentModel, token is instance of Element
+ * and content.first(token) returns true;
+ * c) content is instance of Element and token is instance of
+ * ContentModel, token.type equals to 0 and content equals to
+ * token.content;
+ * d) content is instance of ContentModel, token is instance of
+ * ContentModel and content.first(token) returns true;
+ * 4) If type is one from binary types then:
+ * a) if content instance of Element and content equals to token returns
+ * true;
+ * b) if content instance of ContentModel and content.first(token)
+ * equals to true, then returns true
+ * c) if content.first(token) equals to true returns true;
+ * d) if type equals to ',' returns true if and only if content is
+ * instance of ContentModel and content.empty() && next.first(token)
+ * equals to true.
+ * e) if type equals to '| or '&' returns next.first(token).
+ *
+ */
+
+ public boolean first(final Object token) {
+ if (token == null || token.equals(content) || equals(token)) {
+ return true;
+ }
+ if (type == DEFAULT_TYPE) {
+ return token.equals(content);
+ } else if (isUnaryType(type)) {
+ return canBeFirstInContent(token);
+ } else if (isBinaryType(type)) {
+ boolean contentIsModel = content instanceof ContentModel;
+ boolean contentIsElement = content instanceof Element;
+ if ((contentIsModel && ((ContentModel)content).first(token))
+ || (contentIsElement && content.equals(token))) {
+ return true;
+ }
+ switch (type) {
+ case COMMA_TYPE:
+ return (contentIsModel && ((ContentModel)content).empty())
+ && next.first(token);
+ case LINE_TYPE:
+ case AMPER_TYPE:
+ return next.first(token);
+ default:
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ private boolean canBeFirstInContent(final Object token) {
+ boolean contentIsElement = contentIsElement();
+ boolean tokenIsElement = token instanceof Element;
+ boolean tokenIsModel = token instanceof ContentModel;
+ if (!tokenIsElement && !tokenIsModel) {
+ return false;
+ }
+
+ boolean contentIsModel = !contentIsElement;
+ return (contentIsElement && tokenIsElement && token.equals(content))
+ || (contentIsModel && tokenIsElement
+ && ((ContentModel)content).first(token))
+ || (contentIsElement && tokenIsModel
+ && ((ContentModel)token).type == 0
+ && content.equals(((ContentModel)token).content))
+ || (contentIsModel && tokenIsModel
+ && ((ContentModel)content).first(token));
+
+ }
+
+
+ /**
+ * Adds all elements of this contentModel to elemVec ignoring operations
+ * between elements. For instance, for ((a+)| ((b*),(c?))) elements a,b,c
+ * will be added to the elemVec.
+ * It supposes that elemVec isn't null.
+ * If content is null, nothing will be added to elemVec.
+ */
+
+ public void getElements(final Vector elemVec) {
+ if (content instanceof Element) {
+ elemVec.add(content);
+ } else if (content != null) {
+ ((ContentModel)content).getElements(elemVec);
+ }
+ if (next != null) {
+ next.getElements(elemVec);
+ }
+ }
+
+ /**
+ * @return: true if and only if some of the conditions is true:
+ * 1)type equals to 0 and content equals to null;
+ * 2)type equals to '*' or '?';
+ * 3)if type equals to '|' one of the following conditions is true:
+ * a) content is instance of ContentModel and could match an empty input
+ * stream;
+ * b) next could match an empty input stream;
+ * 4)if type equals to ',' or '&' both conditions are true:
+ * a) content is instance of ContentModel and could match an empty input
+ * stream;
+ * b) next could match an empty input stream;
+ */
+ public boolean empty() {
+ switch (type) {
+ case DEFAULT_TYPE:
+ return content == null;
+ case STAR_TYPE:
+ case QUESTION_TYPE:
+ return true;
+ case PLUS_TYPE:
+ return false;
+ case LINE_TYPE:
+ return (!contentIsElement() && ((ContentModel)content).empty())
+ || next.empty();
+ case AMPER_TYPE:
+ case COMMA_TYPE:
+ return !contentIsElement() && ((ContentModel)content).empty()
+ && next.empty();
+ default:
+ return false;
+ }
+ }
+
+ private boolean isUnaryType(final int type) {
+ return type == STAR_TYPE || type == PLUS_TYPE || type == QUESTION_TYPE;
+ }
+
+ private boolean isExtUnaryType(final int type) {
+ return isUnaryType(type) || type == DEFAULT_TYPE;
+ }
+
+ private boolean isBinaryType(final int type) {
+ return type == LINE_TYPE || type == COMMA_TYPE || type == AMPER_TYPE;
+ }
+
+ private void checkBinaryType(final int type) {
+ if (!isBinaryType(type)) {
+ throw new IllegalArgumentException("Illegal type, must be "
+ + COMMA_TYPE + ", "
+ + LINE_TYPE + ", "
+ + AMPER_TYPE + "");
+ }
+ }
+
+ private void checkUnaryType(final int type) {
+ if (!isUnaryType(type)) {
+ throw new IllegalArgumentException("Illegal type, must be "
+ + STAR_TYPE + ", "
+ + PLUS_TYPE + ", "
+ + QUESTION_TYPE + "");
+ }
+ }
+
+ private void checkObjectParameter(final Object object) {
+ if (!(object instanceof Element || object instanceof ContentModel)) {
+ throw new IllegalArgumentException("Object have to be instance "
+ + "of Element or ContentModel and not null");
+ }
+ }
+
+ private boolean contentIsElement() {
+ return isElement(content);
+ }
+
+ private boolean isElement(final Object obj) {
+ return obj instanceof Element;
+ }
+}
Added: incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/parser/DTD.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/parser/DTD.java?rev=427121&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/parser/DTD.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/parser/DTD.java Mon Jul 31 07:08:47 2006
@@ -0,0 +1,382 @@
+/*
+ * Copyright 2005 - 2006 The Apache Software Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @author Evgeniya G. Maenkova
+ * @version $Revision$
+ */
+package javax.swing.text.html.parser;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.util.BitSet;
+import java.util.Hashtable;
+import java.util.Vector;
+
+public class DTD implements DTDConstants {
+ public static final int FILE_VERSION = 1;
+
+ public String name;
+
+ public Vector elements = new Vector();
+
+ public Hashtable elementHash = new Hashtable();
+ public Hashtable entityHash = new Hashtable();
+
+ public final Element pcdata;
+ public final Element html;
+ public final Element meta;
+ public final Element base;
+ public final Element isindex;
+ public final Element head;
+ public final Element body;
+ public final Element applet;
+ public final Element param;
+ public final Element p;
+ public final Element title;
+
+ private static final Hashtable dtdHash = new Hashtable();
+
+ private static final String pattern = "(\\|)+";
+
+ /**
+ * Created DTD will not be pushed to DTD hash.
+ * @throws IllegalArgumentException if name equals to null
+ */
+ public static DTD getDTD(final String name) throws IOException {
+ checkName(name);
+ String key = name.toLowerCase();
+ Object dtd = dtdHash.get(key);
+ return dtd == null ? new DTD(name.toLowerCase()) : (DTD)dtd;
+ }
+
+ /**
+ *
+ * @throws IllegalArgumentException if dtd or name equal to null
+ */
+ public static void putDTDHash(final String name,
+ final DTD dtd) {
+ checkName(name);
+ checkValue(dtd);
+ dtdHash.put(name.toLowerCase(), dtd);
+ }
+
+ private static void checkName(final String name) {
+ if (name == null) {
+ throw new IllegalArgumentException("Name must be not null");
+ }
+ }
+
+ private static void checkValue(final DTD dtd) {
+ if (dtd == null) {
+ throw new IllegalArgumentException("DTD must be not null");
+ }
+ }
+
+
+ protected DTD(final String name) {
+ //TODO may be it need change the order
+ this.name = name;
+
+ pcdata = createDefaultElement(HTMLConstants.PCDATA_ELEMENT_NAME, 0);
+ putElement(pcdata);
+
+ html = createDefaultElement(HTMLConstants.HTML_ELEMENT_NAME, 1);
+ putElement(html);
+
+ meta = createDefaultElement(HTMLConstants.META_ELEMENT_NAME, 2);
+ putElement(meta);
+
+ base = createDefaultElement(HTMLConstants.BASE_ELEMENT_NAME, 3);
+ putElement(base);
+
+ isindex = createDefaultElement(HTMLConstants.ISINDEX_ELEMENT_NAME, 4);
+ putElement(isindex);
+
+ head = createDefaultElement(HTMLConstants.HEAD_ELEMENT_NAME, 5);
+ putElement(head);
+
+ body = createDefaultElement(HTMLConstants.BODY_ELEMENT_NAME, 6);
+ putElement(body);
+
+ applet = createDefaultElement(HTMLConstants.APPLET_ELEMENT_NAME, 7);
+ putElement(applet);
+
+ param = createDefaultElement(HTMLConstants.PARAM_ELEMENT_NAME, 8);
+ putElement(param);
+
+ p = createDefaultElement(HTMLConstants.P_ELEMENT_NAME, 9);
+ putElement(p);
+
+ title = createDefaultElement(HTMLConstants.TITLE_ELEMENT_NAME, 10);
+ putElement(title);
+
+ putElement(createDefaultElement(HTMLConstants.STYLE_ELEMENT_NAME, 11));
+ putElement(createDefaultElement(HTMLConstants.LINK_ELEMENT_NAME, 12));
+ putElement(new Element(13, HTMLConstants.UNKNOWN_ELEMENT_NAME, false,
+ true, null, null, EMPTY, null, null, null));
+
+ entityHash.put(HTMLConstants.SPACE_ENTITY_NAME,
+ createDefaultEntity(HTMLConstants.SPACE_ENTITY_NAME,
+ " "));
+ entityHash.put(HTMLConstants.RS_ENTITY_NAME,
+ createDefaultEntity(HTMLConstants.RS_ENTITY_NAME,
+ "\n"));
+ entityHash.put(HTMLConstants.RE_ENTITY_NAME,
+ createDefaultEntity(HTMLConstants.RE_ENTITY_NAME,
+ "\r"));
+ }
+
+ private void putElement(final Element element) {
+ elements.add(element);
+ elementHash.put(element.getName(), element);
+ }
+
+
+ private Element createDefaultElement(final String name,
+ final int index) {
+ return new Element(index, name, false, false, null, null,
+ ANY, null, null, null);
+ }
+
+ private Entity createDefaultEntity(final String name,
+ final String data) {
+ return new Entity(name, 0, data, true, false);
+ }
+
+ public void read(final DataInputStream stream) throws IOException {
+ ObjectInputStream is = new ObjectInputStream(stream);
+ try {
+ elementHash = (Hashtable)is.readObject();
+ elements = (Vector)is.readObject();
+ int size = is.readInt();
+ for (int i = 0; i < size; i ++) {
+ String name = (String)is.readObject();
+ int data = is.readInt();
+ DTDUtilities.handleEntity(this, name, data);
+ }
+ is.close();
+ updateFields();
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public String toString() {
+ return name;
+ }
+
+ protected ContentModel defContentModel(final int type,
+ final Object content,
+ final ContentModel next) {
+ return new ContentModel(type, content, next);
+ }
+
+ /**
+ *
+ * @param values attributes split by '|'
+ */
+ protected AttributeList defAttributeList(final String name,
+ final int type,
+ final int modifier,
+ final String value,
+ final String values,
+ final AttributeList next) {
+
+ return new AttributeList(name, type, modifier, value,
+ createAttributeNamesVector(values), next);
+ }
+
+ private Vector createAttributeNamesVector(final String values) {
+ if (values == null) {
+ return null;
+ }
+ Vector result = new Vector();
+ String[] tokens = values.split(pattern);
+ for (int i = 0; i < tokens.length; i++) {
+ String token = tokens[i];
+ if (!"".equals(token)) {
+ result.add(token);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * If element exists but doesn't correspond to this parameters, it will be
+ * updated.
+ */
+ protected Element defElement(final String name,
+ final int type,
+ final boolean oStart,
+ final boolean oEnd,
+ final ContentModel content,
+ final String[] exclusions,
+ final String[] inclusions,
+ final AttributeList atts) {
+ return defineElement(name, type, oStart, oEnd, content,
+ createBitSetByStrings(exclusions),
+ createBitSetByStrings(inclusions),
+ atts);
+
+ }
+
+ private BitSet createBitSetByStrings(final String[] names) {
+ if (names == null) {
+ return null;
+ }
+ BitSet result = new BitSet();
+ for (int i = 0; i < names.length; i++) {
+ Element elem = (Element)elementHash.get(names[i]);
+ if (elem != null) {
+ result.set(elem.getIndex());
+ }
+ }
+
+ return result;
+ }
+
+ protected Entity defEntity(final String name,
+ final int type,
+ final String str) {
+ return defineEntity(name, type, str == null ? null : str.toCharArray());
+ }
+
+ public Entity defEntity(final String name,
+ final int type,
+ final int ch) {
+ return defineEntity(name, type, new char[] {(char)ch});
+ }
+
+ /**
+ * Updated attributes of corresponding element, if this one exists.
+ * Otherwise, new elements are created with these attributes and put to
+ * elementsHash.
+ */
+ public void defineAttributes(final String name,
+ final AttributeList atts) {
+ Object obj = elementHash.get(name);
+ Element elem;
+ if (obj == null) {
+ elem = createDefaultElement(name, elements.size());
+ putElement(elem);
+ } else {
+ elem = (Element)obj;
+ }
+ elem.atts = atts;
+ }
+
+ /**
+ * If element exists but doesn't correspond to this parameters, it will be
+ * updated.
+ */
+ public Element defineElement(final String name,
+ final int type,
+ final boolean omitStart,
+ final boolean omitEnd,
+ final ContentModel contentModel,
+ final BitSet exclusions,
+ final BitSet inclusions,
+ final AttributeList atts) {
+ Object obj = elementHash.get(name);
+ Element result;
+ if (obj == null) {
+ result = new Element(elements.size(), name, omitStart, omitEnd,
+ exclusions, inclusions, type, contentModel,
+ atts, null);
+ putElement(result);
+ } else {
+ result = (Element)obj;
+ result.updateElement(result.index, name, omitStart, omitEnd,
+ exclusions, inclusions, type, contentModel,
+ atts, null);
+ }
+ return result;
+ }
+
+ /**
+ * If entity with this name exists, it will not be updated.
+ */
+ public Entity defineEntity(final String name,
+ final int type,
+ final char[] data) {
+ Object obj = entityHash.get(name);
+ Entity result;
+ if (obj == null) {
+ result = new Entity(name, type, data);
+ entityHash.put(name, result);
+ } else {
+ result = (Entity)obj;
+ }
+ return result;
+ }
+
+ /**
+ *
+ * @return if index < 0 or elements.size() <= index returns null.
+ */
+ public Element getElement(final int index) {
+ return index >= 0 && index < elements.size() ? (Element)
+ elements.get(index) : null;
+ }
+
+ public Element getElement(final String name) {
+ Object obj = elementHash.get(name);
+ if (obj != null) {
+ return (Element)obj;
+ }
+ Element element = createDefaultElement(name, elements.size());
+ putElement(element);
+ return element;
+ }
+
+ public Entity getEntity(final int index) {
+ return null;
+ }
+
+ public Entity getEntity(final String name) {
+ return (Entity)entityHash.get(name);
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ private void replace(final Element elem) {
+ elementHash.put(elem.name, elem);
+ int index = elem.getIndex();
+ elements.setElementAt(elem, index);
+ }
+
+ private void updateField(final Element elem) {
+ elem.updateElement(getElement(elem.getName()));
+ replace(elem);
+ }
+
+ private void updateFields() {
+ updateField(pcdata);
+ updateField(html);
+ updateField(meta);
+ updateField(base);
+ updateField(isindex);
+ updateField(head);
+ updateField(body);
+ updateField(applet);
+ updateField(param);
+ updateField(p);
+ updateField(title);
+ }
+}
Added: incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/parser/DTDConstants.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/parser/DTDConstants.java?rev=427121&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/parser/DTDConstants.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/parser/DTDConstants.java Mon Jul 31 07:08:47 2006
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2005 - 2006 The Apache Software Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @author Evgeniya G. Maenkova
+ * @version $Revision$
+ */
+package javax.swing.text.html.parser;
+
+public interface DTDConstants {
+ 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;
+
+ int RCDATA = 16;
+
+ int EMPTY = 17;
+
+ int MODEL = 18;
+
+ int ANY = 19;
+
+ int FIXED = 1;
+
+ int REQUIRED = 2;
+
+ int CURRENT = 3;
+
+ int CONREF = 4;
+
+ int IMPLIED = 5;
+
+ 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 = 65536;
+
+ int DEFAULT = 131072;
+
+ int PARAMETER = 262144;
+}
+
Added: incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/parser/DTDUtilities.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/parser/DTDUtilities.java?rev=427121&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/parser/DTDUtilities.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/parser/DTDUtilities.java Mon Jul 31 07:08:47 2006
@@ -0,0 +1,261 @@
+/*
+ * Copyright 2005 - 2006 The Apache Software Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @author Evgeniya G. Maenkova
+ * @version $Revision$
+ */
+package javax.swing.text.html.parser;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.util.Hashtable;
+import java.util.Iterator;
+
+class DTDUtilities implements DTDConstants {
+ static final String SPLIT_PATTERN = "\\|";
+ static final String REPLACE_PATTERN = " |\\(|\\)";
+ static void putAttribute(final Hashtable atts,
+ final String name,
+ final String value) {
+ if (name.indexOf("|") >= 0) {
+ String[] names = replaceAndSplit(name);
+ for (int i = 0; i < names.length; i++) {
+ putAttribute(atts, names[i], value);
+ }
+ } else {
+ atts.put(name, value);
+ }
+ };
+
+ static String[] replaceAndSplit(final String s) {
+ return s.replaceAll(REPLACE_PATTERN, "").split(SPLIT_PATTERN);
+ }
+
+ static void handleElement(final Object obj,
+ final String name,
+ final String descr,
+ final Hashtable attrTable) {
+ //For testing
+ if (obj instanceof Hashtable) {
+ ((Hashtable)obj).put(name, descr);
+ return;
+ }
+ DTD dtd = (DTD)obj;
+ if (name.indexOf("|") >= 0) {
+ String[] names = replaceAndSplit(name);
+ for (int i = 0; i < names.length; i++) {
+ handleElement(dtd, names[i], descr, attrTable);
+ }
+ } else {
+ String[] splDescr = splitElementDescr(descr);
+ boolean oStart = isOmitTag(splDescr[0], true);
+ boolean oEnd = isOmitTag(splDescr[0], false);
+ ContentModel contentModel = createContentModel(dtd, splDescr[1]);
+ String[] exclusions = splitString(splDescr[2]);
+ String[] inclusions = splitString(splDescr[3]);
+ AttributeList atts =
+ createAttributeList(dtd, (String)attrTable.get(name));
+ int type = getType(oEnd, splDescr[1]);
+ dtd.defElement(name, type, oStart, oEnd, contentModel,
+ exclusions, inclusions, atts);
+ }
+ };
+
+ static int getType(final boolean oEnd, final String descr) {
+ if (descr.startsWith("EMPTY") && oEnd) {
+ return EMPTY;
+ } else if (descr.startsWith("CDATA")) {
+ return CDATA;
+ } else {
+ return MODEL;
+ }
+ }
+
+ static boolean isOmitTag(final String descr, final boolean isStart) {
+ return descr.charAt(isStart ? 0 : 2) == 'O';
+ }
+
+ static void handleEntity(final DTD dtd, final String name,
+ final int value) {
+ Entity entity = new Entity(name, (char)value);
+ dtd.entityHash.put(name, entity);
+ dtd.entityHash.put(new Integer(value), entity);
+ }
+
+ static AttributeList createAttributeList(final DTD dtd, final String spec) {
+ String[] specs = spec.replaceAll("( )+", " ")
+ .replaceAll("( )*\\|( )*", "|").split(" ");
+ AttributeList result = null;
+ String values = "";
+ int modifier = 0;
+ for (int i = specs.length - 3; i >= 0; i -= 3) {
+ modifier = AttributeList.nameToModifier(specs[i + 2]);
+ values = specs[i + 1];
+ values = values.indexOf(")") >= 0
+ ? values.replaceAll("\\(|\\)", "") : null;
+ result = dtd.defAttributeList(specs[i + 0],
+ AttributeList.name2type(specs[i + 1]),
+ modifier,
+ modifier == DEFAULT ? specs[i + 2] : null,
+ values,
+ result);
+
+ }
+ return result;
+ }
+
+
+ static String[] splitString(final String s) {
+ return s == null ? null : s.split("\\|");
+ }
+
+ static boolean isBalanced(final String s) {
+ int count = 0;
+ for (int i = 0; i < s.length(); i++) {
+ char ch = s.charAt(i);
+ if (ch == ')' && count < 0) {
+ count++;
+ } else if (ch == '(') {
+ count--;
+ }
+ }
+ return count == 0;
+ }
+
+ static ContentModel createContentModel(final DTD dtd, final String descr) {
+ if (descr.startsWith("EMPTY") || descr.startsWith("CDATA")) {
+ return null;
+ }
+ int length = descr.length();
+ if (descr.matches("([a-zA-Z]|[0-9]|#)+")) {
+ return new ContentModel((Element)dtd.elementHash.get(descr));
+ } else if (descr.matches("\\((.)*\\)")
+ && isBalanced(descr.substring(1, length - 1))) {
+ return createContentModel(dtd,
+ descr.substring(1, length - 1));
+ } else if (descr.matches("\\((.)+\\)[+*?]")
+ || descr.matches("([a-zA-Z]|[0-9]|#)+[+|*|?]")) {
+ int index = length - 1;
+ return
+ new ContentModel(descr.charAt(index),
+ createContentModel(dtd,
+ descr.substring(0, index)));
+ } else {
+ int count = 0;
+ char ch = 0;
+ for (int i = descr.length() - 1; i >= 0; i--) {
+ ch = descr.charAt(i);
+ if ("|,&".indexOf(ch) >= 0 && count == 0) {
+ count = i;
+ break;
+ } else if (ch == ')') {
+ count++;
+ } else if (ch == '(') {
+ count--;
+ }
+
+ }
+ return
+ new ContentModel(ch,
+ createContentModel(dtd,
+ descr.substring(0, count)),
+ createContentModel(dtd,
+ descr.substring(count + 1,
+ length)));
+ }
+ }
+
+ static String[] splitElementDescr(final String descr) {
+ String tags = descr.substring(0, 3);
+ String allContent = descr.substring(4, descr.length());
+ allContent = allContent.replaceAll("( )+", "");
+ int incIndex = allContent.indexOf("+(");
+ int excIndex = allContent.indexOf("-(");
+ String content = "";
+ String exc = null;
+ String inc = null;
+
+ if (incIndex >= 0 && excIndex >= 0) {
+ if (incIndex > excIndex) {
+ inc = allContent.substring(incIndex, excIndex);
+ exc = allContent.substring(excIndex, allContent.length());
+ content = allContent.substring(0, incIndex);
+ } else {
+ inc = allContent.substring(excIndex, incIndex);
+ exc = allContent.substring(incIndex, allContent.length());
+ content = allContent.substring(0, excIndex);
+ }
+ } else if (incIndex >= 0) {
+ inc = allContent.substring(incIndex, allContent.length());
+ content = allContent.substring(0, incIndex);
+ } else if (excIndex >= 0) {
+ exc = allContent.substring(excIndex, allContent.length());
+ content = allContent.substring(0, excIndex);
+ } else {
+ content = allContent;
+ }
+ inc = inc == null ? null : inc.substring(2, inc.length() - 1);
+ exc = exc == null ? null : exc.substring(2, exc.length() - 1);
+ return new String[]{tags, content, exc, inc};
+ }
+
+
+ static void initDTD(final DTD dtd) {
+ EntitiesHandler.initEntitiesCreation(dtd);
+ ElementsHandler.initAttributes();
+ putAllElementsIntoHash(dtd);
+ ElementsHandler.initElementsCreation(dtd);
+ }
+
+ static void putAllElementsIntoHash(final DTD dtd) {
+ Iterator iter = ElementsHandler.atts.keySet().iterator();
+ while (iter.hasNext()) {
+ String name = (String)iter.next();
+ dtd.defElement(name, EMPTY, false, false, null, null, null, null);
+ }
+ dtd.defElement("#PCDATA", EMPTY, false, false, null, null, null, null);
+ }
+ //TODO Probably, don't suplicate information in elements vector
+ static void createBinaryDTD(final String fileName) {
+ try {
+ ObjectOutputStream os = new ObjectOutputStream(
+ new FileOutputStream(fileName));
+ DTD dtd = new DTD("tmp");
+ initDTD(dtd);
+ os.writeObject(dtd.elementHash);
+ os.writeObject(dtd.elements);
+ int size = dtd.entityHash.size();
+ os.writeInt((size - 3)/2);
+ Iterator iter = dtd.entityHash.keySet().iterator();
+ while (iter.hasNext()) {
+ Object key = iter.next();
+ if (key instanceof String
+ && !key.equals("#SPACE")
+ && !key.equals("#RS")
+ && !key.equals("#RE")) {
+ Entity entity = (Entity)dtd.entityHash.get(key);
+ os.writeObject(key);
+ os.writeInt(entity.data[0]);
+ }
+ }
+ os.flush();
+ os.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+}
Added: incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/parser/DocumentParser.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/parser/DocumentParser.java?rev=427121&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/parser/DocumentParser.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/parser/DocumentParser.java Mon Jul 31 07:08:47 2006
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2005 - 2006 The Apache Software Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @author Evgeniya G. Maenkova
+ * @version $Revision$
+ */
+package javax.swing.text.html.parser;
+
+import java.io.IOException;
+import java.io.Reader;
+import javax.swing.text.ChangedCharSetException;
+import javax.swing.text.html.HTMLEditorKit;
+
+public class DocumentParser extends Parser {
+
+ public DocumentParser(final DTD a0) {
+ super(a0);
+ throw new UnsupportedOperationException("Not implemented");
+ }
+
+
+ protected void handleError(final int a0, final String a1) {
+ throw new UnsupportedOperationException("Not implemented");
+
+ }
+
+
+ protected void handleText(final char[] a0) {
+ throw new UnsupportedOperationException("Not implemented");
+
+ }
+
+
+ protected void handleEndTag(final TagElement a0) {
+ throw new UnsupportedOperationException("Not implemented");
+ }
+
+
+ protected void handleEmptyTag(final TagElement a0) throws ChangedCharSetException {
+ throw new UnsupportedOperationException("Not implemented");
+
+ }
+
+
+ protected void handleComment(final char[] a0) {
+ throw new UnsupportedOperationException("Not implemented");
+
+ }
+
+
+ protected void handleStartTag(final TagElement a0) {
+ throw new UnsupportedOperationException("Not implemented");
+
+ }
+
+
+ public void parse(final Reader a0, final HTMLEditorKit.ParserCallback a1, final boolean a2) throws IOException {
+ throw new UnsupportedOperationException("Not implemented");
+
+ }
+
+}
+
Added: incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/parser/Element.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/parser/Element.java?rev=427121&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/parser/Element.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/html/parser/Element.java Mon Jul 31 07:08:47 2006
@@ -0,0 +1,197 @@
+/*
+ * Copyright 2005 - 2006 The Apache Software Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @author Evgeniya G. Maenkova
+ * @version $Revision$
+ */
+package javax.swing.text.html.parser;
+
+import java.io.Serializable;
+import java.util.BitSet;
+
+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 = DTDConstants.ANY;
+
+ public ContentModel content;
+
+ public AttributeList atts;
+
+ public Object data;
+
+ Element(final int index,
+ final String name,
+ final boolean oStart,
+ final boolean oEnd,
+ final BitSet exclusions,
+ final BitSet inclusions,
+ final int type,
+ final ContentModel content,
+ final AttributeList atts,
+ final Object data) {
+ this.index = index;
+ this.name = name;
+ this.oStart = oStart;
+ this.oEnd = oEnd;
+ this.inclusions = inclusions;
+ this.exclusions = exclusions;
+ this.type = type;
+ this.content = content;
+ this.atts = atts;
+ this.data = data;
+ }
+
+ Element() {
+ }
+
+ public static int name2type(final String name) {
+ if (name.equals("ANY")) {
+ return DTDConstants.ANY;
+ } else if (name.equals("CDATA")) {
+ return DTDConstants.CDATA;
+ } else if (name.equals("EMPTY")) {
+ return DTDConstants.EMPTY;
+ } else if (name.equals("RCDATA")) {
+ return DTDConstants.RCDATA;
+ } else {
+ return 0;
+ }
+ }
+
+
+ public AttributeList getAttributeByValue(final String value) {
+ AttributeList currentAtts = this.atts;
+ if (value == null) {
+ return null;
+ }
+ while (currentAtts != null) {
+ if (currentAtts.containsValue(value)) {
+ return currentAtts;
+ }
+ currentAtts = currentAtts.next;
+ }
+ return null;
+ }
+
+ public AttributeList getAttribute(final String name) {
+ AttributeList currentAtts = this.atts;
+ if (name == null) {
+ return null;
+ }
+ while (currentAtts != null) {
+ if (name.equals(currentAtts.getName())) {
+ return currentAtts;
+ }
+ currentAtts = currentAtts.next;
+ }
+ return null;
+ }
+
+ public String toString() {
+ return "javax.swing.text.html.parser.Element["
+ + "index=" + index + ","
+ + "name=" + name + ","
+ + "oStart=" + oStart + ","
+ + "oEnd=" + oEnd + ","
+ + "inclusions=" + inclusions + ","
+ + "exclusions=" + exclusions + ","
+ + "type=" + type + ","
+ + "content=" + content + ","
+ + "atts=" + atts + ","
+ + "data=" + data + "]";
+ }
+
+ public boolean isEmpty() {
+ return type == DTDConstants.EMPTY;
+ }
+
+
+ public int getIndex() {
+ return index;
+ }
+
+
+ public AttributeList getAttributes() {
+ return atts;
+ }
+
+ public ContentModel getContent() {
+ return content;
+ }
+
+ public int getType() {
+ return type;
+ }
+
+ public boolean omitEnd() {
+ return oEnd;
+ }
+
+ public boolean omitStart() {
+ return oStart;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ final void updateElement(final int index,
+ final String name,
+ final boolean oStart,
+ final boolean oEnd,
+ final BitSet exclusions,
+ final BitSet inclusions,
+ final int type,
+ final ContentModel content,
+ final AttributeList atts,
+ final Object data) {
+ this.index = index;
+ this.name = name;
+ this.oStart = oStart;
+ this.oEnd = oEnd;
+ this.inclusions = inclusions;
+ this.exclusions = exclusions;
+ this.type = type;
+ this.content = content;
+ this.atts = atts;
+ this.data = data;
+ }
+
+ final void updateElement(final Element element) {
+ this.index = element.index;
+ this.name = element.name;
+ this.oStart = element.oStart;
+ this.oEnd = element.oEnd;
+ this.inclusions = element.inclusions;
+ this.exclusions = element.exclusions;
+ this.type = element.type;
+ this.content = element.content;
+ this.atts = element.atts;
+ this.data = element.data;
+ }
+}
+