Author: veithen
Date: Sun Aug 23 12:26:40 2015
New Revision: 1697172

URL: http://svn.apache.org/r1697172
Log:
Add iterator support to core-aspects and reimplement OMContainer#getChildren().

Added:
    
webservices/axiom/trunk/aspects/core-aspects/src/main/java/org/apache/axiom/core/AbstractNodeIterator.java
   (with props)
    
webservices/axiom/trunk/aspects/core-aspects/src/main/java/org/apache/axiom/core/Axis.java
   (with props)
    
webservices/axiom/trunk/aspects/core-aspects/src/main/java/org/apache/axiom/core/ExceptionTranslator.java
   (with props)
    
webservices/axiom/trunk/aspects/core-aspects/src/main/java/org/apache/axiom/core/NodeIterator.java
   (with props)
    
webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/AxiomExceptionTranslator.java
      - copied, changed from r1697165, 
webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/AxiomExceptionUtil.java
Removed:
    
webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/AxiomExceptionUtil.java
Modified:
    
webservices/axiom/trunk/aspects/core-aspects/src/main/java/org/apache/axiom/core/CoreParentNodeSupport.aj
    
webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/AxiomContainerSupport.aj
    
webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/AxiomElementSupport.aj
    
webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/sourcedelement/TestComplete.java

Added: 
webservices/axiom/trunk/aspects/core-aspects/src/main/java/org/apache/axiom/core/AbstractNodeIterator.java
URL: 
http://svn.apache.org/viewvc/webservices/axiom/trunk/aspects/core-aspects/src/main/java/org/apache/axiom/core/AbstractNodeIterator.java?rev=1697172&view=auto
==============================================================================
--- 
webservices/axiom/trunk/aspects/core-aspects/src/main/java/org/apache/axiom/core/AbstractNodeIterator.java
 (added)
+++ 
webservices/axiom/trunk/aspects/core-aspects/src/main/java/org/apache/axiom/core/AbstractNodeIterator.java
 Sun Aug 23 12:26:40 2015
@@ -0,0 +1,148 @@
+/*
+ * 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.axiom.core;
+
+import java.util.ConcurrentModificationException;
+import java.util.NoSuchElementException;
+
+public abstract class AbstractNodeIterator<T> implements NodeIterator<T> {
+    private final CoreParentNode startNode;
+    private final Axis axis;
+    private final Class<T> type;
+    private final ExceptionTranslator exceptionTranslator;
+    private final DetachPolicy detachPolicy;
+    private CoreNode currentNode;
+    
+    /**
+     * The parent of the current node. This is used to detect concurrent 
modifications.
+     */
+    private CoreParentNode currentParent;
+    
+    private CoreNode nextNode;
+    private boolean hasNext;
+    private int depth;
+    
+    public AbstractNodeIterator(CoreParentNode startNode, Axis axis, Class<T> 
type, ExceptionTranslator exceptionTranslator, DetachPolicy detachPolicy) {
+        this.startNode = startNode;
+        this.axis = axis;
+        this.type = type;
+        this.exceptionTranslator = exceptionTranslator;
+        this.detachPolicy = detachPolicy;
+    }
+
+    protected abstract boolean matches(CoreNode node) throws 
CoreModelException;
+
+    public final boolean hasNext() {
+        if (!hasNext) {
+            CoreNode node = currentNode;
+            if (node instanceof CoreChildNode && 
((CoreChildNode)node).coreGetParent() != currentParent) {
+                throw new ConcurrentModificationException("The current node 
has been removed using a method other than Iterator#remove()");
+            }
+            try {
+                do {
+                    // Get to the next node
+                    switch (axis) {
+                        case CHILDREN:
+                            if (node == null) {
+                                node = startNode.coreGetFirstChild();
+                            } else {
+                                node = 
((CoreChildNode)node).coreGetNextSibling();
+                            }
+                            break;
+                        case DESCENDANTS:
+                        case DESCENDANTS_OR_SELF:
+                            if (node == null) {
+                                if (axis == Axis.DESCENDANTS) {
+                                    node = startNode.coreGetFirstChild();
+                                    depth++;
+                                } else {
+                                    node = startNode;
+                                }
+                            } else {
+                                boolean visitChildren = true;
+                                while (true) {
+                                    // TODO: test for CoreContainer instead????
+                                    if (visitChildren && node instanceof 
CoreElement) {
+                                        CoreChildNode firstChild = 
((CoreElement)node).coreGetFirstChild();
+                                        if (firstChild != null) {
+                                            depth++;
+                                            node = firstChild;
+                                            break;
+                                        }
+                                    }
+                                    if (depth == 0) {
+                                        node = null;
+                                        break;
+                                    }
+                                    CoreChildNode nextSibling = 
((CoreChildNode)node).coreGetNextSibling();
+                                    if (nextSibling != null) {
+                                        node = nextSibling;
+                                        break;
+                                    }
+                                    depth--;
+                                    node = 
((CoreChildNode)node).coreGetParent();
+                                    visitChildren = false;
+                                }
+                            }
+                    }
+                } while (node != null && !matches(node));
+            } catch (CoreModelException ex) {
+                throw exceptionTranslator.toUncheckedException(ex);
+            }
+            nextNode = node;
+            hasNext = true;
+        }
+        return nextNode != null;
+    }
+
+    public final T next() {
+        if (hasNext()) {
+            currentNode = nextNode;
+            currentParent = currentNode instanceof CoreChildNode ? 
((CoreChildNode)currentNode).coreGetParent() : null;
+            hasNext = false;
+            return type.cast(currentNode);
+        } else {
+            throw new NoSuchElementException();
+        }
+    }
+
+    public final void remove() {
+        if (currentNode == null) {
+            throw new IllegalStateException();
+        }
+        // Move to next node before replacing the current one
+        hasNext();
+        if (currentNode instanceof CoreChildNode) {
+//            try {
+                ((CoreChildNode)currentNode).coreDetach(detachPolicy);
+//            } catch (CoreModelException ex) {
+//                throw exceptionTranslator.toUncheckedException(ex);
+//            }
+        }
+        currentNode = null;
+    }
+
+    public final void replace(CoreChildNode newNode) throws CoreModelException 
{
+        // TODO
+        throw new UnsupportedOperationException();
+//        // Move to next node before replacing the current one
+//        hasNext();
+//        ((CoreChildNode)currentNode).coreReplaceWith(newNode);
+    }
+}

Propchange: 
webservices/axiom/trunk/aspects/core-aspects/src/main/java/org/apache/axiom/core/AbstractNodeIterator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
webservices/axiom/trunk/aspects/core-aspects/src/main/java/org/apache/axiom/core/Axis.java
URL: 
http://svn.apache.org/viewvc/webservices/axiom/trunk/aspects/core-aspects/src/main/java/org/apache/axiom/core/Axis.java?rev=1697172&view=auto
==============================================================================
--- 
webservices/axiom/trunk/aspects/core-aspects/src/main/java/org/apache/axiom/core/Axis.java
 (added)
+++ 
webservices/axiom/trunk/aspects/core-aspects/src/main/java/org/apache/axiom/core/Axis.java
 Sun Aug 23 12:26:40 2015
@@ -0,0 +1,39 @@
+/*
+ * 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.axiom.core;
+
+/**
+ * Identifies a node-set relative to a given node.
+ */
+public enum Axis {
+    /**
+     * The children of the node.
+     */
+    CHILDREN,
+    
+    /**
+     * The descendants of the node.
+     */
+    DESCENDANTS,
+    
+    /**
+     * The descendants of the node and the node itself.
+     */
+    DESCENDANTS_OR_SELF
+}
\ No newline at end of file

Propchange: 
webservices/axiom/trunk/aspects/core-aspects/src/main/java/org/apache/axiom/core/Axis.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
webservices/axiom/trunk/aspects/core-aspects/src/main/java/org/apache/axiom/core/CoreParentNodeSupport.aj
URL: 
http://svn.apache.org/viewvc/webservices/axiom/trunk/aspects/core-aspects/src/main/java/org/apache/axiom/core/CoreParentNodeSupport.aj?rev=1697172&r1=1697171&r2=1697172&view=diff
==============================================================================
--- 
webservices/axiom/trunk/aspects/core-aspects/src/main/java/org/apache/axiom/core/CoreParentNodeSupport.aj
 (original)
+++ 
webservices/axiom/trunk/aspects/core-aspects/src/main/java/org/apache/axiom/core/CoreParentNodeSupport.aj
 Sun Aug 23 12:26:40 2015
@@ -274,4 +274,13 @@ public aspect CoreParentNodeSupport {
             content = data;
         }
     }
+    
+    public final <T> NodeIterator<T> CoreParentNode.coreGetNodes(Axis axis, 
Class<T> type, ExceptionTranslator exceptionTranslator, DetachPolicy 
detachPolicy) {
+        return new AbstractNodeIterator<T>(this, axis, type, 
exceptionTranslator, detachPolicy) {
+            @Override
+            protected boolean matches(CoreNode node) throws CoreModelException 
{
+                return true;
+            }
+        };
+    }
 }

Added: 
webservices/axiom/trunk/aspects/core-aspects/src/main/java/org/apache/axiom/core/ExceptionTranslator.java
URL: 
http://svn.apache.org/viewvc/webservices/axiom/trunk/aspects/core-aspects/src/main/java/org/apache/axiom/core/ExceptionTranslator.java?rev=1697172&view=auto
==============================================================================
--- 
webservices/axiom/trunk/aspects/core-aspects/src/main/java/org/apache/axiom/core/ExceptionTranslator.java
 (added)
+++ 
webservices/axiom/trunk/aspects/core-aspects/src/main/java/org/apache/axiom/core/ExceptionTranslator.java
 Sun Aug 23 12:26:40 2015
@@ -0,0 +1,32 @@
+/*
+ * 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.axiom.core;
+
+/**
+ * Translates {@link CoreModelException} instances into {@link 
RuntimeException} instances.
+ */
+public interface ExceptionTranslator {
+    /**
+     * Translate the given exception to an unchecked exception.
+     * 
+     * @param ex the original (checked) exception
+     * @return the corresponding unchecked exception
+     */
+    RuntimeException toUncheckedException(CoreModelException ex);
+}

Propchange: 
webservices/axiom/trunk/aspects/core-aspects/src/main/java/org/apache/axiom/core/ExceptionTranslator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
webservices/axiom/trunk/aspects/core-aspects/src/main/java/org/apache/axiom/core/NodeIterator.java
URL: 
http://svn.apache.org/viewvc/webservices/axiom/trunk/aspects/core-aspects/src/main/java/org/apache/axiom/core/NodeIterator.java?rev=1697172&view=auto
==============================================================================
--- 
webservices/axiom/trunk/aspects/core-aspects/src/main/java/org/apache/axiom/core/NodeIterator.java
 (added)
+++ 
webservices/axiom/trunk/aspects/core-aspects/src/main/java/org/apache/axiom/core/NodeIterator.java
 Sun Aug 23 12:26:40 2015
@@ -0,0 +1,53 @@
+/*
+ * 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.axiom.core;
+
+import java.util.ConcurrentModificationException;
+import java.util.Iterator;
+
+/**
+ * Extended iterator interface used by various methods in {@link 
CoreParentNode}. It defines an
+ * additional method that allows to replace the child node returned by the 
last call to
+ * {@link #next()}.
+ * <p>
+ * All implementations of this interface must satisfy the following 
requirements:
+ * <ol>
+ * <li>The implementation MUST properly implement the {@link #remove()} 
method, i.e. it is not
+ * allowed to throw {@link UnsupportedOperationException}.
+ * <li>A {@link ConcurrentModificationException} MUST be thrown when the 
iterator is used after the
+ * last node returned by {@link Iterator#next()} has been removed using a 
method other than
+ * {@link Iterator#remove()} (e.g. {@link CoreChildNode#coreDetach()}).
+ * <li>If a {@link CoreModelException} occurs inside {@link 
Iterator#hasNext()},
+ * {@link Iterator#next()} or {@link Iterator#remove()}, then the 
implementation MUST use the
+ * supplied {@link ExceptionTranslator} to translate that checked exception 
into an unchecked
+ * exception.
+ * </ol>
+ */
+public interface NodeIterator<T> extends Iterator<T> {
+    /**
+     * Replace the current node.
+     * 
+     * This method only has an effect if the current node is a {@link 
CoreChildNode}.
+     * 
+     * @param newNode
+     * @throws CoreModelException
+     */
+    // TODO: the meaning of this method is not clear for Axis.DESCENDANTS
+    void replace(CoreChildNode newNode) throws CoreModelException;
+}

Propchange: 
webservices/axiom/trunk/aspects/core-aspects/src/main/java/org/apache/axiom/core/NodeIterator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/AxiomContainerSupport.aj
URL: 
http://svn.apache.org/viewvc/webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/AxiomContainerSupport.aj?rev=1697172&r1=1697171&r2=1697172&view=diff
==============================================================================
--- 
webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/AxiomContainerSupport.aj
 (original)
+++ 
webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/AxiomContainerSupport.aj
 Sun Aug 23 12:26:40 2015
@@ -29,6 +29,7 @@ import javax.xml.stream.XMLStreamWriter;
 import javax.xml.transform.sax.SAXResult;
 import javax.xml.transform.sax.SAXSource;
 
+import org.apache.axiom.core.Axis;
 import org.apache.axiom.om.NodeUnavailableException;
 import org.apache.axiom.om.OMContainer;
 import org.apache.axiom.om.OMElement;
@@ -47,7 +48,6 @@ import org.apache.axiom.om.impl.common.s
 import org.apache.axiom.om.impl.common.serializer.push.OutputException;
 import org.apache.axiom.om.impl.common.serializer.push.sax.XMLReaderImpl;
 import org.apache.axiom.om.impl.common.serializer.push.stax.StAXSerializer;
-import org.apache.axiom.om.impl.traverse.OMChildrenIterator;
 import org.apache.axiom.om.util.OMXMLStreamReaderValidator;
 import org.apache.axiom.om.util.StAXUtils;
 import org.apache.commons.logging.Log;
@@ -174,8 +174,8 @@ public aspect AxiomContainerSupport {
         coreRemoveChildren(Policies.DETACH_POLICY);
     }
     
-    public Iterator OMContainer.getChildren() {
-        return new OMChildrenIterator(getFirstOMChild());
+    public Iterator AxiomContainer.getChildren() {
+        return coreGetNodes(Axis.CHILDREN, OMNode.class, 
AxiomExceptionTranslator.INSTANCE, Policies.DETACH_POLICY);
     }
 
     public Iterator OMContainer.getChildrenWithLocalName(String localName) {

Modified: 
webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/AxiomElementSupport.aj
URL: 
http://svn.apache.org/viewvc/webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/AxiomElementSupport.aj?rev=1697172&r1=1697171&r2=1697172&view=diff
==============================================================================
--- 
webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/AxiomElementSupport.aj
 (original)
+++ 
webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/AxiomElementSupport.aj
 Sun Aug 23 12:26:40 2015
@@ -278,7 +278,7 @@ public aspect AxiomElementSupport {
         try {
             coreSetAttribute(Policies.ATTRIBUTE_MATCHER, (AxiomAttribute)attr, 
NodeMigrationPolicy.MOVE_ALWAYS, true, null, ReturnValue.NONE);
         } catch (NodeMigrationException ex) {
-            AxiomExceptionUtil.translate(ex);
+            AxiomExceptionTranslator.translate(ex);
         }
     }
     
@@ -363,7 +363,7 @@ public aspect AxiomElementSupport {
         try {
             
coreAppendAttribute(((AxiomNodeFactory)getOMFactory()).createNamespaceDeclaration(ns),
 NodeMigrationPolicy.MOVE_ALWAYS);
         } catch (NodeMigrationException ex) {
-            throw AxiomExceptionUtil.translate(ex);
+            throw AxiomExceptionTranslator.translate(ex);
         }
         return ns;
     }
@@ -374,7 +374,7 @@ public aspect AxiomElementSupport {
                     
((AxiomNodeFactory)getOMFactory()).createNamespaceDeclaration(ns),
                     NodeMigrationPolicy.MOVE_ALWAYS, true, null, 
ReturnValue.NONE);
         } catch (NodeMigrationException ex) {
-            throw AxiomExceptionUtil.translate(ex);
+            throw AxiomExceptionTranslator.translate(ex);
         }
     }
     

Copied: 
webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/AxiomExceptionTranslator.java
 (from r1697165, 
webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/AxiomExceptionUtil.java)
URL: 
http://svn.apache.org/viewvc/webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/AxiomExceptionTranslator.java?p2=webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/AxiomExceptionTranslator.java&p1=webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/AxiomExceptionUtil.java&r1=1697165&r2=1697172&rev=1697172&view=diff
==============================================================================
--- 
webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/AxiomExceptionUtil.java
 (original)
+++ 
webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/AxiomExceptionTranslator.java
 Sun Aug 23 12:26:40 2015
@@ -19,10 +19,19 @@
 package org.apache.axiom.om.impl.common;
 
 import org.apache.axiom.core.CoreModelException;
+import org.apache.axiom.core.ExceptionTranslator;
 import org.apache.axiom.om.OMException;
 
-public class AxiomExceptionUtil {
+public class AxiomExceptionTranslator implements ExceptionTranslator {
+    public static final AxiomExceptionTranslator INSTANCE = new 
AxiomExceptionTranslator();
+    
+    private AxiomExceptionTranslator() {}
+    
     public static OMException translate(CoreModelException ex) {
         return new OMException(ex);
     }
+
+    public RuntimeException toUncheckedException(CoreModelException ex) {
+        return translate(ex);
+    }
 }

Modified: 
webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/sourcedelement/TestComplete.java
URL: 
http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/sourcedelement/TestComplete.java?rev=1697172&r1=1697171&r2=1697172&view=diff
==============================================================================
--- 
webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/sourcedelement/TestComplete.java
 (original)
+++ 
webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/sourcedelement/TestComplete.java
 Sun Aug 23 12:26:40 2015
@@ -44,7 +44,7 @@ public class TestComplete extends AxiomT
         
         // Trigger expansion of the child OMSE
         // This will cause the child to be partially parsed (i.e. incomplete)
-        child.getChildren();
+        child.getFirstOMChild();
         
         // Add the child OMSE to the root.
         root.addChild(child);
@@ -62,7 +62,7 @@ public class TestComplete extends AxiomT
         root = f.createOMElement("root", rootNS);
         
         root.addChild(child);
-        child.getChildren(); // causes partial parsing...i.e. incomplete child
+        child.getFirstOMChild(); // causes partial parsing...i.e. incomplete 
child
     
         assertTrue(!child.isComplete());
         assertTrue(root.isComplete());


Reply via email to