From 768659fd9332e032f517c1e29a408501851ba727 Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Wed, 16 Jul 2025 17:04:16 +0100 Subject: [PATCH 1/3] Update XmlComplexContentImpl.java --- .../xmlbeans/impl/values/XmlComplexContentImpl.java | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/apache/xmlbeans/impl/values/XmlComplexContentImpl.java b/src/main/java/org/apache/xmlbeans/impl/values/XmlComplexContentImpl.java index b4ad6a119..f47be75ac 100644 --- a/src/main/java/org/apache/xmlbeans/impl/values/XmlComplexContentImpl.java +++ b/src/main/java/org/apache/xmlbeans/impl/values/XmlComplexContentImpl.java @@ -397,12 +397,10 @@ protected void arraySetterHelper(XmlObject[] sources, QName elemName, QNameSet s // up to i from the sources array into the current array, starting with // startDest int n = i; - for (; m > n - startSrc + startDest; m--) { - if (set == null) { - store.remove_element(elemName, m - 1); - } else { - store.remove_element(set, m - 1); - } + if (set == null) { + store.remove_elements_after(elemName, n - startSrc + startDest); + } else { + store.remove_elements_after(set, n - startSrc + startDest); } int j; @@ -531,14 +529,12 @@ protected void arraySetterHelper2(XmlObject[] sources, QName elemName, QNameSet // up to i from the sources array into the current array, starting with // startDest final int n = i; - if (set == null) { store.remove_elements_after(elemName, n - startSrc + startDest); } else { store.remove_elements_after(set, n - startSrc + startDest); } - final int size = Math.min(m - startDest, sources.length - startSrc); ArrayList users = new ArrayList<>(size); if (set == null) { From c5d93e1b892df78a279a93dfa812e80704a92990 Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Wed, 16 Jul 2025 19:10:33 +0100 Subject: [PATCH 2/3] remove_elements_between --- .../org/apache/xmlbeans/impl/store/Xobj.java | 66 +++++++++++++++++++ .../xmlbeans/impl/values/TypeStore.java | 20 +++++- .../impl/values/XmlComplexContentImpl.java | 12 ++-- 3 files changed, 90 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/apache/xmlbeans/impl/store/Xobj.java b/src/main/java/org/apache/xmlbeans/impl/store/Xobj.java index 7e42ebf50..300236d20 100644 --- a/src/main/java/org/apache/xmlbeans/impl/store/Xobj.java +++ b/src/main/java/org/apache/xmlbeans/impl/store/Xobj.java @@ -2303,6 +2303,39 @@ public void remove_elements_after(QName name, int i) { } } + @Override + public void remove_elements_between(final QName name, final int m, final int n) { + if (m < 0 || n < 0) { + throw new IndexOutOfBoundsException(); + } + + if (!isContainer()) { + throw new IllegalStateException(); + } + + if (m >= n) { + return; + } + + ArrayList toRemove = new ArrayList<>(); + Xobj x; + int i = m; + int count = 0; + for (x = _firstChild; x != null; x = x._nextSibling) { + if (x.isElem() && x._name.equals(name) && --i < 0) { + toRemove.add(x); + count++; + if (count >= n - m) { + break; // no need to continue if we've removed enough + } + } + } + final int size = toRemove.size(); + for (int j = size - 1; j >= 0; j--) { + removeElement(toRemove.get(j)); + } + } + @Override public void remove_element(QNameSet names, int i) { if (i < 0) { @@ -2343,6 +2376,39 @@ public void remove_elements_after(QNameSet names, int i) { } } + @Override + public void remove_elements_between(final QNameSet names, final int m, final int n) { + if (m < 0 || n < 0) { + throw new IndexOutOfBoundsException(); + } + + if (!isContainer()) { + throw new IllegalStateException(); + } + + if (m >= n) { + return; + } + + ArrayList toRemove = new ArrayList<>(); + Xobj x; + int i = m; + int count = 0; + for (x = _firstChild; x != null; x = x._nextSibling) { + if (x.isElem() && names.contains(x._name) && --i < 0) { + toRemove.add(x); + count++; + if (count >= n - m) { + break; // no need to continue if we've removed enough + } + } + } + final int size = toRemove.size(); + for (int j = size - 1; j >= 0; j--) { + removeElement(toRemove.get(j)); + } + } + public TypeStoreUser find_attribute_user(QName name) { Xobj a = getAttr(name); diff --git a/src/main/java/org/apache/xmlbeans/impl/values/TypeStore.java b/src/main/java/org/apache/xmlbeans/impl/values/TypeStore.java index 5e404bf14..51935201a 100644 --- a/src/main/java/org/apache/xmlbeans/impl/values/TypeStore.java +++ b/src/main/java/org/apache/xmlbeans/impl/values/TypeStore.java @@ -276,16 +276,30 @@ void find_multiple_element_users(QNameSet names, List f void remove_element(QNameSet names, int i); /** - * Removes all elements after the i-th element with the given name. + * Removes all elements from the i-th element with the given name. * @since 5.4.0 */ void remove_elements_after(QName name, int i); /** - * Removes all elements after the i-th element with the given name. + * Removes all elements from the i-th element with the given names. * @since 5.4.0 */ - void remove_elements_after(QNameSet name, int i); + void remove_elements_after(QNameSet names, int i); + + /** + * Removes all elements from the m-th element with the given name up to the n-th + * element with the given name but not including the n-th element. + * @since 5.4.0 + */ + void remove_elements_between(QName name, int m, int n); + + /** + * Removes all elements from the m-th element with the given name up to the n-th + * element with the given name but not including the n-th element. + * @since 5.4.0 + */ + void remove_elements_between(QNameSet names, int m, int n); /** * Returns the TypeStoreUser underneath the attribute with the given diff --git a/src/main/java/org/apache/xmlbeans/impl/values/XmlComplexContentImpl.java b/src/main/java/org/apache/xmlbeans/impl/values/XmlComplexContentImpl.java index f47be75ac..609f8c03d 100644 --- a/src/main/java/org/apache/xmlbeans/impl/values/XmlComplexContentImpl.java +++ b/src/main/java/org/apache/xmlbeans/impl/values/XmlComplexContentImpl.java @@ -396,12 +396,13 @@ protected void arraySetterHelper(XmlObject[] sources, QName elemName, QNameSet s // ... then come back and insert the elements starting with startSource // up to i from the sources array into the current array, starting with // startDest - int n = i; + final int n = i; if (set == null) { - store.remove_elements_after(elemName, n - startSrc + startDest); + store.remove_elements_between(elemName, n - startSrc + startDest, m); } else { - store.remove_elements_after(set, n - startSrc + startDest); + store.remove_elements_between(set, n - startSrc + startDest, m); } + m = n - startSrc + startDest; int j; for (i = startSrc, j = startDest; i < n; i++, j++) { @@ -530,10 +531,11 @@ protected void arraySetterHelper2(XmlObject[] sources, QName elemName, QNameSet // startDest final int n = i; if (set == null) { - store.remove_elements_after(elemName, n - startSrc + startDest); + store.remove_elements_between(elemName, n - startSrc + startDest, m); } else { - store.remove_elements_after(set, n - startSrc + startDest); + store.remove_elements_between(set, n - startSrc + startDest, m); } + m = n - startSrc + startDest; final int size = Math.min(m - startDest, sources.length - startSrc); ArrayList users = new ArrayList<>(size); From 9685a5d8e2df00fc9a3cfb1e7d03f92d6d3e1e36 Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Wed, 16 Jul 2025 19:51:16 +0100 Subject: [PATCH 3/3] Update XmlComplexContentImpl.java --- .../xmlbeans/impl/values/XmlComplexContentImpl.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/apache/xmlbeans/impl/values/XmlComplexContentImpl.java b/src/main/java/org/apache/xmlbeans/impl/values/XmlComplexContentImpl.java index 609f8c03d..7a09a1e74 100644 --- a/src/main/java/org/apache/xmlbeans/impl/values/XmlComplexContentImpl.java +++ b/src/main/java/org/apache/xmlbeans/impl/values/XmlComplexContentImpl.java @@ -397,12 +397,15 @@ protected void arraySetterHelper(XmlObject[] sources, QName elemName, QNameSet s // up to i from the sources array into the current array, starting with // startDest final int n = i; - if (set == null) { - store.remove_elements_between(elemName, n - startSrc + startDest, m); - } else { - store.remove_elements_between(set, n - startSrc + startDest, m); + final int startPos = n - startSrc + startDest; + if (m > startPos) { + if (set == null) { + store.remove_elements_between(elemName, startPos, m); + } else { + store.remove_elements_between(set, startPos, m); + } + m = startPos; } - m = n - startSrc + startDest; int j; for (i = startSrc, j = startDest; i < n; i++, j++) {