All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.persistence.internal.oxm.XPathFragment Maven / Gradle / Ivy

There is a newer version: 5.0.0-B03
Show newest version
/*
 * Copyright (c) 1998, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.internal.oxm;

import java.nio.charset.Charset;
import java.util.HashSet;
import java.util.Set;
import java.util.StringTokenizer;

import javax.xml.namespace.QName;

import org.eclipse.persistence.internal.oxm.mappings.Field;

/**
 * INTERNAL:
 * 

Purpose: Represents a token from an XPath statement.

*

For example the following XPath statment a/b[2]/text() corresponds to three * XPathFragments: "a", "b[2]", and "text()".

*

Responsibilities:

    *
  • Maintain name, namespace, and prefix information.
  • *
  • Maintain information about the corresponding node type.
  • *
  • Maintain index information if any. The XPathFragment corresponding to * b[2] would have an index value of 2.
  • *
*/ public class XPathFragment { public static final XPathFragment TEXT_FRAGMENT = new XPathFragment(Constants.TEXT); public static final String SELF_XPATH = "."; public static final XPathFragment SELF_FRAGMENT = new XPathFragment(SELF_XPATH); public static final XPathFragment ANY_FRAGMENT = null; public static final Charset CHARSET = Charset.forName(Constants.DEFAULT_XML_ENCODING); private XPathFragment nextFragment; private XML_FIELD xmlField; private String xpath; protected boolean hasAttribute = false; private boolean hasText = false; private boolean hasNamespace = false; private boolean containsIndex = false; private int indexValue = -1;//if containsIndex, then this is the value of the index. private boolean shouldExecuteSelectNodes = false; private String shortName; private String prefix; private byte[] prefixBytes; private String localName; private byte[] localNameBytes; private String namespaceURI; protected boolean nameIsText = false; protected boolean isSelfFragment = false; private QName leafElementType; private boolean generatedPrefix = false; private XPathPredicate predicate; private boolean namespaceAware; private char namespaceSeparator; private Set attributeCollisionSet; private Set nonAttributeCollisionSet; public XPathFragment() { setNamespaceAware(true); namespaceSeparator = Constants.COLON; } public XPathFragment(String xpathString) { this(xpathString, Constants.COLON, true); } public XPathFragment(String xpathString, char namespaceSeparator, boolean namespaceAware) { this.namespaceSeparator = namespaceSeparator; setNamespaceAware(namespaceAware); setXPath(xpathString); } public void setPredicate(XPathPredicate condition) { this.predicate = condition; } public boolean isNamespaceAware() { return namespaceAware; } public void setNamespaceAware(boolean isNamespaceAware) { this.namespaceAware = isNamespaceAware; } public char getNamespaceSeparator() { return this.namespaceSeparator; } public void setNamespaceSeparator(char namespaceSeparator) { this.namespaceSeparator = namespaceSeparator; } public XPathPredicate getPredicate() { return predicate; } public XPathFragment getNextFragment() { return nextFragment; } public void setNextFragment(XPathFragment nextFragment) { this.nextFragment = nextFragment; } public void setXPath(String xpathString) { xpath = xpathString; shortName = xpathString; // handle case: company[name/text()="Oracle"] if(xpathString.length() > 0){ if ((xpath.indexOf('[') != -1) && (xpath.indexOf(']') == -1)) { setShouldExecuteSelectNodes(true); return; } // handle case: ancestor::*/jaxb:class/@name if (xpath.indexOf("::") != -1) { setShouldExecuteSelectNodes(true); return; } if (xpathString.charAt(0) == '@') { hasAttribute = true; shortName = xpathString.substring(1).intern(); indexValue = hasIndex(xpathString); setupNamespaceInformation(shortName); return; } if (xpathString.charAt(0) == '/') { setShouldExecuteSelectNodes(true); shortName = xpathString.substring(xpathString.lastIndexOf('/') + 1).intern(); indexValue = hasIndex(xpathString); setupNamespaceInformation(shortName); return; } } if (xpathString.equals(Constants.TEXT)) { nameIsText = true; shortName = xpathString.intern(); return; } else { nameIsText = false; } // handle "self" xpath if (xpathString.equals(SELF_XPATH)) { isSelfFragment = true; shortName = xpathString.intern(); return; } indexValue = hasIndex(xpathString); setupNamespaceInformation(shortName); } private void setupNamespaceInformation(String xpathString) { int nsindex = xpathString.indexOf(namespaceSeparator); if (nsindex != -1) { hasNamespace = true; localName = xpathString.substring(nsindex + 1).intern(); prefix = xpathString.substring(0, nsindex).intern(); } else { localName = xpathString.intern(); } } public boolean isAttribute() { return hasAttribute; } public void setAttribute(boolean isAttribute) { hasAttribute = isAttribute; } public String getShortName() { if(shortName == null){ if(prefix !=null && prefix.length() >0){ shortName = prefix + Constants.COLON + localName; }else{ shortName = localName; } } return shortName; } public String getPrefix() { return prefix; } public byte[] getPrefixBytes() { if(null == prefixBytes && null != prefix) { prefixBytes = prefix.getBytes(CHARSET); } return prefixBytes; } public void setPrefix(String prefix) { this.prefix = prefix; resetShortName(); } public String getLocalName() { return localName; } public byte[] getLocalNameBytes() { if(null == localNameBytes && null != localName) { localNameBytes = localName.getBytes(CHARSET); } return localNameBytes; } public void setLocalName(String localName) { this.localName = localName; resetShortName(); } public String getNamespaceURI() { return namespaceURI; } public void setNamespaceURI(String namespaceURI) { if (isSelfFragment || namespaceURI !=null && namespaceURI.length() == 0) { this.namespaceURI = null; } else { this.namespaceURI = namespaceURI; } } private int hasIndex(String xpathString) { int index = -1; int startindex = xpathString.lastIndexOf('['); if ((startindex != -1) && (xpathString.lastIndexOf(']') != -1)) { StringTokenizer st = new StringTokenizer(xpathString, "[]"); String element = st.nextToken(); while(st.hasMoreTokens()) { String indexString = st.nextToken(); try { index = Integer.parseInt(indexString); setContainsIndex(true); } catch (NumberFormatException e) { int equalsOffset = indexString.indexOf('='); if (equalsOffset >= 0) { XPathFragment xPathFragment = new XPathFragment(indexString.substring(0, equalsOffset)); String value = indexString.substring(equalsOffset + 2, indexString.length() - 1); predicate = new XPathPredicate(xPathFragment, value); } else { setContainsIndex(true); } setShouldExecuteSelectNodes(true); } } shortName = element; } else { index = -1; } return index; } public int getIndexValue() { return indexValue; } public void setIndexValue(int indexValue) { this.indexValue = indexValue; } public String getXPath() { return xpath; } public boolean hasNamespace() { return hasNamespace; } /** * INTERNAL: * Indicates if the xpath is "." * * @return true if the xpath is ".", false otherwise */ public boolean isSelfFragment() { return isSelfFragment; } public boolean nameIsText() { return nameIsText; } public void setHasText(boolean hasText) { this.hasText = hasText; } public boolean getHasText() { return hasText; } public void setContainsIndex(boolean containsIndex) { this.containsIndex = containsIndex; } public boolean containsIndex() { return containsIndex; } public void setShouldExecuteSelectNodes(boolean newShouldExecuteSelectNodes) { this.shouldExecuteSelectNodes = newShouldExecuteSelectNodes; } public boolean shouldExecuteSelectNodes() { return shouldExecuteSelectNodes; } public boolean equals(Object object) { return equals(object, false); } public boolean equals(Object object, boolean ignorePredicate) { if (null == object) { return false; } else if (this == object) { return true; } try { XPathFragment xPathFragment = (XPathFragment) object; if (hasAttribute && !xPathFragment.hasAttribute) { return false; } if (nameIsText && xPathFragment.nameIsText) { return true; } if (nameIsText != xPathFragment.nameIsText) { return false; } if ((null == localName && null != xPathFragment.localName) || (null != localName && null == xPathFragment.localName)) { return false; } if (null != localName && !localName.equals(xPathFragment.localName)) { return false; } if (namespaceAware && xPathFragment.isNamespaceAware()) { if ((null == namespaceURI && null != xPathFragment.namespaceURI) || (null != namespaceURI && null == xPathFragment.namespaceURI)) { return false; } if (null != namespaceURI && !namespaceURI.equals(xPathFragment.namespaceURI)) { return false; } } if (indexValue != xPathFragment.indexValue) { return false; } if(!ignorePredicate) { if (null == predicate && null != xPathFragment.predicate) { return false; } if (null != predicate && !predicate.equals(xPathFragment.predicate)) { return false; } } } catch (ClassCastException e) { return false; } return true; } public int hashCode() { if(null == localName) { return 1; } else { return localName.hashCode(); } } public QName getLeafElementType() { return leafElementType; } public boolean hasLeafElementType() { return leafElementType != null; } public void setLeafElementType(QName type) { leafElementType = type; } public void setGeneratedPrefix(boolean isGenerated) { generatedPrefix = isGenerated; } public boolean isGeneratedPrefix() { return generatedPrefix; } public XML_FIELD getXMLField() { return this.xmlField; } public void setXMLField(XML_FIELD field) { this.xmlField = field; } private void resetShortName(){ shortName = null; prefixBytes = null; localNameBytes = null; } /** * INTERNAL: * Gets auxiliary set for determining collisions during case insensitive unmarshalling. * * @param isAttribute Determine if retrieving an element or an attribute collision set. * @return * Set containing localNames of attributes or elements of an XPathFragment. */ public Set getChildrenCollisionSet(boolean isAttribute) { return isAttribute ? getAttributeCollisionSet() : getNonAttributeCollisionSet(); } private Set getAttributeCollisionSet() { if (attributeCollisionSet == null) attributeCollisionSet = new HashSet(); return attributeCollisionSet; } private Set getNonAttributeCollisionSet() { if (nonAttributeCollisionSet == null) nonAttributeCollisionSet = new HashSet(); return nonAttributeCollisionSet; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy