You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ws.apache.org by ve...@apache.org on 2015/06/13 17:22:46 UTC

svn commit: r1685272 - in /webservices/axiom/branches/attrs-aspects: aspects/core-aspects/src/main/java/org/apache/axiom/core/ aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/ implementations/axiom-dom/src/main/java/org/apache/axiom/om...

Author: veithen
Date: Sat Jun 13 15:22:46 2015
New Revision: 1685272

URL: http://svn.apache.org/r1685272
Log:
Rewrite DOOM's OMElement#addAttribute(String, String, OMNamespace) implementation.

Added:
    webservices/axiom/branches/attrs-aspects/aspects/core-aspects/src/main/java/org/apache/axiom/core/CoreNSAwareElement.java   (with props)
    webservices/axiom/branches/attrs-aspects/aspects/core-aspects/src/main/java/org/apache/axiom/core/CoreNSAwareElementSupport.aj   (with props)
    webservices/axiom/branches/attrs-aspects/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/Policies.java   (with props)
Modified:
    webservices/axiom/branches/attrs-aspects/aspects/core-aspects/src/main/java/org/apache/axiom/core/CoreAttributeSupport.aj
    webservices/axiom/branches/attrs-aspects/aspects/core-aspects/src/main/java/org/apache/axiom/core/CoreChildNode.java
    webservices/axiom/branches/attrs-aspects/aspects/core-aspects/src/main/java/org/apache/axiom/core/CoreChildNodeSupport.aj
    webservices/axiom/branches/attrs-aspects/aspects/core-aspects/src/main/java/org/apache/axiom/core/CoreElement.java
    webservices/axiom/branches/attrs-aspects/aspects/core-aspects/src/main/java/org/apache/axiom/core/CoreElementSupport.aj
    webservices/axiom/branches/attrs-aspects/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/AxiomElement.java
    webservices/axiom/branches/attrs-aspects/implementations/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/AttrImpl.java
    webservices/axiom/branches/attrs-aspects/implementations/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/ElementImpl.java
    webservices/axiom/branches/attrs-aspects/implementations/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/NSAwareAttribute.java
    webservices/axiom/branches/attrs-aspects/implementations/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/NamedNodeSupport.aj
    webservices/axiom/branches/attrs-aspects/implementations/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/NamespaceDeclaration.java
    webservices/axiom/branches/attrs-aspects/implementations/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/factory/OMDOMFactory.java

Modified: webservices/axiom/branches/attrs-aspects/aspects/core-aspects/src/main/java/org/apache/axiom/core/CoreAttributeSupport.aj
URL: http://svn.apache.org/viewvc/webservices/axiom/branches/attrs-aspects/aspects/core-aspects/src/main/java/org/apache/axiom/core/CoreAttributeSupport.aj?rev=1685272&r1=1685271&r2=1685272&view=diff
==============================================================================
--- webservices/axiom/branches/attrs-aspects/aspects/core-aspects/src/main/java/org/apache/axiom/core/CoreAttributeSupport.aj (original)
+++ webservices/axiom/branches/attrs-aspects/aspects/core-aspects/src/main/java/org/apache/axiom/core/CoreAttributeSupport.aj Sat Jun 13 15:22:46 2015
@@ -66,6 +66,10 @@ public aspect CoreAttributeSupport {
         return nextAttribute;
     }
 
+    public final void CoreAttribute.internalSetNextAttribute(CoreAttribute nextAttribute) {
+        this.nextAttribute = nextAttribute;
+    }
+    
     public final CoreAttribute CoreAttribute.coreGetPreviousAttribute() {
         if (owner instanceof CoreElement) {
             CoreElement ownerElement = (CoreElement)owner;

Modified: webservices/axiom/branches/attrs-aspects/aspects/core-aspects/src/main/java/org/apache/axiom/core/CoreChildNode.java
URL: http://svn.apache.org/viewvc/webservices/axiom/branches/attrs-aspects/aspects/core-aspects/src/main/java/org/apache/axiom/core/CoreChildNode.java?rev=1685272&r1=1685271&r2=1685272&view=diff
==============================================================================
--- webservices/axiom/branches/attrs-aspects/aspects/core-aspects/src/main/java/org/apache/axiom/core/CoreChildNode.java (original)
+++ webservices/axiom/branches/attrs-aspects/aspects/core-aspects/src/main/java/org/apache/axiom/core/CoreChildNode.java Sat Jun 13 15:22:46 2015
@@ -19,5 +19,11 @@
 package org.apache.axiom.core;
 
 public interface CoreChildNode extends CoreNode {
-    
+    /**
+     * Get the parent element of this node.
+     * 
+     * @return the parent element of this node or <code>null</code> if the node has no parent or if
+     *         the parent is not an element
+     */
+    CoreElement coreGetParentElement();
 }

Modified: webservices/axiom/branches/attrs-aspects/aspects/core-aspects/src/main/java/org/apache/axiom/core/CoreChildNodeSupport.aj
URL: http://svn.apache.org/viewvc/webservices/axiom/branches/attrs-aspects/aspects/core-aspects/src/main/java/org/apache/axiom/core/CoreChildNodeSupport.aj?rev=1685272&r1=1685271&r2=1685272&view=diff
==============================================================================
--- webservices/axiom/branches/attrs-aspects/aspects/core-aspects/src/main/java/org/apache/axiom/core/CoreChildNodeSupport.aj (original)
+++ webservices/axiom/branches/attrs-aspects/aspects/core-aspects/src/main/java/org/apache/axiom/core/CoreChildNodeSupport.aj Sat Jun 13 15:22:46 2015
@@ -45,6 +45,10 @@ public aspect CoreChildNodeSupport {
         return getFlag(Flags.HAS_PARENT) ? owner : null;
     }
     
+    public final CoreElement CoreChildNode.coreGetParentElement() {
+        return owner instanceof CoreElement ? (CoreElement)owner : null;
+    }
+    
     public void CoreChildNode.internalSetParent(CoreParentNode parent) {
         if (parent == null) {
             throw new IllegalArgumentException();

Modified: webservices/axiom/branches/attrs-aspects/aspects/core-aspects/src/main/java/org/apache/axiom/core/CoreElement.java
URL: http://svn.apache.org/viewvc/webservices/axiom/branches/attrs-aspects/aspects/core-aspects/src/main/java/org/apache/axiom/core/CoreElement.java?rev=1685272&r1=1685271&r2=1685272&view=diff
==============================================================================
--- webservices/axiom/branches/attrs-aspects/aspects/core-aspects/src/main/java/org/apache/axiom/core/CoreElement.java (original)
+++ webservices/axiom/branches/attrs-aspects/aspects/core-aspects/src/main/java/org/apache/axiom/core/CoreElement.java Sat Jun 13 15:22:46 2015
@@ -20,6 +20,30 @@ package org.apache.axiom.core;
 
 public interface CoreElement extends CoreChildNode, CoreParentNode {
     /**
+     * Specifies the value that should be returned by
+     * {@link CoreElement#coreSetAttribute(AttributeMatcher, String, String, CoreAttribute, NodeMigrationPolicy, ReturnValue)}.
+     */
+    public enum ReturnValue {
+        /**
+         * Nothing should be returned.
+         */
+        NONE,
+        
+        /**
+         * The method will return the attribute that was effectively added to the element (which may
+         * be a clone of the attribute requested to be added if
+         * {@link NodeMigrationPolicy.Action#CLONE} is used).
+         */
+        ADDED_ATTRIBUTE,
+        
+        /**
+         * The method will return the attribute that was replaced by the new attribute, or
+         * <code>null</code> if no matching attribute existed.
+         */
+        REPLACED_ATTRIBUTE,
+    }
+    
+    /**
      * Get the first attribute of this element.
      * 
      * @return the first attribute, or <code>null</code> if this element has no attributes
@@ -32,6 +56,59 @@ public interface CoreElement extends Cor
      * @return the last attribute, or <code>null</code> if this element has no attributes
      */
     CoreAttribute coreGetLastAttribute();
+    
+    /**
+     * Create or update an attribute based on a given {@link AttributeMatcher}.
+     * 
+     * @param matcher
+     *            the {@link AttributeMatcher} implementation to use
+     * @param namespaceURI
+     *            the <code>namespaceURI</code> parameter to pass to
+     *            {@link AttributeMatcher#matches(CoreAttribute, String, String)} and
+     *            {@link AttributeMatcher#createAttribute(NodeFactory, CoreDocument, String, String, String, String)}
+     * @param name
+     *            the <code>name</code> parameter to pass to
+     *            {@link AttributeMatcher#matches(CoreAttribute, String, String)} and
+     *            {@link AttributeMatcher#createAttribute(NodeFactory, CoreDocument, String, String, String, String)}
+     * @param prefix
+     *            the <code>prefix</code> parameter to pass to
+     *            {@link AttributeMatcher#createAttribute(NodeFactory, CoreDocument, String, String, String, String)}
+     *            and {@link AttributeMatcher#update(CoreAttribute, String, String)}
+     * @param value
+     *            the <code>value</code> parameter to pass to
+     *            {@link AttributeMatcher#createAttribute(NodeFactory, CoreDocument, String, String, String, String)}
+     *            and {@link AttributeMatcher#update(CoreAttribute, String, String)}
+     */
+    void coreSetAttribute(AttributeMatcher matcher, String namespaceURI, String name, String prefix, String value);
+    
+    /**
+     * Add a new attribute or replace an existing attribute based on a given
+     * {@link AttributeMatcher}. If a matching attribute on this element is found, it is replaced by
+     * the specified attribute. If no matching attribute is found, then the specified attribute is
+     * added to this element. If the attribute is already owned by this element, then calling this method
+     * has no effect.
+     * 
+     * @param matcher
+     *            the {@link AttributeMatcher} implementation to use
+     * @param attr
+     *            the new attribute to add
+     * @param policy
+     *            the policy to apply if the attribute already has an owner element or belongs to a
+     *            different document
+     * @param changeDocumentOfReplacedAttribute
+     *            specifies if the owner document of the replaced attribute (if any) should be
+     *            changed
+     * @param newDocument
+     *            the new owner document for the replaced attribute, or <code>null</code> if the
+     *            attribute will have its own owner document (which may be created lazily at a later
+     *            moment); only meaningful if <code>changeDocumentOfReplacedAttribute</code> is
+     *            <code>true</code
+     * @param returnValue
+     *            specifies the expected return value of the method
+     * @return the attribute as specified by the <code>returnValue</code> parameter
+     * @throws NodeMigrationException 
+     */
+    CoreAttribute coreSetAttribute(AttributeMatcher matcher, CoreAttribute attr, NodeMigrationPolicy policy, boolean changeDocumentOfReplacedAttribute, CoreDocument newDocument, ReturnValue returnValue) throws NodeMigrationException;
 
     /**
      * Append an attribute to this element. The attribute is simply added at the end of the list of
@@ -47,4 +124,43 @@ public interface CoreElement extends Cor
      *             if appending the attribute was rejected by the policy
      */
     void coreAppendAttribute(CoreAttribute attr, NodeMigrationPolicy policy) throws NodeMigrationException;
+    
+    /**
+     * Look up the namespace URI associated to the given prefix.
+     * 
+     * @param prefix
+     *            The prefix to look for. If this parameter is the empty string, then the URI of the
+     *            default namespace will be returned.
+     * @param strict
+     *            If this parameter is set to <code>true</code>, only namespace declarations will be
+     *            taken into account. If set to <code>false</code> the prefixes of the element and
+     *            its ancestors are also taken into account (limited to instanced of
+     *            {@link CoreNSAwareElement}), even if no explicit namespace declarations exists for
+     *            these prefixes.
+     * @return the namespace URI or <code>null</code> if the prefix is not bound; if the prefix is
+     *         the empty string and no default namespace declaration exists, then an empty string is
+     *         returned
+     */
+    String coreLookupNamespaceURI(String prefix, boolean strict);
+    
+    /**
+     * Find a prefix associated to the given namespace URI. Default namespaces are not taken into
+     * account by this method.
+     * 
+     * @param namespaceURI
+     *            The namespace URI to look for. This parameter must not be <code>null</code> (XML
+     *            forbids to bind a prefix to the null namespace).
+     * @param strict
+     *            If this parameter is set to <code>true</code>, only namespace declarations will be
+     *            taken into account. If set to <code>false</code> the prefixes of the element and
+     *            its ancestors are also taken into account (limited to instanced of
+     *            {@link CoreNSAwareElement}), even if no explicit namespace declarations exists for
+     *            these prefixes.
+     * @return a prefix bound to the given namespace URI or <code>null</code> if none is found
+     * @throws IllegalArgumentException
+     *             if <code>namespaceURI</code> is <code>null</code>
+     */
+    // TODO: wrong Javadoc: null vs. empty string
+    // TODO: we can support default namespaces!
+    String coreLookupPrefix(String namespaceURI, boolean strict);
 }

Modified: webservices/axiom/branches/attrs-aspects/aspects/core-aspects/src/main/java/org/apache/axiom/core/CoreElementSupport.aj
URL: http://svn.apache.org/viewvc/webservices/axiom/branches/attrs-aspects/aspects/core-aspects/src/main/java/org/apache/axiom/core/CoreElementSupport.aj?rev=1685272&r1=1685271&r2=1685272&view=diff
==============================================================================
--- webservices/axiom/branches/attrs-aspects/aspects/core-aspects/src/main/java/org/apache/axiom/core/CoreElementSupport.aj (original)
+++ webservices/axiom/branches/attrs-aspects/aspects/core-aspects/src/main/java/org/apache/axiom/core/CoreElementSupport.aj Sat Jun 13 15:22:46 2015
@@ -79,7 +79,11 @@ public aspect CoreElementSupport {
 
     public final void CoreElement.coreAppendAttribute(CoreAttribute attr, NodeMigrationPolicy policy) throws NodeMigrationException {
         // TODO: we should probably check if the attribute is already owned by the element
-        attr = accept(attr, policy);
+        internalAppendAttribute(accept(attr, policy));
+    }
+
+    private void CoreElement.internalAppendAttribute(CoreAttribute attr) {
+        // TODO: we should probably check if the attribute is already owned by the element
         attr.internalSetOwnerElement(this);
         CoreAttribute lastAttribute = coreGetLastAttribute();
         if (lastAttribute == null) {
@@ -88,4 +92,129 @@ public aspect CoreElementSupport {
             lastAttribute.insertAttributeAfter(attr);
         }
     }
+
+    public final void CoreElement.coreSetAttribute(AttributeMatcher matcher, String namespaceURI, String name, String prefix, String value) {
+        CoreAttribute attr = firstAttribute;
+        CoreAttribute previousAttr = null;
+        while (attr != null && !matcher.matches(attr, namespaceURI, name)) {
+            previousAttr = attr;
+            attr = attr.coreGetNextAttribute();
+        }
+        if (attr == null) {
+            CoreDocument document = coreGetOwnerDocument(false);
+            CoreAttribute newAttr = matcher.createAttribute(coreGetNodeFactory(), document, namespaceURI, name, prefix, value);
+            if (previousAttr == null) {
+                internalAppendAttribute(newAttr);
+            } else {
+                previousAttr.insertAttributeAfter(newAttr);
+            }
+        } else {
+            matcher.update(attr, prefix, value);
+        }
+    }
+    
+    public final CoreAttribute CoreElement.coreSetAttribute(AttributeMatcher matcher, CoreAttribute coreAttr, NodeMigrationPolicy policy, boolean changeDocumentOfReplacedAttribute, CoreDocument newDocument, ReturnValue returnValue) throws NodeMigrationException {
+        if (coreAttr.coreGetOwnerElement() == this) {
+            // TODO: document this and add assertion
+            // TODO: take returnValue into account
+            return coreAttr;
+        }
+        CoreAttribute attr = accept(coreAttr, policy);
+        String namespaceURI = matcher.getNamespaceURI(attr);
+        String name = matcher.getName(attr); 
+        CoreAttribute existingAttr = firstAttribute;
+        CoreAttribute previousAttr = null;
+        while (existingAttr != null && !matcher.matches(existingAttr, namespaceURI, name)) {
+            previousAttr = existingAttr;
+            existingAttr = existingAttr.coreGetNextAttribute();
+        }
+        attr.internalSetOwnerElement(this);
+        if (existingAttr == null) {
+            if (previousAttr == null) {
+                firstAttribute = attr;
+            } else {
+                previousAttr.internalSetNextAttribute(attr);
+            }
+        } else {
+            if (previousAttr == null) {
+                firstAttribute = attr;
+            } else {
+                previousAttr.internalSetNextAttribute(attr);
+            }
+            existingAttr.internalUnsetOwnerElement(changeDocumentOfReplacedAttribute ? newDocument : coreGetOwnerDocument(true));
+            attr.internalSetNextAttribute(existingAttr.coreGetNextAttribute());
+            existingAttr.internalSetNextAttribute(null);
+        }
+        switch (returnValue) {
+            case ADDED_ATTRIBUTE: return attr;
+            case REPLACED_ATTRIBUTE: return existingAttr;
+            default: return null;
+        }
+    }
+
+    public abstract String CoreElement.getImplicitNamespaceURI(String prefix);
+    
+    public final String CoreElement.coreLookupNamespaceURI(String prefix, boolean strict) {
+        if (!strict) {
+            String namespaceURI = getImplicitNamespaceURI(prefix);
+            if (namespaceURI != null) {
+                return namespaceURI;
+            }
+        }
+        for (CoreAttribute attr = coreGetFirstAttribute(); attr != null; attr = attr.coreGetNextAttribute()) {
+            if (attr instanceof CoreNamespaceDeclaration) {
+                CoreNamespaceDeclaration decl = (CoreNamespaceDeclaration)attr;
+                if (prefix.equals(decl.coreGetDeclaredPrefix())) {
+                    return decl.coreGetDeclaredNamespaceURI();
+                }
+            }
+        }
+        CoreElement parentElement = coreGetParentElement();
+        if (parentElement != null) {
+            return parentElement.coreLookupNamespaceURI(prefix, strict);
+        } else if (prefix.length() == 0) {
+            return "";
+        } else {
+            return null;
+        }
+    }
+
+    public abstract String CoreElement.getImplicitPrefix(String namespaceURI);
+    
+    public final String CoreElement.coreLookupPrefix(String namespaceURI, boolean strict) {
+        if (namespaceURI == null) {
+            throw new IllegalArgumentException("namespaceURI must not be null");
+        }
+        if (!strict) {
+            String prefix = getImplicitPrefix(namespaceURI);
+            if (prefix != null) {
+                return prefix;
+            }
+        }
+        for (CoreAttribute attr = coreGetFirstAttribute(); attr != null; attr = attr.coreGetNextAttribute()) {
+            if (attr instanceof CoreNamespaceDeclaration) {
+                CoreNamespaceDeclaration decl = (CoreNamespaceDeclaration)attr;
+                if (decl.coreGetDeclaredNamespaceURI().equals(namespaceURI)) {
+                    return decl.coreGetDeclaredPrefix();
+                }
+            }
+        }
+        CoreElement parentElement = coreGetParentElement();
+        if (parentElement != null) {
+            String prefix = parentElement.coreLookupPrefix(namespaceURI, strict);
+            // The prefix declared on one of the ancestors may be masked by another
+            // namespace declaration on this element (or one of its descendants).
+            for (CoreAttribute attr = coreGetFirstAttribute(); attr != null; attr = attr.coreGetNextAttribute()) {
+                if (attr instanceof CoreNamespaceDeclaration) {
+                    CoreNamespaceDeclaration decl = (CoreNamespaceDeclaration)attr;
+                    if (decl.coreGetDeclaredPrefix().equals(prefix)) {
+                        return null;
+                    }
+                }
+            }
+            return prefix;
+        } else {
+            return null;
+        }
+    }
 }

Added: webservices/axiom/branches/attrs-aspects/aspects/core-aspects/src/main/java/org/apache/axiom/core/CoreNSAwareElement.java
URL: http://svn.apache.org/viewvc/webservices/axiom/branches/attrs-aspects/aspects/core-aspects/src/main/java/org/apache/axiom/core/CoreNSAwareElement.java?rev=1685272&view=auto
==============================================================================
--- webservices/axiom/branches/attrs-aspects/aspects/core-aspects/src/main/java/org/apache/axiom/core/CoreNSAwareElement.java (added)
+++ webservices/axiom/branches/attrs-aspects/aspects/core-aspects/src/main/java/org/apache/axiom/core/CoreNSAwareElement.java Sat Jun 13 15:22:46 2015
@@ -0,0 +1,23 @@
+/*
+ * 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;
+
+public interface CoreNSAwareElement extends CoreElement, CoreNSAwareNamedNode {
+
+}

Propchange: webservices/axiom/branches/attrs-aspects/aspects/core-aspects/src/main/java/org/apache/axiom/core/CoreNSAwareElement.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: webservices/axiom/branches/attrs-aspects/aspects/core-aspects/src/main/java/org/apache/axiom/core/CoreNSAwareElementSupport.aj
URL: http://svn.apache.org/viewvc/webservices/axiom/branches/attrs-aspects/aspects/core-aspects/src/main/java/org/apache/axiom/core/CoreNSAwareElementSupport.aj?rev=1685272&view=auto
==============================================================================
--- webservices/axiom/branches/attrs-aspects/aspects/core-aspects/src/main/java/org/apache/axiom/core/CoreNSAwareElementSupport.aj (added)
+++ webservices/axiom/branches/attrs-aspects/aspects/core-aspects/src/main/java/org/apache/axiom/core/CoreNSAwareElementSupport.aj Sat Jun 13 15:22:46 2015
@@ -0,0 +1,31 @@
+/*
+ * 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;
+
+public aspect CoreNSAwareElementSupport {
+    public final String CoreNSAwareElement.getImplicitNamespaceURI(String prefix) {
+        // TODO
+        throw new UnsupportedOperationException();
+    }
+
+    public final String CoreNSAwareElement.getImplicitPrefix(String namespaceURI) {
+        // TODO
+        throw new UnsupportedOperationException();
+    }
+}

Propchange: webservices/axiom/branches/attrs-aspects/aspects/core-aspects/src/main/java/org/apache/axiom/core/CoreNSAwareElementSupport.aj
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: webservices/axiom/branches/attrs-aspects/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/AxiomElement.java
URL: http://svn.apache.org/viewvc/webservices/axiom/branches/attrs-aspects/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/AxiomElement.java?rev=1685272&r1=1685271&r2=1685272&view=diff
==============================================================================
--- webservices/axiom/branches/attrs-aspects/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/AxiomElement.java (original)
+++ webservices/axiom/branches/attrs-aspects/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/AxiomElement.java Sat Jun 13 15:22:46 2015
@@ -18,11 +18,11 @@
  */
 package org.apache.axiom.om.impl.common;
 
-import org.apache.axiom.core.CoreElement;
+import org.apache.axiom.core.CoreNSAwareElement;
 import org.apache.axiom.core.DeferringParentNode;
 import org.apache.axiom.om.OMNamespace;
 import org.apache.axiom.om.impl.OMElementEx;
 
-public interface AxiomElement extends OMElementEx, AxiomContainer, AxiomChildNode, AxiomNamedInformationItem, CoreElement, DeferringParentNode {
+public interface AxiomElement extends OMElementEx, AxiomContainer, AxiomChildNode, AxiomNamedInformationItem, CoreNSAwareElement, DeferringParentNode {
     void addNamespaceDeclaration(OMNamespace ns);
 }

Added: webservices/axiom/branches/attrs-aspects/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/Policies.java
URL: http://svn.apache.org/viewvc/webservices/axiom/branches/attrs-aspects/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/Policies.java?rev=1685272&view=auto
==============================================================================
--- webservices/axiom/branches/attrs-aspects/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/Policies.java (added)
+++ webservices/axiom/branches/attrs-aspects/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/Policies.java Sat Jun 13 15:22:46 2015
@@ -0,0 +1,44 @@
+/*
+ * 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.om.impl.common;
+
+import org.apache.axiom.core.AttributeMatcher;
+import org.apache.axiom.core.NSAwareAttributeMatcher;
+import org.apache.axiom.core.NodeMigrationPolicy;
+
+public final class Policies {
+    private Policies() {}
+    
+    public static final AttributeMatcher ATTRIBUTE_MATCHER = new NSAwareAttributeMatcher(
+            false,  // Axiom doesn't support namespace unaware attributes
+            false); // Axiom doesn't have any API to (match and) update an existing attribute
+
+    public static final NodeMigrationPolicy ATTRIBUTE_MIGRATION_POLICY = new NodeMigrationPolicy() {
+        public Action getAction(boolean hasParent, boolean isForeignDocument, boolean isForeignModel) {
+            // TODO: doesn't look correct for foreign documents
+            return Action.CLONE;
+        }
+    };
+    
+    public static final NodeMigrationPolicy NODE_MIGRATION_POLICY = new NodeMigrationPolicy() {
+        public Action getAction(boolean hasParent, boolean isForeignDocument, boolean isForeignModel) {
+            return isForeignModel ? Action.CLONE : Action.MOVE;
+        }
+    };
+}

Propchange: webservices/axiom/branches/attrs-aspects/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/Policies.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: webservices/axiom/branches/attrs-aspects/implementations/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/AttrImpl.java
URL: http://svn.apache.org/viewvc/webservices/axiom/branches/attrs-aspects/implementations/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/AttrImpl.java?rev=1685272&r1=1685271&r2=1685272&view=diff
==============================================================================
--- webservices/axiom/branches/attrs-aspects/implementations/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/AttrImpl.java (original)
+++ webservices/axiom/branches/attrs-aspects/implementations/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/AttrImpl.java Sat Jun 13 15:22:46 2015
@@ -21,20 +21,9 @@ package org.apache.axiom.om.impl.dom;
 
 import static org.apache.axiom.dom.DOMExceptionUtil.newDOMException;
 
-import javax.xml.XMLConstants;
-
 import org.apache.axiom.core.NonDeferringParentNode;
 import org.apache.axiom.dom.DOMAttribute;
-import org.apache.axiom.om.OMAttribute;
-import org.apache.axiom.om.OMCloneOptions;
-import org.apache.axiom.om.OMConstants;
 import org.apache.axiom.om.OMFactory;
-import org.apache.axiom.om.OMNamespace;
-import org.apache.axiom.om.impl.OMAttributeEx;
-import org.apache.axiom.om.impl.common.AxiomAttribute;
-import org.apache.axiom.om.impl.common.AxiomText;
-import org.apache.axiom.om.impl.common.OMNamespaceImpl;
-import org.w3c.dom.Attr;
 import org.w3c.dom.DOMException;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
@@ -183,12 +172,6 @@ public abstract class AttrImpl extends R
         return isId;
     }
 
-    ParentNode shallowClone(OMCloneOptions options, ParentNode targetParent, boolean namespaceRepairing) {
-        // Note: targetParent is always null here
-        // TODO
-        return new NSAwareAttribute(getLocalName(), getNamespace(), type, getOMFactory());
-    }
-
     public final boolean isComplete() {
         return true;
     }

Modified: webservices/axiom/branches/attrs-aspects/implementations/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/ElementImpl.java
URL: http://svn.apache.org/viewvc/webservices/axiom/branches/attrs-aspects/implementations/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/ElementImpl.java?rev=1685272&r1=1685271&r2=1685272&view=diff
==============================================================================
--- webservices/axiom/branches/attrs-aspects/implementations/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/ElementImpl.java (original)
+++ webservices/axiom/branches/attrs-aspects/implementations/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/ElementImpl.java Sat Jun 13 15:22:46 2015
@@ -21,6 +21,8 @@ package org.apache.axiom.om.impl.dom;
 
 import static org.apache.axiom.dom.DOMExceptionUtil.newDOMException;
 
+import org.apache.axiom.core.AttributeMatcher;
+import org.apache.axiom.core.CoreModelException;
 import org.apache.axiom.core.NodeMigrationException;
 import org.apache.axiom.core.NodeMigrationPolicy;
 import org.apache.axiom.dom.DOMConfigurationImpl;
@@ -36,9 +38,11 @@ import org.apache.axiom.om.OMNamespace;
 import org.apache.axiom.om.OMNode;
 import org.apache.axiom.om.OMOutputFormat;
 import org.apache.axiom.om.OMXMLParserWrapper;
+import org.apache.axiom.om.impl.common.AxiomAttribute;
 import org.apache.axiom.om.impl.common.AxiomContainer;
 import org.apache.axiom.om.impl.common.AxiomElement;
 import org.apache.axiom.om.impl.common.OMNamespaceImpl;
+import org.apache.axiom.om.impl.common.Policies;
 import org.apache.axiom.om.impl.common.serializer.push.OutputException;
 import org.apache.axiom.om.impl.common.serializer.push.Serializer;
 import org.apache.axiom.om.impl.util.EmptyIterator;
@@ -86,6 +90,29 @@ public class ElementImpl extends ParentN
         internalSetNamespace(generateNSDecl ? handleNamespace(this, ns, false, true) : ns);
     }
 
+    private final String checkNamespaceIsDeclared(String prefix, String namespaceURI, boolean allowDefaultNamespace, boolean declare) {
+        if (prefix == null) {
+            if (namespaceURI.isEmpty()) {
+                prefix = "";
+                declare = false;
+            } else {
+                prefix = coreLookupPrefix(namespaceURI, true);
+                if (prefix != null && (allowDefaultNamespace || !prefix.isEmpty())) {
+                    declare = false;
+                } else {
+                    prefix = OMSerializerUtil.getNextNSPrefix();
+                }
+            }
+        } else {
+            String existingNamespaceURI = coreLookupNamespaceURI(prefix, true);
+            declare = declare && !namespaceURI.equals(existingNamespaceURI);
+        }
+        if (declare) {
+            coreSetAttribute(AttributeMatcher.NAMESPACE_DECLARATION, null, prefix, null, namespaceURI);
+        }
+        return prefix;
+    }
+
     // /
     // /org.w3c.dom.Node methods
     // /
@@ -269,7 +296,7 @@ public class ElementImpl extends ParentN
         String prefix = DOMUtil.getPrefix(qualifiedName);
         DOMUtil.validateAttrName(namespaceURI, localName, prefix);
         
-        AttrImpl attr = (AttrImpl)getAttributeNodeNS(namespaceURI, localName);
+        NSAwareAttribute attr = (NSAwareAttribute)getAttributeNodeNS(namespaceURI, localName);
         if (attr != null) {
             attr.setPrefix(prefix);
             attr.setValue(value);
@@ -322,20 +349,35 @@ public class ElementImpl extends ParentN
         return attr;
     }
 
-    public OMAttribute addAttribute(String localName, String value,
-                                    OMNamespace ns) {
-        OMNamespace namespace = null;
-        if (ns != null) {
-            String namespaceURI = ns.getNamespaceURI();
-            String prefix = ns.getPrefix();
-            if (namespaceURI.length() > 0 || prefix != null) {
-                namespace = findNamespace(namespaceURI, prefix);
-                if (namespace == null || prefix == null && namespace.getPrefix().length() == 0) {
-                    namespace = new OMNamespaceImpl(namespaceURI, prefix != null ? prefix : OMSerializerUtil.getNextNSPrefix());
+    public final OMAttribute addAttribute(String localName, String value, OMNamespace ns) {
+        try {
+            String namespaceURI;
+            String prefix;
+            if (ns == null) {
+                namespaceURI = "";
+                prefix = "";
+            } else {
+                namespaceURI = ns.getNamespaceURI();
+                prefix = ns.getPrefix();
+                if (namespaceURI.length() == 0) {
+                    if (prefix == null) {
+                        prefix = "";
+                    } else if (prefix.length() > 0) {
+                        throw new IllegalArgumentException("Cannot create a prefixed attribute with an empty namespace name");
+                    }
+                } else {
+                    if (prefix == null || prefix.length() > 0) {
+                        prefix = checkNamespaceIsDeclared(prefix, namespaceURI, false, true);
+                    } else {
+                        throw new IllegalArgumentException("Cannot create an unprefixed attribute with a namespace");
+                    }
                 }
             }
+            AxiomAttribute attr = (AxiomAttribute)coreGetNodeFactory().createAttribute(null, namespaceURI, localName, prefix, value, "CDATA");
+            return (AxiomAttribute)coreSetAttribute(Policies.ATTRIBUTE_MATCHER, attr, NodeMigrationPolicy.MOVE_ALWAYS, true, null, ReturnValue.ADDED_ATTRIBUTE);
+        } catch (CoreModelException ex) {
+            throw DOMExceptionUtil.translate(ex);
         }
-        return addAttribute(new NSAwareAttribute(null, localName, namespace, value, getOMFactory()));
     }
 
     public OMNamespace addNamespaceDeclaration(String uri, String prefix) {

Modified: webservices/axiom/branches/attrs-aspects/implementations/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/NSAwareAttribute.java
URL: http://svn.apache.org/viewvc/webservices/axiom/branches/attrs-aspects/implementations/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/NSAwareAttribute.java?rev=1685272&r1=1685271&r2=1685272&view=diff
==============================================================================
--- webservices/axiom/branches/attrs-aspects/implementations/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/NSAwareAttribute.java (original)
+++ webservices/axiom/branches/attrs-aspects/implementations/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/NSAwareAttribute.java Sat Jun 13 15:22:46 2015
@@ -20,7 +20,9 @@ package org.apache.axiom.om.impl.dom;
 
 import javax.xml.XMLConstants;
 
+import org.apache.axiom.core.CoreNSAwareAttribute;
 import org.apache.axiom.om.OMAttribute;
+import org.apache.axiom.om.OMCloneOptions;
 import org.apache.axiom.om.OMConstants;
 import org.apache.axiom.om.OMFactory;
 import org.apache.axiom.om.OMNamespace;
@@ -30,7 +32,7 @@ import org.apache.axiom.om.impl.common.A
 import org.apache.axiom.om.impl.common.OMNamespaceImpl;
 import org.w3c.dom.Attr;
 
-public final class NSAwareAttribute extends AttrImpl implements OMAttributeEx, AxiomAttribute, NamedNode {
+public final class NSAwareAttribute extends AttrImpl implements OMAttributeEx, AxiomAttribute, NamedNode, CoreNSAwareAttribute {
     // TODO: copy isId?
     NSAwareAttribute(String localName, OMNamespace namespace, String type, OMFactory factory) {
         super(null, factory);
@@ -179,4 +181,21 @@ public final class NSAwareAttribute exte
         return localName.hashCode() ^ (attrValue != null ? attrValue.toString().hashCode() : 0) ^
                 (namespace != null ? namespace.hashCode() : 0);
     }
+
+    @Override
+    final ParentNode shallowClone(OMCloneOptions options, ParentNode targetParent, boolean namespaceRepairing) {
+        // Note: targetParent is always null here
+        // TODO
+        return new NSAwareAttribute(getLocalName(), getNamespace(), type, getOMFactory());
+    }
+
+    public String coreGetType() {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    public void coreSetType(String type) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
 }

Modified: webservices/axiom/branches/attrs-aspects/implementations/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/NamedNodeSupport.aj
URL: http://svn.apache.org/viewvc/webservices/axiom/branches/attrs-aspects/implementations/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/NamedNodeSupport.aj?rev=1685272&r1=1685271&r2=1685272&view=diff
==============================================================================
--- webservices/axiom/branches/attrs-aspects/implementations/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/NamedNodeSupport.aj (original)
+++ webservices/axiom/branches/attrs-aspects/implementations/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/NamedNodeSupport.aj Sat Jun 13 15:22:46 2015
@@ -40,4 +40,23 @@ aspect NamedNodeSupport {
             internalSetNamespace(new OMNamespaceImpl(ns.getNamespaceURI(), prefix == null ? "" : prefix));
         }
     }
+    
+    public final String NamedNode.coreGetNamespaceURI() {
+        String namespaceURI = getNamespaceURI();
+        return namespaceURI == null ? "" : namespaceURI;
+    }
+    
+    public final String NamedNode.coreGetPrefix() {
+        String prefix = getPrefix();
+        return prefix == null ? "" : prefix;
+    }
+
+    public final String NamedNode.coreGetLocalName() {
+        return getLocalName();
+    }
+    
+    public final void NamedNode.coreSetPrefix(String prefix) {
+        // TODO
+        throw new UnsupportedOperationException();
+    }
 }

Modified: webservices/axiom/branches/attrs-aspects/implementations/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/NamespaceDeclaration.java
URL: http://svn.apache.org/viewvc/webservices/axiom/branches/attrs-aspects/implementations/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/NamespaceDeclaration.java?rev=1685272&r1=1685271&r2=1685272&view=diff
==============================================================================
--- webservices/axiom/branches/attrs-aspects/implementations/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/NamespaceDeclaration.java (original)
+++ webservices/axiom/branches/attrs-aspects/implementations/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/NamespaceDeclaration.java Sat Jun 13 15:22:46 2015
@@ -18,7 +18,9 @@
  */
 package org.apache.axiom.om.impl.dom;
 
+import org.apache.axiom.core.NodeFactory;
 import org.apache.axiom.dom.DOMNamespaceDeclaration;
+import org.apache.axiom.om.OMCloneOptions;
 import org.apache.axiom.om.OMFactory;
 import org.apache.axiom.om.OMNamespace;
 
@@ -31,6 +33,10 @@ final class NamespaceDeclaration extends
         declaredNamespace = namespace;
     }
 
+    public final NodeFactory coreGetNodeFactory() {
+        return ((NodeFactory)getOMFactory());
+    }
+
     public String coreGetDeclaredPrefix() {
         return declaredNamespace.getPrefix();
     }
@@ -39,4 +45,11 @@ final class NamespaceDeclaration extends
     public String coreGetDeclaredNamespaceURI() {
         return getValue();
     }
+
+    @Override
+    final ParentNode shallowClone(OMCloneOptions options, ParentNode targetParent,
+            boolean namespaceRepairing) {
+        // TODO
+        throw new UnsupportedOperationException();
+    }
 }

Modified: webservices/axiom/branches/attrs-aspects/implementations/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/factory/OMDOMFactory.java
URL: http://svn.apache.org/viewvc/webservices/axiom/branches/attrs-aspects/implementations/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/factory/OMDOMFactory.java?rev=1685272&r1=1685271&r2=1685272&view=diff
==============================================================================
--- webservices/axiom/branches/attrs-aspects/implementations/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/factory/OMDOMFactory.java (original)
+++ webservices/axiom/branches/attrs-aspects/implementations/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/factory/OMDOMFactory.java Sat Jun 13 15:22:46 2015
@@ -328,8 +328,7 @@ public class OMDOMFactory implements Axi
 
     public CoreNSAwareAttribute createAttribute(CoreDocument document, String namespaceURI,
             String localName, String prefix, String value, String type) {
-        // TODO
-        throw new UnsupportedOperationException();
+        return new NSAwareAttribute((DocumentImpl)document, localName, namespaceURI.isEmpty() ? null : new OMNamespaceImpl(namespaceURI, prefix), this);
     }
 
     public final CoreNamespaceDeclaration createNamespaceDeclaration(CoreDocument document,