You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ws.apache.org by co...@apache.org on 2017/02/02 10:59:00 UTC

svn commit: r1781369 - in /webservices/wss4j/trunk/policy/src/main/java/org/apache/wss4j/policy/model: AbstractSecuredParts.java DOM2Writer.java NSStack.java

Author: coheigea
Date: Thu Feb  2 10:58:59 2017
New Revision: 1781369

URL: http://svn.apache.org/viewvc?rev=1781369&view=rev
Log:
Missing files

Added:
    webservices/wss4j/trunk/policy/src/main/java/org/apache/wss4j/policy/model/AbstractSecuredParts.java
    webservices/wss4j/trunk/policy/src/main/java/org/apache/wss4j/policy/model/DOM2Writer.java
    webservices/wss4j/trunk/policy/src/main/java/org/apache/wss4j/policy/model/NSStack.java

Added: webservices/wss4j/trunk/policy/src/main/java/org/apache/wss4j/policy/model/AbstractSecuredParts.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/policy/src/main/java/org/apache/wss4j/policy/model/AbstractSecuredParts.java?rev=1781369&view=auto
==============================================================================
--- webservices/wss4j/trunk/policy/src/main/java/org/apache/wss4j/policy/model/AbstractSecuredParts.java (added)
+++ webservices/wss4j/trunk/policy/src/main/java/org/apache/wss4j/policy/model/AbstractSecuredParts.java Thu Feb  2 10:58:59 2017
@@ -0,0 +1,128 @@
+/**
+ * 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.wss4j.policy.model;
+
+import org.apache.neethi.Constants;
+import org.apache.wss4j.policy.SPConstants;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+import java.util.List;
+
+public abstract class AbstractSecuredParts extends RequiredParts {
+
+    private boolean body;
+    private Attachments attachments;
+
+    public AbstractSecuredParts(SPConstants.SPVersion version, boolean body, Attachments attachments,
+                       List<Header> headers) {
+        super(version, headers);
+
+        this.body = body;
+        this.attachments = attachments;
+    }
+
+    @Override
+    public QName getName() {
+        return getVersion().getSPConstants().getSignedParts();
+    }
+    
+    @Override
+    public boolean equals(Object object) {
+        if (object == this) {
+            return true;
+        }
+        if (!(object instanceof AbstractSecuredParts)) {
+            return false;
+        }
+        
+        AbstractSecuredParts that = (AbstractSecuredParts)object;
+        if (body != that.body) {
+            return false;
+        }
+        if (attachments != null && !attachments.equals(that.attachments) 
+            || attachments == null && that.attachments != null) {
+            return false;
+        }
+        
+        return super.equals(object);
+    }
+    
+    @Override
+    public int hashCode() {
+        int result = 17;
+        if (attachments != null) {
+            result = 31 * result + attachments.hashCode();
+        }
+        result = 31 * result + Boolean.hashCode(body);
+        
+        return 31 * result + super.hashCode();
+    }
+
+    @Override
+    public void serialize(XMLStreamWriter writer) throws XMLStreamException {
+        writer.writeStartElement(getName().getPrefix(), getName().getLocalPart(), getName().getNamespaceURI());
+        writer.writeNamespace(getName().getPrefix(), getName().getNamespaceURI());
+        if (!isNormalized() && isOptional()) {
+            writer.writeAttribute(Constants.ATTR_WSP,
+                                  writer.getNamespaceContext().getNamespaceURI(Constants.ATTR_WSP),
+                                  Constants.ATTR_OPTIONAL, "true");
+        }
+        if (isIgnorable()) {
+            writer.writeAttribute(Constants.ATTR_WSP,
+                                  writer.getNamespaceContext().getNamespaceURI(Constants.ATTR_WSP),
+                                  Constants.ATTR_IGNORABLE, "true");
+        }
+        if (isBody()) {
+            final QName body = getVersion().getSPConstants().getBody();
+            writer.writeEmptyElement(body.getPrefix(), body.getLocalPart(), body.getNamespaceURI());
+        }
+        for (int i = 0; i < getHeaders().size(); i++) {
+            Header header = getHeaders().get(i);
+            final QName headerName = getVersion().getSPConstants().getHeader();
+            writer.writeEmptyElement(headerName.getPrefix(), headerName.getLocalPart(), headerName.getNamespaceURI());
+            if (header.getName() != null) {
+                writer.writeAttribute(SPConstants.NAME, header.getName());
+            }
+            writer.writeAttribute(SPConstants.NAMESPACE, header.getNamespace());
+        }
+        if (getAttachments() != null) {
+            getAttachments().serialize(writer);
+        }
+        writer.writeEndElement();
+    }
+
+    public boolean isBody() {
+        return body;
+    }
+
+    protected void setBody(boolean body) {
+        this.body = body;
+    }
+
+    public Attachments getAttachments() {
+        return attachments;
+    }
+
+    protected void setAttachments(Attachments attachments) {
+        this.attachments = attachments;
+    }
+
+}

Added: webservices/wss4j/trunk/policy/src/main/java/org/apache/wss4j/policy/model/DOM2Writer.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/policy/src/main/java/org/apache/wss4j/policy/model/DOM2Writer.java?rev=1781369&view=auto
==============================================================================
--- webservices/wss4j/trunk/policy/src/main/java/org/apache/wss4j/policy/model/DOM2Writer.java (added)
+++ webservices/wss4j/trunk/policy/src/main/java/org/apache/wss4j/policy/model/DOM2Writer.java Thu Feb  2 10:58:59 2017
@@ -0,0 +1,299 @@
+/**
+ * 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.wss4j.policy.model;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.io.Writer;
+
+/**
+ * This class is a utility to serialize a DOM node as XML. This class
+ * uses the <code>DOM Level 2</code> APIs.
+ * The main difference between this class and DOMWriter is that this class
+ * generates and prints out namespace declarations.
+ */
+final class DOM2Writer {
+    public static final char NL = '\n';
+    public static final String LS = System.getProperty("line.separator",
+            Character.valueOf(NL).toString());
+    
+    public static final String XMLNS_NS = "http://www.w3.org/2000/xmlns/";
+    public static final String XML_NS = "http://www.w3.org/XML/1998/namespace";
+
+    private DOM2Writer() {
+        // Complete
+    }
+
+    /**
+     * Return a string containing this node serialized as XML.
+     */
+    public static String nodeToString(Node node) {
+        StringWriter sw = new StringWriter();
+        serializeAsXML(node, sw, true);
+        return sw.toString();
+    }
+
+    /**
+     * Return a string containing this node serialized as XML.
+     */
+    public static String nodeToString(Node node, boolean omitXMLDecl) {
+        StringWriter sw = new StringWriter();
+        serializeAsXML(node, sw, omitXMLDecl);
+        return sw.toString();
+    }
+
+    /**
+     * Serialize this node into the writer as XML.
+     */
+    public static void serializeAsXML(Node node, Writer writer,
+                                      boolean omitXMLDecl) {
+        serializeAsXML(node, writer, omitXMLDecl, false);
+    }
+
+    /**
+     * Serialize this node into the writer as XML.
+     */
+    public static void serializeAsXML(Node node, Writer writer,
+                                      boolean omitXMLDecl,
+                                      boolean pretty) {
+        PrintWriter out = new PrintWriter(writer);
+        if (!omitXMLDecl) {
+            out.print("<?xml version=\"1.0\" encoding=UTF-8 ?>");
+        }
+        NSStack namespaceStack = new NSStack();
+        print(node, namespaceStack, out, pretty, 0);
+        out.flush();
+    }
+
+    private static void print(Node node, NSStack namespaceStack,
+                              PrintWriter out, boolean pretty,
+                              int indent) {
+        if (node == null) {
+            return;
+        }
+        boolean hasChildren = false;
+        int type = node.getNodeType();
+        switch (type) {
+            case Node.DOCUMENT_NODE:
+                Node child = node.getFirstChild();
+                while (child != null) {
+                    print(child, namespaceStack, out, pretty, indent);
+                    child = child.getNextSibling();
+                }
+                break;
+            case Node.ELEMENT_NODE:
+                namespaceStack.push();
+                if (pretty) {
+                    for (int i = 0; i < indent; i++) {
+                        out.print(' ');
+                    }
+                }
+                out.print('<' + node.getNodeName());
+                String elPrefix = node.getPrefix();
+                String elNamespaceURI = node.getNamespaceURI();
+                if (elPrefix != null && elNamespaceURI != null && elPrefix.length() > 0) {
+                    boolean prefixIsDeclared = false;
+                    try {
+                        String namespaceURI = namespaceStack.getNamespaceURI(elPrefix);
+                        if (elNamespaceURI.equals(namespaceURI)) {
+                            prefixIsDeclared = true;
+                        }
+                    } catch (IllegalArgumentException e) { //NOPMD
+                        //
+                    }
+                    if (!prefixIsDeclared) {
+                        printNamespaceDecl(node, namespaceStack, out);
+                    }
+                }
+                NamedNodeMap attrs = node.getAttributes();
+                int len = (attrs != null) ? attrs.getLength() : 0;
+                for (int i = 0; i < len; i++) {
+                    Attr attr = (Attr) attrs.item(i);
+                    out.print(' ' + attr.getNodeName() + "=\"");
+                    normalize(attr.getValue(), out);
+                    out.print('\"');
+                    String attrPrefix = attr.getPrefix();
+                    String attrNamespaceURI = attr.getNamespaceURI();
+                    if (attrPrefix != null && attrNamespaceURI != null) {
+                        boolean prefixIsDeclared = false;
+                        try {
+                            String namespaceURI = namespaceStack.getNamespaceURI(attrPrefix);
+                            if (attrNamespaceURI.equals(namespaceURI)) {
+                                prefixIsDeclared = true;
+                            }
+                        } catch (IllegalArgumentException e) { //NOPMD
+                            //
+                        }
+                        if (!prefixIsDeclared) {
+                            printNamespaceDecl(attr, namespaceStack, out);
+                        }
+                    }
+                }
+                child = node.getFirstChild();
+                if (child != null) {
+                    hasChildren = true;
+                    out.print('>');
+                    if (pretty) {
+                        out.print(LS);
+                    }
+                    while (child != null) {
+                        print(child, namespaceStack, out, pretty, indent + 1);
+                        child = child.getNextSibling();
+                    }
+                } else {
+                    hasChildren = false;
+                    out.print("/>");
+                    if (pretty) {
+                        out.print(LS);
+                    }
+                }
+                namespaceStack.pop();
+                break;
+            case Node.ENTITY_REFERENCE_NODE:
+                out.print('&');
+                out.print(node.getNodeName());
+                out.print(';');
+                break;
+            case Node.CDATA_SECTION_NODE:
+                out.print("<![CDATA[");
+                out.print(node.getNodeValue());
+                out.print("]]>");
+                break;
+            case Node.TEXT_NODE:
+                normalize(node.getNodeValue(), out);
+                break;
+            case Node.COMMENT_NODE:
+                out.print("<!--");
+                out.print(node.getNodeValue());
+                out.print("-->");
+                if (pretty) {
+                    out.print(LS);
+                }
+                break;
+            case Node.PROCESSING_INSTRUCTION_NODE:
+                out.print("<?");
+                out.print(node.getNodeName());
+                String data = node.getNodeValue();
+                if (data != null && data.length() > 0) {
+                    out.print(' ');
+                    out.print(data);
+                }
+                out.println("?>");
+                if (pretty) {
+                    out.print(LS);
+                }
+                break;
+        }
+        if (type == Node.ELEMENT_NODE && hasChildren) {
+            if (pretty) {
+                for (int i = 0; i < indent; i++) {
+                    out.print(' ');
+                }
+            }
+            out.print("</");
+            out.print(node.getNodeName());
+            out.print('>');
+            if (pretty) {
+                out.print(LS);
+            }
+            hasChildren = false;
+        }
+    }
+
+    private static void printNamespaceDecl(Node node,
+                                           NSStack namespaceStack,
+                                           PrintWriter out) {
+        switch (node.getNodeType()) {
+            case Node.ATTRIBUTE_NODE:
+                printNamespaceDecl(((Attr) node).getOwnerElement(), node,
+                                   namespaceStack, out);
+                break;
+            case Node.ELEMENT_NODE:
+                printNamespaceDecl((Element) node, node, namespaceStack, out);
+                break;
+        }
+    }
+
+    private static void printNamespaceDecl(Element owner, Node node,
+                                           NSStack namespaceStack,
+                                           PrintWriter out) {
+        String namespaceURI = node.getNamespaceURI();
+        String prefix = node.getPrefix();
+        if (!(namespaceURI.equals(XMLNS_NS) && prefix.equals("xmlns")) 
+            && !(namespaceURI.equals(XML_NS) && prefix.equals("xml"))) {
+            if (getNamespace(prefix, owner) == null) {
+                out.print(" xmlns:" + prefix + "=\"" + namespaceURI + '\"');
+            }
+        } else {
+            prefix = node.getLocalName();
+            namespaceURI = node.getNodeValue();
+        }
+        namespaceStack.add(namespaceURI, prefix);
+    }
+
+    /**
+     * Normalizes and prints the given string.
+     */
+    public static void normalize(String s, PrintWriter fOut) {
+        int len = (s != null) ? s.length() : 0;
+        for (int i = 0; i < len; i++) {
+            char c = s.charAt(i);
+            switch (c) {
+                case '<':
+                    fOut.print("&lt;");
+                    break;
+                case '>':
+                    fOut.print("&gt;");
+                    break;
+                case '&':
+                    fOut.print("&amp;");
+                    break;
+                case '"':
+                    fOut.print("&quot;");
+                    break;
+                case '\r':
+                case '\n':
+                default:
+                    fOut.print(c);
+            }
+        }
+    }
+    
+    private static String getNamespace(String prefix, Node e) {
+        while (e != null && e.getNodeType() == Node.ELEMENT_NODE) {
+            Attr attr = null;
+            if (prefix == null) {
+                attr = ((Element) e).getAttributeNode("xmlns");
+            } else {
+                attr = ((Element) e).getAttributeNodeNS(XMLNS_NS, prefix);
+            }
+            if (attr != null) {
+                return attr.getValue();
+            }
+            e = e.getParentNode();
+        }
+        return null;
+    }
+}

Added: webservices/wss4j/trunk/policy/src/main/java/org/apache/wss4j/policy/model/NSStack.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/policy/src/main/java/org/apache/wss4j/policy/model/NSStack.java?rev=1781369&view=auto
==============================================================================
--- webservices/wss4j/trunk/policy/src/main/java/org/apache/wss4j/policy/model/NSStack.java (added)
+++ webservices/wss4j/trunk/policy/src/main/java/org/apache/wss4j/policy/model/NSStack.java Thu Feb  2 10:58:59 2017
@@ -0,0 +1,305 @@
+/**
+ * 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.wss4j.policy.model;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The abstraction this class provides is a push down stack of variable
+ * length frames of prefix to namespace mappings.  Used for keeping track
+ * of what namespaces are active at any given point as an XML document is
+ * traversed or produced.
+ * <p/>
+ * From a performance point of view, this data will both be modified frequently
+ * (at a minimum, there will be one push and pop per XML element processed),
+ * and scanned frequently (many of the "good" mappings will be at the bottom
+ * of the stack).  The one saving grace is that the expected maximum
+ * cardinalities of the number of frames and the number of total mappings
+ * is only in the dozens, representing the nesting depth of an XML document
+ * and the number of active namespaces at any point in the processing.
+ * <p/>
+ * Accordingly, this stack is implemented as a single array, will null
+ * values used to indicate frame boundaries.
+ *
+ */
+class NSStack {
+
+    private Mapping[] stack;
+    private int top = 0;
+    private int iterator = 0;
+    private int currentDefaultNS = -1;
+    // invariant member variable to track low-level logging requirements
+    // we cache this once per instance lifecycle to avoid repeated lookups
+    // in heavily used code.
+
+    NSStack() {
+        stack = new Mapping[32];
+        stack[0] = null;
+    }
+
+    /**
+     * Create a new frame at the top of the stack.
+     */
+    public void push() {
+        top++;
+        if (top >= stack.length) {
+            Mapping[] newstack = new Mapping[stack.length * 2];
+            System.arraycopy(stack, 0, newstack, 0, stack.length);
+            stack = newstack;
+        }
+        stack[top] = null;
+    }
+
+    /**
+     * Remove the top frame from the stack.
+     */
+    public void pop() {
+        clearFrame();
+        top--;
+
+        // If we've moved below the current default NS, figure out the new
+        // default (if any)
+        if (top < currentDefaultNS) {
+            // Reset the currentDefaultNS to ignore the frame just removed.
+            currentDefaultNS = top;
+            while (currentDefaultNS > 0) {
+                if (stack[currentDefaultNS] != null 
+                    && stack[currentDefaultNS].getPrefix().length() == 0) {
+                    break;
+                }
+                currentDefaultNS--;
+            }
+        }
+        if (top == 0) {
+            return;
+        }
+    }
+
+    /**
+     * Return a copy of the current frame.  Returns null if none are present.
+     */
+    public List<Mapping> cloneFrame() {
+        if (stack[top] == null) {
+            return null;
+        }
+        List<Mapping> clone = new ArrayList<>();
+        for (Mapping map = topOfFrame(); map != null; map = next()) {
+            clone.add(map);
+        }
+        return clone;
+    }
+
+    /**
+     * Remove all mappings from the current frame.
+     */
+    private void clearFrame() {
+        while (stack[top] != null) {
+            top--;
+        }
+    }
+
+    /**
+     * Reset the embedded iterator in this class to the top of the current
+     * (i.e., last) frame.  Note that this is not threadsafe, nor does it
+     * provide multiple iterators, so don't use this recursively.  Nor
+     * should you modify the stack while iterating over it.
+     */
+    public Mapping topOfFrame() {
+        iterator = top;
+        while (stack[iterator] != null) {
+            iterator--;
+        }
+        iterator++;
+        return next();
+    }
+
+    /**
+     * Return the next namespace mapping in the top frame.
+     */
+    public Mapping next() {
+        if (iterator > top) {
+            return null;
+        } else {
+            return stack[iterator++];
+        }
+    }
+
+    /**
+     * Add a mapping for a namespaceURI to the specified prefix to the top
+     * frame in the stack.  If the prefix is already mapped in that frame,
+     * remap it to the (possibly different) namespaceURI.
+     */
+    public void add(String namespaceURI, String prefix) {
+        int idx = top;
+        try {
+            // Replace duplicate prefixes (last wins - this could also fault)
+            for (int cursor = top; stack[cursor] != null; cursor--) {
+                if (stack[cursor].getPrefix().equals(prefix)) {
+                    stack[cursor].setNamespaceURI(namespaceURI);
+                    idx = cursor;
+                    return;
+                }
+            }
+            push();
+            stack[top] = new Mapping(namespaceURI, prefix);
+            idx = top;
+        } finally {
+            // If this is the default namespace, note the new in-scope
+            // default is here.
+            if (prefix.length() == 0) {
+                currentDefaultNS = idx;
+            }
+        }
+    }
+
+    /**
+     * Return an active prefix for the given namespaceURI.  NOTE : This
+     * may return null even if the namespaceURI was actually mapped further
+     * up the stack IF the prefix which was used has been repeated further
+     * down the stack.  I.e.:
+     * <p/>
+     * <pre:outer xmlns:pre="namespace">
+     * <pre:inner xmlns:pre="otherNamespace">
+     * *here's where we're looking*
+     * </pre:inner>
+     * </pre:outer>
+     * <p/>
+     * If we look for a prefix for "namespace" at the indicated spot, we won't
+     * find one because "pre" is actually mapped to "otherNamespace"
+     */
+    public String getPrefix(String namespaceURI, boolean noDefault) {
+        if (namespaceURI == null || namespaceURI.equals("")) {
+            return null;
+        }
+        int hash = namespaceURI.hashCode();
+
+        // If defaults are OK, and the given NS is the current default,
+        // return "" as the prefix to favor defaults where possible.
+        if (!noDefault && currentDefaultNS > 0 && stack[currentDefaultNS] != null 
+            && namespaceURI.equals(stack[currentDefaultNS].getNamespaceURI())) {
+            return "";
+        }
+        for (int cursor = top; cursor > 0; cursor--) {
+            Mapping map = stack[cursor];
+            if (map == null) {
+                continue;
+            }
+            if (map.getNamespaceHash() == hash && map.getNamespaceURI().equals(namespaceURI)) {
+                String possiblePrefix = map.getPrefix();
+                if (noDefault && possiblePrefix.length() == 0) {
+                    continue;
+                }
+
+                // now make sure that this is the first occurance of this
+                // particular prefix
+                int ppHash = possiblePrefix.hashCode();
+                for (int cursor2 = top; true; cursor2--) {
+                    if (cursor2 == cursor) {
+                        return possiblePrefix;
+                    }
+                    map = stack[cursor2];
+                    if (map == null) {
+                        continue;
+                    }
+                    if (ppHash == map.getPrefixHash() && possiblePrefix.equals(map.getPrefix())) {
+                        break;
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Return an active prefix for the given namespaceURI, including
+     * the default prefix ("").
+     */
+    public String getPrefix(String namespaceURI) {
+        return getPrefix(namespaceURI, false);
+    }
+
+    /**
+     * Given a prefix, return the associated namespace (if any).
+     */
+    public String getNamespaceURI(String prefix) {
+        String pfix = prefix;
+        if (pfix == null) {
+            pfix = "";
+        }
+        int hash = pfix.hashCode();
+        for (int cursor = top; cursor > 0; cursor--) {
+            Mapping map = stack[cursor];
+            if (map == null) {
+                continue;
+            }
+            if (map.getPrefixHash() == hash && map.getPrefix().equals(pfix)) {
+                return map.getNamespaceURI();
+            }
+        }
+        return null;
+    }
+
+    private static class Mapping implements Serializable {
+        /**
+         *
+         */
+        private static final long serialVersionUID = 4598721541118599293L;
+        private String namespaceURI;
+        private int namespaceHash;
+
+        private String prefix;
+        private int prefixHash;
+
+        Mapping(String namespaceURI, String prefix) {
+            setPrefix(prefix);
+            setNamespaceURI(namespaceURI);
+        }
+
+        public String getNamespaceURI() {
+            return namespaceURI;
+        }
+
+        public int getNamespaceHash() {
+            return namespaceHash;
+        }
+
+        public void setNamespaceURI(String namespaceURI) {
+            this.namespaceURI = namespaceURI;
+            this.namespaceHash = namespaceURI.hashCode();
+        }
+
+        public String getPrefix() {
+            return prefix;
+        }
+
+        public int getPrefixHash() {
+            return prefixHash;
+        }
+
+        public void setPrefix(String prefix) {
+            this.prefix = prefix;
+            this.prefixHash = prefix.hashCode();
+        }
+
+    }
+
+}