summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dalvik/src/main/java/dalvik/system/VMDebug.java24
-rw-r--r--luni-kernel/src/main/java/java/lang/Class.java66
-rw-r--r--luni/src/main/java/java/net/InetAddress.java16
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/dom/CDATASectionImpl.java2
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/dom/CharacterDataImpl.java7
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/dom/DOMImplementationImpl.java2
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/dom/DocumentImpl.java2
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/dom/NodeImpl.java4
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/dom/TextImpl.java84
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderImpl.java54
-rw-r--r--xml/src/test/java/tests/api/javax/xml/parsers/DocumentBuilderTest.java30
-rw-r--r--xml/src/test/java/tests/api/javax/xml/parsers/SAXParserTest.java3
-rw-r--r--xml/src/test/java/tests/xml/AllTests.java1
-rw-r--r--xml/src/test/java/tests/xml/DomTest.java137
14 files changed, 279 insertions, 153 deletions
diff --git a/dalvik/src/main/java/dalvik/system/VMDebug.java b/dalvik/src/main/java/dalvik/system/VMDebug.java
index ce3e95c..6f64c5f 100644
--- a/dalvik/src/main/java/dalvik/system/VMDebug.java
+++ b/dalvik/src/main/java/dalvik/system/VMDebug.java
@@ -34,6 +34,8 @@ import java.io.IOException;
public final class VMDebug {
/**
* Specifies the default method trace data file name.
+ *
+ * @deprecated only used in one place, which is unused and deprecated
*/
static public final String DEFAULT_METHOD_TRACE_FILE_NAME = "/sdcard/dmtrace.trace";
@@ -44,11 +46,13 @@ public final class VMDebug {
public static final int TRACE_COUNT_ALLOCS = 1;
/* constants for getAllocCount */
- private static final int KIND_ALLOCATED_OBJECTS = 1<<0;
- private static final int KIND_ALLOCATED_BYTES = 1<<1;
- private static final int KIND_FREED_OBJECTS = 1<<2;
- private static final int KIND_FREED_BYTES = 1<<3;
- private static final int KIND_GC_INVOCATIONS = 1<<4;
+ private static final int KIND_ALLOCATED_OBJECTS = 1<<0;
+ private static final int KIND_ALLOCATED_BYTES = 1<<1;
+ private static final int KIND_FREED_OBJECTS = 1<<2;
+ private static final int KIND_FREED_BYTES = 1<<3;
+ private static final int KIND_GC_INVOCATIONS = 1<<4;
+ private static final int KIND_CLASS_INIT_COUNT = 1<<5;
+ private static final int KIND_CLASS_INIT_TIME = 1<<6;
private static final int KIND_EXT_ALLOCATED_OBJECTS = 1<<12;
private static final int KIND_EXT_ALLOCATED_BYTES = 1<<13;
private static final int KIND_EXT_FREED_OBJECTS = 1<<14;
@@ -64,6 +68,10 @@ public final class VMDebug {
KIND_FREED_BYTES;
public static final int KIND_GLOBAL_GC_INVOCATIONS =
KIND_GC_INVOCATIONS;
+ public static final int KIND_GLOBAL_CLASS_INIT_COUNT =
+ KIND_CLASS_INIT_COUNT;
+ public static final int KIND_GLOBAL_CLASS_INIT_TIME =
+ KIND_CLASS_INIT_TIME;
public static final int KIND_GLOBAL_EXT_ALLOCATED_OBJECTS =
KIND_EXT_ALLOCATED_OBJECTS;
public static final int KIND_GLOBAL_EXT_ALLOCATED_BYTES =
@@ -83,6 +91,10 @@ public final class VMDebug {
KIND_FREED_BYTES << 16;
public static final int KIND_THREAD_GC_INVOCATIONS =
KIND_GC_INVOCATIONS << 16;
+ public static final int KIND_THREAD_CLASS_INIT_COUNT =
+ KIND_CLASS_INIT_COUNT << 16;
+ public static final int KIND_THREAD_CLASS_INIT_TIME =
+ KIND_CLASS_INIT_TIME << 16;
public static final int KIND_THREAD_EXT_ALLOCATED_OBJECTS =
KIND_EXT_ALLOCATED_OBJECTS << 16;
public static final int KIND_THREAD_EXT_ALLOCATED_BYTES =
@@ -131,6 +143,8 @@ public final class VMDebug {
/**
* Start method tracing with default name, size, and with <code>0</code>
* flags.
+ *
+ * @deprecated not used, not needed
*/
public static void startMethodTracing() {
startMethodTracing(DEFAULT_METHOD_TRACE_FILE_NAME, 0, 0);
diff --git a/luni-kernel/src/main/java/java/lang/Class.java b/luni-kernel/src/main/java/java/lang/Class.java
index b8e3903..101d593 100644
--- a/luni-kernel/src/main/java/java/lang/Class.java
+++ b/luni-kernel/src/main/java/java/lang/Class.java
@@ -177,7 +177,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* @throws ExceptionInInitializerError
* if an exception occurs during static initialization of a
* class.
- * @since Android 1.0
*/
public static Class<?> forName(String className) throws ClassNotFoundException {
return forName(className, true, VMStack.getCallingClassLoader());
@@ -210,7 +209,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* @throws ExceptionInInitializerError
* if an exception occurs during static initialization of a
* class.
- * @since Android 1.0
*/
public static Class<?> forName(String className, boolean initializeBoolean,
ClassLoader classLoader) throws ClassNotFoundException {
@@ -270,7 +268,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* @throws SecurityException
* if a security manager exists and it does not allow member
* access.
- * @since Android 1.0
*/
public Class[] getClasses() {
// BEGIN android-note
@@ -289,7 +286,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* the annotation type.
* @return the annotation of the given type, or {@code null} if there is no
* such annotation.
- * @since Android 1.0
*/
@SuppressWarnings("unchecked")
public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
@@ -309,7 +305,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
*
* @return a copy of the array containing this class' annotations.
* @see #getDeclaredAnnotations()
- * @since Android 1.0
*/
public Annotation[] getAnnotations() {
/*
@@ -353,7 +348,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
*
* @return this class' canonical name, or {@code null} if it does not have a
* canonical name.
- * @since Android 1.0
*/
public String getCanonicalName() {
if (isLocalClass() || isAnonymousClass())
@@ -403,7 +397,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* if a security manager exists and it does not allow accessing
* the class loader.
* @see ClassLoader
- * @since Android 1.0
*/
public ClassLoader getClassLoader() {
SecurityManager smgr = System.getSecurityManager();
@@ -459,7 +452,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* the type of the elements of the array.
*
* @return the component type of this class.
- * @since Android 1.0
*/
public native Class<?> getComponentType();
@@ -477,7 +469,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* if a security manager exists and it does not allow member
* access.
* @see #getDeclaredConstructor(Class...)
- * @since Android 1.0
*/
@SuppressWarnings("unchecked")
public Constructor<T> getConstructor(Class... parameterTypes) throws NoSuchMethodException,
@@ -498,7 +489,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* if a security manager exists and it does not allow member
* access.
* @see #getDeclaredConstructors()
- * @since Android 1.0
*/
public Constructor[] getConstructors() throws SecurityException {
// BEGIN android-note
@@ -518,7 +508,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* @return a copy of the array containing the annotations defined for the
* class that this {@code Class} represents.
* @see #getAnnotations()
- * @since Android 1.0
*/
native public Annotation[] getDeclaredAnnotations();
@@ -534,7 +523,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* @throws SecurityException
* if a security manager exists and it does not allow member
* access.
- * @since Android 1.0
*/
public Class[] getDeclaredClasses() throws SecurityException {
// BEGIN android-note
@@ -596,7 +584,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* if a security manager exists and it does not allow member
* access.
* @see #getConstructor(Class...)
- * @since Android 1.0
*/
@SuppressWarnings("unchecked")
public Constructor<T> getDeclaredConstructor(Class... parameterTypes)
@@ -618,7 +605,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* if a security manager exists and it does not allow member
* access.
* @see #getConstructors()
- * @since Android 1.0
*/
public Constructor[] getDeclaredConstructors() throws SecurityException {
// BEGIN android-note
@@ -688,7 +674,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* if a security manager exists and it does not allow member
* access.
* @see #getField(String)
- * @since Android 1.0
*/
public Field getDeclaredField(String name)
throws NoSuchFieldException, SecurityException {
@@ -716,7 +701,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* if a security manager exists and it does not allow member
* access.
* @see #getFields()
- * @since Android 1.0
*/
public Field[] getDeclaredFields() throws SecurityException {
checkDeclaredMemberAccess();
@@ -755,7 +739,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* if a security manager exists and it does not allow member
* access.
* @see #getMethod(String, Class...)
- * @since Android 1.0
*/
public Method getDeclaredMethod(String name, Class... parameterTypes)
throws NoSuchMethodException, SecurityException {
@@ -783,7 +766,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* if a security manager exists and it does not allow member
* access.
* @see #getMethods()
- * @since Android 1.0
*/
public Method[] getDeclaredMethods() throws SecurityException {
checkDeclaredMemberAccess();
@@ -829,7 +811,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* {@code Class} represents an array class, a primitive type or void.
*
* @return the declaring {@code Class} or {@code null}.
- * @since Android 1.0
*/
native public Class<?> getDeclaringClass();
@@ -838,7 +819,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* enclosing class the method returns {@code null}.
*
* @return the enclosing {@code Class} or {@code null}.
- * @since Android 1.0
*/
native public Class<?> getEnclosingClass();
@@ -847,7 +827,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* anonymous or local/automatic class; otherwise {@code null}.
*
* @return the enclosing {@code Constructor} instance or {@code null}.
- * @since Android 1.0
*/
native public Constructor<?> getEnclosingConstructor();
@@ -856,7 +835,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* anonymous or local/automatic class; otherwise {@code null}.
*
* @return the enclosing {@code Method} instance or {@code null}.
- * @since Android 1.0
*/
native public Method getEnclosingMethod();
@@ -866,7 +844,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* enum} type.
*
* @return an array with the {@code enum} constants or {@code null}.
- * @since Android 1.0
*/
@SuppressWarnings("unchecked")
public T[] getEnumConstants() {
@@ -896,7 +873,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* if a security manager exists and it does not allow member
* access.
* @see #getDeclaredField(String)
- * @since Android 1.0
*/
public Field getField(String name) throws NoSuchFieldException, SecurityException {
checkPublicMemberAccess();
@@ -927,7 +903,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* if a security manager exists and it does not allow member
* access.
* @see #getDeclaredFields()
- * @since Android 1.0
*/
public Field[] getFields() throws SecurityException {
checkPublicMemberAccess();
@@ -944,7 +919,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
*
* @return an array of {@link Type} instances directly implemented by the
* class represented by this {@code class}.
- * @since Android 1.0
*/
public Type[] getGenericInterfaces() {
GenericSignatureParser parser = new GenericSignatureParser(
@@ -958,7 +932,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* class}.
*
* @return an instance of {@code Type} representing the superclass.
- * @since Android 1.0
*/
public Type getGenericSuperclass() {
GenericSignatureParser parser = new GenericSignatureParser(
@@ -976,7 +949,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
*
* @return an array with the interfaces of the class represented by this
* class.
- * @since Android 1.0
*/
public native Class[] getInterfaces();
// BEGIN android-note
@@ -1004,7 +976,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* if a security manager exists and it does not allow member
* access.
* @see #getDeclaredMethod(String, Class...)
- * @since Android 1.0
*/
public Method getMethod(String name, Class... parameterTypes) throws NoSuchMethodException,
SecurityException {
@@ -1036,7 +1007,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* if a security manager exists and it does not allow member
* access.
* @see #getDeclaredMethods()
- * @since Android 1.0
*/
public Method[] getMethods() throws SecurityException {
checkPublicMemberAccess();
@@ -1097,7 +1067,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* defined by constants in the {@link Modifier} class.
*
* @return the modifiers of the class represented by this {@code Class}.
- * @since Android 1.0
*/
public int getModifiers() {
return getModifiers(this, false);
@@ -1118,7 +1087,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* {@link Class}.
*
* @return the name of the class represented by this {@code Class}.
- * @since Android 1.0
*/
public native String getName();
@@ -1130,7 +1098,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* example {@code &quot;Integer[]&quot;}) is returned.
*
* @return the simple name of the class represented by this {@code Class}.
- * @since Android 1.0
*/
public String getSimpleName() {
if (isArray()) {
@@ -1199,7 +1166,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* @return the requested resource's {@code URL} object or {@code null} if
* the resource can not be found.
* @see ClassLoader
- * @since Android 1.0
*/
public URL getResource(String resName) {
// Get absolute resource name, but without the leading slash
@@ -1236,7 +1202,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* @return a stream for the requested resource or {@code null} if no
* resource with the specified name can be found.
* @see ClassLoader
- * @since Android 1.0
*/
public InputStream getResourceAsStream(String resName) {
// Get absolute resource name, but without the leading slash
@@ -1264,15 +1229,15 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
}
/**
- * Returns the signers for the class represented by this {@code Class} or
- * {@code null} if either there are no signers or this {@code Class}
- * represents a primitive type or void.
+ * Returns null. (On Android, a {@code ClassLoader} can load classes from multiple dex files.
+ * All classes from any given dex file will have the same signers, but different dex
+ * files may have different signers. This does not fit well with the original
+ * {@code ClassLoader}-based model of {@code getSigners}.)
*
- * @return the signers of the class represented by this {@code Class}.
- * @since Android 1.0
+ * @return null.
*/
public Object[] getSigners() {
- // TODO Delegate this to class loader somehow? What are these signers?
+ // See http://code.google.com/p/android/issues/detail?id=1766.
return null;
}
@@ -1284,7 +1249,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* class then the {@code Object} class is returned.
*
* @return the superclass of the class represented by this {@code Class}.
- * @since Android 1.0
*/
public native Class<? super T> getSuperclass();
@@ -1295,7 +1259,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
*
* @return an array with the type variables of the class represented by this
* class.
- * @since Android 1.0
*/
@SuppressWarnings("unchecked")
public synchronized TypeVariable<Class<T>>[] getTypeParameters() {
@@ -1310,7 +1273,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
*
* @return {@code true} if this {@code Class} represents an annotation
* class; {@code false} otherwise.
- * @since Android 1.0
*/
public boolean isAnnotation() {
final int ACC_ANNOTATION = 0x2000; // not public in reflect.Modifiers
@@ -1326,7 +1288,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* the annotation to look for.
* @return {@code true} if the class represented by this {@code Class} is
* annotated with {@code annotationClass}; {@code false} otherwise.
- * @since Android 1.0
*/
public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
return getAnnotation(annotationClass) != null;
@@ -1338,7 +1299,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
*
* @return {@code true} if the class represented by this {@code Class} is
* anonymous; {@code false} otherwise.
- * @since Android 1.0
*/
native public boolean isAnonymousClass();
@@ -1348,7 +1308,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
*
* @return {@code true} if the class represented by this {@code Class} is an
* array class; {@code false} otherwise.
- * @since Android 1.0
*/
public boolean isArray() {
return getComponentType() != null;
@@ -1367,7 +1326,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* represented by this {@code Class}; {@code false} otherwise.
* @throws NullPointerException
* if {@code cls} is {@code null}.
- * @since Android 1.0
*/
public native boolean isAssignableFrom(Class<?> cls);
@@ -1377,7 +1335,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
*
* @return {@code true} if the class represented by this {@code Class} is an
* {@code enum}; {@code false} otherwise.
- * @since Android 1.0
*/
public boolean isEnum() {
return ((getModifiers() & 0x4000) != 0) && (getSuperclass() == Enum.class);
@@ -1393,7 +1350,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* @return {@code true} if {@code object} can be cast to the type
* represented by this {@code Class}; {@code false} if {@code
* object} is {@code null} or cannot be cast.
- * @since Android 1.0
*/
public native boolean isInstance(Object object);
@@ -1402,7 +1358,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
*
* @return {@code true} if this {@code Class} represents an interface;
* {@code false} otherwise.
- * @since Android 1.0
*/
public native boolean isInterface();
@@ -1412,7 +1367,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
*
* @return {@code true} if the class represented by this {@code Class} is
* defined locally; {@code false} otherwise.
- * @since Android 1.0
*/
public boolean isLocalClass() {
boolean enclosed = (getEnclosingMethod() != null ||
@@ -1426,7 +1380,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
*
* @return {@code true} if the class represented by this {@code Class} is a
* member class; {@code false} otherwise.
- * @since Android 1.0
*/
public boolean isMemberClass() {
return getDeclaringClass() != null;
@@ -1437,7 +1390,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
*
* @return {@code true} if this {@code Class} represents a primitive type;
* {@code false} otherwise.
- * @since Android 1.0
*/
public native boolean isPrimitive();
@@ -1446,7 +1398,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
*
* @return {@code true} if this {@code Class} represents a synthetic type;
* {@code false} otherwise.
- * @since Android 1.0
*/
public boolean isSynthetic() {
final int ACC_SYNTHETIC = 0x1000; // not public in reflect.Modifiers
@@ -1471,7 +1422,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* @throws SecurityException
* if a security manager exists and it does not allow creating
* new instances.
- * @since Android 1.0
*/
public T newInstance() throws IllegalAccessException,
InstantiationException {
@@ -1498,7 +1448,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
*
* @return Package the {@code Package} of which this {@code Class} is a
* member or {@code null}.
- * @since Android 1.0
*/
public Package getPackage() {
// TODO This might be a hack, but the VM doesn't have the necessary info.
@@ -1519,7 +1468,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
*
* @return the assertion status for the class represented by this {@code
* Class}.
- * @since Android 1.0
*/
public native boolean desiredAssertionStatus();
@@ -1533,7 +1481,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* @return this {@code Class} cast as a subclass of the given type.
* @throws ClassCastException
* if this {@code Class} cannot be cast to the specified type.
- * @since Android 1.0
*/
@SuppressWarnings("unchecked")
public <U> Class<? extends U> asSubclass(Class<U> clazz) {
@@ -1552,7 +1499,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* @return the object that has been cast.
* @throws ClassCastException
* if the object cannot be cast to the specified type.
- * @since Android 1.0
*/
@SuppressWarnings("unchecked")
public T cast(Object obj) {
diff --git a/luni/src/main/java/java/net/InetAddress.java b/luni/src/main/java/java/net/InetAddress.java
index fccfc4c..ad96ed6 100644
--- a/luni/src/main/java/java/net/InetAddress.java
+++ b/luni/src/main/java/java/net/InetAddress.java
@@ -187,12 +187,6 @@ public class InetAddress implements Serializable {
}
};
- static final Comparator<byte[]> LONGEST_FIRST = new Comparator<byte[]>() {
- public int compare(byte[] a1, byte[] a2) {
- return a2.length - a1.length;
- }
- };
-
/**
* Converts an array of byte arrays representing raw IP addresses of a host
* to an array of InetAddress objects, sorting to respect the value of the
@@ -204,10 +198,12 @@ public class InetAddress implements Serializable {
*/
static InetAddress[] bytesToInetAddresses(byte[][] rawAddresses,
String hostName) {
- // Sort the raw byte arrays.
- Comparator<byte[]> comparator = NetUtil.preferIPv6Addresses()
- ? LONGEST_FIRST : SHORTEST_FIRST;
- Arrays.sort(rawAddresses, comparator);
+ // If we prefer IPv4, ignore the RFC3484 ordering we get from getaddrinfo
+ // and always put IPv4 addresses first. Arrays.sort() is stable, so the
+ // internal ordering will not be changed.
+ if (!NetUtil.preferIPv6Addresses()) {
+ Arrays.sort(rawAddresses, SHORTEST_FIRST);
+ }
// Convert the byte arrays to InetAddresses.
InetAddress[] returnedAddresses = new InetAddress[rawAddresses.length];
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/CDATASectionImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/CDATASectionImpl.java
index 33e216a..b28c9da 100644
--- a/xml/src/main/java/org/apache/harmony/xml/dom/CDATASectionImpl.java
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/CDATASectionImpl.java
@@ -31,7 +31,7 @@ import org.w3c.dom.Node;
*/
public class CDATASectionImpl extends TextImpl implements CDATASection {
- CDATASectionImpl(DocumentImpl document, String data) {
+ public CDATASectionImpl(DocumentImpl document, String data) {
super(document, data);
}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/CharacterDataImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/CharacterDataImpl.java
index c39423c..6354747 100644
--- a/xml/src/main/java/org/apache/harmony/xml/dom/CharacterDataImpl.java
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/CharacterDataImpl.java
@@ -51,6 +51,13 @@ public abstract class CharacterDataImpl extends LeafNodeImpl implements
return buffer.toString();
}
+ /**
+ * Appends this node's text content to the given builder.
+ */
+ public void appendDataTo(StringBuilder stringBuilder) {
+ stringBuilder.append(buffer);
+ }
+
public int getLength() {
return buffer.length();
}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/DOMImplementationImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/DOMImplementationImpl.java
index 834cc47..1283eeb 100644
--- a/xml/src/main/java/org/apache/harmony/xml/dom/DOMImplementationImpl.java
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/DOMImplementationImpl.java
@@ -31,7 +31,7 @@ import org.w3c.dom.DocumentType;
* the DOM implementation can easily access them while maintaining the DOM tree
* structure.
*/
-public class DOMImplementationImpl implements DOMImplementation {
+public final class DOMImplementationImpl implements DOMImplementation {
// Singleton instance.
private static DOMImplementationImpl instance;
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/DocumentImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/DocumentImpl.java
index c8819cb..b2f16d1 100644
--- a/xml/src/main/java/org/apache/harmony/xml/dom/DocumentImpl.java
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/DocumentImpl.java
@@ -48,7 +48,7 @@ public class DocumentImpl extends InnerNodeImpl implements Document {
private DOMImplementation domImplementation;
- DocumentImpl(DOMImplementationImpl impl, String namespaceURI,
+ public DocumentImpl(DOMImplementationImpl impl, String namespaceURI,
String qualifiedName, DocumentType doctype) {
super(null);
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/NodeImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/NodeImpl.java
index ebfdd52..24ed102 100644
--- a/xml/src/main/java/org/apache/harmony/xml/dom/NodeImpl.java
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/NodeImpl.java
@@ -224,7 +224,6 @@ public abstract class NodeImpl implements Node {
* account null arguments and the "*" special case.
*
* @param name The required name.
- * @param wildcard TODO
* @return True if and only if the actual name matches the required one.
*/
public boolean matchesName(String name, boolean wildcard) {
@@ -238,7 +237,6 @@ public abstract class NodeImpl implements Node {
*
* @param namespaceURI The required namespace.
* @param localName The required local name.
- * @param wildcard TODO
* @return True if and only if the actual namespace and local name match
* the required pair of namespace and local name.
*/
@@ -309,7 +307,7 @@ public abstract class NodeImpl implements Node {
removeChild(child);
}
// create a text node to hold the given content
- if (textContent != null && textContent.length() != 0){
+ if (textContent != null && textContent.length() != 0) {
appendChild(getOwnerDocument().createTextNode(textContent));
}
return;
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/TextImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/TextImpl.java
index 5c9d123..3840ef4 100644
--- a/xml/src/main/java/org/apache/harmony/xml/dom/TextImpl.java
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/TextImpl.java
@@ -32,7 +32,7 @@ import org.w3c.dom.Text;
*/
public class TextImpl extends CharacterDataImpl implements Text {
- TextImpl(DocumentImpl document, String data) {
+ public TextImpl(DocumentImpl document, String data) {
super(document, data);
}
@@ -46,7 +46,7 @@ public class TextImpl extends CharacterDataImpl implements Text {
return Node.TEXT_NODE;
}
- public Text splitText(int offset) throws DOMException {
+ public final Text splitText(int offset) throws DOMException {
Text newText = getOwnerDocument().createTextNode(
substringData(offset, getLength() - offset));
deleteData(0, offset);
@@ -61,15 +61,83 @@ public class TextImpl extends CharacterDataImpl implements Text {
return this;
}
- public boolean isElementContentWhitespace() {
- throw new UnsupportedOperationException(); // TODO
+ public final boolean isElementContentWhitespace() {
+ // Undefined because we don't validate. Whether whitespace characters
+ // constitute "element content whitespace" is defined by the containing
+ // element's declaration (DTD) and we don't parse that.
+ // TODO: wire this up when we support document validation
+ return false;
}
- public String getWholeText() {
- throw new UnsupportedOperationException(); // TODO
+ public final String getWholeText() {
+ // TODO: support entity references. This code should expand through
+ // the child elements of entity references.
+ // http://code.google.com/p/android/issues/detail?id=6807
+
+ StringBuilder result = new StringBuilder();
+ for (TextImpl n = firstTextNodeInCurrentRun(); n != null; n = n.nextTextNode()) {
+ n.appendDataTo(result);
+ }
+ return result.toString();
}
- public Text replaceWholeText(String content) throws DOMException {
- throw new UnsupportedOperationException(); // TODO
+ public final Text replaceWholeText(String content) throws DOMException {
+ // TODO: support entity references. This code should expand and replace
+ // the child elements of entity references.
+ // http://code.google.com/p/android/issues/detail?id=6807
+
+ Node parent = getParentNode();
+ Text result = null;
+
+ // delete all nodes in the current run of text...
+ for (TextImpl n = firstTextNodeInCurrentRun(); n != null; ) {
+
+ // ...except the current node if we have content for it
+ if (n == this && content != null && content.length() > 0) {
+ setData(content);
+ result = this;
+ n = n.nextTextNode();
+
+ } else {
+ Node toRemove = n; // because removeChild() detaches siblings
+ n = n.nextTextNode();
+ parent.removeChild(toRemove);
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Returns the first text or CDATA node in the current sequence of text and
+ * CDATA nodes.
+ */
+ private TextImpl firstTextNodeInCurrentRun() {
+ TextImpl firstTextInCurrentRun = this;
+ for (Node p = getPreviousSibling(); p != null; p = p.getPreviousSibling()) {
+ short nodeType = p.getNodeType();
+ if (nodeType == Node.TEXT_NODE || nodeType == Node.CDATA_SECTION_NODE) {
+ firstTextInCurrentRun = (TextImpl) p;
+ } else {
+ break;
+ }
+ }
+ return firstTextInCurrentRun;
+ }
+
+ /**
+ * Returns the next sibling node if it exists and it is text or CDATA.
+ * Otherwise returns null.
+ */
+ private TextImpl nextTextNode() {
+ Node nextSibling = getNextSibling();
+ if (nextSibling == null) {
+ return null;
+ }
+
+ short nodeType = nextSibling.getNodeType();
+ return nodeType == Node.TEXT_NODE || nodeType == Node.CDATA_SECTION_NODE
+ ? (TextImpl) nextSibling
+ : null;
}
}
diff --git a/xml/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderImpl.java b/xml/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderImpl.java
index 52240aa..ca2ff98 100644
--- a/xml/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderImpl.java
+++ b/xml/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderImpl.java
@@ -23,10 +23,14 @@ import java.util.StringTokenizer;
import javax.xml.parsers.DocumentBuilder;
+import org.apache.harmony.xml.dom.CDATASectionImpl;
+import org.apache.harmony.xml.dom.DocumentImpl;
+import org.apache.harmony.xml.dom.TextImpl;
import org.kxml2.io.KXmlParser;
import org.w3c.dom.Attr;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
+import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.Text;
@@ -49,7 +53,7 @@ import org.apache.harmony.xml.dom.DOMImplementationImpl;
*/
class DocumentBuilderImpl extends DocumentBuilder {
- private static DOMImplementation dom = DOMImplementationImpl.getInstance();
+ private static DOMImplementationImpl dom = DOMImplementationImpl.getInstance();
private boolean coalescing;
@@ -72,25 +76,6 @@ class DocumentBuilderImpl extends DocumentBuilder {
return dom;
}
- /**
- * Reflects whether this DocumentBuilder is configured to ignore comments.
- *
- * @return True if and only if comments are ignored.
- */
- public boolean isIgnoringComments() {
- return ignoreComments;
- }
-
- /**
- * Reflects whether this DocumentBuilder is configured to ignore element
- * content whitespace.
- *
- * @return True if and only if whitespace element content is ignored.
- */
- public boolean isIgnoringElementContentWhitespace() {
- return ignoreElementContentWhitespace;
- }
-
@Override
public boolean isNamespaceAware() {
return namespaceAware;
@@ -112,7 +97,10 @@ class DocumentBuilderImpl extends DocumentBuilder {
throw new IllegalArgumentException();
}
- Document document = newDocument();
+ String namespaceURI = null;
+ String qualifiedName = null;
+ DocumentType doctype = null;
+ DocumentImpl document = new DocumentImpl(dom, namespaceURI, qualifiedName, doctype);
try {
KXmlParser parser = new KXmlParser();
@@ -189,7 +177,7 @@ class DocumentBuilderImpl extends DocumentBuilder {
* @throws XmlPullParserException If a parsing error occurs.
* @throws IOException If a general IO error occurs.
*/
- private void parse(XmlPullParser parser, Document document, Node node,
+ private void parse(XmlPullParser parser, DocumentImpl document, Node node,
int endToken) throws XmlPullParserException, IOException {
int token = parser.getEventType();
@@ -271,7 +259,7 @@ class DocumentBuilderImpl extends DocumentBuilder {
* whitespace at all.
*/
if (!ignoreElementContentWhitespace) {
- appendText(document, node, true, parser.getText());
+ appendText(document, node, token, parser.getText());
}
} else if (token == XmlPullParser.TEXT || token == XmlPullParser.CDSECT) {
/*
@@ -279,7 +267,7 @@ class DocumentBuilderImpl extends DocumentBuilder {
* That's the easiest case. We simply take it and create a new text node,
* or merge with an adjacent text node.
*/
- appendText(document, node, token == XmlPullParser.TEXT, parser.getText());
+ appendText(document, node, token, parser.getText());
} else if (token == XmlPullParser.ENTITY_REF) {
/*
* Found an entity reference. If an entity resolver is
@@ -294,7 +282,7 @@ class DocumentBuilderImpl extends DocumentBuilder {
String replacement = resolveStandardEntity(entity);
if (replacement != null) {
- appendText(document, node, true, replacement);
+ appendText(document, node, token, replacement);
} else {
node.appendChild(document.createEntityReference(entity));
}
@@ -380,17 +368,17 @@ class DocumentBuilderImpl extends DocumentBuilder {
}
/**
- * @param isText true for a normal TextNode, false for a CDATA section.
- * (If we're not coalescing, it matters which kind of node we put into the DOM.)
+ * @param token the XML pull parser token type, such as XmlPullParser.CDSECT
+ * or XmlPullParser.ENTITY_REF.
*/
- private void appendText(Document document, Node node, boolean isText, String text) {
+ private void appendText(DocumentImpl document, Node parent, int token, String text) {
// Ignore empty runs.
if (text.length() == 0) {
return;
}
// Merge with any previous text node if possible.
if (coalescing) {
- Node lastChild = node.getLastChild();
+ Node lastChild = parent.getLastChild();
if (lastChild != null && lastChild.getNodeType() == Node.TEXT_NODE) {
Text textNode = (Text) lastChild;
textNode.setData(textNode.getNodeValue() + text);
@@ -398,11 +386,9 @@ class DocumentBuilderImpl extends DocumentBuilder {
}
}
// Okay, we really do need a new text node
- if (isText) {
- node.appendChild(document.createTextNode(text));
- } else {
- node.appendChild(document.createCDATASection(text));
- }
+ parent.appendChild(token == XmlPullParser.CDSECT
+ ? new CDATASectionImpl(document, text)
+ : new TextImpl(document, text));
}
@Override
diff --git a/xml/src/test/java/tests/api/javax/xml/parsers/DocumentBuilderTest.java b/xml/src/test/java/tests/api/javax/xml/parsers/DocumentBuilderTest.java
index 6b10a0d..ea7abed 100644
--- a/xml/src/test/java/tests/api/javax/xml/parsers/DocumentBuilderTest.java
+++ b/xml/src/test/java/tests/api/javax/xml/parsers/DocumentBuilderTest.java
@@ -562,24 +562,18 @@ public class DocumentBuilderTest extends TestCase {
method = "parse",
args = {java.lang.String.class}
)
- public void test_parseLjava_lang_String() {
+ public void test_parseLjava_lang_String() throws Exception {
// case 1: Trivial use.
File f = new File(getClass().getResource("/simple.xml").getFile());
- try {
- Document d = db.parse(f.getAbsolutePath());
- assertNotNull(d);
+ Document d = db.parse(f.getAbsolutePath());
+ assertNotNull(d);
// TBD getXmlEncoding() is not supported
// assertEquals("ISO-8859-1", d.getXmlEncoding());
- assertEquals(2, d.getChildNodes().getLength());
- assertEquals("#comment",
- d.getChildNodes().item(0).getNodeName());
- assertEquals("breakfast_menu",
- d.getChildNodes().item(1).getNodeName());
- } catch (IOException ioe) {
- fail("Unexpected IOException " + ioe.toString());
- } catch (SAXException sax) {
- fail("Unexpected SAXException " + sax.toString());
- }
+ assertEquals(2, d.getChildNodes().getLength());
+ assertEquals("#comment",
+ d.getChildNodes().item(0).getNodeName());
+ assertEquals("breakfast_menu",
+ d.getChildNodes().item(1).getNodeName());
// case 2: Try to call parse with null argument
try {
@@ -587,10 +581,6 @@ public class DocumentBuilderTest extends TestCase {
fail("Expected IllegalArgumentException was not thrown");
} catch (IllegalArgumentException iae) {
// expected
- } catch (IOException ioe) {
- fail("Unexpected IOException " + ioe.toString());
- } catch (SAXException sax) {
- fail("Unexpected SAXException " + sax.toString());
}
// case 3: Try to parse a non-existent uri
@@ -599,8 +589,6 @@ public class DocumentBuilderTest extends TestCase {
fail("Expected IOException was not thrown");
} catch (IOException ioe) {
// expected
- } catch (SAXException sax) {
- fail("Unexpected SAXException " + sax.toString());
}
// case 4: Try to parse incorrect xml file
@@ -608,8 +596,6 @@ public class DocumentBuilderTest extends TestCase {
f = new File(getClass().getResource("/wrong.xml").getFile());
db.parse(f.getAbsolutePath());
fail("Expected SAXException was not thrown");
- } catch (IOException ioe) {
- fail("Unexpected IOException " + ioe.toString());
} catch (SAXException sax) {
// expected
}
diff --git a/xml/src/test/java/tests/api/javax/xml/parsers/SAXParserTest.java b/xml/src/test/java/tests/api/javax/xml/parsers/SAXParserTest.java
index ca7cf71..e6d6481 100644
--- a/xml/src/test/java/tests/api/javax/xml/parsers/SAXParserTest.java
+++ b/xml/src/test/java/tests/api/javax/xml/parsers/SAXParserTest.java
@@ -677,8 +677,7 @@ public class SAXParserTest extends TestCase {
MyDefaultHandler dh = new MyDefaultHandler();
InputStream is = new FileInputStream(list_wf[i]);
parser.parse(is, dh, SAXParserTestSupport.XML_SYSTEM_ID);
- assertTrue(SAXParserTestSupport.equalsMaps(hm,
- dh.createData()));
+ assertEquals(hm, dh.createData());
} catch (IOException ioe) {
fail("Unexpected IOException " + ioe.toString());
} catch (SAXException sax) {
diff --git a/xml/src/test/java/tests/xml/AllTests.java b/xml/src/test/java/tests/xml/AllTests.java
index 89da364..597e35e 100644
--- a/xml/src/test/java/tests/xml/AllTests.java
+++ b/xml/src/test/java/tests/xml/AllTests.java
@@ -24,6 +24,7 @@ public class AllTests {
public static Test suite() {
TestSuite suite = tests.TestSuiteFactory.createTestSuite();
+ suite.addTestSuite(DomTest.class);
suite.addTestSuite(SimpleParserTest.class);
suite.addTestSuite(SimpleBuilderTest.class);
suite.addTestSuite(NodeTest.class);
diff --git a/xml/src/test/java/tests/xml/DomTest.java b/xml/src/test/java/tests/xml/DomTest.java
index 5f0a19a..69e8b37 100644
--- a/xml/src/test/java/tests/xml/DomTest.java
+++ b/xml/src/test/java/tests/xml/DomTest.java
@@ -109,7 +109,6 @@ public class DomTest extends TestCase {
factory.setNamespaceAware(true);
builder = factory.newDocumentBuilder();
domImplementation = builder.getDOMImplementation();
-
document = builder.parse(new InputSource(new StringReader(xml)));
// doctype nodes
@@ -448,7 +447,6 @@ public class DomTest extends TestCase {
document.appendChild(root);
EntityReference entityReference = document.createEntityReference("sp");
- entityReference.setNodeValue("Maple Syrup");
root.appendChild(entityReference);
try {
@@ -461,8 +459,7 @@ public class DomTest extends TestCase {
public void testAttributeSetTextContent() throws TransformerException {
String original = domToString(document);
standard.setTextContent("foobar");
- String expected = original.replaceFirst(
- "standard=\"strawberry\"", "standard=\"foobar\"");
+ String expected = original.replace("standard=\"strawberry\"", "standard=\"foobar\"");
assertEquals(expected, domToString(document));
}
@@ -614,8 +611,136 @@ public class DomTest extends TestCase {
}
}
- private String domToString(Document document)
- throws TransformerException {
+ public void testIsElementContentWhitespaceWithoutDeclaration() throws Exception {
+ String xml = "<menu> <item/> </menu>";
+
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ Text text = (Text) factory.newDocumentBuilder()
+ .parse(new InputSource(new StringReader(xml)))
+ .getDocumentElement().getChildNodes().item(0);
+ assertFalse(text.isElementContentWhitespace());
+ }
+
+ public void testIsElementContentWhitespaceWithDeclaration() throws Exception {
+ String xml = "<!DOCTYPE menu [\n"
+ + " <!ELEMENT menu (item)*>\n"
+ + " <!ELEMENT item (#PCDATA)>\n"
+ + "]><menu> <item/> </menu>";
+
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ Text text = (Text) factory.newDocumentBuilder()
+ .parse(new InputSource(new StringReader(xml)))
+ .getDocumentElement().getChildNodes().item(0);
+ assertTrue("This implementation does not recognize element content whitespace",
+ text.isElementContentWhitespace());
+ }
+
+ public void testGetWholeTextFirst() {
+ assertEquals("Belgian waffles & strawberries (< 5g of fat)",
+ descriptionText1.getWholeText());
+ }
+
+ public void testGetWholeTextMiddle() {
+ assertEquals("This implementation doesn't include preceding nodes in getWholeText()",
+ "Belgian waffles & strawberries (< 5g of fat)", descriptionText2.getWholeText());
+ }
+
+ public void testGetWholeTextLast() {
+ assertEquals("This implementation doesn't include preceding nodes in getWholeText()",
+ "Belgian waffles & strawberries (< 5g of fat)", descriptionText3.getWholeText());
+ }
+
+ public void testGetWholeTextOnly() {
+ assertEquals("60%", vitamincText.getWholeText());
+ }
+
+ public void testGetWholeTextWithEntityReference() {
+ EntityReference spReference = document.createEntityReference("sp");
+ description.insertBefore(spReference, descriptionText2);
+
+ assertEquals("This implementation doesn't resolve entity references in getWholeText()",
+ "BelgianMaple Syrup waffles & strawberries (< 5g of fat)",
+ descriptionText1.getWholeText());
+ }
+
+ public void testReplaceWholeTextFirst() throws TransformerException {
+ String original = domToString(document);
+ Text replacement = descriptionText1.replaceWholeText("Eggos");
+ assertSame(descriptionText1, replacement);
+ String expected = original.replace(
+ "Belgian<![CDATA[ waffles & strawberries (< 5g ]]>of fat)", "Eggos");
+ assertEquals(expected, domToString(document));
+ }
+
+ public void testReplaceWholeTextMiddle() throws TransformerException {
+ String original = domToString(document);
+ Text replacement = descriptionText2.replaceWholeText("Eggos");
+ assertSame(descriptionText2, replacement);
+ String expected = original.replace(
+ "Belgian<![CDATA[ waffles & strawberries (< 5g ]]>of fat)", "<![CDATA[Eggos]]>");
+ assertEquals("This implementation doesn't remove preceding nodes in replaceWholeText()",
+ expected, domToString(document));
+ }
+
+ public void testReplaceWholeTextLast() throws TransformerException {
+ String original = domToString(document);
+ Text replacement = descriptionText3.replaceWholeText("Eggos");
+ assertSame(descriptionText3, replacement);
+ String expected = original.replace(
+ "Belgian<![CDATA[ waffles & strawberries (< 5g ]]>of fat)", "Eggos");
+ assertEquals("This implementation doesn't remove preceding nodes in replaceWholeText()",
+ expected, domToString(document));
+ }
+
+ public void testReplaceWholeTextOnly() throws TransformerException {
+ String original = domToString(document);
+ Text replacement = vitamincText.replaceWholeText("70%");
+ assertEquals(Node.TEXT_NODE, replacement.getNodeType());
+ assertSame(vitamincText, replacement);
+ String expected = original.replace("60%", "70%");
+ assertEquals(expected, domToString(document));
+ }
+
+ public void testReplaceWholeTextFirstWithNull() throws TransformerException {
+ String original = domToString(document);
+ assertNull(descriptionText1.replaceWholeText(null));
+ String expected = original.replaceFirst(">.*</description>", "/>");
+ assertEquals("This implementation doesn't remove adjacent nodes in replaceWholeText(null)",
+ expected, domToString(document));
+ }
+
+ public void testReplaceWholeTextMiddleWithNull() throws TransformerException {
+ String original = domToString(document);
+ assertNull(descriptionText2.replaceWholeText(null));
+ String expected = original.replaceFirst(">.*</description>", "/>");
+ assertEquals("This implementation doesn't remove adjacent nodes in replaceWholeText(null)",
+ expected, domToString(document));
+ }
+
+ public void testReplaceWholeTextLastWithNull() throws TransformerException {
+ String original = domToString(document);
+ assertNull(descriptionText3.replaceWholeText(null));
+ String expected = original.replaceFirst(">.*</description>", "/>");
+ assertEquals("This implementation doesn't remove adjacent nodes in replaceWholeText(null)",
+ expected, domToString(document));
+ }
+
+ public void testReplaceWholeTextFirstWithEmptyString() throws TransformerException {
+ String original = domToString(document);
+ assertNull(descriptionText1.replaceWholeText(""));
+ String expected = original.replaceFirst(">.*</description>", "/>");
+ assertEquals("This implementation doesn't remove adjacent nodes in replaceWholeText(null)",
+ expected, domToString(document));
+ }
+
+ public void testReplaceWholeTextOnlyWithEmptyString() throws TransformerException {
+ String original = domToString(document);
+ assertNull(vitamincText.replaceWholeText(""));
+ String expected = original.replaceFirst(">.*</a:vitaminc>", "/>");
+ assertEquals(expected, domToString(document));
+ }
+
+ private String domToString(Document document) throws TransformerException {
StringWriter writer = new StringWriter();
transformer.transform(new DOMSource(document), new StreamResult(writer));
return writer.toString();