This commit is contained in:
Lana Steuck 2015-01-29 15:36:12 -08:00
commit a580d7fb6a
44 changed files with 4084 additions and 912 deletions

View File

@ -270,8 +270,8 @@ public final class BasisLibrary {
if (Double.isNaN(start)) if (Double.isNaN(start))
return(EMPTYSTRING); return(EMPTYSTRING);
final int strlen = value.length(); final int strlen = value.length();
int istart = (int)Math.round(start) - 1; int istart = (int)Math.round(start) - 1;
if (istart > strlen) if (istart > strlen)
return(EMPTYSTRING); return(EMPTYSTRING);
@ -292,10 +292,11 @@ public final class BasisLibrary {
public static String substringF(String value, double start, double length) { public static String substringF(String value, double start, double length) {
if (Double.isInfinite(start) || if (Double.isInfinite(start) ||
Double.isNaN(start) || Double.isNaN(start) ||
Double.isNaN(length)) Double.isNaN(length) ||
length < 0)
return(EMPTYSTRING); return(EMPTYSTRING);
int istart = (int)Math.round(start) - 1; int istart = (int)Math.round(start) - 1;
final int isum; final int isum;
if (Double.isInfinite(length)) if (Double.isInfinite(length))
isum = Integer.MAX_VALUE; isum = Integer.MAX_VALUE;

View File

@ -1,15 +1,15 @@
/* /*
* reserved comment block * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT REMOVE OR ALTER!
*/ */
/* /*
* Copyright 1999-2004 The Apache Software Foundation. * 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
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * http://www.apache.org/licenses/LICENSE-2.0
* 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 * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
@ -17,36 +17,21 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
// $Id: XPathExpressionImpl.java,v 1.3 2005/09/27 09:40:43 sunithareddy Exp $
package com.sun.org.apache.xpath.internal.jaxp; package com.sun.org.apache.xpath.internal.jaxp;
import com.sun.org.apache.xpath.internal.*;
import javax.xml.transform.TransformerException;
import com.sun.org.apache.xpath.internal.objects.XObject;
import com.sun.org.apache.xml.internal.dtm.DTM;
import com.sun.org.apache.xml.internal.utils.PrefixResolver;
import com.sun.org.apache.xpath.internal.res.XPATHErrorResources;
import com.sun.org.apache.xalan.internal.res.XSLMessages;
import com.sun.org.apache.xalan.internal.utils.FactoryImpl;
import com.sun.org.apache.xalan.internal.utils.FeatureManager; import com.sun.org.apache.xalan.internal.utils.FeatureManager;
import com.sun.org.apache.xpath.internal.objects.XObject;
import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName; import javax.xml.namespace.QName;
import javax.xml.xpath.XPathExpressionException; import javax.xml.transform.TransformerException;
import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathEvaluationResult;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFunctionResolver; import javax.xml.xpath.XPathFunctionResolver;
import javax.xml.xpath.XPathVariableResolver; import javax.xml.xpath.XPathVariableResolver;
import javax.xml.xpath.XPathConstants;
import org.w3c.dom.Node;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import org.w3c.dom.DOMImplementation; import org.w3c.dom.Node;
import org.w3c.dom.traversal.NodeIterator;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.xml.sax.InputSource; import org.xml.sax.InputSource;
/** /**
@ -54,22 +39,10 @@ import org.xml.sax.InputSource;
* *
* @author Ramesh Mandava * @author Ramesh Mandava
*/ */
public class XPathExpressionImpl implements javax.xml.xpath.XPathExpression{ public class XPathExpressionImpl extends XPathImplUtil implements XPathExpression {
private XPathFunctionResolver functionResolver;
private XPathVariableResolver variableResolver;
private JAXPPrefixResolver prefixResolver;
private com.sun.org.apache.xpath.internal.XPath xpath; private com.sun.org.apache.xpath.internal.XPath xpath;
// By default Extension Functions are allowed in XPath Expressions. If
// Secure Processing Feature is set on XPathFactory then the invocation of
// extensions function need to throw XPathFunctionException
private boolean featureSecureProcessing = false;
private boolean useServicesMechanism = true;
private final FeatureManager featureManager;
/** Protected constructor to prevent direct instantiation; use compile() /** Protected constructor to prevent direct instantiation; use compile()
* from the context. * from the context.
*/ */
@ -81,7 +54,7 @@ public class XPathExpressionImpl implements javax.xml.xpath.XPathExpression{
protected XPathExpressionImpl(com.sun.org.apache.xpath.internal.XPath xpath, protected XPathExpressionImpl(com.sun.org.apache.xpath.internal.XPath xpath,
JAXPPrefixResolver prefixResolver, JAXPPrefixResolver prefixResolver,
XPathFunctionResolver functionResolver, XPathFunctionResolver functionResolver,
XPathVariableResolver variableResolver ) { XPathVariableResolver variableResolver) {
this(xpath, prefixResolver, functionResolver, variableResolver, this(xpath, prefixResolver, functionResolver, variableResolver,
false, true, new FeatureManager()); false, true, new FeatureManager());
}; };
@ -89,291 +62,108 @@ public class XPathExpressionImpl implements javax.xml.xpath.XPathExpression{
protected XPathExpressionImpl(com.sun.org.apache.xpath.internal.XPath xpath, protected XPathExpressionImpl(com.sun.org.apache.xpath.internal.XPath xpath,
JAXPPrefixResolver prefixResolver,XPathFunctionResolver functionResolver, JAXPPrefixResolver prefixResolver,XPathFunctionResolver functionResolver,
XPathVariableResolver variableResolver, boolean featureSecureProcessing, XPathVariableResolver variableResolver, boolean featureSecureProcessing,
boolean useServicesMechanism, FeatureManager featureManager ) { boolean useServiceMechanism, FeatureManager featureManager) {
this.xpath = xpath; this.xpath = xpath;
this.prefixResolver = prefixResolver; this.prefixResolver = prefixResolver;
this.functionResolver = functionResolver; this.functionResolver = functionResolver;
this.variableResolver = variableResolver; this.variableResolver = variableResolver;
this.featureSecureProcessing = featureSecureProcessing; this.featureSecureProcessing = featureSecureProcessing;
this.useServicesMechanism = useServicesMechanism; this.useServiceMechanism = useServiceMechanism;
this.featureManager = featureManager; this.featureManager = featureManager;
}; };
public void setXPath (com.sun.org.apache.xpath.internal.XPath xpath ) { public void setXPath (com.sun.org.apache.xpath.internal.XPath xpath) {
this.xpath = xpath; this.xpath = xpath;
} }
public Object eval(Object item, QName returnType) public Object eval(Object item, QName returnType)
throws javax.xml.transform.TransformerException { throws javax.xml.transform.TransformerException {
XObject resultObject = eval ( item ); XObject resultObject = eval(item, xpath);
return getResultAsType( resultObject, returnType ); return getResultAsType(resultObject, returnType);
} }
private XObject eval ( Object contextItem ) @Override
throws javax.xml.transform.TransformerException {
com.sun.org.apache.xpath.internal.XPathContext xpathSupport = null;
if ( functionResolver != null ) {
JAXPExtensionsProvider jep = new JAXPExtensionsProvider(
functionResolver, featureSecureProcessing, featureManager );
xpathSupport = new com.sun.org.apache.xpath.internal.XPathContext( jep );
} else {
xpathSupport = new com.sun.org.apache.xpath.internal.XPathContext();
}
xpathSupport.setVarStack(new JAXPVariableStack(variableResolver));
XObject xobj = null;
Node contextNode = (Node)contextItem;
// We always need to have a ContextNode with Xalan XPath implementation
// To allow simple expression evaluation like 1+1 we are setting
// dummy Document as Context Node
if ( contextNode == null )
xobj = xpath.execute(xpathSupport, DTM.NULL, prefixResolver);
else
xobj = xpath.execute(xpathSupport, contextNode, prefixResolver);
return xobj;
}
/**
* <p>Evaluate the compiled XPath expression in the specified context and
* return the result as the specified type.</p>
*
* <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec
* for context item evaluation,
* variable, function and QName resolution and return type conversion.</p>
*
* <p>If <code>returnType</code> is not one of the types defined
* in {@link XPathConstants},
* then an <code>IllegalArgumentException</code> is thrown.</p>
*
* <p>If a <code>null</code> value is provided for
* <code>item</code>, an empty document will be used for the
* context.
* If <code>returnType</code> is <code>null</code>, then a
* <code>NullPointerException</code> is thrown.</p>
*
* @param item The starting context (node or node list, for example).
* @param returnType The desired return type.
*
* @return The <code>Object</code> that is the result of evaluating the
* expression and converting the result to
* <code>returnType</code>.
*
* @throws XPathExpressionException If the expression cannot be evaluated.
* @throws IllegalArgumentException If <code>returnType</code> is not one
* of the types defined in {@link XPathConstants}.
* @throws NullPointerException If <code>returnType</code> is
* <code>null</code>.
*/
public Object evaluate(Object item, QName returnType) public Object evaluate(Object item, QName returnType)
throws XPathExpressionException { throws XPathExpressionException {
//Validating parameters to enforce constraints defined by JAXP spec isSupported(returnType);
if ( returnType == null ) {
//Throwing NullPointerException as defined in spec
String fmsg = XSLMessages.createXPATHMessage(
XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
new Object[] {"returnType"} );
throw new NullPointerException( fmsg );
}
// Checking if requested returnType is supported. returnType need to be
// defined in XPathConstants
if ( !isSupported ( returnType ) ) {
String fmsg = XSLMessages.createXPATHMessage(
XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
new Object[] { returnType.toString() } );
throw new IllegalArgumentException ( fmsg );
}
try { try {
return eval( item, returnType); return eval(item, returnType);
} catch ( java.lang.NullPointerException npe ) { } catch (java.lang.NullPointerException npe) {
// If VariableResolver returns null Or if we get // If VariableResolver returns null Or if we get
// NullPointerException at this stage for some other reason // NullPointerException at this stage for some other reason
// then we have to reurn XPathException // then we have to reurn XPathException
throw new XPathExpressionException ( npe ); throw new XPathExpressionException (npe);
} catch ( javax.xml.transform.TransformerException te ) { } catch (javax.xml.transform.TransformerException te) {
Throwable nestedException = te.getException(); Throwable nestedException = te.getException();
if ( nestedException instanceof javax.xml.xpath.XPathFunctionException ) { if (nestedException instanceof javax.xml.xpath.XPathFunctionException) {
throw (javax.xml.xpath.XPathFunctionException)nestedException; throw (javax.xml.xpath.XPathFunctionException)nestedException;
} else { } else {
// For any other exceptions we need to throw // For any other exceptions we need to throw
// XPathExpressionException ( as per spec ) // XPathExpressionException (as per spec)
throw new XPathExpressionException( te); throw new XPathExpressionException(te);
} }
} }
} }
/**
* <p>Evaluate the compiled XPath expression in the specified context and @Override
* return the result as a <code>String</code>.</p>
*
* <p>This method calls {@link #evaluate(Object item, QName returnType)}
* with a <code>returnType</code> of
* {@link XPathConstants#STRING}.</p>
*
* <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec
* for context item evaluation,
* variable, function and QName resolution and return type conversion.</p>
*
* <p>If a <code>null</code> value is provided for
* <code>item</code>, an empty document will be used for the
* context.
*
* @param item The starting context (node or node list, for example).
*
* @return The <code>String</code> that is the result of evaluating the
* expression and converting the result to a
* <code>String</code>.
*
* @throws XPathExpressionException If the expression cannot be evaluated.
*/
public String evaluate(Object item) public String evaluate(Object item)
throws XPathExpressionException { throws XPathExpressionException {
return (String)this.evaluate( item, XPathConstants.STRING ); return (String)this.evaluate(item, XPathConstants.STRING);
} }
@Override
static DocumentBuilderFactory dbf = null;
static DocumentBuilder db = null;
static Document d = null;
/**
* <p>Evaluate the compiled XPath expression in the context of the
* specified <code>InputSource</code> and return the result as the
* specified type.</p>
*
* <p>This method builds a data model for the {@link InputSource} and calls
* {@link #evaluate(Object item, QName returnType)} on the resulting
* document object.</p>
*
* <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec
* for context item evaluation,
* variable, function and QName resolution and return type conversion.</p>
*
* <p>If <code>returnType</code> is not one of the types defined in
* {@link XPathConstants},
* then an <code>IllegalArgumentException</code> is thrown.</p>
*
*<p>If <code>source</code> or <code>returnType</code> is <code>null</code>,
* then a <code>NullPointerException</code> is thrown.</p>
*
* @param source The <code>InputSource</code> of the document to evaluate
* over.
* @param returnType The desired return type.
*
* @return The <code>Object</code> that is the result of evaluating the
* expression and converting the result to
* <code>returnType</code>.
*
* @throws XPathExpressionException If the expression cannot be evaluated.
* @throws IllegalArgumentException If <code>returnType</code> is not one
* of the types defined in {@link XPathConstants}.
* @throws NullPointerException If <code>source</code> or
* <code>returnType</code> is <code>null</code>.
*/
public Object evaluate(InputSource source, QName returnType) public Object evaluate(InputSource source, QName returnType)
throws XPathExpressionException { throws XPathExpressionException {
if ( ( source == null ) || ( returnType == null ) ) { isSupported (returnType);
String fmsg = XSLMessages.createXPATHMessage(
XPATHErrorResources.ER_SOURCE_RETURN_TYPE_CANNOT_BE_NULL,
null );
throw new NullPointerException ( fmsg );
}
// Checking if requested returnType is supported. returnType need to be
// defined in XPathConstants
if ( !isSupported ( returnType ) ) {
String fmsg = XSLMessages.createXPATHMessage(
XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
new Object[] { returnType.toString() } );
throw new IllegalArgumentException ( fmsg );
}
try { try {
if ( dbf == null ) { Document document = getDocument(source);
dbf = FactoryImpl.getDOMFactory(useServicesMechanism); return eval(document, returnType);
dbf.setNamespaceAware( true ); } catch (TransformerException e) {
dbf.setValidating( false ); throw new XPathExpressionException(e);
}
db = dbf.newDocumentBuilder();
Document document = db.parse( source );
return eval( document, returnType );
} catch ( Exception e ) {
throw new XPathExpressionException ( e );
} }
} }
/** @Override
* <p>Evaluate the compiled XPath expression in the context of the specified <code>InputSource</code> and return the result as a
* <code>String</code>.</p>
*
* <p>This method calls {@link #evaluate(InputSource source, QName returnType)} with a <code>returnType</code> of
* {@link XPathConstants#STRING}.</p>
*
* <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec
* for context item evaluation,
* variable, function and QName resolution and return type conversion.</p>
*
* <p>If <code>source</code> is <code>null</code>, then a <code>NullPointerException</code> is thrown.</p>
*
* @param source The <code>InputSource</code> of the document to evaluate over.
*
* @return The <code>String</code> that is the result of evaluating the expression and converting the result to a
* <code>String</code>.
*
* @throws XPathExpressionException If the expression cannot be evaluated.
* @throws NullPointerException If <code>source</code> is <code>null</code>.
*/
public String evaluate(InputSource source) public String evaluate(InputSource source)
throws XPathExpressionException { throws XPathExpressionException {
return (String)this.evaluate( source, XPathConstants.STRING ); return (String)this.evaluate(source, XPathConstants.STRING);
} }
private boolean isSupported( QName returnType ) { @Override
// XPathConstants.STRING public <T>T evaluateExpression(Object item, Class<T> type)
if ( ( returnType.equals( XPathConstants.STRING ) ) || throws XPathExpressionException {
( returnType.equals( XPathConstants.NUMBER ) ) || isSupportedClassType(type);
( returnType.equals( XPathConstants.BOOLEAN ) ) ||
( returnType.equals( XPathConstants.NODE ) ) ||
( returnType.equals( XPathConstants.NODESET ) ) ) {
return true; try {
} XObject resultObject = eval(item, xpath);
return false; if (type.isAssignableFrom(XPathEvaluationResult.class)) {
} return getXPathResult(resultObject, type);
} else {
return XPathResultImpl.getValue(resultObject, type);
}
private Object getResultAsType( XObject resultObject, QName returnType ) } catch (javax.xml.transform.TransformerException te) {
throws javax.xml.transform.TransformerException { throw new XPathExpressionException(te);
// XPathConstants.STRING
if ( returnType.equals( XPathConstants.STRING ) ) {
return resultObject.str();
} }
// XPathConstants.NUMBER
if ( returnType.equals( XPathConstants.NUMBER ) ) {
return new Double ( resultObject.num());
}
// XPathConstants.BOOLEAN
if ( returnType.equals( XPathConstants.BOOLEAN ) ) {
return new Boolean( resultObject.bool());
}
// XPathConstants.NODESET ---ORdered, UNOrdered???
if ( returnType.equals( XPathConstants.NODESET ) ) {
return resultObject.nodelist();
}
// XPathConstants.NODE
if ( returnType.equals( XPathConstants.NODE ) ) {
NodeIterator ni = resultObject.nodeset();
//Return the first node, or null
return ni.nextNode();
}
// If isSupported check is already done then the execution path
// shouldn't come here. Being defensive
String fmsg = XSLMessages.createXPATHMessage(
XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
new Object[] { returnType.toString()});
throw new IllegalArgumentException ( fmsg );
} }
@Override
public XPathEvaluationResult<?> evaluateExpression(Object item)
throws XPathExpressionException {
return evaluateExpression(item, XPathEvaluationResult.class);
}
@Override
public <T>T evaluateExpression(InputSource source, Class<T> type)
throws XPathExpressionException {
Document document = getDocument(source);
return evaluateExpression(document, type);
}
@Override
public XPathEvaluationResult<?> evaluateExpression(InputSource source)
throws XPathExpressionException {
return evaluateExpression(source, XPathEvaluationResult.class);
}
} }

View File

@ -1,6 +1,5 @@
/* /*
* reserved comment block * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT REMOVE OR ALTER!
*/ */
/* /*
* Copyright 1999-2004 The Apache Software Foundation. * Copyright 1999-2004 The Apache Software Foundation.
@ -28,55 +27,37 @@ import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFunctionResolver; import javax.xml.xpath.XPathFunctionResolver;
import javax.xml.xpath.XPathVariableResolver; import javax.xml.xpath.XPathVariableResolver;
import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathExpression;
import com.sun.org.apache.xml.internal.dtm.DTM;
import com.sun.org.apache.xpath.internal.*; import com.sun.org.apache.xpath.internal.*;
import com.sun.org.apache.xpath.internal.objects.XObject; import com.sun.org.apache.xpath.internal.objects.XObject;
import com.sun.org.apache.xpath.internal.res.XPATHErrorResources;
import com.sun.org.apache.xalan.internal.res.XSLMessages;
import com.sun.org.apache.xalan.internal.utils.FactoryImpl;
import com.sun.org.apache.xalan.internal.utils.FeatureManager; import com.sun.org.apache.xalan.internal.utils.FeatureManager;
import org.w3c.dom.Node;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import org.w3c.dom.traversal.NodeIterator;
import org.xml.sax.InputSource; import org.xml.sax.InputSource;
import org.xml.sax.SAXException; import javax.xml.transform.TransformerException;
import javax.xml.xpath.XPathEvaluationResult;
import javax.xml.parsers.*;
import java.io.IOException;
/** /**
* The XPathImpl class provides implementation for the methods defined in * The XPathImpl class provides implementation for the methods defined in
* javax.xml.xpath.XPath interface. This provide simple access to the results * javax.xml.xpath.XPath interface. This provides simple access to the results
* of an XPath expression. * of an XPath expression.
* *
*
* @author Ramesh Mandava * @author Ramesh Mandava
*
* Updated 12/04/2014:
* New methods: evaluateExpression
* Refactored to share code with XPathExpressionImpl.
*/ */
public class XPathImpl implements javax.xml.xpath.XPath { public class XPathImpl extends XPathImplUtil implements javax.xml.xpath.XPath {
// Private variables // Private variables
private XPathVariableResolver variableResolver;
private XPathFunctionResolver functionResolver;
private XPathVariableResolver origVariableResolver; private XPathVariableResolver origVariableResolver;
private XPathFunctionResolver origFunctionResolver; private XPathFunctionResolver origFunctionResolver;
private NamespaceContext namespaceContext=null; private NamespaceContext namespaceContext=null;
private JAXPPrefixResolver prefixResolver;
// By default Extension Functions are allowed in XPath Expressions. If
// Secure Processing Feature is set on XPathFactory then the invocation of
// extensions function need to throw XPathFunctionException
private boolean featureSecureProcessing = false;
private boolean useServiceMechanism = true;
private final FeatureManager featureManager;
XPathImpl( XPathVariableResolver vr, XPathFunctionResolver fr ) { XPathImpl(XPathVariableResolver vr, XPathFunctionResolver fr) {
this(vr, fr, false, true, new FeatureManager()); this(vr, fr, false, true, new FeatureManager());
} }
XPathImpl( XPathVariableResolver vr, XPathFunctionResolver fr, XPathImpl(XPathVariableResolver vr, XPathFunctionResolver fr,
boolean featureSecureProcessing, boolean useServiceMechanism, boolean featureSecureProcessing, boolean useServiceMechanism,
FeatureManager featureManager) { FeatureManager featureManager) {
this.origVariableResolver = this.variableResolver = vr; this.origVariableResolver = this.variableResolver = vr;
@ -86,451 +67,173 @@ public class XPathImpl implements javax.xml.xpath.XPath {
this.featureManager = featureManager; this.featureManager = featureManager;
} }
/**
* <p>Establishes a variable resolver.</p> //-Override-
*
* @param resolver Variable Resolver
*/
public void setXPathVariableResolver(XPathVariableResolver resolver) { public void setXPathVariableResolver(XPathVariableResolver resolver) {
if ( resolver == null ) { requireNonNull(resolver, "XPathVariableResolver");
String fmsg = XSLMessages.createXPATHMessage(
XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
new Object[] {"XPathVariableResolver"} );
throw new NullPointerException( fmsg );
}
this.variableResolver = resolver; this.variableResolver = resolver;
} }
/** //-Override-
* <p>Returns the current variable resolver.</p>
*
* @return Current variable resolver
*/
public XPathVariableResolver getXPathVariableResolver() { public XPathVariableResolver getXPathVariableResolver() {
return variableResolver; return variableResolver;
} }
/** //-Override-
* <p>Establishes a function resolver.</p>
*
* @param resolver XPath function resolver
*/
public void setXPathFunctionResolver(XPathFunctionResolver resolver) { public void setXPathFunctionResolver(XPathFunctionResolver resolver) {
if ( resolver == null ) { requireNonNull(resolver, "XPathFunctionResolver");
String fmsg = XSLMessages.createXPATHMessage(
XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
new Object[] {"XPathFunctionResolver"} );
throw new NullPointerException( fmsg );
}
this.functionResolver = resolver; this.functionResolver = resolver;
} }
/** //-Override-
* <p>Returns the current function resolver.</p>
*
* @return Current function resolver
*/
public XPathFunctionResolver getXPathFunctionResolver() { public XPathFunctionResolver getXPathFunctionResolver() {
return functionResolver; return functionResolver;
} }
/** //-Override-
* <p>Establishes a namespace context.</p>
*
* @param nsContext Namespace context to use
*/
public void setNamespaceContext(NamespaceContext nsContext) { public void setNamespaceContext(NamespaceContext nsContext) {
if ( nsContext == null ) { requireNonNull(nsContext, "NamespaceContext");
String fmsg = XSLMessages.createXPATHMessage(
XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
new Object[] {"NamespaceContext"} );
throw new NullPointerException( fmsg );
}
this.namespaceContext = nsContext; this.namespaceContext = nsContext;
this.prefixResolver = new JAXPPrefixResolver ( nsContext ); this.prefixResolver = new JAXPPrefixResolver (nsContext);
} }
/** //-Override-
* <p>Returns the current namespace context.</p>
*
* @return Current Namespace context
*/
public NamespaceContext getNamespaceContext() { public NamespaceContext getNamespaceContext() {
return namespaceContext; return namespaceContext;
} }
private static Document d = null;
private DocumentBuilder getParser() {
try {
// we'd really like to cache those DocumentBuilders, but we can't because:
// 1. thread safety. parsers are not thread-safe, so at least
// we need one instance per a thread.
// 2. parsers are non-reentrant, so now we are looking at having a
// pool of parsers.
// 3. then the class loading issue. The look-up procedure of
// DocumentBuilderFactory.newInstance() depends on context class loader
// and system properties, which may change during the execution of JVM.
//
// so we really have to create a fresh DocumentBuilder every time we need one
// - KK
DocumentBuilderFactory dbf = FactoryImpl.getDOMFactory(useServiceMechanism);
dbf.setNamespaceAware( true );
dbf.setValidating( false );
return dbf.newDocumentBuilder();
} catch (ParserConfigurationException e) {
// this should never happen with a well-behaving JAXP implementation.
throw new Error(e);
}
}
private XObject eval(String expression, Object contextItem)
throws javax.xml.transform.TransformerException {
com.sun.org.apache.xpath.internal.XPath xpath = new com.sun.org.apache.xpath.internal.XPath( expression,
null, prefixResolver, com.sun.org.apache.xpath.internal.XPath.SELECT );
com.sun.org.apache.xpath.internal.XPathContext xpathSupport = null;
if ( functionResolver != null ) {
JAXPExtensionsProvider jep = new JAXPExtensionsProvider(
functionResolver, featureSecureProcessing, featureManager );
xpathSupport = new com.sun.org.apache.xpath.internal.XPathContext( jep );
} else {
xpathSupport = new com.sun.org.apache.xpath.internal.XPathContext();
}
XObject xobj = null;
xpathSupport.setVarStack(new JAXPVariableStack(variableResolver));
// If item is null, then we will create a a Dummy contextNode
if ( contextItem instanceof Node ) {
xobj = xpath.execute (xpathSupport, (Node)contextItem,
prefixResolver );
} else {
xobj = xpath.execute ( xpathSupport, DTM.NULL, prefixResolver );
}
return xobj;
}
/** /**
* <p>Evaluate an <code>XPath</code> expression in the specified context and return the result as the specified type.</p> * Evaluate an {@code XPath} expression in the specified context.
*
* <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec
* for context item evaluation,
* variable, function and <code>QName</code> resolution and return type conversion.</p>
*
* <p>If <code>returnType</code> is not one of the types defined in {@link XPathConstants} (
* {@link XPathConstants#NUMBER NUMBER},
* {@link XPathConstants#STRING STRING},
* {@link XPathConstants#BOOLEAN BOOLEAN},
* {@link XPathConstants#NODE NODE} or
* {@link XPathConstants#NODESET NODESET})
* then an <code>IllegalArgumentException</code> is thrown.</p>
*
* <p>If a <code>null</code> value is provided for
* <code>item</code>, an empty document will be used for the
* context.
* If <code>expression</code> or <code>returnType</code> is <code>null</code>, then a
* <code>NullPointerException</code> is thrown.</p>
*
* @param expression The XPath expression. * @param expression The XPath expression.
* @param item The starting context (node or node list, for example). * @param contextItem The starting context.
* @param returnType The desired return type. * @return an XObject as the result of evaluating the expression
* * @throws TransformerException if evaluating fails
* @return Result of evaluating an XPath expression as an <code>Object</code> of <code>returnType</code>.
*
* @throws XPathExpressionException If <code>expression</code> cannot be evaluated.
* @throws IllegalArgumentException If <code>returnType</code> is not one of the types defined in {@link XPathConstants}.
* @throws NullPointerException If <code>expression</code> or <code>returnType</code> is <code>null</code>.
*/ */
private XObject eval(String expression, Object contextItem)
throws TransformerException {
requireNonNull(expression, "XPath expression");
com.sun.org.apache.xpath.internal.XPath xpath = new com.sun.org.apache.xpath.internal.XPath(expression,
null, prefixResolver, com.sun.org.apache.xpath.internal.XPath.SELECT);
return eval(contextItem, xpath);
}
//-Override-
public Object evaluate(String expression, Object item, QName returnType) public Object evaluate(String expression, Object item, QName returnType)
throws XPathExpressionException { throws XPathExpressionException {
if ( expression == null ) { //this check is necessary before calling eval to maintain binary compatibility
String fmsg = XSLMessages.createXPATHMessage( requireNonNull(expression, "XPath expression");
XPATHErrorResources.ER_ARG_CANNOT_BE_NULL, isSupported(returnType);
new Object[] {"XPath expression"} );
throw new NullPointerException ( fmsg );
}
if ( returnType == null ) {
String fmsg = XSLMessages.createXPATHMessage(
XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
new Object[] {"returnType"} );
throw new NullPointerException ( fmsg );
}
// Checking if requested returnType is supported. returnType need to
// be defined in XPathConstants
if ( !isSupported ( returnType ) ) {
String fmsg = XSLMessages.createXPATHMessage(
XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
new Object[] { returnType.toString() } );
throw new IllegalArgumentException ( fmsg );
}
try { try {
XObject resultObject = eval( expression, item ); XObject resultObject = eval(expression, item);
return getResultAsType( resultObject, returnType ); return getResultAsType(resultObject, returnType);
} catch ( java.lang.NullPointerException npe ) { } catch (java.lang.NullPointerException npe) {
// If VariableResolver returns null Or if we get // If VariableResolver returns null Or if we get
// NullPointerException at this stage for some other reason // NullPointerException at this stage for some other reason
// then we have to reurn XPathException // then we have to reurn XPathException
throw new XPathExpressionException ( npe ); throw new XPathExpressionException (npe);
} catch ( javax.xml.transform.TransformerException te ) { } catch (TransformerException te) {
Throwable nestedException = te.getException(); Throwable nestedException = te.getException();
if ( nestedException instanceof javax.xml.xpath.XPathFunctionException ) { if (nestedException instanceof javax.xml.xpath.XPathFunctionException) {
throw (javax.xml.xpath.XPathFunctionException)nestedException; throw (javax.xml.xpath.XPathFunctionException)nestedException;
} else { } else {
// For any other exceptions we need to throw // For any other exceptions we need to throw
// XPathExpressionException ( as per spec ) // XPathExpressionException (as per spec)
throw new XPathExpressionException ( te ); throw new XPathExpressionException (te);
} }
} }
} }
private boolean isSupported( QName returnType ) { //-Override-
if ( ( returnType.equals( XPathConstants.STRING ) ) ||
( returnType.equals( XPathConstants.NUMBER ) ) ||
( returnType.equals( XPathConstants.BOOLEAN ) ) ||
( returnType.equals( XPathConstants.NODE ) ) ||
( returnType.equals( XPathConstants.NODESET ) ) ) {
return true;
}
return false;
}
private Object getResultAsType( XObject resultObject, QName returnType )
throws javax.xml.transform.TransformerException {
// XPathConstants.STRING
if ( returnType.equals( XPathConstants.STRING ) ) {
return resultObject.str();
}
// XPathConstants.NUMBER
if ( returnType.equals( XPathConstants.NUMBER ) ) {
return new Double ( resultObject.num());
}
// XPathConstants.BOOLEAN
if ( returnType.equals( XPathConstants.BOOLEAN ) ) {
return new Boolean( resultObject.bool());
}
// XPathConstants.NODESET ---ORdered, UNOrdered???
if ( returnType.equals( XPathConstants.NODESET ) ) {
return resultObject.nodelist();
}
// XPathConstants.NODE
if ( returnType.equals( XPathConstants.NODE ) ) {
NodeIterator ni = resultObject.nodeset();
//Return the first node, or null
return ni.nextNode();
}
String fmsg = XSLMessages.createXPATHMessage(
XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
new Object[] { returnType.toString()});
throw new IllegalArgumentException( fmsg );
}
/**
* <p>Evaluate an XPath expression in the specified context and return the result as a <code>String</code>.</p>
*
* <p>This method calls {@link #evaluate(String expression, Object item, QName returnType)} with a <code>returnType</code> of
* {@link XPathConstants#STRING}.</p>
*
* <p>See "Evaluation of XPath Expressions" of JAXP 1.3 spec
* for context item evaluation,
* variable, function and QName resolution and return type conversion.</p>
*
* <p>If a <code>null</code> value is provided for
* <code>item</code>, an empty document will be used for the
* context.
* If <code>expression</code> is <code>null</code>, then a <code>NullPointerException</code> is thrown.</p>
*
* @param expression The XPath expression.
* @param item The starting context (node or node list, for example).
*
* @return The <code>String</code> that is the result of evaluating the expression and
* converting the result to a <code>String</code>.
*
* @throws XPathExpressionException If <code>expression</code> cannot be evaluated.
* @throws NullPointerException If <code>expression</code> is <code>null</code>.
*/
public String evaluate(String expression, Object item) public String evaluate(String expression, Object item)
throws XPathExpressionException { throws XPathExpressionException {
return (String)this.evaluate( expression, item, XPathConstants.STRING ); return (String)this.evaluate(expression, item, XPathConstants.STRING);
} }
/** //-Override-
* <p>Compile an XPath expression for later evaluation.</p>
*
* <p>If <code>expression</code> contains any {@link XPathFunction}s,
* they must be available via the {@link XPathFunctionResolver}.
* An {@link XPathExpressionException} will be thrown if the <code>XPathFunction</code>
* cannot be resovled with the <code>XPathFunctionResolver</code>.</p>
*
* <p>If <code>expression</code> is <code>null</code>, a <code>NullPointerException</code> is thrown.</p>
*
* @param expression The XPath expression.
*
* @return Compiled XPath expression.
* @throws XPathExpressionException If <code>expression</code> cannot be compiled.
* @throws NullPointerException If <code>expression</code> is <code>null</code>.
*/
public XPathExpression compile(String expression) public XPathExpression compile(String expression)
throws XPathExpressionException { throws XPathExpressionException {
if ( expression == null ) { requireNonNull(expression, "XPath expression");
String fmsg = XSLMessages.createXPATHMessage(
XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
new Object[] {"XPath expression"} );
throw new NullPointerException ( fmsg );
}
try { try {
com.sun.org.apache.xpath.internal.XPath xpath = new XPath (expression, null, com.sun.org.apache.xpath.internal.XPath xpath = new XPath (expression, null,
prefixResolver, com.sun.org.apache.xpath.internal.XPath.SELECT ); prefixResolver, com.sun.org.apache.xpath.internal.XPath.SELECT);
// Can have errorListener // Can have errorListener
XPathExpressionImpl ximpl = new XPathExpressionImpl (xpath, XPathExpressionImpl ximpl = new XPathExpressionImpl (xpath,
prefixResolver, functionResolver, variableResolver, prefixResolver, functionResolver, variableResolver,
featureSecureProcessing, useServiceMechanism, featureManager ); featureSecureProcessing, useServiceMechanism, featureManager);
return ximpl; return ximpl;
} catch ( javax.xml.transform.TransformerException te ) { } catch (TransformerException te) {
throw new XPathExpressionException ( te ) ; throw new XPathExpressionException (te) ;
} }
} }
//-Override-
/**
* <p>Evaluate an XPath expression in the context of the specified <code>InputSource</code>
* and return the result as the specified type.</p>
*
* <p>This method builds a data model for the {@link InputSource} and calls
* {@link #evaluate(String expression, Object item, QName returnType)} on the resulting document object.</p>
*
* <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec
* for context item evaluation,
* variable, function and QName resolution and return type conversion.</p>
*
* <p>If <code>returnType</code> is not one of the types defined in {@link XPathConstants},
* then an <code>IllegalArgumentException</code> is thrown.</p>
*
* <p>If <code>expression</code>, <code>source</code> or <code>returnType</code> is <code>null</code>,
* then a <code>NullPointerException</code> is thrown.</p>
*
* @param expression The XPath expression.
* @param source The input source of the document to evaluate over.
* @param returnType The desired return type.
*
* @return The <code>Object</code> that encapsulates the result of evaluating the expression.
*
* @throws XPathExpressionException If expression cannot be evaluated.
* @throws IllegalArgumentException If <code>returnType</code> is not one of the types defined in {@link XPathConstants}.
* @throws NullPointerException If <code>expression</code>, <code>source</code> or <code>returnType</code>
* is <code>null</code>.
*/
public Object evaluate(String expression, InputSource source, public Object evaluate(String expression, InputSource source,
QName returnType) throws XPathExpressionException { QName returnType) throws XPathExpressionException {
// Checking validity of different parameters isSupported(returnType);
if( source== null ) {
String fmsg = XSLMessages.createXPATHMessage(
XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
new Object[] {"source"} );
throw new NullPointerException ( fmsg );
}
if ( expression == null ) {
String fmsg = XSLMessages.createXPATHMessage(
XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
new Object[] {"XPath expression"} );
throw new NullPointerException ( fmsg );
}
if ( returnType == null ) {
String fmsg = XSLMessages.createXPATHMessage(
XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
new Object[] {"returnType"} );
throw new NullPointerException ( fmsg );
}
//Checking if requested returnType is supported.
//returnType need to be defined in XPathConstants
if ( !isSupported ( returnType ) ) {
String fmsg = XSLMessages.createXPATHMessage(
XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
new Object[] { returnType.toString() } );
throw new IllegalArgumentException ( fmsg );
}
try { try {
Document document = getDocument(source);
Document document = getParser().parse( source ); XObject resultObject = eval(expression, document);
return getResultAsType(resultObject, returnType);
XObject resultObject = eval( expression, document ); } catch (TransformerException te) {
return getResultAsType( resultObject, returnType );
} catch ( SAXException e ) {
throw new XPathExpressionException ( e );
} catch( IOException e ) {
throw new XPathExpressionException ( e );
} catch ( javax.xml.transform.TransformerException te ) {
Throwable nestedException = te.getException(); Throwable nestedException = te.getException();
if ( nestedException instanceof javax.xml.xpath.XPathFunctionException ) { if (nestedException instanceof javax.xml.xpath.XPathFunctionException) {
throw (javax.xml.xpath.XPathFunctionException)nestedException; throw (javax.xml.xpath.XPathFunctionException)nestedException;
} else { } else {
throw new XPathExpressionException ( te ); throw new XPathExpressionException (te);
} }
} }
} }
//-Override-
/**
* <p>Evaluate an XPath expression in the context of the specified <code>InputSource</code>
* and return the result as a <code>String</code>.</p>
*
* <p>This method calls {@link #evaluate(String expression, InputSource source, QName returnType)} with a
* <code>returnType</code> of {@link XPathConstants#STRING}.</p>
*
* <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec
* for context item evaluation,
* variable, function and QName resolution and return type conversion.</p>
*
* <p>If <code>expression</code> or <code>source</code> is <code>null</code>,
* then a <code>NullPointerException</code> is thrown.</p>
*
* @param expression The XPath expression.
* @param source The <code>InputSource</code> of the document to evaluate over.
*
* @return The <code>String</code> that is the result of evaluating the expression and
* converting the result to a <code>String</code>.
*
* @throws XPathExpressionException If expression cannot be evaluated.
* @throws NullPointerException If <code>expression</code> or <code>source</code> is <code>null</code>.
*/
public String evaluate(String expression, InputSource source) public String evaluate(String expression, InputSource source)
throws XPathExpressionException { throws XPathExpressionException {
return (String)this.evaluate( expression, source, XPathConstants.STRING ); return (String)this.evaluate(expression, source, XPathConstants.STRING);
} }
/** //-Override-
* <p>Reset this <code>XPath</code> to its original configuration.</p>
*
* <p><code>XPath</code> is reset to the same state as when it was created with
* {@link XPathFactory#newXPath()}.
* <code>reset()</code> is designed to allow the reuse of existing <code>XPath</code>s
* thus saving resources associated with the creation of new <code>XPath</code>s.</p>
*
* <p>The reset <code>XPath</code> is not guaranteed to have the same
* {@link XPathFunctionResolver}, {@link XPathVariableResolver}
* or {@link NamespaceContext} <code>Object</code>s, e.g. {@link Object#equals(Object obj)}.
* It is guaranteed to have a functionally equal <code>XPathFunctionResolver</code>,
* <code>XPathVariableResolver</code>
* and <code>NamespaceContext</code>.</p>
*/
public void reset() { public void reset() {
this.variableResolver = this.origVariableResolver; this.variableResolver = this.origVariableResolver;
this.functionResolver = this.origFunctionResolver; this.functionResolver = this.origFunctionResolver;
this.namespaceContext = null; this.namespaceContext = null;
} }
//-Override-
public <T> T evaluateExpression(String expression, Object item, Class<T> type)
throws XPathExpressionException {
isSupportedClassType(type);
try {
XObject resultObject = eval(expression, item);
if (type.isAssignableFrom(XPathEvaluationResult.class)) {
return getXPathResult(resultObject, type);
} else {
return XPathResultImpl.getValue(resultObject, type);
}
} catch (TransformerException te) {
throw new XPathExpressionException (te);
}
}
//-Override-
public XPathEvaluationResult<?> evaluateExpression(String expression, Object item)
throws XPathExpressionException {
return evaluateExpression(expression, item, XPathEvaluationResult.class);
}
//-Override-
public <T> T evaluateExpression(String expression, InputSource source, Class<T> type)
throws XPathExpressionException {
Document document = getDocument(source);
return evaluateExpression(expression, document, type);
}
//-Override-
public XPathEvaluationResult<?> evaluateExpression(String expression, InputSource source)
throws XPathExpressionException {
return evaluateExpression(expression, source, XPathEvaluationResult.class);
}
} }

View File

@ -0,0 +1,262 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.org.apache.xpath.internal.jaxp;
import com.sun.org.apache.xalan.internal.res.XSLMessages;
import com.sun.org.apache.xalan.internal.utils.FactoryImpl;
import com.sun.org.apache.xalan.internal.utils.FeatureManager;
import com.sun.org.apache.xml.internal.dtm.DTM;
import com.sun.org.apache.xpath.internal.objects.XObject;
import com.sun.org.apache.xpath.internal.res.XPATHErrorResources;
import java.io.IOException;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathEvaluationResult;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFunctionResolver;
import javax.xml.xpath.XPathNodes;
import javax.xml.xpath.XPathVariableResolver;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.traversal.NodeIterator;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
* This class contains several utility methods used by XPathImpl and
* XPathExpressionImpl
*/
class XPathImplUtil {
XPathFunctionResolver functionResolver;
XPathVariableResolver variableResolver;
JAXPPrefixResolver prefixResolver;
boolean useServiceMechanism = true;
// By default Extension Functions are allowed in XPath Expressions. If
// Secure Processing Feature is set on XPathFactory then the invocation of
// extensions function need to throw XPathFunctionException
boolean featureSecureProcessing = false;
FeatureManager featureManager;
/**
* Evaluate an XPath context using the internal XPath engine
* @param contextItem The XPath context
* @param xpath The internal XPath engine
* @return an XObject
* @throws javax.xml.transform.TransformerException If the expression cannot be evaluated.
*/
XObject eval(Object contextItem, com.sun.org.apache.xpath.internal.XPath xpath)
throws javax.xml.transform.TransformerException {
com.sun.org.apache.xpath.internal.XPathContext xpathSupport;
if (functionResolver != null) {
JAXPExtensionsProvider jep = new JAXPExtensionsProvider(
functionResolver, featureSecureProcessing, featureManager);
xpathSupport = new com.sun.org.apache.xpath.internal.XPathContext(jep);
} else {
xpathSupport = new com.sun.org.apache.xpath.internal.XPathContext();
}
xpathSupport.setVarStack(new JAXPVariableStack(variableResolver));
XObject xobj;
Node contextNode = (Node)contextItem;
// We always need to have a ContextNode with Xalan XPath implementation
// To allow simple expression evaluation like 1+1 we are setting
// dummy Document as Context Node
if (contextNode == null) {
xobj = xpath.execute(xpathSupport, DTM.NULL, prefixResolver);
} else {
xobj = xpath.execute(xpathSupport, contextNode, prefixResolver);
}
return xobj;
}
/**
* Parse the input source and return a Document.
* @param source The {@code InputSource} of the document
* @return a DOM Document
* @throws XPathExpressionException if there is an error parsing the source.
*/
Document getDocument(InputSource source)
throws XPathExpressionException {
requireNonNull(source, "Source");
try {
// we'd really like to cache those DocumentBuilders, but we can't because:
// 1. thread safety. parsers are not thread-safe, so at least
// we need one instance per a thread.
// 2. parsers are non-reentrant, so now we are looking at having a
// pool of parsers.
// 3. then the class loading issue. The look-up procedure of
// DocumentBuilderFactory.newInstance() depends on context class loader
// and system properties, which may change during the execution of JVM.
//
// so we really have to create a fresh DocumentBuilder every time we need one
// - KK
DocumentBuilderFactory dbf = FactoryImpl.getDOMFactory(useServiceMechanism);
dbf.setNamespaceAware(true);
dbf.setValidating(false);
return dbf.newDocumentBuilder().parse(source);
} catch (ParserConfigurationException | SAXException | IOException e) {
throw new XPathExpressionException (e);
}
}
/**
* Get result depending on the QName type defined in XPathConstants
* @param resultObject the result of an evaluation
* @param returnType the return type
* @return result per the return type
* @throws TransformerException if the result can not be converted to
* the specified return type.
*/
Object getResultAsType(XObject resultObject, QName returnType)
throws TransformerException {
// XPathConstants.STRING
if (returnType.equals(XPathConstants.STRING)) {
return resultObject.str();
}
// XPathConstants.NUMBER
if (returnType.equals(XPathConstants.NUMBER)) {
return resultObject.num();
}
// XPathConstants.BOOLEAN
if (returnType.equals(XPathConstants.BOOLEAN)) {
return resultObject.bool();
}
// XPathConstants.NODESET ---ORdered, UNOrdered???
if (returnType.equals(XPathConstants.NODESET)) {
return resultObject.nodelist();
}
// XPathConstants.NODE
if (returnType.equals(XPathConstants.NODE)) {
NodeIterator ni = resultObject.nodeset();
//Return the first node, or null
return ni.nextNode();
}
// If isSupported check is already done then the execution path
// shouldn't come here. Being defensive
String fmsg = XSLMessages.createXPATHMessage(
XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
new Object[] { returnType.toString()});
throw new IllegalArgumentException (fmsg);
}
/**
* Construct an XPathExpressionResult object based on the result of the
* evaluation and cast to the specified class type.
* @param <T> The class type
* @param resultObject the result of an evaluation
* @param type The class type expected to be returned by the XPath expression.
* @return an instance of the specified type or null if the XObject returned
* an UNKNOWN object type.
* @throws TransformerException if there is an error converting the result
* to the specified type. It's unlikely to happen. This is mostly needed
* by the internal XPath engine.
*/
<T> T getXPathResult(XObject resultObject, Class<T> type)
throws TransformerException {
int resultType = resultObject.getType();
switch (resultType) {
case XObject.CLASS_BOOLEAN :
return type.cast(new XPathResultImpl<>(resultObject, Boolean.class));
case XObject.CLASS_NUMBER :
return type.cast(new XPathResultImpl<>(resultObject, Double.class));
case XObject.CLASS_STRING :
return type.cast(new XPathResultImpl<>(resultObject, String.class));
case XObject.CLASS_NODESET :
return type.cast(new XPathResultImpl<>(resultObject, XPathNodes.class));
case XObject.CLASS_RTREEFRAG : //NODE
return type.cast(new XPathResultImpl<>(resultObject, Node.class));
}
return null;
}
/**
* Check whether or not the specified type is supported
* @param <T> The class type
* @param type The type to be checked
* @throws IllegalArgumentException if the type is not supported
*/
<T> void isSupportedClassType(Class<T> type) {
requireNonNull(type, "The class type");
if (type.isAssignableFrom(Boolean.class) ||
type.isAssignableFrom(Double.class) ||
type.isAssignableFrom(Integer.class) ||
type.isAssignableFrom(Long.class) ||
type.isAssignableFrom(String.class) ||
type.isAssignableFrom(XPathNodes.class) ||
type.isAssignableFrom(Node.class) ||
type.isAssignableFrom(XPathEvaluationResult.class)) {
return;
}
String fmsg = XSLMessages.createXPATHMessage(
XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
new Object[] { type.toString() });
throw new IllegalArgumentException (fmsg);
}
/**
* Check if the requested returnType is supported.
* @param returnType the return type
* @throws IllegalArgumentException if the return type is not supported
*/
void isSupported(QName returnType) {
requireNonNull(returnType, "returnType");
if (returnType.equals(XPathConstants.STRING) ||
returnType.equals(XPathConstants.NUMBER) ||
returnType.equals(XPathConstants.BOOLEAN) ||
returnType.equals(XPathConstants.NODE) ||
returnType.equals(XPathConstants.NODESET)) {
return;
}
String fmsg = XSLMessages.createXPATHMessage(
XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
new Object[] { returnType.toString() });
throw new IllegalArgumentException (fmsg);
}
/**
* Checks that the specified parameter is not {@code null}.
*
* @param <T> the type of the reference
* @param param the parameter to check for nullity
* @param paramName the parameter name
* @throws NullPointerException if {@code param} is {@code null}
*/
<T> void requireNonNull(T param, String paramName) {
if (param == null) {
String fmsg = XSLMessages.createXPATHMessage(
XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
new Object[] {paramName});
throw new NullPointerException (fmsg);
}
}
}

View File

@ -0,0 +1,93 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.org.apache.xpath.internal.jaxp;
import java.util.Iterator;
import javax.xml.xpath.XPathException;
import javax.xml.xpath.XPathNodes;
import javax.xml.xpath.XPathEvaluationResult.XPathResultType;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* This class implements XPathNodes that represents a set of nodes selected by
* evaluating an expression.
*/
public class XPathNodesImpl implements XPathNodes {
Class<Node> elementType;
NodeList nodeList = null;
public XPathNodesImpl(NodeList nodeList, Class<Node> elementType) {
this.nodeList = nodeList;
this.elementType = elementType;
}
@Override
public Iterator<Node> iterator() {
return new NodeSetIterator<>(elementType);
}
class NodeSetIterator<E> implements Iterator<E> {
int currentIndex;
Class<E> elementType;
NodeSetIterator(Class<E> elementType) {
this.elementType = elementType;
}
public boolean hasNext() {
if (nodeList != null) {
return currentIndex < nodeList.getLength();
}
return false;
}
public E next() {
if (nodeList != null && nodeList.getLength() > 0) {
return elementType.cast(nodeList.item(currentIndex++));
}
return null;
}
}
@Override
public int size() {
if (nodeList != null) {
return nodeList.getLength();
}
return 0;
}
@Override
public Node get(int index) throws XPathException {
if (index <0 || index >= size()) {
throw new IndexOutOfBoundsException("Index " + index + " is out of bounds");
}
if (nodeList != null) {
return nodeList.item(index);
}
return null;
}
}

View File

@ -0,0 +1,201 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.org.apache.xpath.internal.jaxp;
import com.sun.org.apache.xpath.internal.objects.XObject;
import java.util.Objects;
import javax.xml.transform.TransformerException;
import javax.xml.xpath.XPathNodes;
import javax.xml.xpath.XPathEvaluationResult;
import javax.xml.xpath.XPathEvaluationResult.XPathResultType;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.traversal.NodeIterator;
/**
* This is the implementation of XPathEvaluationResult that represents the
* result of the evaluation of an XPath expression within the context of a
* particular node.
*/
class XPathResultImpl<T> implements XPathEvaluationResult<T> {
XObject resultObject;
int resultType;
Class<T> type;
XPathResultType mapToType;
NodeList nodeList = null;
int currentIndex;
Node currentNode;
boolean boolValue = false;
Node node = null;
double numValue;
String strValue;
/**
* Construct an XPathEvaluationResult object.
*
* @param resultObject internal XPath result object
* @param type class type
* @throws TransformerException if there is an error reading the XPath
* result.
*/
public XPathResultImpl(XObject resultObject, Class<T> type)
throws TransformerException {
this.resultObject = resultObject;
resultType = resultObject.getType();
this.type = type;
getResult(resultObject);
}
/**
* Return the result type as an enum specified by {@code XPathResultType}
* @return the result type
*/
@Override
public XPathResultType type() {
return mapToType;
}
/**
* Returns the value of the result as the type &lt;T&gt; specified for the class.
*
* @return The value of the result.
*/
@Override
public T value() {
Objects.requireNonNull(type);
try {
return getValue(resultObject, type);
} catch (TransformerException ex) {
throw new RuntimeException(ex);
}
}
/**
* Read the XObject and set values in accordance with the result type
* @param resultObject internal XPath result object
* @throws TransformerException if there is an error reading the XPath
* result.
*/
private void getResult(XObject resultObject) throws TransformerException {
switch (resultType) {
case XObject.CLASS_BOOLEAN:
boolValue = resultObject.bool();
mapToType = XPathResultType.BOOLEAN;
break;
case XObject.CLASS_NUMBER:
numValue = resultObject.num();
mapToType = XPathResultType.NUMBER;
break;
case XObject.CLASS_STRING:
strValue = resultObject.str();
mapToType = XPathResultType.STRING;
break;
case XObject.CLASS_NODESET:
mapToType = XPathResultType.NODESET;
nodeList = resultObject.nodelist();
break;
case XObject.CLASS_RTREEFRAG: //NODE
mapToType = XPathResultType.NODE;
NodeIterator ni = resultObject.nodeset();
//Return the first node, or null
node = ni.nextNode();
break;
}
}
/**
* Read the internal result object and return the value in accordance with
* the type specified.
*
* @param <T> The expected class type.
* @param resultObject internal XPath result object
* @param type the class type
* @return The value of the result, null in case of unexpected type.
* @throws TransformerException if there is an error reading the XPath
* result.
*/
static <T> T getValue(XObject resultObject, Class<T> type) throws TransformerException {
Objects.requireNonNull(type);
if (type.isAssignableFrom(XPathEvaluationResult.class)) {
return type.cast(new XPathResultImpl<T>(resultObject, type));
}
int resultType = classToInternalType(type);
switch (resultType) {
case XObject.CLASS_BOOLEAN:
return type.cast(resultObject.bool());
case XObject.CLASS_NUMBER:
if (Double.class.isAssignableFrom(type)) {
return type.cast(resultObject.num());
} else if (Integer.class.isAssignableFrom(type)) {
return type.cast((int)resultObject.num());
} else if (Long.class.isAssignableFrom(type)) {
return type.cast((long)resultObject.num());
}
/*
This is to suppress warnings. By the current specification,
among numeric types, only Double, Integer and Long are supported.
*/
break;
case XObject.CLASS_STRING:
return type.cast(resultObject.str());
case XObject.CLASS_NODESET:
XPathNodes nodeSet = new XPathNodesImpl(resultObject.nodelist(),
Node.class);
return type.cast(nodeSet);
case XObject.CLASS_RTREEFRAG: //NODE
NodeIterator ni = resultObject.nodeset();
//Return the first node, or null
return type.cast(ni.nextNode());
}
return null;
}
/**
* Map the specified class type to the internal result type
*
* @param <T> The expected class type.
* @param type the class type
* @return the internal XObject type.
*/
static <T> int classToInternalType(Class<T> type) {
if (type.isAssignableFrom(Boolean.class)) {
return XObject.CLASS_BOOLEAN;
} else if (Number.class.isAssignableFrom(type)) {
return XObject.CLASS_NUMBER;
} else if (type.isAssignableFrom(String.class)) {
return XObject.CLASS_STRING;
} else if (type.isAssignableFrom(XPathNodes.class)) {
return XObject.CLASS_NODESET;
} else if (type.isAssignableFrom(Node.class)) {
return XObject.CLASS_RTREEFRAG;
}
return XObject.CLASS_NULL;
}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,12 +25,12 @@
package javax.xml.xpath; package javax.xml.xpath;
import org.xml.sax.InputSource;
import javax.xml.namespace.QName;
import javax.xml.namespace.NamespaceContext; import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
import org.xml.sax.InputSource;
/** /**
* <p><code>XPath</code> provides access to the XPath evaluation environment and expressions.</p> * {@code XPath} provides access to the XPath evaluation environment and expressions.
* *
* <a name="XPath-evaluation"/> * <a name="XPath-evaluation"/>
* <table border="1" cellpadding="2"> * <table border="1" cellpadding="2">
@ -39,7 +39,6 @@ import javax.xml.namespace.NamespaceContext;
* <th colspan="2">Evaluation of XPath Expressions.</th> * <th colspan="2">Evaluation of XPath Expressions.</th>
* </tr> * </tr>
* </thead> * </thead>
* <tbody>
* <tr> * <tr>
* <td>context</td> * <td>context</td>
* <td> * <td>
@ -55,8 +54,8 @@ import javax.xml.namespace.NamespaceContext;
* If the expression contains a variable reference, its value will be found through the {@link XPathVariableResolver} * If the expression contains a variable reference, its value will be found through the {@link XPathVariableResolver}
* set with {@link #setXPathVariableResolver(XPathVariableResolver resolver)}. * set with {@link #setXPathVariableResolver(XPathVariableResolver resolver)}.
* An {@link XPathExpressionException} is raised if the variable resolver is undefined or * An {@link XPathExpressionException} is raised if the variable resolver is undefined or
* the resolver returns <code>null</code> for the variable. * the resolver returns {@code null} for the variable.
* The value of a variable must be immutable through the course of any single evaluation.</p> * The value of a variable must be immutable through the course of any single evaluation.
* </td> * </td>
* </tr> * </tr>
* <tr> * <tr>
@ -65,7 +64,7 @@ import javax.xml.namespace.NamespaceContext;
* If the expression contains a function reference, the function will be found through the {@link XPathFunctionResolver} * If the expression contains a function reference, the function will be found through the {@link XPathFunctionResolver}
* set with {@link #setXPathFunctionResolver(XPathFunctionResolver resolver)}. * set with {@link #setXPathFunctionResolver(XPathFunctionResolver resolver)}.
* An {@link XPathExpressionException} is raised if the function resolver is undefined or * An {@link XPathExpressionException} is raised if the function resolver is undefined or
* the function resolver returns <code>null</code> for the function.</p> * the function resolver returns {@code null} for the function.
* </td> * </td>
* </tr> * </tr>
* <tr> * <tr>
@ -80,7 +79,7 @@ import javax.xml.namespace.NamespaceContext;
* <td> * <td>
* This result of evaluating an expression is converted to an instance of the desired return type. * This result of evaluating an expression is converted to an instance of the desired return type.
* Valid return types are defined in {@link XPathConstants}. * Valid return types are defined in {@link XPathConstants}.
* Conversion to the return type follows XPath conversion rules.</p> * Conversion to the return type follows XPath conversion rules.
* </td> * </td>
* </tr> * </tr>
* </table> * </table>
@ -88,9 +87,9 @@ import javax.xml.namespace.NamespaceContext;
* <p>An XPath object is not thread-safe and not reentrant. * <p>An XPath object is not thread-safe and not reentrant.
* In other words, it is the application's responsibility to make * In other words, it is the application's responsibility to make
* sure that one {@link XPath} object is not used from * sure that one {@link XPath} object is not used from
* more than one thread at any given time, and while the <code>evaluate</code> * more than one thread at any given time, and while the {@code evaluate}
* method is invoked, applications may not recursively call * method is invoked, applications may not recursively call
* the <code>evaluate</code> method. * the {@code evaluate} method.
* <p> * <p>
* *
* @author <a href="Norman.Walsh@Sun.com">Norman Walsh</a> * @author <a href="Norman.Walsh@Sun.com">Norman Walsh</a>
@ -100,191 +99,189 @@ import javax.xml.namespace.NamespaceContext;
*/ */
public interface XPath { public interface XPath {
/**
* <p>Reset this <code>XPath</code> to its original configuration.</p>
*
* <p><code>XPath</code> is reset to the same state as when it was created with
* {@link XPathFactory#newXPath()}.
* <code>reset()</code> is designed to allow the reuse of existing <code>XPath</code>s
* thus saving resources associated with the creation of new <code>XPath</code>s.</p>
*
* <p>The reset <code>XPath</code> is not guaranteed to have the same {@link XPathFunctionResolver}, {@link XPathVariableResolver}
* or {@link NamespaceContext} <code>Object</code>s, e.g. {@link Object#equals(Object obj)}.
* It is guaranteed to have a functionally equal <code>XPathFunctionResolver</code>, <code>XPathVariableResolver</code>
* and <code>NamespaceContext</code>.</p>
*/
public void reset();
/** /**
* <p>Establish a variable resolver.</p> * Reset this {@code XPath} to its original configuration.
* *
* <p>A <code>NullPointerException</code> is thrown if <code>resolver</code> is <code>null</code>.</p> * <p>{@code XPath} is reset to the same state as when it was created with
* {@link XPathFactory#newXPath()}.
* {@code reset()} is designed to allow the reuse of existing {@code XPath}s
* thus saving resources associated with the creation of new {@code XPath}s.
*
* <p>The reset {@code XPath} is not guaranteed to have the same
* {@link XPathFunctionResolver}, {@link XPathVariableResolver}
* or {@link NamespaceContext} {@code Object}s, e.g. {@link Object#equals(Object obj)}.
* It is guaranteed to have a functionally equal {@code XPathFunctionResolver},
* {@code XPathVariableResolver} and {@code NamespaceContext}.
*/
public void reset();
/**
* Establish a variable resolver.
*
* <p>A {@code NullPointerException} is thrown if {@code resolver} is {@code null}.
* *
* @param resolver Variable resolver. * @param resolver Variable resolver.
* *
* @throws NullPointerException If <code>resolver</code> is <code>null</code>. * @throws NullPointerException If {@code resolver} is {@code null}.
*/ */
public void setXPathVariableResolver(XPathVariableResolver resolver); public void setXPathVariableResolver(XPathVariableResolver resolver);
/** /**
* <p>Return the current variable resolver.</p> * Return the current variable resolver.
* *
* <p><code>null</code> is returned in no variable resolver is in effect.</p> * <p>{@code null} is returned in no variable resolver is in effect.
* *
* @return Current variable resolver. * @return Current variable resolver.
*/ */
public XPathVariableResolver getXPathVariableResolver(); public XPathVariableResolver getXPathVariableResolver();
/** /**
* <p>Establish a function resolver.</p> * Establish a function resolver.
* *
* <p>A <code>NullPointerException</code> is thrown if <code>resolver</code> is <code>null</code>.</p> * <p>A {@code NullPointerException} is thrown if {@code resolver} is {@code null}.
* *
* @param resolver XPath function resolver. * @param resolver XPath function resolver.
* *
* @throws NullPointerException If <code>resolver</code> is <code>null</code>. * @throws NullPointerException If {@code resolver} is {@code null}.
*/ */
public void setXPathFunctionResolver(XPathFunctionResolver resolver); public void setXPathFunctionResolver(XPathFunctionResolver resolver);
/** /**
* <p>Return the current function resolver.</p> * Return the current function resolver.
* * <p>
* <p><code>null</code> is returned in no function resolver is in effect.</p> * {@code null} is returned in no function resolver is in effect.
* *
* @return Current function resolver. * @return Current function resolver.
*/ */
public XPathFunctionResolver getXPathFunctionResolver(); public XPathFunctionResolver getXPathFunctionResolver();
/** /**
* <p>Establish a namespace context.</p> * Establish a namespace context.
* *
* <p>A <code>NullPointerException</code> is thrown if <code>nsContext</code> is <code>null</code>.</p> * <p>A {@code NullPointerException} is thrown if {@code nsContext} is {@code null}.
* *
* @param nsContext Namespace context to use. * @param nsContext Namespace context to use.
* *
* @throws NullPointerException If <code>nsContext</code> is <code>null</code>. * @throws NullPointerException If {@code nsContext} is {@code null}.
*/ */
public void setNamespaceContext(NamespaceContext nsContext); public void setNamespaceContext(NamespaceContext nsContext);
/** /**
* <p>Return the current namespace context.</p> * Return the current namespace context.
* *
* <p><code>null</code> is returned in no namespace context is in effect.</p> * <p>{@code null} is returned in no namespace context is in effect.
* *
* @return Current Namespace context. * @return Current Namespace context.
*/ */
public NamespaceContext getNamespaceContext(); public NamespaceContext getNamespaceContext();
/** /**
* <p>Compile an XPath expression for later evaluation.</p> * Compile an XPath expression for later evaluation.
* *
* <p>If <code>expression</code> contains any {@link XPathFunction}s, * <p>If {@code expression} contains any {@link XPathFunction}s,
* they must be available via the {@link XPathFunctionResolver}. * they must be available via the {@link XPathFunctionResolver}.
* An {@link XPathExpressionException} will be thrown if the * An {@link XPathExpressionException} will be thrown if the
* <code>XPathFunction</code> * {@code XPathFunction}
* cannot be resovled with the <code>XPathFunctionResolver</code>.</p> * cannot be resovled with the {@code XPathFunctionResolver}.
* *
* <p>If <code>expression</code> contains any variables, the * <p>If {@code expression} contains any variables, the
* {@link XPathVariableResolver} in effect * {@link XPathVariableResolver} in effect
* <strong>at compile time</strong> will be used to resolve them.</p> * <strong>at compile time</strong> will be used to resolve them.
*
* <p>If <code>expression</code> is <code>null</code>, a <code>NullPointerException</code> is thrown.</p>
* *
* @param expression The XPath expression. * @param expression The XPath expression.
* *
* @return Compiled XPath expression. * @return Compiled XPath expression.
* @throws XPathExpressionException If <code>expression</code> cannot be compiled. * @throws XPathExpressionException If {@code expression} cannot be compiled.
* @throws NullPointerException If <code>expression</code> is <code>null</code>. * @throws NullPointerException If {@code expression} is {@code null}.
*/ */
public XPathExpression compile(String expression) public XPathExpression compile(String expression)
throws XPathExpressionException; throws XPathExpressionException;
/** /**
* <p>Evaluate an <code>XPath</code> expression in the specified context and return the result as the specified type.</p> * Evaluate an {@code XPath} expression in the specified context and
* return the result as the specified type.
* *
* <p>See <a href="#XPath-evaluation">Evaluation of XPath Expressions</a> for context item evaluation, * <p>
* variable, function and <code>QName</code> resolution and return type conversion.</p> * See <a href="#XPath-evaluation">Evaluation of XPath Expressions</a>
* for context item evaluation, variable, function and {@code QName} resolution
* and return type conversion.
* <p>
* The parameter {@code item} represents the context the XPath expression
* will be operated on. The type of the context is implementation-dependent.
* If the value is {@code null}, the operation must have no dependency on
* the context, otherwise an XPathExpressionException will be thrown.
* *
* <p>If <code>returnType</code> is not one of the types defined in {@link XPathConstants} ( * @implNote
* The type of the context is usually {@link org.w3c.dom.Node}.
*
* @param expression The XPath expression.
* @param item The context the XPath expression will be evaluated in.
* @param returnType The result type expected to be returned by the XPath expression.
*
* @return The result of evaluating an XPath expression as an {@code Object} of {@code returnType}.
*
* @throws XPathExpressionException If {@code expression} cannot be evaluated.
* @throws IllegalArgumentException If {@code returnType} is not one of the types defined in {@link XPathConstants} (
* {@link XPathConstants#NUMBER NUMBER}, * {@link XPathConstants#NUMBER NUMBER},
* {@link XPathConstants#STRING STRING}, * {@link XPathConstants#STRING STRING},
* {@link XPathConstants#BOOLEAN BOOLEAN}, * {@link XPathConstants#BOOLEAN BOOLEAN},
* {@link XPathConstants#NODE NODE} or * {@link XPathConstants#NODE NODE} or
* {@link XPathConstants#NODESET NODESET}) * {@link XPathConstants#NODESET NODESET}).
* then an <code>IllegalArgumentException</code> is thrown.</p> * @throws NullPointerException If {@code expression or returnType} is {@code null}.
*
* <p>If a <code>null</code> value is provided for
* <code>item</code>, an empty document will be used for the
* context.
* If <code>expression</code> or <code>returnType</code> is <code>null</code>, then a
* <code>NullPointerException</code> is thrown.</p>
*
* @param expression The XPath expression.
* @param item The starting context (a node, for example).
* @param returnType The desired return type.
*
* @return Result of evaluating an XPath expression as an <code>Object</code> of <code>returnType</code>.
*
* @throws XPathExpressionException If <code>expression</code> cannot be evaluated.
* @throws IllegalArgumentException If <code>returnType</code> is not one of the types defined in {@link XPathConstants}.
* @throws NullPointerException If <code>expression</code> or <code>returnType</code> is <code>null</code>.
*/ */
public Object evaluate(String expression, Object item, QName returnType) public Object evaluate(String expression, Object item, QName returnType)
throws XPathExpressionException; throws XPathExpressionException;
/** /**
* <p>Evaluate an XPath expression in the specified context and return the result as a <code>String</code>.</p> * Evaluate an XPath expression in the specified context and return the result as a {@code String}.
* *
* <p>This method calls {@link #evaluate(String expression, Object item, QName returnType)} with a <code>returnType</code> of * <p>This method calls {@link #evaluate(String expression, Object item, QName returnType)} with a {@code returnType} of
* {@link XPathConstants#STRING}.</p> * {@link XPathConstants#STRING}.
* *
* <p>See <a href="#XPath-evaluation">Evaluation of XPath Expressions</a> for context item evaluation, * <p>See <a href="#XPath-evaluation">Evaluation of XPath Expressions</a> for context item evaluation,
* variable, function and QName resolution and return type conversion.</p> * variable, function and QName resolution and return type conversion.
* *
* <p>If a <code>null</code> value is provided for * <p>
* <code>item</code>, an empty document will be used for the * The parameter {@code item} represents the context the XPath expression
* context. * will be operated on. The type of the context is implementation-dependent.
* If <code>expression</code> is <code>null</code>, then a <code>NullPointerException</code> is thrown.</p> * If the value is {@code null}, the operation must have no dependency on
* the context, otherwise an XPathExpressionException will be thrown.
*
* @implNote
* The type of the context is usually {@link org.w3c.dom.Node}.
* *
* @param expression The XPath expression. * @param expression The XPath expression.
* @param item The starting context (a node, for example). * @param item The context the XPath expression will be evaluated in.
* *
* @return The <code>String</code> that is the result of evaluating the expression and * @return The result of evaluating an XPath expression as a {@code String}.
* converting the result to a <code>String</code>.
* *
* @throws XPathExpressionException If <code>expression</code> cannot be evaluated. * @throws XPathExpressionException If {@code expression} cannot be evaluated.
* @throws NullPointerException If <code>expression</code> is <code>null</code>. * @throws NullPointerException If {@code expression} is {@code null}.
*/ */
public String evaluate(String expression, Object item) public String evaluate(String expression, Object item)
throws XPathExpressionException; throws XPathExpressionException;
/** /**
* <p>Evaluate an XPath expression in the context of the specified <code>InputSource</code> * Evaluate an XPath expression in the context of the specified {@code InputSource}
* and return the result as the specified type.</p> * and return the result as the specified type.
* *
* <p>This method builds a data model for the {@link InputSource} and calls * <p>This method builds a data model for the {@link InputSource} and calls
* {@link #evaluate(String expression, Object item, QName returnType)} on the resulting document object.</p> * {@link #evaluate(String expression, Object item, QName returnType)} on the resulting document object.
* *
* <p>See <a href="#XPath-evaluation">Evaluation of XPath Expressions</a> for context item evaluation, * <p>See <a href="#XPath-evaluation">Evaluation of XPath Expressions</a> for context item evaluation,
* variable, function and QName resolution and return type conversion.</p> * variable, function and QName resolution and return type conversion.
*
* <p>If <code>returnType</code> is not one of the types defined in {@link XPathConstants},
* then an <code>IllegalArgumentException</code> is thrown.</p>
*
* <p>If <code>expression</code>, <code>source</code> or <code>returnType</code> is <code>null</code>,
* then a <code>NullPointerException</code> is thrown.</p>
* *
* @param expression The XPath expression. * @param expression The XPath expression.
* @param source The input source of the document to evaluate over. * @param source The input source of the document to evaluate over.
* @param returnType The desired return type. * @param returnType The desired return type.
* *
* @return The <code>Object</code> that encapsulates the result of evaluating the expression. * @return The {@code Object} that encapsulates the result of evaluating the expression.
* *
* @throws XPathExpressionException If expression cannot be evaluated. * @throws XPathExpressionException If expression cannot be evaluated.
* @throws IllegalArgumentException If <code>returnType</code> is not one of the types defined in {@link XPathConstants}. * @throws IllegalArgumentException If {@code returnType} is not one of the types defined in {@link XPathConstants}.
* @throws NullPointerException If <code>expression</code>, <code>source</code> or <code>returnType</code> * @throws NullPointerException If {@code expression, source or returnType} is {@code null}.
* is <code>null</code>.
*/ */
public Object evaluate( public Object evaluate(
String expression, String expression,
@ -293,27 +290,209 @@ public interface XPath {
throws XPathExpressionException; throws XPathExpressionException;
/** /**
* <p>Evaluate an XPath expression in the context of the specified <code>InputSource</code> * Evaluate an XPath expression in the context of the specified {@code InputSource}
* and return the result as a <code>String</code>.</p> * and return the result as a {@code String}.
* *
* <p>This method calls {@link #evaluate(String expression, InputSource source, QName returnType)} with a * <p>This method calls {@link #evaluate(String expression, InputSource source, QName returnType)} with a
* <code>returnType</code> of {@link XPathConstants#STRING}.</p> * {@code returnType} of {@link XPathConstants#STRING}.
* *
* <p>See <a href="#XPath-evaluation">Evaluation of XPath Expressions</a> for context item evaluation, * <p>See <a href="#XPath-evaluation">Evaluation of XPath Expressions</a> for context item evaluation,
* variable, function and QName resolution and return type conversion.</p> * variable, function and QName resolution and return type conversion.
*
* <p>If <code>expression</code> or <code>source</code> is <code>null</code>,
* then a <code>NullPointerException</code> is thrown.</p>
* *
* @param expression The XPath expression. * @param expression The XPath expression.
* @param source The <code>InputSource</code> of the document to evaluate over. * @param source The {@code InputSource} of the document to evaluate over.
* *
* @return The <code>String</code> that is the result of evaluating the expression and * @return The {@code String} that is the result of evaluating the expression and
* converting the result to a <code>String</code>. * converting the result to a {@code String}.
* *
* @throws XPathExpressionException If expression cannot be evaluated. * @throws XPathExpressionException If expression cannot be evaluated.
* @throws NullPointerException If <code>expression</code> or <code>source</code> is <code>null</code>. * @throws NullPointerException If {@code expression or source} is {@code null}.
*/ */
public String evaluate(String expression, InputSource source) public String evaluate(String expression, InputSource source)
throws XPathExpressionException; throws XPathExpressionException;
/**
* Evaluate an XPath expression in the specified context and return
* the result with the type specified through the {@code class type}
*
* <p>
* The parameter {@code item} represents the context the XPath expression
* will be operated on. The type of the context is implementation-dependent.
* If the value is {@code null}, the operation must have no dependency on
* the context, otherwise an XPathExpressionException will be thrown.
*
* @implNote
* The type of the context is usually {@link org.w3c.dom.Node}.
*
* @implSpec
* The default implementation in the XPath API is equivalent to:
* <pre> {@code
* (T)evaluate(expression, item,
* XPathEvaluationResult.XPathResultType.getQNameType(type));
* }</pre>
*
* Since the {@code evaluate} method does not support the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type, specifying
* XPathEvaluationResult as the type will result in IllegalArgumentException.
* Any implementation supporting the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must override
* this method.
*
* @param <T> The class type that will be returned by the XPath expression.
* @param expression The XPath expression.
* @param item The context the XPath expression will be evaluated in.
* @param type The class type expected to be returned by the XPath expression.
*
* @return The result of evaluating the expression.
*
* @throws XPathExpressionException If the expression cannot be evaluated.
* @throws IllegalArgumentException If {@code type} is not of the types
* corresponding to the types defined in the {@link XPathEvaluationResult.XPathResultType},
* or XPathEvaluationResult is specified as the type but an implementation supporting the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type is not available.
* @throws NullPointerException If {@code expression or type} is {@code null}.
*
* @since 1.9
*/
default <T>T evaluateExpression(String expression, Object item, Class<T> type)
throws XPathExpressionException {
return type.cast(evaluate(expression, item,
XPathEvaluationResult.XPathResultType.getQNameType(type)));
}
/**
* Evaluate an XPath expression in the specified context. This is equivalent to
* calling {@link #evaluateExpression(String expression, Object item, Class type)}
* with type {@link XPathEvaluationResult}:
* <pre> {@code
* evaluateExpression(expression, item, XPathEvaluationResult.class);
* }</pre>
* <p>
* The parameter {@code item} represents the context the XPath expression
* will be operated on. The type of the context is implementation-dependent.
* If the value is {@code null}, the operation must have no dependency on
* the context, otherwise an XPathExpressionException will be thrown.
*
* @implNote
* The type of the context is usually {@link org.w3c.dom.Node}.
*
* @implSpec
* The default implementation in the XPath API is equivalent to:
* <pre> {@code
* evaluateExpression(expression, item, XPathEvaluationResult.class);
* }</pre>
*
* Since the {@code evaluate} method does not support the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY}
* type, the default implementation of this method will always throw an
* IllegalArgumentException. Any implementation supporting the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must therefore
* override this method.
*
* @param expression The XPath expression.
* @param item The context the XPath expression will be evaluated in.
*
* @return The result of evaluating the expression.
*
* @throws XPathExpressionException If the expression cannot be evaluated.
* @throws IllegalArgumentException If the implementation of this method
* does not support the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type.
* @throws NullPointerException If {@code expression} is {@code null}.
*
* @since 1.9
*/
default XPathEvaluationResult<?> evaluateExpression(String expression, Object item)
throws XPathExpressionException
{
return evaluateExpression(expression, item, XPathEvaluationResult.class);
}
/**
* Evaluate an XPath expression in the context of the specified {@code source}
* and return the result as specified.
* <p>
* This method builds a data model for the {@link InputSource} and calls
* {@link #evaluateExpression(String expression, Object item, Class type)}
* on the resulting document object. The data model is usually
* {@link org.w3c.dom.Document}
*
* @implSpec
* The default implementation in the XPath API is equivalent to:
* <pre> {@code
(T)evaluate(expression, source,
XPathEvaluationResult.XPathResultType.getQNameType(type));
* }</pre>
*
* Since the {@code evaluate} method does not support the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type, specifying
* XPathEvaluationResult as the type will result in IllegalArgumentException.
* Any implementation supporting the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must override
* this method.
*
* @param <T> The class type that will be returned by the XPath expression.
* @param expression The XPath expression.
* @param source The input source of the document to evaluate over.
* @param type The class type expected to be returned by the XPath expression.
*
* @return The result of evaluating the expression.
*
* @throws XPathExpressionException If the expression cannot be evaluated.
* @throws IllegalArgumentException If {@code type} is not of the types
* corresponding to the types defined in the {@link XPathEvaluationResult.XPathResultType
* XPathResultType}, or XPathEvaluationResult is specified as the type but an
* implementation supporting the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type is not available.
* @throws NullPointerException If {@code expression, source or type}is {@code null}.
*
* @since 1.9
*/
default <T>T evaluateExpression(String expression, InputSource source, Class<T> type)
throws XPathExpressionException
{
return type.cast(evaluate(expression, source,
XPathEvaluationResult.XPathResultType.getQNameType(type)));
}
/**
* Evaluate an XPath expression in the specified context. This is equivalent to
* calling {@link #evaluateExpression(String expression, Object item, Class type)}
* with type {@link XPathEvaluationResult}:
* <pre> {@code
* evaluateExpression(expression, item, XPathEvaluationResult.class);
* }</pre>
* <p>
*
* @implSpec
* The default implementation in the XPath API is equivalent to:
* <pre> {@code
* evaluateExpression(expression, source, XPathEvaluationResult.class);
* }</pre>
*
* Since the {@code evaluate} method does not support the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY}
* type, the default implementation of this method will always throw an
* IllegalArgumentException. Any implementation supporting the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must therefore
* override this method.
*
* @param expression The XPath expression.
* @param source The input source of the document to evaluate over.
*
* @return The result of evaluating the expression.
*
* @throws XPathExpressionException If the expression cannot be evaluated.
* @throws IllegalArgumentException If the implementation of this method
* does not support the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type.
* @throws NullPointerException If {@code expression or source} is {@code null}.
*
* @since 1.9
*/
default XPathEvaluationResult<?> evaluateExpression(String expression, InputSource source)
throws XPathExpressionException
{
return evaluateExpression(expression, source, XPathEvaluationResult.class);
}
} }

View File

@ -0,0 +1,130 @@
/*
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.xml.xpath;
import java.util.Objects;
import javax.xml.namespace.QName;
import org.w3c.dom.Node;
/**
* The {@code XPathEvaluationResult} interface represents the result of the
* evaluation of an XPath expression within the context of a particular node.
* The evaluation of an XPath expression can result in various result types as
* defined in XML Path Language (XPath) Version 1.0.
* <p>
*
* @param <T> the object type returned by the XPath evaluation.
* @see <a href="http://www.w3.org/TR/xpath">XML Path Language (XPath) Version
* 1.0</a>
*
* @since 1.9
*/
public interface XPathEvaluationResult<T> {
/**
* XPathResultType represents possible return types of an XPath evaluation.
* Provided as an enum type, it allows the use of switch statement. At the
* same time, a mapping is provided between the original QName types in
* {@link XPathConstants} and class types used in the generic methods.
*/
public static enum XPathResultType {
/**
* Any type that represents any of the 5 other types listed below.
* Maps to {@link XPathEvaluationResult}.
*/
ANY(new QName("http://www.w3.org/1999/XSL/Transform", "any"), XPathEvaluationResult.class),
/**
* The XPath 1.0 boolean data type. Maps to Java {@link Boolean}.
*/
BOOLEAN(XPathConstants.BOOLEAN, Boolean.class),
/**
* The XPath 1.0 Number data type. Maps to Java {@link Number}. Of the
* subtypes of Number, only Double, Integer and Long are required.
*/
NUMBER(XPathConstants.NUMBER, Number.class),
/**
* The XPath 1.0 String data type. Maps to Java {@link String}.
*/
STRING(XPathConstants.STRING, String.class),
/**
* The XPath 1.0 NodeSet data type. Maps to {@link org.w3c.dom.NodeList}.
*/
NODESET(XPathConstants.NODESET, XPathNodes.class),
/**
* The XPath 1.0 NodeSet data type. Maps to {@link org.w3c.dom.Node}.
*/
NODE(XPathConstants.NODE, Node.class);
final QName qnameType;
final Class<?> clsType;
XPathResultType(QName qnameType, Class<?> clsType) {
this.qnameType = qnameType;
this.clsType = clsType;
}
/**
* Compares this type to the specified class type.
* @param clsType class type
* @return true if the argument is not null and is a class type that
* matches that this type represents, false otherwise.
*/
private boolean equalsClassType(Class<?> clsType) {
Objects.nonNull(clsType);
if (clsType.isAssignableFrom(this.clsType)) {
return true;
}
return false;
}
/**
* Returns the QName type as specified in {@link XPathConstants} that
* corresponds to the specified class type.
* @param clsType a class type that the enum type supports
* @return the QName type that matches with the specified class type,
* null if there is no match
*/
static public QName getQNameType(Class<?> clsType) {
for (XPathResultType type : XPathResultType.values()) {
if (type.equalsClassType(clsType)) {
return type.qnameType;
}
}
return null;
}
}
/**
* Return the result type as an enum specified by {@code XPathResultType}
* @return the result type
*/
public XPathResultType type();
/**
* Returns the value of the result as the type &lt;T&gt; specified for the class.
*
* @return The value of the result.
*/
public T value();
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,11 +25,11 @@
package javax.xml.xpath; package javax.xml.xpath;
import org.xml.sax.InputSource;
import javax.xml.namespace.QName; import javax.xml.namespace.QName;
import org.xml.sax.InputSource;
/** /**
* <p><code>XPathExpression</code> provides access to compiled XPath expressions.</p> * <p>{@code XPathExpression} provides access to compiled XPath expressions.</p>
* *
* <a name="XPathExpression-evaluation"/> * <a name="XPathExpression-evaluation"/>
* <table border="1" cellpadding="2"> * <table border="1" cellpadding="2">
@ -53,7 +53,7 @@ import javax.xml.namespace.QName;
* <td> * <td>
* If the expression contains a variable reference, its value will be found through the {@link XPathVariableResolver}. * If the expression contains a variable reference, its value will be found through the {@link XPathVariableResolver}.
* An {@link XPathExpressionException} is raised if the variable resolver is undefined or * An {@link XPathExpressionException} is raised if the variable resolver is undefined or
* the resolver returns <code>null</code> for the variable. * the resolver returns {@code null} for the variable.
* The value of a variable must be immutable through the course of any single evaluation.</p> * The value of a variable must be immutable through the course of any single evaluation.</p>
* </td> * </td>
* </tr> * </tr>
@ -62,7 +62,7 @@ import javax.xml.namespace.QName;
* <td> * <td>
* If the expression contains a function reference, the function will be found through the {@link XPathFunctionResolver}. * If the expression contains a function reference, the function will be found through the {@link XPathFunctionResolver}.
* An {@link XPathExpressionException} is raised if the function resolver is undefined or * An {@link XPathExpressionException} is raised if the function resolver is undefined or
* the function resolver returns <code>null</code> for the function.</p> * the function resolver returns {@code null} for the function.</p>
* </td> * </td>
* </tr> * </tr>
* <tr> * <tr>
@ -84,9 +84,9 @@ import javax.xml.namespace.QName;
* <p>An XPath expression is not thread-safe and not reentrant. * <p>An XPath expression is not thread-safe and not reentrant.
* In other words, it is the application's responsibility to make * In other words, it is the application's responsibility to make
* sure that one {@link XPathExpression} object is not used from * sure that one {@link XPathExpression} object is not used from
* more than one thread at any given time, and while the <code>evaluate</code> * more than one thread at any given time, and while the {@code evaluate}
* method is invoked, applications may not recursively call * method is invoked, applications may not recursively call
* the <code>evaluate</code> method. * the {@code evaluate} method.
* <p> * <p>
* *
* @author <a href="mailto:Norman.Walsh@Sun.com">Norman Walsh</a> * @author <a href="mailto:Norman.Walsh@Sun.com">Norman Walsh</a>
@ -96,50 +96,56 @@ import javax.xml.namespace.QName;
*/ */
public interface XPathExpression { public interface XPathExpression {
/** /**
* <p>Evaluate the compiled XPath expression in the specified context and return the result as the specified type.</p> * <p>Evaluate the compiled XPath expression in the specified context and return the result as the specified type.</p>
* *
* <p>See <a href="#XPathExpression-evaluation">Evaluation of XPath Expressions</a> for context item evaluation, * <p>See <a href="#XPathExpression-evaluation">Evaluation of XPath Expressions</a> for context item evaluation,
* variable, function and QName resolution and return type conversion.</p> * variable, function and QName resolution and return type conversion.</p>
* *
* <p>If <code>returnType</code> is not one of the types defined in {@link XPathConstants}, * <p>
* then an <code>IllegalArgumentException</code> is thrown.</p> * The parameter {@code item} represents the context the XPath expression
* will be operated on. The type of the context is implementation-dependent.
* If the value is {@code null}, the operation must have no dependency on
* the context, otherwise an XPathExpressionException will be thrown.
* *
* <p>If a <code>null</code> value is provided for * @implNote
* <code>item</code>, an empty document will be used for the * The type of the context is usually {@link org.w3c.dom.Node}.
* context.
* If <code>returnType</code> is <code>null</code>, then a <code>NullPointerException</code> is thrown.</p>
* *
* @param item The starting context (a node, for example). * @param item The context the XPath expression will be evaluated in.
* @param returnType The desired return type. * @param returnType The result type expected to be returned by the XPath expression.
* *
* @return The <code>Object</code> that is the result of evaluating the expression and converting the result to * @return The {@code Object} that is the result of evaluating the expression and converting the result to
* <code>returnType</code>. * {@code returnType}.
* *
* @throws XPathExpressionException If the expression cannot be evaluated. * @throws XPathExpressionException If the expression cannot be evaluated.
* @throws IllegalArgumentException If <code>returnType</code> is not one of the types defined in {@link XPathConstants}. * @throws IllegalArgumentException If {@code returnType} is not one of the types defined in {@link XPathConstants}.
* @throws NullPointerException If <code>returnType</code> is <code>null</code>. * @throws NullPointerException If {@code returnType} is {@code null}.
*/ */
public Object evaluate(Object item, QName returnType) public Object evaluate(Object item, QName returnType)
throws XPathExpressionException; throws XPathExpressionException;
/** /**
* <p>Evaluate the compiled XPath expression in the specified context and return the result as a <code>String</code>.</p> * <p>Evaluate the compiled XPath expression in the specified context and return the result as a {@code String}.</p>
* *
* <p>This method calls {@link #evaluate(Object item, QName returnType)} with a <code>returnType</code> of * <p>This method calls {@link #evaluate(Object item, QName returnType)} with a {@code returnType} of
* {@link XPathConstants#STRING}.</p> * {@link XPathConstants#STRING}.</p>
* *
* <p>See <a href="#XPathExpression-evaluation">Evaluation of XPath Expressions</a> for context item evaluation, * <p>See <a href="#XPathExpression-evaluation">Evaluation of XPath Expressions</a> for context item evaluation,
* variable, function and QName resolution and return type conversion.</p> * variable, function and QName resolution and return type conversion.</p>
* *
* <p>If a <code>null</code> value is provided for * <p>
* <code>item</code>, an empty document will be used for the * The parameter {@code item} represents the context the XPath expression
* context. * will be operated on. The type of the context is implementation-dependent.
* If the value is {@code null}, the operation must have no dependency on
* the context, otherwise an XPathExpressionException will be thrown.
* *
* @param item The starting context (a node, for example). * @implNote
* The type of the context is usually {@link org.w3c.dom.Node}.
* *
* @return The <code>String</code> that is the result of evaluating the expression and converting the result to a * @param item The context the XPath expression will be evaluated in.
* <code>String</code>. *
* @return The result of evaluating an XPath expression as a {@code String}.
* *
* @throws XPathExpressionException If the expression cannot be evaluated. * @throws XPathExpressionException If the expression cannot be evaluated.
*/ */
@ -147,7 +153,7 @@ public interface XPathExpression {
throws XPathExpressionException; throws XPathExpressionException;
/** /**
* <p>Evaluate the compiled XPath expression in the context of the specified <code>InputSource</code> and return the result as the * <p>Evaluate the compiled XPath expression in the context of the specified {@code InputSource} and return the result as the
* specified type.</p> * specified type.</p>
* *
* <p>This method builds a data model for the {@link InputSource} and calls * <p>This method builds a data model for the {@link InputSource} and calls
@ -156,45 +162,225 @@ public interface XPathExpression {
* <p>See <a href="#XPathExpression-evaluation">Evaluation of XPath Expressions</a> for context item evaluation, * <p>See <a href="#XPathExpression-evaluation">Evaluation of XPath Expressions</a> for context item evaluation,
* variable, function and QName resolution and return type conversion.</p> * variable, function and QName resolution and return type conversion.</p>
* *
* <p>If <code>returnType</code> is not one of the types defined in {@link XPathConstants}, * <p>If {@code returnType} is not one of the types defined in {@link XPathConstants},
* then an <code>IllegalArgumentException</code> is thrown.</p> * then an {@code IllegalArgumentException} is thrown.</p>
* *
* <p>If <code>source</code> or <code>returnType</code> is <code>null</code>, * <p>If {@code source} or {@code returnType} is {@code null},
* then a <code>NullPointerException</code> is thrown.</p> * then a {@code NullPointerException} is thrown.</p>
* *
* @param source The <code>InputSource</code> of the document to evaluate over. * @param source The {@code InputSource} of the document to evaluate over.
* @param returnType The desired return type. * @param returnType The desired return type.
* *
* @return The <code>Object</code> that is the result of evaluating the expression and converting the result to * @return The {@code Object} that is the result of evaluating the expression and converting the result to
* <code>returnType</code>. * {@code returnType}.
* *
* @throws XPathExpressionException If the expression cannot be evaluated. * @throws XPathExpressionException If the expression cannot be evaluated.
* @throws IllegalArgumentException If <code>returnType</code> is not one of the types defined in {@link XPathConstants}. * @throws IllegalArgumentException If {@code returnType} is not one of the types defined in {@link XPathConstants}.
* @throws NullPointerException If <code>source</code> or <code>returnType</code> is <code>null</code>. * @throws NullPointerException If {@code source or returnType} is {@code null}.
*/ */
public Object evaluate(InputSource source, QName returnType) public Object evaluate(InputSource source, QName returnType)
throws XPathExpressionException; throws XPathExpressionException;
/** /**
* <p>Evaluate the compiled XPath expression in the context of the specified <code>InputSource</code> and return the result as a * <p>Evaluate the compiled XPath expression in the context of the specified {@code InputSource} and return the result as a
* <code>String</code>.</p> * {@code String}.</p>
* *
* <p>This method calls {@link #evaluate(InputSource source, QName returnType)} with a <code>returnType</code> of * <p>This method calls {@link #evaluate(InputSource source, QName returnType)} with a {@code returnType} of
* {@link XPathConstants#STRING}.</p> * {@link XPathConstants#STRING}.</p>
* *
* <p>See <a href="#XPathExpression-evaluation">Evaluation of XPath Expressions</a> for context item evaluation, * <p>See <a href="#XPathExpression-evaluation">Evaluation of XPath Expressions</a> for context item evaluation,
* variable, function and QName resolution and return type conversion.</p> * variable, function and QName resolution and return type conversion.</p>
* *
* <p>If <code>source</code> is <code>null</code>, then a <code>NullPointerException</code> is thrown.</p> * <p>If {@code source} is {@code null}, then a {@code NullPointerException} is thrown.</p>
* *
* @param source The <code>InputSource</code> of the document to evaluate over. * @param source The {@code InputSource} of the document to evaluate over.
* *
* @return The <code>String</code> that is the result of evaluating the expression and converting the result to a * @return The {@code String} that is the result of evaluating the expression and converting the result to a
* <code>String</code>. * {@code String}.
* *
* @throws XPathExpressionException If the expression cannot be evaluated. * @throws XPathExpressionException If the expression cannot be evaluated.
* @throws NullPointerException If <code>source</code> is <code>null</code>. * @throws NullPointerException If {@code source} is {@code null}.
*/ */
public String evaluate(InputSource source) public String evaluate(InputSource source)
throws XPathExpressionException; throws XPathExpressionException;
/**
* Evaluate the compiled XPath expression in the specified context, and return
* the result with the type specified through the {@code class type}.
*
* <p>
* The parameter {@code item} represents the context the XPath expression
* will be operated on. The type of the context is implementation-dependent.
* If the value is {@code null}, the operation must have no dependency on
* the context, otherwise an XPathExpressionException will be thrown.
*
* @implNote
* The type of the context is usually {@link org.w3c.dom.Node}.
*
* @implSpec
* The default implementation in the XPath API is equivalent to:
* <pre> {@code
* (T)evaluate(item, XPathEvaluationResult.XPathResultType.getQNameType(type));
* }</pre>
*
* Since the {@code evaluate} method does not support the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type, specifying
* XPathEvaluationResult as the type will result in IllegalArgumentException.
* Any implementation supporting the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must override
* this method.
*
* @param <T> The class type that will be returned by the XPath expression.
* @param item The context the XPath expression will be evaluated in.
* @param type The class type expected to be returned by the XPath expression.
*
* @return The result of evaluating the expression.
*
* @throws XPathExpressionException If the expression cannot be evaluated.
* @throws IllegalArgumentException If {@code type} is not of the types
* corresponding to the types defined in the {@link XPathEvaluationResult.XPathResultType
* XPathResultType}, or XPathEvaluationResult is specified as the type but an
* implementation supporting the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type is not available.
* @throws NullPointerException If {@code type} is {@code null}.
*
* @since 1.9
*/
default <T>T evaluateExpression(Object item, Class<T> type)
throws XPathExpressionException
{
return type.cast(evaluate(item, XPathEvaluationResult.XPathResultType.getQNameType(type)));
}
/**
* Evaluate the compiled XPath expression in the specified context. This is
* equivalent to calling {@link #evaluateExpression(Object item, Class type)}
* with type {@link XPathEvaluationResult}:
* <pre> {@code
* evaluateExpression(item, XPathEvaluationResult.class);
* }</pre>
* <p>
* The parameter {@code item} represents the context the XPath expression
* will be operated on. The type of the context is implementation-dependent.
* If the value is {@code null}, the operation must have no dependency on
* the context, otherwise an XPathExpressionException will be thrown.
*
* @implNote
* The type of the context is usually {@link org.w3c.dom.Node}.
*
* @implSpec
* The default implementation in the XPath API is equivalent to:
* <pre> {@code
* evaluateExpression(item, XPathEvaluationResult.class);
* }</pre>
*
* Since the {@code evaluate} method does not support the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY}
* type, the default implementation of this method will always throw an
* IllegalArgumentException. Any implementation supporting the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must therefore
* override this method.
*
* @param item The context the XPath expression will be evaluated in.
*
* @return The result of evaluating the expression.
*
* @throws XPathExpressionException If the expression cannot be evaluated.
* @throws IllegalArgumentException If the implementation of this method
* does not support the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type.
*
* @since 1.9
*/
default XPathEvaluationResult<?> evaluateExpression(Object item)
throws XPathExpressionException
{
return evaluateExpression(item, XPathEvaluationResult.class);
}
/**
* Evaluate the compiled XPath expression in the specified context,
* and return the result with the type specified through the {@code class type}
* <p>
* This method builds a data model for the {@link InputSource} and calls
* {@link #evaluateExpression(Object item, Class type)} on the resulting
* document object.
* <P>
* By default, the JDK's data model is {@link org.w3c.dom.Document}.
*
* @implSpec
* The default implementation in the XPath API is equivalent to:
* <pre> {@code
(T)evaluate(source, XPathEvaluationResult.XPathResultType.getQNameType(type));
* }</pre>
*
* Since the {@code evaluate} method does not support the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type, specifying
* XPathEvaluationResult as the type will result in IllegalArgumentException.
* Any implementation supporting the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must override
* this method.
*
* @param <T> The class type that will be returned by the XPath expression.
* @param source The {@code InputSource} of the document to evaluate over.
* @param type The class type expected to be returned by the XPath expression.
*
* @return The result of evaluating the expression.
*
* @throws XPathExpressionException If the expression cannot be evaluated.
* @throws IllegalArgumentException If {@code type} is not of the types
* corresponding to the types defined in the {@link XPathEvaluationResult.XPathResultType
* XPathResultType}, or XPathEvaluationResult is specified as the type but an
* implementation supporting the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type
* is not available.
* @throws NullPointerException If {@code source or type} is {@code null}.
*
* @since 1.9
*/
default <T>T evaluateExpression(InputSource source, Class<T> type)
throws XPathExpressionException
{
return type.cast(evaluate(source, XPathEvaluationResult.XPathResultType.getQNameType(type)));
}
/**
* Evaluate the compiled XPath expression in the specified context. This is
* equivalent to calling {@link #evaluateExpression(InputSource source, Class type)}
* with type {@link XPathEvaluationResult}:
* <pre> {@code
* evaluateExpression(source, XPathEvaluationResult.class);
* }</pre>
* <p>
*
* @implSpec
* The default implementation in the XPath API is equivalent to:
* <pre> {@code
* (XPathEvaluationResult)evaluateExpression(source, XPathEvaluationResult.class);
* }</pre>
*
* Since the {@code evaluate} method does not support the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY}
* type, the default implementation of this method will always throw an
* IllegalArgumentException. Any implementation supporting the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must therefore
* override this method.
*
* @param source The {@code InputSource} of the document to evaluate over.
*
* @return The result of evaluating the expression.
*
* @throws XPathExpressionException If the expression cannot be evaluated.
* @throws IllegalArgumentException If the implementation of this method
* does not support the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type.
* @throws NullPointerException If {@code source} is {@code null}.
*
* @since 1.9
*/
default XPathEvaluationResult<?> evaluateExpression(InputSource source)
throws XPathExpressionException
{
return evaluateExpression(source, XPathEvaluationResult.class);
}
} }

View File

@ -117,7 +117,7 @@ public abstract class XPathFactory {
* and returns it if it is successfully created. * and returns it if it is successfully created.
* </li> * </li>
* <li> * <li>
* ${java.home}/conf/jaxp.properties is read and the value associated with the key being the system property above is looked for. * ${java.home}/lib/jaxp.properties is read and the value associated with the key being the system property above is looked for.
* If present, the value is processed just like above. * If present, the value is processed just like above.
* </li> * </li>
* <li> * <li>

View File

@ -176,9 +176,9 @@ class XPathFactoryFinder {
String javah = ss.getSystemProperty( "java.home" ); String javah = ss.getSystemProperty( "java.home" );
String configFile = javah + File.separator + String configFile = javah + File.separator +
"conf" + File.separator + "jaxp.properties"; "lib" + File.separator + "jaxp.properties";
// try to read from $java.home/conf/jaxp.properties // try to read from $java.home/lib/jaxp.properties
try { try {
if(firstTime){ if(firstTime){
synchronized(cacheProps){ synchronized(cacheProps){
@ -193,7 +193,7 @@ class XPathFactoryFinder {
} }
} }
final String factoryClassName = cacheProps.getProperty(propertyName); final String factoryClassName = cacheProps.getProperty(propertyName);
debugPrintln("found " + factoryClassName + " in $java.home/conf/jaxp.properties"); debugPrintln("found " + factoryClassName + " in $java.home/jaxp.properties");
if (factoryClassName != null) { if (factoryClassName != null) {
xpathFactory = createInstance(factoryClassName, true); xpathFactory = createInstance(factoryClassName, true);

View File

@ -0,0 +1,65 @@
/*
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.xml.xpath;
import java.util.Iterator;
import org.w3c.dom.Node;
/**
* XPathNodes represents a set of nodes selected by a location path as specified
* in <a href="http://www.w3.org/TR/xpath/#node-sets">XML Path Language (XPath)
* Version 1.0, 3.3 Node-sets</a>.
*
* @since 1.9
*/
public interface XPathNodes extends Iterable<Node> {
/**
* Returns an iterator of the Nodes.
*
* @return an Iterator.
*/
@Override
public abstract Iterator<Node> iterator();
/**
* Returns the number of items in the result
*
* @return The number of items in the result
*/
public abstract int size();
/**
* Returns a Node at the specified position
*
* @param index Index of the element to return.
* @return The Node at the specified position.
* @throws javax.xml.xpath.XPathException If the index is out of range
* (index &lt; 0 || index &gt;= size())
*/
public abstract Node get(int index)
throws XPathException;
}

View File

@ -1,6 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
<head>
<!-- <!--
Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved. Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it This code is free software; you can redistribute it and/or modify it
@ -23,35 +25,35 @@ Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
or visit www.oracle.com if you need additional information or have any or visit www.oracle.com if you need additional information or have any
questions. questions.
--> -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>javax.xml.xpath</title>
<meta name="@author" content="mailto:Ben@galbraiths.org" />
<meta name="@author" content="mailto:Norman.Walsh@Sun.com" />
<meta name="@author" content="mailto:Jeff.Suttor@Sun.com" />
<meta name="@see" content="http://www.w3.org/TR/xpath" />
<meta name="@since" content="1.5" />
</head> </head>
<body bgcolor="white">
<body> This package provides an <em>object-model neutral</em> API for the
<p>This package provides an <em>object-model neutral</em> API for the
evaluation of XPath expressions and access to the evaluation evaluation of XPath expressions and access to the evaluation
environment. environment.
</p>
<p>The following XML standards apply:</p> <p>
The XPath API supports <a href="http://www.w3.org/TR/xpath">
<ul> XML Path Language (XPath) Version 1.0</a>
<li><a href="http://www.w3.org/TR/xpath">XML Path Language (XPath) Version 1.0</a></li>
</ul>
<hr /> <hr />
<h2>XPath Overview</h2> <ul>
<li><a href='#XPath.Overview'>1. XPath Overview</a></li>
<li><a href='#XPath.Expressions'>2. XPath Expressions</a></li>
<li><a href='#XPath.Datatypes'>3. XPath Data Types</a>
<ul>
<li><a href='#XPath.Datatypes.QName'>3.1 QName Types</a>
<li><a href='#XPath.Datatypes.Class'>3.2 Class Types</a>
<li><a href='#XPath.Datatypes.Enum'>3.3 Enum Types</a>
</ul>
</li>
<li><a href='#XPath.Context'>4. XPath Context</a></li>
<li><a href='#XPath.Use'>5. Using the XPath API</a></li>
</ul>
<p>
<a name="XPath.Overview"></a>
<h3>1. XPath Overview</h3>
<p>The XPath language provides a simple, concise syntax for selecting <p>The XPath language provides a simple, concise syntax for selecting
nodes from an XML document. XPath also provides rules for converting a nodes from an XML document. XPath also provides rules for converting a
@ -67,7 +69,8 @@ stand-alone language, as a single XPath expression can be used to
replace many lines of DOM API code. replace many lines of DOM API code.
</p> </p>
<h3>XPath Expressions</h3> <a name="XPath.Expressions"></a>
<h3>2. XPath Expressions</h3>
<p>An XPath <em>expression</em> is composed of a <em>location <p>An XPath <em>expression</em> is composed of a <em>location
path</em> and one or more optional <em>predicates</em>. Expressions path</em> and one or more optional <em>predicates</em>. Expressions
@ -76,18 +79,22 @@ may also include XPath variables.
<p>The following is an example of a simple XPath expression:</p> <p>The following is an example of a simple XPath expression:</p>
<blockquote>
<pre> <pre>
/foo/bar /foo/bar
</pre> </pre>
</blockquote>
<p>This example would select the <code>&lt;bar&gt;</code> element in <p>This example would select the <code>&lt;bar&gt;</code> element in
an XML document such as the following:</p> an XML document such as the following:</p>
<blockquote>
<pre> <pre>
&lt;foo&gt; &lt;foo&gt;
&lt;bar/&gt; &lt;bar/&gt;
&lt;/foo&gt; &lt;/foo&gt;
</pre> </pre>
</blockquote>
<p>The expression <code>/foo/bar</code> is an example of a location <p>The expression <code>/foo/bar</code> is an example of a location
path. While XPath location paths resemble Unix-style file system path. While XPath location paths resemble Unix-style file system
@ -96,30 +103,36 @@ paths, an important distinction is that XPath expressions return
<code>&lt;bar&gt;</code> elements in the following document would be <code>&lt;bar&gt;</code> elements in the following document would be
selected by the <code>/foo/bar</code> expression:</p> selected by the <code>/foo/bar</code> expression:</p>
<blockquote>
<pre> <pre>
&lt;foo&gt; &lt;foo&gt;
&lt;bar/&gt; &lt;bar/&gt;
&lt;bar/&gt; &lt;bar/&gt;
&lt;bar/&gt; &lt;bar/&gt;
&lt;/foo&gt; &lt;/foo&gt;
</pre> </pre>
</blockquote>
<p>A special location path operator, <code>//</code>, selects nodes at <p>A special location path operator, <code>//</code>, selects nodes at
any depth in an XML document. The following example selects all any depth in an XML document. The following example selects all
<code>&lt;bar&gt;</code> elements regardless of their location in a <code>&lt;bar&gt;</code> elements regardless of their location in a
document:</p> document:</p>
<blockquote>
<pre> <pre>
//bar //bar
</pre> </pre>
</blockquote>
<p>A wildcard operator, *, causes all element nodes to be selected. <p>A wildcard operator, *, causes all element nodes to be selected.
The following example selects all children elements of a The following example selects all children elements of a
<code>&lt;foo&gt;</code> element:</p> <code>&lt;foo&gt;</code> element:
<blockquote>
<pre> <pre>
/foo/* /foo/*
</pre> </pre>
</blockquote>
<p>In addition to element nodes, XPath location paths may also address <p>In addition to element nodes, XPath location paths may also address
attribute nodes, text nodes, comment nodes, and processing instruction attribute nodes, text nodes, comment nodes, and processing instruction
@ -166,35 +179,27 @@ location path. Predicates are of the form
<code>&lt;foo&gt;</code> elements that contain an <code>include</code> <code>&lt;foo&gt;</code> elements that contain an <code>include</code>
attribute with the value of <code>true</code>:</p> attribute with the value of <code>true</code>:</p>
<blockquote>
<pre> <pre>
//foo[@include='true'] //foo[@include='true']
</pre> </pre>
</blockquote>
<p>Predicates may be appended to each other to further refine an <p>Predicates may be appended to each other to further refine an
expression, such as:</p> expression, such as:</p>
<blockquote>
<pre> <pre>
//foo[@include='true'][@mode='bar'] //foo[@include='true'][@mode='bar']
</pre> </pre>
</blockquote>
<h3>Using the XPath API</h3> <a name="XPath.Datatypes"></a>
<h3>3. XPath Data Types</h3>
<p>
The following example demonstrates using the XPath API to select one
or more nodes from an XML document:</p>
<pre>
XPath xpath = XPathFactory.newInstance().newXPath();
String expression = "/widgets/widget";
InputSource inputSource = new InputSource("widgets.xml");
NodeList nodes = (NodeList) xpath.evaluate(expression, inputSource, XPathConstants.NODESET);
</pre>
<h3>XPath Expressions and Types</h3>
<p>While XPath expressions select nodes in the XML document, the XPath <p>While XPath expressions select nodes in the XML document, the XPath
API allows the selected nodes to be coalesced into one of the API allows the selected nodes to be coalesced into one of the
following other data types:</p> following data types:</p>
<ul> <ul>
<li><code>Boolean</code></li> <li><code>Boolean</code></li>
@ -202,14 +207,10 @@ following other data types:</p>
<li><code>String</code></li> <li><code>String</code></li>
</ul> </ul>
<p>The desired return type is specified by a {@link <a name="XPath.Datatypes.QName"></a>
javax.xml.namespace.QName} parameter in method call used to evaluate <h3>3.1 QName types</h3>
the expression, which is either a call to The XPath API defines the following {@link javax.xml.namespace.QName} types to
<code>XPathExpression.evalute(...)</code> or to one of the represent return types of an XPath evaluation:
<code>XPath.evaluate(...)</code> convenience methods. The allowed
QName values are specified as constants in the {@link
javax.xml.xpath.XPathConstants} class; they are:</p>
<ul> <ul>
<li>{@link javax.xml.xpath.XPathConstants#NODESET}</li> <li>{@link javax.xml.xpath.XPathConstants#NODESET}</li>
<li>{@link javax.xml.xpath.XPathConstants#NODE}</li> <li>{@link javax.xml.xpath.XPathConstants#NODE}</li>
@ -218,26 +219,71 @@ javax.xml.xpath.XPathConstants} class; they are:</p>
<li>{@link javax.xml.xpath.XPathConstants#NUMBER}</li> <li>{@link javax.xml.xpath.XPathConstants#NUMBER}</li>
</ul> </ul>
<p>The return type is specified by a {@link javax.xml.namespace.QName} parameter
in method call used to evaluate the expression, which is either a call to
<code>XPathExpression.evalute(...)</code> or <code>XPath.evaluate(...)</code>
methods.
<p>When a <code>Boolean</code> return type is requested, <p>When a <code>Boolean</code> return type is requested,
<code>Boolean.TRUE</code> is returned if one or more nodes were <code>Boolean.TRUE</code> is returned if one or more nodes were
selected; otherwise, <code>Boolean.FALSE</code> is returned.</p> selected; otherwise, <code>Boolean.FALSE</code> is returned.
<p>The <code>String</code> return type is a convenience for retrieving <p>The <code>String</code> return type is a convenience for retrieving
the character data from a text node, attribute node, comment node, or the character data from a text node, attribute node, comment node, or
processing-instruction node. When used on an element node, the value processing-instruction node. When used on an element node, the value
of the child text nodes is returned. of the child text nodes is returned.
</p>
<p>The <code>Number</code> return type attempts to coalesce the text <p>The <code>Number</code> return type attempts to coalesce the text
of a node to a <code>double</code> data type. of a node to a <code>double</code> data type.
</p>
<h3>XPath Context</h3> <a name="XPath.Datatypes.Class"></a>
<h3>3.2 Class types</h3>
In addition to the QName types, the XPath API supports the use of Class types
through the <code>XPathExpression.evaluteExpression(...)</code> or
<code>XPath.evaluateExpression(...)</code> methods.
The XPath data types are mapped to Class types as follows:
<ul>
<li><code>Boolean</code> -- <code>Boolean.class</code></li>
<li><code>Number</code> -- <code>Number.class</code></li>
<li><code>String</code> -- <code>String.class</code></li>
<li><code>Nodeset</code> -- <code>XPathNodes.class</code></li>
<li><code>Node</code> -- <code>Node.class</code></li>
</ul>
<p>
Of the subtypes of Number, only Double, Integer and Long are supported.
<a name="XPath.Datatypes.Enum"></a>
<h3>3.3 Enum types</h3>
Enum types are defined in {@link javax.xml.xpath.XPathEvaluationResult.XPathResultType}
that provide mappings between the QName and Class types above. The result of
evaluating an expression using the <code>XPathExpression.evaluteExpression(...)</code>
or <code>XPath.evaluateExpression(...)</code> methods will be of one of these types.
<a name="XPath.Context"></a>
<h3>4. XPath Context</h3>
<p>XPath location paths may be relative to a particular node in the <p>XPath location paths may be relative to a particular node in the
document, known as the <code>context</code>. Consider the following document, known as the <code>context</code>. A context consists of:
XML document:</p> <ul>
<li>a node (the context node)</li>
<li>a pair of non-zero positive integers (the context position and the context size)</li>
<li>a set of variable bindings</li>
<li>a function library</li>
<li>the set of namespace declarations in scope for the expression</li>
</ul>
<p>
It is an XML document tree represented as a hierarchy of nodes, a
{@link org.w3c.dom.Node} for example, in the JDK implementation.
<a name="XPath.Use"></a>
<h3>5. Using the XPath API</h3>
Consider the following XML document:
<p>
<blockquote>
<pre> <pre>
&lt;widgets&gt; &lt;widgets&gt;
&lt;widget&gt; &lt;widget&gt;
@ -246,36 +292,88 @@ XML document:</p>
&lt;/widget&gt; &lt;/widget&gt;
&lt;/widgets&gt; &lt;/widgets&gt;
</pre> </pre>
</blockquote>
<p>The <code>&lt;widget&gt;</code> element can be selected with the <p>
following XPath API code:</p> The <code>&lt;widget&gt;</code> element can be selected with the following process:
<blockquote>
<pre> <pre>
// parse the XML as a W3C Document // parse the XML as a W3C Document
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document document = builder.parse(new File("/widgets.xml")); Document document = builder.parse(new File("/widgets.xml"));
//Get an XPath object and evaluate the expression
XPath xpath = XPathFactory.newInstance().newXPath(); XPath xpath = XPathFactory.newInstance().newXPath();
String expression = "/widgets/widget"; String expression = "/widgets/widget";
Node widgetNode = (Node) xpath.evaluate(expression, document, XPathConstants.NODE); Node widgetNode = (Node) xpath.evaluate(expression, document, XPathConstants.NODE);
//or using the evaluateExpression method
Node widgetNode = xpath.evaluateExpression(expression, document, Node.class);
</pre> </pre>
</blockquote>
<p>With a reference to the <code>&lt;widget&gt;</code> element, a <p>With a reference to the <code>&lt;widget&gt;</code> element, a
relative XPath expression can now written to select the relative XPath expression can be written to select the
<code>&lt;manufacturer&gt;</code> child element:</p> <code>&lt;manufacturer&gt;</code> child element:</p>
<blockquote>
<pre> <pre>
XPath xpath = XPathFactory.newInstance().newXPath(); XPath xpath = XPathFactory.newInstance().newXPath();
<strong>String expression = "manufacturer";</strong> <strong>String expression = "manufacturer";</strong>
Node manufacturerNode = (Node) xpath.evaluate(expression, <strong>widgetNode</strong>, XPathConstants.NODE); Node manufacturerNode = (Node) xpath.evaluate(expression, <strong>widgetNode</strong>, XPathConstants.NODE);
</pre>
<ul> //or using the evaluateExpression method
<li>Author <a href="mailto:Ben@galbraiths.org">Ben Galbraith</a></li> Node manufacturerNode = xpath.evaluateExpression(expression, <strong>widgetNode</strong>, Node.class);
<li>Author <a href="mailto:Norman.Walsh@Sun.com">Norman Walsh</a></li> </pre>
<li>Author <a href="mailto:Jeff.Suttor@Sun.com">Jeff Suttor</a></li> </blockquote>
<li>See <a href="http://www.w3.org/TR/xpath">XML Path Language (XPath) Version 1.0</a></li>
<li>Since 1.5</li> <p>
</ul> In the above example, the XML file is read into a DOM Document before being passed
to the XPath API. The following code demonstrates the use of InputSource to
leave it to the XPath implementation to process it:
<blockquote>
<pre>
XPath xpath = XPathFactory.newInstance().newXPath();
String expression = "/widgets/widget";
InputSource inputSource = new InputSource("widgets.xml");
NodeList nodes = (NodeList) xpath.evaluate(expression, inputSource, XPathConstants.NODESET);
//or using the evaluateExpression method
XPathNodes nodes = xpath.evaluate(expression, inputSource, XPathNodes.class);
</pre>
</blockquote>
<p>
In the above cases, the type of the expected results are known. In case where
the result type is unknown or any type, the {@link javax.xml.xpath.XPathEvaluationResult}
may be used to determine the return type. The following code demonstrates the usage:
<blockquote>
<pre>
XPathEvaluationResult&lt;?&gt; result = xpath.evaluateExpression(expression, document);
switch (result.type()) {
case NODESET:
XPathNodes nodes = (XPathNodes)result.value();
...
break;
}
</pre>
</blockquote>
<p>
The XPath 1.0 Number data type is defined as a double. However, the XPath
specification also provides functions that returns Integer type. To facilitate
such operations, the XPath API allows Integer and Long to be used in
{@code evaluateExpression} method such as the following code:
<p>
<blockquote>
<pre>
int count = xpath.evaluate("count(/widgets/widget)", document, Integer.class);
</pre>
</blockquote>
@since 1.5
</body> </body>
</html> </html>

View File

@ -0,0 +1,297 @@
/*
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.xml.validation.ptests;
import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;
import static javax.xml.validation.ptests.ValidationTestConst.XML_DIR;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertSame;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import org.w3c.dom.Document;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;
import org.xml.sax.SAXParseException;
/*
* @summary Class containing the test cases for SchemaFactory
*/
@Test(singleThreaded = true)
public class SchemaFactoryTest {
@BeforeClass
public void setup() throws SAXException, IOException, ParserConfigurationException {
sf = newSchemaFactory();
assertNotNull(sf);
xsd1 = Files.readAllBytes(Paths.get(XML_DIR + "test.xsd"));
xsd2 = Files.readAllBytes(Paths.get(XML_DIR + "test1.xsd"));
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
xsdDoc1 = db.parse(newInputStream(xsd1));
xsdDoc2 = db.parse(newInputStream(xsd2));
xml = Files.readAllBytes(Paths.get(XML_DIR + "test.xml"));
}
@Test(expectedExceptions = SAXParseException.class)
public void testNewSchemaDefault() throws SAXException, IOException {
validate(sf.newSchema());
}
@Test
public void testNewSchemaWithFile() throws SAXException, IOException {
validate(sf.newSchema(new File(XML_DIR + "test.xsd")));
}
@Test(expectedExceptions = NullPointerException.class)
public void testNewSchemaWithNullFile() throws SAXException {
sf.newSchema((File) null);
}
@DataProvider(name = "valid-source")
public Object[][] getValidSource() {
return new Object[][] {
{ streamSource(xsd1) },
{ saxSource(xsd1) },
{ domSource(xsdDoc1) } };
}
@Test(dataProvider = "valid-source")
public void testNewSchemaWithValidSource(Source schema) throws SAXException, IOException {
validate(sf.newSchema(schema));
}
@DataProvider(name = "invalid-source")
public Object[][] getInvalidSource() {
return new Object[][] {
{ nullStreamSource() },
{ nullSaxSource() } };
}
@Test(dataProvider = "invalid-source", expectedExceptions = SAXParseException.class)
public void testNewSchemaWithInvalidSource(Source schema) throws SAXException {
sf.newSchema(schema);
}
@Test(expectedExceptions = NullPointerException.class)
public void testNewSchemaWithNullSource() throws SAXException {
sf.newSchema((Source)null);
}
@DataProvider(name = "valid-sources")
public Object[][] getValidSources() {
return new Object[][] {
{ streamSource(xsd1), streamSource(xsd2) },
{ saxSource(xsd1), saxSource(xsd2) },
{ domSource(xsdDoc1), domSource(xsdDoc2) } };
}
@Test(dataProvider = "valid-sources")
public void testNewSchemaWithValidSourceArray(Source schema1, Source schema2) throws SAXException, IOException {
validate(sf.newSchema(new Source[] { schema1, schema2 }));
}
@DataProvider(name = "invalid-sources")
public Object[][] getInvalidSources() {
return new Object[][] {
{ streamSource(xsd1), nullStreamSource() },
{ nullStreamSource(), nullStreamSource() },
{ saxSource(xsd1), nullSaxSource() },
{ nullSaxSource(), nullSaxSource() } };
}
@Test(dataProvider = "invalid-sources", expectedExceptions = SAXParseException.class)
public void testNewSchemaWithInvalidSourceArray(Source schema1, Source schema2) throws SAXException {
sf.newSchema(new Source[] { schema1, schema2 });
}
@DataProvider(name = "null-sources")
public Object[][] getNullSources() {
return new Object[][] {
{ new Source[] { domSource(xsdDoc1), null } },
{ new Source[] { null, null } },
{ null } };
}
@Test(dataProvider = "null-sources", expectedExceptions = NullPointerException.class)
public void testNewSchemaWithNullSourceArray(Source[] schemas) throws SAXException {
sf.newSchema(schemas);
}
@Test(expectedExceptions = NullPointerException.class)
public void testNewSchemaWithNullUrl() throws SAXException {
sf.newSchema((URL) null);
}
@Test
public void testErrorHandler() {
SchemaFactory sf = newSchemaFactory();
assertNull(sf.getErrorHandler(), "When SchemaFactory is created, initially ErrorHandler should not be set.");
ErrorHandler handler = new MyErrorHandler();
sf.setErrorHandler(handler);
assertSame(sf.getErrorHandler(), handler);
sf.setErrorHandler(null);
assertNull(sf.getErrorHandler());
}
@Test(expectedExceptions = SAXNotRecognizedException.class)
public void testGetUnrecognizedProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
SchemaFactory sf = newSchemaFactory();
sf.getProperty(UNRECOGNIZED_NAME);
}
@Test(expectedExceptions = SAXNotRecognizedException.class)
public void testSetUnrecognizedProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
SchemaFactory sf = newSchemaFactory();
sf.setProperty(UNRECOGNIZED_NAME, "test");
}
@Test(expectedExceptions = NullPointerException.class)
public void testGetNullProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
SchemaFactory sf = newSchemaFactory();
assertNotNull(sf);
sf.getProperty(null);
}
@Test(expectedExceptions = NullPointerException.class)
public void testSetNullProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
SchemaFactory sf = newSchemaFactory();
assertNotNull(sf);
sf.setProperty(null, "test");
}
@Test(expectedExceptions = SAXNotRecognizedException.class)
public void testGetUnrecognizedFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
SchemaFactory sf = newSchemaFactory();
sf.getFeature(UNRECOGNIZED_NAME);
}
@Test(expectedExceptions = SAXNotRecognizedException.class)
public void testSetUnrecognizedFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
SchemaFactory sf = newSchemaFactory();
sf.setFeature(UNRECOGNIZED_NAME, true);
}
@Test(expectedExceptions = NullPointerException.class)
public void testGetNullFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
SchemaFactory sf = newSchemaFactory();
assertNotNull(sf);
sf.getFeature(null);
}
@Test(expectedExceptions = NullPointerException.class)
public void testSetNullFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
SchemaFactory sf = newSchemaFactory();
assertNotNull(sf);
sf.setFeature(null, true);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testInvalidSchemaLanguage() {
final String INVALID_SCHEMA_LANGUAGE = "http://relaxng.org/ns/structure/1.0";
SchemaFactory.newInstance(INVALID_SCHEMA_LANGUAGE);
}
@Test(expectedExceptions = NullPointerException.class)
public void testNullSchemaLanguage() {
SchemaFactory.newInstance(null);
}
private void validate(Schema schema) throws SAXException, IOException {
schema.newValidator().validate(new StreamSource(new ByteArrayInputStream(xml)));
}
private InputStream newInputStream(byte[] xsd) {
return new ByteArrayInputStream(xsd);
}
private Source streamSource(byte[] xsd) {
return new StreamSource(newInputStream(xsd));
}
private Source nullStreamSource() {
return new StreamSource((InputStream) null);
}
private Source saxSource(byte[] xsd) {
return new SAXSource(new InputSource(newInputStream(xsd)));
}
private Source nullSaxSource() {
return new SAXSource(new InputSource((InputStream) null));
}
private Source domSource(Document xsdDoc) {
return new DOMSource(xsdDoc);
}
private SchemaFactory newSchemaFactory() {
return SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI);
}
private static final String UNRECOGNIZED_NAME = "http://xml.org/sax/features/namespace-prefixes";
private SchemaFactory sf;
private byte[] xsd1;
private byte[] xsd2;
private Document xsdDoc1;
private Document xsdDoc2;
private byte[] xml;
}

View File

@ -0,0 +1,93 @@
/*
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.xml.validation.ptests;
import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;
import static javax.xml.validation.ptests.ValidationTestConst.XML_DIR;
import static jaxp.library.JAXPTestUtilities.filenameToURL;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import java.io.File;
import java.io.IOException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.TypeInfoProvider;
import javax.xml.validation.ValidatorHandler;
import jaxp.library.JAXPFileBaseTest;
import org.testng.annotations.Test;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
/*
* @summary test ValidatorHandler.getTypeInfoProvider()
*/
public class TypeInfoProviderTest extends JAXPFileBaseTest {
private ValidatorHandler validatorHandler;
@Test
public void test() throws SAXException, ParserConfigurationException, IOException {
SchemaFactory sf = SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(new File(XML_DIR + "shiporder11.xsd"));
validatorHandler = schema.newValidatorHandler();
MyDefaultHandler myDefaultHandler = new MyDefaultHandler();
validatorHandler.setContentHandler(myDefaultHandler);
InputSource is = new InputSource(filenameToURL(XML_DIR + "shiporder11.xml"));
SAXParserFactory parserFactory = SAXParserFactory.newInstance();
parserFactory.setNamespaceAware(true);
XMLReader xmlReader = parserFactory.newSAXParser().getXMLReader();
xmlReader.setContentHandler(validatorHandler);
xmlReader.parse(is);
}
private class MyDefaultHandler extends DefaultHandler {
public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
TypeInfoProvider typeInfoProvider = validatorHandler.getTypeInfoProvider();
int index = atts.getIndex("orderid");
if (index != -1) {
System.out.println(" Index " + index);
System.out.println(" ElementType " + typeInfoProvider.getElementTypeInfo().getTypeName());
assertEquals(typeInfoProvider.getAttributeTypeInfo(index).getTypeName(), "string");
assertTrue(typeInfoProvider.isSpecified(index));
assertFalse(typeInfoProvider.isIdAttribute(index));
}
}
}
}

View File

@ -0,0 +1,144 @@
/*
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.xml.validation.ptests;
import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;
import static javax.xml.validation.ptests.ValidationTestConst.XML_DIR;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertSame;
import static org.testng.Assert.assertTrue;
import java.io.File;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.ValidatorHandler;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.xml.sax.ContentHandler;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;
import org.xml.sax.helpers.DefaultHandler;
/*
* @summary Class containing the test cases for ValidatorHandler API
*/
public class ValidatorHandlerTest {
@BeforeClass
public void setup() throws SAXException {
schema = SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI).newSchema(new File(XML_DIR + "test.xsd"));
assertNotNull(schema);
}
@Test
public void testErrorHandler() {
ValidatorHandler validatorHandler = getValidatorHandler();
assertNull(validatorHandler.getErrorHandler(), "When ValidatorHandler is created, initially ErrorHandler should not be set.");
ErrorHandler handler = new MyErrorHandler();
validatorHandler.setErrorHandler(handler);
assertSame(validatorHandler.getErrorHandler(), handler);
}
@Test(expectedExceptions = SAXNotRecognizedException.class)
public void testGetUnrecognizedProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
ValidatorHandler validatorHandler = getValidatorHandler();
validatorHandler.getProperty(FEATURE_NAME);
}
@Test(expectedExceptions = SAXNotRecognizedException.class)
public void testSetUnrecognizedProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
ValidatorHandler validatorHandler = getValidatorHandler();
validatorHandler.setProperty(FEATURE_NAME, "test");
}
@Test(expectedExceptions = NullPointerException.class)
public void testGetNullProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
ValidatorHandler validatorHandler = getValidatorHandler();
assertNotNull(validatorHandler);
validatorHandler.getProperty(null);
}
@Test(expectedExceptions = NullPointerException.class)
public void testSetNullProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
ValidatorHandler validatorHandler = getValidatorHandler();
assertNotNull(validatorHandler);
validatorHandler.setProperty(null, "test");
}
public void testFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
ValidatorHandler validatorHandler = getValidatorHandler();
assertFalse(validatorHandler.getFeature(FEATURE_NAME), "The feature should be false by default.");
validatorHandler.setFeature(FEATURE_NAME, true);
assertTrue(validatorHandler.getFeature(FEATURE_NAME), "The feature should be false by default.");
}
@Test(expectedExceptions = NullPointerException.class)
public void testGetNullFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
ValidatorHandler validatorHandler = getValidatorHandler();
assertNotNull(validatorHandler);
validatorHandler.getFeature(null);
}
@Test(expectedExceptions = NullPointerException.class)
public void testSetNullFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
ValidatorHandler validatorHandler = getValidatorHandler();
assertNotNull(validatorHandler);
validatorHandler.setFeature(null, true);
}
@Test
public void testContentHandler() {
ValidatorHandler validatorHandler = getValidatorHandler();
assertNull(validatorHandler.getContentHandler(), "When ValidatorHandler is created, initially ContentHandler should not be set.");
ContentHandler handler = new DefaultHandler();
validatorHandler.setContentHandler(handler);
assertSame(validatorHandler.getContentHandler(), handler);
validatorHandler.setContentHandler(null);
assertNull(validatorHandler.getContentHandler());
}
private ValidatorHandler getValidatorHandler() {
return schema.newValidatorHandler();
}
private static final String FEATURE_NAME = "http://xml.org/sax/features/namespace-prefixes";
private Schema schema;
}

View File

@ -0,0 +1,207 @@
/*
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.xml.validation.ptests;
import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;
import static javax.xml.validation.ptests.ValidationTestConst.XML_DIR;
import static jaxp.library.JAXPTestUtilities.filenameToURL;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertSame;
import java.io.File;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import jaxp.library.JAXPFileBaseTest;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import org.w3c.dom.Document;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;
import org.xml.sax.helpers.DefaultHandler;
/*
* @summary Class containing the test cases for Validator API
*/
public class ValidatorTest extends JAXPFileBaseTest {
@BeforeClass
public void setup() throws SAXException, IOException, ParserConfigurationException {
schema = SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI).newSchema(new File(XML_DIR + "test.xsd"));
assertNotNull(schema);
xmlFileUri = filenameToURL(XML_DIR + "test.xml");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
xmlDoc = dbf.newDocumentBuilder().parse(xmlFileUri);
}
@Test
public void testValidateStreamSource() throws SAXException, IOException {
Validator validator = getValidator();
validator.setErrorHandler(new MyErrorHandler());
validator.validate(getStreamSource());
}
@Test(expectedExceptions = NullPointerException.class)
public void testValidateNullSource() throws SAXException, IOException {
Validator validator = getValidator();
assertNotNull(validator);
validator.validate(null);
}
@Test
public void testErrorHandler() {
Validator validator = getValidator();
assertNull(validator.getErrorHandler(), "When Validator is created, initially ErrorHandler should not be set.");
ErrorHandler mh = new MyErrorHandler();
validator.setErrorHandler(mh);
assertSame(validator.getErrorHandler(), mh);
}
@DataProvider(name = "source-result")
public Object[][] getSourceAndResult() {
return new Object[][] {
{ getStreamSource(), null },
{ getSAXSource(), getSAXResult() },
{ getDOMSource(), getDOMResult() },
{ getSAXSource(), null },
{ getDOMSource(), null } };
}
@Test(dataProvider = "source-result")
public void testValidateWithResult(Source source, Result result) throws SAXException, IOException {
Validator validator = getValidator();
validator.validate(source, result);
}
@Test(expectedExceptions = SAXNotRecognizedException.class)
public void testGetUnrecognizedProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
Validator validator = getValidator();
validator.getProperty(UNRECOGNIZED_NAME);
}
@Test(expectedExceptions = SAXNotRecognizedException.class)
public void testSetUnrecognizedProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
Validator validator = getValidator();
validator.setProperty(UNRECOGNIZED_NAME, "test");
}
@Test(expectedExceptions = NullPointerException.class)
public void testGetNullProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
Validator validator = getValidator();
assertNotNull(validator);
validator.getProperty(null);
}
@Test(expectedExceptions = NullPointerException.class)
public void testSetNullProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
Validator validator = getValidator();
assertNotNull(validator);
validator.setProperty(null, "test");
}
@Test(expectedExceptions = SAXNotRecognizedException.class)
public void testGetUnrecognizedFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
Validator validator = getValidator();
validator.getFeature(UNRECOGNIZED_NAME);
}
@Test(expectedExceptions = SAXNotRecognizedException.class)
public void testSetUnrecognizedFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
Validator validator = getValidator();
validator.setFeature(UNRECOGNIZED_NAME, true);
}
@Test(expectedExceptions = NullPointerException.class)
public void testGetNullFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
Validator validator = getValidator();
assertNotNull(validator);
validator.getFeature(null);
}
@Test(expectedExceptions = NullPointerException.class)
public void testSetNullFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
Validator validator = getValidator();
assertNotNull(validator);
validator.setFeature(null, true);
}
private Validator getValidator() {
return schema.newValidator();
}
private Source getStreamSource() {
return new StreamSource(xmlFileUri);
}
private Source getSAXSource() {
return new SAXSource(new InputSource(xmlFileUri));
}
private Result getSAXResult() {
SAXResult saxResult = new SAXResult();
saxResult.setHandler(new DefaultHandler());
return saxResult;
}
private Source getDOMSource() {
return new DOMSource(xmlDoc);
}
private Result getDOMResult() {
return new DOMResult();
}
private static final String UNRECOGNIZED_NAME = "http://xml.org/sax/features/namespace-prefixes";
private String xmlFileUri;
private Schema schema;
private Document xmlDoc;
}

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<shiporder orderid="889923"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="shiporder.xsd">
<orderperson>John Smith</orderperson>
<shipto>
<name>Ola Nordmann</name>
<address>Langgt 23</address>
<city>4000 Stavanger</city>
<country>Norway</country>
</shipto>
<item>
<title>Empire Burlesque</title>
<note>Special Edition</note>
<quantity>1</quantity>
<price>10.90</price>
</item>
<item>
<title>Hide your heart</title>
<quantity>1</quantity>
<price>9.90</price>
</item>
</shiporder>

View File

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="ISO-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- definition of simple elements -->
<xs:element name="orderperson" type="xs:string"/>
<xs:element name="name" type="xs:string"/>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
<xs:element name="title" type="xs:string"/>
<xs:element name="note" type="xs:string"/>
<xs:element name="quantity" type="xs:positiveInteger"/>
<xs:element name="price" type="xs:decimal"/>
<!-- definition of attributes -->
<xs:attribute name="orderid" type="xs:string"/>
<!-- definition of complex elements -->
<xs:element name="shipto">
<xs:complexType>
<xs:sequence>
<xs:element ref="name"/>
<xs:element ref="address"/>
<xs:element ref="city"/>
<xs:element ref="country"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="item">
<xs:complexType>
<xs:sequence>
<xs:element ref="title"/>
<xs:element ref="note" minOccurs="0"/>
<xs:element ref="quantity"/>
<xs:element ref="price"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="shiporder">
<xs:complexType>
<xs:sequence>
<xs:element ref="orderperson"/>
<xs:element ref="shipto"/>
<xs:element ref="item" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute ref="orderid" use="required"/>
</xs:complexType>
</xs:element>
</xs:schema>

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<shiporder orderid="889923"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="shiporder.xsd">
<orderperson>John Smith</orderperson>
<shipto>
<name>Ola Nordmann</name>
<address>Langgt 23</address>
<city>4000 Stavanger</city>
<country>Norway</country>
</shipto>
<item>
<title>Empire Burlesque</title>
<note>Special Edition</note>
<quantity>1</quantity>
<price>10.90</price>
</item>
<item>
<title>Hide your heart</title>
<quantity>1</quantity>
<price>9.90</price>
</item>
</shiporder>

View File

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="ISO-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- definition of simple elements -->
<xs:element name="orderperson" type="xs:string"/>
<xs:element name="name" type="xs:string"/>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
<xs:element name="title" type="xs:string"/>
<xs:element name="note" type="xs:string"/>
<xs:element name="quantity" type="xs:positiveInteger"/>
<xs:element name="price" type="xs:decimal"/>
<!-- definition of attributes -->
<xs:attribute name="orderid" type="xs:string"/>
<!-- definition of complex elements -->
<xs:element name="shipto">
<xs:complexType>
<xs:sequence>
<xs:element ref="name"/>
<xs:element ref="address"/>
<xs:element ref="city"/>
<xs:element ref="country"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="item">
<xs:complexType>
<xs:sequence>
<xs:element ref="title"/>
<xs:element ref="note" minOccurs="0"/>
<xs:element ref="quantity"/>
<xs:element ref="price"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="shiporder">
<xs:complexType>
<xs:sequence>
<xs:element ref="orderperson"/>
<xs:element ref="shipto"/>
<xs:element ref="item" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute ref="orderid" use="required"/>
</xs:complexType>
</xs:element>
</xs:schema>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
<contact xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="test.xsd">
<name> John </name>
<phone>444-121-3434</phone>
</contact>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="contact">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="phone" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="address">
<xs:complexType>
<xs:sequence>
<xs:element name="street" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package test.gaptest;
import java.io.StringReader;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamSource;
import jaxp.library.JAXPBaseTest;
import org.testng.annotations.Test;
/*
* @bug 4511326
* @summary In forwards-compatible mode the attribute isn't ignored
*/
public class Bug4511326 extends JAXPBaseTest {
private static final String XSL = "<xsl:stylesheet version='2.0' "
+ "xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>"
+ "<xsl:template a='1' match='/'>"
+ "<H2><xsl:value-of select='//author'/></H2>"
+ "<H1><xsl:value-of select='//title'/></H1>"
+ "</xsl:template>"
+ "</xsl:stylesheet>";
@Test
public void ignoreAttTest() throws TransformerConfigurationException {
/* Create a TransformFactory instance */
TransformerFactory transformerFactory = TransformerFactory.newInstance();
/* Create and init a StreamSource instance */
StreamSource source = new StreamSource(new StringReader(XSL));
transformerFactory.newTransformer(source);
}
}

View File

@ -0,0 +1,88 @@
/*
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package test.gaptest;
import static javax.xml.transform.OutputKeys.ENCODING;
import static javax.xml.transform.OutputKeys.INDENT;
import static org.testng.Assert.assertEquals;
import java.io.StringReader;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamSource;
import jaxp.library.JAXPBaseTest;
import org.testng.annotations.Test;
/*
* @bug 4512806
* @summary test transformer.setOutputProperties(null)
*/
public class Bug4512806 extends JAXPBaseTest {
@Test
public void testProperty() throws TransformerConfigurationException {
/* Create a transform factory instance */
TransformerFactory tfactory = TransformerFactory.newInstance();
/* Create a StreamSource instance */
StreamSource streamSource = new StreamSource(new StringReader(xslData));
transformer = tfactory.newTransformer(streamSource);
transformer.setOutputProperty(INDENT, "no");
transformer.setOutputProperty(ENCODING, "UTF-16");
assertEquals(printPropertyValue(INDENT), "indent=no");
assertEquals(printPropertyValue(ENCODING), "encoding=UTF-16");
transformer.setOutputProperties(null);
assertEquals(printPropertyValue(INDENT), "indent=yes");
assertEquals(printPropertyValue(ENCODING), "encoding=UTF-8");
}
private String printPropertyValue(String name) {
return name + "=" + transformer.getOutputProperty(name);
}
private Transformer transformer;
private static final String xslData = "<?xml version='1.0'?>"
+ "<xsl:stylesheet"
+ " version='1.0'"
+ " xmlns:xsl='http://www.w3.org/1999/XSL/Transform'"
+ ">\n"
+ " <xsl:output method='xml' indent='yes'"
+ " encoding='UTF-8'/>\n"
+ " <xsl:template match='/'>\n"
+ " Hello World! \n"
+ " </xsl:template>\n"
+ "</xsl:stylesheet>";
}

View File

@ -0,0 +1,61 @@
/*
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package test.gaptest;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import jaxp.library.JAXPBaseTest;
import org.testng.annotations.Test;
/*
* @bug 4515047
* @summary test transform an empty dom source
*/
public class Bug4515047 extends JAXPBaseTest {
@Test
public void testCreateTxDoc() throws TransformerException, ParserConfigurationException {
Transformer transformer = TransformerFactory.newInstance().newTransformer();
StreamResult result = new StreamResult(System.out);
DOMSource source = new DOMSource();
/* This should not throw an Illegal Argument Exception */
//Test empty DOMSource
transformer.transform(source, result);
//Test DOMSource having only an empty node
source.setNode(DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument());
transformer.transform(source, result);
}
}

View File

@ -0,0 +1,123 @@
/*
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package test.gaptest;
import static org.testng.Assert.assertTrue;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.stream.StreamResult;
import jaxp.library.JAXPBaseTest;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.XMLFilterImpl;
/*
* @bug 4515660
* @summary verify property org.xml.sax.driver is used by SAXTransformerFactory
*/
@Test(singleThreaded = true)
public class Bug4515660 extends JAXPBaseTest {
@BeforeClass
public void setSaxDrier() {
setSystemProperty("org.xml.sax.driver", ReaderStub.class.getName());
}
@AfterClass
public void clearSaxDrier() {
setSystemProperty("org.xml.sax.driver", null);
}
@Test
public void testTransformer() throws TransformerException {
String xml = "<?xml version='1.0'?><root/>";
ReaderStub.used = false;
TransformerFactory transFactory = TransformerFactory.newInstance();
Transformer transformer = transFactory.newTransformer();
InputSource in = new InputSource(new StringReader(xml));
SAXSource source = new SAXSource(in);
StreamResult result = new StreamResult(new StringWriter());
transformer.transform(source, result);
assertTrue(ReaderStub.used);
}
@Test
public void testSAXTransformerFactory() throws TransformerConfigurationException {
final String xsl = "<?xml version='1.0'?>\n" + "<xsl:stylesheet" + " xmlns:xsl='http://www.w3.org/1999/XSL/Transform'" + " version='1.0'>\n"
+ " <xsl:template match='/'>Hello World!</xsl:template>\n" + "</xsl:stylesheet>\n";
ReaderStub.used = false;
TransformerFactory transFactory = TransformerFactory.newInstance();
assertTrue(transFactory.getFeature(SAXTransformerFactory.FEATURE));
InputSource in = new InputSource(new StringReader(xsl));
SAXSource source = new SAXSource(in);
transFactory.newTransformer(source);
assertTrue(ReaderStub.used);
}
public static class ReaderStub extends XMLFilterImpl {
static boolean used = false;
public ReaderStub() throws ParserConfigurationException, SAXException {
super();
super.setParent(SAXParserFactory.newInstance().newSAXParser().getXMLReader());
used = true;
}
public void parse(InputSource input) throws SAXException, IOException {
used = true;
super.parse(input);
}
public void parse(String systemId) throws SAXException, IOException {
used = true;
super.parse(systemId);
}
}
}

View File

@ -0,0 +1,79 @@
/*
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package test.gaptest;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
import static jaxp.library.JAXPTestUtilities.USER_DIR;
import static jaxp.library.JAXPTestUtilities.compareDocumentWithGold;
import static org.testng.Assert.assertTrue;
import static test.gaptest.GapTestConst.GOLDEN_DIR;
import static test.gaptest.GapTestConst.XML_DIR;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import jaxp.library.JAXPFileBaseTest;
import org.testng.annotations.Test;
import org.xml.sax.SAXException;
/*
* @bug 4693341
* @summary test transforming to stream with external dtd
*/
public class Bug4693341 extends JAXPFileBaseTest {
@Test
public void test() throws TransformerException, ParserConfigurationException, SAXException, IOException {
Transformer transformer = TransformerFactory.newInstance().newTransformer();
String out = USER_DIR + File.separator + "Bug4693341.out";
StreamResult result = new StreamResult(new File(out));
String in = XML_DIR + "Bug4693341.xml";
String golden = GOLDEN_DIR + "Bug4693341.xml";
File file = new File(in);
StreamSource source = new StreamSource(file);
System.out.println(source.getSystemId());
Files.copy(Paths.get(XML_DIR + "Bug4693341.dtd"),
Paths.get(USER_DIR + File.separator + "Bug4693341.dtd"), REPLACE_EXISTING);
transformer.transform(source, result);
assertTrue(compareDocumentWithGold(golden, out));
}
}

View File

@ -0,0 +1,80 @@
/*
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package test.gaptest;
import static jaxp.library.JAXPTestUtilities.filenameToURL;
import static test.gaptest.GapTestConst.XML_DIR;
import java.io.IOException;
import javax.xml.XMLConstants;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import jaxp.library.JAXPFileBaseTest;
import org.testng.annotations.Test;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
/*
* @bug 4848653
* @summary Verify JAXP schemaLanguage property is ignored if setValidating(false)
*/
public class Bug4848653 extends JAXPFileBaseTest {
@Test
public void test() throws IOException, SAXException, ParserConfigurationException {
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setValidating(false);
SAXParser parser = factory.newSAXParser();
parser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaLanguage", XMLConstants.W3C_XML_SCHEMA_NS_URI);
String filename = XML_DIR + "Bug4848653.xml";
InputSource is = new InputSource(filenameToURL(filename));
XMLReader xmlReader = parser.getXMLReader();
xmlReader.setErrorHandler(new MyErrorHandler());
xmlReader.parse(is);
}
class MyErrorHandler implements ErrorHandler {
public void error(SAXParseException exception) throws SAXParseException {
throw exception;
}
public void warning(SAXParseException exception) throws SAXParseException {
throw exception;
}
public void fatalError(SAXParseException exception) throws SAXParseException {
throw exception;
}
}
}

View File

@ -0,0 +1,246 @@
/*
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package test.gaptest;
import static jaxp.library.JAXPTestUtilities.filenameToURL;
import static org.testng.Assert.assertEquals;
import static test.gaptest.GapTestConst.GOLDEN_DIR;
import static test.gaptest.GapTestConst.XML_DIR;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.stream.StreamSource;
import jaxp.library.JAXPFileBaseTest;
import org.testng.annotations.Test;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/*
* @bug 4858685 4894410
* @summary test transforming text node
*/
public class Bug4858685 extends JAXPFileBaseTest {
@Test
public void test() throws TransformerException, IOException {
String uri = XML_DIR + "certificate.xml";
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
// use URI as a StreamSource
StreamSource streamSource = new StreamSource(filenameToURL(uri));
DOMResult domResult = new DOMResult();
// StreamSource -> DOMResult
transformer.transform(streamSource, domResult);
// dump DOM in a human readable form
String gotString = DOMDump.dumpDom(domResult.getNode());
String goldenString = new String(Files.readAllBytes(Paths.get(GOLDEN_DIR + "Bug4858685.txt")));
assertEquals(gotString, goldenString);
}
/**
* DOMDump: dump a DOM to a String in human readable form. method dumpDOM()
* is static for easy calling:
*/
private static class DOMDump {
/**
* the maximum level to indent with blanks
*/
private static final int BLANKS_LEN = 64;
/**
* each level of the tree will be indented with blanks for readability
*/
private static final String BLANKS = " ";
/**
* dumpDOM will dump the DOM into a String for human readability
*
* @param domNode
* the DOM Node to dump
* @return human readabile DOM as a String
*/
public static String dumpDom(Node domNode) {
return dumpInternal(domNode, 0);
}
/**
* dumpInternal is used internaly to recursively dump DOM Nodes
*
* @param domNode
* to dump
* @param indent
* level
* @return domNode as human readable String
*/
private static String dumpInternal(Node domNode, int indent) {
String result = "";
// indent for readability
result += indentBlanks(indent);
indent += 2;
// protect against null
if (domNode == null) {
result = result + "[null]" + "\n";
return result;
}
// what to output depends on NodeType
short type = domNode.getNodeType();
switch (type) {
case Node.ATTRIBUTE_NODE: {
result += "[attribute] " + domNode.getNodeName() + "=\"" + domNode.getNodeValue() + "\"";
break;
}
case Node.CDATA_SECTION_NODE: {
result += "[cdata] " + domNode.getNodeValue();
break;
}
case Node.COMMENT_NODE: {
result += "[comment] " + domNode.getNodeValue();
break;
}
case Node.DOCUMENT_FRAGMENT_NODE: {
result += "[document fragment]";
break;
}
case Node.DOCUMENT_NODE: {
result += "[document]";
break;
}
case Node.DOCUMENT_TYPE_NODE: {
result += "[document type] " + domNode.getNodeName();
break;
}
case Node.ELEMENT_NODE: {
result += "[element] " + domNode.getNodeName();
// output all attributes for Element
if (domNode.hasAttributes()) {
NamedNodeMap attributes = domNode.getAttributes();
for (int onAttribute = 0; onAttribute < attributes.getLength(); onAttribute++) {
// seprate each attribute with a space
result += " ";
Node attribute = attributes.item(onAttribute);
String namespaceURI = attribute.getNamespaceURI();
String prefix = attribute.getPrefix();
String localName = attribute.getLocalName();
String name = attribute.getNodeName();
String value = attribute.getNodeValue();
// using Namespaces?
if (namespaceURI != null) {
result += "{" + namespaceURI + "}";
}
if (prefix != null) {
result += prefix + ":";
}
// name="value"
result += attribute.getNodeName() + "=\"" + attribute.getNodeValue() + "\"";
}
}
break;
}
case Node.ENTITY_NODE: {
result += "[entity] " + domNode.getNodeName();
break;
}
case Node.ENTITY_REFERENCE_NODE: {
result += "[entity reference] " + domNode.getNodeName();
break;
}
case Node.NOTATION_NODE: {
result += "[notation] " + domNode.getNodeName();
break;
}
case Node.PROCESSING_INSTRUCTION_NODE: {
result += "[pi] target=\"" + domNode.getNodeName() + "\" content=\"" + domNode.getNodeValue() + "\"";
break;
}
case Node.TEXT_NODE: {
result += "[text] " + domNode.getNodeValue();
break;
}
default: {
result += "[unknown]";
break;
}
}
// humans read in lines
result += "\n";
// process children
NodeList children = domNode.getChildNodes();
for (int onChild = 0; onChild < children.getLength(); onChild++) {
Node child = children.item(onChild);
result += dumpInternal(child, indent);
}
// return human readable DOM as String
return result;
}
/**
* indentBlanks will return a String of indent blanks
*
* @param indent
* level
* @return String of blanks
*/
private static String indentBlanks(int indent) {
if (indent == 0) {
return "";
}
if (indent > BLANKS_LEN) {
return BLANKS;
}
return BLANKS.substring(0, indent + 1);
}
}
}

View File

@ -0,0 +1,39 @@
<!ELEMENT SupplierOrder (OrderId, OrderDate, ShippingAddress, LineItems)>
<!ELEMENT OrderId (#PCDATA)>
<!ELEMENT OrderDate (#PCDATA)>
<!ELEMENT ShippingAddress (FirstName, LastName, Street, City, State, Country, ZipCode, Email, Phone)>
<!ELEMENT FirstName (#PCDATA)>
<!ELEMENT LastName (#PCDATA)>
<!ELEMENT Street (#PCDATA)>
<!ELEMENT City (#PCDATA)>
<!ELEMENT State (#PCDATA)>
<!ELEMENT Country (#PCDATA)>
<!ELEMENT ZipCode (#PCDATA)>
<!ELEMENT Email (#PCDATA)>
<!ELEMENT Phone (#PCDATA)>
<!ELEMENT LineItems (LineItem+)>
<!ELEMENT LineItem EMPTY>
<!ATTLIST LineItem
categoryId CDATA #REQUIRED
productId CDATA #REQUIRED
itemId CDATA #REQUIRED
lineNo CDATA #REQUIRED
quantity CDATA #REQUIRED
unitPrice CDATA #REQUIRED
>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE SupplierOrder SYSTEM "Bug4693341.dtd" >
<SupplierOrder>
<OrderId>10016</OrderId>
<OrderDate>Wed May 29 12:45:00 PDT 2002</OrderDate>
<ShippingAddress>
<FirstName>ABC</FirstName>
<LastName>XYZ</LastName>
<Street>1234 Anywhere Street</Street>
<City>Palo Alto</City>
<State>California</State>
<Country>USA</Country>
<ZipCode>94303</ZipCode>
<Email>NULL</Email>
<Phone>NULL</Phone>
</ShippingAddress>
<LineItems>
<LineItem categoryId="BIRDS" itemId="EST-18" lineNo="0" productId="AV-CB-01" quantity="1" unitPrice="193.5"/>
</LineItems>
</SupplierOrder>

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns0="http://headertest.org/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<env:Body>
<ds:X509Certificate xmlns="" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
MIIDVjCCAxICBD6kKrMwCwYHKoZIzjgEAwUAMIGPMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0Ex
FDASBgNVBAcTC1NhbnRhIENsYXJhMR8wHQYDVQQKExZTdW4gTWljcm9zeXN0ZW1zLCBJbmMuMR4w
HAYDVQQLExVKYXZhIGFuZCBYTUwgU29mdHdhcmUxHDAaBgNVBAMTE0pXUy1TZWN1cml0eSBDbGll
bnQwHhcNMDMwNDIxMTczMDI3WhcNMDMwNzIwMTczMDI3WjCBjzELMAkGA1UEBhMCVVMxCzAJBgNV
BAgTAkNBMRQwEgYDVQQHEwtTYW50YSBDbGFyYTEfMB0GA1UEChMWU3VuIE1pY3Jvc3lzdGVtcywg
SW5jLjEeMBwGA1UECxMVSmF2YSBhbmQgWE1MIFNvZnR3YXJlMRwwGgYDVQQDExNKV1MtU2VjdXJp
dHkgQ2xpZW50MIIBtzCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9E
AMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up
1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUj
C8yykrmCouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZ
T+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7
zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYQAAoGAV3R+bUfh+u0yaPBV75umKvFB
ucv37ETDak889b7k72kZdGoHz3oDmp69tiNDg5r7IvKtjHGbZ6C3Nv0ycNR7Sed1QPOF4nn/tgUl
j+BvtVW3iiIRgBJ82KP+28QtwPkkxSp7n5HG0v7bE29E/juLduuhKBQTaaCvajuCFxiBrmAwCwYH
KoZIzjgEAwUAAzEAMC4CFQCCuDNmMKjgY6MV1SmAcCdnhuT6VwIVAJBOiPDnDWp2WlKAERF6nOAf
vKz9
</ds:X509Certificate>
</env:Body>
</env:Envelope>

View File

@ -0,0 +1,39 @@
<!ELEMENT SupplierOrder (OrderId, OrderDate, ShippingAddress, LineItems)>
<!ELEMENT OrderId (#PCDATA)>
<!ELEMENT OrderDate (#PCDATA)>
<!ELEMENT ShippingAddress (FirstName, LastName, Street, City, State, Country, ZipCode, Email, Phone)>
<!ELEMENT FirstName (#PCDATA)>
<!ELEMENT LastName (#PCDATA)>
<!ELEMENT Street (#PCDATA)>
<!ELEMENT City (#PCDATA)>
<!ELEMENT State (#PCDATA)>
<!ELEMENT Country (#PCDATA)>
<!ELEMENT ZipCode (#PCDATA)>
<!ELEMENT Email (#PCDATA)>
<!ELEMENT Phone (#PCDATA)>
<!ELEMENT LineItems (LineItem+)>
<!ELEMENT LineItem EMPTY>
<!ATTLIST LineItem
categoryId CDATA #REQUIRED
productId CDATA #REQUIRED
itemId CDATA #REQUIRED
lineNo CDATA #REQUIRED
quantity CDATA #REQUIRED
unitPrice CDATA #REQUIRED
>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE SupplierOrder SYSTEM "Bug4693341.dtd" >
<SupplierOrder>
<OrderId>10016</OrderId>
<OrderDate>Wed May 29 12:45:00 PDT 2002</OrderDate>
<ShippingAddress>
<FirstName>ABC</FirstName>
<LastName>XYZ</LastName>
<Street>1234 Anywhere Street</Street>
<City>Palo Alto</City>
<State>California</State>
<Country>USA</Country>
<ZipCode>94303</ZipCode>
<Email>NULL</Email>
<Phone>NULL</Phone>
</ShippingAddress>
<LineItems>
<LineItem categoryId="BIRDS" itemId="EST-18" lineNo="0" productId="AV-CB-01" quantity="1" unitPrice="193.5"/>
</LineItems>
</SupplierOrder>

View File

@ -0,0 +1,30 @@
[document]
[element] env:Envelope {http://www.w3.org/2000/xmlns/}xmlns:xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/" {http://www.w3.org/2000/xmlns/}xmlns:xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" {http://www.w3.org/2000/xmlns/}xmlns:xmlns:ns0="http://headertest.org/" {http://www.w3.org/2000/xmlns/}xmlns:xmlns:xsd="http://www.w3.org/2001/XMLSchema" {http://www.w3.org/2000/xmlns/}xmlns:xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
[text]
[element] env:Body
[text]
[element] ds:X509Certificate xmlns="" {http://www.w3.org/2000/xmlns/}xmlns:xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
[text]
MIIDVjCCAxICBD6kKrMwCwYHKoZIzjgEAwUAMIGPMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0Ex
FDASBgNVBAcTC1NhbnRhIENsYXJhMR8wHQYDVQQKExZTdW4gTWljcm9zeXN0ZW1zLCBJbmMuMR4w
HAYDVQQLExVKYXZhIGFuZCBYTUwgU29mdHdhcmUxHDAaBgNVBAMTE0pXUy1TZWN1cml0eSBDbGll
bnQwHhcNMDMwNDIxMTczMDI3WhcNMDMwNzIwMTczMDI3WjCBjzELMAkGA1UEBhMCVVMxCzAJBgNV
BAgTAkNBMRQwEgYDVQQHEwtTYW50YSBDbGFyYTEfMB0GA1UEChMWU3VuIE1pY3Jvc3lzdGVtcywg
SW5jLjEeMBwGA1UECxMVSmF2YSBhbmQgWE1MIFNvZnR3YXJlMRwwGgYDVQQDExNKV1MtU2VjdXJp
dHkgQ2xpZW50MIIBtzCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9E
AMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up
1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUj
C8yykrmCouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZ
T+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7
zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYQAAoGAV3R+bUfh+u0yaPBV75umKvFB
ucv37ETDak889b7k72kZdGoHz3oDmp69tiNDg5r7IvKtjHGbZ6C3Nv0ycNR7Sed1QPOF4nn/tgUl
j+BvtVW3iiIRgBJ82KP+28QtwPkkxSp7n5HG0v7bE29E/juLduuhKBQTaaCvajuCFxiBrmAwCwYH
KoZIzjgEAwUAAzEAMC4CFQCCuDNmMKjgY6MV1SmAcCdnhuT6VwIVAJBOiPDnDWp2WlKAERF6nOAf
vKz9
[text]
[text]

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.xml.validation.ptests;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXParseException;
class MyErrorHandler implements ErrorHandler {
public void error(SAXParseException exception) throws SAXParseException {
throw exception;
}
public void warning(SAXParseException exception) throws SAXParseException {
throw exception;
}
public void fatalError(SAXParseException exception) throws SAXParseException {
throw exception;
}
}

View File

@ -0,0 +1,43 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.xml.validation.ptests;
import static jaxp.library.JAXPTestUtilities.FILE_SEP;
import static jaxp.library.JAXPTestUtilities.getPathByClassName;
/**
* This class defines the path constant
*/
public class ValidationTestConst {
/**
* XML source file directory.
*/
public static final String XML_DIR = getPathByClassName(ValidationTestConst.class,
".." + FILE_SEP + "xmlfiles");
/**
* Golden validation files directory.
*/
public static final String GOLDEN_DIR = getPathByClassName(ValidationTestConst.class,
".." + FILE_SEP + "xmlfiles" + FILE_SEP + "out");
}

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package test.gaptest;
import static jaxp.library.JAXPTestUtilities.FILE_SEP;
import static jaxp.library.JAXPTestUtilities.getPathByClassName;
/**
* This class defines the path constant
*/
public class GapTestConst {
/**
* XML source file directory.
*/
public static final String XML_DIR = getPathByClassName(GapTestConst.class, "xmlfiles");
/**
* Golden validation files directory.
*/
public static final String GOLDEN_DIR = getPathByClassName(GapTestConst.class, "xmlfiles" + FILE_SEP + "out");
}

View File

@ -0,0 +1,190 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.xml.xpath;
import java.io.File;
import javax.xml.xpath.*;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import org.testng.annotations.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
/*
* @bug 8054196
* @summary Test for the project XPath: support any type. This test covers the new
* evaluateExpression methods of XPath, as well as XPathNodes and XPathEvaluationResult.
*/
public class XPathAnyTypeTest extends XPathTestBase {
/*
Test for resolveFunction(QName functionName,int arity); evaluate throws
NPE if functionName is null.
*/
@Test(dataProvider = "xpath", expectedExceptions = NullPointerException.class)
public void testCheckXPathFunctionResolver02(XPath xpath) throws XPathExpressionException {
xpath.setXPathFunctionResolver((functionName, arity) -> null);
assertEquals(xpath.evaluate(null, "5"), "2");
}
/*
Check that NPE is thrown when expression is null.
*/
@Test(dataProvider = "xpath", expectedExceptions = NullPointerException.class)
public void test01(XPath xpath) throws XPathExpressionException {
double result = xpath.evaluateExpression(null, (Object) null, Double.class);
}
/*
Check that NPE is thrown when the class type is null.
*/
@Test(dataProvider = "xpath", expectedExceptions = NullPointerException.class)
public void test02(XPath xpath) throws XPathExpressionException {
double result = xpath.evaluateExpression("1+1", (Object) null, null);
}
/*
Parameter item can be null when the expression does not depends on the
context.
*/
@Test(dataProvider = "xpath")
public void test03(XPath xpath) throws XPathExpressionException {
int result = xpath.evaluateExpression("1+1", (Object) null, Integer.class);
assertTrue(result == 2);
}
/*
* Test return type: boolean.
*/
@Test(dataProvider = "document")
public void test04(XPath xpath, Document doc) throws XPathExpressionException {
boolean result1 = xpath.evaluateExpression("boolean(/Customers/Customer[@id=3])", doc, Boolean.class);
assertTrue(result1);
}
/*
* Test return type: numeric. Subtypes supported: Double, Integer and Long
*/
@Test(dataProvider = "document")
public void test05(XPath xpath, Document doc) throws XPathExpressionException {
double result1 = xpath.evaluateExpression("count(/Customers/Customer)", doc, Double.class);
assertTrue(result1 == 3.0);
int result2 = xpath.evaluateExpression("count(/Customers/Customer)", doc, Integer.class);
assertTrue(result2 == 3);
long result3 = xpath.evaluateExpression("count(/Customers/Customer)", doc, Long.class);
assertTrue(result3 == 3);
}
/*
* Test return type: numeric. Of the subtypes of Number, only Double,
* Integer and Long are required.
*/
@Test(dataProvider = "invalidNumericTypes", expectedExceptions = IllegalArgumentException.class)
public void test06(XPath xpath, Class<Number> type) throws XPathExpressionException {
xpath.evaluateExpression("1+1", (Object) null, type);
}
/*
* Test return type: String.
*/
@Test(dataProvider = "document")
public void test07(XPath xpath, Document doc) throws XPathExpressionException {
String result1 = xpath.evaluateExpression("string(/Customers/Customer[@id=3]/Phone/text())", doc, String.class);
assertTrue(result1.equals("3333333333"));
}
/*
* Test return type: NodeSet.
*/
@Test(dataProvider = "document")
public void test08(XPath xpath, Document doc) throws XPathExpressionException {
XPathNodes nodes = xpath.evaluateExpression("/Customers/Customer", doc, XPathNodes.class);
assertTrue(nodes.size() == 3);
for (Node n : nodes) {
assertEquals(n.getLocalName(), "Customer");
}
}
/*
* Test return type: Node.
*/
@Test(dataProvider = "document")
public void test09(XPath xpath, Document doc) throws XPathExpressionException {
Node n = xpath.evaluateExpression("/Customers/Customer[@id=3]", doc, Node.class);
assertEquals(n.getLocalName(), "Customer");
}
/*
* Test return type: Unsupported type.
*/
@Test(dataProvider = "document", expectedExceptions = IllegalArgumentException.class)
public void test10(XPath xpath, Document doc) throws XPathExpressionException {
File n = xpath.evaluateExpression("/Customers/Customer[@id=3]", doc, File.class);
}
/*
* Test return type: Any::Boolean.
*/
@Test(dataProvider = "document")
public void test11(XPath xpath, Document doc) throws XPathExpressionException {
XPathEvaluationResult<?> result = xpath.evaluateExpression("boolean(/Customers/Customer[@id=3])", doc);
verifyResult(result, true);
}
/*
* Test return type: Any::Number.
*/
@Test(dataProvider = "document")
public void test12(XPath xpath, Document doc) throws XPathExpressionException {
XPathEvaluationResult<?> result = xpath.evaluateExpression("count(/Customers/Customer)", doc);
verifyResult(result, 3.0);
}
/*
* Test return type: Any::String.
*/
@Test(dataProvider = "document")
public void test13(XPath xpath, Document doc) throws XPathExpressionException {
XPathEvaluationResult<?> result = xpath.evaluateExpression(
"string(/Customers/Customer[@id=3]/Phone/text())", doc, XPathEvaluationResult.class);
verifyResult(result, "3333333333");
}
/*
* Test return type: Any::Nodeset.
*/
@Test(dataProvider = "document")
public void test14(XPath xpath, Document doc) throws XPathExpressionException {
XPathEvaluationResult<?> result = xpath.evaluateExpression("/Customers/Customer", doc);
verifyResult(result, "Customer");
}
/*
* Test return type: Any::Node.
*/
@Test(dataProvider = "document")
public void test15(XPath xpath, Document doc) throws XPathExpressionException {
XPathEvaluationResult<?> result = xpath.evaluateExpression("/Customers/Customer[@id=3]", doc);
verifyResult(result, "Customer");
}
}

View File

@ -0,0 +1,176 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.xml.xpath;
import java.io.File;
import javax.xml.xpath.*;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import org.testng.annotations.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
/*
* @bug 8054196
* @summary Test for the project XPath: support any type. This test covers the new
* evaluateExpression methods of XPathExpression.
*/
public class XPathExpAnyTypeTest extends XPathTestBase {
/*
* Check that NPE is thrown when the class type is null.
*/
@Test(dataProvider = "xpath", expectedExceptions = NullPointerException.class)
public void test02(XPath xpath) throws XPathExpressionException {
XPathExpression exp = xpath.compile("1+1");
double result = exp.evaluateExpression((Object)null, null);
}
/*
* Parameter item can be null when the expression does not depends on the
* context.
*/
@Test(dataProvider = "xpath")
public void test03(XPath xpath) throws XPathExpressionException {
XPathExpression exp = xpath.compile("1+1");
int result = exp.evaluateExpression((Object)null, Integer.class);
assertTrue(result == 2);
}
/*
* Test return type: boolean.
*/
@Test(dataProvider = "document")
public void test04(XPath xpath, Document doc) throws XPathExpressionException {
XPathExpression exp = xpath.compile("boolean(/Customers/Customer[@id=3])");
boolean result1 = exp.evaluateExpression(doc, Boolean.class);
assertTrue(result1);
}
/*
* Test return type: numeric.
*/
@Test(dataProvider = "document")
public void test05(XPath xpath, Document doc) throws XPathExpressionException {
XPathExpression exp = xpath.compile("count(/Customers/Customer)");
double result1 = exp.evaluateExpression(doc, Double.class);
assertTrue(result1 == 3.0);
int result2 = exp.evaluateExpression(doc, Integer.class);
assertTrue(result2 == 3);
}
/*
* Test return type: String.
*/
@Test(dataProvider = "document")
public void test06(XPath xpath, Document doc) throws XPathExpressionException {
XPathExpression exp = xpath.compile("string(/Customers/Customer[@id=3]/Phone/text())");
String result1 = exp.evaluateExpression(doc, String.class);
assertTrue(result1.equals("3333333333"));
}
/*
* Test return type: NodeSet.
*/
@Test(dataProvider = "document")
public void test07(XPath xpath, Document doc) throws XPathExpressionException {
XPathExpression exp = xpath.compile("/Customers/Customer");
XPathNodes nodes = exp.evaluateExpression(doc, XPathNodes.class);
assertTrue(nodes.size() == 3);
for (Node n : nodes) {
assertEquals(n.getLocalName(), "Customer");
}
}
/*
* Test return type: Node.
*/
@Test(dataProvider = "document")
public void test08(XPath xpath, Document doc) throws XPathExpressionException {
XPathExpression exp = xpath.compile("/Customers/Customer[@id=3]");
Node n = exp.evaluateExpression(doc, Node.class);
assertEquals(n.getLocalName(), "Customer");
}
/*
* Test return type: Unsupported type.
*/
@Test(dataProvider = "document", expectedExceptions = IllegalArgumentException.class)
public void test09(XPath xpath, Document doc) throws XPathExpressionException {
XPathExpression exp = xpath.compile("/Customers/Customer[@id=3]");
File n = exp.evaluateExpression(doc, File.class);
}
/*
* Test return type: Any::Boolean.
*/
@Test(dataProvider = "document")
public void test10(XPath xpath, Document doc) throws XPathExpressionException {
XPathExpression exp = xpath.compile("boolean(/Customers/Customer[@id=3])");
XPathEvaluationResult<?> result = exp.evaluateExpression(doc);
verifyResult(result, true);
}
/*
* Test return type: Any::Number.
*/
@Test(dataProvider = "document")
public void test11(XPath xpath, Document doc) throws XPathExpressionException {
XPathExpression exp = xpath.compile("count(/Customers/Customer)");
XPathEvaluationResult<?> result = exp.evaluateExpression(doc);
verifyResult(result, 3.0);
}
/*
* Test return type: Any::String.
*/
@Test(dataProvider = "document")
public void test12(XPath xpath, Document doc) throws XPathExpressionException {
XPathExpression exp = xpath.compile("string(/Customers/Customer[@id=3]/Phone/text())");
XPathEvaluationResult<?> result = exp.evaluateExpression(doc, XPathEvaluationResult.class);
verifyResult(result, "3333333333");
}
/*
* Test return type: Any::Nodeset.
*/
@Test(dataProvider = "document")
public void test13(XPath xpath, Document doc) throws XPathExpressionException {
XPathExpression exp = xpath.compile("/Customers/Customer");
XPathEvaluationResult<?> result = exp.evaluateExpression(doc);
verifyResult(result, "Customer");
}
/*
* Test return type: Any::Node.
*/
@Test(dataProvider = "document")
public void test14(XPath xpath, Document doc) throws XPathExpressionException {
XPathExpression exp = xpath.compile("/Customers/Customer[@id=3]");
XPathEvaluationResult<?> result = exp.evaluateExpression(doc);
verifyResult(result, "Customer");
}
}

View File

@ -0,0 +1,140 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.xml.xpath;
import java.io.ByteArrayInputStream;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import javax.xml.parsers.DocumentBuilderFactory;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import org.testng.annotations.DataProvider;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
/*
* Base class for XPath test
*/
class XPathTestBase {
static final String rawXML
= "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
+ "<Customers>"
+ " <Customer id=\"1\">"
+ " <Name>name1</Name>"
+ " <Phone>1111111111</Phone>"
+ " <Email>123@xyz.com</Email>"
+ " <Address>"
+ " <Street>1111 111st ave</Street>"
+ " <City>The City</City>"
+ " <State>The State</State>"
+ " </Address>"
+ " </Customer>"
+ " <Customer id=\"2\">"
+ " <Name>name1</Name>"
+ " <Phone>2222222222</Phone>"
+ " <Email>123@xyz.com</Email>"
+ " <Address>"
+ " <Street>2222 222nd ave</Street>"
+ " <City>The City</City>"
+ " <State>The State</State>"
+ " </Address>"
+ " </Customer>"
+ " <Customer id=\"3\">"
+ " <Name>name1</Name>"
+ " <Phone>3333333333</Phone>"
+ " <Email>123@xyz.com</Email>"
+ " <Address>"
+ " <Street>3333 333rd ave</Street>"
+ " <City>The City</City>"
+ " <State>The State</State>"
+ " </Address>"
+ " </Customer>"
+ "</Customers>";
void verifyResult(XPathEvaluationResult<?> result, Object expected) {
switch (result.type()) {
case BOOLEAN:
assertTrue(((Boolean) result.value()).equals(expected));
return;
case NUMBER:
assertTrue(((Double) result.value()).equals(expected));
return;
case STRING:
assertTrue(((String) result.value()).equals(expected));
return;
case NODESET:
XPathNodes nodes = (XPathNodes) result.value();
for (Node n : nodes) {
assertEquals(n.getLocalName(), expected);
}
return;
case NODE:
assertTrue(((Node) result.value()).getLocalName().equals(expected));
return;
}
assertFalse(true, "Unsupported type");
}
/*
* DataProvider: XPath object
*/
@DataProvider(name = "xpath")
Object[][] getXPath() {
return new Object[][]{{XPathFactory.newInstance().newXPath()}};
}
/*
* DataProvider: Numeric types not supported
*/
@DataProvider(name = "invalidNumericTypes")
Object[][] getInvalidNumericTypes() {
XPath xpath = XPathFactory.newInstance().newXPath();
return new Object[][]{{xpath, AtomicInteger.class},
{xpath, AtomicInteger.class},
{xpath, AtomicLong.class},
{xpath, BigDecimal.class},
{xpath, BigInteger.class},
{xpath, Byte.class},
{xpath, Float.class},
{xpath, Short.class}
};
}
/*
* DataProvider: XPath and Document objects
*/
@DataProvider(name = "document")
Object[][] getDocument() throws Exception {
DocumentBuilderFactory dBF = DocumentBuilderFactory.newInstance();
dBF.setValidating(false);
dBF.setNamespaceAware(true);
Document doc = dBF.newDocumentBuilder().parse(
new ByteArrayInputStream(rawXML.getBytes("UTF-8")));
return new Object[][]{{XPathFactory.newInstance().newXPath(), doc}};
}
}