Merge
This commit is contained in:
commit
edbc932bc7
1
.hgtags
1
.hgtags
@ -290,3 +290,4 @@ abbfccd659b91a7bb815d5e36fed635dcdd40f31 jdk9-b44
|
||||
bfc24ae2b900187585079bb11e66e459d1e525fe jdk9-b45
|
||||
722378bc599e38d9a1dd484de30f10dfd7b21438 jdk9-b46
|
||||
8327024a99559982b848e9c2191da9c0bf8838fd jdk9-b47
|
||||
b2f9702efbe95527ea3a991474fda23987ff1c5c jdk9-b48
|
||||
|
@ -290,3 +290,4 @@ f7c11da0b0481d49cc7a65a453336c108191e821 jdk9-b42
|
||||
3dd628fde2086218d548841022ee8436b6b88185 jdk9-b45
|
||||
12f1e276447bcc81516e85367d53e4f08897049d jdk9-b46
|
||||
b6cca3e6175a69f39e5799b7349ddb0176630291 jdk9-b47
|
||||
0064e246d83f6f9fc245c19b6d05041ecaf4b6d4 jdk9-b48
|
||||
|
@ -987,3 +987,26 @@ AC_DEFUN_ONCE([BASIC_TEST_USABILITY_ISSUES],
|
||||
IS_RECONFIGURE=no
|
||||
fi
|
||||
])
|
||||
|
||||
# Check for support for specific options in bash
|
||||
AC_DEFUN_ONCE([BASIC_CHECK_BASH_OPTIONS],
|
||||
[
|
||||
# Test if bash supports pipefail.
|
||||
AC_MSG_CHECKING([if bash supports pipefail])
|
||||
if ${BASH} -c 'set -o pipefail'; then
|
||||
BASH_ARGS="$BASH_ARGS -o pipefail"
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([if bash supports errexit (-e)])
|
||||
if ${BASH} -e -c 'true'; then
|
||||
BASH_ARGS="$BASH_ARGS -e"
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
|
||||
AC_SUBST(BASH_ARGS)
|
||||
])
|
||||
|
@ -46,8 +46,12 @@ endif
|
||||
BOOT_JDK := $(JDK_IMAGE_DIR)
|
||||
|
||||
# The bootcycle build has a different output directory
|
||||
BUILD_OUTPUT:=@BUILD_OUTPUT@/bootcycle-build
|
||||
SJAVAC_SERVER_DIR:=$(subst @BUILD_OUTPUT@,$(BUILD_OUTPUT),$(SJAVAC_SERVER_DIR))
|
||||
OLD_BUILD_OUTPUT:=@BUILD_OUTPUT@
|
||||
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
|
||||
JAVAC_CMD:=$(BOOT_JDK)/bin/javac
|
||||
|
@ -113,6 +113,7 @@ HELP_SETUP_DEPENDENCY_HELP
|
||||
|
||||
# Setup tools that requires more complex handling, or that is not needed by the configure script.
|
||||
BASIC_SETUP_COMPLEX_TOOLS
|
||||
BASIC_CHECK_BASH_OPTIONS
|
||||
|
||||
# Check if pkg-config is available.
|
||||
PKG_PROG_PKG_CONFIG
|
||||
|
@ -853,6 +853,7 @@ OS_VERSION_MICRO
|
||||
OS_VERSION_MINOR
|
||||
OS_VERSION_MAJOR
|
||||
PKG_CONFIG
|
||||
BASH_ARGS
|
||||
CODESIGN
|
||||
XATTR
|
||||
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.
|
||||
# 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
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
# 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.
|
||||
|
||||
|
||||
@ -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
|
||||
# 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_INCLUDE="'\"$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_INCLUDE="'\"$INCLUDE \" >> 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 WindowsSdkDir="'\"$WindowsSdkDir \" >> set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE
|
||||
$ECHO "$WINPATH_BASH -c 'echo WINDOWSSDKDIR="'\"$WINDOWSSDKDIR \" >> set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE
|
||||
|
@ -78,6 +78,11 @@ endif
|
||||
OUTPUT_SYNC_SUPPORTED:=@OUTPUT_SYNC_SUPPORTED@
|
||||
OUTPUT_SYNC:=@OUTPUT_SYNC@
|
||||
|
||||
# Override the shell with bash
|
||||
BASH:=@BASH@
|
||||
BASH_ARGS:=@BASH_ARGS@
|
||||
SHELL:=$(BASH) $(BASH_ARGS)
|
||||
|
||||
# The "human readable" name of this configuration
|
||||
CONF_NAME:=@CONF_NAME@
|
||||
|
||||
@ -243,7 +248,7 @@ MAKESUPPORT_OUTPUTDIR=$(BUILD_OUTPUT)/makesupport
|
||||
HOTSPOT_OUTPUTDIR=$(BUILD_OUTPUT)/hotspot
|
||||
JDK_OUTPUTDIR=$(BUILD_OUTPUT)/jdk
|
||||
IMAGES_OUTPUTDIR=$(BUILD_OUTPUT)/images
|
||||
TESTMAKE_OUTPUTDIR=$(BUILD_OUTPUT)/testmake
|
||||
TESTMAKE_OUTPUTDIR=$(BUILD_OUTPUT)/test-make
|
||||
MAKESUPPORT_OUTPUTDIR=$(BUILD_OUTPUT)/make-support
|
||||
|
||||
HOTSPOT_DIST=@HOTSPOT_DIST@
|
||||
@ -495,7 +500,6 @@ endif
|
||||
# Tools adhering to a minimal and common standard of posix compliance.
|
||||
AWK:=@AWK@
|
||||
BASENAME:=@BASENAME@
|
||||
BASH:=@BASH@
|
||||
CAT:=@CAT@
|
||||
CCACHE:=@CCACHE@
|
||||
# CD is going away, but remains to cater for legacy makefiles.
|
||||
|
@ -290,3 +290,4 @@ e27c725d6c9d155667b35255f442d4ceb8c3c084 jdk9-b40
|
||||
9e3f2bed80c0e5a84a256ce41f1d10c5ade48466 jdk9-b45
|
||||
326f2068b4a4c05e2fa27d6acf93eba7b54b090d jdk9-b46
|
||||
ee8447ca632e1d39180b4767c749db101bff7314 jdk9-b47
|
||||
a13c49c5f2899b702652a460ed7aa73123e671e6 jdk9-b48
|
||||
|
@ -450,3 +450,4 @@ c363a8b87e477ee45d6d3cb2a36cb365141bc596 jdk9-b38
|
||||
5dc8184af1e2bb30b0103113d1f1a58a21a80c37 jdk9-b45
|
||||
a184ee1d717297bd35b7c3e35393e137921a3ed2 jdk9-b46
|
||||
3b241fb72b8925b75941d612db762a6d5da66d02 jdk9-b47
|
||||
cc775a4a24c7f5d9e624b4205e9fbd48a17331f6 jdk9-b48
|
||||
|
@ -74,6 +74,12 @@ CFLAGS += -D_REENTRANT
|
||||
# no xlc counterpart for -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
|
||||
|
||||
CFLAGS += $(ARCHFLAG)
|
||||
|
@ -1,16 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# If we're cross compiling use that path for nm
|
||||
if [ "$CROSS_COMPILE_ARCH" != "" ]; then
|
||||
NM=$ALT_COMPILER_PATH/nm
|
||||
else
|
||||
NM=nm
|
||||
fi
|
||||
|
||||
$NM --defined-only $* \
|
||||
| awk '{
|
||||
if ($3 ~ /^_ZTV/ || $3 ~ /^gHotSpotVM/) print "\t" $3 ";"
|
||||
if ($3 ~ /^UseSharedSpaces$/) print "\t" $3 ";"
|
||||
if ($3 ~ /^_ZN9Arguments17SharedArchivePathE$/) print "\t" $3 ";"
|
||||
}' \
|
||||
| sort -u
|
@ -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.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -239,8 +239,14 @@ mapfile_reorder : mapfile $(REORDERFILE)
|
||||
rm -f $@
|
||||
cat $^ > $@
|
||||
|
||||
VMDEF_PAT = ^_ZTV
|
||||
VMDEF_PAT := ^gHotSpotVM|$(VMDEF_PAT)
|
||||
VMDEF_PAT := ^UseSharedSpaces$$|$(VMDEF_PAT)
|
||||
VMDEF_PAT := ^_ZN9Arguments17SharedArchivePathE$$|$(VMDEF_PAT)
|
||||
|
||||
vm.def: $(Res_Files) $(Obj_Files)
|
||||
sh $(GAMMADIR)/make/linux/makefiles/build_vm_def.sh *.o > $@
|
||||
$(QUIETLY) $(NM) --defined-only $(Obj_Files) | sort -k3 -u | \
|
||||
awk '$$3 ~ /$(VMDEF_PAT)/ { print "\t" $$3 ";" }' > $@
|
||||
|
||||
mapfile_ext:
|
||||
rm -f $@
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
// Copyright (c) 1998, 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
|
||||
@ -2996,7 +2996,7 @@ enc_class Fast_Unlock(iRegP oop, iRegP box, o7RegP scratch, iRegP scratch2) %{
|
||||
%}
|
||||
|
||||
enc_class enc_String_Equals(o0RegP str1, o1RegP str2, g3RegI cnt, notemp_iRegI result) %{
|
||||
Label Lword_loop, Lpost_word, Lchar, Lchar_loop, Ldone;
|
||||
Label Lchar, Lchar_loop, Ldone;
|
||||
MacroAssembler _masm(&cbuf);
|
||||
|
||||
Register str1_reg = reg_to_register_object($str1$$reg);
|
||||
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -6194,7 +6194,7 @@ void MacroAssembler::string_indexofC8(Register str1, Register str2,
|
||||
ShortBranchVerifier sbv(this);
|
||||
assert(UseSSE42Intrinsics, "SSE4.2 is required");
|
||||
|
||||
// This method uses pcmpestri inxtruction with bound registers
|
||||
// This method uses pcmpestri instruction with bound registers
|
||||
// inputs:
|
||||
// xmm - substring
|
||||
// rax - substring length (elements count)
|
||||
@ -6355,7 +6355,7 @@ void MacroAssembler::string_indexof(Register str1, Register str2,
|
||||
//
|
||||
assert(int_cnt2 == -1 || (0 < int_cnt2 && int_cnt2 < 8), "should be != 0");
|
||||
|
||||
// This method uses pcmpestri inxtruction with bound registers
|
||||
// This method uses pcmpestri instruction with bound registers
|
||||
// inputs:
|
||||
// xmm - substring
|
||||
// rax - substring length (elements count)
|
||||
@ -6644,7 +6644,6 @@ void MacroAssembler::string_compare(Register str1, Register str2,
|
||||
// start from first character again because it has aligned address.
|
||||
int stride2 = 16;
|
||||
int adr_stride = stride << scale;
|
||||
int adr_stride2 = stride2 << scale;
|
||||
|
||||
assert(result == rax && cnt2 == rdx && cnt1 == rcx, "pcmpestri");
|
||||
// rax and rdx are used by pcmpestri as elements counters
|
||||
@ -6743,7 +6742,7 @@ void MacroAssembler::string_compare(Register str1, Register str2,
|
||||
// inputs:
|
||||
// vec1- substring
|
||||
// rax - negative string length (elements count)
|
||||
// mem - scaned string
|
||||
// mem - scanned string
|
||||
// rdx - string length (elements count)
|
||||
// pcmpmask - cmp mode: 11000 (string compare with negated result)
|
||||
// + 00 (unsigned bytes) or + 01 (unsigned shorts)
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "os_aix.inline.hpp"
|
||||
#include "runtime/handles.inline.hpp"
|
||||
#include "runtime/perfMemory.hpp"
|
||||
#include "services/memTracker.hpp"
|
||||
#include "utilities/exceptions.hpp"
|
||||
|
||||
// put OS-includes here
|
||||
@ -196,12 +197,37 @@ static pid_t filename_to_pid(const char* filename) {
|
||||
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
|
||||
// and is considered a secure location. Returns false if the path
|
||||
// is a symbolic link or if an error occurred.
|
||||
//
|
||||
static bool is_directory_secure(const char* path) {
|
||||
struct stat statbuf;
|
||||
int result = 0;
|
||||
@ -211,38 +237,276 @@ static bool is_directory_secure(const char* path) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// the path exists, now check it's mode
|
||||
if (S_ISLNK(statbuf.st_mode) || !S_ISDIR(statbuf.st_mode)) {
|
||||
// the path represents a link or some non-directory file type,
|
||||
// which is not what we expected. declare it insecure.
|
||||
//
|
||||
// The path exists, see if it is secure.
|
||||
return is_statbuf_secure(&statbuf);
|
||||
}
|
||||
|
||||
// (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;
|
||||
}
|
||||
else {
|
||||
// we have an existing directory, check if the permissions are safe.
|
||||
//
|
||||
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.
|
||||
//
|
||||
return false;
|
||||
|
||||
// The path exists, now check its mode.
|
||||
return is_statbuf_secure(&statbuf);
|
||||
}
|
||||
|
||||
|
||||
// Check to make sure fd1 and fd2 are referencing the same file system object.
|
||||
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 the user name for the given user id
|
||||
//
|
||||
// the caller is expected to free the allocated memory.
|
||||
// Return the user name for the given user id.
|
||||
//
|
||||
// The caller is expected to free the allocated memory.
|
||||
static char* get_user_name(uid_t uid) {
|
||||
|
||||
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.
|
||||
//
|
||||
long bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
|
||||
if (bufsize == -1)
|
||||
bufsize = 1024;
|
||||
@ -344,7 +608,8 @@ static char* get_user_name_slow(int vmid, TRAPS) {
|
||||
strcat(usrdir_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) {
|
||||
FREE_C_HEAP_ARRAY(char, usrdir_name);
|
||||
@ -464,28 +729,7 @@ static void remove_file(const char* path) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 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
|
||||
// Cleanup stale shared memory resources
|
||||
//
|
||||
// This method attempts to remove all stale shared memory files in
|
||||
// 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
|
||||
// determine if the process is alive. If the process is not alive,
|
||||
// any stale file resources are removed.
|
||||
//
|
||||
static void cleanup_sharedmem_resources(const char* dirname) {
|
||||
|
||||
// open the user temp directory
|
||||
DIR* dirp = os::opendir(dirname);
|
||||
|
||||
int saved_cwd_fd;
|
||||
// Open the directory.
|
||||
DIR* dirp = open_directory_secure_cwd(dirname, &saved_cwd_fd);
|
||||
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;
|
||||
}
|
||||
|
||||
if (!is_directory_secure(dirname)) {
|
||||
// the directory is not a secure directory
|
||||
os::closedir(dirp);
|
||||
return;
|
||||
}
|
||||
|
||||
// for each entry in the directory that matches the expected file
|
||||
// For each entry in the directory that matches the expected file
|
||||
// name pattern, determine if the file resources are stale and if
|
||||
// so, remove the file resources. Note, instrumented HotSpot processes
|
||||
// for this user may start and/or terminate during this search and
|
||||
// remove or create new files in this directory. The behavior of this
|
||||
// loop under these conditions is dependent upon the implementation of
|
||||
// opendir/readdir.
|
||||
//
|
||||
struct dirent* entry;
|
||||
char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname), mtInternal);
|
||||
|
||||
errno = 0;
|
||||
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) {
|
||||
|
||||
// attempt to remove all unexpected files, except "." and ".."
|
||||
remove_file(dirname, entry->d_name);
|
||||
// Attempt to remove all unexpected files, except "." and "..".
|
||||
unlink(entry->d_name);
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
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
|
||||
// matches the current process id or the process is not running,
|
||||
// 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
|
||||
// process does not exist, then the file resources are removed.
|
||||
// if kill determines that that we don't have permission to
|
||||
// signal the process, then the file resources are assumed to
|
||||
// be stale and are removed because the resources for such a
|
||||
// process should be in a different user specific directory.
|
||||
//
|
||||
if ((pid == os::current_process_id()) ||
|
||||
(kill(pid, 0) == OS_ERR && (errno == ESRCH || errno == EPERM))) {
|
||||
|
||||
remove_file(dirname, entry->d_name);
|
||||
unlink(entry->d_name);
|
||||
}
|
||||
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
|
||||
// if the directory exists but is either a symlink, is otherwise
|
||||
// insecure, or if an error occurred.
|
||||
//
|
||||
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.
|
||||
//
|
||||
if (mkdir(dirname, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) == OS_ERR) {
|
||||
if (errno == EEXIST) {
|
||||
// The directory already exists and was probably created by another
|
||||
// JVM instance. However, this could also be the result of a
|
||||
// deliberate symlink. Verify that the existing directory is safe.
|
||||
//
|
||||
if (!is_directory_secure(dirname)) {
|
||||
// directory is not secure
|
||||
// Directory is not secure.
|
||||
if (PrintMiscellaneous && Verbose) {
|
||||
warning("%s directory is insecure\n", dirname);
|
||||
}
|
||||
@ -614,19 +850,63 @@ static int create_sharedmem_resources(const char* dirname, const char* filename,
|
||||
return -1;
|
||||
}
|
||||
|
||||
int result;
|
||||
|
||||
RESTARTABLE(::open(filename, O_RDWR|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE), result);
|
||||
if (result == OS_ERR) {
|
||||
if (PrintMiscellaneous && Verbose) {
|
||||
warning("could not create file %s: %s\n", filename, strerror(errno));
|
||||
}
|
||||
int saved_cwd_fd;
|
||||
// Open the directory and set the current working directory to it.
|
||||
DIR* dirp = open_directory_secure_cwd(dirname, &saved_cwd_fd);
|
||||
if (dirp == NULL) {
|
||||
// Directory doesn't exist or is insecure, so cannot create shared
|
||||
// memory file.
|
||||
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
|
||||
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
|
||||
RESTARTABLE(::ftruncate(fd, (off_t)size), result);
|
||||
if (result == OS_ERR) {
|
||||
@ -648,7 +928,14 @@ static int open_sharedmem_file(const char* filename, int oflags, TRAPS) {
|
||||
|
||||
// open the file
|
||||
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);
|
||||
#else
|
||||
RESTARTABLE(::open_o_nofollow(filename, oflags), result);
|
||||
#endif
|
||||
|
||||
if (result == OS_ERR) {
|
||||
if (errno == ENOENT) {
|
||||
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));
|
||||
}
|
||||
}
|
||||
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
|
||||
@ -695,13 +989,21 @@ static char* mmap_create_shared(size_t size) {
|
||||
char* dirname = get_user_tmp_dir(user_name);
|
||||
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_sharedmem_resources(dirname);
|
||||
|
||||
assert(((size > 0) && (size % os::vm_page_size() == 0)),
|
||||
"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, dirname);
|
||||
@ -733,6 +1035,9 @@ static char* mmap_create_shared(size_t size) {
|
||||
// clear the shared memory region
|
||||
(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;
|
||||
}
|
||||
|
||||
@ -807,7 +1112,7 @@ static void mmap_attach_shared(const char* user, int vmid, PerfMemory::PerfMemor
|
||||
char* mapAddress;
|
||||
int result;
|
||||
int fd;
|
||||
size_t size;
|
||||
size_t size = 0;
|
||||
const char* luser = NULL;
|
||||
|
||||
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.
|
||||
if (mode == PerfMemory::PERF_MODE_RO) {
|
||||
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;
|
||||
#endif
|
||||
}
|
||||
else if (mode == PerfMemory::PERF_MODE_RW) {
|
||||
#ifdef LATER
|
||||
mmap_prot = PROT_READ | PROT_WRITE;
|
||||
file_flags = O_RDWR;
|
||||
file_flags = O_RDWR | O_NOFOLLOW;
|
||||
#else
|
||||
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
|
||||
"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.
|
||||
//
|
||||
if (!is_directory_secure(dirname)) {
|
||||
FREE_C_HEAP_ARRAY(char, dirname);
|
||||
FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
|
||||
if (luser != user) {
|
||||
FREE_C_HEAP_ARRAY(char, luser);
|
||||
FREE_C_HEAP_ARRAY(char, luser, mtInternal);
|
||||
}
|
||||
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
|
||||
"Process not found");
|
||||
@ -901,6 +1212,9 @@ static void mmap_attach_shared(const char* user, int vmid, PerfMemory::PerfMemor
|
||||
"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;
|
||||
*sizep = size;
|
||||
|
||||
|
@ -199,15 +199,10 @@ void CodeCache::initialize_heaps() {
|
||||
}
|
||||
guarantee(NonProfiledCodeHeapSize + ProfiledCodeHeapSize + NonNMethodCodeHeapSize <= ReservedCodeCacheSize, "Size check");
|
||||
|
||||
// Align reserved sizes of CodeHeaps
|
||||
size_t non_method_size = ReservedCodeSpace::allocation_align_size_up(NonNMethodCodeHeapSize);
|
||||
size_t profiled_size = ReservedCodeSpace::allocation_align_size_up(ProfiledCodeHeapSize);
|
||||
size_t non_profiled_size = ReservedCodeSpace::allocation_align_size_up(NonProfiledCodeHeapSize);
|
||||
|
||||
// Compute initial sizes of CodeHeaps
|
||||
size_t init_non_method_size = MIN2(InitialCodeCacheSize, non_method_size);
|
||||
size_t init_profiled_size = MIN2(InitialCodeCacheSize, profiled_size);
|
||||
size_t init_non_profiled_size = MIN2(InitialCodeCacheSize, non_profiled_size);
|
||||
// Align CodeHeaps
|
||||
size_t alignment = heap_alignment();
|
||||
size_t non_method_size = align_size_up(NonNMethodCodeHeapSize, alignment);
|
||||
size_t profiled_size = align_size_down(ProfiledCodeHeapSize, alignment);
|
||||
|
||||
// Reserve one continuous chunk of memory for CodeHeaps and split it into
|
||||
// parts for the individual heaps. The memory layout looks like this:
|
||||
@ -216,18 +211,27 @@ void CodeCache::initialize_heaps() {
|
||||
// Profiled nmethods
|
||||
// Non-nmethods
|
||||
// ---------- low ------------
|
||||
ReservedCodeSpace rs = reserve_heap_memory(non_profiled_size + profiled_size + non_method_size);
|
||||
ReservedCodeSpace rs = reserve_heap_memory(ReservedCodeCacheSize);
|
||||
ReservedSpace non_method_space = rs.first_part(non_method_size);
|
||||
ReservedSpace rest = rs.last_part(non_method_size);
|
||||
ReservedSpace profiled_space = rest.first_part(profiled_size);
|
||||
ReservedSpace non_profiled_space = rest.last_part(profiled_size);
|
||||
|
||||
// Non-nmethods (stubs, adapters, ...)
|
||||
add_heap(non_method_space, "CodeHeap 'non-nmethods'", init_non_method_size, CodeBlobType::NonNMethod);
|
||||
add_heap(non_method_space, "CodeHeap 'non-nmethods'", CodeBlobType::NonNMethod);
|
||||
// Tier 2 and tier 3 (profiled) methods
|
||||
add_heap(profiled_space, "CodeHeap 'profiled nmethods'", init_profiled_size, CodeBlobType::MethodProfiled);
|
||||
add_heap(profiled_space, "CodeHeap 'profiled nmethods'", CodeBlobType::MethodProfiled);
|
||||
// Tier 1 and tier 4 (non-profiled) methods and native methods
|
||||
add_heap(non_profiled_space, "CodeHeap 'non-profiled nmethods'", init_non_profiled_size, CodeBlobType::MethodNonProfiled);
|
||||
add_heap(non_profiled_space, "CodeHeap 'non-profiled nmethods'", CodeBlobType::MethodNonProfiled);
|
||||
}
|
||||
|
||||
size_t CodeCache::heap_alignment() {
|
||||
// If large page support is enabled, align code heaps according to large
|
||||
// page size to make sure that code cache is covered by large pages.
|
||||
const size_t page_size = os::can_execute_large_page_memory() ?
|
||||
os::page_size_for_region_unaligned(ReservedCodeCacheSize, 8) :
|
||||
os::vm_page_size();
|
||||
return MAX2(page_size, (size_t) os::vm_allocation_granularity());
|
||||
}
|
||||
|
||||
ReservedCodeSpace CodeCache::reserve_heap_memory(size_t size) {
|
||||
@ -284,7 +288,7 @@ const char* CodeCache::get_code_heap_flag_name(int code_blob_type) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CodeCache::add_heap(ReservedSpace rs, const char* name, size_t size_initial, int code_blob_type) {
|
||||
void CodeCache::add_heap(ReservedSpace rs, const char* name, int code_blob_type) {
|
||||
// Check if heap is needed
|
||||
if (!heap_available(code_blob_type)) {
|
||||
return;
|
||||
@ -295,8 +299,8 @@ void CodeCache::add_heap(ReservedSpace rs, const char* name, size_t size_initial
|
||||
_heaps->append(heap);
|
||||
|
||||
// Reserve Space
|
||||
size_t size_initial = MIN2(InitialCodeCacheSize, rs.size());
|
||||
size_initial = round_to(size_initial, os::vm_page_size());
|
||||
|
||||
if (!heap->reserve(rs, size_initial, CodeCacheSegmentSize)) {
|
||||
vm_exit_during_initialization("Could not reserve enough space for code cache");
|
||||
}
|
||||
@ -840,7 +844,7 @@ void CodeCache::initialize() {
|
||||
} else {
|
||||
// Use a single code heap
|
||||
ReservedCodeSpace rs = reserve_heap_memory(ReservedCodeCacheSize);
|
||||
add_heap(rs, "CodeCache", InitialCodeCacheSize, CodeBlobType::All);
|
||||
add_heap(rs, "CodeCache", CodeBlobType::All);
|
||||
}
|
||||
|
||||
// Initialize ICache flush mechanism
|
||||
|
@ -98,12 +98,13 @@ class CodeCache : AllStatic {
|
||||
// CodeHeap management
|
||||
static void initialize_heaps(); // Initializes the CodeHeaps
|
||||
// Creates a new heap with the given name and size, containing CodeBlobs of the given type
|
||||
static void add_heap(ReservedSpace rs, const char* name, size_t size_initial, int code_blob_type);
|
||||
static void add_heap(ReservedSpace rs, const char* name, int code_blob_type);
|
||||
static CodeHeap* get_code_heap(const CodeBlob* cb); // Returns the CodeHeap for the given CodeBlob
|
||||
static CodeHeap* get_code_heap(int code_blob_type); // Returns the CodeHeap for the given CodeBlobType
|
||||
// Returns the name of the VM option to set the size of the corresponding CodeHeap
|
||||
static const char* get_code_heap_flag_name(int code_blob_type);
|
||||
static bool heap_available(int code_blob_type); // Returns true if an own CodeHeap for the given CodeBlobType is available
|
||||
static size_t heap_alignment(); // Returns the alignment of the CodeHeaps in bytes
|
||||
static ReservedCodeSpace reserve_heap_memory(size_t size); // Reserves one continuous chunk of memory for the CodeHeaps
|
||||
|
||||
// Iteration
|
||||
|
@ -553,7 +553,8 @@ static MethodMatcher::Mode check_mode(char name[], const char*& error_msg) {
|
||||
int match = MethodMatcher::Exact;
|
||||
while (name[0] == '*') {
|
||||
match |= MethodMatcher::Suffix;
|
||||
strcpy(name, name + 1);
|
||||
// Copy remaining string plus NUL to the beginning
|
||||
memmove(name, name + 1, strlen(name + 1) + 1);
|
||||
}
|
||||
|
||||
if (strcmp(name, "*") == 0) return MethodMatcher::Any;
|
||||
@ -689,6 +690,13 @@ static MethodMatcher* scan_flag_and_value(const char* type, const char* line, in
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int skip_whitespace(char* line) {
|
||||
// Skip any leading spaces
|
||||
int whitespace_read = 0;
|
||||
sscanf(line, "%*[ \t]%n", &whitespace_read);
|
||||
return whitespace_read;
|
||||
}
|
||||
|
||||
void CompilerOracle::parse_from_line(char* line) {
|
||||
if (line[0] == '\0') return;
|
||||
if (line[0] == '#') return;
|
||||
@ -755,15 +763,9 @@ void CompilerOracle::parse_from_line(char* line) {
|
||||
|
||||
line += bytes_read;
|
||||
|
||||
// Skip any leading spaces before signature
|
||||
int whitespace_read = 0;
|
||||
sscanf(line, "%*[ \t]%n", &whitespace_read);
|
||||
if (whitespace_read > 0) {
|
||||
line += whitespace_read;
|
||||
}
|
||||
|
||||
// there might be a signature following the method.
|
||||
// signatures always begin with ( so match that by hand
|
||||
line += skip_whitespace(line);
|
||||
if (1 == sscanf(line, "(%254[[);/" RANGEBASE "]%n", sig + 1, &bytes_read)) {
|
||||
sig[0] = '(';
|
||||
line += bytes_read;
|
||||
@ -786,7 +788,9 @@ void CompilerOracle::parse_from_line(char* line) {
|
||||
//
|
||||
// For future extensions: extend scan_flag_and_value()
|
||||
char option[256]; // stores flag for Type (1) and type of Type (2)
|
||||
while (sscanf(line, "%*[ \t]%255[a-zA-Z0-9]%n", option, &bytes_read) == 1) {
|
||||
|
||||
line += skip_whitespace(line);
|
||||
while (sscanf(line, "%255[a-zA-Z0-9]%n", option, &bytes_read) == 1) {
|
||||
if (match != NULL && !_quiet) {
|
||||
// Print out the last match added
|
||||
ttyLocker ttyl;
|
||||
@ -816,6 +820,7 @@ void CompilerOracle::parse_from_line(char* line) {
|
||||
// Type (1) option
|
||||
match = add_option_string(c_name, c_match, m_name, m_match, signature, option, true);
|
||||
}
|
||||
line += skip_whitespace(line);
|
||||
} // while(
|
||||
} else {
|
||||
match = add_predicate(command, c_name, c_match, m_name, m_match, signature);
|
||||
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -1351,7 +1351,6 @@ Node* LibraryCallKit::string_indexOf(Node* string_object, ciTypeArray* target_ar
|
||||
Node* cache = __ ConI(cache_i);
|
||||
Node* md2 = __ ConI(md2_i);
|
||||
Node* lastChar = __ ConI(target_array->char_at(target_length - 1));
|
||||
Node* targetCount = __ ConI(target_length);
|
||||
Node* targetCountLess1 = __ ConI(target_length - 1);
|
||||
Node* targetOffset = __ ConI(targetOffset_i);
|
||||
Node* sourceEnd = __ SubI(__ AddI(sourceOffset, sourceCount), targetCountLess1);
|
||||
@ -1408,8 +1407,6 @@ bool LibraryCallKit::inline_string_indexOf() {
|
||||
Node* arg = argument(1);
|
||||
|
||||
Node* result;
|
||||
// Disable the use of pcmpestri until it can be guaranteed that
|
||||
// the load doesn't cross into the uncommited space.
|
||||
if (Matcher::has_match_rule(Op_StrIndexOf) &&
|
||||
UseSSE42Intrinsics) {
|
||||
// Generate SSE4.2 version of indexOf
|
||||
@ -1421,9 +1418,6 @@ bool LibraryCallKit::inline_string_indexOf() {
|
||||
return true;
|
||||
}
|
||||
|
||||
ciInstanceKlass* str_klass = env()->String_klass();
|
||||
const TypeOopPtr* string_type = TypeOopPtr::make_from_klass(str_klass);
|
||||
|
||||
// Make the merge point
|
||||
RegionNode* result_rgn = new RegionNode(4);
|
||||
Node* result_phi = new PhiNode(result_rgn, TypeInt::INT);
|
||||
|
@ -2475,7 +2475,7 @@ void Scheduling::DoScheduling() {
|
||||
if( iop == Op_Con ) continue; // Do not schedule Top
|
||||
if( iop == Op_Node && // Do not schedule PhiNodes, ProjNodes
|
||||
mach->pipeline() == MachNode::pipeline_class() &&
|
||||
!n->is_SpillCopy() ) // Breakpoints, Prolog, etc
|
||||
!n->is_SpillCopy() && !n->is_MachMerge() ) // Breakpoints, Prolog, etc
|
||||
continue;
|
||||
break; // Funny loop structure to be sure...
|
||||
}
|
||||
|
@ -428,6 +428,7 @@ int PhaseChaitin::possibly_merge_multidef(Node *n, uint k, Block *block, RegToDe
|
||||
// Insert the merge node into the block before the first use.
|
||||
uint use_index = block->find_node(reg2defuse.at(reg).first_use());
|
||||
block->insert_node(merge, use_index++);
|
||||
_cfg.map_node_to_block(merge, block);
|
||||
|
||||
// Let the allocator know about the new node, use the same lrg
|
||||
_lrg_map.extend(merge->_idx, lrg);
|
||||
|
@ -1127,7 +1127,7 @@ static void no_shared_spaces(const char* message) {
|
||||
#endif
|
||||
|
||||
intx Arguments::scaled_compile_threshold(intx threshold, double scale) {
|
||||
if (scale == 1.0 || scale < 0.0) {
|
||||
if (scale == 1.0 || scale <= 0.0) {
|
||||
return threshold;
|
||||
} else {
|
||||
return (intx)(threshold * scale);
|
||||
@ -1143,7 +1143,7 @@ intx Arguments::scaled_freq_log(intx freq_log, double scale) {
|
||||
|
||||
// Check value to avoid calculating log2 of 0.
|
||||
if (scale == 0.0) {
|
||||
return 1;
|
||||
return freq_log;
|
||||
}
|
||||
|
||||
intx scaled_freq = scaled_compile_threshold((intx)1 << freq_log, scale);
|
||||
@ -3479,8 +3479,10 @@ jint Arguments::finalize_vm_init_args(SysClassPath* scp_p, bool scp_assembly_req
|
||||
set_mode_flags(_int);
|
||||
}
|
||||
|
||||
if ((TieredCompilation && CompileThresholdScaling == 0)
|
||||
|| (!TieredCompilation && scaled_compile_threshold(CompileThreshold) == 0)) {
|
||||
// CompileThresholdScaling == 0.0 is same as -Xint: Disable compilation (enable interpreter-only mode),
|
||||
// but like -Xint, leave compilation thresholds unaffected.
|
||||
// With tiered compilation disabled, setting CompileThreshold to 0 disables compilation as well.
|
||||
if ((CompileThresholdScaling == 0.0) || (!TieredCompilation && CompileThreshold == 0)) {
|
||||
set_mode_flags(_int);
|
||||
}
|
||||
|
||||
|
@ -84,6 +84,13 @@ public class CheckCompileThresholdScaling {
|
||||
"-XX:CompileThresholdScaling=0.75",
|
||||
"-version"
|
||||
},
|
||||
{
|
||||
"-XX:-TieredCompilation",
|
||||
"-XX:+PrintFlagsFinal",
|
||||
"-XX:CompileThreshold=1000",
|
||||
"-XX:CompileThresholdScaling=0.0",
|
||||
"-version"
|
||||
},
|
||||
{
|
||||
"-XX:-TieredCompilation",
|
||||
"-XX:+PrintFlagsFinal",
|
||||
@ -107,6 +114,11 @@ public class CheckCompileThresholdScaling {
|
||||
"intx CompileThreshold := 750 {pd product}",
|
||||
"double CompileThresholdScaling := 0.750000 {product}"
|
||||
},
|
||||
{
|
||||
"intx CompileThreshold := 1000 {pd product}",
|
||||
"double CompileThresholdScaling := 0.000000 {product}",
|
||||
"interpreted mode"
|
||||
},
|
||||
{
|
||||
"intx CompileThreshold := 0 {pd product}",
|
||||
"double CompileThresholdScaling := 0.750000 {product}",
|
||||
@ -295,21 +307,21 @@ public class CheckCompileThresholdScaling {
|
||||
"double CompileThresholdScaling := 2.000000 {product}"
|
||||
},
|
||||
{
|
||||
"intx Tier0BackedgeNotifyFreqLog := 0 {product}",
|
||||
"intx Tier0InvokeNotifyFreqLog := 0 {product}",
|
||||
"intx Tier23InlineeNotifyFreqLog := 0 {product}",
|
||||
"intx Tier2BackedgeNotifyFreqLog := 0 {product}",
|
||||
"intx Tier2InvokeNotifyFreqLog := 0 {product}",
|
||||
"intx Tier3BackEdgeThreshold := 0 {product}",
|
||||
"intx Tier3BackedgeNotifyFreqLog := 0 {product}",
|
||||
"intx Tier3CompileThreshold := 0 {product}",
|
||||
"intx Tier3InvocationThreshold := 0 {product}",
|
||||
"intx Tier3InvokeNotifyFreqLog := 0 {product}",
|
||||
"intx Tier3MinInvocationThreshold := 0 {product}",
|
||||
"intx Tier4BackEdgeThreshold := 0 {product}",
|
||||
"intx Tier4CompileThreshold := 0 {product}",
|
||||
"intx Tier4InvocationThreshold := 0 {product}",
|
||||
"intx Tier4MinInvocationThreshold := 0 {product}",
|
||||
"intx Tier0BackedgeNotifyFreqLog := 10 {product}",
|
||||
"intx Tier0InvokeNotifyFreqLog := 7 {product}",
|
||||
"intx Tier23InlineeNotifyFreqLog := 20 {product}",
|
||||
"intx Tier2BackedgeNotifyFreqLog := 14 {product}",
|
||||
"intx Tier2InvokeNotifyFreqLog := 11 {product}",
|
||||
"intx Tier3BackEdgeThreshold := 60000 {product}",
|
||||
"intx Tier3BackedgeNotifyFreqLog := 13 {product}",
|
||||
"intx Tier3CompileThreshold := 2000 {product}",
|
||||
"intx Tier3InvocationThreshold := 200 {product}",
|
||||
"intx Tier3InvokeNotifyFreqLog := 10 {product}",
|
||||
"intx Tier3MinInvocationThreshold := 100 {product}",
|
||||
"intx Tier4BackEdgeThreshold := 40000 {product}",
|
||||
"intx Tier4CompileThreshold := 15000 {product}",
|
||||
"intx Tier4InvocationThreshold := 5000 {product}",
|
||||
"intx Tier4MinInvocationThreshold := 600 {product}",
|
||||
"double CompileThresholdScaling := 0.000000 {product}",
|
||||
"interpreted mode"
|
||||
}
|
||||
|
@ -82,6 +82,9 @@ public class PrintCodeCacheRunner implements CodeCacheCLITestCase.Runner {
|
||||
ExitCode.OK,
|
||||
testCaseDescription.getTestOptions(options,
|
||||
CommandLineOptionTest.prepareBooleanFlag(
|
||||
"PrintCodeCache", printCodeCache)));
|
||||
"PrintCodeCache", printCodeCache),
|
||||
// Do not use large pages to avoid large page
|
||||
// alignment of code heaps affecting their size.
|
||||
"-XX:-UseLargePages"));
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ public class CodeCacheStressRunner {
|
||||
try {
|
||||
// adjust timeout and substract vm init and exit time
|
||||
long timeout = Utils.adjustTimeout(Utils.DEFAULT_TEST_TIMEOUT);
|
||||
timeout *= 0.9;
|
||||
timeout *= 0.8;
|
||||
new TimeLimitedRunner(timeout, 2.0d, this::test).call();
|
||||
} catch (Exception e) {
|
||||
throw new Error("Exception occurred during test execution", e);
|
||||
|
@ -77,7 +77,7 @@ public class OverloadCompileQueueTest implements Runnable {
|
||||
}
|
||||
|
||||
public OverloadCompileQueueTest() {
|
||||
Helper.startInfiniteLoopThread(this::lockUnlock);
|
||||
Helper.startInfiniteLoopThread(this::lockUnlock, 100L);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -99,8 +99,9 @@ public class OverloadCompileQueueTest implements Runnable {
|
||||
|
||||
private void lockUnlock() {
|
||||
try {
|
||||
int sleep = Helper.RNG.nextInt(MAX_SLEEP);
|
||||
Helper.WHITE_BOX.lockCompilation();
|
||||
Thread.sleep(Helper.RNG.nextInt(MAX_SLEEP));
|
||||
Thread.sleep(sleep);
|
||||
} catch (InterruptedException e) {
|
||||
throw new Error("TESTBUG: lockUnlocker thread was unexpectedly interrupted", e);
|
||||
} finally {
|
||||
|
@ -21,12 +21,15 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.File;
|
||||
|
||||
import com.oracle.java.testlibrary.*;
|
||||
|
||||
/*
|
||||
* @test CheckCompileCommandOption
|
||||
* @bug 8055286 8056964 8059847
|
||||
* @summary "Checks parsing of -XX:+CompileCommand=option"
|
||||
* @bug 8055286 8056964 8059847 8069035
|
||||
* @summary "Checks parsing of -XX:CompileCommand=option"
|
||||
* @library /testlibrary
|
||||
* @run main CheckCompileCommandOption
|
||||
*/
|
||||
@ -45,38 +48,69 @@ public class CheckCompileCommandOption {
|
||||
// have the the following types: intx, uintx, bool, ccstr,
|
||||
// ccstrlist, and double.
|
||||
|
||||
private static final String[][] FILE_ARGUMENTS = {
|
||||
{
|
||||
"-XX:CompileCommandFile=" + new File(System.getProperty("test.src", "."), "command1.txt"),
|
||||
"-version"
|
||||
},
|
||||
{
|
||||
"-XX:CompileCommandFile=" + new File(System.getProperty("test.src", "."), "command2.txt"),
|
||||
"-version"
|
||||
}
|
||||
};
|
||||
|
||||
private static final String[][] FILE_EXPECTED_OUTPUT = {
|
||||
{
|
||||
"CompileCommand: option com/oracle/Test.test bool MyBoolOption1 = true",
|
||||
"CompileCommand: option com/oracle/Test.test bool MyBoolOption2 = true",
|
||||
"CompileCommand: option com/oracle/Test.test bool MyBoolOption3 = true",
|
||||
"CompileCommand: option com/oracle/Test.test bool MyBoolOption4 = true",
|
||||
"CompileCommand: option com/oracle/Test.test bool MyBoolOption5 = true",
|
||||
"CompileCommand: option com/oracle/Test.test bool MyBoolOption6 = true",
|
||||
"CompileCommand: option com/oracle/Test.test bool MyBoolOption7 = true",
|
||||
"CompileCommand: option com/oracle/Test.test bool MyBoolOption8 = true",
|
||||
"CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption9 = true",
|
||||
"CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption10 = true",
|
||||
"CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption11 = true",
|
||||
"CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption12 = true",
|
||||
"CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption13 = true",
|
||||
"CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption14 = true",
|
||||
"CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption15 = true",
|
||||
"CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption16 = true"
|
||||
},
|
||||
{
|
||||
"CompileCommand: option Test.test const char* MyListOption = '_foo _bar'",
|
||||
"CompileCommand: option Test.test const char* MyStrOption = '_foo'",
|
||||
"CompileCommand: option Test.test bool MyBoolOption = false",
|
||||
"CompileCommand: option Test.test intx MyIntxOption = -1",
|
||||
"CompileCommand: option Test.test uintx MyUintxOption = 1",
|
||||
"CompileCommand: option Test.test bool MyFlag = true",
|
||||
"CompileCommand: option Test.test double MyDoubleOption = 1.123000"
|
||||
}
|
||||
};
|
||||
|
||||
private static final String[][] TYPE_1_ARGUMENTS = {
|
||||
{
|
||||
"-XX:CompileCommand=option,com/oracle/Test.test,MyBoolOption1",
|
||||
"-XX:CompileCommand=option,com/oracle/Test,test,MyBoolOption2",
|
||||
"-XX:CompileCommand=option,com.oracle.Test::test,MyBoolOption3",
|
||||
"-XX:CompileCommand=option,com/oracle/Test::test,MyBoolOption4",
|
||||
"-version"
|
||||
},
|
||||
{
|
||||
"-XX:CompileCommand=option,com/oracle/Test.test,MyBoolOption1,MyBoolOption2",
|
||||
"-version"
|
||||
},
|
||||
{
|
||||
"-XX:CompileCommand=option,com/oracle/Test,test,MyBoolOption1,MyBoolOption2",
|
||||
"-XX:CompileCommand=option,com/oracle/Test.test,MyBoolOption5,MyBoolOption6",
|
||||
"-XX:CompileCommand=option,com/oracle/Test,test,MyBoolOption7,MyBoolOption8",
|
||||
"-version"
|
||||
}
|
||||
};
|
||||
|
||||
private static final String[][] TYPE_1_EXPECTED_OUTPUTS = {
|
||||
{
|
||||
"CompilerOracle: option com/oracle/Test.test bool MyBoolOption1 = true",
|
||||
"CompilerOracle: option com/oracle/Test.test bool MyBoolOption2 = true",
|
||||
"CompilerOracle: option com/oracle/Test.test bool MyBoolOption3 = true",
|
||||
"CompilerOracle: option com/oracle/Test.test bool MyBoolOption4 = true"
|
||||
},
|
||||
{
|
||||
"CompilerOracle: option com/oracle/Test.test bool MyBoolOption1 = true",
|
||||
"CompilerOracle: option com/oracle/Test.test bool MyBoolOption2 = true",
|
||||
},
|
||||
{
|
||||
"CompilerOracle: option com/oracle/Test.test bool MyBoolOption1 = true",
|
||||
"CompilerOracle: option com/oracle/Test.test bool MyBoolOption2 = true",
|
||||
"CompileCommand: option com/oracle/Test.test bool MyBoolOption1 = true",
|
||||
"CompileCommand: option com/oracle/Test.test bool MyBoolOption2 = true",
|
||||
"CompileCommand: option com/oracle/Test.test bool MyBoolOption3 = true",
|
||||
"CompileCommand: option com/oracle/Test.test bool MyBoolOption4 = true",
|
||||
"CompileCommand: option com/oracle/Test.test bool MyBoolOption5 = true",
|
||||
"CompileCommand: option com/oracle/Test.test bool MyBoolOption6 = true",
|
||||
"CompileCommand: option com/oracle/Test.test bool MyBoolOption7 = true",
|
||||
"CompileCommand: option com/oracle/Test.test bool MyBoolOption8 = true"
|
||||
}
|
||||
};
|
||||
|
||||
@ -88,38 +122,28 @@ public class CheckCompileCommandOption {
|
||||
"-XX:CompileCommand=option,Test::test,intx,MyIntxOption,-1",
|
||||
"-XX:CompileCommand=option,Test::test,uintx,MyUintxOption,1",
|
||||
"-XX:CompileCommand=option,Test::test,MyFlag",
|
||||
"-XX:CompileCommand=option,Test::test,double,MyDoubleOption,1.123",
|
||||
"-version"
|
||||
},
|
||||
{
|
||||
"-XX:CompileCommand=option,Test.test,double,MyDoubleOption,1.123",
|
||||
"-version"
|
||||
},
|
||||
{
|
||||
"-XX:CompileCommand=option,Test::test,bool,MyBoolOption,false,intx,MyIntxOption,-1,uintx,MyUintxOption,1,MyFlag,double,MyDoubleOption,1.123",
|
||||
"-XX:CompileCommand=option,Test::test,double,MyDoubleOption1,1.123",
|
||||
"-XX:CompileCommand=option,Test.test,double,MyDoubleOption2,1.123",
|
||||
"-XX:CompileCommand=option,Test::test,bool,MyBoolOptionX,false,intx,MyIntxOptionX,-1,uintx,MyUintxOptionX,1,MyFlagX,double,MyDoubleOptionX,1.123",
|
||||
"-version"
|
||||
}
|
||||
};
|
||||
|
||||
private static final String[][] TYPE_2_EXPECTED_OUTPUTS = {
|
||||
{
|
||||
"CompilerOracle: option Test.test const char* MyListOption = '_foo _bar'",
|
||||
"CompilerOracle: option Test.test const char* MyStrOption = '_foo'",
|
||||
"CompilerOracle: option Test.test bool MyBoolOption = false",
|
||||
"CompilerOracle: option Test.test intx MyIntxOption = -1",
|
||||
"CompilerOracle: option Test.test uintx MyUintxOption = 1",
|
||||
"CompilerOracle: option Test.test bool MyFlag = true",
|
||||
"CompilerOracle: option Test.test double MyDoubleOption = 1.123000"
|
||||
},
|
||||
{
|
||||
"CompilerOracle: option Test.test double MyDoubleOption = 1.123000"
|
||||
},
|
||||
{
|
||||
"CompilerOracle: option Test.test bool MyBoolOption = false",
|
||||
"CompilerOracle: option Test.test intx MyIntxOption = -1",
|
||||
"CompilerOracle: option Test.test uintx MyUintxOption = 1",
|
||||
"CompilerOracle: option Test.test bool MyFlag = true",
|
||||
"CompilerOracle: option Test.test double MyDoubleOption = 1.123000",
|
||||
"CompileCommand: option Test.test const char* MyListOption = '_foo _bar'",
|
||||
"CompileCommand: option Test.test const char* MyStrOption = '_foo'",
|
||||
"CompileCommand: option Test.test bool MyBoolOption = false",
|
||||
"CompileCommand: option Test.test intx MyIntxOption = -1",
|
||||
"CompileCommand: option Test.test uintx MyUintxOption = 1",
|
||||
"CompileCommand: option Test.test bool MyFlag = true",
|
||||
"CompileCommand: option Test.test double MyDoubleOption1 = 1.123000",
|
||||
"CompileCommand: option Test.test double MyDoubleOption2 = 1.123000",
|
||||
"CompileCommand: option Test.test bool MyBoolOptionX = false",
|
||||
"CompileCommand: option Test.test intx MyIntxOptionX = -1",
|
||||
"CompileCommand: option Test.test uintx MyUintxOptionX = 1",
|
||||
"CompileCommand: option Test.test bool MyFlagX = true",
|
||||
"CompileCommand: option Test.test double MyDoubleOptionX = 1.123000",
|
||||
}
|
||||
};
|
||||
|
||||
@ -172,7 +196,7 @@ public class CheckCompileCommandOption {
|
||||
out.shouldContain(expected_output);
|
||||
}
|
||||
|
||||
out.shouldNotContain("CompileCommand: unrecognized line");
|
||||
out.shouldNotContain("CompileCommand: An error occured during parsing");
|
||||
out.shouldHaveExitValue(0);
|
||||
}
|
||||
|
||||
@ -183,7 +207,7 @@ public class CheckCompileCommandOption {
|
||||
pb = ProcessTools.createJavaProcessBuilder(arguments);
|
||||
out = new OutputAnalyzer(pb.start());
|
||||
|
||||
out.shouldContain("CompileCommand: unrecognized line");
|
||||
out.shouldContain("CompileCommand: An error occured during parsing");
|
||||
out.shouldHaveExitValue(0);
|
||||
}
|
||||
|
||||
@ -212,5 +236,10 @@ public class CheckCompileCommandOption {
|
||||
for (String[] arguments: TYPE_2_INVALID_ARGUMENTS) {
|
||||
verifyInvalidOption(arguments);
|
||||
}
|
||||
|
||||
// Check if commands in command file are parsed correctly
|
||||
for (int i = 0; i < FILE_ARGUMENTS.length; i++) {
|
||||
verifyValidOption(FILE_ARGUMENTS[i], FILE_EXPECTED_OUTPUT[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
78
hotspot/test/compiler/oracle/TestCompileCommand.java
Normal file
78
hotspot/test/compiler/oracle/TestCompileCommand.java
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.File;
|
||||
|
||||
import com.oracle.java.testlibrary.*;
|
||||
|
||||
/*
|
||||
* @test TestCompileCommand
|
||||
* @bug 8069389
|
||||
* @summary "Regression tests of -XX:CompileCommand"
|
||||
* @library /testlibrary
|
||||
* @run main TestCompileCommand
|
||||
*/
|
||||
|
||||
public class TestCompileCommand {
|
||||
|
||||
private static final String[][] ARGUMENTS = {
|
||||
{
|
||||
"-XX:CompileCommand=print,*01234567890123456789012345678901234567890123456789,*0123456789012345678901234567890123456789",
|
||||
"-version"
|
||||
}
|
||||
};
|
||||
|
||||
private static final String[][] OUTPUTS = {
|
||||
{
|
||||
"print *01234567890123456789012345678901234567890123456789.*0123456789012345678901234567890123456789"
|
||||
}
|
||||
};
|
||||
|
||||
private static void verifyValidOption(String[] arguments, String[] expected_outputs) throws Exception {
|
||||
ProcessBuilder pb;
|
||||
OutputAnalyzer out;
|
||||
|
||||
pb = ProcessTools.createJavaProcessBuilder(arguments);
|
||||
out = new OutputAnalyzer(pb.start());
|
||||
|
||||
for (String expected_output : expected_outputs) {
|
||||
out.shouldContain(expected_output);
|
||||
}
|
||||
|
||||
out.shouldNotContain("CompileCommand: An error occured during parsing");
|
||||
out.shouldHaveExitValue(0);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
if (ARGUMENTS.length != OUTPUTS.length) {
|
||||
throw new RuntimeException("Test is set up incorrectly: length of arguments and expected outputs for type (1) options does not match.");
|
||||
}
|
||||
|
||||
// Check if type (1) options are parsed correctly
|
||||
for (int i = 0; i < ARGUMENTS.length; i++) {
|
||||
verifyValidOption(ARGUMENTS[i], OUTPUTS[i]);
|
||||
}
|
||||
}
|
||||
}
|
12
hotspot/test/compiler/oracle/command1.txt
Normal file
12
hotspot/test/compiler/oracle/command1.txt
Normal file
@ -0,0 +1,12 @@
|
||||
option,com/oracle/Test.test,MyBoolOption1
|
||||
option,com/oracle/Test,test,MyBoolOption2
|
||||
option,com.oracle.Test::test,MyBoolOption3
|
||||
option,com/oracle/Test::test,MyBoolOption4
|
||||
option,com/oracle/Test.test,MyBoolOption5,MyBoolOption6
|
||||
option,com/oracle/Test,test,MyBoolOption7,MyBoolOption8
|
||||
option,com/oracle/Test.test(I),MyBoolOption9
|
||||
option,com/oracle/Test,test,(I),MyBoolOption10
|
||||
option,com.oracle.Test::test(I),MyBoolOption11
|
||||
option,com/oracle/Test::test(I),MyBoolOption12
|
||||
option,com/oracle/Test.test(I),MyBoolOption13,MyBoolOption14
|
||||
option,com/oracle/Test,test(I),MyBoolOption15,MyBoolOption16
|
7
hotspot/test/compiler/oracle/command2.txt
Normal file
7
hotspot/test/compiler/oracle/command2.txt
Normal file
@ -0,0 +1,7 @@
|
||||
option,Test::test,ccstrlist,MyListOption,_foo,_bar
|
||||
option,Test::test,ccstr,MyStrOption,_foo
|
||||
option,Test::test,bool,MyBoolOption,false
|
||||
option,Test::test,intx,MyIntxOption,-1
|
||||
option,Test::test,uintx,MyUintxOption,1
|
||||
option,Test::test,MyFlag
|
||||
option,Test::test,double,MyDoubleOption,1.123
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 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
|
||||
@ -119,13 +119,13 @@ public class TestRTMTotalCountIncrRate extends CommandLineOptionTest {
|
||||
return new String[] { getMethodWithLockName() };
|
||||
}
|
||||
|
||||
public void lock(booleab forceAbort) {
|
||||
public void lock(boolean forceAbort) {
|
||||
synchronized(monitor) {
|
||||
if (forceAbort) {
|
||||
// We're calling native method in order to force
|
||||
// abort. It's done by explicit xabort call emitted
|
||||
// in SharedRuntime::generate_native_wrapper.
|
||||
// If an actuall JNI call will be replaced by
|
||||
// If an actual JNI call will be replaced by
|
||||
// intrinsic - we'll be in trouble, since xabort
|
||||
// will be no longer called and test may fail.
|
||||
UNSAFE.addressSize();
|
||||
|
@ -34,7 +34,6 @@ import com.oracle.java.testlibrary.InfiniteLoop;
|
||||
/*
|
||||
* @test
|
||||
* @bug 8059624 8064669
|
||||
* @ignore 8066998
|
||||
* @library /testlibrary /../../test/lib
|
||||
* @build ForceNMethodSweepTest
|
||||
* @run main ClassFileInstaller sun.hotspot.WhiteBox
|
||||
@ -42,7 +41,7 @@ import com.oracle.java.testlibrary.InfiniteLoop;
|
||||
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
|
||||
* -XX:-TieredCompilation -XX:+WhiteBoxAPI
|
||||
* -XX:CompileCommand=compileonly,SimpleTestCase$Helper::*
|
||||
* ForceNMethodSweepTest
|
||||
* -XX:-BackgroundCompilation ForceNMethodSweepTest
|
||||
* @summary testing of WB::forceNMethodSweep
|
||||
*/
|
||||
public class ForceNMethodSweepTest extends CompilerWhiteBoxTest {
|
||||
|
@ -290,3 +290,4 @@ a12d347f84176200593999f4da91ae2bb86865b2 jdk9-b39
|
||||
0dab3e848229127c7aca4c58b98e2d90ba70372f jdk9-b45
|
||||
74eaf7ad986576c792df4dbff05eed63e5727695 jdk9-b46
|
||||
e391de88e69b59d7c618387e3cf91032f6991ce9 jdk9-b47
|
||||
833051855168a973780fafeb6fc59e7370bcf400 jdk9-b48
|
||||
|
@ -270,8 +270,8 @@ public final class BasisLibrary {
|
||||
if (Double.isNaN(start))
|
||||
return(EMPTYSTRING);
|
||||
|
||||
final int strlen = value.length();
|
||||
int istart = (int)Math.round(start) - 1;
|
||||
final int strlen = value.length();
|
||||
int istart = (int)Math.round(start) - 1;
|
||||
|
||||
if (istart > strlen)
|
||||
return(EMPTYSTRING);
|
||||
@ -292,10 +292,11 @@ public final class BasisLibrary {
|
||||
public static String substringF(String value, double start, double length) {
|
||||
if (Double.isInfinite(start) ||
|
||||
Double.isNaN(start) ||
|
||||
Double.isNaN(length))
|
||||
Double.isNaN(length) ||
|
||||
length < 0)
|
||||
return(EMPTYSTRING);
|
||||
|
||||
int istart = (int)Math.round(start) - 1;
|
||||
int istart = (int)Math.round(start) - 1;
|
||||
final int isum;
|
||||
if (Double.isInfinite(length))
|
||||
isum = Integer.MAX_VALUE;
|
||||
|
@ -1,15 +1,15 @@
|
||||
/*
|
||||
* reserved comment block
|
||||
* DO NOT REMOVE OR ALTER!
|
||||
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* 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");
|
||||
* 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
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@ -17,36 +17,21 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* 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;
|
||||
|
||||
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 javax.xml.namespace.NamespaceContext;
|
||||
import com.sun.org.apache.xpath.internal.objects.XObject;
|
||||
import javax.xml.namespace.QName;
|
||||
import javax.xml.xpath.XPathExpressionException;
|
||||
import javax.xml.transform.TransformerException;
|
||||
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.XPathVariableResolver;
|
||||
import javax.xml.xpath.XPathConstants;
|
||||
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.DOMImplementation;
|
||||
import org.w3c.dom.traversal.NodeIterator;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
|
||||
import org.w3c.dom.Node;
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
/**
|
||||
@ -54,22 +39,10 @@ import org.xml.sax.InputSource;
|
||||
*
|
||||
* @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;
|
||||
|
||||
// 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()
|
||||
* 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,
|
||||
JAXPPrefixResolver prefixResolver,
|
||||
XPathFunctionResolver functionResolver,
|
||||
XPathVariableResolver variableResolver ) {
|
||||
XPathVariableResolver variableResolver) {
|
||||
this(xpath, prefixResolver, functionResolver, variableResolver,
|
||||
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,
|
||||
JAXPPrefixResolver prefixResolver,XPathFunctionResolver functionResolver,
|
||||
XPathVariableResolver variableResolver, boolean featureSecureProcessing,
|
||||
boolean useServicesMechanism, FeatureManager featureManager ) {
|
||||
boolean useServiceMechanism, FeatureManager featureManager) {
|
||||
this.xpath = xpath;
|
||||
this.prefixResolver = prefixResolver;
|
||||
this.functionResolver = functionResolver;
|
||||
this.variableResolver = variableResolver;
|
||||
this.featureSecureProcessing = featureSecureProcessing;
|
||||
this.useServicesMechanism = useServicesMechanism;
|
||||
this.useServiceMechanism = useServiceMechanism;
|
||||
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;
|
||||
}
|
||||
|
||||
public Object eval(Object item, QName returnType)
|
||||
throws javax.xml.transform.TransformerException {
|
||||
XObject resultObject = eval ( item );
|
||||
return getResultAsType( resultObject, returnType );
|
||||
XObject resultObject = eval(item, xpath);
|
||||
return getResultAsType(resultObject, returnType);
|
||||
}
|
||||
|
||||
private XObject eval ( Object contextItem )
|
||||
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>.
|
||||
*/
|
||||
@Override
|
||||
public Object evaluate(Object item, QName returnType)
|
||||
throws XPathExpressionException {
|
||||
//Validating parameters to enforce constraints defined by JAXP spec
|
||||
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 );
|
||||
}
|
||||
isSupported(returnType);
|
||||
try {
|
||||
return eval( item, returnType);
|
||||
} catch ( java.lang.NullPointerException npe ) {
|
||||
return eval(item, returnType);
|
||||
} catch (java.lang.NullPointerException npe) {
|
||||
// If VariableResolver returns null Or if we get
|
||||
// NullPointerException at this stage for some other reason
|
||||
// then we have to reurn XPathException
|
||||
throw new XPathExpressionException ( npe );
|
||||
} catch ( javax.xml.transform.TransformerException te ) {
|
||||
throw new XPathExpressionException (npe);
|
||||
} catch (javax.xml.transform.TransformerException te) {
|
||||
Throwable nestedException = te.getException();
|
||||
if ( nestedException instanceof javax.xml.xpath.XPathFunctionException ) {
|
||||
if (nestedException instanceof javax.xml.xpath.XPathFunctionException) {
|
||||
throw (javax.xml.xpath.XPathFunctionException)nestedException;
|
||||
} else {
|
||||
// For any other exceptions we need to throw
|
||||
// XPathExpressionException ( as per spec )
|
||||
throw new XPathExpressionException( te);
|
||||
// XPathExpressionException (as per spec)
|
||||
throw new XPathExpressionException(te);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Evaluate the compiled XPath expression in the specified context and
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@Override
|
||||
public String evaluate(Object item)
|
||||
throws XPathExpressionException {
|
||||
return (String)this.evaluate( item, XPathConstants.STRING );
|
||||
return (String)this.evaluate(item, XPathConstants.STRING);
|
||||
}
|
||||
|
||||
|
||||
|
||||
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>.
|
||||
*/
|
||||
@Override
|
||||
public Object evaluate(InputSource source, QName returnType)
|
||||
throws XPathExpressionException {
|
||||
if ( ( source == null ) || ( returnType == null ) ) {
|
||||
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 );
|
||||
}
|
||||
isSupported (returnType);
|
||||
try {
|
||||
if ( dbf == null ) {
|
||||
dbf = FactoryImpl.getDOMFactory(useServicesMechanism);
|
||||
dbf.setNamespaceAware( true );
|
||||
dbf.setValidating( false );
|
||||
}
|
||||
db = dbf.newDocumentBuilder();
|
||||
Document document = db.parse( source );
|
||||
return eval( document, returnType );
|
||||
} catch ( Exception e ) {
|
||||
throw new XPathExpressionException ( e );
|
||||
Document document = getDocument(source);
|
||||
return eval(document, returnType);
|
||||
} catch (TransformerException e) {
|
||||
throw new XPathExpressionException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <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>.
|
||||
*/
|
||||
@Override
|
||||
public String evaluate(InputSource source)
|
||||
throws XPathExpressionException {
|
||||
return (String)this.evaluate( source, XPathConstants.STRING );
|
||||
return (String)this.evaluate(source, XPathConstants.STRING);
|
||||
}
|
||||
|
||||
private boolean isSupported( QName returnType ) {
|
||||
// XPathConstants.STRING
|
||||
if ( ( returnType.equals( XPathConstants.STRING ) ) ||
|
||||
( returnType.equals( XPathConstants.NUMBER ) ) ||
|
||||
( returnType.equals( XPathConstants.BOOLEAN ) ) ||
|
||||
( returnType.equals( XPathConstants.NODE ) ) ||
|
||||
( returnType.equals( XPathConstants.NODESET ) ) ) {
|
||||
@Override
|
||||
public <T>T evaluateExpression(Object item, Class<T> type)
|
||||
throws XPathExpressionException {
|
||||
isSupportedClassType(type);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
XObject resultObject = eval(item, xpath);
|
||||
if (type.isAssignableFrom(XPathEvaluationResult.class)) {
|
||||
return getXPathResult(resultObject, type);
|
||||
} else {
|
||||
return XPathResultImpl.getValue(resultObject, type);
|
||||
}
|
||||
|
||||
private Object getResultAsType( XObject resultObject, QName returnType )
|
||||
throws javax.xml.transform.TransformerException {
|
||||
// XPathConstants.STRING
|
||||
if ( returnType.equals( XPathConstants.STRING ) ) {
|
||||
return resultObject.str();
|
||||
} catch (javax.xml.transform.TransformerException te) {
|
||||
throw new XPathExpressionException(te);
|
||||
}
|
||||
// XPathConstants.NUMBER
|
||||
if ( returnType.equals( XPathConstants.NUMBER ) ) {
|
||||
return new Double ( resultObject.num());
|
||||
}
|
||||
// XPathConstants.BOOLEAN
|
||||
if ( returnType.equals( XPathConstants.BOOLEAN ) ) {
|
||||
return new Boolean( resultObject.bool());
|
||||
}
|
||||
// XPathConstants.NODESET ---ORdered, UNOrdered???
|
||||
if ( returnType.equals( XPathConstants.NODESET ) ) {
|
||||
return resultObject.nodelist();
|
||||
}
|
||||
// XPathConstants.NODE
|
||||
if ( returnType.equals( XPathConstants.NODE ) ) {
|
||||
NodeIterator ni = resultObject.nodeset();
|
||||
//Return the first node, or null
|
||||
return ni.nextNode();
|
||||
}
|
||||
// If isSupported check is already done then the execution path
|
||||
// shouldn't come here. Being defensive
|
||||
String fmsg = XSLMessages.createXPATHMessage(
|
||||
XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
|
||||
new Object[] { returnType.toString()});
|
||||
throw new IllegalArgumentException ( fmsg );
|
||||
}
|
||||
|
||||
@Override
|
||||
public XPathEvaluationResult<?> evaluateExpression(Object item)
|
||||
throws XPathExpressionException {
|
||||
return evaluateExpression(item, XPathEvaluationResult.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T>T evaluateExpression(InputSource source, Class<T> type)
|
||||
throws XPathExpressionException {
|
||||
Document document = getDocument(source);
|
||||
return evaluateExpression(document, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public XPathEvaluationResult<?> evaluateExpression(InputSource source)
|
||||
throws XPathExpressionException {
|
||||
return evaluateExpression(source, XPathEvaluationResult.class);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
/*
|
||||
* reserved comment block
|
||||
* DO NOT REMOVE OR ALTER!
|
||||
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* 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.XPathVariableResolver;
|
||||
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.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 org.w3c.dom.Node;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.traversal.NodeIterator;
|
||||
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import javax.xml.parsers.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.xpath.XPathEvaluationResult;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* @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 XPathVariableResolver variableResolver;
|
||||
private XPathFunctionResolver functionResolver;
|
||||
private XPathVariableResolver origVariableResolver;
|
||||
private XPathFunctionResolver origFunctionResolver;
|
||||
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());
|
||||
}
|
||||
|
||||
XPathImpl( XPathVariableResolver vr, XPathFunctionResolver fr,
|
||||
XPathImpl(XPathVariableResolver vr, XPathFunctionResolver fr,
|
||||
boolean featureSecureProcessing, boolean useServiceMechanism,
|
||||
FeatureManager featureManager) {
|
||||
this.origVariableResolver = this.variableResolver = vr;
|
||||
@ -86,451 +67,173 @@ public class XPathImpl implements javax.xml.xpath.XPath {
|
||||
this.featureManager = featureManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Establishes a variable resolver.</p>
|
||||
*
|
||||
* @param resolver Variable Resolver
|
||||
*/
|
||||
|
||||
//-Override-
|
||||
public void setXPathVariableResolver(XPathVariableResolver resolver) {
|
||||
if ( resolver == null ) {
|
||||
String fmsg = XSLMessages.createXPATHMessage(
|
||||
XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
|
||||
new Object[] {"XPathVariableResolver"} );
|
||||
throw new NullPointerException( fmsg );
|
||||
}
|
||||
requireNonNull(resolver, "XPathVariableResolver");
|
||||
this.variableResolver = resolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the current variable resolver.</p>
|
||||
*
|
||||
* @return Current variable resolver
|
||||
*/
|
||||
//-Override-
|
||||
public XPathVariableResolver getXPathVariableResolver() {
|
||||
return variableResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Establishes a function resolver.</p>
|
||||
*
|
||||
* @param resolver XPath function resolver
|
||||
*/
|
||||
//-Override-
|
||||
public void setXPathFunctionResolver(XPathFunctionResolver resolver) {
|
||||
if ( resolver == null ) {
|
||||
String fmsg = XSLMessages.createXPATHMessage(
|
||||
XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
|
||||
new Object[] {"XPathFunctionResolver"} );
|
||||
throw new NullPointerException( fmsg );
|
||||
}
|
||||
requireNonNull(resolver, "XPathFunctionResolver");
|
||||
this.functionResolver = resolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the current function resolver.</p>
|
||||
*
|
||||
* @return Current function resolver
|
||||
*/
|
||||
//-Override-
|
||||
public XPathFunctionResolver getXPathFunctionResolver() {
|
||||
return functionResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Establishes a namespace context.</p>
|
||||
*
|
||||
* @param nsContext Namespace context to use
|
||||
*/
|
||||
//-Override-
|
||||
public void setNamespaceContext(NamespaceContext nsContext) {
|
||||
if ( nsContext == null ) {
|
||||
String fmsg = XSLMessages.createXPATHMessage(
|
||||
XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
|
||||
new Object[] {"NamespaceContext"} );
|
||||
throw new NullPointerException( fmsg );
|
||||
}
|
||||
requireNonNull(nsContext, "NamespaceContext");
|
||||
this.namespaceContext = nsContext;
|
||||
this.prefixResolver = new JAXPPrefixResolver ( nsContext );
|
||||
this.prefixResolver = new JAXPPrefixResolver (nsContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the current namespace context.</p>
|
||||
*
|
||||
* @return Current Namespace context
|
||||
*/
|
||||
//-Override-
|
||||
public NamespaceContext getNamespaceContext() {
|
||||
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>
|
||||
*
|
||||
* <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>
|
||||
*
|
||||
* Evaluate an {@code XPath} expression in the specified context.
|
||||
* @param expression The XPath expression.
|
||||
* @param item The starting context (node or node list, 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>.
|
||||
* @param contextItem The starting context.
|
||||
* @return an XObject as the result of evaluating the expression
|
||||
* @throws TransformerException if evaluating fails
|
||||
*/
|
||||
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)
|
||||
throws XPathExpressionException {
|
||||
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 );
|
||||
}
|
||||
//this check is necessary before calling eval to maintain binary compatibility
|
||||
requireNonNull(expression, "XPath expression");
|
||||
isSupported(returnType);
|
||||
|
||||
try {
|
||||
|
||||
XObject resultObject = eval( expression, item );
|
||||
return getResultAsType( resultObject, returnType );
|
||||
} catch ( java.lang.NullPointerException npe ) {
|
||||
XObject resultObject = eval(expression, item);
|
||||
return getResultAsType(resultObject, returnType);
|
||||
} catch (java.lang.NullPointerException npe) {
|
||||
// If VariableResolver returns null Or if we get
|
||||
// NullPointerException at this stage for some other reason
|
||||
// then we have to reurn XPathException
|
||||
throw new XPathExpressionException ( npe );
|
||||
} catch ( javax.xml.transform.TransformerException te ) {
|
||||
throw new XPathExpressionException (npe);
|
||||
} catch (TransformerException te) {
|
||||
Throwable nestedException = te.getException();
|
||||
if ( nestedException instanceof javax.xml.xpath.XPathFunctionException ) {
|
||||
if (nestedException instanceof javax.xml.xpath.XPathFunctionException) {
|
||||
throw (javax.xml.xpath.XPathFunctionException)nestedException;
|
||||
} else {
|
||||
// For any other exceptions we need to throw
|
||||
// XPathExpressionException ( as per spec )
|
||||
throw new XPathExpressionException ( te );
|
||||
// XPathExpressionException (as per spec)
|
||||
throw new XPathExpressionException (te);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean isSupported( QName returnType ) {
|
||||
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>.
|
||||
*/
|
||||
//-Override-
|
||||
public String evaluate(String expression, Object item)
|
||||
throws XPathExpressionException {
|
||||
return (String)this.evaluate( expression, item, XPathConstants.STRING );
|
||||
return (String)this.evaluate(expression, item, XPathConstants.STRING);
|
||||
}
|
||||
|
||||
/**
|
||||
* <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>.
|
||||
*/
|
||||
//-Override-
|
||||
public XPathExpression compile(String expression)
|
||||
throws XPathExpressionException {
|
||||
if ( expression == null ) {
|
||||
String fmsg = XSLMessages.createXPATHMessage(
|
||||
XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
|
||||
new Object[] {"XPath expression"} );
|
||||
throw new NullPointerException ( fmsg );
|
||||
}
|
||||
requireNonNull(expression, "XPath expression");
|
||||
try {
|
||||
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
|
||||
XPathExpressionImpl ximpl = new XPathExpressionImpl (xpath,
|
||||
prefixResolver, functionResolver, variableResolver,
|
||||
featureSecureProcessing, useServiceMechanism, featureManager );
|
||||
featureSecureProcessing, useServiceMechanism, featureManager);
|
||||
return ximpl;
|
||||
} catch ( javax.xml.transform.TransformerException te ) {
|
||||
throw new XPathExpressionException ( te ) ;
|
||||
} catch (TransformerException te) {
|
||||
throw new XPathExpressionException (te) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <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>.
|
||||
*/
|
||||
//-Override-
|
||||
public Object evaluate(String expression, InputSource source,
|
||||
QName returnType) throws XPathExpressionException {
|
||||
// Checking validity of different parameters
|
||||
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 );
|
||||
}
|
||||
isSupported(returnType);
|
||||
|
||||
try {
|
||||
|
||||
Document document = getParser().parse( source );
|
||||
|
||||
XObject resultObject = eval( expression, document );
|
||||
return getResultAsType( resultObject, returnType );
|
||||
} catch ( SAXException e ) {
|
||||
throw new XPathExpressionException ( e );
|
||||
} catch( IOException e ) {
|
||||
throw new XPathExpressionException ( e );
|
||||
} catch ( javax.xml.transform.TransformerException te ) {
|
||||
Document document = getDocument(source);
|
||||
XObject resultObject = eval(expression, document);
|
||||
return getResultAsType(resultObject, returnType);
|
||||
} catch (TransformerException te) {
|
||||
Throwable nestedException = te.getException();
|
||||
if ( nestedException instanceof javax.xml.xpath.XPathFunctionException ) {
|
||||
if (nestedException instanceof javax.xml.xpath.XPathFunctionException) {
|
||||
throw (javax.xml.xpath.XPathFunctionException)nestedException;
|
||||
} else {
|
||||
throw new XPathExpressionException ( te );
|
||||
throw new XPathExpressionException (te);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* <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>.
|
||||
*/
|
||||
//-Override-
|
||||
public String evaluate(String expression, InputSource source)
|
||||
throws XPathExpressionException {
|
||||
return (String)this.evaluate( expression, source, XPathConstants.STRING );
|
||||
return (String)this.evaluate(expression, source, XPathConstants.STRING);
|
||||
}
|
||||
|
||||
/**
|
||||
* <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>
|
||||
*/
|
||||
//-Override-
|
||||
public void reset() {
|
||||
this.variableResolver = this.origVariableResolver;
|
||||
this.functionResolver = this.origFunctionResolver;
|
||||
this.namespaceContext = null;
|
||||
}
|
||||
|
||||
//-Override-
|
||||
public <T> T evaluateExpression(String expression, Object item, Class<T> type)
|
||||
throws XPathExpressionException {
|
||||
isSupportedClassType(type);
|
||||
try {
|
||||
XObject resultObject = eval(expression, item);
|
||||
if (type.isAssignableFrom(XPathEvaluationResult.class)) {
|
||||
return getXPathResult(resultObject, type);
|
||||
} else {
|
||||
return XPathResultImpl.getValue(resultObject, type);
|
||||
}
|
||||
} catch (TransformerException te) {
|
||||
throw new XPathExpressionException (te);
|
||||
}
|
||||
}
|
||||
|
||||
//-Override-
|
||||
public XPathEvaluationResult<?> evaluateExpression(String expression, Object item)
|
||||
throws XPathExpressionException {
|
||||
return evaluateExpression(expression, item, XPathEvaluationResult.class);
|
||||
}
|
||||
|
||||
//-Override-
|
||||
public <T> T evaluateExpression(String expression, InputSource source, Class<T> type)
|
||||
throws XPathExpressionException {
|
||||
Document document = getDocument(source);
|
||||
return evaluateExpression(expression, document, type);
|
||||
}
|
||||
|
||||
//-Override-
|
||||
public XPathEvaluationResult<?> evaluateExpression(String expression, InputSource source)
|
||||
throws XPathExpressionException {
|
||||
return evaluateExpression(expression, source, XPathEvaluationResult.class);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,262 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.org.apache.xpath.internal.jaxp;
|
||||
|
||||
import com.sun.org.apache.xalan.internal.res.XSLMessages;
|
||||
import com.sun.org.apache.xalan.internal.utils.FactoryImpl;
|
||||
import com.sun.org.apache.xalan.internal.utils.FeatureManager;
|
||||
import com.sun.org.apache.xml.internal.dtm.DTM;
|
||||
import com.sun.org.apache.xpath.internal.objects.XObject;
|
||||
import com.sun.org.apache.xpath.internal.res.XPATHErrorResources;
|
||||
import java.io.IOException;
|
||||
import javax.xml.namespace.QName;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.xpath.XPathConstants;
|
||||
import javax.xml.xpath.XPathEvaluationResult;
|
||||
import javax.xml.xpath.XPathExpressionException;
|
||||
import javax.xml.xpath.XPathFunctionResolver;
|
||||
import javax.xml.xpath.XPathNodes;
|
||||
import javax.xml.xpath.XPathVariableResolver;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.traversal.NodeIterator;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
/**
|
||||
* This class contains several utility methods used by XPathImpl and
|
||||
* XPathExpressionImpl
|
||||
*/
|
||||
class XPathImplUtil {
|
||||
XPathFunctionResolver functionResolver;
|
||||
XPathVariableResolver variableResolver;
|
||||
JAXPPrefixResolver prefixResolver;
|
||||
boolean useServiceMechanism = true;
|
||||
// By default Extension Functions are allowed in XPath Expressions. If
|
||||
// Secure Processing Feature is set on XPathFactory then the invocation of
|
||||
// extensions function need to throw XPathFunctionException
|
||||
boolean featureSecureProcessing = false;
|
||||
FeatureManager featureManager;
|
||||
|
||||
/**
|
||||
* Evaluate an XPath context using the internal XPath engine
|
||||
* @param contextItem The XPath context
|
||||
* @param xpath The internal XPath engine
|
||||
* @return an XObject
|
||||
* @throws javax.xml.transform.TransformerException If the expression cannot be evaluated.
|
||||
*/
|
||||
XObject eval(Object contextItem, com.sun.org.apache.xpath.internal.XPath xpath)
|
||||
throws javax.xml.transform.TransformerException {
|
||||
com.sun.org.apache.xpath.internal.XPathContext xpathSupport;
|
||||
if (functionResolver != null) {
|
||||
JAXPExtensionsProvider jep = new JAXPExtensionsProvider(
|
||||
functionResolver, featureSecureProcessing, featureManager);
|
||||
xpathSupport = new com.sun.org.apache.xpath.internal.XPathContext(jep);
|
||||
} else {
|
||||
xpathSupport = new com.sun.org.apache.xpath.internal.XPathContext();
|
||||
}
|
||||
|
||||
xpathSupport.setVarStack(new JAXPVariableStack(variableResolver));
|
||||
XObject xobj;
|
||||
|
||||
Node contextNode = (Node)contextItem;
|
||||
// We always need to have a ContextNode with Xalan XPath implementation
|
||||
// To allow simple expression evaluation like 1+1 we are setting
|
||||
// dummy Document as Context Node
|
||||
if (contextNode == null) {
|
||||
xobj = xpath.execute(xpathSupport, DTM.NULL, prefixResolver);
|
||||
} else {
|
||||
xobj = xpath.execute(xpathSupport, contextNode, prefixResolver);
|
||||
}
|
||||
|
||||
return xobj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the input source and return a Document.
|
||||
* @param source The {@code InputSource} of the document
|
||||
* @return a DOM Document
|
||||
* @throws XPathExpressionException if there is an error parsing the source.
|
||||
*/
|
||||
Document getDocument(InputSource source)
|
||||
throws XPathExpressionException {
|
||||
requireNonNull(source, "Source");
|
||||
try {
|
||||
// we'd really like to cache those DocumentBuilders, but we can't because:
|
||||
// 1. thread safety. parsers are not thread-safe, so at least
|
||||
// we need one instance per a thread.
|
||||
// 2. parsers are non-reentrant, so now we are looking at having a
|
||||
// pool of parsers.
|
||||
// 3. then the class loading issue. The look-up procedure of
|
||||
// DocumentBuilderFactory.newInstance() depends on context class loader
|
||||
// and system properties, which may change during the execution of JVM.
|
||||
//
|
||||
// so we really have to create a fresh DocumentBuilder every time we need one
|
||||
// - KK
|
||||
DocumentBuilderFactory dbf = FactoryImpl.getDOMFactory(useServiceMechanism);
|
||||
dbf.setNamespaceAware(true);
|
||||
dbf.setValidating(false);
|
||||
return dbf.newDocumentBuilder().parse(source);
|
||||
} catch (ParserConfigurationException | SAXException | IOException e) {
|
||||
throw new XPathExpressionException (e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get result depending on the QName type defined in XPathConstants
|
||||
* @param resultObject the result of an evaluation
|
||||
* @param returnType the return type
|
||||
* @return result per the return type
|
||||
* @throws TransformerException if the result can not be converted to
|
||||
* the specified return type.
|
||||
*/
|
||||
Object getResultAsType(XObject resultObject, QName returnType)
|
||||
throws TransformerException {
|
||||
// XPathConstants.STRING
|
||||
if (returnType.equals(XPathConstants.STRING)) {
|
||||
return resultObject.str();
|
||||
}
|
||||
// XPathConstants.NUMBER
|
||||
if (returnType.equals(XPathConstants.NUMBER)) {
|
||||
return resultObject.num();
|
||||
}
|
||||
// XPathConstants.BOOLEAN
|
||||
if (returnType.equals(XPathConstants.BOOLEAN)) {
|
||||
return resultObject.bool();
|
||||
}
|
||||
// XPathConstants.NODESET ---ORdered, UNOrdered???
|
||||
if (returnType.equals(XPathConstants.NODESET)) {
|
||||
return resultObject.nodelist();
|
||||
}
|
||||
// XPathConstants.NODE
|
||||
if (returnType.equals(XPathConstants.NODE)) {
|
||||
NodeIterator ni = resultObject.nodeset();
|
||||
//Return the first node, or null
|
||||
return ni.nextNode();
|
||||
}
|
||||
// If isSupported check is already done then the execution path
|
||||
// shouldn't come here. Being defensive
|
||||
String fmsg = XSLMessages.createXPATHMessage(
|
||||
XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
|
||||
new Object[] { returnType.toString()});
|
||||
throw new IllegalArgumentException (fmsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an XPathExpressionResult object based on the result of the
|
||||
* evaluation and cast to the specified class type.
|
||||
* @param <T> The class type
|
||||
* @param resultObject the result of an evaluation
|
||||
* @param type The class type expected to be returned by the XPath expression.
|
||||
* @return an instance of the specified type or null if the XObject returned
|
||||
* an UNKNOWN object type.
|
||||
* @throws TransformerException if there is an error converting the result
|
||||
* to the specified type. It's unlikely to happen. This is mostly needed
|
||||
* by the internal XPath engine.
|
||||
*/
|
||||
<T> T getXPathResult(XObject resultObject, Class<T> type)
|
||||
throws TransformerException {
|
||||
int resultType = resultObject.getType();
|
||||
|
||||
switch (resultType) {
|
||||
case XObject.CLASS_BOOLEAN :
|
||||
return type.cast(new XPathResultImpl<>(resultObject, Boolean.class));
|
||||
case XObject.CLASS_NUMBER :
|
||||
return type.cast(new XPathResultImpl<>(resultObject, Double.class));
|
||||
case XObject.CLASS_STRING :
|
||||
return type.cast(new XPathResultImpl<>(resultObject, String.class));
|
||||
case XObject.CLASS_NODESET :
|
||||
return type.cast(new XPathResultImpl<>(resultObject, XPathNodes.class));
|
||||
case XObject.CLASS_RTREEFRAG : //NODE
|
||||
return type.cast(new XPathResultImpl<>(resultObject, Node.class));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether or not the specified type is supported
|
||||
* @param <T> The class type
|
||||
* @param type The type to be checked
|
||||
* @throws IllegalArgumentException if the type is not supported
|
||||
*/
|
||||
<T> void isSupportedClassType(Class<T> type) {
|
||||
requireNonNull(type, "The class type");
|
||||
if (type.isAssignableFrom(Boolean.class) ||
|
||||
type.isAssignableFrom(Double.class) ||
|
||||
type.isAssignableFrom(Integer.class) ||
|
||||
type.isAssignableFrom(Long.class) ||
|
||||
type.isAssignableFrom(String.class) ||
|
||||
type.isAssignableFrom(XPathNodes.class) ||
|
||||
type.isAssignableFrom(Node.class) ||
|
||||
type.isAssignableFrom(XPathEvaluationResult.class)) {
|
||||
return;
|
||||
}
|
||||
String fmsg = XSLMessages.createXPATHMessage(
|
||||
XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
|
||||
new Object[] { type.toString() });
|
||||
throw new IllegalArgumentException (fmsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the requested returnType is supported.
|
||||
* @param returnType the return type
|
||||
* @throws IllegalArgumentException if the return type is not supported
|
||||
*/
|
||||
void isSupported(QName returnType) {
|
||||
requireNonNull(returnType, "returnType");
|
||||
if (returnType.equals(XPathConstants.STRING) ||
|
||||
returnType.equals(XPathConstants.NUMBER) ||
|
||||
returnType.equals(XPathConstants.BOOLEAN) ||
|
||||
returnType.equals(XPathConstants.NODE) ||
|
||||
returnType.equals(XPathConstants.NODESET)) {
|
||||
return;
|
||||
}
|
||||
String fmsg = XSLMessages.createXPATHMessage(
|
||||
XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
|
||||
new Object[] { returnType.toString() });
|
||||
throw new IllegalArgumentException (fmsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the specified parameter is not {@code null}.
|
||||
*
|
||||
* @param <T> the type of the reference
|
||||
* @param param the parameter to check for nullity
|
||||
* @param paramName the parameter name
|
||||
* @throws NullPointerException if {@code param} is {@code null}
|
||||
*/
|
||||
<T> void requireNonNull(T param, String paramName) {
|
||||
if (param == null) {
|
||||
String fmsg = XSLMessages.createXPATHMessage(
|
||||
XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
|
||||
new Object[] {paramName});
|
||||
throw new NullPointerException (fmsg);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.org.apache.xpath.internal.jaxp;
|
||||
|
||||
import java.util.Iterator;
|
||||
import javax.xml.xpath.XPathException;
|
||||
import javax.xml.xpath.XPathNodes;
|
||||
import javax.xml.xpath.XPathEvaluationResult.XPathResultType;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
/**
|
||||
* This class implements XPathNodes that represents a set of nodes selected by
|
||||
* evaluating an expression.
|
||||
*/
|
||||
public class XPathNodesImpl implements XPathNodes {
|
||||
Class<Node> elementType;
|
||||
NodeList nodeList = null;
|
||||
|
||||
public XPathNodesImpl(NodeList nodeList, Class<Node> elementType) {
|
||||
this.nodeList = nodeList;
|
||||
this.elementType = elementType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Node> iterator() {
|
||||
return new NodeSetIterator<>(elementType);
|
||||
}
|
||||
|
||||
class NodeSetIterator<E> implements Iterator<E> {
|
||||
int currentIndex;
|
||||
Class<E> elementType;
|
||||
NodeSetIterator(Class<E> elementType) {
|
||||
this.elementType = elementType;
|
||||
}
|
||||
public boolean hasNext() {
|
||||
if (nodeList != null) {
|
||||
return currentIndex < nodeList.getLength();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public E next() {
|
||||
if (nodeList != null && nodeList.getLength() > 0) {
|
||||
return elementType.cast(nodeList.item(currentIndex++));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
if (nodeList != null) {
|
||||
return nodeList.getLength();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node get(int index) throws XPathException {
|
||||
if (index <0 || index >= size()) {
|
||||
throw new IndexOutOfBoundsException("Index " + index + " is out of bounds");
|
||||
}
|
||||
if (nodeList != null) {
|
||||
return nodeList.item(index);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,201 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.org.apache.xpath.internal.jaxp;
|
||||
|
||||
import com.sun.org.apache.xpath.internal.objects.XObject;
|
||||
import java.util.Objects;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.xpath.XPathNodes;
|
||||
import javax.xml.xpath.XPathEvaluationResult;
|
||||
import javax.xml.xpath.XPathEvaluationResult.XPathResultType;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.w3c.dom.traversal.NodeIterator;
|
||||
|
||||
|
||||
/**
|
||||
* This is the implementation of XPathEvaluationResult that represents the
|
||||
* result of the evaluation of an XPath expression within the context of a
|
||||
* particular node.
|
||||
*/
|
||||
class XPathResultImpl<T> implements XPathEvaluationResult<T> {
|
||||
|
||||
XObject resultObject;
|
||||
int resultType;
|
||||
Class<T> type;
|
||||
XPathResultType mapToType;
|
||||
NodeList nodeList = null;
|
||||
int currentIndex;
|
||||
Node currentNode;
|
||||
|
||||
boolean boolValue = false;
|
||||
Node node = null;
|
||||
double numValue;
|
||||
String strValue;
|
||||
|
||||
/**
|
||||
* Construct an XPathEvaluationResult object.
|
||||
*
|
||||
* @param resultObject internal XPath result object
|
||||
* @param type class type
|
||||
* @throws TransformerException if there is an error reading the XPath
|
||||
* result.
|
||||
*/
|
||||
public XPathResultImpl(XObject resultObject, Class<T> type)
|
||||
throws TransformerException {
|
||||
this.resultObject = resultObject;
|
||||
resultType = resultObject.getType();
|
||||
this.type = type;
|
||||
getResult(resultObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the result type as an enum specified by {@code XPathResultType}
|
||||
* @return the result type
|
||||
*/
|
||||
@Override
|
||||
public XPathResultType type() {
|
||||
return mapToType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the result as the type <T> specified for the class.
|
||||
*
|
||||
* @return The value of the result.
|
||||
*/
|
||||
@Override
|
||||
public T value() {
|
||||
Objects.requireNonNull(type);
|
||||
try {
|
||||
return getValue(resultObject, type);
|
||||
} catch (TransformerException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the XObject and set values in accordance with the result type
|
||||
* @param resultObject internal XPath result object
|
||||
* @throws TransformerException if there is an error reading the XPath
|
||||
* result.
|
||||
*/
|
||||
private void getResult(XObject resultObject) throws TransformerException {
|
||||
switch (resultType) {
|
||||
case XObject.CLASS_BOOLEAN:
|
||||
boolValue = resultObject.bool();
|
||||
mapToType = XPathResultType.BOOLEAN;
|
||||
break;
|
||||
case XObject.CLASS_NUMBER:
|
||||
numValue = resultObject.num();
|
||||
mapToType = XPathResultType.NUMBER;
|
||||
break;
|
||||
case XObject.CLASS_STRING:
|
||||
strValue = resultObject.str();
|
||||
mapToType = XPathResultType.STRING;
|
||||
break;
|
||||
case XObject.CLASS_NODESET:
|
||||
mapToType = XPathResultType.NODESET;
|
||||
nodeList = resultObject.nodelist();
|
||||
break;
|
||||
case XObject.CLASS_RTREEFRAG: //NODE
|
||||
mapToType = XPathResultType.NODE;
|
||||
NodeIterator ni = resultObject.nodeset();
|
||||
//Return the first node, or null
|
||||
node = ni.nextNode();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the internal result object and return the value in accordance with
|
||||
* the type specified.
|
||||
*
|
||||
* @param <T> The expected class type.
|
||||
* @param resultObject internal XPath result object
|
||||
* @param type the class type
|
||||
* @return The value of the result, null in case of unexpected type.
|
||||
* @throws TransformerException if there is an error reading the XPath
|
||||
* result.
|
||||
*/
|
||||
static <T> T getValue(XObject resultObject, Class<T> type) throws TransformerException {
|
||||
Objects.requireNonNull(type);
|
||||
if (type.isAssignableFrom(XPathEvaluationResult.class)) {
|
||||
return type.cast(new XPathResultImpl<T>(resultObject, type));
|
||||
}
|
||||
int resultType = classToInternalType(type);
|
||||
switch (resultType) {
|
||||
case XObject.CLASS_BOOLEAN:
|
||||
return type.cast(resultObject.bool());
|
||||
case XObject.CLASS_NUMBER:
|
||||
if (Double.class.isAssignableFrom(type)) {
|
||||
return type.cast(resultObject.num());
|
||||
} else if (Integer.class.isAssignableFrom(type)) {
|
||||
return type.cast((int)resultObject.num());
|
||||
} else if (Long.class.isAssignableFrom(type)) {
|
||||
return type.cast((long)resultObject.num());
|
||||
}
|
||||
/*
|
||||
This is to suppress warnings. By the current specification,
|
||||
among numeric types, only Double, Integer and Long are supported.
|
||||
*/
|
||||
break;
|
||||
case XObject.CLASS_STRING:
|
||||
return type.cast(resultObject.str());
|
||||
case XObject.CLASS_NODESET:
|
||||
XPathNodes nodeSet = new XPathNodesImpl(resultObject.nodelist(),
|
||||
Node.class);
|
||||
return type.cast(nodeSet);
|
||||
case XObject.CLASS_RTREEFRAG: //NODE
|
||||
NodeIterator ni = resultObject.nodeset();
|
||||
//Return the first node, or null
|
||||
return type.cast(ni.nextNode());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map the specified class type to the internal result type
|
||||
*
|
||||
* @param <T> The expected class type.
|
||||
* @param type the class type
|
||||
* @return the internal XObject type.
|
||||
*/
|
||||
static <T> int classToInternalType(Class<T> type) {
|
||||
if (type.isAssignableFrom(Boolean.class)) {
|
||||
return XObject.CLASS_BOOLEAN;
|
||||
} else if (Number.class.isAssignableFrom(type)) {
|
||||
return XObject.CLASS_NUMBER;
|
||||
} else if (type.isAssignableFrom(String.class)) {
|
||||
return XObject.CLASS_STRING;
|
||||
} else if (type.isAssignableFrom(XPathNodes.class)) {
|
||||
return XObject.CLASS_NODESET;
|
||||
} else if (type.isAssignableFrom(Node.class)) {
|
||||
return XObject.CLASS_RTREEFRAG;
|
||||
}
|
||||
return XObject.CLASS_NULL;
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,12 +25,12 @@
|
||||
|
||||
package javax.xml.xpath;
|
||||
|
||||
import org.xml.sax.InputSource;
|
||||
import javax.xml.namespace.QName;
|
||||
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"/>
|
||||
* <table border="1" cellpadding="2">
|
||||
@ -39,7 +39,6 @@ import javax.xml.namespace.NamespaceContext;
|
||||
* <th colspan="2">Evaluation of XPath Expressions.</th>
|
||||
* </tr>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr>
|
||||
* <td>context</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}
|
||||
* set with {@link #setXPathVariableResolver(XPathVariableResolver resolver)}.
|
||||
* An {@link XPathExpressionException} is raised if the variable resolver is undefined or
|
||||
* the resolver returns <code>null</code> for the variable.
|
||||
* The value of a variable must be immutable through the course of any single evaluation.</p>
|
||||
* the resolver returns {@code null} for the variable.
|
||||
* The value of a variable must be immutable through the course of any single evaluation.
|
||||
* </td>
|
||||
* </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}
|
||||
* set with {@link #setXPathFunctionResolver(XPathFunctionResolver resolver)}.
|
||||
* 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>
|
||||
* </tr>
|
||||
* <tr>
|
||||
@ -80,7 +79,7 @@ import javax.xml.namespace.NamespaceContext;
|
||||
* <td>
|
||||
* This result of evaluating an expression is converted to an instance of the desired return type.
|
||||
* 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>
|
||||
* </tr>
|
||||
* </table>
|
||||
@ -88,9 +87,9 @@ import javax.xml.namespace.NamespaceContext;
|
||||
* <p>An XPath object is not thread-safe and not reentrant.
|
||||
* In other words, it is the application's responsibility to make
|
||||
* 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
|
||||
* the <code>evaluate</code> method.
|
||||
* the {@code evaluate} method.
|
||||
* <p>
|
||||
*
|
||||
* @author <a href="Norman.Walsh@Sun.com">Norman Walsh</a>
|
||||
@ -100,191 +99,189 @@ import javax.xml.namespace.NamespaceContext;
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* @throws NullPointerException If <code>resolver</code> is <code>null</code>.
|
||||
* @throws NullPointerException If {@code resolver} is {@code null}.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* @throws NullPointerException If <code>resolver</code> is <code>null</code>.
|
||||
* @throws NullPointerException If {@code resolver} is {@code null}.
|
||||
*/
|
||||
public void setXPathFunctionResolver(XPathFunctionResolver resolver);
|
||||
|
||||
/**
|
||||
* <p>Return the current function resolver.</p>
|
||||
*
|
||||
* <p><code>null</code> is returned in no function resolver is in effect.</p>
|
||||
* Return the current function resolver.
|
||||
* <p>
|
||||
* {@code null} is returned in no function resolver is in effect.
|
||||
*
|
||||
* @return Current function resolver.
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* @throws NullPointerException If <code>nsContext</code> is <code>null</code>.
|
||||
* @throws NullPointerException If {@code nsContext} is {@code null}.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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}.
|
||||
* An {@link XPathExpressionException} will be thrown if the
|
||||
* <code>XPathFunction</code>
|
||||
* cannot be resovled with the <code>XPathFunctionResolver</code>.</p>
|
||||
* {@code XPathFunction}
|
||||
* 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
|
||||
* <strong>at compile time</strong> will be used to resolve them.</p>
|
||||
*
|
||||
* <p>If <code>expression</code> is <code>null</code>, a <code>NullPointerException</code> is thrown.</p>
|
||||
* <strong>at compile time</strong> will be used to resolve them.
|
||||
*
|
||||
* @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>.
|
||||
* @throws XPathExpressionException If {@code expression} cannot be compiled.
|
||||
* @throws NullPointerException If {@code expression} is {@code null}.
|
||||
*/
|
||||
public XPathExpression compile(String expression)
|
||||
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,
|
||||
* variable, function and <code>QName</code> resolution and return type conversion.</p>
|
||||
* <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#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 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>.
|
||||
* {@link XPathConstants#NODESET NODESET}).
|
||||
* @throws NullPointerException If {@code expression or returnType} is {@code null}.
|
||||
*/
|
||||
public Object evaluate(String expression, Object item, QName returnType)
|
||||
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
|
||||
* {@link XPathConstants#STRING}.</p>
|
||||
* <p>This method calls {@link #evaluate(String expression, Object item, QName returnType)} with a {@code returnType} of
|
||||
* {@link XPathConstants#STRING}.
|
||||
*
|
||||
* <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
|
||||
* <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>
|
||||
* <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}.
|
||||
*
|
||||
* @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
|
||||
* converting the result to a <code>String</code>.
|
||||
* @return The result of evaluating an XPath expression as a {@code String}.
|
||||
*
|
||||
* @throws XPathExpressionException If <code>expression</code> cannot be evaluated.
|
||||
* @throws NullPointerException If <code>expression</code> is <code>null</code>.
|
||||
* @throws XPathExpressionException If {@code expression} cannot be evaluated.
|
||||
* @throws NullPointerException If {@code expression} is {@code null}.
|
||||
*/
|
||||
public String evaluate(String expression, Object item)
|
||||
throws XPathExpressionException;
|
||||
|
||||
/**
|
||||
* <p>Evaluate an XPath expression in the context of the specified <code>InputSource</code>
|
||||
* and return the result as the specified type.</p>
|
||||
* Evaluate an XPath expression in the context of the specified {@code InputSource}
|
||||
* and return the result as the specified type.
|
||||
*
|
||||
* <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,
|
||||
* 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>
|
||||
* variable, function and QName resolution and return type conversion.
|
||||
*
|
||||
* @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.
|
||||
* @return The {@code Object} 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>.
|
||||
* @throws IllegalArgumentException If {@code returnType} is not one of the types defined in {@link XPathConstants}.
|
||||
* @throws NullPointerException If {@code expression, source or returnType} is {@code null}.
|
||||
*/
|
||||
public Object evaluate(
|
||||
String expression,
|
||||
@ -293,27 +290,209 @@ public interface XPath {
|
||||
throws XPathExpressionException;
|
||||
|
||||
/**
|
||||
* <p>Evaluate an XPath expression in the context of the specified <code>InputSource</code>
|
||||
* and return the result as a <code>String</code>.</p>
|
||||
* Evaluate an XPath expression in the context of the specified {@code InputSource}
|
||||
* and return the result as a {@code String}.
|
||||
*
|
||||
* <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,
|
||||
* 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>
|
||||
* variable, function and QName resolution and return type conversion.
|
||||
*
|
||||
* @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
|
||||
* converting the result to a <code>String</code>.
|
||||
* @return The {@code String} that is the result of evaluating the expression and
|
||||
* converting the result to a {@code String}.
|
||||
*
|
||||
* @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)
|
||||
throws XPathExpressionException;
|
||||
|
||||
/**
|
||||
* Evaluate an XPath expression in the specified context and return
|
||||
* the result with the type specified through the {@code class type}
|
||||
*
|
||||
* <p>
|
||||
* The parameter {@code item} represents the context the XPath expression
|
||||
* will be operated on. The type of the context is implementation-dependent.
|
||||
* If the value is {@code null}, the operation must have no dependency on
|
||||
* the context, otherwise an XPathExpressionException will be thrown.
|
||||
*
|
||||
* @implNote
|
||||
* The type of the context is usually {@link org.w3c.dom.Node}.
|
||||
*
|
||||
* @implSpec
|
||||
* The default implementation in the XPath API is equivalent to:
|
||||
* <pre> {@code
|
||||
* (T)evaluate(expression, item,
|
||||
* XPathEvaluationResult.XPathResultType.getQNameType(type));
|
||||
* }</pre>
|
||||
*
|
||||
* Since the {@code evaluate} method does not support the
|
||||
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type, specifying
|
||||
* XPathEvaluationResult as the type will result in IllegalArgumentException.
|
||||
* Any implementation supporting the
|
||||
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must override
|
||||
* this method.
|
||||
*
|
||||
* @param <T> The class type that will be returned by the XPath expression.
|
||||
* @param expression The XPath expression.
|
||||
* @param item The context the XPath expression will be evaluated in.
|
||||
* @param type The class type expected to be returned by the XPath expression.
|
||||
*
|
||||
* @return The result of evaluating the expression.
|
||||
*
|
||||
* @throws XPathExpressionException If the expression cannot be evaluated.
|
||||
* @throws IllegalArgumentException If {@code type} is not of the types
|
||||
* corresponding to the types defined in the {@link XPathEvaluationResult.XPathResultType},
|
||||
* or XPathEvaluationResult is specified as the type but an implementation supporting the
|
||||
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type is not available.
|
||||
* @throws NullPointerException If {@code expression or type} is {@code null}.
|
||||
*
|
||||
* @since 1.9
|
||||
*/
|
||||
default <T>T evaluateExpression(String expression, Object item, Class<T> type)
|
||||
throws XPathExpressionException {
|
||||
return type.cast(evaluate(expression, item,
|
||||
XPathEvaluationResult.XPathResultType.getQNameType(type)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate an XPath expression in the specified context. This is equivalent to
|
||||
* calling {@link #evaluateExpression(String expression, Object item, Class type)}
|
||||
* with type {@link XPathEvaluationResult}:
|
||||
* <pre> {@code
|
||||
* evaluateExpression(expression, item, XPathEvaluationResult.class);
|
||||
* }</pre>
|
||||
* <p>
|
||||
* The parameter {@code item} represents the context the XPath expression
|
||||
* will be operated on. The type of the context is implementation-dependent.
|
||||
* If the value is {@code null}, the operation must have no dependency on
|
||||
* the context, otherwise an XPathExpressionException will be thrown.
|
||||
*
|
||||
* @implNote
|
||||
* The type of the context is usually {@link org.w3c.dom.Node}.
|
||||
*
|
||||
* @implSpec
|
||||
* The default implementation in the XPath API is equivalent to:
|
||||
* <pre> {@code
|
||||
* evaluateExpression(expression, item, XPathEvaluationResult.class);
|
||||
* }</pre>
|
||||
*
|
||||
* Since the {@code evaluate} method does not support the
|
||||
* {@link XPathEvaluationResult.XPathResultType#ANY ANY}
|
||||
* type, the default implementation of this method will always throw an
|
||||
* IllegalArgumentException. Any implementation supporting the
|
||||
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must therefore
|
||||
* override this method.
|
||||
*
|
||||
* @param expression The XPath expression.
|
||||
* @param item The context the XPath expression will be evaluated in.
|
||||
*
|
||||
* @return The result of evaluating the expression.
|
||||
*
|
||||
* @throws XPathExpressionException If the expression cannot be evaluated.
|
||||
* @throws IllegalArgumentException If the implementation of this method
|
||||
* does not support the
|
||||
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type.
|
||||
* @throws NullPointerException If {@code expression} is {@code null}.
|
||||
*
|
||||
* @since 1.9
|
||||
*/
|
||||
default XPathEvaluationResult<?> evaluateExpression(String expression, Object item)
|
||||
throws XPathExpressionException
|
||||
{
|
||||
return evaluateExpression(expression, item, XPathEvaluationResult.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate an XPath expression in the context of the specified {@code source}
|
||||
* and return the result as specified.
|
||||
* <p>
|
||||
* This method builds a data model for the {@link InputSource} and calls
|
||||
* {@link #evaluateExpression(String expression, Object item, Class type)}
|
||||
* on the resulting document object. The data model is usually
|
||||
* {@link org.w3c.dom.Document}
|
||||
*
|
||||
* @implSpec
|
||||
* The default implementation in the XPath API is equivalent to:
|
||||
* <pre> {@code
|
||||
(T)evaluate(expression, source,
|
||||
XPathEvaluationResult.XPathResultType.getQNameType(type));
|
||||
* }</pre>
|
||||
*
|
||||
* Since the {@code evaluate} method does not support the
|
||||
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type, specifying
|
||||
* XPathEvaluationResult as the type will result in IllegalArgumentException.
|
||||
* Any implementation supporting the
|
||||
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must override
|
||||
* this method.
|
||||
*
|
||||
* @param <T> The class type that will be returned by the XPath expression.
|
||||
* @param expression The XPath expression.
|
||||
* @param source The input source of the document to evaluate over.
|
||||
* @param type The class type expected to be returned by the XPath expression.
|
||||
*
|
||||
* @return The result of evaluating the expression.
|
||||
*
|
||||
* @throws XPathExpressionException If the expression cannot be evaluated.
|
||||
* @throws IllegalArgumentException If {@code type} is not of the types
|
||||
* corresponding to the types defined in the {@link XPathEvaluationResult.XPathResultType
|
||||
* XPathResultType}, or XPathEvaluationResult is specified as the type but an
|
||||
* implementation supporting the
|
||||
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type is not available.
|
||||
* @throws NullPointerException If {@code expression, source or type}is {@code null}.
|
||||
*
|
||||
* @since 1.9
|
||||
*/
|
||||
default <T>T evaluateExpression(String expression, InputSource source, Class<T> type)
|
||||
throws XPathExpressionException
|
||||
{
|
||||
return type.cast(evaluate(expression, source,
|
||||
XPathEvaluationResult.XPathResultType.getQNameType(type)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate an XPath expression in the specified context. This is equivalent to
|
||||
* calling {@link #evaluateExpression(String expression, Object item, Class type)}
|
||||
* with type {@link XPathEvaluationResult}:
|
||||
* <pre> {@code
|
||||
* evaluateExpression(expression, item, XPathEvaluationResult.class);
|
||||
* }</pre>
|
||||
* <p>
|
||||
*
|
||||
* @implSpec
|
||||
* The default implementation in the XPath API is equivalent to:
|
||||
* <pre> {@code
|
||||
* evaluateExpression(expression, source, XPathEvaluationResult.class);
|
||||
* }</pre>
|
||||
*
|
||||
* Since the {@code evaluate} method does not support the
|
||||
* {@link XPathEvaluationResult.XPathResultType#ANY ANY}
|
||||
* type, the default implementation of this method will always throw an
|
||||
* IllegalArgumentException. Any implementation supporting the
|
||||
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must therefore
|
||||
* override this method.
|
||||
*
|
||||
* @param expression The XPath expression.
|
||||
* @param source The input source of the document to evaluate over.
|
||||
*
|
||||
* @return The result of evaluating the expression.
|
||||
*
|
||||
* @throws XPathExpressionException If the expression cannot be evaluated.
|
||||
* @throws IllegalArgumentException If the implementation of this method
|
||||
* does not support the
|
||||
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type.
|
||||
* @throws NullPointerException If {@code expression or source} is {@code null}.
|
||||
*
|
||||
* @since 1.9
|
||||
*/
|
||||
default XPathEvaluationResult<?> evaluateExpression(String expression, InputSource source)
|
||||
throws XPathExpressionException
|
||||
{
|
||||
return evaluateExpression(expression, source, XPathEvaluationResult.class);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package javax.xml.xpath;
|
||||
|
||||
import java.util.Objects;
|
||||
import javax.xml.namespace.QName;
|
||||
import org.w3c.dom.Node;
|
||||
/**
|
||||
* The {@code XPathEvaluationResult} interface represents the result of the
|
||||
* evaluation of an XPath expression within the context of a particular node.
|
||||
* The evaluation of an XPath expression can result in various result types as
|
||||
* defined in XML Path Language (XPath) Version 1.0.
|
||||
* <p>
|
||||
*
|
||||
* @param <T> the object type returned by the XPath evaluation.
|
||||
* @see <a href="http://www.w3.org/TR/xpath">XML Path Language (XPath) Version
|
||||
* 1.0</a>
|
||||
*
|
||||
* @since 1.9
|
||||
*/
|
||||
public interface XPathEvaluationResult<T> {
|
||||
|
||||
/**
|
||||
* XPathResultType represents possible return types of an XPath evaluation.
|
||||
* Provided as an enum type, it allows the use of switch statement. At the
|
||||
* same time, a mapping is provided between the original QName types in
|
||||
* {@link XPathConstants} and class types used in the generic methods.
|
||||
*/
|
||||
public static enum XPathResultType {
|
||||
/**
|
||||
* Any type that represents any of the 5 other types listed below.
|
||||
* Maps to {@link XPathEvaluationResult}.
|
||||
*/
|
||||
ANY(new QName("http://www.w3.org/1999/XSL/Transform", "any"), XPathEvaluationResult.class),
|
||||
/**
|
||||
* The XPath 1.0 boolean data type. Maps to Java {@link Boolean}.
|
||||
*/
|
||||
BOOLEAN(XPathConstants.BOOLEAN, Boolean.class),
|
||||
/**
|
||||
* The XPath 1.0 Number data type. Maps to Java {@link Number}. Of the
|
||||
* subtypes of Number, only Double, Integer and Long are required.
|
||||
*/
|
||||
NUMBER(XPathConstants.NUMBER, Number.class),
|
||||
/**
|
||||
* The XPath 1.0 String data type. Maps to Java {@link String}.
|
||||
*/
|
||||
STRING(XPathConstants.STRING, String.class),
|
||||
/**
|
||||
* The XPath 1.0 NodeSet data type. Maps to {@link org.w3c.dom.NodeList}.
|
||||
*/
|
||||
NODESET(XPathConstants.NODESET, XPathNodes.class),
|
||||
/**
|
||||
* The XPath 1.0 NodeSet data type. Maps to {@link org.w3c.dom.Node}.
|
||||
*/
|
||||
NODE(XPathConstants.NODE, Node.class);
|
||||
|
||||
final QName qnameType;
|
||||
final Class<?> clsType;
|
||||
XPathResultType(QName qnameType, Class<?> clsType) {
|
||||
this.qnameType = qnameType;
|
||||
this.clsType = clsType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this type to the specified class type.
|
||||
* @param clsType class type
|
||||
* @return true if the argument is not null and is a class type that
|
||||
* matches that this type represents, false otherwise.
|
||||
*/
|
||||
private boolean equalsClassType(Class<?> clsType) {
|
||||
Objects.nonNull(clsType);
|
||||
if (clsType.isAssignableFrom(this.clsType)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the QName type as specified in {@link XPathConstants} that
|
||||
* corresponds to the specified class type.
|
||||
* @param clsType a class type that the enum type supports
|
||||
* @return the QName type that matches with the specified class type,
|
||||
* null if there is no match
|
||||
*/
|
||||
static public QName getQNameType(Class<?> clsType) {
|
||||
for (XPathResultType type : XPathResultType.values()) {
|
||||
if (type.equalsClassType(clsType)) {
|
||||
return type.qnameType;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the result type as an enum specified by {@code XPathResultType}
|
||||
* @return the result type
|
||||
*/
|
||||
public XPathResultType type();
|
||||
|
||||
/**
|
||||
* Returns the value of the result as the type <T> specified for the class.
|
||||
*
|
||||
* @return The value of the result.
|
||||
*/
|
||||
public T value();
|
||||
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,11 +25,11 @@
|
||||
|
||||
package javax.xml.xpath;
|
||||
|
||||
import org.xml.sax.InputSource;
|
||||
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"/>
|
||||
* <table border="1" cellpadding="2">
|
||||
@ -53,7 +53,7 @@ import javax.xml.namespace.QName;
|
||||
* <td>
|
||||
* 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
|
||||
* 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>
|
||||
* </td>
|
||||
* </tr>
|
||||
@ -62,7 +62,7 @@ import javax.xml.namespace.QName;
|
||||
* <td>
|
||||
* 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
|
||||
* the function resolver returns <code>null</code> for the function.</p>
|
||||
* the function resolver returns {@code null} for the function.</p>
|
||||
* </td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
@ -84,9 +84,9 @@ import javax.xml.namespace.QName;
|
||||
* <p>An XPath expression is not thread-safe and not reentrant.
|
||||
* In other words, it is the application's responsibility to make
|
||||
* 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
|
||||
* the <code>evaluate</code> method.
|
||||
* the {@code evaluate} method.
|
||||
* <p>
|
||||
*
|
||||
* @author <a href="mailto:Norman.Walsh@Sun.com">Norman Walsh</a>
|
||||
@ -96,50 +96,56 @@ import javax.xml.namespace.QName;
|
||||
*/
|
||||
public interface XPathExpression {
|
||||
|
||||
|
||||
/**
|
||||
* <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,
|
||||
* 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>
|
||||
* 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
|
||||
* <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>
|
||||
* @implNote
|
||||
* The type of the context is usually {@link org.w3c.dom.Node}.
|
||||
*
|
||||
* @param item The starting context (a node, for example).
|
||||
* @param returnType The desired return type.
|
||||
* @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 <code>Object</code> that is the result of evaluating the expression and converting the result to
|
||||
* <code>returnType</code>.
|
||||
* @return The {@code Object} that is the result of evaluating the expression and converting the result to
|
||||
* {@code returnType}.
|
||||
*
|
||||
* @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>.
|
||||
* @throws IllegalArgumentException If {@code returnType} is not one of the types defined in {@link XPathConstants}.
|
||||
* @throws NullPointerException If {@code returnType} is {@code null}.
|
||||
*/
|
||||
public Object evaluate(Object item, QName returnType)
|
||||
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>
|
||||
*
|
||||
* <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>
|
||||
*
|
||||
* <p>If a <code>null</code> value is provided for
|
||||
* <code>item</code>, an empty document will be used for the
|
||||
* context.
|
||||
* <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.
|
||||
*
|
||||
* @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
|
||||
* <code>String</code>.
|
||||
* @param item The context the XPath expression will be evaluated in.
|
||||
*
|
||||
* @return The result of evaluating an XPath expression as a {@code String}.
|
||||
*
|
||||
* @throws XPathExpressionException If the expression cannot be evaluated.
|
||||
*/
|
||||
@ -147,7 +153,7 @@ public interface XPathExpression {
|
||||
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>
|
||||
*
|
||||
* <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,
|
||||
* 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 returnType} is not one of the types defined in {@link XPathConstants},
|
||||
* then an {@code IllegalArgumentException} is thrown.</p>
|
||||
*
|
||||
* <p>If <code>source</code> or <code>returnType</code> is <code>null</code>,
|
||||
* then a <code>NullPointerException</code> is thrown.</p>
|
||||
* <p>If {@code source} or {@code returnType} 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.
|
||||
* @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>.
|
||||
* @return The {@code Object} that is the result of evaluating the expression and converting the result to
|
||||
* {@code returnType}.
|
||||
*
|
||||
* @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>.
|
||||
* @throws IllegalArgumentException If {@code returnType} is not one of the types defined in {@link XPathConstants}.
|
||||
* @throws NullPointerException If {@code source or returnType} is {@code null}.
|
||||
*/
|
||||
public Object evaluate(InputSource source, QName returnType)
|
||||
throws XPathExpressionException;
|
||||
|
||||
/**
|
||||
* <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>Evaluate the compiled XPath expression in the context of the specified {@code InputSource} and return the result as a
|
||||
* {@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>
|
||||
*
|
||||
* <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>
|
||||
*
|
||||
* <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
|
||||
* <code>String</code>.
|
||||
* @return The {@code String} that is the result of evaluating the expression and converting the result to a
|
||||
* {@code String}.
|
||||
*
|
||||
* @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)
|
||||
throws XPathExpressionException;
|
||||
|
||||
/**
|
||||
* Evaluate the compiled XPath expression in the specified context, and return
|
||||
* the result with the type specified through the {@code class type}.
|
||||
*
|
||||
* <p>
|
||||
* The parameter {@code item} represents the context the XPath expression
|
||||
* will be operated on. The type of the context is implementation-dependent.
|
||||
* If the value is {@code null}, the operation must have no dependency on
|
||||
* the context, otherwise an XPathExpressionException will be thrown.
|
||||
*
|
||||
* @implNote
|
||||
* The type of the context is usually {@link org.w3c.dom.Node}.
|
||||
*
|
||||
* @implSpec
|
||||
* The default implementation in the XPath API is equivalent to:
|
||||
* <pre> {@code
|
||||
* (T)evaluate(item, XPathEvaluationResult.XPathResultType.getQNameType(type));
|
||||
* }</pre>
|
||||
*
|
||||
* Since the {@code evaluate} method does not support the
|
||||
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type, specifying
|
||||
* XPathEvaluationResult as the type will result in IllegalArgumentException.
|
||||
* Any implementation supporting the
|
||||
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must override
|
||||
* this method.
|
||||
*
|
||||
* @param <T> The class type that will be returned by the XPath expression.
|
||||
* @param item The context the XPath expression will be evaluated in.
|
||||
* @param type The class type expected to be returned by the XPath expression.
|
||||
*
|
||||
* @return The result of evaluating the expression.
|
||||
*
|
||||
* @throws XPathExpressionException If the expression cannot be evaluated.
|
||||
* @throws IllegalArgumentException If {@code type} is not of the types
|
||||
* corresponding to the types defined in the {@link XPathEvaluationResult.XPathResultType
|
||||
* XPathResultType}, or XPathEvaluationResult is specified as the type but an
|
||||
* implementation supporting the
|
||||
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type is not available.
|
||||
* @throws NullPointerException If {@code type} is {@code null}.
|
||||
*
|
||||
* @since 1.9
|
||||
*/
|
||||
default <T>T evaluateExpression(Object item, Class<T> type)
|
||||
throws XPathExpressionException
|
||||
{
|
||||
return type.cast(evaluate(item, XPathEvaluationResult.XPathResultType.getQNameType(type)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate the compiled XPath expression in the specified context. This is
|
||||
* equivalent to calling {@link #evaluateExpression(Object item, Class type)}
|
||||
* with type {@link XPathEvaluationResult}:
|
||||
* <pre> {@code
|
||||
* evaluateExpression(item, XPathEvaluationResult.class);
|
||||
* }</pre>
|
||||
* <p>
|
||||
* The parameter {@code item} represents the context the XPath expression
|
||||
* will be operated on. The type of the context is implementation-dependent.
|
||||
* If the value is {@code null}, the operation must have no dependency on
|
||||
* the context, otherwise an XPathExpressionException will be thrown.
|
||||
*
|
||||
* @implNote
|
||||
* The type of the context is usually {@link org.w3c.dom.Node}.
|
||||
*
|
||||
* @implSpec
|
||||
* The default implementation in the XPath API is equivalent to:
|
||||
* <pre> {@code
|
||||
* evaluateExpression(item, XPathEvaluationResult.class);
|
||||
* }</pre>
|
||||
*
|
||||
* Since the {@code evaluate} method does not support the
|
||||
* {@link XPathEvaluationResult.XPathResultType#ANY ANY}
|
||||
* type, the default implementation of this method will always throw an
|
||||
* IllegalArgumentException. Any implementation supporting the
|
||||
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must therefore
|
||||
* override this method.
|
||||
*
|
||||
* @param item The context the XPath expression will be evaluated in.
|
||||
*
|
||||
* @return The result of evaluating the expression.
|
||||
*
|
||||
* @throws XPathExpressionException If the expression cannot be evaluated.
|
||||
* @throws IllegalArgumentException If the implementation of this method
|
||||
* does not support the
|
||||
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type.
|
||||
*
|
||||
* @since 1.9
|
||||
*/
|
||||
default XPathEvaluationResult<?> evaluateExpression(Object item)
|
||||
throws XPathExpressionException
|
||||
{
|
||||
return evaluateExpression(item, XPathEvaluationResult.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate the compiled XPath expression in the specified context,
|
||||
* and return the result with the type specified through the {@code class type}
|
||||
* <p>
|
||||
* This method builds a data model for the {@link InputSource} and calls
|
||||
* {@link #evaluateExpression(Object item, Class type)} on the resulting
|
||||
* document object.
|
||||
* <P>
|
||||
* By default, the JDK's data model is {@link org.w3c.dom.Document}.
|
||||
*
|
||||
* @implSpec
|
||||
* The default implementation in the XPath API is equivalent to:
|
||||
* <pre> {@code
|
||||
(T)evaluate(source, XPathEvaluationResult.XPathResultType.getQNameType(type));
|
||||
* }</pre>
|
||||
*
|
||||
* Since the {@code evaluate} method does not support the
|
||||
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type, specifying
|
||||
* XPathEvaluationResult as the type will result in IllegalArgumentException.
|
||||
* Any implementation supporting the
|
||||
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must override
|
||||
* this method.
|
||||
*
|
||||
* @param <T> The class type that will be returned by the XPath expression.
|
||||
* @param source The {@code InputSource} of the document to evaluate over.
|
||||
* @param type The class type expected to be returned by the XPath expression.
|
||||
*
|
||||
* @return The result of evaluating the expression.
|
||||
*
|
||||
* @throws XPathExpressionException If the expression cannot be evaluated.
|
||||
* @throws IllegalArgumentException If {@code type} is not of the types
|
||||
* corresponding to the types defined in the {@link XPathEvaluationResult.XPathResultType
|
||||
* XPathResultType}, or XPathEvaluationResult is specified as the type but an
|
||||
* implementation supporting the
|
||||
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type
|
||||
* is not available.
|
||||
* @throws NullPointerException If {@code source or type} is {@code null}.
|
||||
*
|
||||
* @since 1.9
|
||||
*/
|
||||
default <T>T evaluateExpression(InputSource source, Class<T> type)
|
||||
throws XPathExpressionException
|
||||
{
|
||||
return type.cast(evaluate(source, XPathEvaluationResult.XPathResultType.getQNameType(type)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate the compiled XPath expression in the specified context. This is
|
||||
* equivalent to calling {@link #evaluateExpression(InputSource source, Class type)}
|
||||
* with type {@link XPathEvaluationResult}:
|
||||
* <pre> {@code
|
||||
* evaluateExpression(source, XPathEvaluationResult.class);
|
||||
* }</pre>
|
||||
* <p>
|
||||
*
|
||||
* @implSpec
|
||||
* The default implementation in the XPath API is equivalent to:
|
||||
* <pre> {@code
|
||||
* (XPathEvaluationResult)evaluateExpression(source, XPathEvaluationResult.class);
|
||||
* }</pre>
|
||||
*
|
||||
* Since the {@code evaluate} method does not support the
|
||||
* {@link XPathEvaluationResult.XPathResultType#ANY ANY}
|
||||
* type, the default implementation of this method will always throw an
|
||||
* IllegalArgumentException. Any implementation supporting the
|
||||
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must therefore
|
||||
* override this method.
|
||||
*
|
||||
* @param source The {@code InputSource} of the document to evaluate over.
|
||||
*
|
||||
* @return The result of evaluating the expression.
|
||||
*
|
||||
* @throws XPathExpressionException If the expression cannot be evaluated.
|
||||
* @throws IllegalArgumentException If the implementation of this method
|
||||
* does not support the
|
||||
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type.
|
||||
* @throws NullPointerException If {@code source} is {@code null}.
|
||||
*
|
||||
* @since 1.9
|
||||
*/
|
||||
default XPathEvaluationResult<?> evaluateExpression(InputSource source)
|
||||
throws XPathExpressionException
|
||||
{
|
||||
return evaluateExpression(source, XPathEvaluationResult.class);
|
||||
}
|
||||
}
|
||||
|
@ -117,7 +117,7 @@ public abstract class XPathFactory {
|
||||
* and returns it if it is successfully created.
|
||||
* </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.
|
||||
* </li>
|
||||
* <li>
|
||||
|
@ -176,9 +176,9 @@ class XPathFactoryFinder {
|
||||
|
||||
String javah = ss.getSystemProperty( "java.home" );
|
||||
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 {
|
||||
if(firstTime){
|
||||
synchronized(cacheProps){
|
||||
@ -193,7 +193,7 @@ class XPathFactoryFinder {
|
||||
}
|
||||
}
|
||||
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) {
|
||||
xpathFactory = createInstance(factoryClassName, true);
|
||||
|
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.xml.xpath;
|
||||
|
||||
import java.util.Iterator;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
/**
|
||||
* XPathNodes represents a set of nodes selected by a location path as specified
|
||||
* in <a href="http://www.w3.org/TR/xpath/#node-sets">XML Path Language (XPath)
|
||||
* Version 1.0, 3.3 Node-sets</a>.
|
||||
*
|
||||
* @since 1.9
|
||||
*/
|
||||
public interface XPathNodes extends Iterable<Node> {
|
||||
|
||||
/**
|
||||
* Returns an iterator of the Nodes.
|
||||
*
|
||||
* @return an Iterator.
|
||||
*/
|
||||
@Override
|
||||
public abstract Iterator<Node> iterator();
|
||||
|
||||
/**
|
||||
* Returns the number of items in the result
|
||||
*
|
||||
* @return The number of items in the result
|
||||
*/
|
||||
public abstract int size();
|
||||
|
||||
/**
|
||||
* Returns a Node at the specified position
|
||||
*
|
||||
* @param index Index of the element to return.
|
||||
* @return The Node at the specified position.
|
||||
* @throws javax.xml.xpath.XPathException If the index is out of range
|
||||
* (index < 0 || index >= size())
|
||||
*/
|
||||
public abstract Node get(int index)
|
||||
throws XPathException;
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<html>
|
||||
<head>
|
||||
<!--
|
||||
Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
|
||||
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
|
||||
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>
|
||||
<body bgcolor="white">
|
||||
|
||||
<body>
|
||||
|
||||
<p>This package provides an <em>object-model neutral</em> API for the
|
||||
This package provides an <em>object-model neutral</em> API for the
|
||||
evaluation of XPath expressions and access to the evaluation
|
||||
environment.
|
||||
</p>
|
||||
|
||||
<p>The following XML standards apply:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="http://www.w3.org/TR/xpath">XML Path Language (XPath) Version 1.0</a></li>
|
||||
</ul>
|
||||
<p>
|
||||
The XPath API supports <a href="http://www.w3.org/TR/xpath">
|
||||
XML Path Language (XPath) Version 1.0</a>
|
||||
|
||||
<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
|
||||
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.
|
||||
</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
|
||||
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>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
/foo/bar
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>This example would select the <code><bar></code> element in
|
||||
an XML document such as the following:</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
<foo>
|
||||
<bar/>
|
||||
<bar/>
|
||||
</foo>
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>The expression <code>/foo/bar</code> is an example of a location
|
||||
path. While XPath location paths resemble Unix-style file system
|
||||
@ -96,30 +103,36 @@ paths, an important distinction is that XPath expressions return
|
||||
<code><bar></code> elements in the following document would be
|
||||
selected by the <code>/foo/bar</code> expression:</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
<foo>
|
||||
<bar/>
|
||||
<bar/>
|
||||
<bar/>
|
||||
<bar/>
|
||||
<bar/>
|
||||
<bar/>
|
||||
</foo>
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>A special location path operator, <code>//</code>, selects nodes at
|
||||
any depth in an XML document. The following example selects all
|
||||
<code><bar></code> elements regardless of their location in a
|
||||
document:</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
//bar
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>A wildcard operator, *, causes all element nodes to be selected.
|
||||
The following example selects all children elements of a
|
||||
<code><foo></code> element:</p>
|
||||
<code><foo></code> element:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
/foo/*
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>In addition to element nodes, XPath location paths may also address
|
||||
attribute nodes, text nodes, comment nodes, and processing instruction
|
||||
@ -166,35 +179,27 @@ location path. Predicates are of the form
|
||||
<code><foo></code> elements that contain an <code>include</code>
|
||||
attribute with the value of <code>true</code>:</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
//foo[@include='true']
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>Predicates may be appended to each other to further refine an
|
||||
expression, such as:</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
//foo[@include='true'][@mode='bar']
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<h3>Using the XPath API</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>
|
||||
<a name="XPath.Datatypes"></a>
|
||||
<h3>3. XPath Data Types</h3>
|
||||
|
||||
<p>While XPath expressions select nodes in the XML document, the XPath
|
||||
API allows the selected nodes to be coalesced into one of the
|
||||
following other data types:</p>
|
||||
following data types:</p>
|
||||
|
||||
<ul>
|
||||
<li><code>Boolean</code></li>
|
||||
@ -202,14 +207,10 @@ following other data types:</p>
|
||||
<li><code>String</code></li>
|
||||
</ul>
|
||||
|
||||
<p>The desired 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 to one of the
|
||||
<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>
|
||||
|
||||
<a name="XPath.Datatypes.QName"></a>
|
||||
<h3>3.1 QName types</h3>
|
||||
The XPath API defines the following {@link javax.xml.namespace.QName} types to
|
||||
represent return types of an XPath evaluation:
|
||||
<ul>
|
||||
<li>{@link javax.xml.xpath.XPathConstants#NODESET}</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>
|
||||
</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,
|
||||
<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
|
||||
the character data from a text node, attribute node, comment node, or
|
||||
processing-instruction node. When used on an element node, the value
|
||||
of the child text nodes is returned.
|
||||
</p>
|
||||
|
||||
<p>The <code>Number</code> return type attempts to coalesce the text
|
||||
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
|
||||
document, known as the <code>context</code>. Consider the following
|
||||
XML document:</p>
|
||||
document, known as the <code>context</code>. A context consists of:
|
||||
<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>
|
||||
<widgets>
|
||||
<widget>
|
||||
@ -246,36 +292,88 @@ XML document:</p>
|
||||
</widget>
|
||||
</widgets>
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>The <code><widget></code> element can be selected with the
|
||||
following XPath API code:</p>
|
||||
<p>
|
||||
The <code><widget></code> element can be selected with the following process:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
// parse the XML as a W3C Document
|
||||
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
|
||||
Document document = builder.parse(new File("/widgets.xml"));
|
||||
|
||||
//Get an XPath object and evaluate the expression
|
||||
XPath xpath = XPathFactory.newInstance().newXPath();
|
||||
String expression = "/widgets/widget";
|
||||
Node widgetNode = (Node) xpath.evaluate(expression, document, XPathConstants.NODE);
|
||||
|
||||
//or using the evaluateExpression method
|
||||
Node widgetNode = xpath.evaluateExpression(expression, document, Node.class);
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>With a reference to the <code><widget></code> element, a
|
||||
relative XPath expression can now written to select the
|
||||
relative XPath expression can be written to select the
|
||||
<code><manufacturer></code> child element:</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
XPath xpath = XPathFactory.newInstance().newXPath();
|
||||
<strong>String expression = "manufacturer";</strong>
|
||||
Node manufacturerNode = (Node) xpath.evaluate(expression, <strong>widgetNode</strong>, XPathConstants.NODE);
|
||||
</pre>
|
||||
|
||||
<ul>
|
||||
<li>Author <a href="mailto:Ben@galbraiths.org">Ben Galbraith</a></li>
|
||||
<li>Author <a href="mailto:Norman.Walsh@Sun.com">Norman Walsh</a></li>
|
||||
<li>Author <a href="mailto:Jeff.Suttor@Sun.com">Jeff Suttor</a></li>
|
||||
<li>See <a href="http://www.w3.org/TR/xpath">XML Path Language (XPath) Version 1.0</a></li>
|
||||
<li>Since 1.5</li>
|
||||
</ul>
|
||||
//or using the evaluateExpression method
|
||||
Node manufacturerNode = xpath.evaluateExpression(expression, <strong>widgetNode</strong>, Node.class);
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
In the above example, the XML file is read into a DOM Document before being passed
|
||||
to the XPath API. The following code demonstrates the use of InputSource to
|
||||
leave it to the XPath implementation to process it:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
XPath xpath = XPathFactory.newInstance().newXPath();
|
||||
String expression = "/widgets/widget";
|
||||
InputSource inputSource = new InputSource("widgets.xml");
|
||||
NodeList nodes = (NodeList) xpath.evaluate(expression, inputSource, XPathConstants.NODESET);
|
||||
|
||||
//or using the evaluateExpression method
|
||||
XPathNodes nodes = xpath.evaluate(expression, inputSource, XPathNodes.class);
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
In the above cases, the type of the expected results are known. In case where
|
||||
the result type is unknown or any type, the {@link javax.xml.xpath.XPathEvaluationResult}
|
||||
may be used to determine the return type. The following code demonstrates the usage:
|
||||
<blockquote>
|
||||
<pre>
|
||||
XPathEvaluationResult<?> result = xpath.evaluateExpression(expression, document);
|
||||
switch (result.type()) {
|
||||
case NODESET:
|
||||
XPathNodes nodes = (XPathNodes)result.value();
|
||||
...
|
||||
break;
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
The XPath 1.0 Number data type is defined as a double. However, the XPath
|
||||
specification also provides functions that returns Integer type. To facilitate
|
||||
such operations, the XPath API allows Integer and Long to be used in
|
||||
{@code evaluateExpression} method such as the following code:
|
||||
<p>
|
||||
<blockquote>
|
||||
<pre>
|
||||
int count = xpath.evaluate("count(/widgets/widget)", document, Integer.class);
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
@since 1.5
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@ -0,0 +1,297 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package javax.xml.validation.ptests;
|
||||
|
||||
import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;
|
||||
import static javax.xml.validation.ptests.ValidationTestConst.XML_DIR;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
import static org.testng.Assert.assertNull;
|
||||
import static org.testng.Assert.assertSame;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.sax.SAXSource;
|
||||
import javax.xml.transform.stream.StreamSource;
|
||||
import javax.xml.validation.Schema;
|
||||
import javax.xml.validation.SchemaFactory;
|
||||
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
import org.w3c.dom.Document;
|
||||
import org.xml.sax.ErrorHandler;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.SAXNotRecognizedException;
|
||||
import org.xml.sax.SAXNotSupportedException;
|
||||
import org.xml.sax.SAXParseException;
|
||||
|
||||
/*
|
||||
* @summary Class containing the test cases for SchemaFactory
|
||||
*/
|
||||
@Test(singleThreaded = true)
|
||||
public class SchemaFactoryTest {
|
||||
|
||||
@BeforeClass
|
||||
public void setup() throws SAXException, IOException, ParserConfigurationException {
|
||||
sf = newSchemaFactory();
|
||||
|
||||
assertNotNull(sf);
|
||||
|
||||
xsd1 = Files.readAllBytes(Paths.get(XML_DIR + "test.xsd"));
|
||||
xsd2 = Files.readAllBytes(Paths.get(XML_DIR + "test1.xsd"));
|
||||
|
||||
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||
dbf.setNamespaceAware(true);
|
||||
DocumentBuilder db = dbf.newDocumentBuilder();
|
||||
xsdDoc1 = db.parse(newInputStream(xsd1));
|
||||
xsdDoc2 = db.parse(newInputStream(xsd2));
|
||||
|
||||
xml = Files.readAllBytes(Paths.get(XML_DIR + "test.xml"));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = SAXParseException.class)
|
||||
public void testNewSchemaDefault() throws SAXException, IOException {
|
||||
validate(sf.newSchema());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNewSchemaWithFile() throws SAXException, IOException {
|
||||
validate(sf.newSchema(new File(XML_DIR + "test.xsd")));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void testNewSchemaWithNullFile() throws SAXException {
|
||||
sf.newSchema((File) null);
|
||||
}
|
||||
|
||||
@DataProvider(name = "valid-source")
|
||||
public Object[][] getValidSource() {
|
||||
return new Object[][] {
|
||||
{ streamSource(xsd1) },
|
||||
{ saxSource(xsd1) },
|
||||
{ domSource(xsdDoc1) } };
|
||||
|
||||
}
|
||||
|
||||
@Test(dataProvider = "valid-source")
|
||||
public void testNewSchemaWithValidSource(Source schema) throws SAXException, IOException {
|
||||
validate(sf.newSchema(schema));
|
||||
}
|
||||
|
||||
@DataProvider(name = "invalid-source")
|
||||
public Object[][] getInvalidSource() {
|
||||
return new Object[][] {
|
||||
{ nullStreamSource() },
|
||||
{ nullSaxSource() } };
|
||||
}
|
||||
|
||||
@Test(dataProvider = "invalid-source", expectedExceptions = SAXParseException.class)
|
||||
public void testNewSchemaWithInvalidSource(Source schema) throws SAXException {
|
||||
sf.newSchema(schema);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void testNewSchemaWithNullSource() throws SAXException {
|
||||
sf.newSchema((Source)null);
|
||||
}
|
||||
|
||||
@DataProvider(name = "valid-sources")
|
||||
public Object[][] getValidSources() {
|
||||
return new Object[][] {
|
||||
{ streamSource(xsd1), streamSource(xsd2) },
|
||||
{ saxSource(xsd1), saxSource(xsd2) },
|
||||
{ domSource(xsdDoc1), domSource(xsdDoc2) } };
|
||||
|
||||
}
|
||||
|
||||
@Test(dataProvider = "valid-sources")
|
||||
public void testNewSchemaWithValidSourceArray(Source schema1, Source schema2) throws SAXException, IOException {
|
||||
validate(sf.newSchema(new Source[] { schema1, schema2 }));
|
||||
}
|
||||
|
||||
@DataProvider(name = "invalid-sources")
|
||||
public Object[][] getInvalidSources() {
|
||||
return new Object[][] {
|
||||
{ streamSource(xsd1), nullStreamSource() },
|
||||
{ nullStreamSource(), nullStreamSource() },
|
||||
{ saxSource(xsd1), nullSaxSource() },
|
||||
{ nullSaxSource(), nullSaxSource() } };
|
||||
}
|
||||
|
||||
@Test(dataProvider = "invalid-sources", expectedExceptions = SAXParseException.class)
|
||||
public void testNewSchemaWithInvalidSourceArray(Source schema1, Source schema2) throws SAXException {
|
||||
sf.newSchema(new Source[] { schema1, schema2 });
|
||||
}
|
||||
|
||||
@DataProvider(name = "null-sources")
|
||||
public Object[][] getNullSources() {
|
||||
return new Object[][] {
|
||||
{ new Source[] { domSource(xsdDoc1), null } },
|
||||
{ new Source[] { null, null } },
|
||||
{ null } };
|
||||
|
||||
}
|
||||
|
||||
@Test(dataProvider = "null-sources", expectedExceptions = NullPointerException.class)
|
||||
public void testNewSchemaWithNullSourceArray(Source[] schemas) throws SAXException {
|
||||
sf.newSchema(schemas);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void testNewSchemaWithNullUrl() throws SAXException {
|
||||
sf.newSchema((URL) null);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testErrorHandler() {
|
||||
SchemaFactory sf = newSchemaFactory();
|
||||
assertNull(sf.getErrorHandler(), "When SchemaFactory is created, initially ErrorHandler should not be set.");
|
||||
|
||||
ErrorHandler handler = new MyErrorHandler();
|
||||
sf.setErrorHandler(handler);
|
||||
assertSame(sf.getErrorHandler(), handler);
|
||||
|
||||
sf.setErrorHandler(null);
|
||||
assertNull(sf.getErrorHandler());
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = SAXNotRecognizedException.class)
|
||||
public void testGetUnrecognizedProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
|
||||
SchemaFactory sf = newSchemaFactory();
|
||||
sf.getProperty(UNRECOGNIZED_NAME);
|
||||
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = SAXNotRecognizedException.class)
|
||||
public void testSetUnrecognizedProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
|
||||
SchemaFactory sf = newSchemaFactory();
|
||||
sf.setProperty(UNRECOGNIZED_NAME, "test");
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void testGetNullProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
|
||||
SchemaFactory sf = newSchemaFactory();
|
||||
assertNotNull(sf);
|
||||
sf.getProperty(null);
|
||||
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void testSetNullProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
|
||||
SchemaFactory sf = newSchemaFactory();
|
||||
assertNotNull(sf);
|
||||
sf.setProperty(null, "test");
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = SAXNotRecognizedException.class)
|
||||
public void testGetUnrecognizedFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
|
||||
SchemaFactory sf = newSchemaFactory();
|
||||
sf.getFeature(UNRECOGNIZED_NAME);
|
||||
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = SAXNotRecognizedException.class)
|
||||
public void testSetUnrecognizedFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
|
||||
SchemaFactory sf = newSchemaFactory();
|
||||
sf.setFeature(UNRECOGNIZED_NAME, true);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void testGetNullFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
|
||||
SchemaFactory sf = newSchemaFactory();
|
||||
assertNotNull(sf);
|
||||
sf.getFeature(null);
|
||||
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void testSetNullFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
|
||||
SchemaFactory sf = newSchemaFactory();
|
||||
assertNotNull(sf);
|
||||
sf.setFeature(null, true);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||
public void testInvalidSchemaLanguage() {
|
||||
final String INVALID_SCHEMA_LANGUAGE = "http://relaxng.org/ns/structure/1.0";
|
||||
SchemaFactory.newInstance(INVALID_SCHEMA_LANGUAGE);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void testNullSchemaLanguage() {
|
||||
SchemaFactory.newInstance(null);
|
||||
}
|
||||
|
||||
private void validate(Schema schema) throws SAXException, IOException {
|
||||
schema.newValidator().validate(new StreamSource(new ByteArrayInputStream(xml)));
|
||||
}
|
||||
private InputStream newInputStream(byte[] xsd) {
|
||||
return new ByteArrayInputStream(xsd);
|
||||
}
|
||||
|
||||
private Source streamSource(byte[] xsd) {
|
||||
return new StreamSource(newInputStream(xsd));
|
||||
}
|
||||
|
||||
private Source nullStreamSource() {
|
||||
return new StreamSource((InputStream) null);
|
||||
}
|
||||
|
||||
private Source saxSource(byte[] xsd) {
|
||||
return new SAXSource(new InputSource(newInputStream(xsd)));
|
||||
}
|
||||
|
||||
private Source nullSaxSource() {
|
||||
return new SAXSource(new InputSource((InputStream) null));
|
||||
}
|
||||
|
||||
private Source domSource(Document xsdDoc) {
|
||||
return new DOMSource(xsdDoc);
|
||||
}
|
||||
|
||||
private SchemaFactory newSchemaFactory() {
|
||||
return SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI);
|
||||
}
|
||||
|
||||
private static final String UNRECOGNIZED_NAME = "http://xml.org/sax/features/namespace-prefixes";
|
||||
|
||||
private SchemaFactory sf;
|
||||
private byte[] xsd1;
|
||||
private byte[] xsd2;
|
||||
private Document xsdDoc1;
|
||||
private Document xsdDoc2;
|
||||
private byte[] xml;
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package javax.xml.validation.ptests;
|
||||
|
||||
import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;
|
||||
import static javax.xml.validation.ptests.ValidationTestConst.XML_DIR;
|
||||
import static jaxp.library.JAXPTestUtilities.filenameToURL;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertFalse;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.parsers.SAXParserFactory;
|
||||
import javax.xml.validation.Schema;
|
||||
import javax.xml.validation.SchemaFactory;
|
||||
import javax.xml.validation.TypeInfoProvider;
|
||||
import javax.xml.validation.ValidatorHandler;
|
||||
|
||||
import jaxp.library.JAXPFileBaseTest;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.XMLReader;
|
||||
import org.xml.sax.helpers.DefaultHandler;
|
||||
|
||||
/*
|
||||
* @summary test ValidatorHandler.getTypeInfoProvider()
|
||||
*/
|
||||
public class TypeInfoProviderTest extends JAXPFileBaseTest {
|
||||
|
||||
private ValidatorHandler validatorHandler;
|
||||
|
||||
@Test
|
||||
public void test() throws SAXException, ParserConfigurationException, IOException {
|
||||
|
||||
SchemaFactory sf = SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI);
|
||||
Schema schema = sf.newSchema(new File(XML_DIR + "shiporder11.xsd"));
|
||||
validatorHandler = schema.newValidatorHandler();
|
||||
MyDefaultHandler myDefaultHandler = new MyDefaultHandler();
|
||||
validatorHandler.setContentHandler(myDefaultHandler);
|
||||
|
||||
InputSource is = new InputSource(filenameToURL(XML_DIR + "shiporder11.xml"));
|
||||
|
||||
SAXParserFactory parserFactory = SAXParserFactory.newInstance();
|
||||
parserFactory.setNamespaceAware(true);
|
||||
XMLReader xmlReader = parserFactory.newSAXParser().getXMLReader();
|
||||
xmlReader.setContentHandler(validatorHandler);
|
||||
xmlReader.parse(is);
|
||||
|
||||
}
|
||||
|
||||
private class MyDefaultHandler extends DefaultHandler {
|
||||
|
||||
public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
|
||||
TypeInfoProvider typeInfoProvider = validatorHandler.getTypeInfoProvider();
|
||||
int index = atts.getIndex("orderid");
|
||||
if (index != -1) {
|
||||
System.out.println(" Index " + index);
|
||||
System.out.println(" ElementType " + typeInfoProvider.getElementTypeInfo().getTypeName());
|
||||
assertEquals(typeInfoProvider.getAttributeTypeInfo(index).getTypeName(), "string");
|
||||
assertTrue(typeInfoProvider.isSpecified(index));
|
||||
assertFalse(typeInfoProvider.isIdAttribute(index));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package javax.xml.validation.ptests;
|
||||
|
||||
import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;
|
||||
import static javax.xml.validation.ptests.ValidationTestConst.XML_DIR;
|
||||
import static org.testng.Assert.assertFalse;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
import static org.testng.Assert.assertNull;
|
||||
import static org.testng.Assert.assertSame;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import javax.xml.validation.Schema;
|
||||
import javax.xml.validation.SchemaFactory;
|
||||
import javax.xml.validation.ValidatorHandler;
|
||||
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
import org.xml.sax.ContentHandler;
|
||||
import org.xml.sax.ErrorHandler;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.SAXNotRecognizedException;
|
||||
import org.xml.sax.SAXNotSupportedException;
|
||||
import org.xml.sax.helpers.DefaultHandler;
|
||||
|
||||
/*
|
||||
* @summary Class containing the test cases for ValidatorHandler API
|
||||
*/
|
||||
public class ValidatorHandlerTest {
|
||||
@BeforeClass
|
||||
public void setup() throws SAXException {
|
||||
schema = SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI).newSchema(new File(XML_DIR + "test.xsd"));
|
||||
|
||||
assertNotNull(schema);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testErrorHandler() {
|
||||
ValidatorHandler validatorHandler = getValidatorHandler();
|
||||
assertNull(validatorHandler.getErrorHandler(), "When ValidatorHandler is created, initially ErrorHandler should not be set.");
|
||||
|
||||
ErrorHandler handler = new MyErrorHandler();
|
||||
validatorHandler.setErrorHandler(handler);
|
||||
assertSame(validatorHandler.getErrorHandler(), handler);
|
||||
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = SAXNotRecognizedException.class)
|
||||
public void testGetUnrecognizedProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
|
||||
ValidatorHandler validatorHandler = getValidatorHandler();
|
||||
validatorHandler.getProperty(FEATURE_NAME);
|
||||
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = SAXNotRecognizedException.class)
|
||||
public void testSetUnrecognizedProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
|
||||
ValidatorHandler validatorHandler = getValidatorHandler();
|
||||
validatorHandler.setProperty(FEATURE_NAME, "test");
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void testGetNullProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
|
||||
ValidatorHandler validatorHandler = getValidatorHandler();
|
||||
assertNotNull(validatorHandler);
|
||||
validatorHandler.getProperty(null);
|
||||
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void testSetNullProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
|
||||
ValidatorHandler validatorHandler = getValidatorHandler();
|
||||
assertNotNull(validatorHandler);
|
||||
validatorHandler.setProperty(null, "test");
|
||||
}
|
||||
|
||||
public void testFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
|
||||
ValidatorHandler validatorHandler = getValidatorHandler();
|
||||
assertFalse(validatorHandler.getFeature(FEATURE_NAME), "The feature should be false by default.");
|
||||
|
||||
validatorHandler.setFeature(FEATURE_NAME, true);
|
||||
assertTrue(validatorHandler.getFeature(FEATURE_NAME), "The feature should be false by default.");
|
||||
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void testGetNullFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
|
||||
ValidatorHandler validatorHandler = getValidatorHandler();
|
||||
assertNotNull(validatorHandler);
|
||||
validatorHandler.getFeature(null);
|
||||
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void testSetNullFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
|
||||
ValidatorHandler validatorHandler = getValidatorHandler();
|
||||
assertNotNull(validatorHandler);
|
||||
validatorHandler.setFeature(null, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContentHandler() {
|
||||
ValidatorHandler validatorHandler = getValidatorHandler();
|
||||
assertNull(validatorHandler.getContentHandler(), "When ValidatorHandler is created, initially ContentHandler should not be set.");
|
||||
|
||||
ContentHandler handler = new DefaultHandler();
|
||||
validatorHandler.setContentHandler(handler);
|
||||
assertSame(validatorHandler.getContentHandler(), handler);
|
||||
|
||||
validatorHandler.setContentHandler(null);
|
||||
assertNull(validatorHandler.getContentHandler());
|
||||
|
||||
}
|
||||
|
||||
private ValidatorHandler getValidatorHandler() {
|
||||
return schema.newValidatorHandler();
|
||||
}
|
||||
|
||||
private static final String FEATURE_NAME = "http://xml.org/sax/features/namespace-prefixes";
|
||||
|
||||
private Schema schema;
|
||||
|
||||
}
|
@ -0,0 +1,207 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package javax.xml.validation.ptests;
|
||||
|
||||
import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;
|
||||
import static javax.xml.validation.ptests.ValidationTestConst.XML_DIR;
|
||||
import static jaxp.library.JAXPTestUtilities.filenameToURL;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
import static org.testng.Assert.assertNull;
|
||||
import static org.testng.Assert.assertSame;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.transform.Result;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.dom.DOMResult;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.sax.SAXResult;
|
||||
import javax.xml.transform.sax.SAXSource;
|
||||
import javax.xml.transform.stream.StreamSource;
|
||||
import javax.xml.validation.Schema;
|
||||
import javax.xml.validation.SchemaFactory;
|
||||
import javax.xml.validation.Validator;
|
||||
|
||||
import jaxp.library.JAXPFileBaseTest;
|
||||
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
import org.w3c.dom.Document;
|
||||
import org.xml.sax.ErrorHandler;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.SAXNotRecognizedException;
|
||||
import org.xml.sax.SAXNotSupportedException;
|
||||
import org.xml.sax.helpers.DefaultHandler;
|
||||
|
||||
/*
|
||||
* @summary Class containing the test cases for Validator API
|
||||
*/
|
||||
public class ValidatorTest extends JAXPFileBaseTest {
|
||||
|
||||
@BeforeClass
|
||||
public void setup() throws SAXException, IOException, ParserConfigurationException {
|
||||
schema = SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI).newSchema(new File(XML_DIR + "test.xsd"));
|
||||
|
||||
assertNotNull(schema);
|
||||
|
||||
xmlFileUri = filenameToURL(XML_DIR + "test.xml");
|
||||
|
||||
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||
dbf.setNamespaceAware(true);
|
||||
xmlDoc = dbf.newDocumentBuilder().parse(xmlFileUri);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateStreamSource() throws SAXException, IOException {
|
||||
Validator validator = getValidator();
|
||||
validator.setErrorHandler(new MyErrorHandler());
|
||||
validator.validate(getStreamSource());
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void testValidateNullSource() throws SAXException, IOException {
|
||||
Validator validator = getValidator();
|
||||
assertNotNull(validator);
|
||||
validator.validate(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testErrorHandler() {
|
||||
Validator validator = getValidator();
|
||||
assertNull(validator.getErrorHandler(), "When Validator is created, initially ErrorHandler should not be set.");
|
||||
|
||||
ErrorHandler mh = new MyErrorHandler();
|
||||
validator.setErrorHandler(mh);
|
||||
assertSame(validator.getErrorHandler(), mh);
|
||||
|
||||
}
|
||||
|
||||
@DataProvider(name = "source-result")
|
||||
public Object[][] getSourceAndResult() {
|
||||
return new Object[][] {
|
||||
{ getStreamSource(), null },
|
||||
{ getSAXSource(), getSAXResult() },
|
||||
{ getDOMSource(), getDOMResult() },
|
||||
{ getSAXSource(), null },
|
||||
{ getDOMSource(), null } };
|
||||
}
|
||||
|
||||
@Test(dataProvider = "source-result")
|
||||
public void testValidateWithResult(Source source, Result result) throws SAXException, IOException {
|
||||
Validator validator = getValidator();
|
||||
validator.validate(source, result);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = SAXNotRecognizedException.class)
|
||||
public void testGetUnrecognizedProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
|
||||
Validator validator = getValidator();
|
||||
validator.getProperty(UNRECOGNIZED_NAME);
|
||||
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = SAXNotRecognizedException.class)
|
||||
public void testSetUnrecognizedProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
|
||||
Validator validator = getValidator();
|
||||
validator.setProperty(UNRECOGNIZED_NAME, "test");
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void testGetNullProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
|
||||
Validator validator = getValidator();
|
||||
assertNotNull(validator);
|
||||
validator.getProperty(null);
|
||||
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void testSetNullProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
|
||||
Validator validator = getValidator();
|
||||
assertNotNull(validator);
|
||||
validator.setProperty(null, "test");
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = SAXNotRecognizedException.class)
|
||||
public void testGetUnrecognizedFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
|
||||
Validator validator = getValidator();
|
||||
validator.getFeature(UNRECOGNIZED_NAME);
|
||||
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = SAXNotRecognizedException.class)
|
||||
public void testSetUnrecognizedFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
|
||||
Validator validator = getValidator();
|
||||
validator.setFeature(UNRECOGNIZED_NAME, true);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void testGetNullFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
|
||||
Validator validator = getValidator();
|
||||
assertNotNull(validator);
|
||||
validator.getFeature(null);
|
||||
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void testSetNullFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
|
||||
Validator validator = getValidator();
|
||||
assertNotNull(validator);
|
||||
validator.setFeature(null, true);
|
||||
}
|
||||
|
||||
private Validator getValidator() {
|
||||
return schema.newValidator();
|
||||
}
|
||||
|
||||
private Source getStreamSource() {
|
||||
return new StreamSource(xmlFileUri);
|
||||
}
|
||||
|
||||
private Source getSAXSource() {
|
||||
return new SAXSource(new InputSource(xmlFileUri));
|
||||
}
|
||||
|
||||
private Result getSAXResult() {
|
||||
SAXResult saxResult = new SAXResult();
|
||||
saxResult.setHandler(new DefaultHandler());
|
||||
return saxResult;
|
||||
}
|
||||
|
||||
private Source getDOMSource() {
|
||||
return new DOMSource(xmlDoc);
|
||||
}
|
||||
|
||||
private Result getDOMResult() {
|
||||
return new DOMResult();
|
||||
}
|
||||
|
||||
private static final String UNRECOGNIZED_NAME = "http://xml.org/sax/features/namespace-prefixes";
|
||||
private String xmlFileUri;
|
||||
private Schema schema;
|
||||
private Document xmlDoc;
|
||||
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
|
||||
<shiporder orderid="889923"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="shiporder.xsd">
|
||||
<orderperson>John Smith</orderperson>
|
||||
<shipto>
|
||||
<name>Ola Nordmann</name>
|
||||
<address>Langgt 23</address>
|
||||
<city>4000 Stavanger</city>
|
||||
<country>Norway</country>
|
||||
</shipto>
|
||||
<item>
|
||||
<title>Empire Burlesque</title>
|
||||
<note>Special Edition</note>
|
||||
<quantity>1</quantity>
|
||||
<price>10.90</price>
|
||||
</item>
|
||||
<item>
|
||||
<title>Hide your heart</title>
|
||||
<quantity>1</quantity>
|
||||
<price>9.90</price>
|
||||
</item>
|
||||
</shiporder>
|
@ -0,0 +1,51 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
|
||||
<!-- definition of simple elements -->
|
||||
<xs:element name="orderperson" type="xs:string"/>
|
||||
<xs:element name="name" type="xs:string"/>
|
||||
<xs:element name="address" type="xs:string"/>
|
||||
<xs:element name="city" type="xs:string"/>
|
||||
<xs:element name="country" type="xs:string"/>
|
||||
<xs:element name="title" type="xs:string"/>
|
||||
<xs:element name="note" type="xs:string"/>
|
||||
<xs:element name="quantity" type="xs:positiveInteger"/>
|
||||
<xs:element name="price" type="xs:decimal"/>
|
||||
|
||||
<!-- definition of attributes -->
|
||||
<xs:attribute name="orderid" type="xs:string"/>
|
||||
|
||||
<!-- definition of complex elements -->
|
||||
<xs:element name="shipto">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element ref="name"/>
|
||||
<xs:element ref="address"/>
|
||||
<xs:element ref="city"/>
|
||||
<xs:element ref="country"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="item">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element ref="title"/>
|
||||
<xs:element ref="note" minOccurs="0"/>
|
||||
<xs:element ref="quantity"/>
|
||||
<xs:element ref="price"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="shiporder">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element ref="orderperson"/>
|
||||
<xs:element ref="shipto"/>
|
||||
<xs:element ref="item" maxOccurs="unbounded"/>
|
||||
</xs:sequence>
|
||||
<xs:attribute ref="orderid" use="required"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
</xs:schema>
|
@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
|
||||
<shiporder orderid="889923"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="shiporder.xsd">
|
||||
<orderperson>John Smith</orderperson>
|
||||
<shipto>
|
||||
<name>Ola Nordmann</name>
|
||||
<address>Langgt 23</address>
|
||||
<city>4000 Stavanger</city>
|
||||
<country>Norway</country>
|
||||
</shipto>
|
||||
<item>
|
||||
<title>Empire Burlesque</title>
|
||||
<note>Special Edition</note>
|
||||
<quantity>1</quantity>
|
||||
<price>10.90</price>
|
||||
</item>
|
||||
<item>
|
||||
<title>Hide your heart</title>
|
||||
<quantity>1</quantity>
|
||||
<price>9.90</price>
|
||||
</item>
|
||||
</shiporder>
|
@ -0,0 +1,51 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
|
||||
<!-- definition of simple elements -->
|
||||
<xs:element name="orderperson" type="xs:string"/>
|
||||
<xs:element name="name" type="xs:string"/>
|
||||
<xs:element name="address" type="xs:string"/>
|
||||
<xs:element name="city" type="xs:string"/>
|
||||
<xs:element name="country" type="xs:string"/>
|
||||
<xs:element name="title" type="xs:string"/>
|
||||
<xs:element name="note" type="xs:string"/>
|
||||
<xs:element name="quantity" type="xs:positiveInteger"/>
|
||||
<xs:element name="price" type="xs:decimal"/>
|
||||
|
||||
<!-- definition of attributes -->
|
||||
<xs:attribute name="orderid" type="xs:string"/>
|
||||
|
||||
<!-- definition of complex elements -->
|
||||
<xs:element name="shipto">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element ref="name"/>
|
||||
<xs:element ref="address"/>
|
||||
<xs:element ref="city"/>
|
||||
<xs:element ref="country"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="item">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element ref="title"/>
|
||||
<xs:element ref="note" minOccurs="0"/>
|
||||
<xs:element ref="quantity"/>
|
||||
<xs:element ref="price"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="shiporder">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element ref="orderperson"/>
|
||||
<xs:element ref="shipto"/>
|
||||
<xs:element ref="item" maxOccurs="unbounded"/>
|
||||
</xs:sequence>
|
||||
<xs:attribute ref="orderid" use="required"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
</xs:schema>
|
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<contact xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="test.xsd">
|
||||
<name> John </name>
|
||||
<phone>444-121-3434</phone>
|
||||
</contact>
|
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<xs:element name="contact">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="name" type="xs:string"/>
|
||||
<xs:element name="phone" type="xs:string"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<xs:element name="address">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="street" type="xs:string"/>
|
||||
<xs:element name="city" type="xs:string"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package test.gaptest;
|
||||
|
||||
import java.io.StringReader;
|
||||
|
||||
import javax.xml.transform.TransformerConfigurationException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.stream.StreamSource;
|
||||
|
||||
import jaxp.library.JAXPBaseTest;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/*
|
||||
* @bug 4511326
|
||||
* @summary In forwards-compatible mode the attribute isn't ignored
|
||||
*/
|
||||
|
||||
public class Bug4511326 extends JAXPBaseTest {
|
||||
|
||||
private static final String XSL = "<xsl:stylesheet version='2.0' "
|
||||
+ "xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>"
|
||||
+ "<xsl:template a='1' match='/'>"
|
||||
+ "<H2><xsl:value-of select='//author'/></H2>"
|
||||
+ "<H1><xsl:value-of select='//title'/></H1>"
|
||||
+ "</xsl:template>"
|
||||
+ "</xsl:stylesheet>";
|
||||
|
||||
|
||||
@Test
|
||||
public void ignoreAttTest() throws TransformerConfigurationException {
|
||||
/* Create a TransformFactory instance */
|
||||
TransformerFactory transformerFactory = TransformerFactory.newInstance();
|
||||
|
||||
/* Create and init a StreamSource instance */
|
||||
StreamSource source = new StreamSource(new StringReader(XSL));
|
||||
|
||||
transformerFactory.newTransformer(source);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package test.gaptest;
|
||||
|
||||
import static javax.xml.transform.OutputKeys.ENCODING;
|
||||
import static javax.xml.transform.OutputKeys.INDENT;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.StringReader;
|
||||
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerConfigurationException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.stream.StreamSource;
|
||||
|
||||
import jaxp.library.JAXPBaseTest;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/*
|
||||
* @bug 4512806
|
||||
* @summary test transformer.setOutputProperties(null)
|
||||
*/
|
||||
public class Bug4512806 extends JAXPBaseTest {
|
||||
|
||||
@Test
|
||||
public void testProperty() throws TransformerConfigurationException {
|
||||
/* Create a transform factory instance */
|
||||
TransformerFactory tfactory = TransformerFactory.newInstance();
|
||||
|
||||
/* Create a StreamSource instance */
|
||||
StreamSource streamSource = new StreamSource(new StringReader(xslData));
|
||||
|
||||
transformer = tfactory.newTransformer(streamSource);
|
||||
transformer.setOutputProperty(INDENT, "no");
|
||||
transformer.setOutputProperty(ENCODING, "UTF-16");
|
||||
|
||||
assertEquals(printPropertyValue(INDENT), "indent=no");
|
||||
assertEquals(printPropertyValue(ENCODING), "encoding=UTF-16");
|
||||
|
||||
transformer.setOutputProperties(null);
|
||||
|
||||
assertEquals(printPropertyValue(INDENT), "indent=yes");
|
||||
assertEquals(printPropertyValue(ENCODING), "encoding=UTF-8");
|
||||
|
||||
}
|
||||
|
||||
private String printPropertyValue(String name) {
|
||||
return name + "=" + transformer.getOutputProperty(name);
|
||||
}
|
||||
|
||||
private Transformer transformer;
|
||||
|
||||
private static final String xslData = "<?xml version='1.0'?>"
|
||||
+ "<xsl:stylesheet"
|
||||
+ " version='1.0'"
|
||||
+ " xmlns:xsl='http://www.w3.org/1999/XSL/Transform'"
|
||||
+ ">\n"
|
||||
+ " <xsl:output method='xml' indent='yes'"
|
||||
+ " encoding='UTF-8'/>\n"
|
||||
+ " <xsl:template match='/'>\n"
|
||||
+ " Hello World! \n"
|
||||
+ " </xsl:template>\n"
|
||||
+ "</xsl:stylesheet>";
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package test.gaptest;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
|
||||
import jaxp.library.JAXPBaseTest;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/*
|
||||
* @bug 4515047
|
||||
* @summary test transform an empty dom source
|
||||
*/
|
||||
|
||||
public class Bug4515047 extends JAXPBaseTest {
|
||||
|
||||
@Test
|
||||
public void testCreateTxDoc() throws TransformerException, ParserConfigurationException {
|
||||
Transformer transformer = TransformerFactory.newInstance().newTransformer();
|
||||
|
||||
StreamResult result = new StreamResult(System.out);
|
||||
DOMSource source = new DOMSource();
|
||||
|
||||
/* This should not throw an Illegal Argument Exception */
|
||||
//Test empty DOMSource
|
||||
transformer.transform(source, result);
|
||||
|
||||
//Test DOMSource having only an empty node
|
||||
source.setNode(DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument());
|
||||
transformer.transform(source, result);
|
||||
}
|
||||
|
||||
}
|
123
jaxp/test/javax/xml/jaxp/functional/test/gaptest/Bug4515660.java
Normal file
123
jaxp/test/javax/xml/jaxp/functional/test/gaptest/Bug4515660.java
Normal file
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package test.gaptest;
|
||||
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.parsers.SAXParserFactory;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerConfigurationException;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.sax.SAXSource;
|
||||
import javax.xml.transform.sax.SAXTransformerFactory;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
|
||||
import jaxp.library.JAXPBaseTest;
|
||||
|
||||
import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.helpers.XMLFilterImpl;
|
||||
|
||||
/*
|
||||
* @bug 4515660
|
||||
* @summary verify property org.xml.sax.driver is used by SAXTransformerFactory
|
||||
*/
|
||||
@Test(singleThreaded = true)
|
||||
public class Bug4515660 extends JAXPBaseTest {
|
||||
|
||||
@BeforeClass
|
||||
public void setSaxDrier() {
|
||||
setSystemProperty("org.xml.sax.driver", ReaderStub.class.getName());
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public void clearSaxDrier() {
|
||||
setSystemProperty("org.xml.sax.driver", null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransformer() throws TransformerException {
|
||||
String xml = "<?xml version='1.0'?><root/>";
|
||||
ReaderStub.used = false;
|
||||
|
||||
TransformerFactory transFactory = TransformerFactory.newInstance();
|
||||
Transformer transformer = transFactory.newTransformer();
|
||||
InputSource in = new InputSource(new StringReader(xml));
|
||||
SAXSource source = new SAXSource(in);
|
||||
StreamResult result = new StreamResult(new StringWriter());
|
||||
|
||||
transformer.transform(source, result);
|
||||
|
||||
assertTrue(ReaderStub.used);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSAXTransformerFactory() throws TransformerConfigurationException {
|
||||
final String xsl = "<?xml version='1.0'?>\n" + "<xsl:stylesheet" + " xmlns:xsl='http://www.w3.org/1999/XSL/Transform'" + " version='1.0'>\n"
|
||||
+ " <xsl:template match='/'>Hello World!</xsl:template>\n" + "</xsl:stylesheet>\n";
|
||||
|
||||
ReaderStub.used = false;
|
||||
|
||||
TransformerFactory transFactory = TransformerFactory.newInstance();
|
||||
assertTrue(transFactory.getFeature(SAXTransformerFactory.FEATURE));
|
||||
|
||||
InputSource in = new InputSource(new StringReader(xsl));
|
||||
SAXSource source = new SAXSource(in);
|
||||
|
||||
transFactory.newTransformer(source);
|
||||
assertTrue(ReaderStub.used);
|
||||
|
||||
}
|
||||
|
||||
public static class ReaderStub extends XMLFilterImpl {
|
||||
static boolean used = false;
|
||||
|
||||
public ReaderStub() throws ParserConfigurationException, SAXException {
|
||||
super();
|
||||
super.setParent(SAXParserFactory.newInstance().newSAXParser().getXMLReader());
|
||||
used = true;
|
||||
}
|
||||
|
||||
public void parse(InputSource input) throws SAXException, IOException {
|
||||
used = true;
|
||||
super.parse(input);
|
||||
}
|
||||
|
||||
public void parse(String systemId) throws SAXException, IOException {
|
||||
used = true;
|
||||
super.parse(systemId);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package test.gaptest;
|
||||
|
||||
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
|
||||
import static jaxp.library.JAXPTestUtilities.USER_DIR;
|
||||
import static jaxp.library.JAXPTestUtilities.compareDocumentWithGold;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
import static test.gaptest.GapTestConst.GOLDEN_DIR;
|
||||
import static test.gaptest.GapTestConst.XML_DIR;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
import javax.xml.transform.stream.StreamSource;
|
||||
|
||||
import jaxp.library.JAXPFileBaseTest;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
/*
|
||||
* @bug 4693341
|
||||
* @summary test transforming to stream with external dtd
|
||||
*/
|
||||
|
||||
public class Bug4693341 extends JAXPFileBaseTest {
|
||||
|
||||
@Test
|
||||
public void test() throws TransformerException, ParserConfigurationException, SAXException, IOException {
|
||||
|
||||
Transformer transformer = TransformerFactory.newInstance().newTransformer();
|
||||
|
||||
String out = USER_DIR + File.separator + "Bug4693341.out";
|
||||
StreamResult result = new StreamResult(new File(out));
|
||||
|
||||
String in = XML_DIR + "Bug4693341.xml";
|
||||
String golden = GOLDEN_DIR + "Bug4693341.xml";
|
||||
File file = new File(in);
|
||||
StreamSource source = new StreamSource(file);
|
||||
System.out.println(source.getSystemId());
|
||||
|
||||
Files.copy(Paths.get(XML_DIR + "Bug4693341.dtd"),
|
||||
Paths.get(USER_DIR + File.separator + "Bug4693341.dtd"), REPLACE_EXISTING);
|
||||
|
||||
transformer.transform(source, result);
|
||||
|
||||
assertTrue(compareDocumentWithGold(golden, out));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package test.gaptest;
|
||||
|
||||
import static jaxp.library.JAXPTestUtilities.filenameToURL;
|
||||
import static test.gaptest.GapTestConst.XML_DIR;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.xml.XMLConstants;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.parsers.SAXParser;
|
||||
import javax.xml.parsers.SAXParserFactory;
|
||||
|
||||
import jaxp.library.JAXPFileBaseTest;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
import org.xml.sax.ErrorHandler;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.SAXParseException;
|
||||
import org.xml.sax.XMLReader;
|
||||
|
||||
/*
|
||||
* @bug 4848653
|
||||
* @summary Verify JAXP schemaLanguage property is ignored if setValidating(false)
|
||||
*/
|
||||
|
||||
public class Bug4848653 extends JAXPFileBaseTest {
|
||||
|
||||
@Test
|
||||
public void test() throws IOException, SAXException, ParserConfigurationException {
|
||||
SAXParserFactory factory = SAXParserFactory.newInstance();
|
||||
factory.setValidating(false);
|
||||
SAXParser parser = factory.newSAXParser();
|
||||
parser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaLanguage", XMLConstants.W3C_XML_SCHEMA_NS_URI);
|
||||
|
||||
String filename = XML_DIR + "Bug4848653.xml";
|
||||
InputSource is = new InputSource(filenameToURL(filename));
|
||||
XMLReader xmlReader = parser.getXMLReader();
|
||||
xmlReader.setErrorHandler(new MyErrorHandler());
|
||||
xmlReader.parse(is);
|
||||
}
|
||||
|
||||
class MyErrorHandler implements ErrorHandler {
|
||||
public void error(SAXParseException exception) throws SAXParseException {
|
||||
throw exception;
|
||||
}
|
||||
|
||||
public void warning(SAXParseException exception) throws SAXParseException {
|
||||
throw exception;
|
||||
}
|
||||
|
||||
public void fatalError(SAXParseException exception) throws SAXParseException {
|
||||
throw exception;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
246
jaxp/test/javax/xml/jaxp/functional/test/gaptest/Bug4858685.java
Normal file
246
jaxp/test/javax/xml/jaxp/functional/test/gaptest/Bug4858685.java
Normal file
@ -0,0 +1,246 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package test.gaptest;
|
||||
|
||||
import static jaxp.library.JAXPTestUtilities.filenameToURL;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static test.gaptest.GapTestConst.GOLDEN_DIR;
|
||||
import static test.gaptest.GapTestConst.XML_DIR;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.dom.DOMResult;
|
||||
import javax.xml.transform.stream.StreamSource;
|
||||
|
||||
import jaxp.library.JAXPFileBaseTest;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
/*
|
||||
* @bug 4858685 4894410
|
||||
* @summary test transforming text node
|
||||
*/
|
||||
|
||||
public class Bug4858685 extends JAXPFileBaseTest {
|
||||
@Test
|
||||
public void test() throws TransformerException, IOException {
|
||||
String uri = XML_DIR + "certificate.xml";
|
||||
TransformerFactory transformerFactory = TransformerFactory.newInstance();
|
||||
|
||||
Transformer transformer = transformerFactory.newTransformer();
|
||||
|
||||
// use URI as a StreamSource
|
||||
StreamSource streamSource = new StreamSource(filenameToURL(uri));
|
||||
|
||||
DOMResult domResult = new DOMResult();
|
||||
|
||||
// StreamSource -> DOMResult
|
||||
transformer.transform(streamSource, domResult);
|
||||
|
||||
// dump DOM in a human readable form
|
||||
String gotString = DOMDump.dumpDom(domResult.getNode());
|
||||
|
||||
String goldenString = new String(Files.readAllBytes(Paths.get(GOLDEN_DIR + "Bug4858685.txt")));
|
||||
|
||||
assertEquals(gotString, goldenString);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* DOMDump: dump a DOM to a String in human readable form. method dumpDOM()
|
||||
* is static for easy calling:
|
||||
*/
|
||||
private static class DOMDump {
|
||||
|
||||
/**
|
||||
* the maximum level to indent with blanks
|
||||
*/
|
||||
private static final int BLANKS_LEN = 64;
|
||||
|
||||
/**
|
||||
* each level of the tree will be indented with blanks for readability
|
||||
*/
|
||||
private static final String BLANKS = " ";
|
||||
|
||||
/**
|
||||
* dumpDOM will dump the DOM into a String for human readability
|
||||
*
|
||||
* @param domNode
|
||||
* the DOM Node to dump
|
||||
* @return human readabile DOM as a String
|
||||
*/
|
||||
public static String dumpDom(Node domNode) {
|
||||
return dumpInternal(domNode, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* dumpInternal is used internaly to recursively dump DOM Nodes
|
||||
*
|
||||
* @param domNode
|
||||
* to dump
|
||||
* @param indent
|
||||
* level
|
||||
* @return domNode as human readable String
|
||||
*/
|
||||
private static String dumpInternal(Node domNode, int indent) {
|
||||
|
||||
String result = "";
|
||||
|
||||
// indent for readability
|
||||
result += indentBlanks(indent);
|
||||
indent += 2;
|
||||
|
||||
// protect against null
|
||||
if (domNode == null) {
|
||||
result = result + "[null]" + "\n";
|
||||
return result;
|
||||
}
|
||||
|
||||
// what to output depends on NodeType
|
||||
short type = domNode.getNodeType();
|
||||
switch (type) {
|
||||
case Node.ATTRIBUTE_NODE: {
|
||||
result += "[attribute] " + domNode.getNodeName() + "=\"" + domNode.getNodeValue() + "\"";
|
||||
break;
|
||||
}
|
||||
case Node.CDATA_SECTION_NODE: {
|
||||
result += "[cdata] " + domNode.getNodeValue();
|
||||
break;
|
||||
}
|
||||
case Node.COMMENT_NODE: {
|
||||
result += "[comment] " + domNode.getNodeValue();
|
||||
break;
|
||||
}
|
||||
case Node.DOCUMENT_FRAGMENT_NODE: {
|
||||
result += "[document fragment]";
|
||||
break;
|
||||
}
|
||||
case Node.DOCUMENT_NODE: {
|
||||
result += "[document]";
|
||||
break;
|
||||
}
|
||||
case Node.DOCUMENT_TYPE_NODE: {
|
||||
result += "[document type] " + domNode.getNodeName();
|
||||
break;
|
||||
}
|
||||
case Node.ELEMENT_NODE: {
|
||||
result += "[element] " + domNode.getNodeName();
|
||||
// output all attributes for Element
|
||||
if (domNode.hasAttributes()) {
|
||||
NamedNodeMap attributes = domNode.getAttributes();
|
||||
for (int onAttribute = 0; onAttribute < attributes.getLength(); onAttribute++) {
|
||||
|
||||
// seprate each attribute with a space
|
||||
result += " ";
|
||||
|
||||
Node attribute = attributes.item(onAttribute);
|
||||
String namespaceURI = attribute.getNamespaceURI();
|
||||
String prefix = attribute.getPrefix();
|
||||
String localName = attribute.getLocalName();
|
||||
String name = attribute.getNodeName();
|
||||
String value = attribute.getNodeValue();
|
||||
|
||||
// using Namespaces?
|
||||
if (namespaceURI != null) {
|
||||
result += "{" + namespaceURI + "}";
|
||||
}
|
||||
if (prefix != null) {
|
||||
result += prefix + ":";
|
||||
}
|
||||
|
||||
// name="value"
|
||||
result += attribute.getNodeName() + "=\"" + attribute.getNodeValue() + "\"";
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case Node.ENTITY_NODE: {
|
||||
result += "[entity] " + domNode.getNodeName();
|
||||
break;
|
||||
}
|
||||
case Node.ENTITY_REFERENCE_NODE: {
|
||||
result += "[entity reference] " + domNode.getNodeName();
|
||||
break;
|
||||
}
|
||||
case Node.NOTATION_NODE: {
|
||||
result += "[notation] " + domNode.getNodeName();
|
||||
break;
|
||||
}
|
||||
case Node.PROCESSING_INSTRUCTION_NODE: {
|
||||
result += "[pi] target=\"" + domNode.getNodeName() + "\" content=\"" + domNode.getNodeValue() + "\"";
|
||||
break;
|
||||
}
|
||||
case Node.TEXT_NODE: {
|
||||
result += "[text] " + domNode.getNodeValue();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
result += "[unknown]";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// humans read in lines
|
||||
result += "\n";
|
||||
|
||||
// process children
|
||||
NodeList children = domNode.getChildNodes();
|
||||
for (int onChild = 0; onChild < children.getLength(); onChild++) {
|
||||
Node child = children.item(onChild);
|
||||
result += dumpInternal(child, indent);
|
||||
}
|
||||
|
||||
// return human readable DOM as String
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* indentBlanks will return a String of indent blanks
|
||||
*
|
||||
* @param indent
|
||||
* level
|
||||
* @return String of blanks
|
||||
*/
|
||||
private static String indentBlanks(int indent) {
|
||||
if (indent == 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (indent > BLANKS_LEN) {
|
||||
return BLANKS;
|
||||
}
|
||||
|
||||
return BLANKS.substring(0, indent + 1);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
<!ELEMENT SupplierOrder (OrderId, OrderDate, ShippingAddress, LineItems)>
|
||||
|
||||
<!ELEMENT OrderId (#PCDATA)>
|
||||
|
||||
<!ELEMENT OrderDate (#PCDATA)>
|
||||
|
||||
<!ELEMENT ShippingAddress (FirstName, LastName, Street, City, State, Country, ZipCode, Email, Phone)>
|
||||
|
||||
<!ELEMENT FirstName (#PCDATA)>
|
||||
|
||||
<!ELEMENT LastName (#PCDATA)>
|
||||
|
||||
<!ELEMENT Street (#PCDATA)>
|
||||
|
||||
<!ELEMENT City (#PCDATA)>
|
||||
|
||||
<!ELEMENT State (#PCDATA)>
|
||||
|
||||
<!ELEMENT Country (#PCDATA)>
|
||||
|
||||
<!ELEMENT ZipCode (#PCDATA)>
|
||||
|
||||
<!ELEMENT Email (#PCDATA)>
|
||||
|
||||
<!ELEMENT Phone (#PCDATA)>
|
||||
|
||||
<!ELEMENT LineItems (LineItem+)>
|
||||
|
||||
<!ELEMENT LineItem EMPTY>
|
||||
|
||||
<!ATTLIST LineItem
|
||||
categoryId CDATA #REQUIRED
|
||||
productId CDATA #REQUIRED
|
||||
itemId CDATA #REQUIRED
|
||||
lineNo CDATA #REQUIRED
|
||||
quantity CDATA #REQUIRED
|
||||
unitPrice CDATA #REQUIRED
|
||||
>
|
||||
|
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE SupplierOrder SYSTEM "Bug4693341.dtd" >
|
||||
<SupplierOrder>
|
||||
<OrderId>10016</OrderId>
|
||||
<OrderDate>Wed May 29 12:45:00 PDT 2002</OrderDate>
|
||||
<ShippingAddress>
|
||||
<FirstName>ABC</FirstName>
|
||||
<LastName>XYZ</LastName>
|
||||
<Street>1234 Anywhere Street</Street>
|
||||
<City>Palo Alto</City>
|
||||
<State>California</State>
|
||||
<Country>USA</Country>
|
||||
<ZipCode>94303</ZipCode>
|
||||
<Email>NULL</Email>
|
||||
<Phone>NULL</Phone>
|
||||
</ShippingAddress>
|
||||
<LineItems>
|
||||
<LineItem categoryId="BIRDS" itemId="EST-18" lineNo="0" productId="AV-CB-01" quantity="1" unitPrice="193.5"/>
|
||||
</LineItems>
|
||||
</SupplierOrder>
|
@ -0,0 +1 @@
|
||||
<a/>
|
@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<env:Envelope xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/"
|
||||
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
|
||||
xmlns:ns0="http://headertest.org/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<env:Body>
|
||||
<ds:X509Certificate xmlns="" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
|
||||
MIIDVjCCAxICBD6kKrMwCwYHKoZIzjgEAwUAMIGPMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0Ex
|
||||
FDASBgNVBAcTC1NhbnRhIENsYXJhMR8wHQYDVQQKExZTdW4gTWljcm9zeXN0ZW1zLCBJbmMuMR4w
|
||||
HAYDVQQLExVKYXZhIGFuZCBYTUwgU29mdHdhcmUxHDAaBgNVBAMTE0pXUy1TZWN1cml0eSBDbGll
|
||||
bnQwHhcNMDMwNDIxMTczMDI3WhcNMDMwNzIwMTczMDI3WjCBjzELMAkGA1UEBhMCVVMxCzAJBgNV
|
||||
BAgTAkNBMRQwEgYDVQQHEwtTYW50YSBDbGFyYTEfMB0GA1UEChMWU3VuIE1pY3Jvc3lzdGVtcywg
|
||||
SW5jLjEeMBwGA1UECxMVSmF2YSBhbmQgWE1MIFNvZnR3YXJlMRwwGgYDVQQDExNKV1MtU2VjdXJp
|
||||
dHkgQ2xpZW50MIIBtzCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9E
|
||||
AMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up
|
||||
1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUj
|
||||
C8yykrmCouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZ
|
||||
T+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7
|
||||
zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYQAAoGAV3R+bUfh+u0yaPBV75umKvFB
|
||||
ucv37ETDak889b7k72kZdGoHz3oDmp69tiNDg5r7IvKtjHGbZ6C3Nv0ycNR7Sed1QPOF4nn/tgUl
|
||||
j+BvtVW3iiIRgBJ82KP+28QtwPkkxSp7n5HG0v7bE29E/juLduuhKBQTaaCvajuCFxiBrmAwCwYH
|
||||
KoZIzjgEAwUAAzEAMC4CFQCCuDNmMKjgY6MV1SmAcCdnhuT6VwIVAJBOiPDnDWp2WlKAERF6nOAf
|
||||
vKz9
|
||||
</ds:X509Certificate>
|
||||
</env:Body>
|
||||
</env:Envelope>
|
@ -0,0 +1,39 @@
|
||||
<!ELEMENT SupplierOrder (OrderId, OrderDate, ShippingAddress, LineItems)>
|
||||
|
||||
<!ELEMENT OrderId (#PCDATA)>
|
||||
|
||||
<!ELEMENT OrderDate (#PCDATA)>
|
||||
|
||||
<!ELEMENT ShippingAddress (FirstName, LastName, Street, City, State, Country, ZipCode, Email, Phone)>
|
||||
|
||||
<!ELEMENT FirstName (#PCDATA)>
|
||||
|
||||
<!ELEMENT LastName (#PCDATA)>
|
||||
|
||||
<!ELEMENT Street (#PCDATA)>
|
||||
|
||||
<!ELEMENT City (#PCDATA)>
|
||||
|
||||
<!ELEMENT State (#PCDATA)>
|
||||
|
||||
<!ELEMENT Country (#PCDATA)>
|
||||
|
||||
<!ELEMENT ZipCode (#PCDATA)>
|
||||
|
||||
<!ELEMENT Email (#PCDATA)>
|
||||
|
||||
<!ELEMENT Phone (#PCDATA)>
|
||||
|
||||
<!ELEMENT LineItems (LineItem+)>
|
||||
|
||||
<!ELEMENT LineItem EMPTY>
|
||||
|
||||
<!ATTLIST LineItem
|
||||
categoryId CDATA #REQUIRED
|
||||
productId CDATA #REQUIRED
|
||||
itemId CDATA #REQUIRED
|
||||
lineNo CDATA #REQUIRED
|
||||
quantity CDATA #REQUIRED
|
||||
unitPrice CDATA #REQUIRED
|
||||
>
|
||||
|
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE SupplierOrder SYSTEM "Bug4693341.dtd" >
|
||||
<SupplierOrder>
|
||||
<OrderId>10016</OrderId>
|
||||
<OrderDate>Wed May 29 12:45:00 PDT 2002</OrderDate>
|
||||
<ShippingAddress>
|
||||
<FirstName>ABC</FirstName>
|
||||
<LastName>XYZ</LastName>
|
||||
<Street>1234 Anywhere Street</Street>
|
||||
<City>Palo Alto</City>
|
||||
<State>California</State>
|
||||
<Country>USA</Country>
|
||||
<ZipCode>94303</ZipCode>
|
||||
<Email>NULL</Email>
|
||||
<Phone>NULL</Phone>
|
||||
</ShippingAddress>
|
||||
<LineItems>
|
||||
<LineItem categoryId="BIRDS" itemId="EST-18" lineNo="0" productId="AV-CB-01" quantity="1" unitPrice="193.5"/>
|
||||
</LineItems>
|
||||
</SupplierOrder>
|
@ -0,0 +1,30 @@
|
||||
[document]
|
||||
[element] env:Envelope {http://www.w3.org/2000/xmlns/}xmlns:xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/" {http://www.w3.org/2000/xmlns/}xmlns:xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" {http://www.w3.org/2000/xmlns/}xmlns:xmlns:ns0="http://headertest.org/" {http://www.w3.org/2000/xmlns/}xmlns:xmlns:xsd="http://www.w3.org/2001/XMLSchema" {http://www.w3.org/2000/xmlns/}xmlns:xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
[text]
|
||||
|
||||
[element] env:Body
|
||||
[text]
|
||||
|
||||
[element] ds:X509Certificate xmlns="" {http://www.w3.org/2000/xmlns/}xmlns:xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
|
||||
[text]
|
||||
MIIDVjCCAxICBD6kKrMwCwYHKoZIzjgEAwUAMIGPMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0Ex
|
||||
FDASBgNVBAcTC1NhbnRhIENsYXJhMR8wHQYDVQQKExZTdW4gTWljcm9zeXN0ZW1zLCBJbmMuMR4w
|
||||
HAYDVQQLExVKYXZhIGFuZCBYTUwgU29mdHdhcmUxHDAaBgNVBAMTE0pXUy1TZWN1cml0eSBDbGll
|
||||
bnQwHhcNMDMwNDIxMTczMDI3WhcNMDMwNzIwMTczMDI3WjCBjzELMAkGA1UEBhMCVVMxCzAJBgNV
|
||||
BAgTAkNBMRQwEgYDVQQHEwtTYW50YSBDbGFyYTEfMB0GA1UEChMWU3VuIE1pY3Jvc3lzdGVtcywg
|
||||
SW5jLjEeMBwGA1UECxMVSmF2YSBhbmQgWE1MIFNvZnR3YXJlMRwwGgYDVQQDExNKV1MtU2VjdXJp
|
||||
dHkgQ2xpZW50MIIBtzCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9E
|
||||
AMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up
|
||||
1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUj
|
||||
C8yykrmCouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZ
|
||||
T+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7
|
||||
zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYQAAoGAV3R+bUfh+u0yaPBV75umKvFB
|
||||
ucv37ETDak889b7k72kZdGoHz3oDmp69tiNDg5r7IvKtjHGbZ6C3Nv0ycNR7Sed1QPOF4nn/tgUl
|
||||
j+BvtVW3iiIRgBJ82KP+28QtwPkkxSp7n5HG0v7bE29E/juLduuhKBQTaaCvajuCFxiBrmAwCwYH
|
||||
KoZIzjgEAwUAAzEAMC4CFQCCuDNmMKjgY6MV1SmAcCdnhuT6VwIVAJBOiPDnDWp2WlKAERF6nOAf
|
||||
vKz9
|
||||
|
||||
[text]
|
||||
|
||||
[text]
|
||||
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package javax.xml.validation.ptests;
|
||||
|
||||
import org.xml.sax.ErrorHandler;
|
||||
import org.xml.sax.SAXParseException;
|
||||
|
||||
class MyErrorHandler implements ErrorHandler {
|
||||
public void error(SAXParseException exception) throws SAXParseException {
|
||||
throw exception;
|
||||
}
|
||||
|
||||
public void warning(SAXParseException exception) throws SAXParseException {
|
||||
throw exception;
|
||||
}
|
||||
|
||||
public void fatalError(SAXParseException exception) throws SAXParseException {
|
||||
throw exception;
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package javax.xml.validation.ptests;
|
||||
|
||||
import static jaxp.library.JAXPTestUtilities.FILE_SEP;
|
||||
import static jaxp.library.JAXPTestUtilities.getPathByClassName;
|
||||
|
||||
/**
|
||||
* This class defines the path constant
|
||||
*/
|
||||
public class ValidationTestConst {
|
||||
/**
|
||||
* XML source file directory.
|
||||
*/
|
||||
public static final String XML_DIR = getPathByClassName(ValidationTestConst.class,
|
||||
".." + FILE_SEP + "xmlfiles");
|
||||
|
||||
/**
|
||||
* Golden validation files directory.
|
||||
*/
|
||||
public static final String GOLDEN_DIR = getPathByClassName(ValidationTestConst.class,
|
||||
".." + FILE_SEP + "xmlfiles" + FILE_SEP + "out");
|
||||
}
|
41
jaxp/test/javax/xml/jaxp/libs/test/gaptest/GapTestConst.java
Normal file
41
jaxp/test/javax/xml/jaxp/libs/test/gaptest/GapTestConst.java
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package test.gaptest;
|
||||
|
||||
import static jaxp.library.JAXPTestUtilities.FILE_SEP;
|
||||
import static jaxp.library.JAXPTestUtilities.getPathByClassName;
|
||||
|
||||
/**
|
||||
* This class defines the path constant
|
||||
*/
|
||||
public class GapTestConst {
|
||||
/**
|
||||
* XML source file directory.
|
||||
*/
|
||||
public static final String XML_DIR = getPathByClassName(GapTestConst.class, "xmlfiles");
|
||||
|
||||
/**
|
||||
* Golden validation files directory.
|
||||
*/
|
||||
public static final String GOLDEN_DIR = getPathByClassName(GapTestConst.class, "xmlfiles" + FILE_SEP + "out");
|
||||
}
|
@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package javax.xml.xpath;
|
||||
|
||||
import java.io.File;
|
||||
import javax.xml.xpath.*;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
import org.testng.annotations.Test;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
/*
|
||||
* @bug 8054196
|
||||
* @summary Test for the project XPath: support any type. This test covers the new
|
||||
* evaluateExpression methods of XPath, as well as XPathNodes and XPathEvaluationResult.
|
||||
*/
|
||||
public class XPathAnyTypeTest extends XPathTestBase {
|
||||
/*
|
||||
Test for resolveFunction(QName functionName,int arity); evaluate throws
|
||||
NPE if functionName is null.
|
||||
*/
|
||||
|
||||
@Test(dataProvider = "xpath", expectedExceptions = NullPointerException.class)
|
||||
public void testCheckXPathFunctionResolver02(XPath xpath) throws XPathExpressionException {
|
||||
xpath.setXPathFunctionResolver((functionName, arity) -> null);
|
||||
assertEquals(xpath.evaluate(null, "5"), "2");
|
||||
}
|
||||
/*
|
||||
Check that NPE is thrown when expression is null.
|
||||
*/
|
||||
|
||||
@Test(dataProvider = "xpath", expectedExceptions = NullPointerException.class)
|
||||
public void test01(XPath xpath) throws XPathExpressionException {
|
||||
double result = xpath.evaluateExpression(null, (Object) null, Double.class);
|
||||
}
|
||||
|
||||
/*
|
||||
Check that NPE is thrown when the class type is null.
|
||||
*/
|
||||
@Test(dataProvider = "xpath", expectedExceptions = NullPointerException.class)
|
||||
public void test02(XPath xpath) throws XPathExpressionException {
|
||||
double result = xpath.evaluateExpression("1+1", (Object) null, null);
|
||||
}
|
||||
|
||||
/*
|
||||
Parameter item can be null when the expression does not depends on the
|
||||
context.
|
||||
*/
|
||||
@Test(dataProvider = "xpath")
|
||||
public void test03(XPath xpath) throws XPathExpressionException {
|
||||
int result = xpath.evaluateExpression("1+1", (Object) null, Integer.class);
|
||||
assertTrue(result == 2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test return type: boolean.
|
||||
*/
|
||||
@Test(dataProvider = "document")
|
||||
public void test04(XPath xpath, Document doc) throws XPathExpressionException {
|
||||
boolean result1 = xpath.evaluateExpression("boolean(/Customers/Customer[@id=3])", doc, Boolean.class);
|
||||
assertTrue(result1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test return type: numeric. Subtypes supported: Double, Integer and Long
|
||||
*/
|
||||
@Test(dataProvider = "document")
|
||||
public void test05(XPath xpath, Document doc) throws XPathExpressionException {
|
||||
double result1 = xpath.evaluateExpression("count(/Customers/Customer)", doc, Double.class);
|
||||
assertTrue(result1 == 3.0);
|
||||
int result2 = xpath.evaluateExpression("count(/Customers/Customer)", doc, Integer.class);
|
||||
assertTrue(result2 == 3);
|
||||
long result3 = xpath.evaluateExpression("count(/Customers/Customer)", doc, Long.class);
|
||||
assertTrue(result3 == 3);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test return type: numeric. Of the subtypes of Number, only Double,
|
||||
* Integer and Long are required.
|
||||
*/
|
||||
@Test(dataProvider = "invalidNumericTypes", expectedExceptions = IllegalArgumentException.class)
|
||||
public void test06(XPath xpath, Class<Number> type) throws XPathExpressionException {
|
||||
xpath.evaluateExpression("1+1", (Object) null, type);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test return type: String.
|
||||
*/
|
||||
@Test(dataProvider = "document")
|
||||
public void test07(XPath xpath, Document doc) throws XPathExpressionException {
|
||||
String result1 = xpath.evaluateExpression("string(/Customers/Customer[@id=3]/Phone/text())", doc, String.class);
|
||||
assertTrue(result1.equals("3333333333"));
|
||||
}
|
||||
|
||||
/*
|
||||
* Test return type: NodeSet.
|
||||
*/
|
||||
@Test(dataProvider = "document")
|
||||
public void test08(XPath xpath, Document doc) throws XPathExpressionException {
|
||||
XPathNodes nodes = xpath.evaluateExpression("/Customers/Customer", doc, XPathNodes.class);
|
||||
assertTrue(nodes.size() == 3);
|
||||
for (Node n : nodes) {
|
||||
assertEquals(n.getLocalName(), "Customer");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Test return type: Node.
|
||||
*/
|
||||
@Test(dataProvider = "document")
|
||||
public void test09(XPath xpath, Document doc) throws XPathExpressionException {
|
||||
Node n = xpath.evaluateExpression("/Customers/Customer[@id=3]", doc, Node.class);
|
||||
assertEquals(n.getLocalName(), "Customer");
|
||||
}
|
||||
|
||||
/*
|
||||
* Test return type: Unsupported type.
|
||||
*/
|
||||
@Test(dataProvider = "document", expectedExceptions = IllegalArgumentException.class)
|
||||
public void test10(XPath xpath, Document doc) throws XPathExpressionException {
|
||||
File n = xpath.evaluateExpression("/Customers/Customer[@id=3]", doc, File.class);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test return type: Any::Boolean.
|
||||
*/
|
||||
@Test(dataProvider = "document")
|
||||
public void test11(XPath xpath, Document doc) throws XPathExpressionException {
|
||||
XPathEvaluationResult<?> result = xpath.evaluateExpression("boolean(/Customers/Customer[@id=3])", doc);
|
||||
verifyResult(result, true);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test return type: Any::Number.
|
||||
*/
|
||||
@Test(dataProvider = "document")
|
||||
public void test12(XPath xpath, Document doc) throws XPathExpressionException {
|
||||
XPathEvaluationResult<?> result = xpath.evaluateExpression("count(/Customers/Customer)", doc);
|
||||
verifyResult(result, 3.0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test return type: Any::String.
|
||||
*/
|
||||
@Test(dataProvider = "document")
|
||||
public void test13(XPath xpath, Document doc) throws XPathExpressionException {
|
||||
XPathEvaluationResult<?> result = xpath.evaluateExpression(
|
||||
"string(/Customers/Customer[@id=3]/Phone/text())", doc, XPathEvaluationResult.class);
|
||||
verifyResult(result, "3333333333");
|
||||
}
|
||||
|
||||
/*
|
||||
* Test return type: Any::Nodeset.
|
||||
*/
|
||||
@Test(dataProvider = "document")
|
||||
public void test14(XPath xpath, Document doc) throws XPathExpressionException {
|
||||
XPathEvaluationResult<?> result = xpath.evaluateExpression("/Customers/Customer", doc);
|
||||
verifyResult(result, "Customer");
|
||||
}
|
||||
|
||||
/*
|
||||
* Test return type: Any::Node.
|
||||
*/
|
||||
@Test(dataProvider = "document")
|
||||
public void test15(XPath xpath, Document doc) throws XPathExpressionException {
|
||||
XPathEvaluationResult<?> result = xpath.evaluateExpression("/Customers/Customer[@id=3]", doc);
|
||||
verifyResult(result, "Customer");
|
||||
}
|
||||
}
|
@ -0,0 +1,176 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.xml.xpath;
|
||||
|
||||
import java.io.File;
|
||||
import javax.xml.xpath.*;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
import org.testng.annotations.Test;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
/*
|
||||
* @bug 8054196
|
||||
* @summary Test for the project XPath: support any type. This test covers the new
|
||||
* evaluateExpression methods of XPathExpression.
|
||||
*/
|
||||
public class XPathExpAnyTypeTest extends XPathTestBase {
|
||||
|
||||
/*
|
||||
* Check that NPE is thrown when the class type is null.
|
||||
*/
|
||||
@Test(dataProvider = "xpath", expectedExceptions = NullPointerException.class)
|
||||
public void test02(XPath xpath) throws XPathExpressionException {
|
||||
XPathExpression exp = xpath.compile("1+1");
|
||||
double result = exp.evaluateExpression((Object)null, null);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parameter item can be null when the expression does not depends on the
|
||||
* context.
|
||||
*/
|
||||
@Test(dataProvider = "xpath")
|
||||
public void test03(XPath xpath) throws XPathExpressionException {
|
||||
XPathExpression exp = xpath.compile("1+1");
|
||||
int result = exp.evaluateExpression((Object)null, Integer.class);
|
||||
assertTrue(result == 2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test return type: boolean.
|
||||
*/
|
||||
@Test(dataProvider = "document")
|
||||
public void test04(XPath xpath, Document doc) throws XPathExpressionException {
|
||||
XPathExpression exp = xpath.compile("boolean(/Customers/Customer[@id=3])");
|
||||
boolean result1 = exp.evaluateExpression(doc, Boolean.class);
|
||||
assertTrue(result1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test return type: numeric.
|
||||
*/
|
||||
@Test(dataProvider = "document")
|
||||
public void test05(XPath xpath, Document doc) throws XPathExpressionException {
|
||||
XPathExpression exp = xpath.compile("count(/Customers/Customer)");
|
||||
double result1 = exp.evaluateExpression(doc, Double.class);
|
||||
assertTrue(result1 == 3.0);
|
||||
|
||||
int result2 = exp.evaluateExpression(doc, Integer.class);
|
||||
assertTrue(result2 == 3);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test return type: String.
|
||||
*/
|
||||
@Test(dataProvider = "document")
|
||||
public void test06(XPath xpath, Document doc) throws XPathExpressionException {
|
||||
XPathExpression exp = xpath.compile("string(/Customers/Customer[@id=3]/Phone/text())");
|
||||
String result1 = exp.evaluateExpression(doc, String.class);
|
||||
assertTrue(result1.equals("3333333333"));
|
||||
}
|
||||
|
||||
/*
|
||||
* Test return type: NodeSet.
|
||||
*/
|
||||
@Test(dataProvider = "document")
|
||||
public void test07(XPath xpath, Document doc) throws XPathExpressionException {
|
||||
XPathExpression exp = xpath.compile("/Customers/Customer");
|
||||
XPathNodes nodes = exp.evaluateExpression(doc, XPathNodes.class);
|
||||
assertTrue(nodes.size() == 3);
|
||||
for (Node n : nodes) {
|
||||
assertEquals(n.getLocalName(), "Customer");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Test return type: Node.
|
||||
*/
|
||||
@Test(dataProvider = "document")
|
||||
public void test08(XPath xpath, Document doc) throws XPathExpressionException {
|
||||
XPathExpression exp = xpath.compile("/Customers/Customer[@id=3]");
|
||||
Node n = exp.evaluateExpression(doc, Node.class);
|
||||
assertEquals(n.getLocalName(), "Customer");
|
||||
}
|
||||
|
||||
/*
|
||||
* Test return type: Unsupported type.
|
||||
*/
|
||||
@Test(dataProvider = "document", expectedExceptions = IllegalArgumentException.class)
|
||||
public void test09(XPath xpath, Document doc) throws XPathExpressionException {
|
||||
XPathExpression exp = xpath.compile("/Customers/Customer[@id=3]");
|
||||
File n = exp.evaluateExpression(doc, File.class);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test return type: Any::Boolean.
|
||||
*/
|
||||
@Test(dataProvider = "document")
|
||||
public void test10(XPath xpath, Document doc) throws XPathExpressionException {
|
||||
XPathExpression exp = xpath.compile("boolean(/Customers/Customer[@id=3])");
|
||||
XPathEvaluationResult<?> result = exp.evaluateExpression(doc);
|
||||
verifyResult(result, true);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test return type: Any::Number.
|
||||
*/
|
||||
@Test(dataProvider = "document")
|
||||
public void test11(XPath xpath, Document doc) throws XPathExpressionException {
|
||||
XPathExpression exp = xpath.compile("count(/Customers/Customer)");
|
||||
XPathEvaluationResult<?> result = exp.evaluateExpression(doc);
|
||||
verifyResult(result, 3.0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test return type: Any::String.
|
||||
*/
|
||||
@Test(dataProvider = "document")
|
||||
public void test12(XPath xpath, Document doc) throws XPathExpressionException {
|
||||
XPathExpression exp = xpath.compile("string(/Customers/Customer[@id=3]/Phone/text())");
|
||||
XPathEvaluationResult<?> result = exp.evaluateExpression(doc, XPathEvaluationResult.class);
|
||||
verifyResult(result, "3333333333");
|
||||
}
|
||||
|
||||
/*
|
||||
* Test return type: Any::Nodeset.
|
||||
*/
|
||||
@Test(dataProvider = "document")
|
||||
public void test13(XPath xpath, Document doc) throws XPathExpressionException {
|
||||
XPathExpression exp = xpath.compile("/Customers/Customer");
|
||||
XPathEvaluationResult<?> result = exp.evaluateExpression(doc);
|
||||
verifyResult(result, "Customer");
|
||||
}
|
||||
|
||||
/*
|
||||
* Test return type: Any::Node.
|
||||
*/
|
||||
@Test(dataProvider = "document")
|
||||
public void test14(XPath xpath, Document doc) throws XPathExpressionException {
|
||||
XPathExpression exp = xpath.compile("/Customers/Customer[@id=3]");
|
||||
XPathEvaluationResult<?> result = exp.evaluateExpression(doc);
|
||||
verifyResult(result, "Customer");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package javax.xml.xpath;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertFalse;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
/*
|
||||
* Base class for XPath test
|
||||
*/
|
||||
class XPathTestBase {
|
||||
|
||||
static final String rawXML
|
||||
= "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
|
||||
+ "<Customers>"
|
||||
+ " <Customer id=\"1\">"
|
||||
+ " <Name>name1</Name>"
|
||||
+ " <Phone>1111111111</Phone>"
|
||||
+ " <Email>123@xyz.com</Email>"
|
||||
+ " <Address>"
|
||||
+ " <Street>1111 111st ave</Street>"
|
||||
+ " <City>The City</City>"
|
||||
+ " <State>The State</State>"
|
||||
+ " </Address>"
|
||||
+ " </Customer>"
|
||||
+ " <Customer id=\"2\">"
|
||||
+ " <Name>name1</Name>"
|
||||
+ " <Phone>2222222222</Phone>"
|
||||
+ " <Email>123@xyz.com</Email>"
|
||||
+ " <Address>"
|
||||
+ " <Street>2222 222nd ave</Street>"
|
||||
+ " <City>The City</City>"
|
||||
+ " <State>The State</State>"
|
||||
+ " </Address>"
|
||||
+ " </Customer>"
|
||||
+ " <Customer id=\"3\">"
|
||||
+ " <Name>name1</Name>"
|
||||
+ " <Phone>3333333333</Phone>"
|
||||
+ " <Email>123@xyz.com</Email>"
|
||||
+ " <Address>"
|
||||
+ " <Street>3333 333rd ave</Street>"
|
||||
+ " <City>The City</City>"
|
||||
+ " <State>The State</State>"
|
||||
+ " </Address>"
|
||||
+ " </Customer>"
|
||||
+ "</Customers>";
|
||||
|
||||
void verifyResult(XPathEvaluationResult<?> result, Object expected) {
|
||||
switch (result.type()) {
|
||||
case BOOLEAN:
|
||||
assertTrue(((Boolean) result.value()).equals(expected));
|
||||
return;
|
||||
case NUMBER:
|
||||
assertTrue(((Double) result.value()).equals(expected));
|
||||
return;
|
||||
case STRING:
|
||||
assertTrue(((String) result.value()).equals(expected));
|
||||
return;
|
||||
case NODESET:
|
||||
XPathNodes nodes = (XPathNodes) result.value();
|
||||
for (Node n : nodes) {
|
||||
assertEquals(n.getLocalName(), expected);
|
||||
}
|
||||
return;
|
||||
case NODE:
|
||||
assertTrue(((Node) result.value()).getLocalName().equals(expected));
|
||||
return;
|
||||
}
|
||||
assertFalse(true, "Unsupported type");
|
||||
}
|
||||
|
||||
/*
|
||||
* DataProvider: XPath object
|
||||
*/
|
||||
@DataProvider(name = "xpath")
|
||||
Object[][] getXPath() {
|
||||
return new Object[][]{{XPathFactory.newInstance().newXPath()}};
|
||||
}
|
||||
|
||||
/*
|
||||
* DataProvider: Numeric types not supported
|
||||
*/
|
||||
@DataProvider(name = "invalidNumericTypes")
|
||||
Object[][] getInvalidNumericTypes() {
|
||||
XPath xpath = XPathFactory.newInstance().newXPath();
|
||||
return new Object[][]{{xpath, AtomicInteger.class},
|
||||
{xpath, AtomicInteger.class},
|
||||
{xpath, AtomicLong.class},
|
||||
{xpath, BigDecimal.class},
|
||||
{xpath, BigInteger.class},
|
||||
{xpath, Byte.class},
|
||||
{xpath, Float.class},
|
||||
{xpath, Short.class}
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* DataProvider: XPath and Document objects
|
||||
*/
|
||||
@DataProvider(name = "document")
|
||||
Object[][] getDocument() throws Exception {
|
||||
DocumentBuilderFactory dBF = DocumentBuilderFactory.newInstance();
|
||||
dBF.setValidating(false);
|
||||
dBF.setNamespaceAware(true);
|
||||
Document doc = dBF.newDocumentBuilder().parse(
|
||||
new ByteArrayInputStream(rawXML.getBytes("UTF-8")));
|
||||
|
||||
return new Object[][]{{XPathFactory.newInstance().newXPath(), doc}};
|
||||
}
|
||||
}
|
@ -293,3 +293,4 @@ edc13d27dc871be57d7ca77eef77e6d04972fee2 jdk9-b43
|
||||
e529374fbe526dbd668e5e98fc047b42b3bc6d33 jdk9-b45
|
||||
64ca52b0bda8028636e4ccafbe1107befcdda47d jdk9-b46
|
||||
6c17d648d03e4bf4729c3645f8db55d34115e0b7 jdk9-b47
|
||||
33e7e699804892c0496adf60ad67cc12855aeb61 jdk9-b48
|
||||
|
@ -135,7 +135,7 @@ public class SchemaGenerator extends AbstractProcessor {
|
||||
|
||||
private void filterClass(List<Reference> classes, Collection<? extends Element> elements) {
|
||||
for (Element element : elements) {
|
||||
if (element.getKind().equals(ElementKind.CLASS)) {
|
||||
if (element.getKind().equals(ElementKind.CLASS) || element.getKind().equals(ElementKind.ENUM)) {
|
||||
classes.add(new Reference((TypeElement) element, processingEnv));
|
||||
filterClass(classes, ElementFilter.typesIn(element.getEnclosedElements()));
|
||||
}
|
||||
|
@ -290,3 +290,4 @@ e336cbd8b15e959e70ed02f0f5e93fa76ebd4c07 jdk9-b41
|
||||
9acaa4f57b0b9e3757a7b4576ca9418a75ea8287 jdk9-b45
|
||||
efedac7f44ed41cea2b1038138047271f55aacba jdk9-b46
|
||||
b641c14730ac05d9ec8b4f66e6fca3dc21adb403 jdk9-b47
|
||||
ebb2eb7f1aec78eb6d8cc4c96f018afa11093cde jdk9-b48
|
||||
|
@ -34,28 +34,23 @@ include JavaCompilation.gmk
|
||||
include NativeCompilation.gmk
|
||||
include SetupJavaCompilers.gmk
|
||||
|
||||
# The exception handling of swing beaninfo which have the own tool directory
|
||||
ifeq (, $(BUILD_TOOLS_JDK))
|
||||
$(eval $(call SetupJavaCompilation,BUILD_TOOLS_JDK, \
|
||||
SETUP := GENERATE_OLDBYTECODE, \
|
||||
ADD_JAVAC_FLAGS := "-Xbootclasspath/p:$(BUILDTOOLS_OUTPUTDIR)/interim_jimage_classes", \
|
||||
SRC := $(JDK_TOPDIR)/make/src/classes, \
|
||||
BIN := $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes, \
|
||||
COPY := boot.modules ext.modules))
|
||||
endif
|
||||
################################################################################
|
||||
|
||||
$(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes/build/tools/generatenimbus/resources/%.template: \
|
||||
$(JDK_TOPDIR)/src/java.desktop/share/classes/javax/swing/plaf/nimbus/%.template
|
||||
$(call install-file)
|
||||
$(eval $(call SetupJavaCompilation,BUILD_TOOLS_JDK, \
|
||||
SETUP := GENERATE_OLDBYTECODE, \
|
||||
ADD_JAVAC_FLAGS := "-Xbootclasspath/p:$(BUILDTOOLS_OUTPUTDIR)/interim_jimage_classes", \
|
||||
SRC := $(JDK_TOPDIR)/make/src/classes, \
|
||||
BIN := $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes, \
|
||||
COPY := boot.modules ext.modules))
|
||||
|
||||
BUILD_TOOLS_JDK += $(foreach i, $(wildcard $(JDK_TOPDIR)/src/java.desktop/share/classes/javax/swing/plaf/nimbus/*.template), $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes/build/tools/generatenimbus/resources/$(notdir $i))
|
||||
$(eval $(call SetupCopyFiles,COPY_NIMBUS_TEMPLATES, \
|
||||
SRC := $(JDK_TOPDIR)/src/java.desktop/share/classes/javax/swing/plaf/nimbus, \
|
||||
DEST := $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes/build/tools/generatenimbus/resources, \
|
||||
FILES := $(wildcard $(JDK_TOPDIR)/src/java.desktop/share/classes/javax/swing/plaf/nimbus/*.template)))
|
||||
|
||||
# Resource used by CheckDeps tool
|
||||
$(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes/build/tools/deps/refs.allowed: \
|
||||
$(JDK_TOPDIR)/make/data/checkdeps/refs.allowed
|
||||
$(call install-file)
|
||||
BUILD_TOOLS_JDK += $(COPY_NIMBUS_TEMPLATES)
|
||||
|
||||
BUILD_TOOLS_JDK += $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes/build/tools/deps/refs.allowed
|
||||
################################################################################
|
||||
|
||||
# Add a checksum ("jsum") to the end of a text file. Prevents trivial tampering with class lists.
|
||||
TOOL_ADDJSUM = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
|
||||
@ -130,10 +125,6 @@ TOOL_OSX_TOBIN = $(JAVA_SMALL) -Djava.awt.headless=true -cp $(BUILDTOOLS_OUTPUTD
|
||||
TOOL_CLDRCONVERTER = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
|
||||
build.tools.cldrconverter.CLDRConverter
|
||||
|
||||
TOOL_CHECKDEPS = $(JAVA_SMALL) -Xbootclasspath/p:$(INTERIM_LANGTOOLS_JAR) \
|
||||
-cp "$(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes$(PATH_SEP)$(JDK_OUTPUTDIR)" \
|
||||
build.tools.deps.CheckDeps
|
||||
|
||||
TOOL_GENMODULESXML = $(JAVA_SMALL) -Xbootclasspath/p:$(INTERIM_LANGTOOLS_JAR) \
|
||||
-cp "$(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes$(PATH_SEP)$(JDK_OUTPUTDIR)" \
|
||||
build.tools.module.GenJdepsModulesXml
|
||||
@ -161,25 +152,25 @@ $(eval $(call SetupJavaCompilation,BUILD_INTERIM_JIMAGE, \
|
||||
# Tools needed on solaris because OBJCOPY is broken.
|
||||
|
||||
ifeq ($(OPENJDK_TARGET_OS), solaris)
|
||||
$(eval $(call SetupNativeCompilation,ADD_GNU_DEBUGLINK, \
|
||||
SRC := $(JDK_TOPDIR)/make/src/native/add_gnu_debuglink, \
|
||||
LANG := C, \
|
||||
CC := $(BUILD_CC), \
|
||||
LDEXE := $(BUILD_LD), \
|
||||
LDFLAGS := -lelf, \
|
||||
OBJECT_DIR := $(BUILDTOOLS_OUTPUTDIR)/objs/add_gnu_debuglink, \
|
||||
OUTPUT_DIR := $(BUILDTOOLS_OUTPUTDIR)/bin, \
|
||||
PROGRAM := add_gnu_debuglink))
|
||||
$(eval $(call SetupNativeCompilation,ADD_GNU_DEBUGLINK, \
|
||||
SRC := $(JDK_TOPDIR)/make/src/native/add_gnu_debuglink, \
|
||||
LANG := C, \
|
||||
CC := $(BUILD_CC), \
|
||||
LDEXE := $(BUILD_LD), \
|
||||
LDFLAGS := -lelf, \
|
||||
OBJECT_DIR := $(BUILDTOOLS_OUTPUTDIR)/objs/add_gnu_debuglink, \
|
||||
OUTPUT_DIR := $(BUILDTOOLS_OUTPUTDIR)/bin, \
|
||||
PROGRAM := add_gnu_debuglink))
|
||||
|
||||
$(eval $(call SetupNativeCompilation,FIX_EMPTY_SEC_HDR_FLAGS, \
|
||||
SRC := $(JDK_TOPDIR)/make/src/native/fix_empty_sec_hdr_flags, \
|
||||
LANG := C, \
|
||||
CC := $(BUILD_CC), \
|
||||
LDEXE := $(BUILD_LD), \
|
||||
LDFLAGS := -lelf, \
|
||||
OBJECT_DIR := $(BUILDTOOLS_OUTPUTDIR)/objs/fix_empty_sec_hdr_flags, \
|
||||
OUTPUT_DIR := $(BUILDTOOLS_OUTPUTDIR)/bin, \
|
||||
PROGRAM := fix_empty_sec_hdr_flags))
|
||||
$(eval $(call SetupNativeCompilation,FIX_EMPTY_SEC_HDR_FLAGS, \
|
||||
SRC := $(JDK_TOPDIR)/make/src/native/fix_empty_sec_hdr_flags, \
|
||||
LANG := C, \
|
||||
CC := $(BUILD_CC), \
|
||||
LDEXE := $(BUILD_LD), \
|
||||
LDFLAGS := -lelf, \
|
||||
OBJECT_DIR := $(BUILDTOOLS_OUTPUTDIR)/objs/fix_empty_sec_hdr_flags, \
|
||||
OUTPUT_DIR := $(BUILDTOOLS_OUTPUTDIR)/bin, \
|
||||
PROGRAM := fix_empty_sec_hdr_flags))
|
||||
endif
|
||||
|
||||
$(BUILD_TOOLS_JDK): $(BUILD_INTERIM_JIMAGE)
|
||||
|
@ -1,34 +0,0 @@
|
||||
#
|
||||
# This properties-formatted file contains the names of the non-existent types
|
||||
# that are allowed to be referenced from classes in a profiles image.
|
||||
#
|
||||
# The property key is a type that does not exist. The property value is one or
|
||||
# more types that reference the missing type. The property value also encodes
|
||||
# the names of the profiles where this reference is allowed.
|
||||
|
||||
# jsse.jar is not subsetted by the profiles build. For compact1 and compact2
|
||||
# then this means that there are references to Kerberos types that do not
|
||||
# exist. These references are harmless.
|
||||
#
|
||||
javax.security.auth.kerberos.KerberosKey=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,sun.security.ssl.krb5.Krb5ProxyImpl,compact1,compact2
|
||||
javax.security.auth.kerberos.KerberosPrincipal=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,sun.security.ssl.krb5.Krb5ProxyImpl,compact1,compact2
|
||||
javax.security.auth.kerberos.KerberosTicket=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
|
||||
javax.security.auth.kerberos.KeyTab=sun.security.ssl.krb5.Krb5ProxyImpl,compact1,compact2
|
||||
javax.security.auth.kerberos.ServicePermission=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,sun.security.ssl.krb5.Krb5ProxyImpl,compact1,compact2
|
||||
sun.security.jgss.GSSCaller=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,sun.security.ssl.krb5.Krb5ProxyImpl,compact1,compact2
|
||||
sun.security.jgss.krb5.Krb5Util=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,sun.security.ssl.krb5.Krb5ProxyImpl,compact1,compact2
|
||||
sun.security.jgss.krb5.ServiceCreds=sun.security.ssl.krb5.Krb5ProxyImpl,sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
|
||||
sun.security.krb5.EncryptedData= sun.security.ssl.krb5.KerberosPreMasterSecret,sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
|
||||
sun.security.krb5.EncryptionKey=sun.security.ssl.krb5.KerberosPreMasterSecret,sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
|
||||
sun.security.krb5.internal.crypto.KeyUsage=sun.security.ssl.krb5.KerberosPreMasterSecret,sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
|
||||
sun.security.krb5.internal.EncTicketPart=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
|
||||
sun.security.krb5.internal.Krb5=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
|
||||
sun.security.krb5.internal.Ticket=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
|
||||
sun.security.krb5.KrbException=sun.security.ssl.krb5.KerberosPreMasterSecret,sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
|
||||
sun.security.krb5.PrincipalName=sun.security.ssl.krb5.Krb5ProxyImpl,sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
|
||||
sun.security.krb5.Realm=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
|
||||
|
||||
# Residual references to java.beans.
|
||||
# The RemoveMethods tool does not yet purge the constant pool.
|
||||
#
|
||||
java.beans.PropertyChangeListener=java.util.logging.LogManager,compact1,compact2,compact3
|
@ -28,6 +28,13 @@
|
||||
# string and the runtime name into the Version.java file.
|
||||
# To be printed by java -version
|
||||
|
||||
# These dependencies should ideally be added to prerequesites for Version.java
|
||||
# but skip for now until we have better incremental build for java.
|
||||
# $(call DependOnVariable, LAUNCHER_NAME) \
|
||||
# $(call DependOnVariable, RELEASE) \
|
||||
# $(call DependOnVariable, FULL_VERSION) \
|
||||
# $(call DependOnVariable, RUNTIME_VERSION)
|
||||
|
||||
$(SUPPORT_OUTPUTDIR)/gensrc/java.base/sun/misc/Version.java: \
|
||||
$(JDK_TOPDIR)/src/java.base/share/classes/sun/misc/Version.java.template
|
||||
$(MKDIR) -p $(@D)
|
||||
|
@ -74,8 +74,6 @@ endif
|
||||
|
||||
##########################################################################################
|
||||
|
||||
BUILD_LIBVERIFY_SRC := check_code.c check_format.c
|
||||
|
||||
ifeq ($(OPENJDK_TARGET_OS), solaris)
|
||||
ifneq ($(OPENJDK_TARGET_CPU), x86_64)
|
||||
BUILD_LIBVERIFY_REORDER := $(JDK_TOPDIR)/make/mapfiles/libverify/reorder-$(OPENJDK_TARGET_CPU)
|
||||
@ -116,10 +114,6 @@ TARGETS += $(BUILD_LIBVERIFY)
|
||||
|
||||
LIBJAVA_SRC_DIRS := $(call FindSrcDirsForLib, java.base, java)
|
||||
|
||||
ifeq ($(OPENJDK_TARGET_OS), macosx)
|
||||
LIBJAVA_EXCLUDE_FILES += $(JDK_TOPDIR)/src/java.base/unix/native/libjava/HostLocaleProviderAdapter_md.c
|
||||
endif
|
||||
|
||||
LIBJAVA_CFLAGS := $(addprefix -I, $(LIBJAVA_SRC_DIRS)) \
|
||||
-I$(JDK_TOPDIR)/src/java.base/share/native/libfdlibm \
|
||||
-I$(SUPPORT_OUTPUTDIR)/headers/java.base \
|
||||
@ -134,9 +128,7 @@ ifneq (, $(JDK_UPDATE_VERSION))
|
||||
LIBJAVA_CFLAGS += -DJDK_UPDATE_VERSION='"$(JDK_UPDATE_VERSION)"'
|
||||
endif
|
||||
|
||||
ifneq ($(OPENJDK_TARGET_OS), macosx)
|
||||
LIBJAVA_EXCLUDE_FILES += java_props_macosx.c
|
||||
else
|
||||
ifeq ($(OPENJDK_TARGET_OS), macosx)
|
||||
BUILD_LIBJAVA_java_props_md.c_CFLAGS := -x objective-c
|
||||
BUILD_LIBJAVA_java_props_macosx.c_CFLAGS := -x objective-c
|
||||
endif
|
||||
@ -151,8 +143,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJAVA, \
|
||||
LIBRARY := java, \
|
||||
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
|
||||
SRC := $(LIBJAVA_SRC_DIRS), \
|
||||
EXCLUDES := fdlibm/src zip prefs, \
|
||||
EXCLUDE_FILES := $(LIBJAVA_EXCLUDE_FILES), \
|
||||
LANG := C, \
|
||||
OPTIMIZATION := HIGH, \
|
||||
CFLAGS := $(CFLAGS_JDKLIB) \
|
||||
@ -247,19 +237,10 @@ TARGETS += $(BUILD_LIBZIP)
|
||||
|
||||
##########################################################################################
|
||||
|
||||
BUILD_LIBJLI_SRC_DIRS := $(JDK_TOPDIR)/src/java.base/share/native/libjli \
|
||||
$(JDK_TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/native/libjli
|
||||
LIBJLI_SRC_DIRS := $(call FindSrcDirsForLib, java.base, jli)
|
||||
|
||||
LIBJLI_CFLAGS := $(CFLAGS_JDKLIB)
|
||||
|
||||
BUILD_LIBJLI_FILES := \
|
||||
java.c \
|
||||
splashscreen_stubs.c \
|
||||
parse_manifest.c \
|
||||
version_comp.c \
|
||||
wildcard.c \
|
||||
jli_util.c
|
||||
|
||||
ifeq ($(JVM_VARIANT_ZERO), true)
|
||||
ERGO_FAMILY := zero
|
||||
else
|
||||
@ -269,68 +250,55 @@ else
|
||||
ERGO_FAMILY := $(OPENJDK_TARGET_CPU_ARCH)
|
||||
endif
|
||||
endif
|
||||
LIBJLI_ALL_ERGO := $(wildcard $(addsuffix /ergo_*.c, $(LIBJLI_SRC_DIRS)))
|
||||
LIBJLI_EXCLUDE_ERGO := $(filter-out %/ergo_$(ERGO_FAMILY).c, $(LIBJLI_ALL_ERGO))
|
||||
# If all specialized ergo files are excluded, use generic ergo
|
||||
ifeq ($(LIBJLI_ALL_ERGO), $(LIBJLI_EXCLUDE_ERGO))
|
||||
LIBJLI_CFLAGS += -DUSE_GENERIC_ERGO
|
||||
endif
|
||||
LIBJLI_EXCLUDE_FILES += $(notdir $(LIBJLI_EXCLUDE_ERGO))
|
||||
|
||||
ifeq ($(OPENJDK_TARGET_OS), macosx)
|
||||
BUILD_LIBJLI_SRC_DIRS += $(JDK_TOPDIR)/src/java.base/macosx/native/libjli
|
||||
BUILD_LIBJLI_FILES += java_md_common.c java_md_macosx.c
|
||||
LIBJLI_EXCLUDE_FILES += java_md_solinux.c ergo.c
|
||||
|
||||
BUILD_LIBJLI_java_md_macosx.c_CFLAGS := -x objective-c
|
||||
BUILD_LIBJLI_STATIC_java_md_macosx.c_CFLAGS := -x objective-c
|
||||
endif
|
||||
|
||||
ifeq ($(OPENJDK_TARGET_OS), windows)
|
||||
BUILD_LIBJLI_FILES += java_md.c \
|
||||
cmdtoargs.c
|
||||
# Staticically link with c runtime on windows.
|
||||
LIBJLI_CFLAGS := $(filter-out -MD, $(LIBJLI_CFLAGS))
|
||||
else ifneq ($(OPENJDK_TARGET_OS), macosx)
|
||||
|
||||
BUILD_LIBJLI_FILES += java_md_common.c
|
||||
BUILD_LIBJLI_FILES += java_md_solinux.c ergo.c
|
||||
|
||||
ERGO_ARCH_FILE = ergo_$(ERGO_FAMILY).c
|
||||
|
||||
# if the architecture specific ergo file exists then
|
||||
# use it, else use the generic definitions from ergo.c
|
||||
ifneq ($(wildcard $(JDK_TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/native/libjli/$(ERGO_ARCH_FILE)), )
|
||||
BUILD_LIBJLI_FILES += $(ERGO_ARCH_FILE)
|
||||
else # !ERGO_ARCH_FILE
|
||||
LIBJLI_CFLAGS += -DUSE_GENERIC_ERGO
|
||||
endif # ERGO_ARCH_FILE
|
||||
endif #WINDOWS
|
||||
|
||||
LIBJLI_CFLAGS += $(foreach dir, $(BUILD_LIBJLI_SRC_DIRS), -I$(dir))
|
||||
|
||||
# Append defines depending on target platform
|
||||
LIBJLI_CFLAGS += $(OPENJDK_TARGET_CPU_JLI_CFLAGS)
|
||||
|
||||
ifeq ($(OPENJDK_TARGET_OS), macosx)
|
||||
LIBJLI_CFLAGS += -DPACKAGE_PATH=\"$(PACKAGE_PATH)\"
|
||||
endif
|
||||
|
||||
ifneq ($(USE_EXTERNAL_LIBZ), true)
|
||||
BUILD_LIBJLI_SRC_DIRS += $(JDK_TOPDIR)/src/java.base/share/native/libzip/zlib-1.2.8
|
||||
LIBJLI_CFLAGS += $(ZLIB_CPPFLAGS)
|
||||
BUILD_LIBJLI_FILES += \
|
||||
inflate.c \
|
||||
inftrees.c \
|
||||
inffast.c \
|
||||
zadler32.c \
|
||||
zcrc32.c \
|
||||
zutil.c
|
||||
endif
|
||||
|
||||
ifeq ($(OPENJDK_TARGET_OS), windows)
|
||||
# Staticically link with c runtime on windows.
|
||||
LIBJLI_CFLAGS := $(filter-out -MD, $(LIBJLI_CFLAGS))
|
||||
LIBJLI_OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE)
|
||||
else
|
||||
LIBJLI_OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE)/jli
|
||||
endif
|
||||
|
||||
LIBJLI_CFLAGS += $(addprefix -I, $(LIBJLI_SRC_DIRS))
|
||||
|
||||
# Append defines depending on target platform
|
||||
LIBJLI_CFLAGS += $(OPENJDK_TARGET_CPU_JLI_CFLAGS)
|
||||
|
||||
ifneq ($(USE_EXTERNAL_LIBZ), true)
|
||||
LIBJLI_CFLAGS += $(ZLIB_CPPFLAGS)
|
||||
LIBJLI_EXTRA_FILES += \
|
||||
$(addprefix $(JDK_TOPDIR)/src/java.base/share/native/libzip/zlib-1.2.8/, \
|
||||
inflate.c \
|
||||
inftrees.c \
|
||||
inffast.c \
|
||||
zadler32.c \
|
||||
zcrc32.c \
|
||||
zutil.c \
|
||||
)
|
||||
endif
|
||||
|
||||
$(eval $(call SetupNativeCompilation,BUILD_LIBJLI, \
|
||||
LIBRARY := jli, \
|
||||
OUTPUT_DIR := $(LIBJLI_OUTPUT_DIR), \
|
||||
SRC := $(BUILD_LIBJLI_SRC_DIRS), \
|
||||
INCLUDE_FILES := $(BUILD_LIBJLI_FILES), \
|
||||
SRC := $(LIBJLI_SRC_DIRS), \
|
||||
EXCLUDE_FILES := $(LIBJLI_EXCLUDE_FILES), \
|
||||
EXTRA_FILES := $(LIBJLI_EXTRA_FILES), \
|
||||
LANG := C, \
|
||||
OPTIMIZATION := HIGH, \
|
||||
CFLAGS := $(LIBJLI_CFLAGS), \
|
||||
@ -376,8 +344,9 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
|
||||
$(eval $(call SetupNativeCompilation,BUILD_LIBJLI_STATIC, \
|
||||
STATIC_LIBRARY := jli_static, \
|
||||
OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE), \
|
||||
SRC := $(BUILD_LIBJLI_SRC_DIRS), \
|
||||
INCLUDE_FILES := $(BUILD_LIBJLI_FILES), \
|
||||
SRC := $(LIBJLI_SRC_DIRS), \
|
||||
EXCLUDE_FILES := $(LIBJLI_EXCLUDE_FILES), \
|
||||
EXTRA_FILES := $(LIBJLI_EXTRA_FILES), \
|
||||
LANG := C, \
|
||||
OPTIMIZATION := HIGH, \
|
||||
CFLAGS := $(STATIC_LIBRARY_FLAGS) $(LIBJLI_CFLAGS), \
|
||||
@ -395,8 +364,9 @@ else ifeq ($(OPENJDK_TARGET_OS), macosx)
|
||||
$(eval $(call SetupNativeCompilation,BUILD_LIBJLI_STATIC, \
|
||||
LIBRARY := jli_static, \
|
||||
OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE), \
|
||||
SRC := $(BUILD_LIBJLI_SRC_DIRS), \
|
||||
INCLUDE_FILES := $(BUILD_LIBJLI_FILES), \
|
||||
SRC := $(LIBJLI_SRC_DIRS), \
|
||||
EXCLUDE_FILES := $(LIBJLI_EXCLUDE_FILES), \
|
||||
EXTRA_FILES := $(LIBJLI_EXTRA_FILES), \
|
||||
LANG := C, \
|
||||
OPTIMIZATION := HIGH, \
|
||||
CFLAGS := $(CFLAGS_JDKLIB) $(LIBJLI_CFLAGS), \
|
||||
@ -411,16 +381,17 @@ else ifeq ($(OPENJDK_TARGET_OS), macosx)
|
||||
|
||||
else ifeq ($(OPENJDK_TARGET_OS), aix)
|
||||
# AIX also requires a static libjli because the compiler doesn't support '-rpath'
|
||||
$(eval $(call SetupNativeCompilation,BUILD_LIBJLI_STATIC,\
|
||||
STATIC_LIBRARY:=jli_static,\
|
||||
OUTPUT_DIR:=$(SUPPORT_OUTPUTDIR)/native/$(MODULE),\
|
||||
SRC:=$(BUILD_LIBJLI_SRC_DIRS),\
|
||||
INCLUDE_FILES:=$(BUILD_LIBJLI_FILES),\
|
||||
LANG:=C,\
|
||||
OPTIMIZATION:=HIGH, \
|
||||
CFLAGS:=$(STATIC_LIBRARY_FLAGS) $(LIBJLI_CFLAGS),\
|
||||
ARFLAGS:=$(ARFLAGS),\
|
||||
OBJECT_DIR:=$(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjli_static))
|
||||
$(eval $(call SetupNativeCompilation,BUILD_LIBJLI_STATIC, \
|
||||
STATIC_LIBRARY := jli_static, \
|
||||
OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE), \
|
||||
SRC := $(LIBJLI_SRC_DIRS), \
|
||||
EXCLUDE_FILES := $(LIBJLI_EXCLUDE_FILES), \
|
||||
EXTRA_FILES := $(LIBJLI_EXTRA_FILES), \
|
||||
LANG := C, \
|
||||
OPTIMIZATION := HIGH, \
|
||||
CFLAGS := $(STATIC_LIBRARY_FLAGS) $(LIBJLI_CFLAGS), \
|
||||
ARFLAGS := $(ARFLAGS), \
|
||||
OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjli_static))
|
||||
|
||||
TARGETS += $(BUILD_LIBJLI_STATIC)
|
||||
|
||||
|
@ -31,7 +31,7 @@ include LibCommon.gmk
|
||||
$(eval $(call SetupNativeCompilation,BUILD_LIBATTACH, \
|
||||
LIBRARY := attach, \
|
||||
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
|
||||
SRC := $(JDK_TOPDIR)/src/jdk.attach/$(OPENJDK_TARGET_OS)/native/libattach, \
|
||||
SRC := $(call FindSrcDirsForLib, jdk.attach, attach), \
|
||||
LANG := C, \
|
||||
OPTIMIZATION := LOW, \
|
||||
CFLAGS := $(CFLAGS_JDKLIB) $(CFLAGS_WARNINGS_ARE_ERRORS) \
|
||||
|
@ -28,9 +28,7 @@ include LibCommon.gmk
|
||||
################################################################################
|
||||
|
||||
LIBJAAS_MAPFILE :=
|
||||
ifneq ($(OPENJDK_TARGET_OS), solaris)
|
||||
LIBJAAS_EXCLUDE_FILES := Solaris.c
|
||||
else
|
||||
ifeq ($(OPENJDK_TARGET_OS), solaris)
|
||||
# only on solaris...wonder why
|
||||
LIBJAAS_MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libjaas/mapfile-vers
|
||||
endif
|
||||
@ -43,7 +41,7 @@ endif
|
||||
$(eval $(call SetupNativeCompilation,BUILD_LIBJAAS, \
|
||||
LIBRARY := $(LIBJAAS_NAME), \
|
||||
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
|
||||
SRC := $(JDK_TOPDIR)/src/jdk.security.auth/$(OPENJDK_TARGET_OS_TYPE)/native/libjaas, \
|
||||
SRC := $(call FindSrcDirsForLib, jdk.security.auth, jaas), \
|
||||
LANG := C, \
|
||||
OPTIMIZATION := LOW, \
|
||||
CFLAGS := $(CFLAGS_JDKLIB) -I$(SUPPORT_OUTPUTDIR)/headers/jdk.security.auth, \
|
||||
@ -53,7 +51,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJAAS, \
|
||||
LDFLAGS_windows := netapi32.lib user32.lib mpr.lib advapi32.lib, \
|
||||
LDFLAGS_SUFFIX_windows := $(LDFLAGS_JDKLIB_SUFFIX), \
|
||||
LDFLAGS_SUFFIX_solaris := -lc, \
|
||||
EXCLUDE_FILES := $(LIBJAAS_EXCLUDE_FILES), \
|
||||
VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
|
||||
RC_FLAGS := $(RC_FLAGS) \
|
||||
-D "JDK_FNAME=$(LIBJAAS_NAME).dll" \
|
||||
|
@ -23,39 +23,16 @@
|
||||
# questions.
|
||||
#
|
||||
|
||||
LIBNET_SRC_DIRS := $(JDK_TOPDIR)/src/java.base/share/native/libnet \
|
||||
$(JDK_TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/native/libnet
|
||||
LIBNET_CFLAGS += -I$(SUPPORT_OUTPUTDIR)/headers/java.base \
|
||||
$(LIBJAVA_HEADER_FLAGS)
|
||||
|
||||
LIBNET_CFLAGS += $(foreach dir, $(LIBNET_SRC_DIRS), -I$(dir))
|
||||
|
||||
LIBNET_EXCLUDE_FILES :=
|
||||
ifneq ($(OPENJDK_TARGET_OS), solaris)
|
||||
LIBNET_EXCLUDE_FILES += solaris_close.c
|
||||
endif
|
||||
|
||||
ifneq ($(OPENJDK_TARGET_OS), linux)
|
||||
LIBNET_EXCLUDE_FILES += linux_close.c
|
||||
endif
|
||||
|
||||
ifneq ($(OPENJDK_TARGET_OS), macosx)
|
||||
LIBNET_EXCLUDE_FILES += bsd_close.c
|
||||
endif
|
||||
|
||||
ifeq ($(OPENJDK_TARGET_OS), aix)
|
||||
LIBNET_SRC_DIRS += $(JDK_TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS)/native/libnet/java/net/
|
||||
endif
|
||||
LIBNET_SRC_DIRS := $(call FindSrcDirsForLib, java.base, net)
|
||||
|
||||
$(eval $(call SetupNativeCompilation,BUILD_LIBNET, \
|
||||
LIBRARY := net, \
|
||||
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
|
||||
SRC := $(LIBNET_SRC_DIRS), \
|
||||
EXCLUDE_FILES := $(LIBNET_EXCLUDE_FILES), \
|
||||
LANG := C, \
|
||||
OPTIMIZATION := LOW, \
|
||||
CFLAGS := $(CFLAGS_JDKLIB) \
|
||||
$(LIBNET_CFLAGS), \
|
||||
CFLAGS := $(CFLAGS_JDKLIB) -I$(SUPPORT_OUTPUTDIR)/headers/java.base \
|
||||
$(LIBJAVA_HEADER_FLAGS) $(addprefix -I, $(LIBNET_SRC_DIRS)), \
|
||||
MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libnet/mapfile-vers, \
|
||||
LDFLAGS := $(LDFLAGS_JDKLIB) \
|
||||
$(call SET_SHARED_LIBRARY_ORIGIN), \
|
||||
|
@ -65,7 +65,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBNIO, \
|
||||
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
|
||||
SRC := $(BUILD_LIBNIO_SRC), \
|
||||
EXCLUDE_FILES := $(BUILD_LIBNIO_EXFILES), \
|
||||
EXCLUDES := sctp, \
|
||||
LANG := C, \
|
||||
OPTIMIZATION := HIGH, \
|
||||
CFLAGS := $(CFLAGS_JDKLIB) \
|
||||
|
@ -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.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -214,10 +214,10 @@ SUNWprivate_1.1 {
|
||||
Java_java_lang_Throwable_fillInStackTrace;
|
||||
Java_java_lang_Throwable_getStackTraceDepth;
|
||||
Java_java_lang_Throwable_getStackTraceElement;
|
||||
Java_java_lang_UNIXProcess_init;
|
||||
Java_java_lang_UNIXProcess_waitForProcessExit;
|
||||
Java_java_lang_UNIXProcess_forkAndExec;
|
||||
Java_java_lang_UNIXProcess_destroyProcess;
|
||||
Java_java_lang_ProcessImpl_init;
|
||||
Java_java_lang_ProcessImpl_waitForProcessExit;
|
||||
Java_java_lang_ProcessImpl_forkAndExec;
|
||||
Java_java_lang_ProcessImpl_destroyProcess;
|
||||
Java_java_nio_Bits_copyFromShortArray;
|
||||
Java_java_nio_Bits_copyToShortArray;
|
||||
Java_java_nio_Bits_copyFromIntArray;
|
||||
|
@ -1,226 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 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 build.tools.deps;
|
||||
|
||||
import java.nio.file.DirectoryStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Properties;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
|
||||
import com.sun.tools.classfile.ClassFile;
|
||||
import com.sun.tools.classfile.Dependencies;
|
||||
import com.sun.tools.classfile.Dependency;
|
||||
|
||||
/**
|
||||
* A simple tool to check the JAR files in a JRE image to ensure that there
|
||||
* aren't any references to types that do not exist. The tool is intended to
|
||||
* be used in the JDK "profiles" build to help ensure that the profile
|
||||
* definitions are kept up to date.
|
||||
*/
|
||||
|
||||
public class CheckDeps {
|
||||
|
||||
// classfile API for finding dependencies
|
||||
static final Dependency.Finder finder = Dependencies.getClassDependencyFinder();
|
||||
|
||||
// "known types", found in rt.jar or other JAR files
|
||||
static final Set<String> knownTypes = new HashSet<>();
|
||||
|
||||
// References to unknown types. The map key is the unknown type, the
|
||||
// map value is the set of classes that reference it.
|
||||
static final Map<String,Set<String>> unknownRefs = new HashMap<>();
|
||||
|
||||
// The property name is the name of an unknown type that is allowed to be
|
||||
// references. The property value is a comma separated list of the types
|
||||
// that are allowed to reference it. The list also includes the names of
|
||||
// the profiles that the reference is allowed.
|
||||
static final Properties allowedBadRefs = new Properties();
|
||||
|
||||
/**
|
||||
* Returns the class name for the given class file. In the case of inner
|
||||
* classes then the enclosing class is returned in order to keep the
|
||||
* rules simple.
|
||||
*/
|
||||
static String toClassName(String s) {
|
||||
int i = s.indexOf('$');
|
||||
if (i > 0)
|
||||
s = s.substring(0, i);
|
||||
return s.replace("/", ".");
|
||||
}
|
||||
|
||||
/**
|
||||
* Analyze the dependencies of all classes in the given JAR file. The
|
||||
* method updates knownTypes and unknownRefs as part of the analysis.
|
||||
*/
|
||||
static void analyzeDependencies(Path jarpath) throws Exception {
|
||||
System.out.format("Analyzing %s%n", jarpath);
|
||||
try (JarFile jf = new JarFile(jarpath.toFile())) {
|
||||
Enumeration<JarEntry> entries = jf.entries();
|
||||
while (entries.hasMoreElements()) {
|
||||
JarEntry e = entries.nextElement();
|
||||
String name = e.getName();
|
||||
if (name.endsWith(".class")) {
|
||||
ClassFile cf = ClassFile.read(jf.getInputStream(e));
|
||||
for (Dependency d : finder.findDependencies(cf)) {
|
||||
String origin = toClassName(d.getOrigin().getName());
|
||||
String target = toClassName(d.getTarget().getName());
|
||||
|
||||
// origin is now known
|
||||
unknownRefs.remove(origin);
|
||||
knownTypes.add(origin);
|
||||
|
||||
// if the target is not known then record the reference
|
||||
if (!knownTypes.contains(target)) {
|
||||
Set<String> refs = unknownRefs.get(target);
|
||||
if (refs == null) {
|
||||
// first time seeing this unknown type
|
||||
refs = new HashSet<>();
|
||||
unknownRefs.put(target, refs);
|
||||
}
|
||||
refs.add(origin);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* We have closure (no references to types that do not exist) if
|
||||
* unknownRefs is empty. When unknownRefs is not empty then it should
|
||||
* only contain references that are allowed to be present (these are
|
||||
* loaded from the refs.allowed properties file).
|
||||
*
|
||||
* @param the profile that is being tested, this determines the exceptions
|
||||
* in {@code allowedBadRefs} that apply.
|
||||
*
|
||||
* @return {@code true} if there are no missing types or the only references
|
||||
* to missing types are described by {@code allowedBadRefs}.
|
||||
*/
|
||||
static boolean checkClosure(String profile) {
|
||||
// process the references to types that do not exist.
|
||||
boolean fail = false;
|
||||
for (Map.Entry<String,Set<String>> entry: unknownRefs.entrySet()) {
|
||||
String target = entry.getKey();
|
||||
for (String origin: entry.getValue()) {
|
||||
// check if origin -> target allowed
|
||||
String value = allowedBadRefs.getProperty(target);
|
||||
if (value == null) {
|
||||
System.err.format("%s -> %s (unknown type)%n", origin, target);
|
||||
fail = true;
|
||||
} else {
|
||||
// target is known, check if the origin is one that we
|
||||
// expect and that the exception applies to the profile.
|
||||
boolean found = false;
|
||||
boolean applicable = false;
|
||||
for (String s: value.split(",")) {
|
||||
s = s.trim();
|
||||
if (s.equals(origin))
|
||||
found = true;
|
||||
if (s.equals(profile))
|
||||
applicable = true;
|
||||
}
|
||||
if (!found || !applicable) {
|
||||
if (!found) {
|
||||
System.err.format("%s -> %s (not allowed)%n", origin, target);
|
||||
} else {
|
||||
System.err.format("%s -> %s (reference not applicable to %s)%n",
|
||||
origin, target, profile);
|
||||
}
|
||||
fail = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return !fail;
|
||||
}
|
||||
|
||||
static void fail(URL url) throws Exception {
|
||||
System.err.println("One or more unexpected references encountered");
|
||||
if (url != null)
|
||||
System.err.format("Check %s is up to date%n", Paths.get(url.toURI()));
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
// load properties file so that we know what missing types that are
|
||||
// allowed to be referenced.
|
||||
URL url = CheckDeps.class.getResource("refs.allowed");
|
||||
if (url != null) {
|
||||
try (InputStream in = url.openStream()) {
|
||||
allowedBadRefs.load(new InputStreamReader(in, StandardCharsets.UTF_8));
|
||||
}
|
||||
}
|
||||
|
||||
if (args.length != 2) {
|
||||
System.err.println("Usage: java CheckDeps <image> <profile>");
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
String image = args[0];
|
||||
String profile = args[1];
|
||||
|
||||
// process JAR files on boot class path
|
||||
Path lib = Paths.get(image, "lib");
|
||||
try (DirectoryStream<Path> stream = Files.newDirectoryStream(lib, "*.jar")) {
|
||||
for (Path jarpath: stream) {
|
||||
analyzeDependencies(jarpath);
|
||||
}
|
||||
}
|
||||
|
||||
// classes on boot class path should not reference other types
|
||||
boolean okay = checkClosure(profile);
|
||||
if (!okay)
|
||||
fail(url);
|
||||
|
||||
// process JAR files in the extensions directory
|
||||
try (DirectoryStream<Path> stream = Files.newDirectoryStream(lib.resolve("ext"), "*.jar")) {
|
||||
for (Path jarpath: stream) {
|
||||
analyzeDependencies(jarpath);
|
||||
}
|
||||
}
|
||||
|
||||
// re-check to ensure that the extensions doesn't reference types that
|
||||
// do not exist.
|
||||
okay = checkClosure(profile);
|
||||
if (!okay)
|
||||
fail(url);
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, 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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -27,6 +27,9 @@ package java.lang;
|
||||
|
||||
import sun.misc.FloatingDecimal;
|
||||
import java.util.Arrays;
|
||||
import java.util.Spliterator;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
/**
|
||||
* A mutable sequence of characters.
|
||||
@ -292,7 +295,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
|
||||
if (beginIndex < 0 || endIndex > count || beginIndex > endIndex) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
return Character.codePointCountImpl(value, beginIndex, endIndex-beginIndex);
|
||||
return Character.codePointCountImpl(value, beginIndex, endIndex - beginIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1431,6 +1434,34 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
|
||||
@Override
|
||||
public abstract String toString();
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 1.9
|
||||
*/
|
||||
@Override
|
||||
public IntStream chars() {
|
||||
// Reuse String-based spliterator. This requires a supplier to
|
||||
// capture the value and count when the terminal operation is executed
|
||||
return StreamSupport.intStream(
|
||||
() -> new String.IntCharArraySpliterator(value, 0, count, 0),
|
||||
Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED,
|
||||
false);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 1.9
|
||||
*/
|
||||
@Override
|
||||
public IntStream codePoints() {
|
||||
// Reuse String-based spliterator. This requires a supplier to
|
||||
// capture the value and count when the terminal operation is executed
|
||||
return StreamSupport.intStream(
|
||||
() -> new String.CodePointsSpliterator(value, 0, count, 0),
|
||||
Spliterator.ORDERED,
|
||||
false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Needed by {@code String} for the contentEquals method.
|
||||
*/
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1994, 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
|
||||
@ -41,6 +41,11 @@ public class Object {
|
||||
registerNatives();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new object.
|
||||
*/
|
||||
public Object() {}
|
||||
|
||||
/**
|
||||
* Returns the runtime class of this {@code Object}. The returned
|
||||
* {@code Class} object is the object that is locked by {@code
|
||||
@ -86,12 +91,11 @@ public class Object {
|
||||
* for unequal objects may improve the performance of hash tables.
|
||||
* </ul>
|
||||
* <p>
|
||||
* As much as is reasonably practical, the hashCode method defined by
|
||||
* class {@code Object} does return distinct integers for distinct
|
||||
* objects. (This is typically implemented by converting the internal
|
||||
* address of the object into an integer, but this implementation
|
||||
* technique is not required by the
|
||||
* Java™ programming language.)
|
||||
* As much as is reasonably practical, the hashCode method defined
|
||||
* by class {@code Object} does return distinct integers for
|
||||
* distinct objects. (The hashCode may or may not be implemented
|
||||
* as some function of an object's memory address at some point
|
||||
* in time.)
|
||||
*
|
||||
* @return a hash code value for this object.
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
@ -344,10 +348,12 @@ public class Object {
|
||||
* ... // Perform action appropriate to condition
|
||||
* }
|
||||
* </pre>
|
||||
* (For more information on this topic, see Section 3.2.3 in Doug Lea's
|
||||
* "Concurrent Programming in Java (Second Edition)" (Addison-Wesley,
|
||||
* 2000), or Item 50 in Joshua Bloch's "Effective Java Programming
|
||||
* Language Guide" (Addison-Wesley, 2001).
|
||||
*
|
||||
* (For more information on this topic, see section 14.2,
|
||||
* Condition Queues, in Brian Goetz and others' "Java Concurrency
|
||||
* in Practice" (Addison-Wesley, 2006) or Item 69 in Joshua
|
||||
* Bloch's "Effective Java (Second Edition)" (Addison-Wesley,
|
||||
* 2008).
|
||||
*
|
||||
* <p>If the current thread is {@linkplain java.lang.Thread#interrupt()
|
||||
* interrupted} by any thread before or while it is waiting, then an
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1994, 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
|
||||
@ -34,10 +34,14 @@ import java.util.Comparator;
|
||||
import java.util.Formatter;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.Spliterator;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.function.IntConsumer;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
/**
|
||||
* The {@code String} class represents character strings. All
|
||||
@ -2894,6 +2898,180 @@ public final class String
|
||||
return this;
|
||||
}
|
||||
|
||||
static class IntCharArraySpliterator implements Spliterator.OfInt {
|
||||
private final char[] array;
|
||||
private int index; // current index, modified on advance/split
|
||||
private final int fence; // one past last index
|
||||
private final int cs;
|
||||
|
||||
IntCharArraySpliterator(char[] array, int acs) {
|
||||
this(array, 0, array.length, acs);
|
||||
}
|
||||
|
||||
IntCharArraySpliterator(char[] array, int origin, int fence, int acs) {
|
||||
this.array = array;
|
||||
this.index = origin;
|
||||
this.fence = fence;
|
||||
this.cs = acs | Spliterator.ORDERED | Spliterator.SIZED
|
||||
| Spliterator.SUBSIZED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OfInt trySplit() {
|
||||
int lo = index, mid = (lo + fence) >>> 1;
|
||||
return (lo >= mid)
|
||||
? null
|
||||
: new IntCharArraySpliterator(array, lo, index = mid, cs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEachRemaining(IntConsumer action) {
|
||||
char[] a; int i, hi; // hoist accesses and checks from loop
|
||||
if (action == null)
|
||||
throw new NullPointerException();
|
||||
if ((a = array).length >= (hi = fence) &&
|
||||
(i = index) >= 0 && i < (index = hi)) {
|
||||
do { action.accept(a[i]); } while (++i < hi);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tryAdvance(IntConsumer action) {
|
||||
if (action == null)
|
||||
throw new NullPointerException();
|
||||
if (index >= 0 && index < fence) {
|
||||
action.accept(array[index++]);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long estimateSize() { return (long)(fence - index); }
|
||||
|
||||
@Override
|
||||
public int characteristics() {
|
||||
return cs;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a stream of {@code int} zero-extending the {@code char} values
|
||||
* from this sequence. Any char which maps to a <a
|
||||
* href="{@docRoot}/java/lang/Character.html#unicode">surrogate code
|
||||
* point</a> is passed through uninterpreted.
|
||||
*
|
||||
* @return an IntStream of char values from this sequence
|
||||
* @since 1.9
|
||||
*/
|
||||
@Override
|
||||
public IntStream chars() {
|
||||
return StreamSupport.intStream(
|
||||
new IntCharArraySpliterator(value, Spliterator.IMMUTABLE), false);
|
||||
}
|
||||
|
||||
static class CodePointsSpliterator implements Spliterator.OfInt {
|
||||
private final char[] array;
|
||||
private int index; // current index, modified on advance/split
|
||||
private final int fence; // one past last index
|
||||
private final int cs;
|
||||
|
||||
CodePointsSpliterator(char[] array, int acs) {
|
||||
this(array, 0, array.length, acs);
|
||||
}
|
||||
|
||||
CodePointsSpliterator(char[] array, int origin, int fence, int acs) {
|
||||
this.array = array;
|
||||
this.index = origin;
|
||||
this.fence = fence;
|
||||
this.cs = acs | Spliterator.ORDERED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OfInt trySplit() {
|
||||
int lo = index, mid = (lo + fence) >>> 1;
|
||||
if (lo >= mid)
|
||||
return null;
|
||||
|
||||
int midOneLess;
|
||||
// If the mid-point intersects a surrogate pair
|
||||
if (Character.isLowSurrogate(array[mid]) &&
|
||||
Character.isHighSurrogate(array[midOneLess = (mid -1)])) {
|
||||
// If there is only one pair it cannot be split
|
||||
if (lo >= midOneLess)
|
||||
return null;
|
||||
// Shift the mid-point to align with the surrogate pair
|
||||
return new CodePointsSpliterator(array, lo, index = midOneLess, cs);
|
||||
}
|
||||
return new CodePointsSpliterator(array, lo, index = mid, cs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEachRemaining(IntConsumer action) {
|
||||
char[] a; int i, hi; // hoist accesses and checks from loop
|
||||
if (action == null)
|
||||
throw new NullPointerException();
|
||||
if ((a = array).length >= (hi = fence) &&
|
||||
(i = index) >= 0 && i < (index = hi)) {
|
||||
do {
|
||||
i = advance(a, i, hi, action);
|
||||
} while (i < hi);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tryAdvance(IntConsumer action) {
|
||||
if (action == null)
|
||||
throw new NullPointerException();
|
||||
if (index >= 0 && index < fence) {
|
||||
index = advance(array, index, fence, action);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Advance one code point from the index, i, and return the next
|
||||
// index to advance from
|
||||
private static int advance(char[] a, int i, int hi, IntConsumer action) {
|
||||
char c1 = a[i++];
|
||||
int cp = c1;
|
||||
if (Character.isHighSurrogate(c1) && i < hi) {
|
||||
char c2 = a[i];
|
||||
if (Character.isLowSurrogate(c2)) {
|
||||
i++;
|
||||
cp = Character.toCodePoint(c1, c2);
|
||||
}
|
||||
}
|
||||
action.accept(cp);
|
||||
return i;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long estimateSize() { return (long)(fence - index); }
|
||||
|
||||
@Override
|
||||
public int characteristics() {
|
||||
return cs;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a stream of code point values from this sequence. Any surrogate
|
||||
* pairs encountered in the sequence are combined as if by {@linkplain
|
||||
* Character#toCodePoint Character.toCodePoint} and the result is passed
|
||||
* to the stream. Any other code units, including ordinary BMP characters,
|
||||
* unpaired surrogates, and undefined code units, are zero-extended to
|
||||
* {@code int} values which are then passed to the stream.
|
||||
*
|
||||
* @return an IntStream of Unicode code points from this sequence
|
||||
* @since 1.9
|
||||
*/
|
||||
@Override
|
||||
public IntStream codePoints() {
|
||||
return StreamSupport.intStream(
|
||||
new CodePointsSpliterator(value, Spliterator.IMMUTABLE), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts this string to a new character array.
|
||||
*
|
||||
|
@ -376,19 +376,16 @@ public final class System {
|
||||
* the difference between two such values, obtained within the same
|
||||
* instance of a Java virtual machine, is computed.
|
||||
*
|
||||
* <p> For example, to measure how long some code takes to execute:
|
||||
* <pre> {@code
|
||||
* <p>For example, to measure how long some code takes to execute:
|
||||
* <pre> {@code
|
||||
* long startTime = System.nanoTime();
|
||||
* // ... the code being measured ...
|
||||
* long estimatedTime = System.nanoTime() - startTime;}</pre>
|
||||
* long elapsedNanos = System.nanoTime() - startTime;}</pre>
|
||||
*
|
||||
* <p>To compare two nanoTime values
|
||||
* <pre> {@code
|
||||
* long t0 = System.nanoTime();
|
||||
* ...
|
||||
* long t1 = System.nanoTime();}</pre>
|
||||
*
|
||||
* one should use {@code t1 - t0 < 0}, not {@code t1 < t0},
|
||||
* <p>To compare elapsed time against a timeout, use <pre> {@code
|
||||
* if (System.nanoTime() - startTime >= timeoutNanos) ...}</pre>
|
||||
* instead of <pre> {@code
|
||||
* if (System.nanoTime() >= startTime + timeoutNanos) ...}</pre>
|
||||
* because of the possibility of numerical overflow.
|
||||
*
|
||||
* @return the current value of the running Java Virtual Machine's
|
||||
|
@ -553,6 +553,12 @@ public interface Spliterator<T> {
|
||||
* sub-split size is known and additions or removals to the source are not
|
||||
* reflected when traversing.
|
||||
*
|
||||
* <p>A top-level Spliterator should not report both {@code CONCURRENT} and
|
||||
* {@code IMMUTABLE}, since they are mutually exclusive. Such a Spliterator
|
||||
* is inconsistent and no guarantees can be made about any computation using
|
||||
* that Spliterator. Sub-spliterators may report {@code IMMUTABLE} if
|
||||
* additions or removals to the source are not reflected when traversing.
|
||||
*
|
||||
* @apiNote Most concurrent collections maintain a consistency policy
|
||||
* guaranteeing accuracy with respect to elements present at the point of
|
||||
* Spliterator construction, but possibly not reflecting subsequent
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user