org.apache.batik.dom.AbstractText Maven / Gradle / Ivy
/*
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You 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.
*/
package org.apache.batik.dom;
import org.apache.batik.dom.util.XMLSupport;
import org.apache.batik.util.XMLConstants;
import org.apache.batik.xml.XMLUtilities;
import org.w3c.dom.DOMException;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.Text;
/**
* This class implements the {@link org.w3c.dom.Text} interface.
*
* @author Stephane Hillion
* @version $Id: AbstractText.java 1802297 2017-07-18 13:58:12Z ssteiner $
*/
public abstract class AbstractText
extends AbstractCharacterData
implements Text {
/**
* DOM: Implements {@link org.w3c.dom.Text#splitText(int)}.
*/
public Text splitText(int offset) throws DOMException {
if (isReadonly()) {
throw createDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
"readonly.node",
new Object[] {(int) getNodeType(),
getNodeName() });
}
String v = getNodeValue();
if (offset < 0 || offset >= v.length()) {
throw createDOMException(DOMException.INDEX_SIZE_ERR,
"offset",
new Object[] {offset});
}
Node n = getParentNode();
if (n == null) {
throw createDOMException(DOMException.INDEX_SIZE_ERR,
"need.parent",
new Object[] {});
}
String t1 = v.substring(offset);
Text t = createTextNode(t1);
Node ns = getNextSibling();
if (ns != null) {
n.insertBefore(t, ns);
} else {
n.appendChild(t);
}
setNodeValue(v.substring(0, offset));
return t;
}
/**
* Get the previous logically
* adjacent text node.
*/
protected Node getPreviousLogicallyAdjacentTextNode(Node n) {
Node p = n.getPreviousSibling();
Node parent = n.getParentNode();
while (p == null
&& parent != null
&& parent.getNodeType() == Node.ENTITY_REFERENCE_NODE) {
p = parent;
parent = p.getParentNode();
p = p.getPreviousSibling();
}
while (p != null && p.getNodeType() == Node.ENTITY_REFERENCE_NODE) {
p = p.getLastChild();
}
if (p == null) {
return null;
}
int nt = p.getNodeType();
if (nt == Node.TEXT_NODE || nt == Node.CDATA_SECTION_NODE) {
return p;
}
return null;
}
/**
* Get the next logically
* adjacent text node.
*/
protected Node getNextLogicallyAdjacentTextNode(Node n) {
Node p = n.getNextSibling();
Node parent = n.getParentNode();
while (p == null
&& parent != null
&& parent.getNodeType() == Node.ENTITY_REFERENCE_NODE) {
p = parent;
parent = p.getParentNode();
p = p.getNextSibling();
}
while (p != null && p.getNodeType() == Node.ENTITY_REFERENCE_NODE) {
p = p.getFirstChild();
}
if (p == null) {
return null;
}
int nt = p.getNodeType();
if (nt == Node.TEXT_NODE || nt == Node.CDATA_SECTION_NODE) {
return p;
}
return null;
}
/**
* DOM: Implements {@link org.w3c.dom.Text#getWholeText()}.
*/
public String getWholeText() {
StringBuffer sb = new StringBuffer();
for (Node n = this;
n != null;
n = getPreviousLogicallyAdjacentTextNode(n)) {
sb.insert(0, n.getNodeValue());
}
for (Node n = getNextLogicallyAdjacentTextNode(this);
n != null;
n = getNextLogicallyAdjacentTextNode(n)) {
sb.append(n.getNodeValue());
}
return sb.toString();
}
/**
* DOM: Implements
* {@link org.w3c.dom.Text#isElementContentWhitespace()}.
*/
public boolean isElementContentWhitespace() {
int len = nodeValue.length();
for (int i = 0; i < len; i++) {
if (!XMLUtilities.isXMLSpace(nodeValue.charAt(i))) {
return false;
}
}
Node p = getParentNode();
if (p.getNodeType() == Node.ELEMENT_NODE) {
String sp = XMLSupport.getXMLSpace((Element) p);
return !sp.equals(XMLConstants.XML_PRESERVE_VALUE);
}
return true;
}
/**
* DOM: Implements {@link org.w3c.dom.Text#replaceWholeText(String)}.
*/
public Text replaceWholeText(String s) throws DOMException {
for (Node n = getPreviousLogicallyAdjacentTextNode(this);
n != null;
n = getPreviousLogicallyAdjacentTextNode(n)) {
AbstractNode an = (AbstractNode) n;
if (an.isReadonly()) {
throw createDOMException
(DOMException.NO_MODIFICATION_ALLOWED_ERR,
"readonly.node",
new Object[] {(int) n.getNodeType(),
n.getNodeName() });
}
}
for (Node n = getNextLogicallyAdjacentTextNode(this);
n != null;
n = getNextLogicallyAdjacentTextNode(n)) {
AbstractNode an = (AbstractNode) n;
if (an.isReadonly()) {
throw createDOMException
(DOMException.NO_MODIFICATION_ALLOWED_ERR,
"readonly.node",
new Object[] {(int) n.getNodeType(),
n.getNodeName() });
}
}
Node parent = getParentNode();
for (Node n = getPreviousLogicallyAdjacentTextNode(this);
n != null;
n = getPreviousLogicallyAdjacentTextNode(n)) {
parent.removeChild(n);
}
for (Node n = getNextLogicallyAdjacentTextNode(this);
n != null;
n = getNextLogicallyAdjacentTextNode(n)) {
parent.removeChild(n);
}
if (isReadonly()) {
Text t = createTextNode(s);
parent.replaceChild(t, this);
return t;
}
setNodeValue(s);
return this;
}
/**
* DOM: Implements {@link org.w3c.dom.Node#getTextContent()}.
*/
public String getTextContent() {
if (isElementContentWhitespace()) {
return "";
}
return getNodeValue();
}
/**
* Creates a text node of the current type.
*/
protected abstract Text createTextNode(String text);
}