Merge
This commit is contained in:
commit
5b196d9525
1
.hgtags
1
.hgtags
@ -290,3 +290,4 @@ abbfccd659b91a7bb815d5e36fed635dcdd40f31 jdk9-b44
|
|||||||
bfc24ae2b900187585079bb11e66e459d1e525fe jdk9-b45
|
bfc24ae2b900187585079bb11e66e459d1e525fe jdk9-b45
|
||||||
722378bc599e38d9a1dd484de30f10dfd7b21438 jdk9-b46
|
722378bc599e38d9a1dd484de30f10dfd7b21438 jdk9-b46
|
||||||
8327024a99559982b848e9c2191da9c0bf8838fd jdk9-b47
|
8327024a99559982b848e9c2191da9c0bf8838fd jdk9-b47
|
||||||
|
b2f9702efbe95527ea3a991474fda23987ff1c5c jdk9-b48
|
||||||
|
@ -290,3 +290,4 @@ f7c11da0b0481d49cc7a65a453336c108191e821 jdk9-b42
|
|||||||
3dd628fde2086218d548841022ee8436b6b88185 jdk9-b45
|
3dd628fde2086218d548841022ee8436b6b88185 jdk9-b45
|
||||||
12f1e276447bcc81516e85367d53e4f08897049d jdk9-b46
|
12f1e276447bcc81516e85367d53e4f08897049d jdk9-b46
|
||||||
b6cca3e6175a69f39e5799b7349ddb0176630291 jdk9-b47
|
b6cca3e6175a69f39e5799b7349ddb0176630291 jdk9-b47
|
||||||
|
0064e246d83f6f9fc245c19b6d05041ecaf4b6d4 jdk9-b48
|
||||||
|
@ -987,3 +987,26 @@ AC_DEFUN_ONCE([BASIC_TEST_USABILITY_ISSUES],
|
|||||||
IS_RECONFIGURE=no
|
IS_RECONFIGURE=no
|
||||||
fi
|
fi
|
||||||
])
|
])
|
||||||
|
|
||||||
|
# Check for support for specific options in bash
|
||||||
|
AC_DEFUN_ONCE([BASIC_CHECK_BASH_OPTIONS],
|
||||||
|
[
|
||||||
|
# Test if bash supports pipefail.
|
||||||
|
AC_MSG_CHECKING([if bash supports pipefail])
|
||||||
|
if ${BASH} -c 'set -o pipefail'; then
|
||||||
|
BASH_ARGS="$BASH_ARGS -o pipefail"
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([if bash supports errexit (-e)])
|
||||||
|
if ${BASH} -e -c 'true'; then
|
||||||
|
BASH_ARGS="$BASH_ARGS -e"
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_SUBST(BASH_ARGS)
|
||||||
|
])
|
||||||
|
@ -46,8 +46,12 @@ endif
|
|||||||
BOOT_JDK := $(JDK_IMAGE_DIR)
|
BOOT_JDK := $(JDK_IMAGE_DIR)
|
||||||
|
|
||||||
# The bootcycle build has a different output directory
|
# The bootcycle build has a different output directory
|
||||||
BUILD_OUTPUT:=@BUILD_OUTPUT@/bootcycle-build
|
OLD_BUILD_OUTPUT:=@BUILD_OUTPUT@
|
||||||
SJAVAC_SERVER_DIR:=$(subst @BUILD_OUTPUT@,$(BUILD_OUTPUT),$(SJAVAC_SERVER_DIR))
|
BUILD_OUTPUT:=$(OLD_BUILD_OUTPUT)/bootcycle-build
|
||||||
|
# The HOTSPOT_DIST dir is not defined relative to BUILD_OUTPUT in spec.gmk. Must not
|
||||||
|
# use space in this patsubst to avoid leading space in HOTSPOT_DIST.
|
||||||
|
HOTSPOT_DIST:=$(patsubst $(OLD_BUILD_OUTPUT)%,$(BUILD_OUTPUT)%,$(HOTSPOT_DIST))
|
||||||
|
SJAVAC_SERVER_DIR:=$(patsubst $(OLD_BUILD_OUTPUT)%, $(BUILD_OUTPUT)%, $(SJAVAC_SERVER_DIR))
|
||||||
|
|
||||||
JAVA_CMD:=$(BOOT_JDK)/bin/java
|
JAVA_CMD:=$(BOOT_JDK)/bin/java
|
||||||
JAVAC_CMD:=$(BOOT_JDK)/bin/javac
|
JAVAC_CMD:=$(BOOT_JDK)/bin/javac
|
||||||
|
@ -113,6 +113,7 @@ HELP_SETUP_DEPENDENCY_HELP
|
|||||||
|
|
||||||
# Setup tools that requires more complex handling, or that is not needed by the configure script.
|
# Setup tools that requires more complex handling, or that is not needed by the configure script.
|
||||||
BASIC_SETUP_COMPLEX_TOOLS
|
BASIC_SETUP_COMPLEX_TOOLS
|
||||||
|
BASIC_CHECK_BASH_OPTIONS
|
||||||
|
|
||||||
# Check if pkg-config is available.
|
# Check if pkg-config is available.
|
||||||
PKG_PROG_PKG_CONFIG
|
PKG_PROG_PKG_CONFIG
|
||||||
|
@ -853,6 +853,7 @@ OS_VERSION_MICRO
|
|||||||
OS_VERSION_MINOR
|
OS_VERSION_MINOR
|
||||||
OS_VERSION_MAJOR
|
OS_VERSION_MAJOR
|
||||||
PKG_CONFIG
|
PKG_CONFIG
|
||||||
|
BASH_ARGS
|
||||||
CODESIGN
|
CODESIGN
|
||||||
XATTR
|
XATTR
|
||||||
DSYMUTIL
|
DSYMUTIL
|
||||||
@ -3522,6 +3523,9 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Check for support for specific options in bash
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
|
# Copyright (c) 2011, 2012, 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.
|
||||||
@ -4329,7 +4333,7 @@ TOOLCHAIN_DESCRIPTION_xlc="IBM XL C/C++"
|
|||||||
#CUSTOM_AUTOCONF_INCLUDE
|
#CUSTOM_AUTOCONF_INCLUDE
|
||||||
|
|
||||||
# Do not change or remove the following line, it is needed for consistency checks:
|
# Do not change or remove the following line, it is needed for consistency checks:
|
||||||
DATE_WHEN_GENERATED=1420811523
|
DATE_WHEN_GENERATED=1421247827
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
#
|
#
|
||||||
@ -19609,6 +19613,32 @@ $as_echo "yes" >&6; }
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Test if bash supports pipefail.
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if bash supports pipefail" >&5
|
||||||
|
$as_echo_n "checking if bash supports pipefail... " >&6; }
|
||||||
|
if ${BASH} -c 'set -o pipefail'; then
|
||||||
|
BASH_ARGS="$BASH_ARGS -o pipefail"
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||||
|
$as_echo "yes" >&6; }
|
||||||
|
else
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||||
|
$as_echo "no" >&6; }
|
||||||
|
fi
|
||||||
|
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if bash supports errexit (-e)" >&5
|
||||||
|
$as_echo_n "checking if bash supports errexit (-e)... " >&6; }
|
||||||
|
if ${BASH} -e -c 'true'; then
|
||||||
|
BASH_ARGS="$BASH_ARGS -e"
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||||
|
$as_echo "yes" >&6; }
|
||||||
|
else
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||||
|
$as_echo "no" >&6; }
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Check if pkg-config is available.
|
# Check if pkg-config is available.
|
||||||
|
|
||||||
|
|
||||||
@ -27408,8 +27438,8 @@ $as_echo "$as_me: Trying to extract Visual Studio environment variables" >&6;}
|
|||||||
# The trailing space for everyone except PATH is no typo, but is needed due
|
# The trailing space for everyone except PATH is no typo, but is needed due
|
||||||
# to trailing \ in the Windows paths. These will be stripped later.
|
# to trailing \ in the Windows paths. These will be stripped later.
|
||||||
$ECHO "$WINPATH_BASH -c 'echo VS_PATH="'\"$PATH\" > set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE
|
$ECHO "$WINPATH_BASH -c 'echo VS_PATH="'\"$PATH\" > set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE
|
||||||
$ECHO "$WINPATH_BASH -c 'echo VS_INCLUDE="'\"$INCLUDE\;$include \" >> set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE
|
$ECHO "$WINPATH_BASH -c 'echo VS_INCLUDE="'\"$INCLUDE \" >> set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE
|
||||||
$ECHO "$WINPATH_BASH -c 'echo VS_LIB="'\"$LIB\;$lib \" >> set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE
|
$ECHO "$WINPATH_BASH -c 'echo VS_LIB="'\"$LIB \" >> set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE
|
||||||
$ECHO "$WINPATH_BASH -c 'echo VCINSTALLDIR="'\"$VCINSTALLDIR \" >> set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE
|
$ECHO "$WINPATH_BASH -c 'echo VCINSTALLDIR="'\"$VCINSTALLDIR \" >> set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE
|
||||||
$ECHO "$WINPATH_BASH -c 'echo WindowsSdkDir="'\"$WindowsSdkDir \" >> set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE
|
$ECHO "$WINPATH_BASH -c 'echo WindowsSdkDir="'\"$WindowsSdkDir \" >> set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE
|
||||||
$ECHO "$WINPATH_BASH -c 'echo WINDOWSSDKDIR="'\"$WINDOWSSDKDIR \" >> set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE
|
$ECHO "$WINPATH_BASH -c 'echo WINDOWSSDKDIR="'\"$WINDOWSSDKDIR \" >> set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE
|
||||||
|
@ -78,6 +78,11 @@ endif
|
|||||||
OUTPUT_SYNC_SUPPORTED:=@OUTPUT_SYNC_SUPPORTED@
|
OUTPUT_SYNC_SUPPORTED:=@OUTPUT_SYNC_SUPPORTED@
|
||||||
OUTPUT_SYNC:=@OUTPUT_SYNC@
|
OUTPUT_SYNC:=@OUTPUT_SYNC@
|
||||||
|
|
||||||
|
# Override the shell with bash
|
||||||
|
BASH:=@BASH@
|
||||||
|
BASH_ARGS:=@BASH_ARGS@
|
||||||
|
SHELL:=$(BASH) $(BASH_ARGS)
|
||||||
|
|
||||||
# The "human readable" name of this configuration
|
# The "human readable" name of this configuration
|
||||||
CONF_NAME:=@CONF_NAME@
|
CONF_NAME:=@CONF_NAME@
|
||||||
|
|
||||||
@ -243,7 +248,7 @@ MAKESUPPORT_OUTPUTDIR=$(BUILD_OUTPUT)/makesupport
|
|||||||
HOTSPOT_OUTPUTDIR=$(BUILD_OUTPUT)/hotspot
|
HOTSPOT_OUTPUTDIR=$(BUILD_OUTPUT)/hotspot
|
||||||
JDK_OUTPUTDIR=$(BUILD_OUTPUT)/jdk
|
JDK_OUTPUTDIR=$(BUILD_OUTPUT)/jdk
|
||||||
IMAGES_OUTPUTDIR=$(BUILD_OUTPUT)/images
|
IMAGES_OUTPUTDIR=$(BUILD_OUTPUT)/images
|
||||||
TESTMAKE_OUTPUTDIR=$(BUILD_OUTPUT)/testmake
|
TESTMAKE_OUTPUTDIR=$(BUILD_OUTPUT)/test-make
|
||||||
MAKESUPPORT_OUTPUTDIR=$(BUILD_OUTPUT)/make-support
|
MAKESUPPORT_OUTPUTDIR=$(BUILD_OUTPUT)/make-support
|
||||||
|
|
||||||
HOTSPOT_DIST=@HOTSPOT_DIST@
|
HOTSPOT_DIST=@HOTSPOT_DIST@
|
||||||
@ -495,7 +500,6 @@ endif
|
|||||||
# Tools adhering to a minimal and common standard of posix compliance.
|
# Tools adhering to a minimal and common standard of posix compliance.
|
||||||
AWK:=@AWK@
|
AWK:=@AWK@
|
||||||
BASENAME:=@BASENAME@
|
BASENAME:=@BASENAME@
|
||||||
BASH:=@BASH@
|
|
||||||
CAT:=@CAT@
|
CAT:=@CAT@
|
||||||
CCACHE:=@CCACHE@
|
CCACHE:=@CCACHE@
|
||||||
# CD is going away, but remains to cater for legacy makefiles.
|
# CD is going away, but remains to cater for legacy makefiles.
|
||||||
|
@ -290,3 +290,4 @@ e27c725d6c9d155667b35255f442d4ceb8c3c084 jdk9-b40
|
|||||||
9e3f2bed80c0e5a84a256ce41f1d10c5ade48466 jdk9-b45
|
9e3f2bed80c0e5a84a256ce41f1d10c5ade48466 jdk9-b45
|
||||||
326f2068b4a4c05e2fa27d6acf93eba7b54b090d jdk9-b46
|
326f2068b4a4c05e2fa27d6acf93eba7b54b090d jdk9-b46
|
||||||
ee8447ca632e1d39180b4767c749db101bff7314 jdk9-b47
|
ee8447ca632e1d39180b4767c749db101bff7314 jdk9-b47
|
||||||
|
a13c49c5f2899b702652a460ed7aa73123e671e6 jdk9-b48
|
||||||
|
@ -450,3 +450,4 @@ c363a8b87e477ee45d6d3cb2a36cb365141bc596 jdk9-b38
|
|||||||
5dc8184af1e2bb30b0103113d1f1a58a21a80c37 jdk9-b45
|
5dc8184af1e2bb30b0103113d1f1a58a21a80c37 jdk9-b45
|
||||||
a184ee1d717297bd35b7c3e35393e137921a3ed2 jdk9-b46
|
a184ee1d717297bd35b7c3e35393e137921a3ed2 jdk9-b46
|
||||||
3b241fb72b8925b75941d612db762a6d5da66d02 jdk9-b47
|
3b241fb72b8925b75941d612db762a6d5da66d02 jdk9-b47
|
||||||
|
cc775a4a24c7f5d9e624b4205e9fbd48a17331f6 jdk9-b48
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
|
# Copyright (c) 2002, 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
|
||||||
@ -132,6 +132,7 @@ SUNWprivate_1.1 {
|
|||||||
JVM_GetMethodIxSignatureUTF;
|
JVM_GetMethodIxSignatureUTF;
|
||||||
JVM_GetMethodParameters;
|
JVM_GetMethodParameters;
|
||||||
JVM_GetMethodTypeAnnotations;
|
JVM_GetMethodTypeAnnotations;
|
||||||
|
JVM_GetNanoTimeAdjustment;
|
||||||
JVM_GetPrimitiveArrayElement;
|
JVM_GetPrimitiveArrayElement;
|
||||||
JVM_GetProtectionDomain;
|
JVM_GetProtectionDomain;
|
||||||
JVM_GetStackAccessControlContext;
|
JVM_GetStackAccessControlContext;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
|
# Copyright (c) 2002, 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
|
||||||
@ -130,6 +130,7 @@ SUNWprivate_1.1 {
|
|||||||
JVM_GetMethodIxNameUTF;
|
JVM_GetMethodIxNameUTF;
|
||||||
JVM_GetMethodIxSignatureUTF;
|
JVM_GetMethodIxSignatureUTF;
|
||||||
JVM_GetMethodParameters;
|
JVM_GetMethodParameters;
|
||||||
|
JVM_GetNanoTimeAdjustment;
|
||||||
JVM_GetPrimitiveArrayElement;
|
JVM_GetPrimitiveArrayElement;
|
||||||
JVM_GetProtectionDomain;
|
JVM_GetProtectionDomain;
|
||||||
JVM_GetStackAccessControlContext;
|
JVM_GetStackAccessControlContext;
|
||||||
|
@ -74,6 +74,12 @@ CFLAGS += -D_REENTRANT
|
|||||||
# no xlc counterpart for -fcheck-new
|
# no xlc counterpart for -fcheck-new
|
||||||
# CFLAGS += -fcheck-new
|
# CFLAGS += -fcheck-new
|
||||||
|
|
||||||
|
# We need to define this on the command line if we want to use the the
|
||||||
|
# predefined format specifiers from "inttypes.h". Otherwise system headrs
|
||||||
|
# can indirectly include inttypes.h before we define __STDC_FORMAT_MACROS
|
||||||
|
# in globalDefinitions.hpp
|
||||||
|
CFLAGS += -D__STDC_FORMAT_MACROS
|
||||||
|
|
||||||
ARCHFLAG = -q64
|
ARCHFLAG = -q64
|
||||||
|
|
||||||
CFLAGS += $(ARCHFLAG)
|
CFLAGS += $(ARCHFLAG)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
|
# Copyright (c) 2002, 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
|
||||||
@ -130,6 +130,7 @@
|
|||||||
_JVM_GetMethodIxSignatureUTF
|
_JVM_GetMethodIxSignatureUTF
|
||||||
_JVM_GetMethodParameters
|
_JVM_GetMethodParameters
|
||||||
_JVM_GetMethodTypeAnnotations
|
_JVM_GetMethodTypeAnnotations
|
||||||
|
_JVM_GetNanoTimeAdjustment
|
||||||
_JVM_GetPrimitiveArrayElement
|
_JVM_GetPrimitiveArrayElement
|
||||||
_JVM_GetProtectionDomain
|
_JVM_GetProtectionDomain
|
||||||
_JVM_GetStackAccessControlContext
|
_JVM_GetStackAccessControlContext
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
|
# Copyright (c) 2002, 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
|
||||||
@ -130,6 +130,7 @@
|
|||||||
_JVM_GetMethodIxSignatureUTF
|
_JVM_GetMethodIxSignatureUTF
|
||||||
_JVM_GetMethodParameters
|
_JVM_GetMethodParameters
|
||||||
_JVM_GetMethodTypeAnnotations
|
_JVM_GetMethodTypeAnnotations
|
||||||
|
_JVM_GetNanoTimeAdjustment
|
||||||
_JVM_GetPrimitiveArrayElement
|
_JVM_GetPrimitiveArrayElement
|
||||||
_JVM_GetProtectionDomain
|
_JVM_GetProtectionDomain
|
||||||
_JVM_GetStackAccessControlContext
|
_JVM_GetStackAccessControlContext
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
|
# Copyright (c) 2002, 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
|
||||||
@ -132,6 +132,7 @@ SUNWprivate_1.1 {
|
|||||||
JVM_GetMethodIxSignatureUTF;
|
JVM_GetMethodIxSignatureUTF;
|
||||||
JVM_GetMethodParameters;
|
JVM_GetMethodParameters;
|
||||||
JVM_GetMethodTypeAnnotations;
|
JVM_GetMethodTypeAnnotations;
|
||||||
|
JVM_GetNanoTimeAdjustment;
|
||||||
JVM_GetPrimitiveArrayElement;
|
JVM_GetPrimitiveArrayElement;
|
||||||
JVM_GetProtectionDomain;
|
JVM_GetProtectionDomain;
|
||||||
JVM_GetStackAccessControlContext;
|
JVM_GetStackAccessControlContext;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
|
# Copyright (c) 2002, 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
|
||||||
@ -132,6 +132,7 @@ SUNWprivate_1.1 {
|
|||||||
JVM_GetMethodIxSignatureUTF;
|
JVM_GetMethodIxSignatureUTF;
|
||||||
JVM_GetMethodParameters;
|
JVM_GetMethodParameters;
|
||||||
JVM_GetMethodTypeAnnotations;
|
JVM_GetMethodTypeAnnotations;
|
||||||
|
JVM_GetNanoTimeAdjustment;
|
||||||
JVM_GetPrimitiveArrayElement;
|
JVM_GetPrimitiveArrayElement;
|
||||||
JVM_GetProtectionDomain;
|
JVM_GetProtectionDomain;
|
||||||
JVM_GetStackAccessControlContext;
|
JVM_GetStackAccessControlContext;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
|
# Copyright (c) 2002, 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
|
||||||
@ -132,6 +132,7 @@ SUNWprivate_1.1 {
|
|||||||
JVM_GetMethodIxSignatureUTF;
|
JVM_GetMethodIxSignatureUTF;
|
||||||
JVM_GetMethodParameters;
|
JVM_GetMethodParameters;
|
||||||
JVM_GetMethodTypeAnnotations;
|
JVM_GetMethodTypeAnnotations;
|
||||||
|
JVM_GetNanoTimeAdjustment;
|
||||||
JVM_GetPrimitiveArrayElement;
|
JVM_GetPrimitiveArrayElement;
|
||||||
JVM_GetProtectionDomain;
|
JVM_GetProtectionDomain;
|
||||||
JVM_GetStackAccessControlContext;
|
JVM_GetStackAccessControlContext;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
|
# Copyright (c) 2002, 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
|
||||||
@ -132,6 +132,7 @@ SUNWprivate_1.1 {
|
|||||||
JVM_GetMethodIxSignatureUTF;
|
JVM_GetMethodIxSignatureUTF;
|
||||||
JVM_GetMethodParameters;
|
JVM_GetMethodParameters;
|
||||||
JVM_GetMethodTypeAnnotations;
|
JVM_GetMethodTypeAnnotations;
|
||||||
|
JVM_GetNanoTimeAdjustment;
|
||||||
JVM_GetPrimitiveArrayElement;
|
JVM_GetPrimitiveArrayElement;
|
||||||
JVM_GetProtectionDomain;
|
JVM_GetProtectionDomain;
|
||||||
JVM_GetStackAccessControlContext;
|
JVM_GetStackAccessControlContext;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
|
# Copyright (c) 2000, 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
|
||||||
@ -132,6 +132,7 @@ SUNWprivate_1.1 {
|
|||||||
JVM_GetMethodIxSignatureUTF;
|
JVM_GetMethodIxSignatureUTF;
|
||||||
JVM_GetMethodParameters;
|
JVM_GetMethodParameters;
|
||||||
JVM_GetMethodTypeAnnotations;
|
JVM_GetMethodTypeAnnotations;
|
||||||
|
JVM_GetNanoTimeAdjustment;
|
||||||
JVM_GetPrimitiveArrayElement;
|
JVM_GetPrimitiveArrayElement;
|
||||||
JVM_GetProtectionDomain;
|
JVM_GetProtectionDomain;
|
||||||
JVM_GetStackAccessControlContext;
|
JVM_GetStackAccessControlContext;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright 2012, 2014 SAP AG. All rights reserved.
|
* Copyright 2012, 2014 SAP AG. 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.
|
||||||
*
|
*
|
||||||
@ -1115,6 +1115,15 @@ jlong os::javaTimeMillis() {
|
|||||||
return jlong(time.tv_sec) * 1000 + jlong(time.tv_usec / 1000);
|
return jlong(time.tv_sec) * 1000 + jlong(time.tv_usec / 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void os::javaTimeSystemUTC(jlong &seconds, jlong &nanos) {
|
||||||
|
timeval time;
|
||||||
|
int status = gettimeofday(&time, NULL);
|
||||||
|
assert(status != -1, "aix error at gettimeofday()");
|
||||||
|
seconds = jlong(time.tv_sec);
|
||||||
|
nanos = jlong(time.tv_usec) * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// We need to manually declare mread_real_time,
|
// We need to manually declare mread_real_time,
|
||||||
// because IBM didn't provide a prototype in time.h.
|
// because IBM didn't provide a prototype in time.h.
|
||||||
// (they probably only ever tested in C, not C++)
|
// (they probably only ever tested in C, not C++)
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include "os_aix.inline.hpp"
|
#include "os_aix.inline.hpp"
|
||||||
#include "runtime/handles.inline.hpp"
|
#include "runtime/handles.inline.hpp"
|
||||||
#include "runtime/perfMemory.hpp"
|
#include "runtime/perfMemory.hpp"
|
||||||
|
#include "services/memTracker.hpp"
|
||||||
#include "utilities/exceptions.hpp"
|
#include "utilities/exceptions.hpp"
|
||||||
|
|
||||||
// put OS-includes here
|
// put OS-includes here
|
||||||
@ -196,12 +197,37 @@ static pid_t filename_to_pid(const char* filename) {
|
|||||||
return pid;
|
return pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if the given statbuf is considered a secure directory for
|
||||||
|
// the backing store files. Returns true if the directory is considered
|
||||||
|
// a secure location. Returns false if the statbuf is a symbolic link or
|
||||||
|
// if an error occurred.
|
||||||
|
static bool is_statbuf_secure(struct stat *statp) {
|
||||||
|
if (S_ISLNK(statp->st_mode) || !S_ISDIR(statp->st_mode)) {
|
||||||
|
// The path represents a link or some non-directory file type,
|
||||||
|
// which is not what we expected. Declare it insecure.
|
||||||
|
//
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// We have an existing directory, check if the permissions are safe.
|
||||||
|
if ((statp->st_mode & (S_IWGRP|S_IWOTH)) != 0) {
|
||||||
|
// The directory is open for writing and could be subjected
|
||||||
|
// to a symlink or a hard link attack. Declare it insecure.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// See if the uid of the directory matches the effective uid of the process.
|
||||||
|
//
|
||||||
|
if (statp->st_uid != geteuid()) {
|
||||||
|
// The directory was not created by this user, declare it insecure.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// check if the given path is considered a secure directory for
|
|
||||||
|
// Check if the given path is considered a secure directory for
|
||||||
// the backing store files. Returns true if the directory exists
|
// the backing store files. Returns true if the directory exists
|
||||||
// and is considered a secure location. Returns false if the path
|
// and is considered a secure location. Returns false if the path
|
||||||
// is a symbolic link or if an error occurred.
|
// is a symbolic link or if an error occurred.
|
||||||
//
|
|
||||||
static bool is_directory_secure(const char* path) {
|
static bool is_directory_secure(const char* path) {
|
||||||
struct stat statbuf;
|
struct stat statbuf;
|
||||||
int result = 0;
|
int result = 0;
|
||||||
@ -211,38 +237,276 @@ static bool is_directory_secure(const char* path) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// the path exists, now check it's mode
|
// The path exists, see if it is secure.
|
||||||
if (S_ISLNK(statbuf.st_mode) || !S_ISDIR(statbuf.st_mode)) {
|
return is_statbuf_secure(&statbuf);
|
||||||
// the path represents a link or some non-directory file type,
|
}
|
||||||
// which is not what we expected. declare it insecure.
|
|
||||||
//
|
// (Taken over from Solaris to support the O_NOFOLLOW case on AIX.)
|
||||||
|
// Check if the given directory file descriptor is considered a secure
|
||||||
|
// directory for the backing store files. Returns true if the directory
|
||||||
|
// exists and is considered a secure location. Returns false if the path
|
||||||
|
// is a symbolic link or if an error occurred.
|
||||||
|
static bool is_dirfd_secure(int dir_fd) {
|
||||||
|
struct stat statbuf;
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
RESTARTABLE(::fstat(dir_fd, &statbuf), result);
|
||||||
|
if (result == OS_ERR) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
// we have an existing directory, check if the permissions are safe.
|
// The path exists, now check its mode.
|
||||||
//
|
return is_statbuf_secure(&statbuf);
|
||||||
if ((statbuf.st_mode & (S_IWGRP|S_IWOTH)) != 0) {
|
}
|
||||||
// the directory is open for writing and could be subjected
|
|
||||||
// to a symlnk attack. declare it insecure.
|
|
||||||
//
|
// Check to make sure fd1 and fd2 are referencing the same file system object.
|
||||||
return false;
|
static bool is_same_fsobject(int fd1, int fd2) {
|
||||||
|
struct stat statbuf1;
|
||||||
|
struct stat statbuf2;
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
RESTARTABLE(::fstat(fd1, &statbuf1), result);
|
||||||
|
if (result == OS_ERR) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
RESTARTABLE(::fstat(fd2, &statbuf2), result);
|
||||||
|
if (result == OS_ERR) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((statbuf1.st_ino == statbuf2.st_ino) &&
|
||||||
|
(statbuf1.st_dev == statbuf2.st_dev)) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper functions for open without O_NOFOLLOW which is not present on AIX 5.3/6.1.
|
||||||
|
// We use the jdk6 implementation here.
|
||||||
|
#ifndef O_NOFOLLOW
|
||||||
|
// The O_NOFOLLOW oflag doesn't exist before solaris 5.10, this is to simulate that behaviour
|
||||||
|
// was done in jdk 5/6 hotspot by Oracle this way
|
||||||
|
static int open_o_nofollow_impl(const char* path, int oflag, mode_t mode, bool use_mode) {
|
||||||
|
struct stat orig_st;
|
||||||
|
struct stat new_st;
|
||||||
|
bool create;
|
||||||
|
int error;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
create = false;
|
||||||
|
|
||||||
|
if (lstat(path, &orig_st) != 0) {
|
||||||
|
if (errno == ENOENT && (oflag & O_CREAT) != 0) {
|
||||||
|
// File doesn't exist, but_we want to create it, add O_EXCL flag
|
||||||
|
// to make sure no-one creates it (or a symlink) before us
|
||||||
|
// This works as we expect with symlinks, from posix man page:
|
||||||
|
// 'If O_EXCL and O_CREAT are set, and path names a symbolic
|
||||||
|
// link, open() shall fail and set errno to [EEXIST]'.
|
||||||
|
oflag |= O_EXCL;
|
||||||
|
create = true;
|
||||||
|
} else {
|
||||||
|
// File doesn't exist, and we are not creating it.
|
||||||
|
return OS_ERR;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// Lstat success, check if existing file is a link.
|
||||||
|
if ((orig_st.st_mode & S_IFMT) == S_IFLNK) {
|
||||||
|
// File is a symlink.
|
||||||
|
errno = ELOOP;
|
||||||
|
return OS_ERR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (use_mode == true) {
|
||||||
|
fd = open(path, oflag, mode);
|
||||||
|
} else {
|
||||||
|
fd = open(path, oflag);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fd == OS_ERR) {
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Can't do inode checks on before/after if we created the file.
|
||||||
|
if (create == false) {
|
||||||
|
if (fstat(fd, &new_st) != 0) {
|
||||||
|
// Keep errno from fstat, in case close also fails.
|
||||||
|
error = errno;
|
||||||
|
::close(fd);
|
||||||
|
errno = error;
|
||||||
|
return OS_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (orig_st.st_dev != new_st.st_dev || orig_st.st_ino != new_st.st_ino) {
|
||||||
|
// File was tampered with during race window.
|
||||||
|
::close(fd);
|
||||||
|
errno = EEXIST;
|
||||||
|
if (PrintMiscellaneous && Verbose) {
|
||||||
|
warning("possible file tampering attempt detected when opening %s", path);
|
||||||
|
}
|
||||||
|
return OS_ERR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int open_o_nofollow(const char* path, int oflag, mode_t mode) {
|
||||||
|
return open_o_nofollow_impl(path, oflag, mode, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int open_o_nofollow(const char* path, int oflag) {
|
||||||
|
return open_o_nofollow_impl(path, oflag, 0, false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Open the directory of the given path and validate it.
|
||||||
|
// Return a DIR * of the open directory.
|
||||||
|
static DIR *open_directory_secure(const char* dirname) {
|
||||||
|
// Open the directory using open() so that it can be verified
|
||||||
|
// to be secure by calling is_dirfd_secure(), opendir() and then check
|
||||||
|
// to see if they are the same file system object. This method does not
|
||||||
|
// introduce a window of opportunity for the directory to be attacked that
|
||||||
|
// calling opendir() and is_directory_secure() does.
|
||||||
|
int result;
|
||||||
|
DIR *dirp = NULL;
|
||||||
|
|
||||||
|
// No O_NOFOLLOW defined at buildtime, and it is not documented for open;
|
||||||
|
// so provide a workaround in this case.
|
||||||
|
#ifdef O_NOFOLLOW
|
||||||
|
RESTARTABLE(::open(dirname, O_RDONLY|O_NOFOLLOW), result);
|
||||||
|
#else
|
||||||
|
// workaround (jdk6 coding)
|
||||||
|
RESTARTABLE(::open_o_nofollow(dirname, O_RDONLY), result);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (result == OS_ERR) {
|
||||||
|
// Directory doesn't exist or is a symlink, so there is nothing to cleanup.
|
||||||
|
if (PrintMiscellaneous && Verbose) {
|
||||||
|
if (errno == ELOOP) {
|
||||||
|
warning("directory %s is a symlink and is not secure\n", dirname);
|
||||||
|
} else {
|
||||||
|
warning("could not open directory %s: %s\n", dirname, strerror(errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dirp;
|
||||||
|
}
|
||||||
|
int fd = result;
|
||||||
|
|
||||||
|
// Determine if the open directory is secure.
|
||||||
|
if (!is_dirfd_secure(fd)) {
|
||||||
|
// The directory is not a secure directory.
|
||||||
|
os::close(fd);
|
||||||
|
return dirp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open the directory.
|
||||||
|
dirp = ::opendir(dirname);
|
||||||
|
if (dirp == NULL) {
|
||||||
|
// The directory doesn't exist, close fd and return.
|
||||||
|
os::close(fd);
|
||||||
|
return dirp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check to make sure fd and dirp are referencing the same file system object.
|
||||||
|
if (!is_same_fsobject(fd, dirp->dd_fd)) {
|
||||||
|
// The directory is not secure.
|
||||||
|
os::close(fd);
|
||||||
|
os::closedir(dirp);
|
||||||
|
dirp = NULL;
|
||||||
|
return dirp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close initial open now that we know directory is secure
|
||||||
|
os::close(fd);
|
||||||
|
|
||||||
|
return dirp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: The code below uses fchdir(), open() and unlink() because
|
||||||
|
// fdopendir(), openat() and unlinkat() are not supported on all
|
||||||
|
// versions. Once the support for fdopendir(), openat() and unlinkat()
|
||||||
|
// is available on all supported versions the code can be changed
|
||||||
|
// to use these functions.
|
||||||
|
|
||||||
|
// Open the directory of the given path, validate it and set the
|
||||||
|
// current working directory to it.
|
||||||
|
// Return a DIR * of the open directory and the saved cwd fd.
|
||||||
|
//
|
||||||
|
static DIR *open_directory_secure_cwd(const char* dirname, int *saved_cwd_fd) {
|
||||||
|
|
||||||
|
// Open the directory.
|
||||||
|
DIR* dirp = open_directory_secure(dirname);
|
||||||
|
if (dirp == NULL) {
|
||||||
|
// Directory doesn't exist or is insecure, so there is nothing to cleanup.
|
||||||
|
return dirp;
|
||||||
|
}
|
||||||
|
int fd = dirp->dd_fd;
|
||||||
|
|
||||||
|
// Open a fd to the cwd and save it off.
|
||||||
|
int result;
|
||||||
|
RESTARTABLE(::open(".", O_RDONLY), result);
|
||||||
|
if (result == OS_ERR) {
|
||||||
|
*saved_cwd_fd = -1;
|
||||||
|
} else {
|
||||||
|
*saved_cwd_fd = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the current directory to dirname by using the fd of the directory.
|
||||||
|
result = fchdir(fd);
|
||||||
|
|
||||||
|
return dirp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close the directory and restore the current working directory.
|
||||||
|
static void close_directory_secure_cwd(DIR* dirp, int saved_cwd_fd) {
|
||||||
|
|
||||||
|
int result;
|
||||||
|
// If we have a saved cwd change back to it and close the fd.
|
||||||
|
if (saved_cwd_fd != -1) {
|
||||||
|
result = fchdir(saved_cwd_fd);
|
||||||
|
::close(saved_cwd_fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close the directory.
|
||||||
|
os::closedir(dirp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the given file descriptor is considered a secure.
|
||||||
|
static bool is_file_secure(int fd, const char *filename) {
|
||||||
|
|
||||||
|
int result;
|
||||||
|
struct stat statbuf;
|
||||||
|
|
||||||
|
// Determine if the file is secure.
|
||||||
|
RESTARTABLE(::fstat(fd, &statbuf), result);
|
||||||
|
if (result == OS_ERR) {
|
||||||
|
if (PrintMiscellaneous && Verbose) {
|
||||||
|
warning("fstat failed on %s: %s\n", filename, strerror(errno));
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (statbuf.st_nlink > 1) {
|
||||||
|
// A file with multiple links is not expected.
|
||||||
|
if (PrintMiscellaneous && Verbose) {
|
||||||
|
warning("file %s has multiple links\n", filename);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return the user name for the given user id.
|
||||||
// return the user name for the given user id
|
|
||||||
//
|
|
||||||
// the caller is expected to free the allocated memory.
|
|
||||||
//
|
//
|
||||||
|
// The caller is expected to free the allocated memory.
|
||||||
static char* get_user_name(uid_t uid) {
|
static char* get_user_name(uid_t uid) {
|
||||||
|
|
||||||
struct passwd pwent;
|
struct passwd pwent;
|
||||||
|
|
||||||
// determine the max pwbuf size from sysconf, and hardcode
|
// Determine the max pwbuf size from sysconf, and hardcode
|
||||||
// a default if this not available through sysconf.
|
// a default if this not available through sysconf.
|
||||||
//
|
|
||||||
long bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
|
long bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
|
||||||
if (bufsize == -1)
|
if (bufsize == -1)
|
||||||
bufsize = 1024;
|
bufsize = 1024;
|
||||||
@ -344,7 +608,8 @@ static char* get_user_name_slow(int vmid, TRAPS) {
|
|||||||
strcat(usrdir_name, "/");
|
strcat(usrdir_name, "/");
|
||||||
strcat(usrdir_name, dentry->d_name);
|
strcat(usrdir_name, dentry->d_name);
|
||||||
|
|
||||||
DIR* subdirp = os::opendir(usrdir_name);
|
// Open the user directory.
|
||||||
|
DIR* subdirp = open_directory_secure(usrdir_name);
|
||||||
|
|
||||||
if (subdirp == NULL) {
|
if (subdirp == NULL) {
|
||||||
FREE_C_HEAP_ARRAY(char, usrdir_name);
|
FREE_C_HEAP_ARRAY(char, usrdir_name);
|
||||||
@ -464,28 +729,7 @@ static void remove_file(const char* path) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cleanup stale shared memory resources
|
||||||
// remove file
|
|
||||||
//
|
|
||||||
// this method removes the file with the given file name in the
|
|
||||||
// named directory.
|
|
||||||
//
|
|
||||||
static void remove_file(const char* dirname, const char* filename) {
|
|
||||||
|
|
||||||
size_t nbytes = strlen(dirname) + strlen(filename) + 2;
|
|
||||||
char* path = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal);
|
|
||||||
|
|
||||||
strcpy(path, dirname);
|
|
||||||
strcat(path, "/");
|
|
||||||
strcat(path, filename);
|
|
||||||
|
|
||||||
remove_file(path);
|
|
||||||
|
|
||||||
FREE_C_HEAP_ARRAY(char, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// cleanup stale shared memory resources
|
|
||||||
//
|
//
|
||||||
// This method attempts to remove all stale shared memory files in
|
// This method attempts to remove all stale shared memory files in
|
||||||
// the named user temporary directory. It scans the named directory
|
// the named user temporary directory. It scans the named directory
|
||||||
@ -493,33 +737,26 @@ static void remove_file(const char* dirname, const char* filename) {
|
|||||||
// process id is extracted from the file name and a test is run to
|
// process id is extracted from the file name and a test is run to
|
||||||
// determine if the process is alive. If the process is not alive,
|
// determine if the process is alive. If the process is not alive,
|
||||||
// any stale file resources are removed.
|
// any stale file resources are removed.
|
||||||
//
|
|
||||||
static void cleanup_sharedmem_resources(const char* dirname) {
|
static void cleanup_sharedmem_resources(const char* dirname) {
|
||||||
|
|
||||||
// open the user temp directory
|
int saved_cwd_fd;
|
||||||
DIR* dirp = os::opendir(dirname);
|
// Open the directory.
|
||||||
|
DIR* dirp = open_directory_secure_cwd(dirname, &saved_cwd_fd);
|
||||||
if (dirp == NULL) {
|
if (dirp == NULL) {
|
||||||
// directory doesn't exist, so there is nothing to cleanup
|
// Directory doesn't exist or is insecure, so there is nothing to cleanup.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_directory_secure(dirname)) {
|
// For each entry in the directory that matches the expected file
|
||||||
// the directory is not a secure directory
|
|
||||||
os::closedir(dirp);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// for each entry in the directory that matches the expected file
|
|
||||||
// name pattern, determine if the file resources are stale and if
|
// name pattern, determine if the file resources are stale and if
|
||||||
// so, remove the file resources. Note, instrumented HotSpot processes
|
// so, remove the file resources. Note, instrumented HotSpot processes
|
||||||
// for this user may start and/or terminate during this search and
|
// for this user may start and/or terminate during this search and
|
||||||
// remove or create new files in this directory. The behavior of this
|
// remove or create new files in this directory. The behavior of this
|
||||||
// loop under these conditions is dependent upon the implementation of
|
// loop under these conditions is dependent upon the implementation of
|
||||||
// opendir/readdir.
|
// opendir/readdir.
|
||||||
//
|
|
||||||
struct dirent* entry;
|
struct dirent* entry;
|
||||||
char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname), mtInternal);
|
char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname), mtInternal);
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) {
|
while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) {
|
||||||
|
|
||||||
@ -529,56 +766,55 @@ static void cleanup_sharedmem_resources(const char* dirname) {
|
|||||||
|
|
||||||
if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
|
if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
|
||||||
|
|
||||||
// attempt to remove all unexpected files, except "." and ".."
|
// Attempt to remove all unexpected files, except "." and "..".
|
||||||
remove_file(dirname, entry->d_name);
|
unlink(entry->d_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// we now have a file name that converts to a valid integer
|
// We now have a file name that converts to a valid integer
|
||||||
// that could represent a process id . if this process id
|
// that could represent a process id . if this process id
|
||||||
// matches the current process id or the process is not running,
|
// matches the current process id or the process is not running,
|
||||||
// then remove the stale file resources.
|
// then remove the stale file resources.
|
||||||
//
|
//
|
||||||
// process liveness is detected by sending signal number 0 to
|
// Process liveness is detected by sending signal number 0 to
|
||||||
// the process id (see kill(2)). if kill determines that the
|
// the process id (see kill(2)). if kill determines that the
|
||||||
// process does not exist, then the file resources are removed.
|
// process does not exist, then the file resources are removed.
|
||||||
// if kill determines that that we don't have permission to
|
// if kill determines that that we don't have permission to
|
||||||
// signal the process, then the file resources are assumed to
|
// signal the process, then the file resources are assumed to
|
||||||
// be stale and are removed because the resources for such a
|
// be stale and are removed because the resources for such a
|
||||||
// process should be in a different user specific directory.
|
// process should be in a different user specific directory.
|
||||||
//
|
|
||||||
if ((pid == os::current_process_id()) ||
|
if ((pid == os::current_process_id()) ||
|
||||||
(kill(pid, 0) == OS_ERR && (errno == ESRCH || errno == EPERM))) {
|
(kill(pid, 0) == OS_ERR && (errno == ESRCH || errno == EPERM))) {
|
||||||
|
|
||||||
remove_file(dirname, entry->d_name);
|
unlink(entry->d_name);
|
||||||
}
|
}
|
||||||
errno = 0;
|
errno = 0;
|
||||||
}
|
}
|
||||||
os::closedir(dirp);
|
|
||||||
FREE_C_HEAP_ARRAY(char, dbuf);
|
// Close the directory and reset the current working directory.
|
||||||
|
close_directory_secure_cwd(dirp, saved_cwd_fd);
|
||||||
|
|
||||||
|
FREE_C_HEAP_ARRAY(char, dbuf, mtInternal);
|
||||||
}
|
}
|
||||||
|
|
||||||
// make the user specific temporary directory. Returns true if
|
// Make the user specific temporary directory. Returns true if
|
||||||
// the directory exists and is secure upon return. Returns false
|
// the directory exists and is secure upon return. Returns false
|
||||||
// if the directory exists but is either a symlink, is otherwise
|
// if the directory exists but is either a symlink, is otherwise
|
||||||
// insecure, or if an error occurred.
|
// insecure, or if an error occurred.
|
||||||
//
|
|
||||||
static bool make_user_tmp_dir(const char* dirname) {
|
static bool make_user_tmp_dir(const char* dirname) {
|
||||||
|
|
||||||
// create the directory with 0755 permissions. note that the directory
|
// Create the directory with 0755 permissions. note that the directory
|
||||||
// will be owned by euid::egid, which may not be the same as uid::gid.
|
// will be owned by euid::egid, which may not be the same as uid::gid.
|
||||||
//
|
|
||||||
if (mkdir(dirname, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) == OS_ERR) {
|
if (mkdir(dirname, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) == OS_ERR) {
|
||||||
if (errno == EEXIST) {
|
if (errno == EEXIST) {
|
||||||
// The directory already exists and was probably created by another
|
// The directory already exists and was probably created by another
|
||||||
// JVM instance. However, this could also be the result of a
|
// JVM instance. However, this could also be the result of a
|
||||||
// deliberate symlink. Verify that the existing directory is safe.
|
// deliberate symlink. Verify that the existing directory is safe.
|
||||||
//
|
|
||||||
if (!is_directory_secure(dirname)) {
|
if (!is_directory_secure(dirname)) {
|
||||||
// directory is not secure
|
// Directory is not secure.
|
||||||
if (PrintMiscellaneous && Verbose) {
|
if (PrintMiscellaneous && Verbose) {
|
||||||
warning("%s directory is insecure\n", dirname);
|
warning("%s directory is insecure\n", dirname);
|
||||||
}
|
}
|
||||||
@ -614,19 +850,63 @@ static int create_sharedmem_resources(const char* dirname, const char* filename,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int result;
|
int saved_cwd_fd;
|
||||||
|
// Open the directory and set the current working directory to it.
|
||||||
RESTARTABLE(::open(filename, O_RDWR|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE), result);
|
DIR* dirp = open_directory_secure_cwd(dirname, &saved_cwd_fd);
|
||||||
if (result == OS_ERR) {
|
if (dirp == NULL) {
|
||||||
if (PrintMiscellaneous && Verbose) {
|
// Directory doesn't exist or is insecure, so cannot create shared
|
||||||
warning("could not create file %s: %s\n", filename, strerror(errno));
|
// memory file.
|
||||||
}
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Open the filename in the current directory.
|
||||||
|
// Cannot use O_TRUNC here; truncation of an existing file has to happen
|
||||||
|
// after the is_file_secure() check below.
|
||||||
|
int result;
|
||||||
|
|
||||||
|
// No O_NOFOLLOW defined at buildtime, and it is not documented for open;
|
||||||
|
// so provide a workaround in this case.
|
||||||
|
#ifdef O_NOFOLLOW
|
||||||
|
RESTARTABLE(::open(filename, O_RDWR|O_CREAT|O_NOFOLLOW, S_IREAD|S_IWRITE), result);
|
||||||
|
#else
|
||||||
|
// workaround function (jdk6 code)
|
||||||
|
RESTARTABLE(::open_o_nofollow(filename, O_RDWR|O_CREAT, S_IREAD|S_IWRITE), result);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (result == OS_ERR) {
|
||||||
|
if (PrintMiscellaneous && Verbose) {
|
||||||
|
if (errno == ELOOP) {
|
||||||
|
warning("file %s is a symlink and is not secure\n", filename);
|
||||||
|
} else {
|
||||||
|
warning("could not create file %s: %s\n", filename, strerror(errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Close the directory and reset the current working directory.
|
||||||
|
close_directory_secure_cwd(dirp, saved_cwd_fd);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// Close the directory and reset the current working directory.
|
||||||
|
close_directory_secure_cwd(dirp, saved_cwd_fd);
|
||||||
|
|
||||||
// save the file descriptor
|
// save the file descriptor
|
||||||
int fd = result;
|
int fd = result;
|
||||||
|
|
||||||
|
// Check to see if the file is secure.
|
||||||
|
if (!is_file_secure(fd, filename)) {
|
||||||
|
::close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Truncate the file to get rid of any existing data.
|
||||||
|
RESTARTABLE(::ftruncate(fd, (off_t)0), result);
|
||||||
|
if (result == OS_ERR) {
|
||||||
|
if (PrintMiscellaneous && Verbose) {
|
||||||
|
warning("could not truncate shared memory file: %s\n", strerror(errno));
|
||||||
|
}
|
||||||
|
::close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
// set the file size
|
// set the file size
|
||||||
RESTARTABLE(::ftruncate(fd, (off_t)size), result);
|
RESTARTABLE(::ftruncate(fd, (off_t)size), result);
|
||||||
if (result == OS_ERR) {
|
if (result == OS_ERR) {
|
||||||
@ -648,7 +928,14 @@ static int open_sharedmem_file(const char* filename, int oflags, TRAPS) {
|
|||||||
|
|
||||||
// open the file
|
// open the file
|
||||||
int result;
|
int result;
|
||||||
|
// No O_NOFOLLOW defined at buildtime, and it is not documented for open;
|
||||||
|
// so provide a workaround in this case
|
||||||
|
#ifdef O_NOFOLLOW
|
||||||
RESTARTABLE(::open(filename, oflags), result);
|
RESTARTABLE(::open(filename, oflags), result);
|
||||||
|
#else
|
||||||
|
RESTARTABLE(::open_o_nofollow(filename, oflags), result);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (result == OS_ERR) {
|
if (result == OS_ERR) {
|
||||||
if (errno == ENOENT) {
|
if (errno == ENOENT) {
|
||||||
THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
|
THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
|
||||||
@ -662,8 +949,15 @@ static int open_sharedmem_file(const char* filename, int oflags, TRAPS) {
|
|||||||
THROW_MSG_0(vmSymbols::java_io_IOException(), strerror(errno));
|
THROW_MSG_0(vmSymbols::java_io_IOException(), strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
int fd = result;
|
||||||
|
|
||||||
return result;
|
// Check to see if the file is secure.
|
||||||
|
if (!is_file_secure(fd, filename)) {
|
||||||
|
::close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a named shared memory region. returns the address of the
|
// create a named shared memory region. returns the address of the
|
||||||
@ -695,13 +989,21 @@ static char* mmap_create_shared(size_t size) {
|
|||||||
char* dirname = get_user_tmp_dir(user_name);
|
char* dirname = get_user_tmp_dir(user_name);
|
||||||
char* filename = get_sharedmem_filename(dirname, vmid);
|
char* filename = get_sharedmem_filename(dirname, vmid);
|
||||||
|
|
||||||
|
// Get the short filename.
|
||||||
|
char* short_filename = strrchr(filename, '/');
|
||||||
|
if (short_filename == NULL) {
|
||||||
|
short_filename = filename;
|
||||||
|
} else {
|
||||||
|
short_filename++;
|
||||||
|
}
|
||||||
|
|
||||||
// cleanup any stale shared memory files
|
// cleanup any stale shared memory files
|
||||||
cleanup_sharedmem_resources(dirname);
|
cleanup_sharedmem_resources(dirname);
|
||||||
|
|
||||||
assert(((size > 0) && (size % os::vm_page_size() == 0)),
|
assert(((size > 0) && (size % os::vm_page_size() == 0)),
|
||||||
"unexpected PerfMemory region size");
|
"unexpected PerfMemory region size");
|
||||||
|
|
||||||
fd = create_sharedmem_resources(dirname, filename, size);
|
fd = create_sharedmem_resources(dirname, short_filename, size);
|
||||||
|
|
||||||
FREE_C_HEAP_ARRAY(char, user_name);
|
FREE_C_HEAP_ARRAY(char, user_name);
|
||||||
FREE_C_HEAP_ARRAY(char, dirname);
|
FREE_C_HEAP_ARRAY(char, dirname);
|
||||||
@ -733,6 +1035,9 @@ static char* mmap_create_shared(size_t size) {
|
|||||||
// clear the shared memory region
|
// clear the shared memory region
|
||||||
(void)::memset((void*) mapAddress, 0, size);
|
(void)::memset((void*) mapAddress, 0, size);
|
||||||
|
|
||||||
|
// It does not go through os api, the operation has to record from here.
|
||||||
|
MemTracker::record_virtual_memory_reserve((address)mapAddress, size, CURRENT_PC, mtInternal);
|
||||||
|
|
||||||
return mapAddress;
|
return mapAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -807,7 +1112,7 @@ static void mmap_attach_shared(const char* user, int vmid, PerfMemory::PerfMemor
|
|||||||
char* mapAddress;
|
char* mapAddress;
|
||||||
int result;
|
int result;
|
||||||
int fd;
|
int fd;
|
||||||
size_t size;
|
size_t size = 0;
|
||||||
const char* luser = NULL;
|
const char* luser = NULL;
|
||||||
|
|
||||||
int mmap_prot;
|
int mmap_prot;
|
||||||
@ -819,12 +1124,18 @@ static void mmap_attach_shared(const char* user, int vmid, PerfMemory::PerfMemor
|
|||||||
// constructs for the file and the shared memory mapping.
|
// constructs for the file and the shared memory mapping.
|
||||||
if (mode == PerfMemory::PERF_MODE_RO) {
|
if (mode == PerfMemory::PERF_MODE_RO) {
|
||||||
mmap_prot = PROT_READ;
|
mmap_prot = PROT_READ;
|
||||||
|
|
||||||
|
// No O_NOFOLLOW defined at buildtime, and it is not documented for open.
|
||||||
|
#ifdef O_NOFOLLOW
|
||||||
|
file_flags = O_RDONLY | O_NOFOLLOW;
|
||||||
|
#else
|
||||||
file_flags = O_RDONLY;
|
file_flags = O_RDONLY;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else if (mode == PerfMemory::PERF_MODE_RW) {
|
else if (mode == PerfMemory::PERF_MODE_RW) {
|
||||||
#ifdef LATER
|
#ifdef LATER
|
||||||
mmap_prot = PROT_READ | PROT_WRITE;
|
mmap_prot = PROT_READ | PROT_WRITE;
|
||||||
file_flags = O_RDWR;
|
file_flags = O_RDWR | O_NOFOLLOW;
|
||||||
#else
|
#else
|
||||||
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
|
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
|
||||||
"Unsupported access mode");
|
"Unsupported access mode");
|
||||||
@ -853,9 +1164,9 @@ static void mmap_attach_shared(const char* user, int vmid, PerfMemory::PerfMemor
|
|||||||
// store file, we don't follow them when attaching either.
|
// store file, we don't follow them when attaching either.
|
||||||
//
|
//
|
||||||
if (!is_directory_secure(dirname)) {
|
if (!is_directory_secure(dirname)) {
|
||||||
FREE_C_HEAP_ARRAY(char, dirname);
|
FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
|
||||||
if (luser != user) {
|
if (luser != user) {
|
||||||
FREE_C_HEAP_ARRAY(char, luser);
|
FREE_C_HEAP_ARRAY(char, luser, mtInternal);
|
||||||
}
|
}
|
||||||
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
|
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
|
||||||
"Process not found");
|
"Process not found");
|
||||||
@ -901,6 +1212,9 @@ static void mmap_attach_shared(const char* user, int vmid, PerfMemory::PerfMemor
|
|||||||
"Could not map PerfMemory");
|
"Could not map PerfMemory");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// It does not go through os api, the operation has to record from here.
|
||||||
|
MemTracker::record_virtual_memory_reserve((address)mapAddress, size, CURRENT_PC, mtInternal);
|
||||||
|
|
||||||
*addr = mapAddress;
|
*addr = mapAddress;
|
||||||
*sizep = size;
|
*sizep = size;
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 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
|
||||||
@ -984,6 +984,14 @@ jlong os::javaTimeMillis() {
|
|||||||
return jlong(time.tv_sec) * 1000 + jlong(time.tv_usec / 1000);
|
return jlong(time.tv_sec) * 1000 + jlong(time.tv_usec / 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void os::javaTimeSystemUTC(jlong &seconds, jlong &nanos) {
|
||||||
|
timeval time;
|
||||||
|
int status = gettimeofday(&time, NULL);
|
||||||
|
assert(status != -1, "bsd error");
|
||||||
|
seconds = jlong(time.tv_sec);
|
||||||
|
nanos = jlong(time.tv_usec) * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef __APPLE__
|
#ifndef __APPLE__
|
||||||
#ifndef CLOCK_MONOTONIC
|
#ifndef CLOCK_MONOTONIC
|
||||||
#define CLOCK_MONOTONIC (1)
|
#define CLOCK_MONOTONIC (1)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 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
|
||||||
@ -1322,6 +1322,15 @@ jlong os::javaTimeMillis() {
|
|||||||
return jlong(time.tv_sec) * 1000 + jlong(time.tv_usec / 1000);
|
return jlong(time.tv_sec) * 1000 + jlong(time.tv_usec / 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void os::javaTimeSystemUTC(jlong &seconds, jlong &nanos) {
|
||||||
|
timeval time;
|
||||||
|
int status = gettimeofday(&time, NULL);
|
||||||
|
assert(status != -1, "linux error");
|
||||||
|
seconds = jlong(time.tv_sec);
|
||||||
|
nanos = jlong(time.tv_usec) * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifndef CLOCK_MONOTONIC
|
#ifndef CLOCK_MONOTONIC
|
||||||
#define CLOCK_MONOTONIC (1)
|
#define CLOCK_MONOTONIC (1)
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 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
|
||||||
@ -1475,6 +1475,16 @@ jlong os::javaTimeMillis() {
|
|||||||
return jlong(t.tv_sec) * 1000 + jlong(t.tv_usec) / 1000;
|
return jlong(t.tv_sec) * 1000 + jlong(t.tv_usec) / 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void os::javaTimeSystemUTC(jlong &seconds, jlong &nanos) {
|
||||||
|
timeval t;
|
||||||
|
if (gettimeofday(&t, NULL) == -1) {
|
||||||
|
fatal(err_msg("os::javaTimeSystemUTC: gettimeofday (%s)", strerror(errno)));
|
||||||
|
}
|
||||||
|
seconds = jlong(t.tv_sec);
|
||||||
|
nanos = jlong(t.tv_usec) * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
jlong os::javaTimeNanos() {
|
jlong os::javaTimeNanos() {
|
||||||
return (jlong)getTimeNanos();
|
return (jlong)getTimeNanos();
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 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
|
||||||
@ -839,6 +839,12 @@ jlong windows_to_java_time(FILETIME wt) {
|
|||||||
return (a - offset()) / 10000;
|
return (a - offset()) / 10000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns time ticks in (10th of micro seconds)
|
||||||
|
jlong windows_to_time_ticks(FILETIME wt) {
|
||||||
|
jlong a = jlong_from(wt.dwHighDateTime, wt.dwLowDateTime);
|
||||||
|
return (a - offset());
|
||||||
|
}
|
||||||
|
|
||||||
FILETIME java_to_windows_time(jlong l) {
|
FILETIME java_to_windows_time(jlong l) {
|
||||||
jlong a = (l * 10000) + offset();
|
jlong a = (l * 10000) + offset();
|
||||||
FILETIME result;
|
FILETIME result;
|
||||||
@ -874,6 +880,15 @@ jlong os::javaTimeMillis() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void os::javaTimeSystemUTC(jlong &seconds, jlong &nanos) {
|
||||||
|
FILETIME wt;
|
||||||
|
GetSystemTimeAsFileTime(&wt);
|
||||||
|
jlong ticks = windows_to_time_ticks(wt); // 10th of micros
|
||||||
|
jlong secs = jlong(ticks / 10000000); // 10000 * 1000
|
||||||
|
seconds = secs;
|
||||||
|
nanos = jlong(ticks - (secs*10000000)) * 100;
|
||||||
|
}
|
||||||
|
|
||||||
jlong os::javaTimeNanos() {
|
jlong os::javaTimeNanos() {
|
||||||
if (!win32::_has_performance_count) {
|
if (!win32::_has_performance_count) {
|
||||||
return javaTimeMillis() * NANOSECS_PER_MILLISEC; // the best we can do.
|
return javaTimeMillis() * NANOSECS_PER_MILLISEC; // the best we can do.
|
||||||
@ -1693,7 +1708,7 @@ void os::win32::print_windows_version(outputStream* st) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 6004:
|
case 10000:
|
||||||
if (is_workstation) {
|
if (is_workstation) {
|
||||||
st->print("10");
|
st->print("10");
|
||||||
} else {
|
} else {
|
||||||
|
@ -1950,7 +1950,7 @@ bool ClassVerifier::is_protected_access(instanceKlassHandle this_class,
|
|||||||
InstanceKlass* target_instance = InstanceKlass::cast(target_class);
|
InstanceKlass* target_instance = InstanceKlass::cast(target_class);
|
||||||
fieldDescriptor fd;
|
fieldDescriptor fd;
|
||||||
if (is_method) {
|
if (is_method) {
|
||||||
Method* m = target_instance->uncached_lookup_method(field_name, field_sig, Klass::normal);
|
Method* m = target_instance->uncached_lookup_method(field_name, field_sig, Klass::find_overpass);
|
||||||
if (m != NULL && m->is_protected()) {
|
if (m != NULL && m->is_protected()) {
|
||||||
if (!this_class->is_same_class_package(m->method_holder())) {
|
if (!this_class->is_same_class_package(m->method_holder())) {
|
||||||
return true;
|
return true;
|
||||||
@ -2496,7 +2496,7 @@ void ClassVerifier::verify_invoke_init(
|
|||||||
Method* m = InstanceKlass::cast(ref_klass)->uncached_lookup_method(
|
Method* m = InstanceKlass::cast(ref_klass)->uncached_lookup_method(
|
||||||
vmSymbols::object_initializer_name(),
|
vmSymbols::object_initializer_name(),
|
||||||
cp->signature_ref_at(bcs->get_index_u2()),
|
cp->signature_ref_at(bcs->get_index_u2()),
|
||||||
Klass::normal);
|
Klass::find_overpass);
|
||||||
// Do nothing if method is not found. Let resolution detect the error.
|
// Do nothing if method is not found. Let resolution detect the error.
|
||||||
if (m != NULL) {
|
if (m != NULL) {
|
||||||
instanceKlassHandle mh(THREAD, m->method_holder());
|
instanceKlassHandle mh(THREAD, m->method_holder());
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 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
|
||||||
@ -289,11 +289,11 @@ void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle kl
|
|||||||
// returns first instance method
|
// returns first instance method
|
||||||
// Looks up method in classes, then looks up local default methods
|
// Looks up method in classes, then looks up local default methods
|
||||||
void LinkResolver::lookup_instance_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) {
|
void LinkResolver::lookup_instance_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) {
|
||||||
Method* result_oop = klass->uncached_lookup_method(name, signature, Klass::normal);
|
Method* result_oop = klass->uncached_lookup_method(name, signature, Klass::find_overpass);
|
||||||
result = methodHandle(THREAD, result_oop);
|
result = methodHandle(THREAD, result_oop);
|
||||||
while (!result.is_null() && result->is_static() && result->method_holder()->super() != NULL) {
|
while (!result.is_null() && result->is_static() && result->method_holder()->super() != NULL) {
|
||||||
KlassHandle super_klass = KlassHandle(THREAD, result->method_holder()->super());
|
KlassHandle super_klass = KlassHandle(THREAD, result->method_holder()->super());
|
||||||
result = methodHandle(THREAD, super_klass->uncached_lookup_method(name, signature, Klass::normal));
|
result = methodHandle(THREAD, super_klass->uncached_lookup_method(name, signature, Klass::find_overpass));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (klass->oop_is_array()) {
|
if (klass->oop_is_array()) {
|
||||||
@ -320,7 +320,8 @@ int LinkResolver::vtable_index_of_interface_method(KlassHandle klass,
|
|||||||
// First check in default method array
|
// First check in default method array
|
||||||
if (!resolved_method->is_abstract() &&
|
if (!resolved_method->is_abstract() &&
|
||||||
(InstanceKlass::cast(klass())->default_methods() != NULL)) {
|
(InstanceKlass::cast(klass())->default_methods() != NULL)) {
|
||||||
int index = InstanceKlass::find_method_index(InstanceKlass::cast(klass())->default_methods(), name, signature, false, false);
|
int index = InstanceKlass::find_method_index(InstanceKlass::cast(klass())->default_methods(),
|
||||||
|
name, signature, Klass::find_overpass, Klass::find_static);
|
||||||
if (index >= 0 ) {
|
if (index >= 0 ) {
|
||||||
vtable_index = InstanceKlass::cast(klass())->default_vtable_indices()->at(index);
|
vtable_index = InstanceKlass::cast(klass())->default_vtable_indices()->at(index);
|
||||||
}
|
}
|
||||||
|
@ -115,6 +115,7 @@ oop Universe::_the_min_jint_string = NULL;
|
|||||||
LatestMethodCache* Universe::_finalizer_register_cache = NULL;
|
LatestMethodCache* Universe::_finalizer_register_cache = NULL;
|
||||||
LatestMethodCache* Universe::_loader_addClass_cache = NULL;
|
LatestMethodCache* Universe::_loader_addClass_cache = NULL;
|
||||||
LatestMethodCache* Universe::_pd_implies_cache = NULL;
|
LatestMethodCache* Universe::_pd_implies_cache = NULL;
|
||||||
|
LatestMethodCache* Universe::_throw_illegal_access_error_cache = NULL;
|
||||||
oop Universe::_out_of_memory_error_java_heap = NULL;
|
oop Universe::_out_of_memory_error_java_heap = NULL;
|
||||||
oop Universe::_out_of_memory_error_metaspace = NULL;
|
oop Universe::_out_of_memory_error_metaspace = NULL;
|
||||||
oop Universe::_out_of_memory_error_class_metaspace = NULL;
|
oop Universe::_out_of_memory_error_class_metaspace = NULL;
|
||||||
@ -130,7 +131,6 @@ oop Universe::_virtual_machine_error_instance = NULL;
|
|||||||
oop Universe::_vm_exception = NULL;
|
oop Universe::_vm_exception = NULL;
|
||||||
oop Universe::_allocation_context_notification_obj = NULL;
|
oop Universe::_allocation_context_notification_obj = NULL;
|
||||||
|
|
||||||
Method* Universe::_throw_illegal_access_error = NULL;
|
|
||||||
Array<int>* Universe::_the_empty_int_array = NULL;
|
Array<int>* Universe::_the_empty_int_array = NULL;
|
||||||
Array<u2>* Universe::_the_empty_short_array = NULL;
|
Array<u2>* Universe::_the_empty_short_array = NULL;
|
||||||
Array<Klass*>* Universe::_the_empty_klass_array = NULL;
|
Array<Klass*>* Universe::_the_empty_klass_array = NULL;
|
||||||
@ -236,6 +236,7 @@ void Universe::serialize(SerializeClosure* f, bool do_all) {
|
|||||||
_finalizer_register_cache->serialize(f);
|
_finalizer_register_cache->serialize(f);
|
||||||
_loader_addClass_cache->serialize(f);
|
_loader_addClass_cache->serialize(f);
|
||||||
_pd_implies_cache->serialize(f);
|
_pd_implies_cache->serialize(f);
|
||||||
|
_throw_illegal_access_error_cache->serialize(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Universe::check_alignment(uintx size, uintx alignment, const char* name) {
|
void Universe::check_alignment(uintx size, uintx alignment, const char* name) {
|
||||||
@ -664,6 +665,7 @@ jint universe_init() {
|
|||||||
Universe::_finalizer_register_cache = new LatestMethodCache();
|
Universe::_finalizer_register_cache = new LatestMethodCache();
|
||||||
Universe::_loader_addClass_cache = new LatestMethodCache();
|
Universe::_loader_addClass_cache = new LatestMethodCache();
|
||||||
Universe::_pd_implies_cache = new LatestMethodCache();
|
Universe::_pd_implies_cache = new LatestMethodCache();
|
||||||
|
Universe::_throw_illegal_access_error_cache = new LatestMethodCache();
|
||||||
|
|
||||||
if (UseSharedSpaces) {
|
if (UseSharedSpaces) {
|
||||||
// Read the data structures supporting the shared spaces (shared
|
// Read the data structures supporting the shared spaces (shared
|
||||||
@ -1016,7 +1018,8 @@ bool universe_post_init() {
|
|||||||
tty->print_cr("Unable to link/verify Unsafe.throwIllegalAccessError method");
|
tty->print_cr("Unable to link/verify Unsafe.throwIllegalAccessError method");
|
||||||
return false; // initialization failed (cannot throw exception yet)
|
return false; // initialization failed (cannot throw exception yet)
|
||||||
}
|
}
|
||||||
Universe::_throw_illegal_access_error = m;
|
Universe::_throw_illegal_access_error_cache->init(
|
||||||
|
SystemDictionary::misc_Unsafe_klass(), m);
|
||||||
|
|
||||||
// Setup method for registering loaded classes in class loader vector
|
// Setup method for registering loaded classes in class loader vector
|
||||||
InstanceKlass::cast(SystemDictionary::ClassLoader_klass())->link_class(CHECK_false);
|
InstanceKlass::cast(SystemDictionary::ClassLoader_klass())->link_class(CHECK_false);
|
||||||
@ -1042,7 +1045,7 @@ bool universe_post_init() {
|
|||||||
return false; // initialization failed
|
return false; // initialization failed
|
||||||
}
|
}
|
||||||
Universe::_pd_implies_cache->init(
|
Universe::_pd_implies_cache->init(
|
||||||
SystemDictionary::ProtectionDomain_klass(), m);;
|
SystemDictionary::ProtectionDomain_klass(), m);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This needs to be done before the first scavenge/gc, since
|
// This needs to be done before the first scavenge/gc, since
|
||||||
|
@ -148,8 +148,7 @@ class Universe: AllStatic {
|
|||||||
static LatestMethodCache* _finalizer_register_cache; // static method for registering finalizable objects
|
static LatestMethodCache* _finalizer_register_cache; // static method for registering finalizable objects
|
||||||
static LatestMethodCache* _loader_addClass_cache; // method for registering loaded classes in class loader vector
|
static LatestMethodCache* _loader_addClass_cache; // method for registering loaded classes in class loader vector
|
||||||
static LatestMethodCache* _pd_implies_cache; // method for checking protection domain attributes
|
static LatestMethodCache* _pd_implies_cache; // method for checking protection domain attributes
|
||||||
|
static LatestMethodCache* _throw_illegal_access_error_cache; // Unsafe.throwIllegalAccessError() method
|
||||||
static Method* _throw_illegal_access_error;
|
|
||||||
|
|
||||||
// preallocated error objects (no backtrace)
|
// preallocated error objects (no backtrace)
|
||||||
static oop _out_of_memory_error_java_heap;
|
static oop _out_of_memory_error_java_heap;
|
||||||
@ -305,6 +304,7 @@ class Universe: AllStatic {
|
|||||||
static Method* loader_addClass_method() { return _loader_addClass_cache->get_method(); }
|
static Method* loader_addClass_method() { return _loader_addClass_cache->get_method(); }
|
||||||
|
|
||||||
static Method* protection_domain_implies_method() { return _pd_implies_cache->get_method(); }
|
static Method* protection_domain_implies_method() { return _pd_implies_cache->get_method(); }
|
||||||
|
static Method* throw_illegal_access_error() { return _throw_illegal_access_error_cache->get_method(); }
|
||||||
|
|
||||||
static oop null_ptr_exception_instance() { return _null_ptr_exception_instance; }
|
static oop null_ptr_exception_instance() { return _null_ptr_exception_instance; }
|
||||||
static oop arithmetic_exception_instance() { return _arithmetic_exception_instance; }
|
static oop arithmetic_exception_instance() { return _arithmetic_exception_instance; }
|
||||||
@ -314,8 +314,6 @@ class Universe: AllStatic {
|
|||||||
static inline oop allocation_context_notification_obj();
|
static inline oop allocation_context_notification_obj();
|
||||||
static inline void set_allocation_context_notification_obj(oop obj);
|
static inline void set_allocation_context_notification_obj(oop obj);
|
||||||
|
|
||||||
static Method* throw_illegal_access_error() { return _throw_illegal_access_error; }
|
|
||||||
|
|
||||||
static Array<int>* the_empty_int_array() { return _the_empty_int_array; }
|
static Array<int>* the_empty_int_array() { return _the_empty_int_array; }
|
||||||
static Array<u2>* the_empty_short_array() { return _the_empty_short_array; }
|
static Array<u2>* the_empty_short_array() { return _the_empty_short_array; }
|
||||||
static Array<Method*>* the_empty_method_array() { return _the_empty_method_array; }
|
static Array<Method*>* the_empty_method_array() { return _the_empty_method_array; }
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 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
|
||||||
@ -71,10 +71,13 @@ Klass* ArrayKlass::find_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) co
|
|||||||
return super()->find_field(name, sig, fd);
|
return super()->find_field(name, sig, fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
Method* ArrayKlass::uncached_lookup_method(Symbol* name, Symbol* signature, MethodLookupMode mode) const {
|
Method* ArrayKlass::uncached_lookup_method(Symbol* name, Symbol* signature, OverpassLookupMode overpass_mode) const {
|
||||||
// There are no methods in an array klass but the super class (Object) has some
|
// There are no methods in an array klass but the super class (Object) has some
|
||||||
assert(super(), "super klass must be present");
|
assert(super(), "super klass must be present");
|
||||||
return super()->uncached_lookup_method(name, signature, mode);
|
// Always ignore overpass methods in superclasses, although technically the
|
||||||
|
// super klass of an array, (j.l.Object) should not have
|
||||||
|
// any overpass methods present.
|
||||||
|
return super()->uncached_lookup_method(name, signature, Klass::skip_overpass);
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayKlass::ArrayKlass(Symbol* name) {
|
ArrayKlass::ArrayKlass(Symbol* name) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 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
|
||||||
@ -82,7 +82,7 @@ class ArrayKlass: public Klass {
|
|||||||
Klass* find_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const;
|
Klass* find_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const;
|
||||||
|
|
||||||
// Lookup operations
|
// Lookup operations
|
||||||
Method* uncached_lookup_method(Symbol* name, Symbol* signature, MethodLookupMode mode) const;
|
Method* uncached_lookup_method(Symbol* name, Symbol* signature, OverpassLookupMode overpass_mode) const;
|
||||||
|
|
||||||
// Casting from Klass*
|
// Casting from Klass*
|
||||||
static ArrayKlass* cast(Klass* k) {
|
static ArrayKlass* cast(Klass* k) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 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
|
||||||
@ -493,12 +493,7 @@ Symbol* ConstantPool::uncached_klass_ref_at_noresolve(int which) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
char* ConstantPool::string_at_noresolve(int which) {
|
char* ConstantPool::string_at_noresolve(int which) {
|
||||||
Symbol* s = unresolved_string_at(which);
|
return unresolved_string_at(which)->as_C_string();
|
||||||
if (s == NULL) {
|
|
||||||
return (char*)"<pseudo-string>";
|
|
||||||
} else {
|
|
||||||
return unresolved_string_at(which)->as_C_string();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicType ConstantPool::basic_type_for_signature_at(int which) {
|
BasicType ConstantPool::basic_type_for_signature_at(int which) {
|
||||||
@ -1828,7 +1823,7 @@ void ConstantPool::patch_resolved_references(GrowableArray<Handle>* cp_patches)
|
|||||||
// explicitly, because it may require scavenging.
|
// explicitly, because it may require scavenging.
|
||||||
int obj_index = cp_to_object_index(index);
|
int obj_index = cp_to_object_index(index);
|
||||||
pseudo_string_at_put(index, obj_index, patch());
|
pseudo_string_at_put(index, obj_index, patch());
|
||||||
DEBUG_ONLY(cp_patches->at_put(index, Handle());)
|
DEBUG_ONLY(cp_patches->at_put(index, Handle());)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 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
|
||||||
@ -48,17 +48,21 @@ class SymbolHashMap;
|
|||||||
class CPSlot VALUE_OBJ_CLASS_SPEC {
|
class CPSlot VALUE_OBJ_CLASS_SPEC {
|
||||||
intptr_t _ptr;
|
intptr_t _ptr;
|
||||||
public:
|
public:
|
||||||
|
enum TagBits { _resolved_value = 0, _symbol_bit = 1, _pseudo_bit = 2, _symbol_mask = 3 };
|
||||||
|
|
||||||
CPSlot(intptr_t ptr): _ptr(ptr) {}
|
CPSlot(intptr_t ptr): _ptr(ptr) {}
|
||||||
CPSlot(Klass* ptr): _ptr((intptr_t)ptr) {}
|
CPSlot(Klass* ptr): _ptr((intptr_t)ptr) {}
|
||||||
CPSlot(Symbol* ptr): _ptr((intptr_t)ptr | 1) {}
|
CPSlot(Symbol* ptr): _ptr((intptr_t)ptr | _symbol_bit) {}
|
||||||
|
CPSlot(Symbol* ptr, int tag_bits): _ptr((intptr_t)ptr | tag_bits) {}
|
||||||
|
|
||||||
intptr_t value() { return _ptr; }
|
intptr_t value() { return _ptr; }
|
||||||
bool is_resolved() { return (_ptr & 1) == 0; }
|
bool is_resolved() { return (_ptr & _symbol_bit ) == _resolved_value; }
|
||||||
bool is_unresolved() { return (_ptr & 1) == 1; }
|
bool is_unresolved() { return (_ptr & _symbol_bit ) != _resolved_value; }
|
||||||
|
bool is_pseudo_string() { return (_ptr & _symbol_mask) == _symbol_bit + _pseudo_bit; }
|
||||||
|
|
||||||
Symbol* get_symbol() {
|
Symbol* get_symbol() {
|
||||||
assert(is_unresolved(), "bad call");
|
assert(is_unresolved(), "bad call");
|
||||||
return (Symbol*)(_ptr & ~1);
|
return (Symbol*)(_ptr & ~_symbol_mask);
|
||||||
}
|
}
|
||||||
Klass* get_klass() {
|
Klass* get_klass() {
|
||||||
assert(is_resolved(), "bad call");
|
assert(is_resolved(), "bad call");
|
||||||
@ -261,7 +265,7 @@ class ConstantPool : public Metadata {
|
|||||||
|
|
||||||
void unresolved_string_at_put(int which, Symbol* s) {
|
void unresolved_string_at_put(int which, Symbol* s) {
|
||||||
release_tag_at_put(which, JVM_CONSTANT_String);
|
release_tag_at_put(which, JVM_CONSTANT_String);
|
||||||
*symbol_at_addr(which) = s;
|
slot_at_put(which, CPSlot(s, CPSlot::_symbol_bit));
|
||||||
}
|
}
|
||||||
|
|
||||||
void int_at_put(int which, jint i) {
|
void int_at_put(int which, jint i) {
|
||||||
@ -405,20 +409,18 @@ class ConstantPool : public Metadata {
|
|||||||
// use pseudo-strings to link themselves to related metaobjects.
|
// use pseudo-strings to link themselves to related metaobjects.
|
||||||
|
|
||||||
bool is_pseudo_string_at(int which) {
|
bool is_pseudo_string_at(int which) {
|
||||||
// A pseudo string is a string that doesn't have a symbol in the cpSlot
|
assert(tag_at(which).is_string(), "Corrupted constant pool");
|
||||||
return unresolved_string_at(which) == NULL;
|
return slot_at(which).is_pseudo_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
oop pseudo_string_at(int which, int obj_index) {
|
oop pseudo_string_at(int which, int obj_index) {
|
||||||
assert(tag_at(which).is_string(), "Corrupted constant pool");
|
assert(is_pseudo_string_at(which), "must be a pseudo-string");
|
||||||
assert(unresolved_string_at(which) == NULL, "shouldn't have symbol");
|
|
||||||
oop s = resolved_references()->obj_at(obj_index);
|
oop s = resolved_references()->obj_at(obj_index);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
oop pseudo_string_at(int which) {
|
oop pseudo_string_at(int which) {
|
||||||
assert(tag_at(which).is_string(), "Corrupted constant pool");
|
assert(is_pseudo_string_at(which), "must be a pseudo-string");
|
||||||
assert(unresolved_string_at(which) == NULL, "shouldn't have symbol");
|
|
||||||
int obj_index = cp_to_object_index(which);
|
int obj_index = cp_to_object_index(which);
|
||||||
oop s = resolved_references()->obj_at(obj_index);
|
oop s = resolved_references()->obj_at(obj_index);
|
||||||
return s;
|
return s;
|
||||||
@ -426,7 +428,8 @@ class ConstantPool : public Metadata {
|
|||||||
|
|
||||||
void pseudo_string_at_put(int which, int obj_index, oop x) {
|
void pseudo_string_at_put(int which, int obj_index, oop x) {
|
||||||
assert(tag_at(which).is_string(), "Corrupted constant pool");
|
assert(tag_at(which).is_string(), "Corrupted constant pool");
|
||||||
unresolved_string_at_put(which, NULL); // indicates patched string
|
Symbol* sym = unresolved_string_at(which);
|
||||||
|
slot_at_put(which, CPSlot(sym, (CPSlot::_symbol_bit | CPSlot::_pseudo_bit)));
|
||||||
string_at_put(which, obj_index, x); // this works just fine
|
string_at_put(which, obj_index, x); // this works just fine
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -443,15 +446,14 @@ class ConstantPool : public Metadata {
|
|||||||
|
|
||||||
Symbol* unresolved_string_at(int which) {
|
Symbol* unresolved_string_at(int which) {
|
||||||
assert(tag_at(which).is_string(), "Corrupted constant pool");
|
assert(tag_at(which).is_string(), "Corrupted constant pool");
|
||||||
Symbol* s = *symbol_at_addr(which);
|
Symbol* sym = slot_at(which).get_symbol();
|
||||||
return s;
|
return sym;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns an UTF8 for a CONSTANT_String entry at a given index.
|
// Returns an UTF8 for a CONSTANT_String entry at a given index.
|
||||||
// UTF8 char* representation was chosen to avoid conversion of
|
// UTF8 char* representation was chosen to avoid conversion of
|
||||||
// java_lang_Strings at resolved entries into Symbol*s
|
// java_lang_Strings at resolved entries into Symbol*s
|
||||||
// or vice versa.
|
// or vice versa.
|
||||||
// Caller is responsible for checking for pseudo-strings.
|
|
||||||
char* string_at_noresolve(int which);
|
char* string_at_noresolve(int which);
|
||||||
|
|
||||||
jint name_and_type_at(int which) {
|
jint name_and_type_at(int which) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 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
|
||||||
@ -1416,18 +1416,21 @@ static int binary_search(Array<Method*>* methods, Symbol* name) {
|
|||||||
|
|
||||||
// find_method looks up the name/signature in the local methods array
|
// find_method looks up the name/signature in the local methods array
|
||||||
Method* InstanceKlass::find_method(Symbol* name, Symbol* signature) const {
|
Method* InstanceKlass::find_method(Symbol* name, Symbol* signature) const {
|
||||||
return find_method_impl(name, signature, false);
|
return find_method_impl(name, signature, find_overpass, find_static);
|
||||||
}
|
}
|
||||||
|
|
||||||
Method* InstanceKlass::find_method_impl(Symbol* name, Symbol* signature, bool skipping_overpass) const {
|
Method* InstanceKlass::find_method_impl(Symbol* name, Symbol* signature,
|
||||||
return InstanceKlass::find_method_impl(methods(), name, signature, skipping_overpass, false);
|
OverpassLookupMode overpass_mode, StaticLookupMode static_mode) const {
|
||||||
|
return InstanceKlass::find_method_impl(methods(), name, signature, overpass_mode, static_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// find_instance_method looks up the name/signature in the local methods array
|
// find_instance_method looks up the name/signature in the local methods array
|
||||||
// and skips over static methods
|
// and skips over static methods
|
||||||
Method* InstanceKlass::find_instance_method(
|
Method* InstanceKlass::find_instance_method(
|
||||||
Array<Method*>* methods, Symbol* name, Symbol* signature) {
|
Array<Method*>* methods, Symbol* name, Symbol* signature) {
|
||||||
Method* meth = InstanceKlass::find_method_impl(methods, name, signature, false, true);
|
Method* meth = InstanceKlass::find_method_impl(methods, name, signature,
|
||||||
|
find_overpass, skip_static);
|
||||||
|
assert(((meth == NULL) || !meth->is_static()), "find_instance_method should have skipped statics");
|
||||||
return meth;
|
return meth;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1440,12 +1443,12 @@ Method* InstanceKlass::find_instance_method(Symbol* name, Symbol* signature) {
|
|||||||
// find_method looks up the name/signature in the local methods array
|
// find_method looks up the name/signature in the local methods array
|
||||||
Method* InstanceKlass::find_method(
|
Method* InstanceKlass::find_method(
|
||||||
Array<Method*>* methods, Symbol* name, Symbol* signature) {
|
Array<Method*>* methods, Symbol* name, Symbol* signature) {
|
||||||
return InstanceKlass::find_method_impl(methods, name, signature, false, false);
|
return InstanceKlass::find_method_impl(methods, name, signature, find_overpass, find_static);
|
||||||
}
|
}
|
||||||
|
|
||||||
Method* InstanceKlass::find_method_impl(
|
Method* InstanceKlass::find_method_impl(
|
||||||
Array<Method*>* methods, Symbol* name, Symbol* signature, bool skipping_overpass, bool skipping_static) {
|
Array<Method*>* methods, Symbol* name, Symbol* signature, OverpassLookupMode overpass_mode, StaticLookupMode static_mode) {
|
||||||
int hit = find_method_index(methods, name, signature, skipping_overpass, skipping_static);
|
int hit = find_method_index(methods, name, signature, overpass_mode, static_mode);
|
||||||
return hit >= 0 ? methods->at(hit): NULL;
|
return hit >= 0 ? methods->at(hit): NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1463,7 +1466,9 @@ bool InstanceKlass::method_matches(Method* m, Symbol* signature, bool skipping_o
|
|||||||
// is important during method resolution to prefer a static method, for example,
|
// is important during method resolution to prefer a static method, for example,
|
||||||
// over an overpass method.
|
// over an overpass method.
|
||||||
int InstanceKlass::find_method_index(
|
int InstanceKlass::find_method_index(
|
||||||
Array<Method*>* methods, Symbol* name, Symbol* signature, bool skipping_overpass, bool skipping_static) {
|
Array<Method*>* methods, Symbol* name, Symbol* signature, OverpassLookupMode overpass_mode, StaticLookupMode static_mode) {
|
||||||
|
bool skipping_overpass = (overpass_mode == skip_overpass);
|
||||||
|
bool skipping_static = (static_mode == skip_static);
|
||||||
int hit = binary_search(methods, name);
|
int hit = binary_search(methods, name);
|
||||||
if (hit != -1) {
|
if (hit != -1) {
|
||||||
Method* m = methods->at(hit);
|
Method* m = methods->at(hit);
|
||||||
@ -1489,7 +1494,7 @@ int InstanceKlass::find_method_index(
|
|||||||
}
|
}
|
||||||
// not found
|
// not found
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
int index = skipping_overpass || skipping_static ? -1 : linear_search(methods, name, signature);
|
int index = (skipping_overpass || skipping_static) ? -1 : linear_search(methods, name, signature);
|
||||||
assert(index == -1, err_msg("binary search should have found entry %d", index));
|
assert(index == -1, err_msg("binary search should have found entry %d", index));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -1515,16 +1520,16 @@ int InstanceKlass::find_method_by_name(
|
|||||||
|
|
||||||
// uncached_lookup_method searches both the local class methods array and all
|
// uncached_lookup_method searches both the local class methods array and all
|
||||||
// superclasses methods arrays, skipping any overpass methods in superclasses.
|
// superclasses methods arrays, skipping any overpass methods in superclasses.
|
||||||
Method* InstanceKlass::uncached_lookup_method(Symbol* name, Symbol* signature, MethodLookupMode mode) const {
|
Method* InstanceKlass::uncached_lookup_method(Symbol* name, Symbol* signature, OverpassLookupMode overpass_mode) const {
|
||||||
MethodLookupMode lookup_mode = mode;
|
OverpassLookupMode overpass_local_mode = overpass_mode;
|
||||||
Klass* klass = const_cast<InstanceKlass*>(this);
|
Klass* klass = const_cast<InstanceKlass*>(this);
|
||||||
while (klass != NULL) {
|
while (klass != NULL) {
|
||||||
Method* method = InstanceKlass::cast(klass)->find_method_impl(name, signature, (lookup_mode == skip_overpass));
|
Method* method = InstanceKlass::cast(klass)->find_method_impl(name, signature, overpass_local_mode, find_static);
|
||||||
if (method != NULL) {
|
if (method != NULL) {
|
||||||
return method;
|
return method;
|
||||||
}
|
}
|
||||||
klass = InstanceKlass::cast(klass)->super();
|
klass = InstanceKlass::cast(klass)->super();
|
||||||
lookup_mode = skip_overpass; // Always ignore overpass methods in superclasses
|
overpass_local_mode = skip_overpass; // Always ignore overpass methods in superclasses
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -1554,7 +1559,7 @@ Method* InstanceKlass::lookup_method_in_ordered_interfaces(Symbol* name,
|
|||||||
}
|
}
|
||||||
// Look up interfaces
|
// Look up interfaces
|
||||||
if (m == NULL) {
|
if (m == NULL) {
|
||||||
m = lookup_method_in_all_interfaces(name, signature, normal);
|
m = lookup_method_in_all_interfaces(name, signature, find_defaults);
|
||||||
}
|
}
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
@ -1564,7 +1569,7 @@ Method* InstanceKlass::lookup_method_in_ordered_interfaces(Symbol* name,
|
|||||||
// They should only be found in the initial InterfaceMethodRef
|
// They should only be found in the initial InterfaceMethodRef
|
||||||
Method* InstanceKlass::lookup_method_in_all_interfaces(Symbol* name,
|
Method* InstanceKlass::lookup_method_in_all_interfaces(Symbol* name,
|
||||||
Symbol* signature,
|
Symbol* signature,
|
||||||
MethodLookupMode mode) const {
|
DefaultsLookupMode defaults_mode) const {
|
||||||
Array<Klass*>* all_ifs = transitive_interfaces();
|
Array<Klass*>* all_ifs = transitive_interfaces();
|
||||||
int num_ifs = all_ifs->length();
|
int num_ifs = all_ifs->length();
|
||||||
InstanceKlass *ik = NULL;
|
InstanceKlass *ik = NULL;
|
||||||
@ -1572,7 +1577,7 @@ Method* InstanceKlass::lookup_method_in_all_interfaces(Symbol* name,
|
|||||||
ik = InstanceKlass::cast(all_ifs->at(i));
|
ik = InstanceKlass::cast(all_ifs->at(i));
|
||||||
Method* m = ik->lookup_method(name, signature);
|
Method* m = ik->lookup_method(name, signature);
|
||||||
if (m != NULL && m->is_public() && !m->is_static() &&
|
if (m != NULL && m->is_public() && !m->is_static() &&
|
||||||
((mode != skip_defaults) || !m->is_default_method())) {
|
((defaults_mode != skip_defaults) || !m->is_default_method())) {
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 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
|
||||||
@ -499,14 +499,15 @@ class InstanceKlass: public Klass {
|
|||||||
static bool method_matches(Method* m, Symbol* signature, bool skipping_overpass, bool skipping_static);
|
static bool method_matches(Method* m, Symbol* signature, bool skipping_overpass, bool skipping_static);
|
||||||
|
|
||||||
// find a local method index in default_methods (returns -1 if not found)
|
// find a local method index in default_methods (returns -1 if not found)
|
||||||
static int find_method_index(Array<Method*>* methods, Symbol* name, Symbol* signature, bool skipping_overpass, bool skipping_static);
|
static int find_method_index(Array<Method*>* methods, Symbol* name, Symbol* signature,
|
||||||
|
OverpassLookupMode overpass_mode, StaticLookupMode static_mode);
|
||||||
|
|
||||||
// lookup operation (returns NULL if not found)
|
// lookup operation (returns NULL if not found)
|
||||||
Method* uncached_lookup_method(Symbol* name, Symbol* signature, MethodLookupMode mode) const;
|
Method* uncached_lookup_method(Symbol* name, Symbol* signature, OverpassLookupMode overpass_mode) const;
|
||||||
|
|
||||||
// lookup a method in all the interfaces that this class implements
|
// lookup a method in all the interfaces that this class implements
|
||||||
// (returns NULL if not found)
|
// (returns NULL if not found)
|
||||||
Method* lookup_method_in_all_interfaces(Symbol* name, Symbol* signature, MethodLookupMode mode) const;
|
Method* lookup_method_in_all_interfaces(Symbol* name, Symbol* signature, DefaultsLookupMode defaults_mode) const;
|
||||||
|
|
||||||
// lookup a method in local defaults then in all interfaces
|
// lookup a method in local defaults then in all interfaces
|
||||||
// (returns NULL if not found)
|
// (returns NULL if not found)
|
||||||
@ -1058,8 +1059,10 @@ private:
|
|||||||
Klass* array_klass_impl(bool or_null, TRAPS);
|
Klass* array_klass_impl(bool or_null, TRAPS);
|
||||||
|
|
||||||
// find a local method (returns NULL if not found)
|
// find a local method (returns NULL if not found)
|
||||||
Method* find_method_impl(Symbol* name, Symbol* signature, bool skipping_overpass) const;
|
Method* find_method_impl(Symbol* name, Symbol* signature,
|
||||||
static Method* find_method_impl(Array<Method*>* methods, Symbol* name, Symbol* signature, bool skipping_overpass, bool skipping_static);
|
OverpassLookupMode overpass_mode, StaticLookupMode static_mode) const;
|
||||||
|
static Method* find_method_impl(Array<Method*>* methods, Symbol* name, Symbol* signature,
|
||||||
|
OverpassLookupMode overpass_mode, StaticLookupMode static_mode);
|
||||||
|
|
||||||
// Free CHeap allocated fields.
|
// Free CHeap allocated fields.
|
||||||
void release_C_heap_structures();
|
void release_C_heap_structures();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 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
|
||||||
@ -140,7 +140,7 @@ Klass* Klass::find_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Method* Klass::uncached_lookup_method(Symbol* name, Symbol* signature, MethodLookupMode mode) const {
|
Method* Klass::uncached_lookup_method(Symbol* name, Symbol* signature, OverpassLookupMode overpass_mode) const {
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
tty->print_cr("Error: uncached_lookup_method called on a klass oop."
|
tty->print_cr("Error: uncached_lookup_method called on a klass oop."
|
||||||
" Likely error: reflection method does not correctly"
|
" Likely error: reflection method does not correctly"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 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
|
||||||
@ -164,7 +164,9 @@ protected:
|
|||||||
void* operator new(size_t size, ClassLoaderData* loader_data, size_t word_size, TRAPS) throw();
|
void* operator new(size_t size, ClassLoaderData* loader_data, size_t word_size, TRAPS) throw();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum MethodLookupMode { normal, skip_overpass, skip_defaults };
|
enum DefaultsLookupMode { find_defaults, skip_defaults };
|
||||||
|
enum OverpassLookupMode { find_overpass, skip_overpass };
|
||||||
|
enum StaticLookupMode { find_static, skip_static };
|
||||||
|
|
||||||
bool is_klass() const volatile { return true; }
|
bool is_klass() const volatile { return true; }
|
||||||
|
|
||||||
@ -413,10 +415,10 @@ protected:
|
|||||||
// lookup operation for MethodLookupCache
|
// lookup operation for MethodLookupCache
|
||||||
friend class MethodLookupCache;
|
friend class MethodLookupCache;
|
||||||
virtual Klass* find_field(Symbol* name, Symbol* signature, fieldDescriptor* fd) const;
|
virtual Klass* find_field(Symbol* name, Symbol* signature, fieldDescriptor* fd) const;
|
||||||
virtual Method* uncached_lookup_method(Symbol* name, Symbol* signature, MethodLookupMode mode) const;
|
virtual Method* uncached_lookup_method(Symbol* name, Symbol* signature, OverpassLookupMode overpass_mode) const;
|
||||||
public:
|
public:
|
||||||
Method* lookup_method(Symbol* name, Symbol* signature) const {
|
Method* lookup_method(Symbol* name, Symbol* signature) const {
|
||||||
return uncached_lookup_method(name, signature, normal);
|
return uncached_lookup_method(name, signature, find_overpass);
|
||||||
}
|
}
|
||||||
|
|
||||||
// array class with specific rank
|
// array class with specific rank
|
||||||
|
@ -649,7 +649,7 @@ bool klassVtable::needs_new_vtable_entry(methodHandle target_method,
|
|||||||
// this check for all access permissions.
|
// this check for all access permissions.
|
||||||
InstanceKlass *sk = InstanceKlass::cast(super);
|
InstanceKlass *sk = InstanceKlass::cast(super);
|
||||||
if (sk->has_miranda_methods()) {
|
if (sk->has_miranda_methods()) {
|
||||||
if (sk->lookup_method_in_all_interfaces(name, signature, Klass::normal) != NULL) {
|
if (sk->lookup_method_in_all_interfaces(name, signature, Klass::find_defaults) != NULL) {
|
||||||
return false; // found a matching miranda; we do not need a new entry
|
return false; // found a matching miranda; we do not need a new entry
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -725,7 +725,7 @@ bool klassVtable::is_miranda(Method* m, Array<Method*>* class_methods,
|
|||||||
&& mo->method_holder() != NULL
|
&& mo->method_holder() != NULL
|
||||||
&& mo->method_holder()->super() != NULL)
|
&& mo->method_holder()->super() != NULL)
|
||||||
{
|
{
|
||||||
mo = mo->method_holder()->super()->uncached_lookup_method(name, signature, Klass::normal);
|
mo = mo->method_holder()->super()->uncached_lookup_method(name, signature, Klass::find_overpass);
|
||||||
}
|
}
|
||||||
if (mo == NULL || mo->access_flags().is_private() ) {
|
if (mo == NULL || mo->access_flags().is_private() ) {
|
||||||
// super class hierarchy does not implement it or protection is different
|
// super class hierarchy does not implement it or protection is different
|
||||||
@ -770,7 +770,7 @@ void klassVtable::add_new_mirandas_to_lists(
|
|||||||
if (is_miranda(im, class_methods, default_methods, super)) { // is it a miranda at all?
|
if (is_miranda(im, class_methods, default_methods, super)) { // is it a miranda at all?
|
||||||
InstanceKlass *sk = InstanceKlass::cast(super);
|
InstanceKlass *sk = InstanceKlass::cast(super);
|
||||||
// check if it is a duplicate of a super's miranda
|
// check if it is a duplicate of a super's miranda
|
||||||
if (sk->lookup_method_in_all_interfaces(im->name(), im->signature(), Klass::normal) == NULL) {
|
if (sk->lookup_method_in_all_interfaces(im->name(), im->signature(), Klass::find_defaults) == NULL) {
|
||||||
new_mirandas->append(im);
|
new_mirandas->append(im);
|
||||||
}
|
}
|
||||||
if (all_mirandas != NULL) {
|
if (all_mirandas != NULL) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 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
|
||||||
@ -300,6 +300,48 @@ JVM_LEAF(jlong, JVM_NanoTime(JNIEnv *env, jclass ignored))
|
|||||||
return os::javaTimeNanos();
|
return os::javaTimeNanos();
|
||||||
JVM_END
|
JVM_END
|
||||||
|
|
||||||
|
// The function below is actually exposed by sun.misc.VM and not
|
||||||
|
// java.lang.System, but we choose to keep it here so that it stays next
|
||||||
|
// to JVM_CurrentTimeMillis and JVM_NanoTime
|
||||||
|
|
||||||
|
const jlong MAX_DIFF_SECS = 0x0100000000; // 2^32
|
||||||
|
const jlong MIN_DIFF_SECS = -MAX_DIFF_SECS; // -2^32
|
||||||
|
|
||||||
|
JVM_LEAF(jlong, JVM_GetNanoTimeAdjustment(JNIEnv *env, jclass ignored, jlong offset_secs))
|
||||||
|
JVMWrapper("JVM_GetNanoTimeAdjustment");
|
||||||
|
jlong seconds;
|
||||||
|
jlong nanos;
|
||||||
|
|
||||||
|
os::javaTimeSystemUTC(seconds, nanos);
|
||||||
|
|
||||||
|
// We're going to verify that the result can fit in a long.
|
||||||
|
// For that we need the difference in seconds between 'seconds'
|
||||||
|
// and 'offset_secs' to be such that:
|
||||||
|
// |seconds - offset_secs| < (2^63/10^9)
|
||||||
|
// We're going to approximate 10^9 ~< 2^30 (1000^3 ~< 1024^3)
|
||||||
|
// which makes |seconds - offset_secs| < 2^33
|
||||||
|
// and we will prefer +/- 2^32 as the maximum acceptable diff
|
||||||
|
// as 2^32 has a more natural feel than 2^33...
|
||||||
|
//
|
||||||
|
// So if |seconds - offset_secs| >= 2^32 - we return a special
|
||||||
|
// sentinel value (-1) which the caller should take as an
|
||||||
|
// exception value indicating that the offset given to us is
|
||||||
|
// too far from range of the current time - leading to too big
|
||||||
|
// a nano adjustment. The caller is expected to recover by
|
||||||
|
// computing a more accurate offset and calling this method
|
||||||
|
// again. (For the record 2^32 secs is ~136 years, so that
|
||||||
|
// should rarely happen)
|
||||||
|
//
|
||||||
|
jlong diff = seconds - offset_secs;
|
||||||
|
if (diff >= MAX_DIFF_SECS || diff <= MIN_DIFF_SECS) {
|
||||||
|
return -1; // sentinel value: the offset is too far off the target
|
||||||
|
}
|
||||||
|
|
||||||
|
// return the adjustment. If you compute a time by adding
|
||||||
|
// this number of nanoseconds along with the number of seconds
|
||||||
|
// in the offset you should get the current UTC time.
|
||||||
|
return (diff * (jlong)1000000000) + nanos;
|
||||||
|
JVM_END
|
||||||
|
|
||||||
JVM_ENTRY(void, JVM_ArrayCopy(JNIEnv *env, jclass ignored, jobject src, jint src_pos,
|
JVM_ENTRY(void, JVM_ArrayCopy(JNIEnv *env, jclass ignored, jobject src, jint src_pos,
|
||||||
jobject dst, jint dst_pos, jint length))
|
jobject dst, jint dst_pos, jint length))
|
||||||
@ -1167,7 +1209,7 @@ JVM_ENTRY(jobject, JVM_DoPrivileged(JNIEnv *env, jclass cls, jobject action, job
|
|||||||
Method* m_oop = object->klass()->uncached_lookup_method(
|
Method* m_oop = object->klass()->uncached_lookup_method(
|
||||||
vmSymbols::run_method_name(),
|
vmSymbols::run_method_name(),
|
||||||
vmSymbols::void_object_signature(),
|
vmSymbols::void_object_signature(),
|
||||||
Klass::normal);
|
Klass::find_overpass);
|
||||||
methodHandle m (THREAD, m_oop);
|
methodHandle m (THREAD, m_oop);
|
||||||
if (m.is_null() || !m->is_method() || !m()->is_public() || m()->is_static()) {
|
if (m.is_null() || !m->is_method() || !m()->is_public() || m()->is_static()) {
|
||||||
THROW_MSG_0(vmSymbols::java_lang_InternalError(), "No run method");
|
THROW_MSG_0(vmSymbols::java_lang_InternalError(), "No run method");
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 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
|
||||||
@ -131,6 +131,9 @@ JVM_CurrentTimeMillis(JNIEnv *env, jclass ignored);
|
|||||||
JNIEXPORT jlong JNICALL
|
JNIEXPORT jlong JNICALL
|
||||||
JVM_NanoTime(JNIEnv *env, jclass ignored);
|
JVM_NanoTime(JNIEnv *env, jclass ignored);
|
||||||
|
|
||||||
|
JNIEXPORT jlong JNICALL
|
||||||
|
JVM_GetNanoTimeAdjustment(JNIEnv *env, jclass ignored, jlong offset_secs);
|
||||||
|
|
||||||
JNIEXPORT void JNICALL
|
JNIEXPORT void JNICALL
|
||||||
JVM_ArrayCopy(JNIEnv *env, jclass ignored, jobject src, jint src_pos,
|
JVM_ArrayCopy(JNIEnv *env, jclass ignored, jobject src, jint src_pos,
|
||||||
jobject dst, jint dst_pos, jint length);
|
jobject dst, jint dst_pos, jint length);
|
||||||
|
@ -3376,7 +3376,9 @@ void VM_RedefineClasses::AdjustCpoolCacheAndVtable::do_klass(Klass* k) {
|
|||||||
// not yet in the vtable, because the vtable setup is in progress.
|
// not yet in the vtable, because the vtable setup is in progress.
|
||||||
// This must be done after we adjust the default_methods and
|
// This must be done after we adjust the default_methods and
|
||||||
// default_vtable_indices for methods already in the vtable.
|
// default_vtable_indices for methods already in the vtable.
|
||||||
|
// If redefining Unsafe, walk all the vtables looking for entries.
|
||||||
if (ik->vtable_length() > 0 && (_the_class_oop->is_interface()
|
if (ik->vtable_length() > 0 && (_the_class_oop->is_interface()
|
||||||
|
|| _the_class_oop == SystemDictionary::misc_Unsafe_klass()
|
||||||
|| ik->is_subtype_of(_the_class_oop))) {
|
|| ik->is_subtype_of(_the_class_oop))) {
|
||||||
// ik->vtable() creates a wrapper object; rm cleans it up
|
// ik->vtable() creates a wrapper object; rm cleans it up
|
||||||
ResourceMark rm(_thread);
|
ResourceMark rm(_thread);
|
||||||
@ -3396,7 +3398,9 @@ void VM_RedefineClasses::AdjustCpoolCacheAndVtable::do_klass(Klass* k) {
|
|||||||
// interface, then we have to call adjust_method_entries() for
|
// interface, then we have to call adjust_method_entries() for
|
||||||
// every InstanceKlass that has an itable since there isn't a
|
// every InstanceKlass that has an itable since there isn't a
|
||||||
// subclass relationship between an interface and an InstanceKlass.
|
// subclass relationship between an interface and an InstanceKlass.
|
||||||
|
// If redefining Unsafe, walk all the itables looking for entries.
|
||||||
if (ik->itable_length() > 0 && (_the_class_oop->is_interface()
|
if (ik->itable_length() > 0 && (_the_class_oop->is_interface()
|
||||||
|
|| _the_class_oop == SystemDictionary::misc_Unsafe_klass()
|
||||||
|| ik->is_subclass_of(_the_class_oop))) {
|
|| ik->is_subclass_of(_the_class_oop))) {
|
||||||
// ik->itable() creates a wrapper object; rm cleans it up
|
// ik->itable() creates a wrapper object; rm cleans it up
|
||||||
ResourceMark rm(_thread);
|
ResourceMark rm(_thread);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 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
|
||||||
@ -405,6 +405,8 @@ bool MethodComparator::pool_constants_same(int cpi_old, int cpi_new) {
|
|||||||
if (strcmp(_old_cp->string_at_noresolve(cpi_old),
|
if (strcmp(_old_cp->string_at_noresolve(cpi_old),
|
||||||
_new_cp->string_at_noresolve(cpi_new)) != 0)
|
_new_cp->string_at_noresolve(cpi_new)) != 0)
|
||||||
return false;
|
return false;
|
||||||
|
if (_old_cp->is_pseudo_string_at(cpi_old) || _new_cp->is_pseudo_string_at(cpi_new))
|
||||||
|
return (_old_cp->is_pseudo_string_at(cpi_old) == _new_cp->is_pseudo_string_at(cpi_new));
|
||||||
} else if (tag_old.is_klass() || tag_old.is_unresolved_klass()) {
|
} else if (tag_old.is_klass() || tag_old.is_unresolved_klass()) {
|
||||||
// tag_old should be klass - 4881222
|
// tag_old should be klass - 4881222
|
||||||
if (! (tag_new.is_unresolved_klass() || tag_new.is_klass()))
|
if (! (tag_new.is_unresolved_klass() || tag_new.is_klass()))
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 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
|
||||||
@ -393,7 +393,7 @@ address NativeLookup::base_library_lookup(const char* class_name, const char* me
|
|||||||
|
|
||||||
// Find method and invoke standard lookup
|
// Find method and invoke standard lookup
|
||||||
methodHandle method (THREAD,
|
methodHandle method (THREAD,
|
||||||
klass->uncached_lookup_method(m_name, s_name, Klass::normal));
|
klass->uncached_lookup_method(m_name, s_name, Klass::find_overpass));
|
||||||
address result = lookup(method, in_base_library, CATCH);
|
address result = lookup(method, in_base_library, CATCH);
|
||||||
assert(in_base_library, "must be in basic library");
|
assert(in_base_library, "must be in basic library");
|
||||||
guarantee(result != NULL, "must be non NULL");
|
guarantee(result != NULL, "must be non NULL");
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 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
|
||||||
@ -173,10 +173,10 @@ class os: AllStatic {
|
|||||||
static jlong javaTimeMillis();
|
static jlong javaTimeMillis();
|
||||||
static jlong javaTimeNanos();
|
static jlong javaTimeNanos();
|
||||||
static void javaTimeNanos_info(jvmtiTimerInfo *info_ptr);
|
static void javaTimeNanos_info(jvmtiTimerInfo *info_ptr);
|
||||||
|
static void javaTimeSystemUTC(jlong &seconds, jlong &nanos);
|
||||||
static void run_periodic_checks();
|
static void run_periodic_checks();
|
||||||
static bool supports_monotonic_clock();
|
static bool supports_monotonic_clock();
|
||||||
|
|
||||||
|
|
||||||
// Returns the elapsed time in seconds since the vm started.
|
// Returns the elapsed time in seconds since the vm started.
|
||||||
static double elapsedTime();
|
static double elapsedTime();
|
||||||
|
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
* @bug 8042235
|
* @bug 8042235
|
||||||
* @summary redefining method used by multiple MethodHandles crashes VM
|
* @summary redefining method used by multiple MethodHandles crashes VM
|
||||||
* @compile -XDignore.symbol.file RedefineMethodUsedByMultipleMethodHandles.java
|
* @compile -XDignore.symbol.file RedefineMethodUsedByMultipleMethodHandles.java
|
||||||
* @ignore 7076820
|
|
||||||
* @run main RedefineMethodUsedByMultipleMethodHandles
|
* @run main RedefineMethodUsedByMultipleMethodHandles
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -28,7 +28,6 @@ import com.oracle.java.testlibrary.*;
|
|||||||
* @bug 8038636
|
* @bug 8038636
|
||||||
* @library /testlibrary
|
* @library /testlibrary
|
||||||
* @build Agent
|
* @build Agent
|
||||||
* @ignore 7076820
|
|
||||||
* @run main ClassFileInstaller Agent
|
* @run main ClassFileInstaller Agent
|
||||||
* @run main Launcher
|
* @run main Launcher
|
||||||
* @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:TypeProfileLevel=222 -XX:ReservedCodeCacheSize=3M Agent
|
* @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:TypeProfileLevel=222 -XX:ReservedCodeCacheSize=3M Agent
|
||||||
|
@ -28,7 +28,6 @@ import com.oracle.java.testlibrary.*;
|
|||||||
* @bug 8040237
|
* @bug 8040237
|
||||||
* @library /testlibrary
|
* @library /testlibrary
|
||||||
* @build Agent Test A B
|
* @build Agent Test A B
|
||||||
* @ignore 7076820
|
|
||||||
* @run main ClassFileInstaller Agent
|
* @run main ClassFileInstaller Agent
|
||||||
* @run main Launcher
|
* @run main Launcher
|
||||||
* @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:TypeProfileLevel=222 -XX:ReservedCodeCacheSize=3M Agent
|
* @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:TypeProfileLevel=222 -XX:ReservedCodeCacheSize=3M Agent
|
||||||
|
@ -41,6 +41,10 @@ public class CompressedClassSpaceSizeInJmapHeap {
|
|||||||
// Compressed Class Space is only available on 64-bit JVMs
|
// Compressed Class Space is only available on 64-bit JVMs
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!Platform.shouldSAAttach()) {
|
||||||
|
System.out.println("SA attach not expected to work - test skipped.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
String pid = Integer.toString(ProcessTools.getProcessId());
|
String pid = Integer.toString(ProcessTools.getProcessId());
|
||||||
|
|
||||||
|
63
hotspot/test/runtime/Unsafe/AllocateInstance.java
Normal file
63
hotspot/test/runtime/Unsafe/AllocateInstance.java
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @summary Verifies the behaviour of Unsafe.allocateInstance
|
||||||
|
* @library /testlibrary
|
||||||
|
* @run main AllocateInstance
|
||||||
|
*/
|
||||||
|
|
||||||
|
import com.oracle.java.testlibrary.*;
|
||||||
|
import sun.misc.Unsafe;
|
||||||
|
import static com.oracle.java.testlibrary.Asserts.*;
|
||||||
|
|
||||||
|
public class AllocateInstance {
|
||||||
|
public static void main(String args[]) throws Exception {
|
||||||
|
Unsafe unsafe = Utils.getUnsafe();
|
||||||
|
|
||||||
|
// allocateInstance() should not result in a call to the constructor
|
||||||
|
TestClass tc = (TestClass)unsafe.allocateInstance(TestClass.class);
|
||||||
|
assertFalse(tc.calledConstructor);
|
||||||
|
|
||||||
|
// allocateInstance() on an abstract class should result in an InstantiationException
|
||||||
|
try {
|
||||||
|
AbstractClass ac = (AbstractClass)unsafe.allocateInstance(AbstractClass.class);
|
||||||
|
throw new RuntimeException("Did not get expected InstantiationException");
|
||||||
|
} catch (InstantiationException e) {
|
||||||
|
// Expected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TestClass {
|
||||||
|
public boolean calledConstructor = false;
|
||||||
|
|
||||||
|
public TestClass() {
|
||||||
|
calledConstructor = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class AbstractClass {
|
||||||
|
public AbstractClass() {}
|
||||||
|
}
|
||||||
|
}
|
66
hotspot/test/runtime/Unsafe/AllocateMemory.java
Normal file
66
hotspot/test/runtime/Unsafe/AllocateMemory.java
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @summary Verifies behaviour of Unsafe.allocateMemory
|
||||||
|
* @library /testlibrary
|
||||||
|
* @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:MallocMaxTestWords=20m AllocateMemory
|
||||||
|
*/
|
||||||
|
|
||||||
|
import com.oracle.java.testlibrary.*;
|
||||||
|
import sun.misc.Unsafe;
|
||||||
|
import static com.oracle.java.testlibrary.Asserts.*;
|
||||||
|
|
||||||
|
public class AllocateMemory {
|
||||||
|
public static void main(String args[]) throws Exception {
|
||||||
|
Unsafe unsafe = Utils.getUnsafe();
|
||||||
|
|
||||||
|
// Allocate a byte, write to the location and read back the value
|
||||||
|
long address = unsafe.allocateMemory(1);
|
||||||
|
assertNotEquals(address, 0L);
|
||||||
|
|
||||||
|
unsafe.putByte(address, Byte.MAX_VALUE);
|
||||||
|
assertEquals(Byte.MAX_VALUE, unsafe.getByte(address));
|
||||||
|
unsafe.freeMemory(address);
|
||||||
|
|
||||||
|
// Call to allocateMemory() with a negative value should result in an IllegalArgumentException
|
||||||
|
try {
|
||||||
|
address = unsafe.allocateMemory(-1);
|
||||||
|
throw new RuntimeException("Did not get expected IllegalArgumentException");
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
// Expected
|
||||||
|
assertNotEquals(address, 0L);
|
||||||
|
}
|
||||||
|
|
||||||
|
// allocateMemory() should throw an OutOfMemoryError when the underlying malloc fails,
|
||||||
|
// we test this by limiting the malloc using -XX:MallocMaxTestWords
|
||||||
|
try {
|
||||||
|
address = unsafe.allocateMemory(20 * 1024 * 1024 * 8);
|
||||||
|
} catch (OutOfMemoryError e) {
|
||||||
|
// Expected
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
throw new RuntimeException("Did not get expected OutOfMemoryError");
|
||||||
|
}
|
||||||
|
}
|
56
hotspot/test/runtime/Unsafe/CopyMemory.java
Normal file
56
hotspot/test/runtime/Unsafe/CopyMemory.java
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @summary Verifies behaviour of Unsafe.copyMemory
|
||||||
|
* @library /testlibrary
|
||||||
|
* @run main CopyMemory
|
||||||
|
*/
|
||||||
|
|
||||||
|
import com.oracle.java.testlibrary.*;
|
||||||
|
import sun.misc.Unsafe;
|
||||||
|
import static com.oracle.java.testlibrary.Asserts.*;
|
||||||
|
|
||||||
|
public class CopyMemory {
|
||||||
|
final static int LENGTH = 8;
|
||||||
|
public static void main(String args[]) throws Exception {
|
||||||
|
Unsafe unsafe = Utils.getUnsafe();
|
||||||
|
long src = unsafe.allocateMemory(LENGTH);
|
||||||
|
long dst = unsafe.allocateMemory(LENGTH);
|
||||||
|
assertNotEquals(src, 0L);
|
||||||
|
assertNotEquals(dst, 0L);
|
||||||
|
|
||||||
|
// call copyMemory() with different lengths and verify the contents of
|
||||||
|
// the destination array
|
||||||
|
for (int i = 0; i < LENGTH; i++) {
|
||||||
|
unsafe.putByte(src + i, (byte)i);
|
||||||
|
unsafe.copyMemory(src, dst, i);
|
||||||
|
for (int j = 0; j < i; j++) {
|
||||||
|
assertEquals(unsafe.getByte(src + j), unsafe.getByte(src + j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unsafe.freeMemory(src);
|
||||||
|
unsafe.freeMemory(dst);
|
||||||
|
}
|
||||||
|
}
|
99
hotspot/test/runtime/Unsafe/DefineClass.java
Normal file
99
hotspot/test/runtime/Unsafe/DefineClass.java
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @summary Verifies the behaviour of Unsafe.defineClass
|
||||||
|
* @library /testlibrary
|
||||||
|
* @run main DefineClass
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.security.ProtectionDomain;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import com.oracle.java.testlibrary.*;
|
||||||
|
import sun.misc.Unsafe;
|
||||||
|
import static com.oracle.java.testlibrary.Asserts.*;
|
||||||
|
|
||||||
|
public class DefineClass {
|
||||||
|
public static void main(String args[]) throws Exception {
|
||||||
|
Unsafe unsafe = Utils.getUnsafe();
|
||||||
|
TestClassLoader classloader = new TestClassLoader();
|
||||||
|
ProtectionDomain pd = new ProtectionDomain(null, null);
|
||||||
|
|
||||||
|
byte klassbuf[] = InMemoryJavaCompiler.compile("TestClass", "class TestClass { }");
|
||||||
|
|
||||||
|
// Invalid class data
|
||||||
|
try {
|
||||||
|
unsafe.defineClass(null, klassbuf, 4, klassbuf.length - 4, classloader, pd);
|
||||||
|
throw new RuntimeException("defineClass did not throw expected ClassFormatError");
|
||||||
|
} catch (ClassFormatError e) {
|
||||||
|
// Expected
|
||||||
|
}
|
||||||
|
|
||||||
|
// Negative offset
|
||||||
|
try {
|
||||||
|
unsafe.defineClass(null, klassbuf, -1, klassbuf.length, classloader, pd);
|
||||||
|
throw new RuntimeException("defineClass did not throw expected IndexOutOfBoundsException");
|
||||||
|
} catch (IndexOutOfBoundsException e) {
|
||||||
|
// Expected
|
||||||
|
}
|
||||||
|
|
||||||
|
// Negative length
|
||||||
|
try {
|
||||||
|
unsafe.defineClass(null, klassbuf, 0, -1, classloader, pd);
|
||||||
|
throw new RuntimeException("defineClass did not throw expected IndexOutOfBoundsException");
|
||||||
|
} catch (IndexOutOfBoundsException e) {
|
||||||
|
// Expected
|
||||||
|
}
|
||||||
|
|
||||||
|
// Offset greater than klassbuf.length
|
||||||
|
try {
|
||||||
|
unsafe.defineClass(null, klassbuf, klassbuf.length + 1, klassbuf.length, classloader, pd);
|
||||||
|
throw new RuntimeException("defineClass did not throw expected IndexOutOfBoundsException");
|
||||||
|
} catch (IndexOutOfBoundsException e) {
|
||||||
|
// Expected
|
||||||
|
}
|
||||||
|
|
||||||
|
// Length greater than klassbuf.length
|
||||||
|
try {
|
||||||
|
unsafe.defineClass(null, klassbuf, 0, klassbuf.length + 1, classloader, pd);
|
||||||
|
throw new RuntimeException("defineClass did not throw expected IndexOutOfBoundsException");
|
||||||
|
} catch (IndexOutOfBoundsException e) {
|
||||||
|
// Expected
|
||||||
|
}
|
||||||
|
|
||||||
|
Class klass = unsafe.defineClass(null, klassbuf, 0, klassbuf.length, classloader, pd);
|
||||||
|
assertEquals(klass.getClassLoader(), classloader);
|
||||||
|
assertEquals(klass.getProtectionDomain(), pd);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class TestClassLoader extends ClassLoader {
|
||||||
|
public TestClassLoader(ClassLoader parent) {
|
||||||
|
super(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestClassLoader() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
65
hotspot/test/runtime/Unsafe/FieldOffset.java
Normal file
65
hotspot/test/runtime/Unsafe/FieldOffset.java
Normal 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @summary Verifies the behaviour of Unsafe.fieldOffset
|
||||||
|
* @library /testlibrary
|
||||||
|
* @run main FieldOffset
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import com.oracle.java.testlibrary.*;
|
||||||
|
import sun.misc.Unsafe;
|
||||||
|
import java.lang.reflect.*;
|
||||||
|
import static com.oracle.java.testlibrary.Asserts.*;
|
||||||
|
|
||||||
|
public class FieldOffset {
|
||||||
|
public static void main(String args[]) throws Exception {
|
||||||
|
Unsafe unsafe = Utils.getUnsafe();
|
||||||
|
Field fields[] = Test.class.getDeclaredFields();
|
||||||
|
|
||||||
|
for (int i = 0; i < fields.length; i++) {
|
||||||
|
int offset = unsafe.fieldOffset(fields[i]);
|
||||||
|
// Ensure we got a valid offset value back
|
||||||
|
assertNotEquals(offset, unsafe.INVALID_FIELD_OFFSET);
|
||||||
|
|
||||||
|
// Make sure the field offset is unique
|
||||||
|
for (int j = 0; j < i; j++) {
|
||||||
|
assertNotEquals(offset, unsafe.fieldOffset(fields[j]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Test {
|
||||||
|
boolean booleanField;
|
||||||
|
byte byteField;
|
||||||
|
char charField;
|
||||||
|
double doubleField;
|
||||||
|
float floatField;
|
||||||
|
int intField;
|
||||||
|
long longField;
|
||||||
|
Object objectField;
|
||||||
|
short shortField;
|
||||||
|
}
|
||||||
|
}
|
46
hotspot/test/runtime/Unsafe/GetField.java
Normal file
46
hotspot/test/runtime/Unsafe/GetField.java
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @summary Verifies behaviour of Unsafe.getField
|
||||||
|
* @library /testlibrary
|
||||||
|
* @run main GetField
|
||||||
|
*/
|
||||||
|
|
||||||
|
import com.oracle.java.testlibrary.*;
|
||||||
|
import sun.misc.Unsafe;
|
||||||
|
import java.lang.reflect.*;
|
||||||
|
import static com.oracle.java.testlibrary.Asserts.*;
|
||||||
|
|
||||||
|
public class GetField {
|
||||||
|
public static void main(String args[]) throws Exception {
|
||||||
|
Unsafe unsafe = Utils.getUnsafe();
|
||||||
|
// Unsafe.INVALID_FIELD_OFFSET is a static final int field,
|
||||||
|
// make sure getField returns the correct field
|
||||||
|
Field field = Unsafe.class.getField("INVALID_FIELD_OFFSET");
|
||||||
|
assertNotEquals(field.getModifiers() & Modifier.FINAL, 0);
|
||||||
|
assertNotEquals(field.getModifiers() & Modifier.STATIC, 0);
|
||||||
|
assertEquals(field.getType(), int.class);
|
||||||
|
}
|
||||||
|
}
|
52
hotspot/test/runtime/Unsafe/GetPutAddress.java
Normal file
52
hotspot/test/runtime/Unsafe/GetPutAddress.java
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* Verify behaviour of Unsafe.get/putAddress and Unsafe.addressSize
|
||||||
|
* @library /testlibrary
|
||||||
|
* @run main GetPutAddress
|
||||||
|
*/
|
||||||
|
|
||||||
|
import com.oracle.java.testlibrary.*;
|
||||||
|
import sun.misc.Unsafe;
|
||||||
|
import static com.oracle.java.testlibrary.Asserts.*;
|
||||||
|
|
||||||
|
public class GetPutAddress {
|
||||||
|
public static void main(String args[]) throws Exception {
|
||||||
|
Unsafe unsafe = Utils.getUnsafe();
|
||||||
|
int addressSize = unsafe.addressSize();
|
||||||
|
// Ensure the size returned from Unsafe.addressSize is correct
|
||||||
|
assertEquals(unsafe.addressSize(), Platform.is32bit() ? 4 : 8);
|
||||||
|
|
||||||
|
// Write the address, read it back and make sure it's the same value
|
||||||
|
long address = unsafe.allocateMemory(addressSize);
|
||||||
|
unsafe.putAddress(address, address);
|
||||||
|
long readAddress = unsafe.getAddress(address);
|
||||||
|
if (addressSize == 4) {
|
||||||
|
readAddress &= 0x00000000FFFFFFFFL;
|
||||||
|
}
|
||||||
|
assertEquals(address, readAddress);
|
||||||
|
unsafe.freeMemory(address);
|
||||||
|
}
|
||||||
|
}
|
59
hotspot/test/runtime/Unsafe/GetPutBoolean.java
Normal file
59
hotspot/test/runtime/Unsafe/GetPutBoolean.java
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @summary Verify behaviour of Unsafe.get/putBoolean
|
||||||
|
* @library /testlibrary
|
||||||
|
* @run main GetPutBoolean
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import com.oracle.java.testlibrary.*;
|
||||||
|
import sun.misc.Unsafe;
|
||||||
|
import static com.oracle.java.testlibrary.Asserts.*;
|
||||||
|
|
||||||
|
public class GetPutBoolean {
|
||||||
|
public static void main(String args[]) throws Exception {
|
||||||
|
Unsafe unsafe = Utils.getUnsafe();
|
||||||
|
Test t = new Test();
|
||||||
|
Field field = Test.class.getField("b1");
|
||||||
|
|
||||||
|
int offset = unsafe.fieldOffset(field);
|
||||||
|
assertEquals(false, unsafe.getBoolean(t, offset));
|
||||||
|
unsafe.putBoolean(t, offset, true);
|
||||||
|
assertEquals(true, unsafe.getBoolean(t, offset));
|
||||||
|
|
||||||
|
boolean arrayBoolean[] = { true, false, false, true };
|
||||||
|
int scale = unsafe.arrayIndexScale(arrayBoolean.getClass());
|
||||||
|
offset = unsafe.arrayBaseOffset(arrayBoolean.getClass());
|
||||||
|
for (int i = 0; i < arrayBoolean.length; i++) {
|
||||||
|
assertEquals(unsafe.getBoolean(arrayBoolean, offset), arrayBoolean[i]);
|
||||||
|
offset += scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Test {
|
||||||
|
public boolean b1 = false;
|
||||||
|
}
|
||||||
|
}
|
64
hotspot/test/runtime/Unsafe/GetPutByte.java
Normal file
64
hotspot/test/runtime/Unsafe/GetPutByte.java
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @summary Verify behaviour of Unsafe.get/putByte
|
||||||
|
* @library /testlibrary
|
||||||
|
* @run main GetPutByte
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import com.oracle.java.testlibrary.*;
|
||||||
|
import sun.misc.Unsafe;
|
||||||
|
import static com.oracle.java.testlibrary.Asserts.*;
|
||||||
|
|
||||||
|
public class GetPutByte {
|
||||||
|
public static void main(String args[]) throws Exception {
|
||||||
|
Unsafe unsafe = Utils.getUnsafe();
|
||||||
|
Test t = new Test();
|
||||||
|
Field field = Test.class.getField("b");
|
||||||
|
|
||||||
|
int offset = unsafe.fieldOffset(field);
|
||||||
|
assertEquals((byte)0, unsafe.getByte(t, offset));
|
||||||
|
unsafe.putByte(t, offset, (byte)1);
|
||||||
|
assertEquals((byte)1, unsafe.getByte(t, offset));
|
||||||
|
|
||||||
|
long address = unsafe.allocateMemory(8);
|
||||||
|
unsafe.putByte(address, (byte)2);
|
||||||
|
assertEquals((byte)2, unsafe.getByte(address));
|
||||||
|
unsafe.freeMemory(address);
|
||||||
|
|
||||||
|
byte arrayByte[] = { -1, 0, 1, 2 };
|
||||||
|
int scale = unsafe.arrayIndexScale(arrayByte.getClass());
|
||||||
|
offset = unsafe.arrayBaseOffset(arrayByte.getClass());
|
||||||
|
for (int i = 0; i < arrayByte.length; i++) {
|
||||||
|
assertEquals(unsafe.getByte(arrayByte, offset), arrayByte[i]);
|
||||||
|
offset += scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Test {
|
||||||
|
public byte b = 0;
|
||||||
|
}
|
||||||
|
}
|
64
hotspot/test/runtime/Unsafe/GetPutChar.java
Normal file
64
hotspot/test/runtime/Unsafe/GetPutChar.java
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @summary Verify behaviour of Unsafe.get/putChar
|
||||||
|
* @library /testlibrary
|
||||||
|
* @run main GetPutChar
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import com.oracle.java.testlibrary.*;
|
||||||
|
import sun.misc.Unsafe;
|
||||||
|
import static com.oracle.java.testlibrary.Asserts.*;
|
||||||
|
|
||||||
|
public class GetPutChar {
|
||||||
|
public static void main(String args[]) throws Exception {
|
||||||
|
Unsafe unsafe = Utils.getUnsafe();
|
||||||
|
Test t = new Test();
|
||||||
|
Field field = Test.class.getField("c");
|
||||||
|
|
||||||
|
int offset = unsafe.fieldOffset(field);
|
||||||
|
assertEquals('\u0000', unsafe.getChar(t, offset));
|
||||||
|
unsafe.putChar(t, offset, '\u0001');
|
||||||
|
assertEquals('\u0001', unsafe.getChar(t, offset));
|
||||||
|
|
||||||
|
long address = unsafe.allocateMemory(8);
|
||||||
|
unsafe.putChar(address, '\u0002');
|
||||||
|
assertEquals('\u0002', unsafe.getChar(address));
|
||||||
|
unsafe.freeMemory(address);
|
||||||
|
|
||||||
|
char arrayChar[] = { '\uabcd', '\u00ff', '\uff00', };
|
||||||
|
int scale = unsafe.arrayIndexScale(arrayChar.getClass());
|
||||||
|
offset = unsafe.arrayBaseOffset(arrayChar.getClass());
|
||||||
|
for (int i = 0; i < arrayChar.length; i++) {
|
||||||
|
assertEquals(unsafe.getChar(arrayChar, offset), arrayChar[i]);
|
||||||
|
offset += scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Test {
|
||||||
|
public char c = '\u0000';
|
||||||
|
}
|
||||||
|
}
|
64
hotspot/test/runtime/Unsafe/GetPutDouble.java
Normal file
64
hotspot/test/runtime/Unsafe/GetPutDouble.java
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @summary Verify behaviour of Unsafe.get/putDouble
|
||||||
|
* @library /testlibrary
|
||||||
|
* @run main GetPutDouble
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import com.oracle.java.testlibrary.*;
|
||||||
|
import sun.misc.Unsafe;
|
||||||
|
import static com.oracle.java.testlibrary.Asserts.*;
|
||||||
|
|
||||||
|
public class GetPutDouble {
|
||||||
|
public static void main(String args[]) throws Exception {
|
||||||
|
Unsafe unsafe = Utils.getUnsafe();
|
||||||
|
Test t = new Test();
|
||||||
|
Field field = Test.class.getField("d");
|
||||||
|
|
||||||
|
int offset = unsafe.fieldOffset(field);
|
||||||
|
assertEquals(-1.0, unsafe.getDouble(t, offset));
|
||||||
|
unsafe.putDouble(t, offset, 0.0);
|
||||||
|
assertEquals(0.0, unsafe.getDouble(t, offset));
|
||||||
|
|
||||||
|
long address = unsafe.allocateMemory(8);
|
||||||
|
unsafe.putDouble(address, 1.0);
|
||||||
|
assertEquals(1.0, unsafe.getDouble(address));
|
||||||
|
unsafe.freeMemory(address);
|
||||||
|
|
||||||
|
double arrayDouble[] = { -1.0, 0.0, 1.0, 2.0 };
|
||||||
|
int scale = unsafe.arrayIndexScale(arrayDouble.getClass());
|
||||||
|
offset = unsafe.arrayBaseOffset(arrayDouble.getClass());
|
||||||
|
for (int i = 0; i < arrayDouble.length; i++) {
|
||||||
|
assertEquals(unsafe.getDouble(arrayDouble, offset), arrayDouble[i]);
|
||||||
|
offset += scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Test {
|
||||||
|
public double d = -1.0;
|
||||||
|
}
|
||||||
|
}
|
64
hotspot/test/runtime/Unsafe/GetPutFloat.java
Normal file
64
hotspot/test/runtime/Unsafe/GetPutFloat.java
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @summary Verify behaviour of Unsafe.get/putFloat
|
||||||
|
* @library /testlibrary
|
||||||
|
* @run main GetPutFloat
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import com.oracle.java.testlibrary.*;
|
||||||
|
import sun.misc.Unsafe;
|
||||||
|
import static com.oracle.java.testlibrary.Asserts.*;
|
||||||
|
|
||||||
|
public class GetPutFloat {
|
||||||
|
public static void main(String args[]) throws Exception {
|
||||||
|
Unsafe unsafe = Utils.getUnsafe();
|
||||||
|
Test t = new Test();
|
||||||
|
Field field = Test.class.getField("f");
|
||||||
|
|
||||||
|
int offset = unsafe.fieldOffset(field);
|
||||||
|
assertEquals(-1.0f, unsafe.getFloat(t, offset));
|
||||||
|
unsafe.putFloat(t, offset, 0.0f);
|
||||||
|
assertEquals(0.0f, unsafe.getFloat(t, offset));
|
||||||
|
|
||||||
|
long address = unsafe.allocateMemory(8);
|
||||||
|
unsafe.putFloat(address, 1.0f);
|
||||||
|
assertEquals(1.0f, unsafe.getFloat(address));
|
||||||
|
unsafe.freeMemory(address);
|
||||||
|
|
||||||
|
float arrayFloat[] = { -1.0f, 0.0f, 1.0f, 2.0f };
|
||||||
|
int scale = unsafe.arrayIndexScale(arrayFloat.getClass());
|
||||||
|
offset = unsafe.arrayBaseOffset(arrayFloat.getClass());
|
||||||
|
for (int i = 0; i < arrayFloat.length; i++) {
|
||||||
|
assertEquals(unsafe.getFloat(arrayFloat, offset), arrayFloat[i]);
|
||||||
|
offset += scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Test {
|
||||||
|
public float f = -1.0f;
|
||||||
|
}
|
||||||
|
}
|
63
hotspot/test/runtime/Unsafe/GetPutInt.java
Normal file
63
hotspot/test/runtime/Unsafe/GetPutInt.java
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @library /testlibrary
|
||||||
|
* @run main GetPutInt
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import com.oracle.java.testlibrary.*;
|
||||||
|
import sun.misc.Unsafe;
|
||||||
|
import static com.oracle.java.testlibrary.Asserts.*;
|
||||||
|
|
||||||
|
public class GetPutInt {
|
||||||
|
public static void main(String args[]) throws Exception {
|
||||||
|
Unsafe unsafe = Utils.getUnsafe();
|
||||||
|
Test t = new Test();
|
||||||
|
Field field = Test.class.getField("i");
|
||||||
|
|
||||||
|
int offset = unsafe.fieldOffset(field);
|
||||||
|
assertEquals(-1, unsafe.getInt(t, offset));
|
||||||
|
unsafe.putInt(t, offset, 0);
|
||||||
|
assertEquals(0, unsafe.getInt(t, offset));
|
||||||
|
|
||||||
|
long address = unsafe.allocateMemory(8);
|
||||||
|
unsafe.putInt(address, 1);
|
||||||
|
assertEquals(1, unsafe.getInt(address));
|
||||||
|
unsafe.freeMemory(address);
|
||||||
|
|
||||||
|
int arrayInt[] = { -1, 0, 1, 2 };
|
||||||
|
int scale = unsafe.arrayIndexScale(arrayInt.getClass());
|
||||||
|
offset = unsafe.arrayBaseOffset(arrayInt.getClass());
|
||||||
|
for (int i = 0; i < arrayInt.length; i++) {
|
||||||
|
assertEquals(unsafe.getInt(arrayInt, offset), arrayInt[i]);
|
||||||
|
offset += scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Test {
|
||||||
|
public int i = -1;
|
||||||
|
}
|
||||||
|
}
|
64
hotspot/test/runtime/Unsafe/GetPutLong.java
Normal file
64
hotspot/test/runtime/Unsafe/GetPutLong.java
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @summary Verify behaviour of Unsafe.get/putLong
|
||||||
|
* @library /testlibrary
|
||||||
|
* @run main GetPutLong
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import com.oracle.java.testlibrary.*;
|
||||||
|
import sun.misc.Unsafe;
|
||||||
|
import static com.oracle.java.testlibrary.Asserts.*;
|
||||||
|
|
||||||
|
public class GetPutLong {
|
||||||
|
public static void main(String args[]) throws Exception {
|
||||||
|
Unsafe unsafe = Utils.getUnsafe();
|
||||||
|
Test t = new Test();
|
||||||
|
Field field = Test.class.getField("l");
|
||||||
|
|
||||||
|
int offset = unsafe.fieldOffset(field);
|
||||||
|
assertEquals(-1L, unsafe.getLong(t, offset));
|
||||||
|
unsafe.putLong(t, offset, 0L);
|
||||||
|
assertEquals(0L, unsafe.getLong(t, offset));
|
||||||
|
|
||||||
|
long address = unsafe.allocateMemory(8);
|
||||||
|
unsafe.putLong(address, 1L);
|
||||||
|
assertEquals(1L, unsafe.getLong(address));
|
||||||
|
unsafe.freeMemory(address);
|
||||||
|
|
||||||
|
long arrayLong[] = { -1, 0, 1, 2 };
|
||||||
|
int scale = unsafe.arrayIndexScale(arrayLong.getClass());
|
||||||
|
offset = unsafe.arrayBaseOffset(arrayLong.getClass());
|
||||||
|
for (int i = 0; i < arrayLong.length; i++) {
|
||||||
|
assertEquals(unsafe.getLong(arrayLong, offset), arrayLong[i]);
|
||||||
|
offset += scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Test {
|
||||||
|
public long l = -1L;
|
||||||
|
}
|
||||||
|
}
|
61
hotspot/test/runtime/Unsafe/GetPutObject.java
Normal file
61
hotspot/test/runtime/Unsafe/GetPutObject.java
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @summary Verify behaviour of Unsafe.get/putObject
|
||||||
|
* @library /testlibrary
|
||||||
|
* @run main GetPutObject
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import com.oracle.java.testlibrary.*;
|
||||||
|
import sun.misc.Unsafe;
|
||||||
|
import static com.oracle.java.testlibrary.Asserts.*;
|
||||||
|
|
||||||
|
public class GetPutObject {
|
||||||
|
public static void main(String args[]) throws Exception {
|
||||||
|
Unsafe unsafe = Utils.getUnsafe();
|
||||||
|
Test t = new Test();
|
||||||
|
Object o = new Object();
|
||||||
|
Field field = Test.class.getField("o");
|
||||||
|
|
||||||
|
int offset = unsafe.fieldOffset(field);
|
||||||
|
assertEquals(t.o, unsafe.getObject(t, offset));
|
||||||
|
|
||||||
|
unsafe.putObject(t, offset, o);
|
||||||
|
assertEquals(o, unsafe.getObject(t, offset));
|
||||||
|
|
||||||
|
Object arrayObject[] = { unsafe, null, new Object() };
|
||||||
|
int scale = unsafe.arrayIndexScale(arrayObject.getClass());
|
||||||
|
offset = unsafe.arrayBaseOffset(arrayObject.getClass());
|
||||||
|
for (int i = 0; i < arrayObject.length; i++) {
|
||||||
|
assertEquals(unsafe.getObject(arrayObject, offset), arrayObject[i]);
|
||||||
|
offset += scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Test {
|
||||||
|
public Object o = new Object();
|
||||||
|
}
|
||||||
|
}
|
64
hotspot/test/runtime/Unsafe/GetPutShort.java
Normal file
64
hotspot/test/runtime/Unsafe/GetPutShort.java
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @summary Verify behaviour of Unsafe.get/putShort
|
||||||
|
* @library /testlibrary
|
||||||
|
* @run main GetPutShort
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import com.oracle.java.testlibrary.*;
|
||||||
|
import sun.misc.Unsafe;
|
||||||
|
import static com.oracle.java.testlibrary.Asserts.*;
|
||||||
|
|
||||||
|
public class GetPutShort {
|
||||||
|
public static void main(String args[]) throws Exception {
|
||||||
|
Unsafe unsafe = Utils.getUnsafe();
|
||||||
|
Test t = new Test();
|
||||||
|
Field field = Test.class.getField("s");
|
||||||
|
|
||||||
|
int offset = unsafe.fieldOffset(field);
|
||||||
|
assertEquals((short)-1, unsafe.getShort(t, offset));
|
||||||
|
unsafe.putShort(t, offset, (short)0);
|
||||||
|
assertEquals((short)0, unsafe.getShort(t, offset));
|
||||||
|
|
||||||
|
long address = unsafe.allocateMemory(8);
|
||||||
|
unsafe.putShort(address, (short)1);
|
||||||
|
assertEquals((short)1, unsafe.getShort(address));
|
||||||
|
unsafe.freeMemory(address);
|
||||||
|
|
||||||
|
short arrayShort[] = { -1, 0, 1, 2 };
|
||||||
|
int scale = unsafe.arrayIndexScale(arrayShort.getClass());
|
||||||
|
offset = unsafe.arrayBaseOffset(arrayShort.getClass());
|
||||||
|
for (int i = 0; i < arrayShort.length; i++) {
|
||||||
|
assertEquals(unsafe.getShort(arrayShort, offset), arrayShort[i]);
|
||||||
|
offset += scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Test {
|
||||||
|
public short s = -1;
|
||||||
|
}
|
||||||
|
}
|
44
hotspot/test/runtime/Unsafe/GetUnsafe.java
Normal file
44
hotspot/test/runtime/Unsafe/GetUnsafe.java
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @summary Verifies that getUnsafe() actually throws SecurityException when unsafeAccess is prohibited.
|
||||||
|
* @library /testlibrary
|
||||||
|
* @run main GetUnsafe
|
||||||
|
*/
|
||||||
|
|
||||||
|
import sun.misc.Unsafe;
|
||||||
|
import static com.oracle.java.testlibrary.Asserts.*;
|
||||||
|
|
||||||
|
public class GetUnsafe {
|
||||||
|
public static void main(String args[]) throws Exception {
|
||||||
|
try {
|
||||||
|
Unsafe unsafe = Unsafe.getUnsafe();
|
||||||
|
} catch (SecurityException e) {
|
||||||
|
// Expected
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
throw new RuntimeException("Did not get expected SecurityException");
|
||||||
|
}
|
||||||
|
}
|
48
hotspot/test/runtime/Unsafe/PageSize.java
Normal file
48
hotspot/test/runtime/Unsafe/PageSize.java
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @summary Make sure pageSize() returns a value that is a power of two
|
||||||
|
* @library /testlibrary
|
||||||
|
* @run main PageSize
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import com.oracle.java.testlibrary.*;
|
||||||
|
import sun.misc.Unsafe;
|
||||||
|
import static com.oracle.java.testlibrary.Asserts.*;
|
||||||
|
|
||||||
|
public class PageSize {
|
||||||
|
public static void main(String args[]) throws Exception {
|
||||||
|
Unsafe unsafe = Utils.getUnsafe();
|
||||||
|
int pageSize = unsafe.pageSize();
|
||||||
|
|
||||||
|
for (int n = 1; n != 0; n <<= 1) {
|
||||||
|
if (pageSize == n) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new RuntimeException("Expected pagesize to be a power of two, actual pagesize:" + pageSize);
|
||||||
|
}
|
||||||
|
}
|
44
hotspot/test/runtime/Unsafe/SetMemory.java
Normal file
44
hotspot/test/runtime/Unsafe/SetMemory.java
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @summary Verifies that setMemory works correctly
|
||||||
|
* @library /testlibrary
|
||||||
|
* @run main SetMemory
|
||||||
|
*/
|
||||||
|
|
||||||
|
import com.oracle.java.testlibrary.*;
|
||||||
|
import sun.misc.Unsafe;
|
||||||
|
import static com.oracle.java.testlibrary.Asserts.*;
|
||||||
|
|
||||||
|
public class SetMemory {
|
||||||
|
public static void main(String args[]) throws Exception {
|
||||||
|
Unsafe unsafe = Utils.getUnsafe();
|
||||||
|
long address = unsafe.allocateMemory(1);
|
||||||
|
assertNotEquals(address, 0L);
|
||||||
|
unsafe.setMemory(address, 1, (byte)17);
|
||||||
|
assertEquals((byte)17, unsafe.getByte(address));
|
||||||
|
unsafe.freeMemory(address);
|
||||||
|
}
|
||||||
|
}
|
49
hotspot/test/runtime/Unsafe/ThrowException.java
Normal file
49
hotspot/test/runtime/Unsafe/ThrowException.java
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @summary Verify that throwException() can throw an exception
|
||||||
|
* @library /testlibrary
|
||||||
|
* @run main ThrowException
|
||||||
|
*/
|
||||||
|
|
||||||
|
import com.oracle.java.testlibrary.*;
|
||||||
|
import sun.misc.Unsafe;
|
||||||
|
import static com.oracle.java.testlibrary.Asserts.*;
|
||||||
|
|
||||||
|
public class ThrowException {
|
||||||
|
public static void main(String args[]) throws Exception {
|
||||||
|
Unsafe unsafe = Utils.getUnsafe();
|
||||||
|
try {
|
||||||
|
unsafe.throwException(new TestException());
|
||||||
|
} catch (Throwable t) {
|
||||||
|
if (t instanceof TestException) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
throw t;
|
||||||
|
}
|
||||||
|
throw new RuntimeException("Did not throw expected TestException");
|
||||||
|
}
|
||||||
|
static class TestException extends Exception {}
|
||||||
|
}
|
@ -0,0 +1,138 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
* @bug 8008678
|
||||||
|
* @summary JSR 292: constant pool reconstitution must support pseudo strings
|
||||||
|
* @library /testlibrary
|
||||||
|
* @compile -XDignore.symbol.file TestLambdaFormRetransformation.java
|
||||||
|
* @run main TestLambdaFormRetransformation
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.instrument.ClassFileTransformer;
|
||||||
|
import java.lang.instrument.IllegalClassFormatException;
|
||||||
|
import java.lang.instrument.Instrumentation;
|
||||||
|
import java.lang.instrument.UnmodifiableClassException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.security.ProtectionDomain;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import com.oracle.java.testlibrary.ExitCode;
|
||||||
|
import com.oracle.java.testlibrary.OutputAnalyzer;
|
||||||
|
import com.oracle.java.testlibrary.ProcessTools;
|
||||||
|
|
||||||
|
public class TestLambdaFormRetransformation {
|
||||||
|
private static String MANIFEST = String.format("Manifest-Version: 1.0\n" +
|
||||||
|
"Premain-Class: %s\n" +
|
||||||
|
"Can-Retransform-Classes: true\n",
|
||||||
|
Agent.class.getName());
|
||||||
|
|
||||||
|
private static String CP = System.getProperty("test.classes");
|
||||||
|
|
||||||
|
public static void main(String args[]) throws Throwable {
|
||||||
|
Path agent = TestLambdaFormRetransformation.buildAgent();
|
||||||
|
OutputAnalyzer oa = ProcessTools.executeTestJvm("-javaagent:" +
|
||||||
|
agent.toAbsolutePath().toString(), "-version");
|
||||||
|
oa.shouldHaveExitValue(ExitCode.OK.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Path buildAgent() throws IOException {
|
||||||
|
Path manifest = TestLambdaFormRetransformation.createManifest();
|
||||||
|
Path jar = Files.createTempFile(Paths.get("."), null, ".jar");
|
||||||
|
|
||||||
|
String[] args = new String[] {
|
||||||
|
"-cfm",
|
||||||
|
jar.toAbsolutePath().toString(),
|
||||||
|
manifest.toAbsolutePath().toString(),
|
||||||
|
"-C",
|
||||||
|
TestLambdaFormRetransformation.CP,
|
||||||
|
Agent.class.getName() + ".class"
|
||||||
|
};
|
||||||
|
|
||||||
|
sun.tools.jar.Main jarTool = new sun.tools.jar.Main(System.out, System.err, "jar");
|
||||||
|
|
||||||
|
if (!jarTool.run(args)) {
|
||||||
|
throw new Error("jar failed: args=" + Arrays.toString(args));
|
||||||
|
}
|
||||||
|
return jar;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Path createManifest() throws IOException {
|
||||||
|
Path manifest = Files.createTempFile(Paths.get("."), null, ".mf");
|
||||||
|
byte[] manifestBytes = TestLambdaFormRetransformation.MANIFEST.getBytes();
|
||||||
|
Files.write(manifest, manifestBytes);
|
||||||
|
return manifest;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Agent implements ClassFileTransformer {
|
||||||
|
private static Runnable lambda = () -> {
|
||||||
|
System.out.println("I'll crash you!");
|
||||||
|
};
|
||||||
|
|
||||||
|
public static void premain(String args, Instrumentation instrumentation) {
|
||||||
|
if (!instrumentation.isRetransformClassesSupported()) {
|
||||||
|
System.out.println("Class retransformation is not supported.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
System.out.println("Calling lambda to ensure that lambda forms were created");
|
||||||
|
|
||||||
|
Agent.lambda.run();
|
||||||
|
|
||||||
|
System.out.println("Registering class file transformer");
|
||||||
|
|
||||||
|
instrumentation.addTransformer(new Agent());
|
||||||
|
|
||||||
|
for (Class c : instrumentation.getAllLoadedClasses()) {
|
||||||
|
if (c.getName().contains("LambdaForm") &&
|
||||||
|
instrumentation.isModifiableClass(c)) {
|
||||||
|
System.out.format("We've found a modifiable lambda form: %s%n", c.getName());
|
||||||
|
try {
|
||||||
|
instrumentation.retransformClasses(c);
|
||||||
|
} catch (UnmodifiableClassException e) {
|
||||||
|
throw new AssertionError("Modification of modifiable class " +
|
||||||
|
"caused UnmodifiableClassException", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String args[]) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] transform(ClassLoader loader,
|
||||||
|
String className,
|
||||||
|
Class<?> classBeingRedefined,
|
||||||
|
ProtectionDomain protectionDomain,
|
||||||
|
byte[] classfileBuffer
|
||||||
|
) throws IllegalClassFormatException {
|
||||||
|
System.out.println("Transforming " + className);
|
||||||
|
return classfileBuffer.clone();
|
||||||
|
}
|
||||||
|
}
|
@ -290,3 +290,4 @@ a12d347f84176200593999f4da91ae2bb86865b2 jdk9-b39
|
|||||||
0dab3e848229127c7aca4c58b98e2d90ba70372f jdk9-b45
|
0dab3e848229127c7aca4c58b98e2d90ba70372f jdk9-b45
|
||||||
74eaf7ad986576c792df4dbff05eed63e5727695 jdk9-b46
|
74eaf7ad986576c792df4dbff05eed63e5727695 jdk9-b46
|
||||||
e391de88e69b59d7c618387e3cf91032f6991ce9 jdk9-b47
|
e391de88e69b59d7c618387e3cf91032f6991ce9 jdk9-b47
|
||||||
|
833051855168a973780fafeb6fc59e7370bcf400 jdk9-b48
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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 <T> 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;
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 <T> specified for the class.
|
||||||
|
*
|
||||||
|
* @return The value of the result.
|
||||||
|
*/
|
||||||
|
public T value();
|
||||||
|
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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>
|
||||||
|
@ -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);
|
||||||
|
@ -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 < 0 || index >= size())
|
||||||
|
*/
|
||||||
|
public abstract Node get(int index)
|
||||||
|
throws XPathException;
|
||||||
|
}
|
@ -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><bar></code> element in
|
<p>This example would select the <code><bar></code> element in
|
||||||
an XML document such as the following:</p>
|
an XML document such as the following:</p>
|
||||||
|
|
||||||
|
<blockquote>
|
||||||
<pre>
|
<pre>
|
||||||
<foo>
|
<foo>
|
||||||
<bar/>
|
<bar/>
|
||||||
</foo>
|
</foo>
|
||||||
</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><bar></code> elements in the following document would be
|
<code><bar></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>
|
||||||
<foo>
|
<foo>
|
||||||
<bar/>
|
<bar/>
|
||||||
<bar/>
|
<bar/>
|
||||||
<bar/>
|
<bar/>
|
||||||
</foo>
|
</foo>
|
||||||
</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><bar></code> elements regardless of their location in a
|
<code><bar></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><foo></code> element:</p>
|
<code><foo></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><foo></code> elements that contain an <code>include</code>
|
<code><foo></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>
|
||||||
<widgets>
|
<widgets>
|
||||||
<widget>
|
<widget>
|
||||||
@ -246,36 +292,88 @@ XML document:</p>
|
|||||||
</widget>
|
</widget>
|
||||||
</widgets>
|
</widgets>
|
||||||
</pre>
|
</pre>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
<p>The <code><widget></code> element can be selected with the
|
<p>
|
||||||
following XPath API code:</p>
|
The <code><widget></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><widget></code> element, a
|
<p>With a reference to the <code><widget></code> element, a
|
||||||
relative XPath expression can now written to select the
|
relative XPath expression can be written to select the
|
||||||
<code><manufacturer></code> child element:</p>
|
<code><manufacturer></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<?> 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>
|
||||||
|
@ -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;
|
||||||
|
}
|
@ -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));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
|
||||||
|
}
|
@ -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;
|
||||||
|
|
||||||
|
}
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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>";
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
123
jaxp/test/javax/xml/jaxp/functional/test/gaptest/Bug4515660.java
Normal file
123
jaxp/test/javax/xml/jaxp/functional/test/gaptest/Bug4515660.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user