This commit is contained in:
Dean Long 2015-01-31 02:42:13 -05:00
commit 5b196d9525
262 changed files with 12246 additions and 3307 deletions

View File

@ -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

View File

@ -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

View File

@ -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)
])

View File

@ -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

View File

@ -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

View File

@ -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

View 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.

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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++)

View File

@ -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;

View File

@ -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)

View File

@ -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

View File

@ -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();
} }

View File

@ -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 {

View File

@ -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());

View File

@ -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);
} }

View File

@ -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

View File

@ -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; }

View File

@ -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) {

View File

@ -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) {

View File

@ -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

View File

@ -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) {

View File

@ -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;
} }
} }

View File

@ -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();

View File

@ -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"

View File

@ -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

View File

@ -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) {

View File

@ -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");

View File

@ -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);

View File

@ -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);

View File

@ -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()))

View File

@ -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");

View File

@ -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();

View File

@ -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
*/ */

View File

@ -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

View File

@ -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

View File

@ -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());

View 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() {}
}
}

View 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");
}
}

View 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);
}
}

View 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();
}
}
}

View File

@ -0,0 +1,65 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* 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;
}
}

View 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);
}
}

View 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);
}
}

View 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;
}
}

View 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;
}
}

View 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';
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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();
}
}

View 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;
}
}

View 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");
}
}

View 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);
}
}

View 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);
}
}

View 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 {}
}

View File

@ -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();
}
}

View File

@ -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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

Some files were not shown because too many files have changed in this diff Show More