diff options
author | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
---|---|---|
committer | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
commit | 554fd8c5195424bdbcabf5de30fdc183aba391bd (patch) | |
tree | 976dc5ab7fddf506dadce60ae936f43f58787092 /libjava/classpath/external | |
download | cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2 cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz |
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig;
imported gcc-4.6.4 source tree from verified upstream tarball.
downloading a git-generated archive based on the 'upstream' tag
should provide you with a source tree that is binary identical
to the one extracted from the above tarball.
if you have obtained the source via the command 'git clone',
however, do note that line-endings of files in your working
directory might differ from line-endings of the respective
files in the upstream repository.
Diffstat (limited to 'libjava/classpath/external')
287 files changed, 63599 insertions, 0 deletions
diff --git a/libjava/classpath/external/.cvsignore b/libjava/classpath/external/.cvsignore new file mode 100644 index 000000000..282522db0 --- /dev/null +++ b/libjava/classpath/external/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/libjava/classpath/external/Makefile.am b/libjava/classpath/external/Makefile.am new file mode 100644 index 000000000..2eeef805a --- /dev/null +++ b/libjava/classpath/external/Makefile.am @@ -0,0 +1,5 @@ +## Input file for automake to generate the Makefile.in used by configure + +SUBDIRS = sax w3c_dom relaxngDatatype jsr166 + +EXTRA_DIST = README diff --git a/libjava/classpath/external/Makefile.in b/libjava/classpath/external/Makefile.in new file mode 100644 index 000000000..355e6858d --- /dev/null +++ b/libjava/classpath/external/Makefile.in @@ -0,0 +1,587 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = external +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/../../config/depstand.m4 \ + $(top_srcdir)/../../config/lead-dot.m4 \ + $(top_srcdir)/../../config/lib-ld.m4 \ + $(top_srcdir)/../../config/lib-link.m4 \ + $(top_srcdir)/../../config/lib-prefix.m4 \ + $(top_srcdir)/../../config/multi.m4 \ + $(top_srcdir)/../../config/no-executables.m4 \ + $(top_srcdir)/../../config/override.m4 \ + $(top_srcdir)/../../libtool.m4 \ + $(top_srcdir)/../../ltoptions.m4 \ + $(top_srcdir)/../../ltsugar.m4 \ + $(top_srcdir)/../../ltversion.m4 \ + $(top_srcdir)/../../lt~obsolete.m4 \ + $(top_srcdir)/m4/ac_prog_antlr.m4 \ + $(top_srcdir)/m4/ac_prog_java.m4 \ + $(top_srcdir)/m4/ac_prog_java_works.m4 \ + $(top_srcdir)/m4/ac_prog_javac.m4 \ + $(top_srcdir)/m4/ac_prog_javac_works.m4 \ + $(top_srcdir)/m4/acattribute.m4 $(top_srcdir)/m4/accross.m4 \ + $(top_srcdir)/m4/acinclude.m4 \ + $(top_srcdir)/m4/ax_create_stdint_h.m4 \ + $(top_srcdir)/m4/ax_func_which_gethostbyname_r.m4 \ + $(top_srcdir)/m4/gcc_attribute.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/../../mkinstalldirs +CONFIG_HEADER = $(top_builddir)/include/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +ANTLR = @ANTLR@ +ANTLR_JAR = @ANTLR_JAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CAIRO_CFLAGS = @CAIRO_CFLAGS@ +CAIRO_LIBS = @CAIRO_LIBS@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLASSPATH_CONVENIENCE = @CLASSPATH_CONVENIENCE@ +CLASSPATH_INCLUDES = @CLASSPATH_INCLUDES@ +CLASSPATH_MODULE = @CLASSPATH_MODULE@ +COLLECTIONS_PREFIX = @COLLECTIONS_PREFIX@ +CP = @CP@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATE = @DATE@ +DEFAULT_PREFS_PEER = @DEFAULT_PREFS_PEER@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +ECJ_JAR = @ECJ_JAR@ +EGREP = @EGREP@ +ERROR_CFLAGS = @ERROR_CFLAGS@ +EXAMPLESDIR = @EXAMPLESDIR@ +EXEEXT = @EXEEXT@ +EXTRA_CFLAGS = @EXTRA_CFLAGS@ +FGREP = @FGREP@ +FIND = @FIND@ +FREETYPE2_CFLAGS = @FREETYPE2_CFLAGS@ +FREETYPE2_LIBS = @FREETYPE2_LIBS@ +GCONF_CFLAGS = @GCONF_CFLAGS@ +GCONF_LIBS = @GCONF_LIBS@ +GDK_CFLAGS = @GDK_CFLAGS@ +GDK_LIBS = @GDK_LIBS@ +GJDOC = @GJDOC@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +GMP_CFLAGS = @GMP_CFLAGS@ +GMP_LIBS = @GMP_LIBS@ +GREP = @GREP@ +GSTREAMER_BASE_CFLAGS = @GSTREAMER_BASE_CFLAGS@ +GSTREAMER_BASE_LIBS = @GSTREAMER_BASE_LIBS@ +GSTREAMER_CFLAGS = @GSTREAMER_CFLAGS@ +GSTREAMER_FILE_READER = @GSTREAMER_FILE_READER@ +GSTREAMER_LIBS = @GSTREAMER_LIBS@ +GSTREAMER_MIXER_PROVIDER = @GSTREAMER_MIXER_PROVIDER@ +GSTREAMER_PLUGINS_BASE_CFLAGS = @GSTREAMER_PLUGINS_BASE_CFLAGS@ +GSTREAMER_PLUGINS_BASE_LIBS = @GSTREAMER_PLUGINS_BASE_LIBS@ +GST_PLUGIN_LDFLAGS = @GST_PLUGIN_LDFLAGS@ +GTK_CFLAGS = @GTK_CFLAGS@ +GTK_LIBS = @GTK_LIBS@ +INIT_LOAD_LIBRARY = @INIT_LOAD_LIBRARY@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JAR = @JAR@ +JAVA = @JAVA@ +JAVAC = @JAVAC@ +JAVAC_IS_GCJ = @JAVAC_IS_GCJ@ +JAVAC_MEM_OPT = @JAVAC_MEM_OPT@ +JAVA_LANG_SYSTEM_EXPLICIT_INITIALIZATION = @JAVA_LANG_SYSTEM_EXPLICIT_INITIALIZATION@ +JAY = @JAY@ +JAY_SKELETON = @JAY_SKELETON@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBDEBUG = @LIBDEBUG@ +LIBICONV = @LIBICONV@ +LIBMAGIC = @LIBMAGIC@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBVERSION = @LIBVERSION@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR = @MKDIR@ +MKDIR_P = @MKDIR_P@ +MOC = @MOC@ +MOZILLA_CFLAGS = @MOZILLA_CFLAGS@ +MOZILLA_LIBS = @MOZILLA_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PANGOFT2_CFLAGS = @PANGOFT2_CFLAGS@ +PANGOFT2_LIBS = @PANGOFT2_LIBS@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PATH_TO_ESCHER = @PATH_TO_ESCHER@ +PATH_TO_GLIBJ_ZIP = @PATH_TO_GLIBJ_ZIP@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PLUGIN_DIR = @PLUGIN_DIR@ +QT_CFLAGS = @QT_CFLAGS@ +QT_LIBS = @QT_LIBS@ +RANLIB = @RANLIB@ +REMOVE = @REMOVE@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRICT_WARNING_CFLAGS = @STRICT_WARNING_CFLAGS@ +STRIP = @STRIP@ +TOOLSDIR = @TOOLSDIR@ +USER_JAVAH = @USER_JAVAH@ +VERSION = @VERSION@ +WANT_NATIVE_BIG_INTEGER = @WANT_NATIVE_BIG_INTEGER@ +WARNING_CFLAGS = @WARNING_CFLAGS@ +XMKMF = @XMKMF@ +XML_CFLAGS = @XML_CFLAGS@ +XML_LIBS = @XML_LIBS@ +XSLT_CFLAGS = @XSLT_CFLAGS@ +XSLT_LIBS = @XSLT_LIBS@ +XTEST_LIBS = @XTEST_LIBS@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +ZIP = @ZIP@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_ANTLR = @ac_ct_ANTLR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +default_toolkit = @default_toolkit@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +glibjdir = @glibjdir@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +multi_basedir = @multi_basedir@ +nativeexeclibdir = @nativeexeclibdir@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +toolexeclibdir = @toolexeclibdir@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +uudecode = @uudecode@ +vm_classes = @vm_classes@ +SUBDIRS = sax w3c_dom relaxngDatatype jsr166 +EXTRA_DIST = README +all: all-recursive + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu external/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu external/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +check-am: all-am +check: check-recursive +all-am: Makefile +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ + install-am install-strip tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am check check-am clean clean-generic clean-libtool \ + ctags ctags-recursive distclean distclean-generic \ + distclean-libtool distclean-tags dvi dvi-am html html-am info \ + info-am install install-am install-data install-data-am \ + install-dvi install-dvi-am install-exec install-exec-am \ + install-html install-html-am install-info install-info-am \ + install-man install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ + uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libjava/classpath/external/README b/libjava/classpath/external/README new file mode 100644 index 000000000..d6d6491d6 --- /dev/null +++ b/libjava/classpath/external/README @@ -0,0 +1,3 @@ +This directory contains libraries maintained externally to GNU Classpath. + +See the README files in the subdirectories for more information. diff --git a/libjava/classpath/external/jsr166/.cvsignore b/libjava/classpath/external/jsr166/.cvsignore new file mode 100644 index 000000000..70845e08e --- /dev/null +++ b/libjava/classpath/external/jsr166/.cvsignore @@ -0,0 +1 @@ +Makefile.in diff --git a/libjava/classpath/external/jsr166/IMPORTING b/libjava/classpath/external/jsr166/IMPORTING new file mode 100644 index 000000000..30bf3f474 --- /dev/null +++ b/libjava/classpath/external/jsr166/IMPORTING @@ -0,0 +1,31 @@ +The code in this directory comes from the JSR 166 +reference implementation. The RI consists of a public +domain part and a part that is copyright Sun. We remove +the copyrighted code prior to import so as not to taint +our source repository. + +To do a new import: + +* Download the RI from the source repository. + http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/main/java + I clicked on the "download tarball" link. + +* Unpack the tarball in a fresh directory. + mkdir tmp; cd tmp; tar zxvvf .../java.tar.gz + +* Clean up the results. + .../classpath/scripts/sanitize-jsr166 + +* Import these using 'cvs import' into the appropriate subdirectory. + The vendor branch name is 'JSR166'. + +* Merge the vendor branch onto the branch you're using (currently + the generics branch, but eventually it will be the trunk). + +* Build the result. + +* When it works, check it in. + +In general we try to avoid divergence from upstream as much +as possible. You may need to write new classes or methods in +order for the build to succeed. diff --git a/libjava/classpath/external/jsr166/Makefile.am b/libjava/classpath/external/jsr166/Makefile.am new file mode 100644 index 000000000..fa2db2ebf --- /dev/null +++ b/libjava/classpath/external/jsr166/Makefile.am @@ -0,0 +1,74 @@ +## Input file for automake to generate the Makefile.in used by configure + +EXTRA_DIST = IMPORTING \ +readme \ +java/util/AbstractQueue.java \ +java/util/concurrent/ScheduledThreadPoolExecutor.java \ +java/util/concurrent/ExecutorCompletionService.java \ +java/util/concurrent/LinkedBlockingQueue.java \ +java/util/concurrent/BlockingDeque.java \ +java/util/concurrent/Delayed.java \ +java/util/concurrent/ThreadFactory.java \ +java/util/concurrent/ArrayBlockingQueue.java \ +java/util/concurrent/RunnableFuture.java \ +java/util/concurrent/LinkedBlockingDeque.java \ +java/util/concurrent/CopyOnWriteArraySet.java \ +java/util/concurrent/DelayQueue.java \ +java/util/concurrent/SynchronousQueue.java \ +java/util/concurrent/Executor.java \ +java/util/concurrent/ExecutionException.java \ +java/util/concurrent/Semaphore.java \ +java/util/concurrent/BrokenBarrierException.java \ +java/util/concurrent/CompletionService.java \ +java/util/concurrent/CyclicBarrier.java \ +java/util/concurrent/AbstractExecutorService.java \ +java/util/concurrent/TimeoutException.java \ +java/util/concurrent/ConcurrentMap.java \ +java/util/concurrent/PriorityBlockingQueue.java \ +java/util/concurrent/CancellationException.java \ +java/util/concurrent/ConcurrentSkipListSet.java \ +java/util/concurrent/ConcurrentLinkedQueue.java \ +java/util/concurrent/RejectedExecutionHandler.java \ +java/util/concurrent/TimeUnit.java \ +java/util/concurrent/RejectedExecutionException.java \ +java/util/concurrent/ExecutorService.java \ +java/util/concurrent/ConcurrentHashMap.java \ +java/util/concurrent/ScheduledExecutorService.java \ +java/util/concurrent/ThreadPoolExecutor.java \ +java/util/concurrent/BlockingQueue.java \ +java/util/concurrent/ConcurrentSkipListMap.java \ +java/util/concurrent/ConcurrentNavigableMap.java \ +java/util/concurrent/Future.java \ +java/util/concurrent/FutureTask.java \ +java/util/concurrent/CountDownLatch.java \ +java/util/concurrent/RunnableScheduledFuture.java \ +java/util/concurrent/Callable.java \ +java/util/concurrent/locks/ReentrantLock.java \ +java/util/concurrent/locks/Lock.java \ +java/util/concurrent/locks/Condition.java \ +java/util/concurrent/locks/AbstractQueuedSynchronizer.java \ +java/util/concurrent/locks/AbstractOwnableSynchronizer.java \ +java/util/concurrent/locks/LockSupport.java \ +java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java \ +java/util/concurrent/locks/ReadWriteLock.java \ +java/util/concurrent/locks/ReentrantReadWriteLock.java \ +java/util/concurrent/Executors.java \ +java/util/concurrent/atomic/AtomicLongFieldUpdater.java \ +java/util/concurrent/atomic/AtomicLongArray.java \ +java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java \ +java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java \ +java/util/concurrent/atomic/AtomicBoolean.java \ +java/util/concurrent/atomic/AtomicReferenceArray.java \ +java/util/concurrent/atomic/AtomicStampedReference.java \ +java/util/concurrent/atomic/AtomicIntegerArray.java \ +java/util/concurrent/atomic/AtomicMarkableReference.java \ +java/util/concurrent/atomic/AtomicReference.java \ +java/util/concurrent/atomic/AtomicInteger.java \ +java/util/concurrent/atomic/AtomicLong.java \ +java/util/concurrent/ScheduledFuture.java \ +java/util/concurrent/Exchanger.java \ +java/util/Deque.java \ +java/util/NavigableMap.java \ +java/util/Queue.java \ +java/util/NavigableSet.java \ +java/util/ArrayDeque.java diff --git a/libjava/classpath/external/jsr166/Makefile.in b/libjava/classpath/external/jsr166/Makefile.in new file mode 100644 index 000000000..7a8589563 --- /dev/null +++ b/libjava/classpath/external/jsr166/Makefile.in @@ -0,0 +1,510 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = external/jsr166 +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/../../config/depstand.m4 \ + $(top_srcdir)/../../config/lead-dot.m4 \ + $(top_srcdir)/../../config/lib-ld.m4 \ + $(top_srcdir)/../../config/lib-link.m4 \ + $(top_srcdir)/../../config/lib-prefix.m4 \ + $(top_srcdir)/../../config/multi.m4 \ + $(top_srcdir)/../../config/no-executables.m4 \ + $(top_srcdir)/../../config/override.m4 \ + $(top_srcdir)/../../libtool.m4 \ + $(top_srcdir)/../../ltoptions.m4 \ + $(top_srcdir)/../../ltsugar.m4 \ + $(top_srcdir)/../../ltversion.m4 \ + $(top_srcdir)/../../lt~obsolete.m4 \ + $(top_srcdir)/m4/ac_prog_antlr.m4 \ + $(top_srcdir)/m4/ac_prog_java.m4 \ + $(top_srcdir)/m4/ac_prog_java_works.m4 \ + $(top_srcdir)/m4/ac_prog_javac.m4 \ + $(top_srcdir)/m4/ac_prog_javac_works.m4 \ + $(top_srcdir)/m4/acattribute.m4 $(top_srcdir)/m4/accross.m4 \ + $(top_srcdir)/m4/acinclude.m4 \ + $(top_srcdir)/m4/ax_create_stdint_h.m4 \ + $(top_srcdir)/m4/ax_func_which_gethostbyname_r.m4 \ + $(top_srcdir)/m4/gcc_attribute.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/../../mkinstalldirs +CONFIG_HEADER = $(top_builddir)/include/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +ANTLR = @ANTLR@ +ANTLR_JAR = @ANTLR_JAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CAIRO_CFLAGS = @CAIRO_CFLAGS@ +CAIRO_LIBS = @CAIRO_LIBS@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLASSPATH_CONVENIENCE = @CLASSPATH_CONVENIENCE@ +CLASSPATH_INCLUDES = @CLASSPATH_INCLUDES@ +CLASSPATH_MODULE = @CLASSPATH_MODULE@ +COLLECTIONS_PREFIX = @COLLECTIONS_PREFIX@ +CP = @CP@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATE = @DATE@ +DEFAULT_PREFS_PEER = @DEFAULT_PREFS_PEER@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +ECJ_JAR = @ECJ_JAR@ +EGREP = @EGREP@ +ERROR_CFLAGS = @ERROR_CFLAGS@ +EXAMPLESDIR = @EXAMPLESDIR@ +EXEEXT = @EXEEXT@ +EXTRA_CFLAGS = @EXTRA_CFLAGS@ +FGREP = @FGREP@ +FIND = @FIND@ +FREETYPE2_CFLAGS = @FREETYPE2_CFLAGS@ +FREETYPE2_LIBS = @FREETYPE2_LIBS@ +GCONF_CFLAGS = @GCONF_CFLAGS@ +GCONF_LIBS = @GCONF_LIBS@ +GDK_CFLAGS = @GDK_CFLAGS@ +GDK_LIBS = @GDK_LIBS@ +GJDOC = @GJDOC@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +GMP_CFLAGS = @GMP_CFLAGS@ +GMP_LIBS = @GMP_LIBS@ +GREP = @GREP@ +GSTREAMER_BASE_CFLAGS = @GSTREAMER_BASE_CFLAGS@ +GSTREAMER_BASE_LIBS = @GSTREAMER_BASE_LIBS@ +GSTREAMER_CFLAGS = @GSTREAMER_CFLAGS@ +GSTREAMER_FILE_READER = @GSTREAMER_FILE_READER@ +GSTREAMER_LIBS = @GSTREAMER_LIBS@ +GSTREAMER_MIXER_PROVIDER = @GSTREAMER_MIXER_PROVIDER@ +GSTREAMER_PLUGINS_BASE_CFLAGS = @GSTREAMER_PLUGINS_BASE_CFLAGS@ +GSTREAMER_PLUGINS_BASE_LIBS = @GSTREAMER_PLUGINS_BASE_LIBS@ +GST_PLUGIN_LDFLAGS = @GST_PLUGIN_LDFLAGS@ +GTK_CFLAGS = @GTK_CFLAGS@ +GTK_LIBS = @GTK_LIBS@ +INIT_LOAD_LIBRARY = @INIT_LOAD_LIBRARY@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JAR = @JAR@ +JAVA = @JAVA@ +JAVAC = @JAVAC@ +JAVAC_IS_GCJ = @JAVAC_IS_GCJ@ +JAVAC_MEM_OPT = @JAVAC_MEM_OPT@ +JAVA_LANG_SYSTEM_EXPLICIT_INITIALIZATION = @JAVA_LANG_SYSTEM_EXPLICIT_INITIALIZATION@ +JAY = @JAY@ +JAY_SKELETON = @JAY_SKELETON@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBDEBUG = @LIBDEBUG@ +LIBICONV = @LIBICONV@ +LIBMAGIC = @LIBMAGIC@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBVERSION = @LIBVERSION@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR = @MKDIR@ +MKDIR_P = @MKDIR_P@ +MOC = @MOC@ +MOZILLA_CFLAGS = @MOZILLA_CFLAGS@ +MOZILLA_LIBS = @MOZILLA_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PANGOFT2_CFLAGS = @PANGOFT2_CFLAGS@ +PANGOFT2_LIBS = @PANGOFT2_LIBS@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PATH_TO_ESCHER = @PATH_TO_ESCHER@ +PATH_TO_GLIBJ_ZIP = @PATH_TO_GLIBJ_ZIP@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PLUGIN_DIR = @PLUGIN_DIR@ +QT_CFLAGS = @QT_CFLAGS@ +QT_LIBS = @QT_LIBS@ +RANLIB = @RANLIB@ +REMOVE = @REMOVE@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRICT_WARNING_CFLAGS = @STRICT_WARNING_CFLAGS@ +STRIP = @STRIP@ +TOOLSDIR = @TOOLSDIR@ +USER_JAVAH = @USER_JAVAH@ +VERSION = @VERSION@ +WANT_NATIVE_BIG_INTEGER = @WANT_NATIVE_BIG_INTEGER@ +WARNING_CFLAGS = @WARNING_CFLAGS@ +XMKMF = @XMKMF@ +XML_CFLAGS = @XML_CFLAGS@ +XML_LIBS = @XML_LIBS@ +XSLT_CFLAGS = @XSLT_CFLAGS@ +XSLT_LIBS = @XSLT_LIBS@ +XTEST_LIBS = @XTEST_LIBS@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +ZIP = @ZIP@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_ANTLR = @ac_ct_ANTLR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +default_toolkit = @default_toolkit@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +glibjdir = @glibjdir@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +multi_basedir = @multi_basedir@ +nativeexeclibdir = @nativeexeclibdir@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +toolexeclibdir = @toolexeclibdir@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +uudecode = @uudecode@ +vm_classes = @vm_classes@ +EXTRA_DIST = IMPORTING \ +readme \ +java/util/AbstractQueue.java \ +java/util/concurrent/ScheduledThreadPoolExecutor.java \ +java/util/concurrent/ExecutorCompletionService.java \ +java/util/concurrent/LinkedBlockingQueue.java \ +java/util/concurrent/BlockingDeque.java \ +java/util/concurrent/Delayed.java \ +java/util/concurrent/ThreadFactory.java \ +java/util/concurrent/ArrayBlockingQueue.java \ +java/util/concurrent/RunnableFuture.java \ +java/util/concurrent/LinkedBlockingDeque.java \ +java/util/concurrent/CopyOnWriteArraySet.java \ +java/util/concurrent/DelayQueue.java \ +java/util/concurrent/SynchronousQueue.java \ +java/util/concurrent/Executor.java \ +java/util/concurrent/ExecutionException.java \ +java/util/concurrent/Semaphore.java \ +java/util/concurrent/BrokenBarrierException.java \ +java/util/concurrent/CompletionService.java \ +java/util/concurrent/CyclicBarrier.java \ +java/util/concurrent/AbstractExecutorService.java \ +java/util/concurrent/TimeoutException.java \ +java/util/concurrent/ConcurrentMap.java \ +java/util/concurrent/PriorityBlockingQueue.java \ +java/util/concurrent/CancellationException.java \ +java/util/concurrent/ConcurrentSkipListSet.java \ +java/util/concurrent/ConcurrentLinkedQueue.java \ +java/util/concurrent/RejectedExecutionHandler.java \ +java/util/concurrent/TimeUnit.java \ +java/util/concurrent/RejectedExecutionException.java \ +java/util/concurrent/ExecutorService.java \ +java/util/concurrent/ConcurrentHashMap.java \ +java/util/concurrent/ScheduledExecutorService.java \ +java/util/concurrent/ThreadPoolExecutor.java \ +java/util/concurrent/BlockingQueue.java \ +java/util/concurrent/ConcurrentSkipListMap.java \ +java/util/concurrent/ConcurrentNavigableMap.java \ +java/util/concurrent/Future.java \ +java/util/concurrent/FutureTask.java \ +java/util/concurrent/CountDownLatch.java \ +java/util/concurrent/RunnableScheduledFuture.java \ +java/util/concurrent/Callable.java \ +java/util/concurrent/locks/ReentrantLock.java \ +java/util/concurrent/locks/Lock.java \ +java/util/concurrent/locks/Condition.java \ +java/util/concurrent/locks/AbstractQueuedSynchronizer.java \ +java/util/concurrent/locks/AbstractOwnableSynchronizer.java \ +java/util/concurrent/locks/LockSupport.java \ +java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java \ +java/util/concurrent/locks/ReadWriteLock.java \ +java/util/concurrent/locks/ReentrantReadWriteLock.java \ +java/util/concurrent/Executors.java \ +java/util/concurrent/atomic/AtomicLongFieldUpdater.java \ +java/util/concurrent/atomic/AtomicLongArray.java \ +java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java \ +java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java \ +java/util/concurrent/atomic/AtomicBoolean.java \ +java/util/concurrent/atomic/AtomicReferenceArray.java \ +java/util/concurrent/atomic/AtomicStampedReference.java \ +java/util/concurrent/atomic/AtomicIntegerArray.java \ +java/util/concurrent/atomic/AtomicMarkableReference.java \ +java/util/concurrent/atomic/AtomicReference.java \ +java/util/concurrent/atomic/AtomicInteger.java \ +java/util/concurrent/atomic/AtomicLong.java \ +java/util/concurrent/ScheduledFuture.java \ +java/util/concurrent/Exchanger.java \ +java/util/Deque.java \ +java/util/NavigableMap.java \ +java/util/Queue.java \ +java/util/NavigableSet.java \ +java/util/ArrayDeque.java + +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu external/jsr166/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu external/jsr166/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libjava/classpath/external/jsr166/java/util/AbstractQueue.java b/libjava/classpath/external/jsr166/java/util/AbstractQueue.java new file mode 100644 index 000000000..644df6c49 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/AbstractQueue.java @@ -0,0 +1,166 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util; + +/** + * This class provides skeletal implementations of some {@link Queue} + * operations. The implementations in this class are appropriate when + * the base implementation does <em>not</em> allow <tt>null</tt> + * elements. Methods {@link #add add}, {@link #remove remove}, and + * {@link #element element} are based on {@link #offer offer}, {@link + * #poll poll}, and {@link #peek peek}, respectively but throw + * exceptions instead of indicating failure via <tt>false</tt> or + * <tt>null</tt> returns. + * + * <p> A <tt>Queue</tt> implementation that extends this class must + * minimally define a method {@link Queue#offer} which does not permit + * insertion of <tt>null</tt> elements, along with methods {@link + * Queue#peek}, {@link Queue#poll}, {@link Collection#size}, and a + * {@link Collection#iterator} supporting {@link + * Iterator#remove}. Typically, additional methods will be overridden + * as well. If these requirements cannot be met, consider instead + * subclassing {@link AbstractCollection}. + * + * <p>This class is a member of the + * <a href="{@docRoot}/../technotes/guides/collections/index.html"> + * Java Collections Framework</a>. + * + * @since 1.5 + * @author Doug Lea + * @param <E> the type of elements held in this collection + */ +public abstract class AbstractQueue<E> + extends AbstractCollection<E> + implements Queue<E> { + + /** + * Constructor for use by subclasses. + */ + protected AbstractQueue() { + } + + /** + * Inserts the specified element into this queue if it is possible to do so + * immediately without violating capacity restrictions, returning + * <tt>true</tt> upon success and throwing an <tt>IllegalStateException</tt> + * if no space is currently available. + * + * <p>This implementation returns <tt>true</tt> if <tt>offer</tt> succeeds, + * else throws an <tt>IllegalStateException</tt>. + * + * @param e the element to add + * @return <tt>true</tt> (as specified by {@link Collection#add}) + * @throws IllegalStateException if the element cannot be added at this + * time due to capacity restrictions + * @throws ClassCastException if the class of the specified element + * prevents it from being added to this queue + * @throws NullPointerException if the specified element is null and + * this queue does not permit null elements + * @throws IllegalArgumentException if some property of this element + * prevents it from being added to this queue + */ + public boolean add(E e) { + if (offer(e)) + return true; + else + throw new IllegalStateException("Queue full"); + } + + /** + * Retrieves and removes the head of this queue. This method differs + * from {@link #poll poll} only in that it throws an exception if this + * queue is empty. + * + * <p>This implementation returns the result of <tt>poll</tt> + * unless the queue is empty. + * + * @return the head of this queue + * @throws NoSuchElementException if this queue is empty + */ + public E remove() { + E x = poll(); + if (x != null) + return x; + else + throw new NoSuchElementException(); + } + + /** + * Retrieves, but does not remove, the head of this queue. This method + * differs from {@link #peek peek} only in that it throws an exception if + * this queue is empty. + * + * <p>This implementation returns the result of <tt>peek</tt> + * unless the queue is empty. + * + * @return the head of this queue + * @throws NoSuchElementException if this queue is empty + */ + public E element() { + E x = peek(); + if (x != null) + return x; + else + throw new NoSuchElementException(); + } + + /** + * Removes all of the elements from this queue. + * The queue will be empty after this call returns. + * + * <p>This implementation repeatedly invokes {@link #poll poll} until it + * returns <tt>null</tt>. + */ + public void clear() { + while (poll() != null) + ; + } + + /** + * Adds all of the elements in the specified collection to this + * queue. Attempts to addAll of a queue to itself result in + * <tt>IllegalArgumentException</tt>. Further, the behavior of + * this operation is undefined if the specified collection is + * modified while the operation is in progress. + * + * <p>This implementation iterates over the specified collection, + * and adds each element returned by the iterator to this + * queue, in turn. A runtime exception encountered while + * trying to add an element (including, in particular, a + * <tt>null</tt> element) may result in only some of the elements + * having been successfully added when the associated exception is + * thrown. + * + * @param c collection containing elements to be added to this queue + * @return <tt>true</tt> if this queue changed as a result of the call + * @throws ClassCastException if the class of an element of the specified + * collection prevents it from being added to this queue + * @throws NullPointerException if the specified collection contains a + * null element and this queue does not permit null elements, + * or if the specified collection is null + * @throws IllegalArgumentException if some property of an element of the + * specified collection prevents it from being added to this + * queue, or if the specified collection is this queue + * @throws IllegalStateException if not all the elements can be added at + * this time due to insertion restrictions + * @see #add(Object) + */ + public boolean addAll(Collection<? extends E> c) { + if (c == null) + throw new NullPointerException(); + if (c == this) + throw new IllegalArgumentException(); + boolean modified = false; + Iterator<? extends E> e = c.iterator(); + while (e.hasNext()) { + if (add(e.next())) + modified = true; + } + return modified; + } + +} diff --git a/libjava/classpath/external/jsr166/java/util/ArrayDeque.java b/libjava/classpath/external/jsr166/java/util/ArrayDeque.java new file mode 100644 index 000000000..a4bc75c99 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/ArrayDeque.java @@ -0,0 +1,839 @@ +/* + * Written by Josh Bloch of Google Inc. and released to the public domain, + * as explained at http://creativecommons.org/licenses/publicdomain. + */ + +package java.util; +import java.io.*; + +/** + * Resizable-array implementation of the {@link Deque} interface. Array + * deques have no capacity restrictions; they grow as necessary to support + * usage. They are not thread-safe; in the absence of external + * synchronization, they do not support concurrent access by multiple threads. + * Null elements are prohibited. This class is likely to be faster than + * {@link Stack} when used as a stack, and faster than {@link LinkedList} + * when used as a queue. + * + * <p>Most <tt>ArrayDeque</tt> operations run in amortized constant time. + * Exceptions include {@link #remove(Object) remove}, {@link + * #removeFirstOccurrence removeFirstOccurrence}, {@link #removeLastOccurrence + * removeLastOccurrence}, {@link #contains contains}, {@link #iterator + * iterator.remove()}, and the bulk operations, all of which run in linear + * time. + * + * <p>The iterators returned by this class's <tt>iterator</tt> method are + * <i>fail-fast</i>: If the deque is modified at any time after the iterator + * is created, in any way except through the iterator's own <tt>remove</tt> + * method, the iterator will generally throw a {@link + * ConcurrentModificationException}. Thus, in the face of concurrent + * modification, the iterator fails quickly and cleanly, rather than risking + * arbitrary, non-deterministic behavior at an undetermined time in the + * future. + * + * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed + * as it is, generally speaking, impossible to make any hard guarantees in the + * presence of unsynchronized concurrent modification. Fail-fast iterators + * throw <tt>ConcurrentModificationException</tt> on a best-effort basis. + * Therefore, it would be wrong to write a program that depended on this + * exception for its correctness: <i>the fail-fast behavior of iterators + * should be used only to detect bugs.</i> + * + * <p>This class and its iterator implement all of the + * <em>optional</em> methods of the {@link Collection} and {@link + * Iterator} interfaces. + * + * <p>This class is a member of the + * <a href="{@docRoot}/../technotes/guides/collections/index.html"> + * Java Collections Framework</a>. + * + * @author Josh Bloch and Doug Lea + * @since 1.6 + * @param <E> the type of elements held in this collection + */ +public class ArrayDeque<E> extends AbstractCollection<E> + implements Deque<E>, Cloneable, Serializable +{ + /** + * The array in which the elements of the deque are stored. + * The capacity of the deque is the length of this array, which is + * always a power of two. The array is never allowed to become + * full, except transiently within an addX method where it is + * resized (see doubleCapacity) immediately upon becoming full, + * thus avoiding head and tail wrapping around to equal each + * other. We also guarantee that all array cells not holding + * deque elements are always null. + */ + private transient E[] elements; + + /** + * The index of the element at the head of the deque (which is the + * element that would be removed by remove() or pop()); or an + * arbitrary number equal to tail if the deque is empty. + */ + private transient int head; + + /** + * The index at which the next element would be added to the tail + * of the deque (via addLast(E), add(E), or push(E)). + */ + private transient int tail; + + /** + * The minimum capacity that we'll use for a newly created deque. + * Must be a power of 2. + */ + private static final int MIN_INITIAL_CAPACITY = 8; + + // ****** Array allocation and resizing utilities ****** + + /** + * Allocate empty array to hold the given number of elements. + * + * @param numElements the number of elements to hold + */ + private void allocateElements(int numElements) { + int initialCapacity = MIN_INITIAL_CAPACITY; + // Find the best power of two to hold elements. + // Tests "<=" because arrays aren't kept full. + if (numElements >= initialCapacity) { + initialCapacity = numElements; + initialCapacity |= (initialCapacity >>> 1); + initialCapacity |= (initialCapacity >>> 2); + initialCapacity |= (initialCapacity >>> 4); + initialCapacity |= (initialCapacity >>> 8); + initialCapacity |= (initialCapacity >>> 16); + initialCapacity++; + + if (initialCapacity < 0) // Too many elements, must back off + initialCapacity >>>= 1;// Good luck allocating 2 ^ 30 elements + } + elements = (E[]) new Object[initialCapacity]; + } + + /** + * Double the capacity of this deque. Call only when full, i.e., + * when head and tail have wrapped around to become equal. + */ + private void doubleCapacity() { + assert head == tail; + int p = head; + int n = elements.length; + int r = n - p; // number of elements to the right of p + int newCapacity = n << 1; + if (newCapacity < 0) + throw new IllegalStateException("Sorry, deque too big"); + Object[] a = new Object[newCapacity]; + System.arraycopy(elements, p, a, 0, r); + System.arraycopy(elements, 0, a, r, p); + elements = (E[])a; + head = 0; + tail = n; + } + + /** + * Copies the elements from our element array into the specified array, + * in order (from first to last element in the deque). It is assumed + * that the array is large enough to hold all elements in the deque. + * + * @return its argument + */ + private <T> T[] copyElements(T[] a) { + if (head < tail) { + System.arraycopy(elements, head, a, 0, size()); + } else if (head > tail) { + int headPortionLen = elements.length - head; + System.arraycopy(elements, head, a, 0, headPortionLen); + System.arraycopy(elements, 0, a, headPortionLen, tail); + } + return a; + } + + /** + * Constructs an empty array deque with an initial capacity + * sufficient to hold 16 elements. + */ + public ArrayDeque() { + elements = (E[]) new Object[16]; + } + + /** + * Constructs an empty array deque with an initial capacity + * sufficient to hold the specified number of elements. + * + * @param numElements lower bound on initial capacity of the deque + */ + public ArrayDeque(int numElements) { + allocateElements(numElements); + } + + /** + * Constructs a deque containing the elements of the specified + * collection, in the order they are returned by the collection's + * iterator. (The first element returned by the collection's + * iterator becomes the first element, or <i>front</i> of the + * deque.) + * + * @param c the collection whose elements are to be placed into the deque + * @throws NullPointerException if the specified collection is null + */ + public ArrayDeque(Collection<? extends E> c) { + allocateElements(c.size()); + addAll(c); + } + + // The main insertion and extraction methods are addFirst, + // addLast, pollFirst, pollLast. The other methods are defined in + // terms of these. + + /** + * Inserts the specified element at the front of this deque. + * + * @param e the element to add + * @throws NullPointerException if the specified element is null + */ + public void addFirst(E e) { + if (e == null) + throw new NullPointerException(); + elements[head = (head - 1) & (elements.length - 1)] = e; + if (head == tail) + doubleCapacity(); + } + + /** + * Inserts the specified element at the end of this deque. + * + * <p>This method is equivalent to {@link #add}. + * + * @param e the element to add + * @throws NullPointerException if the specified element is null + */ + public void addLast(E e) { + if (e == null) + throw new NullPointerException(); + elements[tail] = e; + if ( (tail = (tail + 1) & (elements.length - 1)) == head) + doubleCapacity(); + } + + /** + * Inserts the specified element at the front of this deque. + * + * @param e the element to add + * @return <tt>true</tt> (as specified by {@link Deque#offerFirst}) + * @throws NullPointerException if the specified element is null + */ + public boolean offerFirst(E e) { + addFirst(e); + return true; + } + + /** + * Inserts the specified element at the end of this deque. + * + * @param e the element to add + * @return <tt>true</tt> (as specified by {@link Deque#offerLast}) + * @throws NullPointerException if the specified element is null + */ + public boolean offerLast(E e) { + addLast(e); + return true; + } + + /** + * @throws NoSuchElementException {@inheritDoc} + */ + public E removeFirst() { + E x = pollFirst(); + if (x == null) + throw new NoSuchElementException(); + return x; + } + + /** + * @throws NoSuchElementException {@inheritDoc} + */ + public E removeLast() { + E x = pollLast(); + if (x == null) + throw new NoSuchElementException(); + return x; + } + + public E pollFirst() { + int h = head; + E result = elements[h]; // Element is null if deque empty + if (result == null) + return null; + elements[h] = null; // Must null out slot + head = (h + 1) & (elements.length - 1); + return result; + } + + public E pollLast() { + int t = (tail - 1) & (elements.length - 1); + E result = elements[t]; + if (result == null) + return null; + elements[t] = null; + tail = t; + return result; + } + + /** + * @throws NoSuchElementException {@inheritDoc} + */ + public E getFirst() { + E x = elements[head]; + if (x == null) + throw new NoSuchElementException(); + return x; + } + + /** + * @throws NoSuchElementException {@inheritDoc} + */ + public E getLast() { + E x = elements[(tail - 1) & (elements.length - 1)]; + if (x == null) + throw new NoSuchElementException(); + return x; + } + + public E peekFirst() { + return elements[head]; // elements[head] is null if deque empty + } + + public E peekLast() { + return elements[(tail - 1) & (elements.length - 1)]; + } + + /** + * Removes the first occurrence of the specified element in this + * deque (when traversing the deque from head to tail). + * If the deque does not contain the element, it is unchanged. + * More formally, removes the first element <tt>e</tt> such that + * <tt>o.equals(e)</tt> (if such an element exists). + * Returns <tt>true</tt> if this deque contained the specified element + * (or equivalently, if this deque changed as a result of the call). + * + * @param o element to be removed from this deque, if present + * @return <tt>true</tt> if the deque contained the specified element + */ + public boolean removeFirstOccurrence(Object o) { + if (o == null) + return false; + int mask = elements.length - 1; + int i = head; + E x; + while ( (x = elements[i]) != null) { + if (o.equals(x)) { + delete(i); + return true; + } + i = (i + 1) & mask; + } + return false; + } + + /** + * Removes the last occurrence of the specified element in this + * deque (when traversing the deque from head to tail). + * If the deque does not contain the element, it is unchanged. + * More formally, removes the last element <tt>e</tt> such that + * <tt>o.equals(e)</tt> (if such an element exists). + * Returns <tt>true</tt> if this deque contained the specified element + * (or equivalently, if this deque changed as a result of the call). + * + * @param o element to be removed from this deque, if present + * @return <tt>true</tt> if the deque contained the specified element + */ + public boolean removeLastOccurrence(Object o) { + if (o == null) + return false; + int mask = elements.length - 1; + int i = (tail - 1) & mask; + E x; + while ( (x = elements[i]) != null) { + if (o.equals(x)) { + delete(i); + return true; + } + i = (i - 1) & mask; + } + return false; + } + + // *** Queue methods *** + + /** + * Inserts the specified element at the end of this deque. + * + * <p>This method is equivalent to {@link #addLast}. + * + * @param e the element to add + * @return <tt>true</tt> (as specified by {@link Collection#add}) + * @throws NullPointerException if the specified element is null + */ + public boolean add(E e) { + addLast(e); + return true; + } + + /** + * Inserts the specified element at the end of this deque. + * + * <p>This method is equivalent to {@link #offerLast}. + * + * @param e the element to add + * @return <tt>true</tt> (as specified by {@link Queue#offer}) + * @throws NullPointerException if the specified element is null + */ + public boolean offer(E e) { + return offerLast(e); + } + + /** + * Retrieves and removes the head of the queue represented by this deque. + * + * This method differs from {@link #poll poll} only in that it throws an + * exception if this deque is empty. + * + * <p>This method is equivalent to {@link #removeFirst}. + * + * @return the head of the queue represented by this deque + * @throws NoSuchElementException {@inheritDoc} + */ + public E remove() { + return removeFirst(); + } + + /** + * Retrieves and removes the head of the queue represented by this deque + * (in other words, the first element of this deque), or returns + * <tt>null</tt> if this deque is empty. + * + * <p>This method is equivalent to {@link #pollFirst}. + * + * @return the head of the queue represented by this deque, or + * <tt>null</tt> if this deque is empty + */ + public E poll() { + return pollFirst(); + } + + /** + * Retrieves, but does not remove, the head of the queue represented by + * this deque. This method differs from {@link #peek peek} only in + * that it throws an exception if this deque is empty. + * + * <p>This method is equivalent to {@link #getFirst}. + * + * @return the head of the queue represented by this deque + * @throws NoSuchElementException {@inheritDoc} + */ + public E element() { + return getFirst(); + } + + /** + * Retrieves, but does not remove, the head of the queue represented by + * this deque, or returns <tt>null</tt> if this deque is empty. + * + * <p>This method is equivalent to {@link #peekFirst}. + * + * @return the head of the queue represented by this deque, or + * <tt>null</tt> if this deque is empty + */ + public E peek() { + return peekFirst(); + } + + // *** Stack methods *** + + /** + * Pushes an element onto the stack represented by this deque. In other + * words, inserts the element at the front of this deque. + * + * <p>This method is equivalent to {@link #addFirst}. + * + * @param e the element to push + * @throws NullPointerException if the specified element is null + */ + public void push(E e) { + addFirst(e); + } + + /** + * Pops an element from the stack represented by this deque. In other + * words, removes and returns the first element of this deque. + * + * <p>This method is equivalent to {@link #removeFirst()}. + * + * @return the element at the front of this deque (which is the top + * of the stack represented by this deque) + * @throws NoSuchElementException {@inheritDoc} + */ + public E pop() { + return removeFirst(); + } + + private void checkInvariants() { + assert elements[tail] == null; + assert head == tail ? elements[head] == null : + (elements[head] != null && + elements[(tail - 1) & (elements.length - 1)] != null); + assert elements[(head - 1) & (elements.length - 1)] == null; + } + + /** + * Removes the element at the specified position in the elements array, + * adjusting head and tail as necessary. This can result in motion of + * elements backwards or forwards in the array. + * + * <p>This method is called delete rather than remove to emphasize + * that its semantics differ from those of {@link List#remove(int)}. + * + * @return true if elements moved backwards + */ + private boolean delete(int i) { + checkInvariants(); + final E[] elements = this.elements; + final int mask = elements.length - 1; + final int h = head; + final int t = tail; + final int front = (i - h) & mask; + final int back = (t - i) & mask; + + // Invariant: head <= i < tail mod circularity + if (front >= ((t - h) & mask)) + throw new ConcurrentModificationException(); + + // Optimize for least element motion + if (front < back) { + if (h <= i) { + System.arraycopy(elements, h, elements, h + 1, front); + } else { // Wrap around + System.arraycopy(elements, 0, elements, 1, i); + elements[0] = elements[mask]; + System.arraycopy(elements, h, elements, h + 1, mask - h); + } + elements[h] = null; + head = (h + 1) & mask; + return false; + } else { + if (i < t) { // Copy the null tail as well + System.arraycopy(elements, i + 1, elements, i, back); + tail = t - 1; + } else { // Wrap around + System.arraycopy(elements, i + 1, elements, i, mask - i); + elements[mask] = elements[0]; + System.arraycopy(elements, 1, elements, 0, t); + tail = (t - 1) & mask; + } + return true; + } + } + + // *** Collection Methods *** + + /** + * Returns the number of elements in this deque. + * + * @return the number of elements in this deque + */ + public int size() { + return (tail - head) & (elements.length - 1); + } + + /** + * Returns <tt>true</tt> if this deque contains no elements. + * + * @return <tt>true</tt> if this deque contains no elements + */ + public boolean isEmpty() { + return head == tail; + } + + /** + * Returns an iterator over the elements in this deque. The elements + * will be ordered from first (head) to last (tail). This is the same + * order that elements would be dequeued (via successive calls to + * {@link #remove} or popped (via successive calls to {@link #pop}). + * + * @return an iterator over the elements in this deque + */ + public Iterator<E> iterator() { + return new DeqIterator(); + } + + public Iterator<E> descendingIterator() { + return new DescendingIterator(); + } + + private class DeqIterator implements Iterator<E> { + /** + * Index of element to be returned by subsequent call to next. + */ + private int cursor = head; + + /** + * Tail recorded at construction (also in remove), to stop + * iterator and also to check for comodification. + */ + private int fence = tail; + + /** + * Index of element returned by most recent call to next. + * Reset to -1 if element is deleted by a call to remove. + */ + private int lastRet = -1; + + public boolean hasNext() { + return cursor != fence; + } + + public E next() { + if (cursor == fence) + throw new NoSuchElementException(); + E result = elements[cursor]; + // This check doesn't catch all possible comodifications, + // but does catch the ones that corrupt traversal + if (tail != fence || result == null) + throw new ConcurrentModificationException(); + lastRet = cursor; + cursor = (cursor + 1) & (elements.length - 1); + return result; + } + + public void remove() { + if (lastRet < 0) + throw new IllegalStateException(); + if (delete(lastRet)) { // if left-shifted, undo increment in next() + cursor = (cursor - 1) & (elements.length - 1); + fence = tail; + } + lastRet = -1; + } + } + + private class DescendingIterator implements Iterator<E> { + /* + * This class is nearly a mirror-image of DeqIterator, using + * tail instead of head for initial cursor, and head instead of + * tail for fence. + */ + private int cursor = tail; + private int fence = head; + private int lastRet = -1; + + public boolean hasNext() { + return cursor != fence; + } + + public E next() { + if (cursor == fence) + throw new NoSuchElementException(); + cursor = (cursor - 1) & (elements.length - 1); + E result = elements[cursor]; + if (head != fence || result == null) + throw new ConcurrentModificationException(); + lastRet = cursor; + return result; + } + + public void remove() { + if (lastRet < 0) + throw new IllegalStateException(); + if (!delete(lastRet)) { + cursor = (cursor + 1) & (elements.length - 1); + fence = head; + } + lastRet = -1; + } + } + + /** + * Returns <tt>true</tt> if this deque contains the specified element. + * More formally, returns <tt>true</tt> if and only if this deque contains + * at least one element <tt>e</tt> such that <tt>o.equals(e)</tt>. + * + * @param o object to be checked for containment in this deque + * @return <tt>true</tt> if this deque contains the specified element + */ + public boolean contains(Object o) { + if (o == null) + return false; + int mask = elements.length - 1; + int i = head; + E x; + while ( (x = elements[i]) != null) { + if (o.equals(x)) + return true; + i = (i + 1) & mask; + } + return false; + } + + /** + * Removes a single instance of the specified element from this deque. + * If the deque does not contain the element, it is unchanged. + * More formally, removes the first element <tt>e</tt> such that + * <tt>o.equals(e)</tt> (if such an element exists). + * Returns <tt>true</tt> if this deque contained the specified element + * (or equivalently, if this deque changed as a result of the call). + * + * <p>This method is equivalent to {@link #removeFirstOccurrence}. + * + * @param o element to be removed from this deque, if present + * @return <tt>true</tt> if this deque contained the specified element + */ + public boolean remove(Object o) { + return removeFirstOccurrence(o); + } + + /** + * Removes all of the elements from this deque. + * The deque will be empty after this call returns. + */ + public void clear() { + int h = head; + int t = tail; + if (h != t) { // clear all cells + head = tail = 0; + int i = h; + int mask = elements.length - 1; + do { + elements[i] = null; + i = (i + 1) & mask; + } while (i != t); + } + } + + /** + * Returns an array containing all of the elements in this deque + * in proper sequence (from first to last element). + * + * <p>The returned array will be "safe" in that no references to it are + * maintained by this deque. (In other words, this method must allocate + * a new array). The caller is thus free to modify the returned array. + * + * <p>This method acts as bridge between array-based and collection-based + * APIs. + * + * @return an array containing all of the elements in this deque + */ + public Object[] toArray() { + return copyElements(new Object[size()]); + } + + /** + * Returns an array containing all of the elements in this deque in + * proper sequence (from first to last element); the runtime type of the + * returned array is that of the specified array. If the deque fits in + * the specified array, it is returned therein. Otherwise, a new array + * is allocated with the runtime type of the specified array and the + * size of this deque. + * + * <p>If this deque fits in the specified array with room to spare + * (i.e., the array has more elements than this deque), the element in + * the array immediately following the end of the deque is set to + * <tt>null</tt>. + * + * <p>Like the {@link #toArray()} method, this method acts as bridge between + * array-based and collection-based APIs. Further, this method allows + * precise control over the runtime type of the output array, and may, + * under certain circumstances, be used to save allocation costs. + * + * <p>Suppose <tt>x</tt> is a deque known to contain only strings. + * The following code can be used to dump the deque into a newly + * allocated array of <tt>String</tt>: + * + * <pre> + * String[] y = x.toArray(new String[0]);</pre> + * + * Note that <tt>toArray(new Object[0])</tt> is identical in function to + * <tt>toArray()</tt>. + * + * @param a the array into which the elements of the deque are to + * be stored, if it is big enough; otherwise, a new array of the + * same runtime type is allocated for this purpose + * @return an array containing all of the elements in this deque + * @throws ArrayStoreException if the runtime type of the specified array + * is not a supertype of the runtime type of every element in + * this deque + * @throws NullPointerException if the specified array is null + */ + public <T> T[] toArray(T[] a) { + int size = size(); + if (a.length < size) + a = (T[])java.lang.reflect.Array.newInstance( + a.getClass().getComponentType(), size); + copyElements(a); + if (a.length > size) + a[size] = null; + return a; + } + + // *** Object methods *** + + /** + * Returns a copy of this deque. + * + * @return a copy of this deque + */ + public ArrayDeque<E> clone() { + try { + ArrayDeque<E> result = (ArrayDeque<E>) super.clone(); + // Classpath local: we don't have Arrays.copyOf yet. + // result.elements = Arrays.copyOf(elements, elements.length); + result.elements = (E[]) elements.clone(); + return result; + + } catch (CloneNotSupportedException e) { + throw new AssertionError(); + } + } + + /** + * Appease the serialization gods. + */ + private static final long serialVersionUID = 2340985798034038923L; + + /** + * Serialize this deque. + * + * @serialData The current size (<tt>int</tt>) of the deque, + * followed by all of its elements (each an object reference) in + * first-to-last order. + */ + private void writeObject(ObjectOutputStream s) throws IOException { + s.defaultWriteObject(); + + // Write out size + s.writeInt(size()); + + // Write out elements in order. + int mask = elements.length - 1; + for (int i = head; i != tail; i = (i + 1) & mask) + s.writeObject(elements[i]); + } + + /** + * Deserialize this deque. + */ + private void readObject(ObjectInputStream s) + throws IOException, ClassNotFoundException { + s.defaultReadObject(); + + // Read in size and allocate array + int size = s.readInt(); + allocateElements(size); + head = 0; + tail = size; + + // Read in all elements in the proper order. + for (int i = 0; i < size; i++) + elements[i] = (E)s.readObject(); + } +} diff --git a/libjava/classpath/external/jsr166/java/util/Deque.java b/libjava/classpath/external/jsr166/java/util/Deque.java new file mode 100644 index 000000000..a769561dc --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/Deque.java @@ -0,0 +1,547 @@ +/* + * Written by Doug Lea and Josh Bloch with assistance from members of + * JCP JSR-166 Expert Group and released to the public domain, as explained + * at http://creativecommons.org/licenses/publicdomain + */ + +package java.util; + +/** + * A linear collection that supports element insertion and removal at + * both ends. The name <i>deque</i> is short for "double ended queue" + * and is usually pronounced "deck". Most <tt>Deque</tt> + * implementations place no fixed limits on the number of elements + * they may contain, but this interface supports capacity-restricted + * deques as well as those with no fixed size limit. + * + * <p>This interface defines methods to access the elements at both + * ends of the deque. Methods are provided to insert, remove, and + * examine the element. Each of these methods exists in two forms: + * one throws an exception if the operation fails, the other returns a + * special value (either <tt>null</tt> or <tt>false</tt>, depending on + * the operation). The latter form of the insert operation is + * designed specifically for use with capacity-restricted + * <tt>Deque</tt> implementations; in most implementations, insert + * operations cannot fail. + * + * <p>The twelve methods described above are summarized in the + * following table: + * + * <p> + * <table BORDER CELLPADDING=3 CELLSPACING=1> + * <tr> + * <td></td> + * <td ALIGN=CENTER COLSPAN = 2> <b>First Element (Head)</b></td> + * <td ALIGN=CENTER COLSPAN = 2> <b>Last Element (Tail)</b></td> + * </tr> + * <tr> + * <td></td> + * <td ALIGN=CENTER><em>Throws exception</em></td> + * <td ALIGN=CENTER><em>Special value</em></td> + * <td ALIGN=CENTER><em>Throws exception</em></td> + * <td ALIGN=CENTER><em>Special value</em></td> + * </tr> + * <tr> + * <td><b>Insert</b></td> + * <td>{@link #addFirst addFirst(e)}</td> + * <td>{@link #offerFirst offerFirst(e)}</td> + * <td>{@link #addLast addLast(e)}</td> + * <td>{@link #offerLast offerLast(e)}</td> + * </tr> + * <tr> + * <td><b>Remove</b></td> + * <td>{@link #removeFirst removeFirst()}</td> + * <td>{@link #pollFirst pollFirst()}</td> + * <td>{@link #removeLast removeLast()}</td> + * <td>{@link #pollLast pollLast()}</td> + * </tr> + * <tr> + * <td><b>Examine</b></td> + * <td>{@link #getFirst getFirst()}</td> + * <td>{@link #peekFirst peekFirst()}</td> + * <td>{@link #getLast getLast()}</td> + * <td>{@link #peekLast peekLast()}</td> + * </tr> + * </table> + * + * <p>This interface extends the {@link Queue} interface. When a deque is + * used as a queue, FIFO (First-In-First-Out) behavior results. Elements are + * added at the end of the deque and removed from the beginning. The methods + * inherited from the <tt>Queue</tt> interface are precisely equivalent to + * <tt>Deque</tt> methods as indicated in the following table: + * + * <p> + * <table BORDER CELLPADDING=3 CELLSPACING=1> + * <tr> + * <td ALIGN=CENTER> <b><tt>Queue</tt> Method</b></td> + * <td ALIGN=CENTER> <b>Equivalent <tt>Deque</tt> Method</b></td> + * </tr> + * <tr> + * <td>{@link java.util.Queue#add add(e)}</td> + * <td>{@link #addLast addLast(e)}</td> + * </tr> + * <tr> + * <td>{@link java.util.Queue#offer offer(e)}</td> + * <td>{@link #offerLast offerLast(e)}</td> + * </tr> + * <tr> + * <td>{@link java.util.Queue#remove remove()}</td> + * <td>{@link #removeFirst removeFirst()}</td> + * </tr> + * <tr> + * <td>{@link java.util.Queue#poll poll()}</td> + * <td>{@link #pollFirst pollFirst()}</td> + * </tr> + * <tr> + * <td>{@link java.util.Queue#element element()}</td> + * <td>{@link #getFirst getFirst()}</td> + * </tr> + * <tr> + * <td>{@link java.util.Queue#peek peek()}</td> + * <td>{@link #peek peekFirst()}</td> + * </tr> + * </table> + * + * <p>Deques can also be used as LIFO (Last-In-First-Out) stacks. This + * interface should be used in preference to the legacy {@link Stack} class. + * When a deque is used as a stack, elements are pushed and popped from the + * beginning of the deque. Stack methods are precisely equivalent to + * <tt>Deque</tt> methods as indicated in the table below: + * + * <p> + * <table BORDER CELLPADDING=3 CELLSPACING=1> + * <tr> + * <td ALIGN=CENTER> <b>Stack Method</b></td> + * <td ALIGN=CENTER> <b>Equivalent <tt>Deque</tt> Method</b></td> + * </tr> + * <tr> + * <td>{@link #push push(e)}</td> + * <td>{@link #addFirst addFirst(e)}</td> + * </tr> + * <tr> + * <td>{@link #pop pop()}</td> + * <td>{@link #removeFirst removeFirst()}</td> + * </tr> + * <tr> + * <td>{@link #peek peek()}</td> + * <td>{@link #peekFirst peekFirst()}</td> + * </tr> + * </table> + * + * <p>Note that the {@link #peek peek} method works equally well when + * a deque is used as a queue or a stack; in either case, elements are + * drawn from the beginning of the deque. + * + * <p>This interface provides two methods to remove interior + * elements, {@link #removeFirstOccurrence removeFirstOccurrence} and + * {@link #removeLastOccurrence removeLastOccurrence}. + * + * <p>Unlike the {@link List} interface, this interface does not + * provide support for indexed access to elements. + * + * <p>While <tt>Deque</tt> implementations are not strictly required + * to prohibit the insertion of null elements, they are strongly + * encouraged to do so. Users of any <tt>Deque</tt> implementations + * that do allow null elements are strongly encouraged <i>not</i> to + * take advantage of the ability to insert nulls. This is so because + * <tt>null</tt> is used as a special return value by various methods + * to indicated that the deque is empty. + * + * <p><tt>Deque</tt> implementations generally do not define + * element-based versions of the <tt>equals</tt> and <tt>hashCode</tt> + * methods, but instead inherit the identity-based versions from class + * <tt>Object</tt>. + * + * <p>This interface is a member of the <a + * href="{@docRoot}/../technotes/guides/collections/index.html"> Java Collections + * Framework</a>. + * + * @author Doug Lea + * @author Josh Bloch + * @since 1.6 + * @param <E> the type of elements held in this collection + */ + +public interface Deque<E> extends Queue<E> { + /** + * Inserts the specified element at the front of this deque if it is + * possible to do so immediately without violating capacity restrictions. + * When using a capacity-restricted deque, it is generally preferable to + * use method {@link #offerFirst}. + * + * @param e the element to add + * @throws IllegalStateException if the element cannot be added at this + * time due to capacity restrictions + * @throws ClassCastException if the class of the specified element + * prevents it from being added to this deque + * @throws NullPointerException if the specified element is null and this + * deque does not permit null elements + * @throws IllegalArgumentException if some property of the specified + * element prevents it from being added to this deque + */ + void addFirst(E e); + + /** + * Inserts the specified element at the end of this deque if it is + * possible to do so immediately without violating capacity restrictions. + * When using a capacity-restricted deque, it is generally preferable to + * use method {@link #offerLast}. + * + * <p>This method is equivalent to {@link #add}. + * + * @param e the element to add + * @throws IllegalStateException if the element cannot be added at this + * time due to capacity restrictions + * @throws ClassCastException if the class of the specified element + * prevents it from being added to this deque + * @throws NullPointerException if the specified element is null and this + * deque does not permit null elements + * @throws IllegalArgumentException if some property of the specified + * element prevents it from being added to this deque + */ + void addLast(E e); + + /** + * Inserts the specified element at the front of this deque unless it would + * violate capacity restrictions. When using a capacity-restricted deque, + * this method is generally preferable to the {@link #addFirst} method, + * which can fail to insert an element only by throwing an exception. + * + * @param e the element to add + * @return <tt>true</tt> if the element was added to this deque, else + * <tt>false</tt> + * @throws ClassCastException if the class of the specified element + * prevents it from being added to this deque + * @throws NullPointerException if the specified element is null and this + * deque does not permit null elements + * @throws IllegalArgumentException if some property of the specified + * element prevents it from being added to this deque + */ + boolean offerFirst(E e); + + /** + * Inserts the specified element at the end of this deque unless it would + * violate capacity restrictions. When using a capacity-restricted deque, + * this method is generally preferable to the {@link #addLast} method, + * which can fail to insert an element only by throwing an exception. + * + * @param e the element to add + * @return <tt>true</tt> if the element was added to this deque, else + * <tt>false</tt> + * @throws ClassCastException if the class of the specified element + * prevents it from being added to this deque + * @throws NullPointerException if the specified element is null and this + * deque does not permit null elements + * @throws IllegalArgumentException if some property of the specified + * element prevents it from being added to this deque + */ + boolean offerLast(E e); + + /** + * Retrieves and removes the first element of this deque. This method + * differs from {@link #pollFirst pollFirst} only in that it throws an + * exception if this deque is empty. + * + * @return the head of this deque + * @throws NoSuchElementException if this deque is empty + */ + E removeFirst(); + + /** + * Retrieves and removes the last element of this deque. This method + * differs from {@link #pollLast pollLast} only in that it throws an + * exception if this deque is empty. + * + * @return the tail of this deque + * @throws NoSuchElementException if this deque is empty + */ + E removeLast(); + + /** + * Retrieves and removes the first element of this deque, + * or returns <tt>null</tt> if this deque is empty. + * + * @return the head of this deque, or <tt>null</tt> if this deque is empty + */ + E pollFirst(); + + /** + * Retrieves and removes the last element of this deque, + * or returns <tt>null</tt> if this deque is empty. + * + * @return the tail of this deque, or <tt>null</tt> if this deque is empty + */ + E pollLast(); + + /** + * Retrieves, but does not remove, the first element of this deque. + * + * This method differs from {@link #peekFirst peekFirst} only in that it + * throws an exception if this deque is empty. + * + * @return the head of this deque + * @throws NoSuchElementException if this deque is empty + */ + E getFirst(); + + /** + * Retrieves, but does not remove, the last element of this deque. + * This method differs from {@link #peekLast peekLast} only in that it + * throws an exception if this deque is empty. + * + * @return the tail of this deque + * @throws NoSuchElementException if this deque is empty + */ + E getLast(); + + /** + * Retrieves, but does not remove, the first element of this deque, + * or returns <tt>null</tt> if this deque is empty. + * + * @return the head of this deque, or <tt>null</tt> if this deque is empty + */ + E peekFirst(); + + /** + * Retrieves, but does not remove, the last element of this deque, + * or returns <tt>null</tt> if this deque is empty. + * + * @return the tail of this deque, or <tt>null</tt> if this deque is empty + */ + E peekLast(); + + /** + * Removes the first occurrence of the specified element from this deque. + * If the deque does not contain the element, it is unchanged. + * More formally, removes the first element <tt>e</tt> such that + * <tt>(o==null ? e==null : o.equals(e))</tt> + * (if such an element exists). + * Returns <tt>true</tt> if this deque contained the specified element + * (or equivalently, if this deque changed as a result of the call). + * + * @param o element to be removed from this deque, if present + * @return <tt>true</tt> if an element was removed as a result of this call + * @throws ClassCastException if the class of the specified element + * is incompatible with this deque (optional) + * @throws NullPointerException if the specified element is null and this + * deque does not permit null elements (optional) + */ + boolean removeFirstOccurrence(Object o); + + /** + * Removes the last occurrence of the specified element from this deque. + * If the deque does not contain the element, it is unchanged. + * More formally, removes the last element <tt>e</tt> such that + * <tt>(o==null ? e==null : o.equals(e))</tt> + * (if such an element exists). + * Returns <tt>true</tt> if this deque contained the specified element + * (or equivalently, if this deque changed as a result of the call). + * + * @param o element to be removed from this deque, if present + * @return <tt>true</tt> if an element was removed as a result of this call + * @throws ClassCastException if the class of the specified element + * is incompatible with this deque (optional) + * @throws NullPointerException if the specified element is null and this + * deque does not permit null elements (optional) + */ + boolean removeLastOccurrence(Object o); + + // *** Queue methods *** + + /** + * Inserts the specified element into the queue represented by this deque + * (in other words, at the tail of this deque) if it is possible to do so + * immediately without violating capacity restrictions, returning + * <tt>true</tt> upon success and throwing an + * <tt>IllegalStateException</tt> if no space is currently available. + * When using a capacity-restricted deque, it is generally preferable to + * use {@link #offer(Object) offer}. + * + * <p>This method is equivalent to {@link #addLast}. + * + * @param e the element to add + * @return <tt>true</tt> (as specified by {@link Collection#add}) + * @throws IllegalStateException if the element cannot be added at this + * time due to capacity restrictions + * @throws ClassCastException if the class of the specified element + * prevents it from being added to this deque + * @throws NullPointerException if the specified element is null and this + * deque does not permit null elements + * @throws IllegalArgumentException if some property of the specified + * element prevents it from being added to this deque + */ + boolean add(E e); + + /** + * Inserts the specified element into the queue represented by this deque + * (in other words, at the tail of this deque) if it is possible to do so + * immediately without violating capacity restrictions, returning + * <tt>true</tt> upon success and <tt>false</tt> if no space is currently + * available. When using a capacity-restricted deque, this method is + * generally preferable to the {@link #add} method, which can fail to + * insert an element only by throwing an exception. + * + * <p>This method is equivalent to {@link #offerLast}. + * + * @param e the element to add + * @return <tt>true</tt> if the element was added to this deque, else + * <tt>false</tt> + * @throws ClassCastException if the class of the specified element + * prevents it from being added to this deque + * @throws NullPointerException if the specified element is null and this + * deque does not permit null elements + * @throws IllegalArgumentException if some property of the specified + * element prevents it from being added to this deque + */ + boolean offer(E e); + + /** + * Retrieves and removes the head of the queue represented by this deque + * (in other words, the first element of this deque). + * This method differs from {@link #poll poll} only in that it throws an + * exception if this deque is empty. + * + * <p>This method is equivalent to {@link #removeFirst()}. + * + * @return the head of the queue represented by this deque + * @throws NoSuchElementException if this deque is empty + */ + E remove(); + + /** + * Retrieves and removes the head of the queue represented by this deque + * (in other words, the first element of this deque), or returns + * <tt>null</tt> if this deque is empty. + * + * <p>This method is equivalent to {@link #pollFirst()}. + * + * @return the first element of this deque, or <tt>null</tt> if + * this deque is empty + */ + E poll(); + + /** + * Retrieves, but does not remove, the head of the queue represented by + * this deque (in other words, the first element of this deque). + * This method differs from {@link #peek peek} only in that it throws an + * exception if this deque is empty. + * + * <p>This method is equivalent to {@link #getFirst()}. + * + * @return the head of the queue represented by this deque + * @throws NoSuchElementException if this deque is empty + */ + E element(); + + /** + * Retrieves, but does not remove, the head of the queue represented by + * this deque (in other words, the first element of this deque), or + * returns <tt>null</tt> if this deque is empty. + * + * <p>This method is equivalent to {@link #peekFirst()}. + * + * @return the head of the queue represented by this deque, or + * <tt>null</tt> if this deque is empty + */ + E peek(); + + + // *** Stack methods *** + + /** + * Pushes an element onto the stack represented by this deque (in other + * words, at the head of this deque) if it is possible to do so + * immediately without violating capacity restrictions, returning + * <tt>true</tt> upon success and throwing an + * <tt>IllegalStateException</tt> if no space is currently available. + * + * <p>This method is equivalent to {@link #addFirst}. + * + * @param e the element to push + * @throws IllegalStateException if the element cannot be added at this + * time due to capacity restrictions + * @throws ClassCastException if the class of the specified element + * prevents it from being added to this deque + * @throws NullPointerException if the specified element is null and this + * deque does not permit null elements + * @throws IllegalArgumentException if some property of the specified + * element prevents it from being added to this deque + */ + void push(E e); + + /** + * Pops an element from the stack represented by this deque. In other + * words, removes and returns the first element of this deque. + * + * <p>This method is equivalent to {@link #removeFirst()}. + * + * @return the element at the front of this deque (which is the top + * of the stack represented by this deque) + * @throws NoSuchElementException if this deque is empty + */ + E pop(); + + + // *** Collection methods *** + + /** + * Removes the first occurrence of the specified element from this deque. + * If the deque does not contain the element, it is unchanged. + * More formally, removes the first element <tt>e</tt> such that + * <tt>(o==null ? e==null : o.equals(e))</tt> + * (if such an element exists). + * Returns <tt>true</tt> if this deque contained the specified element + * (or equivalently, if this deque changed as a result of the call). + * + * <p>This method is equivalent to {@link #removeFirstOccurrence}. + * + * @param o element to be removed from this deque, if present + * @return <tt>true</tt> if an element was removed as a result of this call + * @throws ClassCastException if the class of the specified element + * is incompatible with this deque (optional) + * @throws NullPointerException if the specified element is null and this + * deque does not permit null elements (optional) + */ + boolean remove(Object o); + + /** + * Returns <tt>true</tt> if this deque contains the specified element. + * More formally, returns <tt>true</tt> if and only if this deque contains + * at least one element <tt>e</tt> such that + * <tt>(o==null ? e==null : o.equals(e))</tt>. + * + * @param o element whose presence in this deque is to be tested + * @return <tt>true</tt> if this deque contains the specified element + * @throws ClassCastException if the type of the specified element + * is incompatible with this deque (optional) + * @throws NullPointerException if the specified element is null and this + * deque does not permit null elements (optional) + */ + boolean contains(Object o); + + /** + * Returns the number of elements in this deque. + * + * @return the number of elements in this deque + */ + public int size(); + + /** + * Returns an iterator over the elements in this deque in proper sequence. + * The elements will be returned in order from first (head) to last (tail). + * + * @return an iterator over the elements in this deque in proper sequence + */ + Iterator<E> iterator(); + + /** + * Returns an iterator over the elements in this deque in reverse + * sequential order. The elements will be returned in order from + * last (tail) to first (head). + * + * @return an iterator over the elements in this deque in reverse + * sequence + */ + Iterator<E> descendingIterator(); + +} diff --git a/libjava/classpath/external/jsr166/java/util/NavigableMap.java b/libjava/classpath/external/jsr166/java/util/NavigableMap.java new file mode 100644 index 000000000..a55f84bdd --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/NavigableMap.java @@ -0,0 +1,395 @@ +/* + * Written by Doug Lea and Josh Bloch with assistance from members of JCP + * JSR-166 Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util; + +/** + * A {@link SortedMap} extended with navigation methods returning the + * closest matches for given search targets. Methods + * {@code lowerEntry}, {@code floorEntry}, {@code ceilingEntry}, + * and {@code higherEntry} return {@code Map.Entry} objects + * associated with keys respectively less than, less than or equal, + * greater than or equal, and greater than a given key, returning + * {@code null} if there is no such key. Similarly, methods + * {@code lowerKey}, {@code floorKey}, {@code ceilingKey}, and + * {@code higherKey} return only the associated keys. All of these + * methods are designed for locating, not traversing entries. + * + * <p>A {@code NavigableMap} may be accessed and traversed in either + * ascending or descending key order. The {@code descendingMap} + * method returns a view of the map with the senses of all relational + * and directional methods inverted. The performance of ascending + * operations and views is likely to be faster than that of descending + * ones. Methods {@code subMap}, {@code headMap}, + * and {@code tailMap} differ from the like-named {@code + * SortedMap} methods in accepting additional arguments describing + * whether lower and upper bounds are inclusive versus exclusive. + * Submaps of any {@code NavigableMap} must implement the {@code + * NavigableMap} interface. + * + * <p>This interface additionally defines methods {@code firstEntry}, + * {@code pollFirstEntry}, {@code lastEntry}, and + * {@code pollLastEntry} that return and/or remove the least and + * greatest mappings, if any exist, else returning {@code null}. + * + * <p>Implementations of entry-returning methods are expected to + * return {@code Map.Entry} pairs representing snapshots of mappings + * at the time they were produced, and thus generally do <em>not</em> + * support the optional {@code Entry.setValue} method. Note however + * that it is possible to change mappings in the associated map using + * method {@code put}. + * + * <p>Methods + * {@link #subMap(Object, Object) subMap(K, K)}, + * {@link #headMap(Object) headMap(K)}, and + * {@link #tailMap(Object) tailMap(K)} + * are specified to return {@code SortedMap} to allow existing + * implementations of {@code SortedMap} to be compatibly retrofitted to + * implement {@code NavigableMap}, but extensions and implementations + * of this interface are encouraged to override these methods to return + * {@code NavigableMap}. Similarly, + * {@link #keySet()} can be overriden to return {@code NavigableSet}. + * + * <p>This interface is a member of the + * <a href="{@docRoot}/../technotes/guides/collections/index.html"> + * Java Collections Framework</a>. + * + * @author Doug Lea + * @author Josh Bloch + * @param <K> the type of keys maintained by this map + * @param <V> the type of mapped values + * @since 1.6 + */ +public interface NavigableMap<K,V> extends SortedMap<K,V> { + /** + * Returns a key-value mapping associated with the greatest key + * strictly less than the given key, or {@code null} if there is + * no such key. + * + * @param key the key + * @return an entry with the greatest key less than {@code key}, + * or {@code null} if there is no such key + * @throws ClassCastException if the specified key cannot be compared + * with the keys currently in the map + * @throws NullPointerException if the specified key is null + * and this map does not permit null keys + */ + Map.Entry<K,V> lowerEntry(K key); + + /** + * Returns the greatest key strictly less than the given key, or + * {@code null} if there is no such key. + * + * @param key the key + * @return the greatest key less than {@code key}, + * or {@code null} if there is no such key + * @throws ClassCastException if the specified key cannot be compared + * with the keys currently in the map + * @throws NullPointerException if the specified key is null + * and this map does not permit null keys + */ + K lowerKey(K key); + + /** + * Returns a key-value mapping associated with the greatest key + * less than or equal to the given key, or {@code null} if there + * is no such key. + * + * @param key the key + * @return an entry with the greatest key less than or equal to + * {@code key}, or {@code null} if there is no such key + * @throws ClassCastException if the specified key cannot be compared + * with the keys currently in the map + * @throws NullPointerException if the specified key is null + * and this map does not permit null keys + */ + Map.Entry<K,V> floorEntry(K key); + + /** + * Returns the greatest key less than or equal to the given key, + * or {@code null} if there is no such key. + * + * @param key the key + * @return the greatest key less than or equal to {@code key}, + * or {@code null} if there is no such key + * @throws ClassCastException if the specified key cannot be compared + * with the keys currently in the map + * @throws NullPointerException if the specified key is null + * and this map does not permit null keys + */ + K floorKey(K key); + + /** + * Returns a key-value mapping associated with the least key + * greater than or equal to the given key, or {@code null} if + * there is no such key. + * + * @param key the key + * @return an entry with the least key greater than or equal to + * {@code key}, or {@code null} if there is no such key + * @throws ClassCastException if the specified key cannot be compared + * with the keys currently in the map + * @throws NullPointerException if the specified key is null + * and this map does not permit null keys + */ + Map.Entry<K,V> ceilingEntry(K key); + + /** + * Returns the least key greater than or equal to the given key, + * or {@code null} if there is no such key. + * + * @param key the key + * @return the least key greater than or equal to {@code key}, + * or {@code null} if there is no such key + * @throws ClassCastException if the specified key cannot be compared + * with the keys currently in the map + * @throws NullPointerException if the specified key is null + * and this map does not permit null keys + */ + K ceilingKey(K key); + + /** + * Returns a key-value mapping associated with the least key + * strictly greater than the given key, or {@code null} if there + * is no such key. + * + * @param key the key + * @return an entry with the least key greater than {@code key}, + * or {@code null} if there is no such key + * @throws ClassCastException if the specified key cannot be compared + * with the keys currently in the map + * @throws NullPointerException if the specified key is null + * and this map does not permit null keys + */ + Map.Entry<K,V> higherEntry(K key); + + /** + * Returns the least key strictly greater than the given key, or + * {@code null} if there is no such key. + * + * @param key the key + * @return the least key greater than {@code key}, + * or {@code null} if there is no such key + * @throws ClassCastException if the specified key cannot be compared + * with the keys currently in the map + * @throws NullPointerException if the specified key is null + * and this map does not permit null keys + */ + K higherKey(K key); + + /** + * Returns a key-value mapping associated with the least + * key in this map, or {@code null} if the map is empty. + * + * @return an entry with the least key, + * or {@code null} if this map is empty + */ + Map.Entry<K,V> firstEntry(); + + /** + * Returns a key-value mapping associated with the greatest + * key in this map, or {@code null} if the map is empty. + * + * @return an entry with the greatest key, + * or {@code null} if this map is empty + */ + Map.Entry<K,V> lastEntry(); + + /** + * Removes and returns a key-value mapping associated with + * the least key in this map, or {@code null} if the map is empty. + * + * @return the removed first entry of this map, + * or {@code null} if this map is empty + */ + Map.Entry<K,V> pollFirstEntry(); + + /** + * Removes and returns a key-value mapping associated with + * the greatest key in this map, or {@code null} if the map is empty. + * + * @return the removed last entry of this map, + * or {@code null} if this map is empty + */ + Map.Entry<K,V> pollLastEntry(); + + /** + * Returns a reverse order view of the mappings contained in this map. + * The descending map is backed by this map, so changes to the map are + * reflected in the descending map, and vice-versa. If either map is + * modified while an iteration over a collection view of either map + * is in progress (except through the iterator's own {@code remove} + * operation), the results of the iteration are undefined. + * + * <p>The returned map has an ordering equivalent to + * <tt>{@link Collections#reverseOrder(Comparator) Collections.reverseOrder}(comparator())</tt>. + * The expression {@code m.descendingMap().descendingMap()} returns a + * view of {@code m} essentially equivalent to {@code m}. + * + * @return a reverse order view of this map + */ + NavigableMap<K,V> descendingMap(); + + /** + * Returns a {@link NavigableSet} view of the keys contained in this map. + * The set's iterator returns the keys in ascending order. + * The set is backed by the map, so changes to the map are reflected in + * the set, and vice-versa. If the map is modified while an iteration + * over the set is in progress (except through the iterator's own {@code + * remove} operation), the results of the iteration are undefined. The + * set supports element removal, which removes the corresponding mapping + * from the map, via the {@code Iterator.remove}, {@code Set.remove}, + * {@code removeAll}, {@code retainAll}, and {@code clear} operations. + * It does not support the {@code add} or {@code addAll} operations. + * + * @return a navigable set view of the keys in this map + */ + NavigableSet<K> navigableKeySet(); + + /** + * Returns a reverse order {@link NavigableSet} view of the keys contained in this map. + * The set's iterator returns the keys in descending order. + * The set is backed by the map, so changes to the map are reflected in + * the set, and vice-versa. If the map is modified while an iteration + * over the set is in progress (except through the iterator's own {@code + * remove} operation), the results of the iteration are undefined. The + * set supports element removal, which removes the corresponding mapping + * from the map, via the {@code Iterator.remove}, {@code Set.remove}, + * {@code removeAll}, {@code retainAll}, and {@code clear} operations. + * It does not support the {@code add} or {@code addAll} operations. + * + * @return a reverse order navigable set view of the keys in this map + */ + NavigableSet<K> descendingKeySet(); + + /** + * Returns a view of the portion of this map whose keys range from + * {@code fromKey} to {@code toKey}. If {@code fromKey} and + * {@code toKey} are equal, the returned map is empty unless + * {@code fromExclusive} and {@code toExclusive} are both true. The + * returned map is backed by this map, so changes in the returned map are + * reflected in this map, and vice-versa. The returned map supports all + * optional map operations that this map supports. + * + * <p>The returned map will throw an {@code IllegalArgumentException} + * on an attempt to insert a key outside of its range, or to construct a + * submap either of whose endpoints lie outside its range. + * + * @param fromKey low endpoint of the keys in the returned map + * @param fromInclusive {@code true} if the low endpoint + * is to be included in the returned view + * @param toKey high endpoint of the keys in the returned map + * @param toInclusive {@code true} if the high endpoint + * is to be included in the returned view + * @return a view of the portion of this map whose keys range from + * {@code fromKey} to {@code toKey} + * @throws ClassCastException if {@code fromKey} and {@code toKey} + * cannot be compared to one another using this map's comparator + * (or, if the map has no comparator, using natural ordering). + * Implementations may, but are not required to, throw this + * exception if {@code fromKey} or {@code toKey} + * cannot be compared to keys currently in the map. + * @throws NullPointerException if {@code fromKey} or {@code toKey} + * is null and this map does not permit null keys + * @throws IllegalArgumentException if {@code fromKey} is greater than + * {@code toKey}; or if this map itself has a restricted + * range, and {@code fromKey} or {@code toKey} lies + * outside the bounds of the range + */ + NavigableMap<K,V> subMap(K fromKey, boolean fromInclusive, + K toKey, boolean toInclusive); + + /** + * Returns a view of the portion of this map whose keys are less than (or + * equal to, if {@code inclusive} is true) {@code toKey}. The returned + * map is backed by this map, so changes in the returned map are reflected + * in this map, and vice-versa. The returned map supports all optional + * map operations that this map supports. + * + * <p>The returned map will throw an {@code IllegalArgumentException} + * on an attempt to insert a key outside its range. + * + * @param toKey high endpoint of the keys in the returned map + * @param inclusive {@code true} if the high endpoint + * is to be included in the returned view + * @return a view of the portion of this map whose keys are less than + * (or equal to, if {@code inclusive} is true) {@code toKey} + * @throws ClassCastException if {@code toKey} is not compatible + * with this map's comparator (or, if the map has no comparator, + * if {@code toKey} does not implement {@link Comparable}). + * Implementations may, but are not required to, throw this + * exception if {@code toKey} cannot be compared to keys + * currently in the map. + * @throws NullPointerException if {@code toKey} is null + * and this map does not permit null keys + * @throws IllegalArgumentException if this map itself has a + * restricted range, and {@code toKey} lies outside the + * bounds of the range + */ + NavigableMap<K,V> headMap(K toKey, boolean inclusive); + + /** + * Returns a view of the portion of this map whose keys are greater than (or + * equal to, if {@code inclusive} is true) {@code fromKey}. The returned + * map is backed by this map, so changes in the returned map are reflected + * in this map, and vice-versa. The returned map supports all optional + * map operations that this map supports. + * + * <p>The returned map will throw an {@code IllegalArgumentException} + * on an attempt to insert a key outside its range. + * + * @param fromKey low endpoint of the keys in the returned map + * @param inclusive {@code true} if the low endpoint + * is to be included in the returned view + * @return a view of the portion of this map whose keys are greater than + * (or equal to, if {@code inclusive} is true) {@code fromKey} + * @throws ClassCastException if {@code fromKey} is not compatible + * with this map's comparator (or, if the map has no comparator, + * if {@code fromKey} does not implement {@link Comparable}). + * Implementations may, but are not required to, throw this + * exception if {@code fromKey} cannot be compared to keys + * currently in the map. + * @throws NullPointerException if {@code fromKey} is null + * and this map does not permit null keys + * @throws IllegalArgumentException if this map itself has a + * restricted range, and {@code fromKey} lies outside the + * bounds of the range + */ + NavigableMap<K,V> tailMap(K fromKey, boolean inclusive); + + /** + * {@inheritDoc} + * + * <p>Equivalent to {@code subMap(fromKey, true, toKey, false)}. + * + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + * @throws IllegalArgumentException {@inheritDoc} + */ + SortedMap<K,V> subMap(K fromKey, K toKey); + + /** + * {@inheritDoc} + * + * <p>Equivalent to {@code headMap(toKey, false)}. + * + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + * @throws IllegalArgumentException {@inheritDoc} + */ + SortedMap<K,V> headMap(K toKey); + + /** + * {@inheritDoc} + * + * <p>Equivalent to {@code tailMap(fromKey, true)}. + * + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + * @throws IllegalArgumentException {@inheritDoc} + */ + SortedMap<K,V> tailMap(K fromKey); +} diff --git a/libjava/classpath/external/jsr166/java/util/NavigableSet.java b/libjava/classpath/external/jsr166/java/util/NavigableSet.java new file mode 100644 index 000000000..e14fe347d --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/NavigableSet.java @@ -0,0 +1,290 @@ +/* + * Written by Doug Lea and Josh Bloch with assistance from members of JCP + * JSR-166 Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util; + +/** + * A {@link SortedSet} extended with navigation methods reporting + * closest matches for given search targets. Methods {@code lower}, + * {@code floor}, {@code ceiling}, and {@code higher} return elements + * respectively less than, less than or equal, greater than or equal, + * and greater than a given element, returning {@code null} if there + * is no such element. A {@code NavigableSet} may be accessed and + * traversed in either ascending or descending order. The {@code + * descendingSet} method returns a view of the set with the senses of + * all relational and directional methods inverted. The performance of + * ascending operations and views is likely to be faster than that of + * descending ones. This interface additionally defines methods + * {@code pollFirst} and {@code pollLast} that return and remove the + * lowest and highest element, if one exists, else returning {@code + * null}. Methods {@code subSet}, {@code headSet}, + * and {@code tailSet} differ from the like-named {@code + * SortedSet} methods in accepting additional arguments describing + * whether lower and upper bounds are inclusive versus exclusive. + * Subsets of any {@code NavigableSet} must implement the {@code + * NavigableSet} interface. + * + * <p> The return values of navigation methods may be ambiguous in + * implementations that permit {@code null} elements. However, even + * in this case the result can be disambiguated by checking + * {@code contains(null)}. To avoid such issues, implementations of + * this interface are encouraged to <em>not</em> permit insertion of + * {@code null} elements. (Note that sorted sets of {@link + * Comparable} elements intrinsically do not permit {@code null}.) + * + * <p>Methods + * {@link #subSet(Object, Object) subSet(E, E)}, + * {@link #headSet(Object) headSet(E)}, and + * {@link #tailSet(Object) tailSet(E)} + * are specified to return {@code SortedSet} to allow existing + * implementations of {@code SortedSet} to be compatibly retrofitted to + * implement {@code NavigableSet}, but extensions and implementations + * of this interface are encouraged to override these methods to return + * {@code NavigableSet}. + * + * <p>This interface is a member of the + * <a href="{@docRoot}/../technotes/guides/collections/index.html"> + * Java Collections Framework</a>. + * + * @author Doug Lea + * @author Josh Bloch + * @param <E> the type of elements maintained by this set + * @since 1.6 + */ +public interface NavigableSet<E> extends SortedSet<E> { + /** + * Returns the greatest element in this set strictly less than the + * given element, or {@code null} if there is no such element. + * + * @param e the value to match + * @return the greatest element less than {@code e}, + * or {@code null} if there is no such element + * @throws ClassCastException if the specified element cannot be + * compared with the elements currently in the set + * @throws NullPointerException if the specified element is null + * and this set does not permit null elements + */ + E lower(E e); + + /** + * Returns the greatest element in this set less than or equal to + * the given element, or {@code null} if there is no such element. + * + * @param e the value to match + * @return the greatest element less than or equal to {@code e}, + * or {@code null} if there is no such element + * @throws ClassCastException if the specified element cannot be + * compared with the elements currently in the set + * @throws NullPointerException if the specified element is null + * and this set does not permit null elements + */ + E floor(E e); + + /** + * Returns the least element in this set greater than or equal to + * the given element, or {@code null} if there is no such element. + * + * @param e the value to match + * @return the least element greater than or equal to {@code e}, + * or {@code null} if there is no such element + * @throws ClassCastException if the specified element cannot be + * compared with the elements currently in the set + * @throws NullPointerException if the specified element is null + * and this set does not permit null elements + */ + E ceiling(E e); + + /** + * Returns the least element in this set strictly greater than the + * given element, or {@code null} if there is no such element. + * + * @param e the value to match + * @return the least element greater than {@code e}, + * or {@code null} if there is no such element + * @throws ClassCastException if the specified element cannot be + * compared with the elements currently in the set + * @throws NullPointerException if the specified element is null + * and this set does not permit null elements + */ + E higher(E e); + + /** + * Retrieves and removes the first (lowest) element, + * or returns {@code null} if this set is empty. + * + * @return the first element, or {@code null} if this set is empty + */ + E pollFirst(); + + /** + * Retrieves and removes the last (highest) element, + * or returns {@code null} if this set is empty. + * + * @return the last element, or {@code null} if this set is empty + */ + E pollLast(); + + /** + * Returns an iterator over the elements in this set, in ascending order. + * + * @return an iterator over the elements in this set, in ascending order + */ + Iterator<E> iterator(); + + /** + * Returns a reverse order view of the elements contained in this set. + * The descending set is backed by this set, so changes to the set are + * reflected in the descending set, and vice-versa. If either set is + * modified while an iteration over either set is in progress (except + * through the iterator's own {@code remove} operation), the results of + * the iteration are undefined. + * + * <p>The returned set has an ordering equivalent to + * <tt>{@link Collections#reverseOrder(Comparator) Collections.reverseOrder}(comparator())</tt>. + * The expression {@code s.descendingSet().descendingSet()} returns a + * view of {@code s} essentially equivalent to {@code s}. + * + * @return a reverse order view of this set + */ + NavigableSet<E> descendingSet(); + + /** + * Returns an iterator over the elements in this set, in descending order. + * Equivalent in effect to {@code descendingSet().iterator()}. + * + * @return an iterator over the elements in this set, in descending order + */ + Iterator<E> descendingIterator(); + + /** + * Returns a view of the portion of this set whose elements range from + * {@code fromElement} to {@code toElement}. If {@code fromElement} and + * {@code toElement} are equal, the returned set is empty unless {@code + * fromExclusive} and {@code toExclusive} are both true. The returned set + * is backed by this set, so changes in the returned set are reflected in + * this set, and vice-versa. The returned set supports all optional set + * operations that this set supports. + * + * <p>The returned set will throw an {@code IllegalArgumentException} + * on an attempt to insert an element outside its range. + * + * @param fromElement low endpoint of the returned set + * @param fromInclusive {@code true} if the low endpoint + * is to be included in the returned view + * @param toElement high endpoint of the returned set + * @param toInclusive {@code true} if the high endpoint + * is to be included in the returned view + * @return a view of the portion of this set whose elements range from + * {@code fromElement}, inclusive, to {@code toElement}, exclusive + * @throws ClassCastException if {@code fromElement} and + * {@code toElement} cannot be compared to one another using this + * set's comparator (or, if the set has no comparator, using + * natural ordering). Implementations may, but are not required + * to, throw this exception if {@code fromElement} or + * {@code toElement} cannot be compared to elements currently in + * the set. + * @throws NullPointerException if {@code fromElement} or + * {@code toElement} is null and this set does + * not permit null elements + * @throws IllegalArgumentException if {@code fromElement} is + * greater than {@code toElement}; or if this set itself + * has a restricted range, and {@code fromElement} or + * {@code toElement} lies outside the bounds of the range. + */ + NavigableSet<E> subSet(E fromElement, boolean fromInclusive, + E toElement, boolean toInclusive); + + /** + * Returns a view of the portion of this set whose elements are less than + * (or equal to, if {@code inclusive} is true) {@code toElement}. The + * returned set is backed by this set, so changes in the returned set are + * reflected in this set, and vice-versa. The returned set supports all + * optional set operations that this set supports. + * + * <p>The returned set will throw an {@code IllegalArgumentException} + * on an attempt to insert an element outside its range. + * + * @param toElement high endpoint of the returned set + * @param inclusive {@code true} if the high endpoint + * is to be included in the returned view + * @return a view of the portion of this set whose elements are less than + * (or equal to, if {@code inclusive} is true) {@code toElement} + * @throws ClassCastException if {@code toElement} is not compatible + * with this set's comparator (or, if the set has no comparator, + * if {@code toElement} does not implement {@link Comparable}). + * Implementations may, but are not required to, throw this + * exception if {@code toElement} cannot be compared to elements + * currently in the set. + * @throws NullPointerException if {@code toElement} is null and + * this set does not permit null elements + * @throws IllegalArgumentException if this set itself has a + * restricted range, and {@code toElement} lies outside the + * bounds of the range + */ + NavigableSet<E> headSet(E toElement, boolean inclusive); + + /** + * Returns a view of the portion of this set whose elements are greater + * than (or equal to, if {@code inclusive} is true) {@code fromElement}. + * The returned set is backed by this set, so changes in the returned set + * are reflected in this set, and vice-versa. The returned set supports + * all optional set operations that this set supports. + * + * <p>The returned set will throw an {@code IllegalArgumentException} + * on an attempt to insert an element outside its range. + * + * @param fromElement low endpoint of the returned set + * @param inclusive {@code true} if the low endpoint + * is to be included in the returned view + * @return a view of the portion of this set whose elements are greater + * than or equal to {@code fromElement} + * @throws ClassCastException if {@code fromElement} is not compatible + * with this set's comparator (or, if the set has no comparator, + * if {@code fromElement} does not implement {@link Comparable}). + * Implementations may, but are not required to, throw this + * exception if {@code fromElement} cannot be compared to elements + * currently in the set. + * @throws NullPointerException if {@code fromElement} is null + * and this set does not permit null elements + * @throws IllegalArgumentException if this set itself has a + * restricted range, and {@code fromElement} lies outside the + * bounds of the range + */ + NavigableSet<E> tailSet(E fromElement, boolean inclusive); + + /** + * {@inheritDoc} + * + * <p>Equivalent to {@code subSet(fromElement, true, toElement, false)}. + * + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + * @throws IllegalArgumentException {@inheritDoc} + */ + SortedSet<E> subSet(E fromElement, E toElement); + + /** + * {@inheritDoc} + * + * <p>Equivalent to {@code headSet(toElement, false)}. + * + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + * @throws IllegalArgumentException {@inheritDoc} +na */ + SortedSet<E> headSet(E toElement); + + /** + * {@inheritDoc} + * + * <p>Equivalent to {@code tailSet(fromElement, true)}. + * + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + * @throws IllegalArgumentException {@inheritDoc} + */ + SortedSet<E> tailSet(E fromElement); +} diff --git a/libjava/classpath/external/jsr166/java/util/Queue.java b/libjava/classpath/external/jsr166/java/util/Queue.java new file mode 100644 index 000000000..5711545b0 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/Queue.java @@ -0,0 +1,189 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util; + +/** + * A collection designed for holding elements prior to processing. + * Besides basic {@link java.util.Collection Collection} operations, + * queues provide additional insertion, extraction, and inspection + * operations. Each of these methods exists in two forms: one throws + * an exception if the operation fails, the other returns a special + * value (either <tt>null</tt> or <tt>false</tt>, depending on the + * operation). The latter form of the insert operation is designed + * specifically for use with capacity-restricted <tt>Queue</tt> + * implementations; in most implementations, insert operations cannot + * fail. + * + * <p> + * <table BORDER CELLPADDING=3 CELLSPACING=1> + * <tr> + * <td></td> + * <td ALIGN=CENTER><em>Throws exception</em></td> + * <td ALIGN=CENTER><em>Returns special value</em></td> + * </tr> + * <tr> + * <td><b>Insert</b></td> + * <td>{@link #add add(e)}</td> + * <td>{@link #offer offer(e)}</td> + * </tr> + * <tr> + * <td><b>Remove</b></td> + * <td>{@link #remove remove()}</td> + * <td>{@link #poll poll()}</td> + * </tr> + * <tr> + * <td><b>Examine</b></td> + * <td>{@link #element element()}</td> + * <td>{@link #peek peek()}</td> + * </tr> + * </table> + * + * <p>Queues typically, but do not necessarily, order elements in a + * FIFO (first-in-first-out) manner. Among the exceptions are + * priority queues, which order elements according to a supplied + * comparator, or the elements' natural ordering, and LIFO queues (or + * stacks) which order the elements LIFO (last-in-first-out). + * Whatever the ordering used, the <em>head</em> of the queue is that + * element which would be removed by a call to {@link #remove() } or + * {@link #poll()}. In a FIFO queue, all new elements are inserted at + * the <em> tail</em> of the queue. Other kinds of queues may use + * different placement rules. Every <tt>Queue</tt> implementation + * must specify its ordering properties. + * + * <p>The {@link #offer offer} method inserts an element if possible, + * otherwise returning <tt>false</tt>. This differs from the {@link + * java.util.Collection#add Collection.add} method, which can fail to + * add an element only by throwing an unchecked exception. The + * <tt>offer</tt> method is designed for use when failure is a normal, + * rather than exceptional occurrence, for example, in fixed-capacity + * (or "bounded") queues. + * + * <p>The {@link #remove()} and {@link #poll()} methods remove and + * return the head of the queue. + * Exactly which element is removed from the queue is a + * function of the queue's ordering policy, which differs from + * implementation to implementation. The <tt>remove()</tt> and + * <tt>poll()</tt> methods differ only in their behavior when the + * queue is empty: the <tt>remove()</tt> method throws an exception, + * while the <tt>poll()</tt> method returns <tt>null</tt>. + * + * <p>The {@link #element()} and {@link #peek()} methods return, but do + * not remove, the head of the queue. + * + * <p>The <tt>Queue</tt> interface does not define the <i>blocking queue + * methods</i>, which are common in concurrent programming. These methods, + * which wait for elements to appear or for space to become available, are + * defined in the {@link java.util.concurrent.BlockingQueue} interface, which + * extends this interface. + * + * <p><tt>Queue</tt> implementations generally do not allow insertion + * of <tt>null</tt> elements, although some implementations, such as + * {@link LinkedList}, do not prohibit insertion of <tt>null</tt>. + * Even in the implementations that permit it, <tt>null</tt> should + * not be inserted into a <tt>Queue</tt>, as <tt>null</tt> is also + * used as a special return value by the <tt>poll</tt> method to + * indicate that the queue contains no elements. + * + * <p><tt>Queue</tt> implementations generally do not define + * element-based versions of methods <tt>equals</tt> and + * <tt>hashCode</tt> but instead inherit the identity based versions + * from class <tt>Object</tt>, because element-based equality is not + * always well-defined for queues with the same elements but different + * ordering properties. + * + * + * <p>This interface is a member of the + * <a href="{@docRoot}/../technotes/guides/collections/index.html"> + * Java Collections Framework</a>. + * + * @see java.util.Collection + * @see LinkedList + * @see PriorityQueue + * @see java.util.concurrent.LinkedBlockingQueue + * @see java.util.concurrent.BlockingQueue + * @see java.util.concurrent.ArrayBlockingQueue + * @see java.util.concurrent.LinkedBlockingQueue + * @see java.util.concurrent.PriorityBlockingQueue + * @since 1.5 + * @author Doug Lea + * @param <E> the type of elements held in this collection + */ +public interface Queue<E> extends Collection<E> { + /** + * Inserts the specified element into this queue if it is possible to do so + * immediately without violating capacity restrictions, returning + * <tt>true</tt> upon success and throwing an <tt>IllegalStateException</tt> + * if no space is currently available. + * + * @param e the element to add + * @return <tt>true</tt> (as specified by {@link Collection#add}) + * @throws IllegalStateException if the element cannot be added at this + * time due to capacity restrictions + * @throws ClassCastException if the class of the specified element + * prevents it from being added to this queue + * @throws NullPointerException if the specified element is null and + * this queue does not permit null elements + * @throws IllegalArgumentException if some property of this element + * prevents it from being added to this queue + */ + boolean add(E e); + + /** + * Inserts the specified element into this queue if it is possible to do + * so immediately without violating capacity restrictions. + * When using a capacity-restricted queue, this method is generally + * preferable to {@link #add}, which can fail to insert an element only + * by throwing an exception. + * + * @param e the element to add + * @return <tt>true</tt> if the element was added to this queue, else + * <tt>false</tt> + * @throws ClassCastException if the class of the specified element + * prevents it from being added to this queue + * @throws NullPointerException if the specified element is null and + * this queue does not permit null elements + * @throws IllegalArgumentException if some property of this element + * prevents it from being added to this queue + */ + boolean offer(E e); + + /** + * Retrieves and removes the head of this queue. This method differs + * from {@link #poll poll} only in that it throws an exception if this + * queue is empty. + * + * @return the head of this queue + * @throws NoSuchElementException if this queue is empty + */ + E remove(); + + /** + * Retrieves and removes the head of this queue, + * or returns <tt>null</tt> if this queue is empty. + * + * @return the head of this queue, or <tt>null</tt> if this queue is empty + */ + E poll(); + + /** + * Retrieves, but does not remove, the head of this queue. This method + * differs from {@link #peek peek} only in that it throws an exception + * if this queue is empty. + * + * @return the head of this queue + * @throws NoSuchElementException if this queue is empty + */ + E element(); + + /** + * Retrieves, but does not remove, the head of this queue, + * or returns <tt>null</tt> if this queue is empty. + * + * @return the head of this queue, or <tt>null</tt> if this queue is empty + */ + E peek(); +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/AbstractExecutorService.java b/libjava/classpath/external/jsr166/java/util/concurrent/AbstractExecutorService.java new file mode 100644 index 000000000..ac15c5010 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/AbstractExecutorService.java @@ -0,0 +1,270 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; +import java.util.*; + +/** + * Provides default implementations of {@link ExecutorService} + * execution methods. This class implements the <tt>submit</tt>, + * <tt>invokeAny</tt> and <tt>invokeAll</tt> methods using a + * {@link RunnableFuture} returned by <tt>newTaskFor</tt>, which defaults + * to the {@link FutureTask} class provided in this package. For example, + * the implementation of <tt>submit(Runnable)</tt> creates an + * associated <tt>RunnableFuture</tt> that is executed and + * returned. Subclasses may override the <tt>newTaskFor</tt> methods + * to return <tt>RunnableFuture</tt> implementations other than + * <tt>FutureTask</tt>. + * + * <p> <b>Extension example</b>. Here is a sketch of a class + * that customizes {@link ThreadPoolExecutor} to use + * a <tt>CustomTask</tt> class instead of the default <tt>FutureTask</tt>: + * <pre> + * public class CustomThreadPoolExecutor extends ThreadPoolExecutor { + * + * static class CustomTask<V> implements RunnableFuture<V> {...} + * + * protected <V> RunnableFuture<V> newTaskFor(Callable<V> c) { + * return new CustomTask<V>(c); + * } + * protected <V> RunnableFuture<V> newTaskFor(Runnable r, V v) { + * return new CustomTask<V>(r, v); + * } + * // ... add constructors, etc. + * } + * </pre> + * @since 1.5 + * @author Doug Lea + */ +public abstract class AbstractExecutorService implements ExecutorService { + + /** + * Returns a <tt>RunnableFuture</tt> for the given runnable and default + * value. + * + * @param runnable the runnable task being wrapped + * @param value the default value for the returned future + * @return a <tt>RunnableFuture</tt> which when run will run the + * underlying runnable and which, as a <tt>Future</tt>, will yield + * the given value as its result and provide for cancellation of + * the underlying task. + * @since 1.6 + */ + protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) { + return new FutureTask<T>(runnable, value); + } + + /** + * Returns a <tt>RunnableFuture</tt> for the given callable task. + * + * @param callable the callable task being wrapped + * @return a <tt>RunnableFuture</tt> which when run will call the + * underlying callable and which, as a <tt>Future</tt>, will yield + * the callable's result as its result and provide for + * cancellation of the underlying task. + * @since 1.6 + */ + protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) { + return new FutureTask<T>(callable); + } + + public Future<?> submit(Runnable task) { + if (task == null) throw new NullPointerException(); + RunnableFuture<Object> ftask = newTaskFor(task, null); + execute(ftask); + return ftask; + } + + public <T> Future<T> submit(Runnable task, T result) { + if (task == null) throw new NullPointerException(); + RunnableFuture<T> ftask = newTaskFor(task, result); + execute(ftask); + return ftask; + } + + public <T> Future<T> submit(Callable<T> task) { + if (task == null) throw new NullPointerException(); + RunnableFuture<T> ftask = newTaskFor(task); + execute(ftask); + return ftask; + } + + /** + * the main mechanics of invokeAny. + */ + private <T> T doInvokeAny(Collection<? extends Callable<T>> tasks, + boolean timed, long nanos) + throws InterruptedException, ExecutionException, TimeoutException { + if (tasks == null) + throw new NullPointerException(); + int ntasks = tasks.size(); + if (ntasks == 0) + throw new IllegalArgumentException(); + List<Future<T>> futures= new ArrayList<Future<T>>(ntasks); + ExecutorCompletionService<T> ecs = + new ExecutorCompletionService<T>(this); + + // For efficiency, especially in executors with limited + // parallelism, check to see if previously submitted tasks are + // done before submitting more of them. This interleaving + // plus the exception mechanics account for messiness of main + // loop. + + try { + // Record exceptions so that if we fail to obtain any + // result, we can throw the last exception we got. + ExecutionException ee = null; + long lastTime = (timed)? System.nanoTime() : 0; + Iterator<? extends Callable<T>> it = tasks.iterator(); + + // Start one task for sure; the rest incrementally + futures.add(ecs.submit(it.next())); + --ntasks; + int active = 1; + + for (;;) { + Future<T> f = ecs.poll(); + if (f == null) { + if (ntasks > 0) { + --ntasks; + futures.add(ecs.submit(it.next())); + ++active; + } + else if (active == 0) + break; + else if (timed) { + f = ecs.poll(nanos, TimeUnit.NANOSECONDS); + if (f == null) + throw new TimeoutException(); + long now = System.nanoTime(); + nanos -= now - lastTime; + lastTime = now; + } + else + f = ecs.take(); + } + if (f != null) { + --active; + try { + return f.get(); + } catch (InterruptedException ie) { + throw ie; + } catch (ExecutionException eex) { + ee = eex; + } catch (RuntimeException rex) { + ee = new ExecutionException(rex); + } + } + } + + if (ee == null) + ee = new ExecutionException(); + throw ee; + + } finally { + for (Future<T> f : futures) + f.cancel(true); + } + } + + public <T> T invokeAny(Collection<? extends Callable<T>> tasks) + throws InterruptedException, ExecutionException { + try { + return doInvokeAny(tasks, false, 0); + } catch (TimeoutException cannotHappen) { + assert false; + return null; + } + } + + public <T> T invokeAny(Collection<? extends Callable<T>> tasks, + long timeout, TimeUnit unit) + throws InterruptedException, ExecutionException, TimeoutException { + return doInvokeAny(tasks, true, unit.toNanos(timeout)); + } + + public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) + throws InterruptedException { + if (tasks == null) + throw new NullPointerException(); + List<Future<T>> futures = new ArrayList<Future<T>>(tasks.size()); + boolean done = false; + try { + for (Callable<T> t : tasks) { + RunnableFuture<T> f = newTaskFor(t); + futures.add(f); + execute(f); + } + for (Future<T> f : futures) { + if (!f.isDone()) { + try { + f.get(); + } catch (CancellationException ignore) { + } catch (ExecutionException ignore) { + } + } + } + done = true; + return futures; + } finally { + if (!done) + for (Future<T> f : futures) + f.cancel(true); + } + } + + public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, + long timeout, TimeUnit unit) + throws InterruptedException { + if (tasks == null || unit == null) + throw new NullPointerException(); + long nanos = unit.toNanos(timeout); + List<Future<T>> futures = new ArrayList<Future<T>>(tasks.size()); + boolean done = false; + try { + for (Callable<T> t : tasks) + futures.add(newTaskFor(t)); + + long lastTime = System.nanoTime(); + + // Interleave time checks and calls to execute in case + // executor doesn't have any/much parallelism. + Iterator<Future<T>> it = futures.iterator(); + while (it.hasNext()) { + execute((Runnable)(it.next())); + long now = System.nanoTime(); + nanos -= now - lastTime; + lastTime = now; + if (nanos <= 0) + return futures; + } + + for (Future<T> f : futures) { + if (!f.isDone()) { + if (nanos <= 0) + return futures; + try { + f.get(nanos, TimeUnit.NANOSECONDS); + } catch (CancellationException ignore) { + } catch (ExecutionException ignore) { + } catch (TimeoutException toe) { + return futures; + } + long now = System.nanoTime(); + nanos -= now - lastTime; + lastTime = now; + } + } + done = true; + return futures; + } finally { + if (!done) + for (Future<T> f : futures) + f.cancel(true); + } + } + +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/ArrayBlockingQueue.java b/libjava/classpath/external/jsr166/java/util/concurrent/ArrayBlockingQueue.java new file mode 100644 index 000000000..3ce9ed859 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/ArrayBlockingQueue.java @@ -0,0 +1,778 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; +import java.util.concurrent.locks.*; +import java.util.*; + +/** + * A bounded {@linkplain BlockingQueue blocking queue} backed by an + * array. This queue orders elements FIFO (first-in-first-out). The + * <em>head</em> of the queue is that element that has been on the + * queue the longest time. The <em>tail</em> of the queue is that + * element that has been on the queue the shortest time. New elements + * are inserted at the tail of the queue, and the queue retrieval + * operations obtain elements at the head of the queue. + * + * <p>This is a classic "bounded buffer", in which a + * fixed-sized array holds elements inserted by producers and + * extracted by consumers. Once created, the capacity cannot be + * increased. Attempts to <tt>put</tt> an element into a full queue + * will result in the operation blocking; attempts to <tt>take</tt> an + * element from an empty queue will similarly block. + * + * <p> This class supports an optional fairness policy for ordering + * waiting producer and consumer threads. By default, this ordering + * is not guaranteed. However, a queue constructed with fairness set + * to <tt>true</tt> grants threads access in FIFO order. Fairness + * generally decreases throughput but reduces variability and avoids + * starvation. + * + * <p>This class and its iterator implement all of the + * <em>optional</em> methods of the {@link Collection} and {@link + * Iterator} interfaces. + * + * <p>This class is a member of the + * <a href="{@docRoot}/../technotes/guides/collections/index.html"> + * Java Collections Framework</a>. + * + * @since 1.5 + * @author Doug Lea + * @param <E> the type of elements held in this collection + */ +public class ArrayBlockingQueue<E> extends AbstractQueue<E> + implements BlockingQueue<E>, java.io.Serializable { + + /** + * Serialization ID. This class relies on default serialization + * even for the items array, which is default-serialized, even if + * it is empty. Otherwise it could not be declared final, which is + * necessary here. + */ + private static final long serialVersionUID = -817911632652898426L; + + /** The queued items */ + private final E[] items; + /** items index for next take, poll or remove */ + private int takeIndex; + /** items index for next put, offer, or add. */ + private int putIndex; + /** Number of items in the queue */ + private int count; + + /* + * Concurrency control uses the classic two-condition algorithm + * found in any textbook. + */ + + /** Main lock guarding all access */ + private final ReentrantLock lock; + /** Condition for waiting takes */ + private final Condition notEmpty; + /** Condition for waiting puts */ + private final Condition notFull; + + // Internal helper methods + + /** + * Circularly increment i. + */ + final int inc(int i) { + return (++i == items.length)? 0 : i; + } + + /** + * Inserts element at current put position, advances, and signals. + * Call only when holding lock. + */ + private void insert(E x) { + items[putIndex] = x; + putIndex = inc(putIndex); + ++count; + notEmpty.signal(); + } + + /** + * Extracts element at current take position, advances, and signals. + * Call only when holding lock. + */ + private E extract() { + final E[] items = this.items; + E x = items[takeIndex]; + items[takeIndex] = null; + takeIndex = inc(takeIndex); + --count; + notFull.signal(); + return x; + } + + /** + * Utility for remove and iterator.remove: Delete item at position i. + * Call only when holding lock. + */ + void removeAt(int i) { + final E[] items = this.items; + // if removing front item, just advance + if (i == takeIndex) { + items[takeIndex] = null; + takeIndex = inc(takeIndex); + } else { + // slide over all others up through putIndex. + for (;;) { + int nexti = inc(i); + if (nexti != putIndex) { + items[i] = items[nexti]; + i = nexti; + } else { + items[i] = null; + putIndex = i; + break; + } + } + } + --count; + notFull.signal(); + } + + /** + * Creates an <tt>ArrayBlockingQueue</tt> with the given (fixed) + * capacity and default access policy. + * + * @param capacity the capacity of this queue + * @throws IllegalArgumentException if <tt>capacity</tt> is less than 1 + */ + public ArrayBlockingQueue(int capacity) { + this(capacity, false); + } + + /** + * Creates an <tt>ArrayBlockingQueue</tt> with the given (fixed) + * capacity and the specified access policy. + * + * @param capacity the capacity of this queue + * @param fair if <tt>true</tt> then queue accesses for threads blocked + * on insertion or removal, are processed in FIFO order; + * if <tt>false</tt> the access order is unspecified. + * @throws IllegalArgumentException if <tt>capacity</tt> is less than 1 + */ + public ArrayBlockingQueue(int capacity, boolean fair) { + if (capacity <= 0) + throw new IllegalArgumentException(); + this.items = (E[]) new Object[capacity]; + lock = new ReentrantLock(fair); + notEmpty = lock.newCondition(); + notFull = lock.newCondition(); + } + + /** + * Creates an <tt>ArrayBlockingQueue</tt> with the given (fixed) + * capacity, the specified access policy and initially containing the + * elements of the given collection, + * added in traversal order of the collection's iterator. + * + * @param capacity the capacity of this queue + * @param fair if <tt>true</tt> then queue accesses for threads blocked + * on insertion or removal, are processed in FIFO order; + * if <tt>false</tt> the access order is unspecified. + * @param c the collection of elements to initially contain + * @throws IllegalArgumentException if <tt>capacity</tt> is less than + * <tt>c.size()</tt>, or less than 1. + * @throws NullPointerException if the specified collection or any + * of its elements are null + */ + public ArrayBlockingQueue(int capacity, boolean fair, + Collection<? extends E> c) { + this(capacity, fair); + if (capacity < c.size()) + throw new IllegalArgumentException(); + + for (Iterator<? extends E> it = c.iterator(); it.hasNext();) + add(it.next()); + } + + /** + * Inserts the specified element at the tail of this queue if it is + * possible to do so immediately without exceeding the queue's capacity, + * returning <tt>true</tt> upon success and throwing an + * <tt>IllegalStateException</tt> if this queue is full. + * + * @param e the element to add + * @return <tt>true</tt> (as specified by {@link Collection#add}) + * @throws IllegalStateException if this queue is full + * @throws NullPointerException if the specified element is null + */ + public boolean add(E e) { + return super.add(e); + } + + /** + * Inserts the specified element at the tail of this queue if it is + * possible to do so immediately without exceeding the queue's capacity, + * returning <tt>true</tt> upon success and <tt>false</tt> if this queue + * is full. This method is generally preferable to method {@link #add}, + * which can fail to insert an element only by throwing an exception. + * + * @throws NullPointerException if the specified element is null + */ + public boolean offer(E e) { + if (e == null) throw new NullPointerException(); + final ReentrantLock lock = this.lock; + lock.lock(); + try { + if (count == items.length) + return false; + else { + insert(e); + return true; + } + } finally { + lock.unlock(); + } + } + + /** + * Inserts the specified element at the tail of this queue, waiting + * for space to become available if the queue is full. + * + * @throws InterruptedException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + */ + public void put(E e) throws InterruptedException { + if (e == null) throw new NullPointerException(); + final E[] items = this.items; + final ReentrantLock lock = this.lock; + lock.lockInterruptibly(); + try { + try { + while (count == items.length) + notFull.await(); + } catch (InterruptedException ie) { + notFull.signal(); // propagate to non-interrupted thread + throw ie; + } + insert(e); + } finally { + lock.unlock(); + } + } + + /** + * Inserts the specified element at the tail of this queue, waiting + * up to the specified wait time for space to become available if + * the queue is full. + * + * @throws InterruptedException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + */ + public boolean offer(E e, long timeout, TimeUnit unit) + throws InterruptedException { + + if (e == null) throw new NullPointerException(); + long nanos = unit.toNanos(timeout); + final ReentrantLock lock = this.lock; + lock.lockInterruptibly(); + try { + for (;;) { + if (count != items.length) { + insert(e); + return true; + } + if (nanos <= 0) + return false; + try { + nanos = notFull.awaitNanos(nanos); + } catch (InterruptedException ie) { + notFull.signal(); // propagate to non-interrupted thread + throw ie; + } + } + } finally { + lock.unlock(); + } + } + + public E poll() { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + if (count == 0) + return null; + E x = extract(); + return x; + } finally { + lock.unlock(); + } + } + + public E take() throws InterruptedException { + final ReentrantLock lock = this.lock; + lock.lockInterruptibly(); + try { + try { + while (count == 0) + notEmpty.await(); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + E x = extract(); + return x; + } finally { + lock.unlock(); + } + } + + public E poll(long timeout, TimeUnit unit) throws InterruptedException { + long nanos = unit.toNanos(timeout); + final ReentrantLock lock = this.lock; + lock.lockInterruptibly(); + try { + for (;;) { + if (count != 0) { + E x = extract(); + return x; + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + public E peek() { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + return (count == 0) ? null : items[takeIndex]; + } finally { + lock.unlock(); + } + } + + // this doc comment is overridden to remove the reference to collections + // greater in size than Integer.MAX_VALUE + /** + * Returns the number of elements in this queue. + * + * @return the number of elements in this queue + */ + public int size() { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + return count; + } finally { + lock.unlock(); + } + } + + // this doc comment is a modified copy of the inherited doc comment, + // without the reference to unlimited queues. + /** + * Returns the number of additional elements that this queue can ideally + * (in the absence of memory or resource constraints) accept without + * blocking. This is always equal to the initial capacity of this queue + * less the current <tt>size</tt> of this queue. + * + * <p>Note that you <em>cannot</em> always tell if an attempt to insert + * an element will succeed by inspecting <tt>remainingCapacity</tt> + * because it may be the case that another thread is about to + * insert or remove an element. + */ + public int remainingCapacity() { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + return items.length - count; + } finally { + lock.unlock(); + } + } + + /** + * Removes a single instance of the specified element from this queue, + * if it is present. More formally, removes an element <tt>e</tt> such + * that <tt>o.equals(e)</tt>, if this queue contains one or more such + * elements. + * Returns <tt>true</tt> if this queue contained the specified element + * (or equivalently, if this queue changed as a result of the call). + * + * @param o element to be removed from this queue, if present + * @return <tt>true</tt> if this queue changed as a result of the call + */ + public boolean remove(Object o) { + if (o == null) return false; + final E[] items = this.items; + final ReentrantLock lock = this.lock; + lock.lock(); + try { + int i = takeIndex; + int k = 0; + for (;;) { + if (k++ >= count) + return false; + if (o.equals(items[i])) { + removeAt(i); + return true; + } + i = inc(i); + } + + } finally { + lock.unlock(); + } + } + + /** + * Returns <tt>true</tt> if this queue contains the specified element. + * More formally, returns <tt>true</tt> if and only if this queue contains + * at least one element <tt>e</tt> such that <tt>o.equals(e)</tt>. + * + * @param o object to be checked for containment in this queue + * @return <tt>true</tt> if this queue contains the specified element + */ + public boolean contains(Object o) { + if (o == null) return false; + final E[] items = this.items; + final ReentrantLock lock = this.lock; + lock.lock(); + try { + int i = takeIndex; + int k = 0; + while (k++ < count) { + if (o.equals(items[i])) + return true; + i = inc(i); + } + return false; + } finally { + lock.unlock(); + } + } + + /** + * Returns an array containing all of the elements in this queue, in + * proper sequence. + * + * <p>The returned array will be "safe" in that no references to it are + * maintained by this queue. (In other words, this method must allocate + * a new array). The caller is thus free to modify the returned array. + * + * <p>This method acts as bridge between array-based and collection-based + * APIs. + * + * @return an array containing all of the elements in this queue + */ + public Object[] toArray() { + final E[] items = this.items; + final ReentrantLock lock = this.lock; + lock.lock(); + try { + Object[] a = new Object[count]; + int k = 0; + int i = takeIndex; + while (k < count) { + a[k++] = items[i]; + i = inc(i); + } + return a; + } finally { + lock.unlock(); + } + } + + /** + * Returns an array containing all of the elements in this queue, in + * proper sequence; the runtime type of the returned array is that of + * the specified array. If the queue fits in the specified array, it + * is returned therein. Otherwise, a new array is allocated with the + * runtime type of the specified array and the size of this queue. + * + * <p>If this queue fits in the specified array with room to spare + * (i.e., the array has more elements than this queue), the element in + * the array immediately following the end of the queue is set to + * <tt>null</tt>. + * + * <p>Like the {@link #toArray()} method, this method acts as bridge between + * array-based and collection-based APIs. Further, this method allows + * precise control over the runtime type of the output array, and may, + * under certain circumstances, be used to save allocation costs. + * + * <p>Suppose <tt>x</tt> is a queue known to contain only strings. + * The following code can be used to dump the queue into a newly + * allocated array of <tt>String</tt>: + * + * <pre> + * String[] y = x.toArray(new String[0]);</pre> + * + * Note that <tt>toArray(new Object[0])</tt> is identical in function to + * <tt>toArray()</tt>. + * + * @param a the array into which the elements of the queue are to + * be stored, if it is big enough; otherwise, a new array of the + * same runtime type is allocated for this purpose + * @return an array containing all of the elements in this queue + * @throws ArrayStoreException if the runtime type of the specified array + * is not a supertype of the runtime type of every element in + * this queue + * @throws NullPointerException if the specified array is null + */ + public <T> T[] toArray(T[] a) { + final E[] items = this.items; + final ReentrantLock lock = this.lock; + lock.lock(); + try { + if (a.length < count) + a = (T[])java.lang.reflect.Array.newInstance( + a.getClass().getComponentType(), + count + ); + + int k = 0; + int i = takeIndex; + while (k < count) { + a[k++] = (T)items[i]; + i = inc(i); + } + if (a.length > count) + a[count] = null; + return a; + } finally { + lock.unlock(); + } + } + + public String toString() { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + return super.toString(); + } finally { + lock.unlock(); + } + } + + /** + * Atomically removes all of the elements from this queue. + * The queue will be empty after this call returns. + */ + public void clear() { + final E[] items = this.items; + final ReentrantLock lock = this.lock; + lock.lock(); + try { + int i = takeIndex; + int k = count; + while (k-- > 0) { + items[i] = null; + i = inc(i); + } + count = 0; + putIndex = 0; + takeIndex = 0; + notFull.signalAll(); + } finally { + lock.unlock(); + } + } + + /** + * @throws UnsupportedOperationException {@inheritDoc} + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + * @throws IllegalArgumentException {@inheritDoc} + */ + public int drainTo(Collection<? super E> c) { + if (c == null) + throw new NullPointerException(); + if (c == this) + throw new IllegalArgumentException(); + final E[] items = this.items; + final ReentrantLock lock = this.lock; + lock.lock(); + try { + int i = takeIndex; + int n = 0; + int max = count; + while (n < max) { + c.add(items[i]); + items[i] = null; + i = inc(i); + ++n; + } + if (n > 0) { + count = 0; + putIndex = 0; + takeIndex = 0; + notFull.signalAll(); + } + return n; + } finally { + lock.unlock(); + } + } + + /** + * @throws UnsupportedOperationException {@inheritDoc} + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + * @throws IllegalArgumentException {@inheritDoc} + */ + public int drainTo(Collection<? super E> c, int maxElements) { + if (c == null) + throw new NullPointerException(); + if (c == this) + throw new IllegalArgumentException(); + if (maxElements <= 0) + return 0; + final E[] items = this.items; + final ReentrantLock lock = this.lock; + lock.lock(); + try { + int i = takeIndex; + int n = 0; + int sz = count; + int max = (maxElements < count)? maxElements : count; + while (n < max) { + c.add(items[i]); + items[i] = null; + i = inc(i); + ++n; + } + if (n > 0) { + count -= n; + takeIndex = i; + notFull.signalAll(); + } + return n; + } finally { + lock.unlock(); + } + } + + + /** + * Returns an iterator over the elements in this queue in proper sequence. + * The returned <tt>Iterator</tt> is a "weakly consistent" iterator that + * will never throw {@link ConcurrentModificationException}, + * and guarantees to traverse elements as they existed upon + * construction of the iterator, and may (but is not guaranteed to) + * reflect any modifications subsequent to construction. + * + * @return an iterator over the elements in this queue in proper sequence + */ + public Iterator<E> iterator() { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + return new Itr(); + } finally { + lock.unlock(); + } + } + + /** + * Iterator for ArrayBlockingQueue + */ + private class Itr implements Iterator<E> { + /** + * Index of element to be returned by next, + * or a negative number if no such. + */ + private int nextIndex; + + /** + * nextItem holds on to item fields because once we claim + * that an element exists in hasNext(), we must return it in + * the following next() call even if it was in the process of + * being removed when hasNext() was called. + */ + private E nextItem; + + /** + * Index of element returned by most recent call to next. + * Reset to -1 if this element is deleted by a call to remove. + */ + private int lastRet; + + Itr() { + lastRet = -1; + if (count == 0) + nextIndex = -1; + else { + nextIndex = takeIndex; + nextItem = items[takeIndex]; + } + } + + public boolean hasNext() { + /* + * No sync. We can return true by mistake here + * only if this iterator passed across threads, + * which we don't support anyway. + */ + return nextIndex >= 0; + } + + /** + * Checks whether nextIndex is valid; if so setting nextItem. + * Stops iterator when either hits putIndex or sees null item. + */ + private void checkNext() { + if (nextIndex == putIndex) { + nextIndex = -1; + nextItem = null; + } else { + nextItem = items[nextIndex]; + if (nextItem == null) + nextIndex = -1; + } + } + + public E next() { + final ReentrantLock lock = ArrayBlockingQueue.this.lock; + lock.lock(); + try { + if (nextIndex < 0) + throw new NoSuchElementException(); + lastRet = nextIndex; + E x = nextItem; + nextIndex = inc(nextIndex); + checkNext(); + return x; + } finally { + lock.unlock(); + } + } + + public void remove() { + final ReentrantLock lock = ArrayBlockingQueue.this.lock; + lock.lock(); + try { + int i = lastRet; + if (i == -1) + throw new IllegalStateException(); + lastRet = -1; + + int ti = takeIndex; + removeAt(i); + // back up cursor (reset to front if was first element) + nextIndex = (i == ti) ? takeIndex : i; + checkNext(); + } finally { + lock.unlock(); + } + } + } +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/BlockingDeque.java b/libjava/classpath/external/jsr166/java/util/concurrent/BlockingDeque.java new file mode 100644 index 000000000..d77a96555 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/BlockingDeque.java @@ -0,0 +1,613 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; +import java.util.*; + +/** + * A {@link Deque} that additionally supports blocking operations that wait + * for the deque to become non-empty when retrieving an element, and wait for + * space to become available in the deque when storing an element. + * + * <p><tt>BlockingDeque</tt> methods come in four forms, with different ways + * of handling operations that cannot be satisfied immediately, but may be + * satisfied at some point in the future: + * one throws an exception, the second returns a special value (either + * <tt>null</tt> or <tt>false</tt>, depending on the operation), the third + * blocks the current thread indefinitely until the operation can succeed, + * and the fourth blocks for only a given maximum time limit before giving + * up. These methods are summarized in the following table: + * + * <p> + * <table BORDER CELLPADDING=3 CELLSPACING=1> + * <tr> + * <td ALIGN=CENTER COLSPAN = 5> <b>First Element (Head)</b></td> + * </tr> + * <tr> + * <td></td> + * <td ALIGN=CENTER><em>Throws exception</em></td> + * <td ALIGN=CENTER><em>Special value</em></td> + * <td ALIGN=CENTER><em>Blocks</em></td> + * <td ALIGN=CENTER><em>Times out</em></td> + * </tr> + * <tr> + * <td><b>Insert</b></td> + * <td>{@link #addFirst addFirst(e)}</td> + * <td>{@link #offerFirst(Object) offerFirst(e)}</td> + * <td>{@link #putFirst putFirst(e)}</td> + * <td>{@link #offerFirst(Object, long, TimeUnit) offerFirst(e, time, unit)}</td> + * </tr> + * <tr> + * <td><b>Remove</b></td> + * <td>{@link #removeFirst removeFirst()}</td> + * <td>{@link #pollFirst pollFirst()}</td> + * <td>{@link #takeFirst takeFirst()}</td> + * <td>{@link #pollFirst(long, TimeUnit) pollFirst(time, unit)}</td> + * </tr> + * <tr> + * <td><b>Examine</b></td> + * <td>{@link #getFirst getFirst()}</td> + * <td>{@link #peekFirst peekFirst()}</td> + * <td><em>not applicable</em></td> + * <td><em>not applicable</em></td> + * </tr> + * <tr> + * <td ALIGN=CENTER COLSPAN = 5> <b>Last Element (Tail)</b></td> + * </tr> + * <tr> + * <td></td> + * <td ALIGN=CENTER><em>Throws exception</em></td> + * <td ALIGN=CENTER><em>Special value</em></td> + * <td ALIGN=CENTER><em>Blocks</em></td> + * <td ALIGN=CENTER><em>Times out</em></td> + * </tr> + * <tr> + * <td><b>Insert</b></td> + * <td>{@link #addLast addLast(e)}</td> + * <td>{@link #offerLast(Object) offerLast(e)}</td> + * <td>{@link #putLast putLast(e)}</td> + * <td>{@link #offerLast(Object, long, TimeUnit) offerLast(e, time, unit)}</td> + * </tr> + * <tr> + * <td><b>Remove</b></td> + * <td>{@link #removeLast() removeLast()}</td> + * <td>{@link #pollLast() pollLast()}</td> + * <td>{@link #takeLast takeLast()}</td> + * <td>{@link #pollLast(long, TimeUnit) pollLast(time, unit)}</td> + * </tr> + * <tr> + * <td><b>Examine</b></td> + * <td>{@link #getLast getLast()}</td> + * <td>{@link #peekLast peekLast()}</td> + * <td><em>not applicable</em></td> + * <td><em>not applicable</em></td> + * </tr> + * </table> + * + * <p>Like any {@link BlockingQueue}, a <tt>BlockingDeque</tt> is thread safe, + * does not permit null elements, and may (or may not) be + * capacity-constrained. + * + * <p>A <tt>BlockingDeque</tt> implementation may be used directly as a FIFO + * <tt>BlockingQueue</tt>. The methods inherited from the + * <tt>BlockingQueue</tt> interface are precisely equivalent to + * <tt>BlockingDeque</tt> methods as indicated in the following table: + * + * <p> + * <table BORDER CELLPADDING=3 CELLSPACING=1> + * <tr> + * <td ALIGN=CENTER> <b><tt>BlockingQueue</tt> Method</b></td> + * <td ALIGN=CENTER> <b>Equivalent <tt>BlockingDeque</tt> Method</b></td> + * </tr> + * <tr> + * <td ALIGN=CENTER COLSPAN = 2> <b>Insert</b></td> + * </tr> + * <tr> + * <td>{@link #add(Object) add(e)}</td> + * <td>{@link #addLast(Object) addLast(e)}</td> + * </tr> + * <tr> + * <td>{@link #offer(Object) offer(e)}</td> + * <td>{@link #offerLast(Object) offerLast(e)}</td> + * </tr> + * <tr> + * <td>{@link #put(Object) put(e)}</td> + * <td>{@link #putLast(Object) putLast(e)}</td> + * </tr> + * <tr> + * <td>{@link #offer(Object, long, TimeUnit) offer(e, time, unit)}</td> + * <td>{@link #offerLast(Object, long, TimeUnit) offerLast(e, time, unit)}</td> + * </tr> + * <tr> + * <td ALIGN=CENTER COLSPAN = 2> <b>Remove</b></td> + * </tr> + * <tr> + * <td>{@link #remove() remove()}</td> + * <td>{@link #removeFirst() removeFirst()}</td> + * </tr> + * <tr> + * <td>{@link #poll() poll()}</td> + * <td>{@link #pollFirst() pollFirst()}</td> + * </tr> + * <tr> + * <td>{@link #take() take()}</td> + * <td>{@link #takeFirst() takeFirst()}</td> + * </tr> + * <tr> + * <td>{@link #poll(long, TimeUnit) poll(time, unit)}</td> + * <td>{@link #pollFirst(long, TimeUnit) pollFirst(time, unit)}</td> + * </tr> + * <tr> + * <td ALIGN=CENTER COLSPAN = 2> <b>Examine</b></td> + * </tr> + * <tr> + * <td>{@link #element() element()}</td> + * <td>{@link #getFirst() getFirst()}</td> + * </tr> + * <tr> + * <td>{@link #peek() peek()}</td> + * <td>{@link #peekFirst() peekFirst()}</td> + * </tr> + * </table> + * + * <p>Memory consistency effects: As with other concurrent + * collections, actions in a thread prior to placing an object into a + * {@code BlockingDeque} + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a> + * actions subsequent to the access or removal of that element from + * the {@code BlockingDeque} in another thread. + * + * <p>This interface is a member of the + * <a href="{@docRoot}/../technotes/guides/collections/index.html"> + * Java Collections Framework</a>. + * + * @since 1.6 + * @author Doug Lea + * @param <E> the type of elements held in this collection + */ +public interface BlockingDeque<E> extends BlockingQueue<E>, Deque<E> { + /* + * We have "diamond" multiple interface inheritance here, and that + * introduces ambiguities. Methods might end up with different + * specs depending on the branch chosen by javadoc. Thus a lot of + * methods specs here are copied from superinterfaces. + */ + + /** + * Inserts the specified element at the front of this deque if it is + * possible to do so immediately without violating capacity restrictions, + * throwing an <tt>IllegalStateException</tt> if no space is currently + * available. When using a capacity-restricted deque, it is generally + * preferable to use {@link #offerFirst(Object) offerFirst}. + * + * @param e the element to add + * @throws IllegalStateException {@inheritDoc} + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException if the specified element is null + * @throws IllegalArgumentException {@inheritDoc} + */ + void addFirst(E e); + + /** + * Inserts the specified element at the end of this deque if it is + * possible to do so immediately without violating capacity restrictions, + * throwing an <tt>IllegalStateException</tt> if no space is currently + * available. When using a capacity-restricted deque, it is generally + * preferable to use {@link #offerLast(Object) offerLast}. + * + * @param e the element to add + * @throws IllegalStateException {@inheritDoc} + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException if the specified element is null + * @throws IllegalArgumentException {@inheritDoc} + */ + void addLast(E e); + + /** + * Inserts the specified element at the front of this deque if it is + * possible to do so immediately without violating capacity restrictions, + * returning <tt>true</tt> upon success and <tt>false</tt> if no space is + * currently available. + * When using a capacity-restricted deque, this method is generally + * preferable to the {@link #addFirst(Object) addFirst} method, which can + * fail to insert an element only by throwing an exception. + * + * @param e the element to add + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException if the specified element is null + * @throws IllegalArgumentException {@inheritDoc} + */ + boolean offerFirst(E e); + + /** + * Inserts the specified element at the end of this deque if it is + * possible to do so immediately without violating capacity restrictions, + * returning <tt>true</tt> upon success and <tt>false</tt> if no space is + * currently available. + * When using a capacity-restricted deque, this method is generally + * preferable to the {@link #addLast(Object) addLast} method, which can + * fail to insert an element only by throwing an exception. + * + * @param e the element to add + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException if the specified element is null + * @throws IllegalArgumentException {@inheritDoc} + */ + boolean offerLast(E e); + + /** + * Inserts the specified element at the front of this deque, + * waiting if necessary for space to become available. + * + * @param e the element to add + * @throws InterruptedException if interrupted while waiting + * @throws ClassCastException if the class of the specified element + * prevents it from being added to this deque + * @throws NullPointerException if the specified element is null + * @throws IllegalArgumentException if some property of the specified + * element prevents it from being added to this deque + */ + void putFirst(E e) throws InterruptedException; + + /** + * Inserts the specified element at the end of this deque, + * waiting if necessary for space to become available. + * + * @param e the element to add + * @throws InterruptedException if interrupted while waiting + * @throws ClassCastException if the class of the specified element + * prevents it from being added to this deque + * @throws NullPointerException if the specified element is null + * @throws IllegalArgumentException if some property of the specified + * element prevents it from being added to this deque + */ + void putLast(E e) throws InterruptedException; + + /** + * Inserts the specified element at the front of this deque, + * waiting up to the specified wait time if necessary for space to + * become available. + * + * @param e the element to add + * @param timeout how long to wait before giving up, in units of + * <tt>unit</tt> + * @param unit a <tt>TimeUnit</tt> determining how to interpret the + * <tt>timeout</tt> parameter + * @return <tt>true</tt> if successful, or <tt>false</tt> if + * the specified waiting time elapses before space is available + * @throws InterruptedException if interrupted while waiting + * @throws ClassCastException if the class of the specified element + * prevents it from being added to this deque + * @throws NullPointerException if the specified element is null + * @throws IllegalArgumentException if some property of the specified + * element prevents it from being added to this deque + */ + boolean offerFirst(E e, long timeout, TimeUnit unit) + throws InterruptedException; + + /** + * Inserts the specified element at the end of this deque, + * waiting up to the specified wait time if necessary for space to + * become available. + * + * @param e the element to add + * @param timeout how long to wait before giving up, in units of + * <tt>unit</tt> + * @param unit a <tt>TimeUnit</tt> determining how to interpret the + * <tt>timeout</tt> parameter + * @return <tt>true</tt> if successful, or <tt>false</tt> if + * the specified waiting time elapses before space is available + * @throws InterruptedException if interrupted while waiting + * @throws ClassCastException if the class of the specified element + * prevents it from being added to this deque + * @throws NullPointerException if the specified element is null + * @throws IllegalArgumentException if some property of the specified + * element prevents it from being added to this deque + */ + boolean offerLast(E e, long timeout, TimeUnit unit) + throws InterruptedException; + + /** + * Retrieves and removes the first element of this deque, waiting + * if necessary until an element becomes available. + * + * @return the head of this deque + * @throws InterruptedException if interrupted while waiting + */ + E takeFirst() throws InterruptedException; + + /** + * Retrieves and removes the last element of this deque, waiting + * if necessary until an element becomes available. + * + * @return the tail of this deque + * @throws InterruptedException if interrupted while waiting + */ + E takeLast() throws InterruptedException; + + /** + * Retrieves and removes the first element of this deque, waiting + * up to the specified wait time if necessary for an element to + * become available. + * + * @param timeout how long to wait before giving up, in units of + * <tt>unit</tt> + * @param unit a <tt>TimeUnit</tt> determining how to interpret the + * <tt>timeout</tt> parameter + * @return the head of this deque, or <tt>null</tt> if the specified + * waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + E pollFirst(long timeout, TimeUnit unit) + throws InterruptedException; + + /** + * Retrieves and removes the last element of this deque, waiting + * up to the specified wait time if necessary for an element to + * become available. + * + * @param timeout how long to wait before giving up, in units of + * <tt>unit</tt> + * @param unit a <tt>TimeUnit</tt> determining how to interpret the + * <tt>timeout</tt> parameter + * @return the tail of this deque, or <tt>null</tt> if the specified + * waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + E pollLast(long timeout, TimeUnit unit) + throws InterruptedException; + + /** + * Removes the first occurrence of the specified element from this deque. + * If the deque does not contain the element, it is unchanged. + * More formally, removes the first element <tt>e</tt> such that + * <tt>o.equals(e)</tt> (if such an element exists). + * Returns <tt>true</tt> if this deque contained the specified element + * (or equivalently, if this deque changed as a result of the call). + * + * @param o element to be removed from this deque, if present + * @return <tt>true</tt> if an element was removed as a result of this call + * @throws ClassCastException if the class of the specified element + * is incompatible with this deque (optional) + * @throws NullPointerException if the specified element is null (optional) + */ + boolean removeFirstOccurrence(Object o); + + /** + * Removes the last occurrence of the specified element from this deque. + * If the deque does not contain the element, it is unchanged. + * More formally, removes the last element <tt>e</tt> such that + * <tt>o.equals(e)</tt> (if such an element exists). + * Returns <tt>true</tt> if this deque contained the specified element + * (or equivalently, if this deque changed as a result of the call). + * + * @param o element to be removed from this deque, if present + * @return <tt>true</tt> if an element was removed as a result of this call + * @throws ClassCastException if the class of the specified element + * is incompatible with this deque (optional) + * @throws NullPointerException if the specified element is null (optional) + */ + boolean removeLastOccurrence(Object o); + + // *** BlockingQueue methods *** + + /** + * Inserts the specified element into the queue represented by this deque + * (in other words, at the tail of this deque) if it is possible to do so + * immediately without violating capacity restrictions, returning + * <tt>true</tt> upon success and throwing an + * <tt>IllegalStateException</tt> if no space is currently available. + * When using a capacity-restricted deque, it is generally preferable to + * use {@link #offer(Object) offer}. + * + * <p>This method is equivalent to {@link #addLast(Object) addLast}. + * + * @param e the element to add + * @throws IllegalStateException {@inheritDoc} + * @throws ClassCastException if the class of the specified element + * prevents it from being added to this deque + * @throws NullPointerException if the specified element is null + * @throws IllegalArgumentException if some property of the specified + * element prevents it from being added to this deque + */ + boolean add(E e); + + /** + * Inserts the specified element into the queue represented by this deque + * (in other words, at the tail of this deque) if it is possible to do so + * immediately without violating capacity restrictions, returning + * <tt>true</tt> upon success and <tt>false</tt> if no space is currently + * available. When using a capacity-restricted deque, this method is + * generally preferable to the {@link #add} method, which can fail to + * insert an element only by throwing an exception. + * + * <p>This method is equivalent to {@link #offerLast(Object) offerLast}. + * + * @param e the element to add + * @throws ClassCastException if the class of the specified element + * prevents it from being added to this deque + * @throws NullPointerException if the specified element is null + * @throws IllegalArgumentException if some property of the specified + * element prevents it from being added to this deque + */ + boolean offer(E e); + + /** + * Inserts the specified element into the queue represented by this deque + * (in other words, at the tail of this deque), waiting if necessary for + * space to become available. + * + * <p>This method is equivalent to {@link #putLast(Object) putLast}. + * + * @param e the element to add + * @throws InterruptedException {@inheritDoc} + * @throws ClassCastException if the class of the specified element + * prevents it from being added to this deque + * @throws NullPointerException if the specified element is null + * @throws IllegalArgumentException if some property of the specified + * element prevents it from being added to this deque + */ + void put(E e) throws InterruptedException; + + /** + * Inserts the specified element into the queue represented by this deque + * (in other words, at the tail of this deque), waiting up to the + * specified wait time if necessary for space to become available. + * + * <p>This method is equivalent to + * {@link #offerLast(Object,long,TimeUnit) offerLast}. + * + * @param e the element to add + * @return <tt>true</tt> if the element was added to this deque, else + * <tt>false</tt> + * @throws InterruptedException {@inheritDoc} + * @throws ClassCastException if the class of the specified element + * prevents it from being added to this deque + * @throws NullPointerException if the specified element is null + * @throws IllegalArgumentException if some property of the specified + * element prevents it from being added to this deque + */ + boolean offer(E e, long timeout, TimeUnit unit) + throws InterruptedException; + + /** + * Retrieves and removes the head of the queue represented by this deque + * (in other words, the first element of this deque). + * This method differs from {@link #poll poll} only in that it + * throws an exception if this deque is empty. + * + * <p>This method is equivalent to {@link #removeFirst() removeFirst}. + * + * @return the head of the queue represented by this deque + * @throws NoSuchElementException if this deque is empty + */ + E remove(); + + /** + * Retrieves and removes the head of the queue represented by this deque + * (in other words, the first element of this deque), or returns + * <tt>null</tt> if this deque is empty. + * + * <p>This method is equivalent to {@link #pollFirst()}. + * + * @return the head of this deque, or <tt>null</tt> if this deque is empty + */ + E poll(); + + /** + * Retrieves and removes the head of the queue represented by this deque + * (in other words, the first element of this deque), waiting if + * necessary until an element becomes available. + * + * <p>This method is equivalent to {@link #takeFirst() takeFirst}. + * + * @return the head of this deque + * @throws InterruptedException if interrupted while waiting + */ + E take() throws InterruptedException; + + /** + * Retrieves and removes the head of the queue represented by this deque + * (in other words, the first element of this deque), waiting up to the + * specified wait time if necessary for an element to become available. + * + * <p>This method is equivalent to + * {@link #pollFirst(long,TimeUnit) pollFirst}. + * + * @return the head of this deque, or <tt>null</tt> if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + E poll(long timeout, TimeUnit unit) + throws InterruptedException; + + /** + * Retrieves, but does not remove, the head of the queue represented by + * this deque (in other words, the first element of this deque). + * This method differs from {@link #peek peek} only in that it throws an + * exception if this deque is empty. + * + * <p>This method is equivalent to {@link #getFirst() getFirst}. + * + * @return the head of this deque + * @throws NoSuchElementException if this deque is empty + */ + E element(); + + /** + * Retrieves, but does not remove, the head of the queue represented by + * this deque (in other words, the first element of this deque), or + * returns <tt>null</tt> if this deque is empty. + * + * <p>This method is equivalent to {@link #peekFirst() peekFirst}. + * + * @return the head of this deque, or <tt>null</tt> if this deque is empty + */ + E peek(); + + /** + * Removes the first occurrence of the specified element from this deque. + * If the deque does not contain the element, it is unchanged. + * More formally, removes the first element <tt>e</tt> such that + * <tt>o.equals(e)</tt> (if such an element exists). + * Returns <tt>true</tt> if this deque contained the specified element + * (or equivalently, if this deque changed as a result of the call). + * + * <p>This method is equivalent to + * {@link #removeFirstOccurrence(Object) removeFirstOccurrence}. + * + * @param o element to be removed from this deque, if present + * @return <tt>true</tt> if this deque changed as a result of the call + * @throws ClassCastException if the class of the specified element + * is incompatible with this deque (optional) + * @throws NullPointerException if the specified element is null (optional) + */ + boolean remove(Object o); + + /** + * Returns <tt>true</tt> if this deque contains the specified element. + * More formally, returns <tt>true</tt> if and only if this deque contains + * at least one element <tt>e</tt> such that <tt>o.equals(e)</tt>. + * + * @param o object to be checked for containment in this deque + * @return <tt>true</tt> if this deque contains the specified element + * @throws ClassCastException if the class of the specified element + * is incompatible with this deque (optional) + * @throws NullPointerException if the specified element is null (optional) + */ + public boolean contains(Object o); + + /** + * Returns the number of elements in this deque. + * + * @return the number of elements in this deque + */ + public int size(); + + /** + * Returns an iterator over the elements in this deque in proper sequence. + * The elements will be returned in order from first (head) to last (tail). + * + * @return an iterator over the elements in this deque in proper sequence + */ + Iterator<E> iterator(); + + // *** Stack methods *** + + /** + * Pushes an element onto the stack represented by this deque. In other + * words, inserts the element at the front of this deque unless it would + * violate capacity restrictions. + * + * <p>This method is equivalent to {@link #addFirst(Object) addFirst}. + * + * @throws IllegalStateException {@inheritDoc} + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException if the specified element is null + * @throws IllegalArgumentException {@inheritDoc} + */ + void push(E e); +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/BlockingQueue.java b/libjava/classpath/external/jsr166/java/util/concurrent/BlockingQueue.java new file mode 100644 index 000000000..b47cc9842 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/BlockingQueue.java @@ -0,0 +1,344 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; + +import java.util.Collection; +import java.util.Queue; + +/** + * A {@link java.util.Queue} that additionally supports operations + * that wait for the queue to become non-empty when retrieving an + * element, and wait for space to become available in the queue when + * storing an element. + * + * <p><tt>BlockingQueue</tt> methods come in four forms, with different ways + * of handling operations that cannot be satisfied immediately, but may be + * satisfied at some point in the future: + * one throws an exception, the second returns a special value (either + * <tt>null</tt> or <tt>false</tt>, depending on the operation), the third + * blocks the current thread indefinitely until the operation can succeed, + * and the fourth blocks for only a given maximum time limit before giving + * up. These methods are summarized in the following table: + * + * <p> + * <table BORDER CELLPADDING=3 CELLSPACING=1> + * <tr> + * <td></td> + * <td ALIGN=CENTER><em>Throws exception</em></td> + * <td ALIGN=CENTER><em>Special value</em></td> + * <td ALIGN=CENTER><em>Blocks</em></td> + * <td ALIGN=CENTER><em>Times out</em></td> + * </tr> + * <tr> + * <td><b>Insert</b></td> + * <td>{@link #add add(e)}</td> + * <td>{@link #offer offer(e)}</td> + * <td>{@link #put put(e)}</td> + * <td>{@link #offer(Object, long, TimeUnit) offer(e, time, unit)}</td> + * </tr> + * <tr> + * <td><b>Remove</b></td> + * <td>{@link #remove remove()}</td> + * <td>{@link #poll poll()}</td> + * <td>{@link #take take()}</td> + * <td>{@link #poll(long, TimeUnit) poll(time, unit)}</td> + * </tr> + * <tr> + * <td><b>Examine</b></td> + * <td>{@link #element element()}</td> + * <td>{@link #peek peek()}</td> + * <td><em>not applicable</em></td> + * <td><em>not applicable</em></td> + * </tr> + * </table> + * + * <p>A <tt>BlockingQueue</tt> does not accept <tt>null</tt> elements. + * Implementations throw <tt>NullPointerException</tt> on attempts + * to <tt>add</tt>, <tt>put</tt> or <tt>offer</tt> a <tt>null</tt>. A + * <tt>null</tt> is used as a sentinel value to indicate failure of + * <tt>poll</tt> operations. + * + * <p>A <tt>BlockingQueue</tt> may be capacity bounded. At any given + * time it may have a <tt>remainingCapacity</tt> beyond which no + * additional elements can be <tt>put</tt> without blocking. + * A <tt>BlockingQueue</tt> without any intrinsic capacity constraints always + * reports a remaining capacity of <tt>Integer.MAX_VALUE</tt>. + * + * <p> <tt>BlockingQueue</tt> implementations are designed to be used + * primarily for producer-consumer queues, but additionally support + * the {@link java.util.Collection} interface. So, for example, it is + * possible to remove an arbitrary element from a queue using + * <tt>remove(x)</tt>. However, such operations are in general + * <em>not</em> performed very efficiently, and are intended for only + * occasional use, such as when a queued message is cancelled. + * + * <p> <tt>BlockingQueue</tt> implementations are thread-safe. All + * queuing methods achieve their effects atomically using internal + * locks or other forms of concurrency control. However, the + * <em>bulk</em> Collection operations <tt>addAll</tt>, + * <tt>containsAll</tt>, <tt>retainAll</tt> and <tt>removeAll</tt> are + * <em>not</em> necessarily performed atomically unless specified + * otherwise in an implementation. So it is possible, for example, for + * <tt>addAll(c)</tt> to fail (throwing an exception) after adding + * only some of the elements in <tt>c</tt>. + * + * <p>A <tt>BlockingQueue</tt> does <em>not</em> intrinsically support + * any kind of "close" or "shutdown" operation to + * indicate that no more items will be added. The needs and usage of + * such features tend to be implementation-dependent. For example, a + * common tactic is for producers to insert special + * <em>end-of-stream</em> or <em>poison</em> objects, that are + * interpreted accordingly when taken by consumers. + * + * <p> + * Usage example, based on a typical producer-consumer scenario. + * Note that a <tt>BlockingQueue</tt> can safely be used with multiple + * producers and multiple consumers. + * <pre> + * class Producer implements Runnable { + * private final BlockingQueue queue; + * Producer(BlockingQueue q) { queue = q; } + * public void run() { + * try { + * while (true) { queue.put(produce()); } + * } catch (InterruptedException ex) { ... handle ...} + * } + * Object produce() { ... } + * } + * + * class Consumer implements Runnable { + * private final BlockingQueue queue; + * Consumer(BlockingQueue q) { queue = q; } + * public void run() { + * try { + * while (true) { consume(queue.take()); } + * } catch (InterruptedException ex) { ... handle ...} + * } + * void consume(Object x) { ... } + * } + * + * class Setup { + * void main() { + * BlockingQueue q = new SomeQueueImplementation(); + * Producer p = new Producer(q); + * Consumer c1 = new Consumer(q); + * Consumer c2 = new Consumer(q); + * new Thread(p).start(); + * new Thread(c1).start(); + * new Thread(c2).start(); + * } + * } + * </pre> + * + * <p>Memory consistency effects: As with other concurrent + * collections, actions in a thread prior to placing an object into a + * {@code BlockingQueue} + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a> + * actions subsequent to the access or removal of that element from + * the {@code BlockingQueue} in another thread. + * + * <p>This interface is a member of the + * <a href="{@docRoot}/../technotes/guides/collections/index.html"> + * Java Collections Framework</a>. + * + * @since 1.5 + * @author Doug Lea + * @param <E> the type of elements held in this collection + */ +public interface BlockingQueue<E> extends Queue<E> { + /** + * Inserts the specified element into this queue if it is possible to do + * so immediately without violating capacity restrictions, returning + * <tt>true</tt> upon success and throwing an + * <tt>IllegalStateException</tt> if no space is currently available. + * When using a capacity-restricted queue, it is generally preferable to + * use {@link #offer(Object) offer}. + * + * @param e the element to add + * @return <tt>true</tt> (as specified by {@link Collection#add}) + * @throws IllegalStateException if the element cannot be added at this + * time due to capacity restrictions + * @throws ClassCastException if the class of the specified element + * prevents it from being added to this queue + * @throws NullPointerException if the specified element is null + * @throws IllegalArgumentException if some property of the specified + * element prevents it from being added to this queue + */ + boolean add(E e); + + /** + * Inserts the specified element into this queue if it is possible to do + * so immediately without violating capacity restrictions, returning + * <tt>true</tt> upon success and <tt>false</tt> if no space is currently + * available. When using a capacity-restricted queue, this method is + * generally preferable to {@link #add}, which can fail to insert an + * element only by throwing an exception. + * + * @param e the element to add + * @return <tt>true</tt> if the element was added to this queue, else + * <tt>false</tt> + * @throws ClassCastException if the class of the specified element + * prevents it from being added to this queue + * @throws NullPointerException if the specified element is null + * @throws IllegalArgumentException if some property of the specified + * element prevents it from being added to this queue + */ + boolean offer(E e); + + /** + * Inserts the specified element into this queue, waiting if necessary + * for space to become available. + * + * @param e the element to add + * @throws InterruptedException if interrupted while waiting + * @throws ClassCastException if the class of the specified element + * prevents it from being added to this queue + * @throws NullPointerException if the specified element is null + * @throws IllegalArgumentException if some property of the specified + * element prevents it from being added to this queue + */ + void put(E e) throws InterruptedException; + + /** + * Inserts the specified element into this queue, waiting up to the + * specified wait time if necessary for space to become available. + * + * @param e the element to add + * @param timeout how long to wait before giving up, in units of + * <tt>unit</tt> + * @param unit a <tt>TimeUnit</tt> determining how to interpret the + * <tt>timeout</tt> parameter + * @return <tt>true</tt> if successful, or <tt>false</tt> if + * the specified waiting time elapses before space is available + * @throws InterruptedException if interrupted while waiting + * @throws ClassCastException if the class of the specified element + * prevents it from being added to this queue + * @throws NullPointerException if the specified element is null + * @throws IllegalArgumentException if some property of the specified + * element prevents it from being added to this queue + */ + boolean offer(E e, long timeout, TimeUnit unit) + throws InterruptedException; + + /** + * Retrieves and removes the head of this queue, waiting if necessary + * until an element becomes available. + * + * @return the head of this queue + * @throws InterruptedException if interrupted while waiting + */ + E take() throws InterruptedException; + + /** + * Retrieves and removes the head of this queue, waiting up to the + * specified wait time if necessary for an element to become available. + * + * @param timeout how long to wait before giving up, in units of + * <tt>unit</tt> + * @param unit a <tt>TimeUnit</tt> determining how to interpret the + * <tt>timeout</tt> parameter + * @return the head of this queue, or <tt>null</tt> if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + E poll(long timeout, TimeUnit unit) + throws InterruptedException; + + /** + * Returns the number of additional elements that this queue can ideally + * (in the absence of memory or resource constraints) accept without + * blocking, or <tt>Integer.MAX_VALUE</tt> if there is no intrinsic + * limit. + * + * <p>Note that you <em>cannot</em> always tell if an attempt to insert + * an element will succeed by inspecting <tt>remainingCapacity</tt> + * because it may be the case that another thread is about to + * insert or remove an element. + * + * @return the remaining capacity + */ + int remainingCapacity(); + + /** + * Removes a single instance of the specified element from this queue, + * if it is present. More formally, removes an element <tt>e</tt> such + * that <tt>o.equals(e)</tt>, if this queue contains one or more such + * elements. + * Returns <tt>true</tt> if this queue contained the specified element + * (or equivalently, if this queue changed as a result of the call). + * + * @param o element to be removed from this queue, if present + * @return <tt>true</tt> if this queue changed as a result of the call + * @throws ClassCastException if the class of the specified element + * is incompatible with this queue (optional) + * @throws NullPointerException if the specified element is null (optional) + */ + boolean remove(Object o); + + /** + * Returns <tt>true</tt> if this queue contains the specified element. + * More formally, returns <tt>true</tt> if and only if this queue contains + * at least one element <tt>e</tt> such that <tt>o.equals(e)</tt>. + * + * @param o object to be checked for containment in this queue + * @return <tt>true</tt> if this queue contains the specified element + * @throws ClassCastException if the class of the specified element + * is incompatible with this queue (optional) + * @throws NullPointerException if the specified element is null (optional) + */ + public boolean contains(Object o); + + /** + * Removes all available elements from this queue and adds them + * to the given collection. This operation may be more + * efficient than repeatedly polling this queue. A failure + * encountered while attempting to add elements to + * collection <tt>c</tt> may result in elements being in neither, + * either or both collections when the associated exception is + * thrown. Attempts to drain a queue to itself result in + * <tt>IllegalArgumentException</tt>. Further, the behavior of + * this operation is undefined if the specified collection is + * modified while the operation is in progress. + * + * @param c the collection to transfer elements into + * @return the number of elements transferred + * @throws UnsupportedOperationException if addition of elements + * is not supported by the specified collection + * @throws ClassCastException if the class of an element of this queue + * prevents it from being added to the specified collection + * @throws NullPointerException if the specified collection is null + * @throws IllegalArgumentException if the specified collection is this + * queue, or some property of an element of this queue prevents + * it from being added to the specified collection + */ + int drainTo(Collection<? super E> c); + + /** + * Removes at most the given number of available elements from + * this queue and adds them to the given collection. A failure + * encountered while attempting to add elements to + * collection <tt>c</tt> may result in elements being in neither, + * either or both collections when the associated exception is + * thrown. Attempts to drain a queue to itself result in + * <tt>IllegalArgumentException</tt>. Further, the behavior of + * this operation is undefined if the specified collection is + * modified while the operation is in progress. + * + * @param c the collection to transfer elements into + * @param maxElements the maximum number of elements to transfer + * @return the number of elements transferred + * @throws UnsupportedOperationException if addition of elements + * is not supported by the specified collection + * @throws ClassCastException if the class of an element of this queue + * prevents it from being added to the specified collection + * @throws NullPointerException if the specified collection is null + * @throws IllegalArgumentException if the specified collection is this + * queue, or some property of an element of this queue prevents + * it from being added to the specified collection + */ + int drainTo(Collection<? super E> c, int maxElements); +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/BrokenBarrierException.java b/libjava/classpath/external/jsr166/java/util/concurrent/BrokenBarrierException.java new file mode 100644 index 000000000..3f93fbb9d --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/BrokenBarrierException.java @@ -0,0 +1,38 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; + +/** + * Exception thrown when a thread tries to wait upon a barrier that is + * in a broken state, or which enters the broken state while the thread + * is waiting. + * + * @see CyclicBarrier + * + * @since 1.5 + * @author Doug Lea + * + */ +public class BrokenBarrierException extends Exception { + private static final long serialVersionUID = 7117394618823254244L; + + /** + * Constructs a <tt>BrokenBarrierException</tt> with no specified detail + * message. + */ + public BrokenBarrierException() {} + + /** + * Constructs a <tt>BrokenBarrierException</tt> with the specified + * detail message. + * + * @param message the detail message + */ + public BrokenBarrierException(String message) { + super(message); + } +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/Callable.java b/libjava/classpath/external/jsr166/java/util/concurrent/Callable.java new file mode 100644 index 000000000..abc4d0407 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/Callable.java @@ -0,0 +1,36 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; + +/** + * A task that returns a result and may throw an exception. + * Implementors define a single method with no arguments called + * <tt>call</tt>. + * + * <p>The <tt>Callable</tt> interface is similar to {@link + * java.lang.Runnable}, in that both are designed for classes whose + * instances are potentially executed by another thread. A + * <tt>Runnable</tt>, however, does not return a result and cannot + * throw a checked exception. + * + * <p> The {@link Executors} class contains utility methods to + * convert from other common forms to <tt>Callable</tt> classes. + * + * @see Executor + * @since 1.5 + * @author Doug Lea + * @param <V> the result type of method <tt>call</tt> + */ +public interface Callable<V> { + /** + * Computes a result, or throws an exception if unable to do so. + * + * @return computed result + * @throws Exception if unable to compute a result + */ + V call() throws Exception; +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/CancellationException.java b/libjava/classpath/external/jsr166/java/util/concurrent/CancellationException.java new file mode 100644 index 000000000..2c29544a0 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/CancellationException.java @@ -0,0 +1,34 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; + +/** + * Exception indicating that the result of a value-producing task, + * such as a {@link FutureTask}, cannot be retrieved because the task + * was cancelled. + * + * @since 1.5 + * @author Doug Lea + */ +public class CancellationException extends IllegalStateException { + private static final long serialVersionUID = -9202173006928992231L; + + /** + * Constructs a <tt>CancellationException</tt> with no detail message. + */ + public CancellationException() {} + + /** + * Constructs a <tt>CancellationException</tt> with the specified detail + * message. + * + * @param message the detail message + */ + public CancellationException(String message) { + super(message); + } +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/CompletionService.java b/libjava/classpath/external/jsr166/java/util/concurrent/CompletionService.java new file mode 100644 index 000000000..df9f719c4 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/CompletionService.java @@ -0,0 +1,97 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; + +/** + * A service that decouples the production of new asynchronous tasks + * from the consumption of the results of completed tasks. Producers + * <tt>submit</tt> tasks for execution. Consumers <tt>take</tt> + * completed tasks and process their results in the order they + * complete. A <tt>CompletionService</tt> can for example be used to + * manage asynchronous IO, in which tasks that perform reads are + * submitted in one part of a program or system, and then acted upon + * in a different part of the program when the reads complete, + * possibly in a different order than they were requested. + * + * <p>Typically, a <tt>CompletionService</tt> relies on a separate + * {@link Executor} to actually execute the tasks, in which case the + * <tt>CompletionService</tt> only manages an internal completion + * queue. The {@link ExecutorCompletionService} class provides an + * implementation of this approach. + * + * <p>Memory consistency effects: Actions in a thread prior to + * submitting a task to a {@code CompletionService} + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a> + * actions taken by that task, which in turn <i>happen-before</i> + * actions following a successful return from the corresponding {@code take()}. + * + */ +public interface CompletionService<V> { + /** + * Submits a value-returning task for execution and returns a Future + * representing the pending results of the task. Upon completion, + * this task may be taken or polled. + * + * @param task the task to submit + * @return a Future representing pending completion of the task + * @throws RejectedExecutionException if the task cannot be + * scheduled for execution + * @throws NullPointerException if the task is null + */ + Future<V> submit(Callable<V> task); + + /** + * Submits a Runnable task for execution and returns a Future + * representing that task. Upon completion, this task may be + * taken or polled. + * + * @param task the task to submit + * @param result the result to return upon successful completion + * @return a Future representing pending completion of the task, + * and whose <tt>get()</tt> method will return the given + * result value upon completion + * @throws RejectedExecutionException if the task cannot be + * scheduled for execution + * @throws NullPointerException if the task is null + */ + Future<V> submit(Runnable task, V result); + + /** + * Retrieves and removes the Future representing the next + * completed task, waiting if none are yet present. + * + * @return the Future representing the next completed task + * @throws InterruptedException if interrupted while waiting + */ + Future<V> take() throws InterruptedException; + + + /** + * Retrieves and removes the Future representing the next + * completed task or <tt>null</tt> if none are present. + * + * @return the Future representing the next completed task, or + * <tt>null</tt> if none are present + */ + Future<V> poll(); + + /** + * Retrieves and removes the Future representing the next + * completed task, waiting if necessary up to the specified wait + * time if none are yet present. + * + * @param timeout how long to wait before giving up, in units of + * <tt>unit</tt> + * @param unit a <tt>TimeUnit</tt> determining how to interpret the + * <tt>timeout</tt> parameter + * @return the Future representing the next completed task or + * <tt>null</tt> if the specified waiting time elapses + * before one is present + * @throws InterruptedException if interrupted while waiting + */ + Future<V> poll(long timeout, TimeUnit unit) throws InterruptedException; +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/ConcurrentHashMap.java b/libjava/classpath/external/jsr166/java/util/concurrent/ConcurrentHashMap.java new file mode 100644 index 000000000..9ad9ab25b --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/ConcurrentHashMap.java @@ -0,0 +1,1277 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; +import java.util.concurrent.locks.*; +import java.util.*; +import java.io.Serializable; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + +/** + * A hash table supporting full concurrency of retrievals and + * adjustable expected concurrency for updates. This class obeys the + * same functional specification as {@link java.util.Hashtable}, and + * includes versions of methods corresponding to each method of + * <tt>Hashtable</tt>. However, even though all operations are + * thread-safe, retrieval operations do <em>not</em> entail locking, + * and there is <em>not</em> any support for locking the entire table + * in a way that prevents all access. This class is fully + * interoperable with <tt>Hashtable</tt> in programs that rely on its + * thread safety but not on its synchronization details. + * + * <p> Retrieval operations (including <tt>get</tt>) generally do not + * block, so may overlap with update operations (including + * <tt>put</tt> and <tt>remove</tt>). Retrievals reflect the results + * of the most recently <em>completed</em> update operations holding + * upon their onset. For aggregate operations such as <tt>putAll</tt> + * and <tt>clear</tt>, concurrent retrievals may reflect insertion or + * removal of only some entries. Similarly, Iterators and + * Enumerations return elements reflecting the state of the hash table + * at some point at or since the creation of the iterator/enumeration. + * They do <em>not</em> throw {@link ConcurrentModificationException}. + * However, iterators are designed to be used by only one thread at a time. + * + * <p> The allowed concurrency among update operations is guided by + * the optional <tt>concurrencyLevel</tt> constructor argument + * (default <tt>16</tt>), which is used as a hint for internal sizing. The + * table is internally partitioned to try to permit the indicated + * number of concurrent updates without contention. Because placement + * in hash tables is essentially random, the actual concurrency will + * vary. Ideally, you should choose a value to accommodate as many + * threads as will ever concurrently modify the table. Using a + * significantly higher value than you need can waste space and time, + * and a significantly lower value can lead to thread contention. But + * overestimates and underestimates within an order of magnitude do + * not usually have much noticeable impact. A value of one is + * appropriate when it is known that only one thread will modify and + * all others will only read. Also, resizing this or any other kind of + * hash table is a relatively slow operation, so, when possible, it is + * a good idea to provide estimates of expected table sizes in + * constructors. + * + * <p>This class and its views and iterators implement all of the + * <em>optional</em> methods of the {@link Map} and {@link Iterator} + * interfaces. + * + * <p> Like {@link Hashtable} but unlike {@link HashMap}, this class + * does <em>not</em> allow <tt>null</tt> to be used as a key or value. + * + * <p>This class is a member of the + * <a href="{@docRoot}/../technotes/guides/collections/index.html"> + * Java Collections Framework</a>. + * + * @since 1.5 + * @author Doug Lea + * @param <K> the type of keys maintained by this map + * @param <V> the type of mapped values + */ +public class ConcurrentHashMap<K, V> extends AbstractMap<K, V> + implements ConcurrentMap<K, V>, Serializable { + private static final long serialVersionUID = 7249069246763182397L; + + /* + * The basic strategy is to subdivide the table among Segments, + * each of which itself is a concurrently readable hash table. + */ + + /* ---------------- Constants -------------- */ + + /** + * The default initial capacity for this table, + * used when not otherwise specified in a constructor. + */ + static final int DEFAULT_INITIAL_CAPACITY = 16; + + /** + * The default load factor for this table, used when not + * otherwise specified in a constructor. + */ + static final float DEFAULT_LOAD_FACTOR = 0.75f; + + /** + * The default concurrency level for this table, used when not + * otherwise specified in a constructor. + */ + static final int DEFAULT_CONCURRENCY_LEVEL = 16; + + /** + * The maximum capacity, used if a higher value is implicitly + * specified by either of the constructors with arguments. MUST + * be a power of two <= 1<<30 to ensure that entries are indexable + * using ints. + */ + static final int MAXIMUM_CAPACITY = 1 << 30; + + /** + * The maximum number of segments to allow; used to bound + * constructor arguments. + */ + static final int MAX_SEGMENTS = 1 << 16; // slightly conservative + + /** + * Number of unsynchronized retries in size and containsValue + * methods before resorting to locking. This is used to avoid + * unbounded retries if tables undergo continuous modification + * which would make it impossible to obtain an accurate result. + */ + static final int RETRIES_BEFORE_LOCK = 2; + + /* ---------------- Fields -------------- */ + + /** + * Mask value for indexing into segments. The upper bits of a + * key's hash code are used to choose the segment. + */ + final int segmentMask; + + /** + * Shift value for indexing within segments. + */ + final int segmentShift; + + /** + * The segments, each of which is a specialized hash table + */ + final Segment<K,V>[] segments; + + transient Set<K> keySet; + transient Set<Map.Entry<K,V>> entrySet; + transient Collection<V> values; + + /* ---------------- Small Utilities -------------- */ + + /** + * Applies a supplemental hash function to a given hashCode, which + * defends against poor quality hash functions. This is critical + * because ConcurrentHashMap uses power-of-two length hash tables, + * that otherwise encounter collisions for hashCodes that do not + * differ in lower bits. + */ + private static int hash(int h) { + // This function ensures that hashCodes that differ only by + // constant multiples at each bit position have a bounded + // number of collisions (approximately 8 at default load factor). + h ^= (h >>> 20) ^ (h >>> 12); + return h ^ (h >>> 7) ^ (h >>> 4); + } + + /** + * Returns the segment that should be used for key with given hash + * @param hash the hash code for the key + * @return the segment + */ + final Segment<K,V> segmentFor(int hash) { + return segments[(hash >>> segmentShift) & segmentMask]; + } + + /* ---------------- Inner Classes -------------- */ + + /** + * ConcurrentHashMap list entry. Note that this is never exported + * out as a user-visible Map.Entry. + * + * Because the value field is volatile, not final, it is legal wrt + * the Java Memory Model for an unsynchronized reader to see null + * instead of initial value when read via a data race. Although a + * reordering leading to this is not likely to ever actually + * occur, the Segment.readValueUnderLock method is used as a + * backup in case a null (pre-initialized) value is ever seen in + * an unsynchronized access method. + */ + static final class HashEntry<K,V> { + final K key; + final int hash; + volatile V value; + final HashEntry<K,V> next; + + HashEntry(K key, int hash, HashEntry<K,V> next, V value) { + this.key = key; + this.hash = hash; + this.next = next; + this.value = value; + } + + @SuppressWarnings("unchecked") + static final <K,V> HashEntry<K,V>[] newArray(int i) { + return new HashEntry[i]; + } + } + + /** + * Segments are specialized versions of hash tables. This + * subclasses from ReentrantLock opportunistically, just to + * simplify some locking and avoid separate construction. + */ + static final class Segment<K,V> extends ReentrantLock implements Serializable { + /* + * Segments maintain a table of entry lists that are ALWAYS + * kept in a consistent state, so can be read without locking. + * Next fields of nodes are immutable (final). All list + * additions are performed at the front of each bin. This + * makes it easy to check changes, and also fast to traverse. + * When nodes would otherwise be changed, new nodes are + * created to replace them. This works well for hash tables + * since the bin lists tend to be short. (The average length + * is less than two for the default load factor threshold.) + * + * Read operations can thus proceed without locking, but rely + * on selected uses of volatiles to ensure that completed + * write operations performed by other threads are + * noticed. For most purposes, the "count" field, tracking the + * number of elements, serves as that volatile variable + * ensuring visibility. This is convenient because this field + * needs to be read in many read operations anyway: + * + * - All (unsynchronized) read operations must first read the + * "count" field, and should not look at table entries if + * it is 0. + * + * - All (synchronized) write operations should write to + * the "count" field after structurally changing any bin. + * The operations must not take any action that could even + * momentarily cause a concurrent read operation to see + * inconsistent data. This is made easier by the nature of + * the read operations in Map. For example, no operation + * can reveal that the table has grown but the threshold + * has not yet been updated, so there are no atomicity + * requirements for this with respect to reads. + * + * As a guide, all critical volatile reads and writes to the + * count field are marked in code comments. + */ + + private static final long serialVersionUID = 2249069246763182397L; + + /** + * The number of elements in this segment's region. + */ + transient volatile int count; + + /** + * Number of updates that alter the size of the table. This is + * used during bulk-read methods to make sure they see a + * consistent snapshot: If modCounts change during a traversal + * of segments computing size or checking containsValue, then + * we might have an inconsistent view of state so (usually) + * must retry. + */ + transient int modCount; + + /** + * The table is rehashed when its size exceeds this threshold. + * (The value of this field is always <tt>(int)(capacity * + * loadFactor)</tt>.) + */ + transient int threshold; + + /** + * The per-segment table. + */ + transient volatile HashEntry<K,V>[] table; + + /** + * The load factor for the hash table. Even though this value + * is same for all segments, it is replicated to avoid needing + * links to outer object. + * @serial + */ + final float loadFactor; + + Segment(int initialCapacity, float lf) { + loadFactor = lf; + setTable(HashEntry.<K,V>newArray(initialCapacity)); + } + + @SuppressWarnings("unchecked") + static final <K,V> Segment<K,V>[] newArray(int i) { + return new Segment[i]; + } + + /** + * Sets table to new HashEntry array. + * Call only while holding lock or in constructor. + */ + void setTable(HashEntry<K,V>[] newTable) { + threshold = (int)(newTable.length * loadFactor); + table = newTable; + } + + /** + * Returns properly casted first entry of bin for given hash. + */ + HashEntry<K,V> getFirst(int hash) { + HashEntry<K,V>[] tab = table; + return tab[hash & (tab.length - 1)]; + } + + /** + * Reads value field of an entry under lock. Called if value + * field ever appears to be null. This is possible only if a + * compiler happens to reorder a HashEntry initialization with + * its table assignment, which is legal under memory model + * but is not known to ever occur. + */ + V readValueUnderLock(HashEntry<K,V> e) { + lock(); + try { + return e.value; + } finally { + unlock(); + } + } + + /* Specialized implementations of map methods */ + + V get(Object key, int hash) { + if (count != 0) { // read-volatile + HashEntry<K,V> e = getFirst(hash); + while (e != null) { + if (e.hash == hash && key.equals(e.key)) { + V v = e.value; + if (v != null) + return v; + return readValueUnderLock(e); // recheck + } + e = e.next; + } + } + return null; + } + + boolean containsKey(Object key, int hash) { + if (count != 0) { // read-volatile + HashEntry<K,V> e = getFirst(hash); + while (e != null) { + if (e.hash == hash && key.equals(e.key)) + return true; + e = e.next; + } + } + return false; + } + + boolean containsValue(Object value) { + if (count != 0) { // read-volatile + HashEntry<K,V>[] tab = table; + int len = tab.length; + for (int i = 0 ; i < len; i++) { + for (HashEntry<K,V> e = tab[i]; e != null; e = e.next) { + V v = e.value; + if (v == null) // recheck + v = readValueUnderLock(e); + if (value.equals(v)) + return true; + } + } + } + return false; + } + + boolean replace(K key, int hash, V oldValue, V newValue) { + lock(); + try { + HashEntry<K,V> e = getFirst(hash); + while (e != null && (e.hash != hash || !key.equals(e.key))) + e = e.next; + + boolean replaced = false; + if (e != null && oldValue.equals(e.value)) { + replaced = true; + e.value = newValue; + } + return replaced; + } finally { + unlock(); + } + } + + V replace(K key, int hash, V newValue) { + lock(); + try { + HashEntry<K,V> e = getFirst(hash); + while (e != null && (e.hash != hash || !key.equals(e.key))) + e = e.next; + + V oldValue = null; + if (e != null) { + oldValue = e.value; + e.value = newValue; + } + return oldValue; + } finally { + unlock(); + } + } + + + V put(K key, int hash, V value, boolean onlyIfAbsent) { + lock(); + try { + int c = count; + if (c++ > threshold) // ensure capacity + rehash(); + HashEntry<K,V>[] tab = table; + int index = hash & (tab.length - 1); + HashEntry<K,V> first = tab[index]; + HashEntry<K,V> e = first; + while (e != null && (e.hash != hash || !key.equals(e.key))) + e = e.next; + + V oldValue; + if (e != null) { + oldValue = e.value; + if (!onlyIfAbsent) + e.value = value; + } + else { + oldValue = null; + ++modCount; + tab[index] = new HashEntry<K,V>(key, hash, first, value); + count = c; // write-volatile + } + return oldValue; + } finally { + unlock(); + } + } + + void rehash() { + HashEntry<K,V>[] oldTable = table; + int oldCapacity = oldTable.length; + if (oldCapacity >= MAXIMUM_CAPACITY) + return; + + /* + * Reclassify nodes in each list to new Map. Because we are + * using power-of-two expansion, the elements from each bin + * must either stay at same index, or move with a power of two + * offset. We eliminate unnecessary node creation by catching + * cases where old nodes can be reused because their next + * fields won't change. Statistically, at the default + * threshold, only about one-sixth of them need cloning when + * a table doubles. The nodes they replace will be garbage + * collectable as soon as they are no longer referenced by any + * reader thread that may be in the midst of traversing table + * right now. + */ + + HashEntry<K,V>[] newTable = HashEntry.newArray(oldCapacity<<1); + threshold = (int)(newTable.length * loadFactor); + int sizeMask = newTable.length - 1; + for (int i = 0; i < oldCapacity ; i++) { + // We need to guarantee that any existing reads of old Map can + // proceed. So we cannot yet null out each bin. + HashEntry<K,V> e = oldTable[i]; + + if (e != null) { + HashEntry<K,V> next = e.next; + int idx = e.hash & sizeMask; + + // Single node on list + if (next == null) + newTable[idx] = e; + + else { + // Reuse trailing consecutive sequence at same slot + HashEntry<K,V> lastRun = e; + int lastIdx = idx; + for (HashEntry<K,V> last = next; + last != null; + last = last.next) { + int k = last.hash & sizeMask; + if (k != lastIdx) { + lastIdx = k; + lastRun = last; + } + } + newTable[lastIdx] = lastRun; + + // Clone all remaining nodes + for (HashEntry<K,V> p = e; p != lastRun; p = p.next) { + int k = p.hash & sizeMask; + HashEntry<K,V> n = newTable[k]; + newTable[k] = new HashEntry<K,V>(p.key, p.hash, + n, p.value); + } + } + } + } + table = newTable; + } + + /** + * Remove; match on key only if value null, else match both. + */ + V remove(Object key, int hash, Object value) { + lock(); + try { + int c = count - 1; + HashEntry<K,V>[] tab = table; + int index = hash & (tab.length - 1); + HashEntry<K,V> first = tab[index]; + HashEntry<K,V> e = first; + while (e != null && (e.hash != hash || !key.equals(e.key))) + e = e.next; + + V oldValue = null; + if (e != null) { + V v = e.value; + if (value == null || value.equals(v)) { + oldValue = v; + // All entries following removed node can stay + // in list, but all preceding ones need to be + // cloned. + ++modCount; + HashEntry<K,V> newFirst = e.next; + for (HashEntry<K,V> p = first; p != e; p = p.next) + newFirst = new HashEntry<K,V>(p.key, p.hash, + newFirst, p.value); + tab[index] = newFirst; + count = c; // write-volatile + } + } + return oldValue; + } finally { + unlock(); + } + } + + void clear() { + if (count != 0) { + lock(); + try { + HashEntry<K,V>[] tab = table; + for (int i = 0; i < tab.length ; i++) + tab[i] = null; + ++modCount; + count = 0; // write-volatile + } finally { + unlock(); + } + } + } + } + + + + /* ---------------- Public operations -------------- */ + + /** + * Creates a new, empty map with the specified initial + * capacity, load factor and concurrency level. + * + * @param initialCapacity the initial capacity. The implementation + * performs internal sizing to accommodate this many elements. + * @param loadFactor the load factor threshold, used to control resizing. + * Resizing may be performed when the average number of elements per + * bin exceeds this threshold. + * @param concurrencyLevel the estimated number of concurrently + * updating threads. The implementation performs internal sizing + * to try to accommodate this many threads. + * @throws IllegalArgumentException if the initial capacity is + * negative or the load factor or concurrencyLevel are + * nonpositive. + */ + public ConcurrentHashMap(int initialCapacity, + float loadFactor, int concurrencyLevel) { + if (!(loadFactor > 0) || initialCapacity < 0 || concurrencyLevel <= 0) + throw new IllegalArgumentException(); + + if (concurrencyLevel > MAX_SEGMENTS) + concurrencyLevel = MAX_SEGMENTS; + + // Find power-of-two sizes best matching arguments + int sshift = 0; + int ssize = 1; + while (ssize < concurrencyLevel) { + ++sshift; + ssize <<= 1; + } + segmentShift = 32 - sshift; + segmentMask = ssize - 1; + this.segments = Segment.newArray(ssize); + + if (initialCapacity > MAXIMUM_CAPACITY) + initialCapacity = MAXIMUM_CAPACITY; + int c = initialCapacity / ssize; + if (c * ssize < initialCapacity) + ++c; + int cap = 1; + while (cap < c) + cap <<= 1; + + for (int i = 0; i < this.segments.length; ++i) + this.segments[i] = new Segment<K,V>(cap, loadFactor); + } + + /** + * Creates a new, empty map with the specified initial capacity + * and load factor and with the default concurrencyLevel (16). + * + * @param initialCapacity The implementation performs internal + * sizing to accommodate this many elements. + * @param loadFactor the load factor threshold, used to control resizing. + * Resizing may be performed when the average number of elements per + * bin exceeds this threshold. + * @throws IllegalArgumentException if the initial capacity of + * elements is negative or the load factor is nonpositive + * + * @since 1.6 + */ + public ConcurrentHashMap(int initialCapacity, float loadFactor) { + this(initialCapacity, loadFactor, DEFAULT_CONCURRENCY_LEVEL); + } + + /** + * Creates a new, empty map with the specified initial capacity, + * and with default load factor (0.75) and concurrencyLevel (16). + * + * @param initialCapacity the initial capacity. The implementation + * performs internal sizing to accommodate this many elements. + * @throws IllegalArgumentException if the initial capacity of + * elements is negative. + */ + public ConcurrentHashMap(int initialCapacity) { + this(initialCapacity, DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL); + } + + /** + * Creates a new, empty map with a default initial capacity (16), + * load factor (0.75) and concurrencyLevel (16). + */ + public ConcurrentHashMap() { + this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL); + } + + /** + * Creates a new map with the same mappings as the given map. + * The map is created with a capacity of 1.5 times the number + * of mappings in the given map or 16 (whichever is greater), + * and a default load factor (0.75) and concurrencyLevel (16). + * + * @param m the map + */ + public ConcurrentHashMap(Map<? extends K, ? extends V> m) { + this(Math.max((int) (m.size() / DEFAULT_LOAD_FACTOR) + 1, + DEFAULT_INITIAL_CAPACITY), + DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL); + putAll(m); + } + + /** + * Returns <tt>true</tt> if this map contains no key-value mappings. + * + * @return <tt>true</tt> if this map contains no key-value mappings + */ + public boolean isEmpty() { + final Segment<K,V>[] segments = this.segments; + /* + * We keep track of per-segment modCounts to avoid ABA + * problems in which an element in one segment was added and + * in another removed during traversal, in which case the + * table was never actually empty at any point. Note the + * similar use of modCounts in the size() and containsValue() + * methods, which are the only other methods also susceptible + * to ABA problems. + */ + int[] mc = new int[segments.length]; + int mcsum = 0; + for (int i = 0; i < segments.length; ++i) { + if (segments[i].count != 0) + return false; + else + mcsum += mc[i] = segments[i].modCount; + } + // If mcsum happens to be zero, then we know we got a snapshot + // before any modifications at all were made. This is + // probably common enough to bother tracking. + if (mcsum != 0) { + for (int i = 0; i < segments.length; ++i) { + if (segments[i].count != 0 || + mc[i] != segments[i].modCount) + return false; + } + } + return true; + } + + /** + * Returns the number of key-value mappings in this map. If the + * map contains more than <tt>Integer.MAX_VALUE</tt> elements, returns + * <tt>Integer.MAX_VALUE</tt>. + * + * @return the number of key-value mappings in this map + */ + public int size() { + final Segment<K,V>[] segments = this.segments; + long sum = 0; + long check = 0; + int[] mc = new int[segments.length]; + // Try a few times to get accurate count. On failure due to + // continuous async changes in table, resort to locking. + for (int k = 0; k < RETRIES_BEFORE_LOCK; ++k) { + check = 0; + sum = 0; + int mcsum = 0; + for (int i = 0; i < segments.length; ++i) { + sum += segments[i].count; + mcsum += mc[i] = segments[i].modCount; + } + if (mcsum != 0) { + for (int i = 0; i < segments.length; ++i) { + check += segments[i].count; + if (mc[i] != segments[i].modCount) { + check = -1; // force retry + break; + } + } + } + if (check == sum) + break; + } + if (check != sum) { // Resort to locking all segments + sum = 0; + for (int i = 0; i < segments.length; ++i) + segments[i].lock(); + for (int i = 0; i < segments.length; ++i) + sum += segments[i].count; + for (int i = 0; i < segments.length; ++i) + segments[i].unlock(); + } + if (sum > Integer.MAX_VALUE) + return Integer.MAX_VALUE; + else + return (int)sum; + } + + /** + * Returns the value to which the specified key is mapped, + * or {@code null} if this map contains no mapping for the key. + * + * <p>More formally, if this map contains a mapping from a key + * {@code k} to a value {@code v} such that {@code key.equals(k)}, + * then this method returns {@code v}; otherwise it returns + * {@code null}. (There can be at most one such mapping.) + * + * @throws NullPointerException if the specified key is null + */ + public V get(Object key) { + int hash = hash(key.hashCode()); + return segmentFor(hash).get(key, hash); + } + + /** + * Tests if the specified object is a key in this table. + * + * @param key possible key + * @return <tt>true</tt> if and only if the specified object + * is a key in this table, as determined by the + * <tt>equals</tt> method; <tt>false</tt> otherwise. + * @throws NullPointerException if the specified key is null + */ + public boolean containsKey(Object key) { + int hash = hash(key.hashCode()); + return segmentFor(hash).containsKey(key, hash); + } + + /** + * Returns <tt>true</tt> if this map maps one or more keys to the + * specified value. Note: This method requires a full internal + * traversal of the hash table, and so is much slower than + * method <tt>containsKey</tt>. + * + * @param value value whose presence in this map is to be tested + * @return <tt>true</tt> if this map maps one or more keys to the + * specified value + * @throws NullPointerException if the specified value is null + */ + public boolean containsValue(Object value) { + if (value == null) + throw new NullPointerException(); + + // See explanation of modCount use above + + final Segment<K,V>[] segments = this.segments; + int[] mc = new int[segments.length]; + + // Try a few times without locking + for (int k = 0; k < RETRIES_BEFORE_LOCK; ++k) { + int sum = 0; + int mcsum = 0; + for (int i = 0; i < segments.length; ++i) { + int c = segments[i].count; + mcsum += mc[i] = segments[i].modCount; + if (segments[i].containsValue(value)) + return true; + } + boolean cleanSweep = true; + if (mcsum != 0) { + for (int i = 0; i < segments.length; ++i) { + int c = segments[i].count; + if (mc[i] != segments[i].modCount) { + cleanSweep = false; + break; + } + } + } + if (cleanSweep) + return false; + } + // Resort to locking all segments + for (int i = 0; i < segments.length; ++i) + segments[i].lock(); + boolean found = false; + try { + for (int i = 0; i < segments.length; ++i) { + if (segments[i].containsValue(value)) { + found = true; + break; + } + } + } finally { + for (int i = 0; i < segments.length; ++i) + segments[i].unlock(); + } + return found; + } + + /** + * Legacy method testing if some key maps into the specified value + * in this table. This method is identical in functionality to + * {@link #containsValue}, and exists solely to ensure + * full compatibility with class {@link java.util.Hashtable}, + * which supported this method prior to introduction of the + * Java Collections framework. + + * @param value a value to search for + * @return <tt>true</tt> if and only if some key maps to the + * <tt>value</tt> argument in this table as + * determined by the <tt>equals</tt> method; + * <tt>false</tt> otherwise + * @throws NullPointerException if the specified value is null + */ + public boolean contains(Object value) { + return containsValue(value); + } + + /** + * Maps the specified key to the specified value in this table. + * Neither the key nor the value can be null. + * + * <p> The value can be retrieved by calling the <tt>get</tt> method + * with a key that is equal to the original key. + * + * @param key key with which the specified value is to be associated + * @param value value to be associated with the specified key + * @return the previous value associated with <tt>key</tt>, or + * <tt>null</tt> if there was no mapping for <tt>key</tt> + * @throws NullPointerException if the specified key or value is null + */ + public V put(K key, V value) { + if (value == null) + throw new NullPointerException(); + int hash = hash(key.hashCode()); + return segmentFor(hash).put(key, hash, value, false); + } + + /** + * {@inheritDoc} + * + * @return the previous value associated with the specified key, + * or <tt>null</tt> if there was no mapping for the key + * @throws NullPointerException if the specified key or value is null + */ + public V putIfAbsent(K key, V value) { + if (value == null) + throw new NullPointerException(); + int hash = hash(key.hashCode()); + return segmentFor(hash).put(key, hash, value, true); + } + + /** + * Copies all of the mappings from the specified map to this one. + * These mappings replace any mappings that this map had for any of the + * keys currently in the specified map. + * + * @param m mappings to be stored in this map + */ + public void putAll(Map<? extends K, ? extends V> m) { + for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) + put(e.getKey(), e.getValue()); + } + + /** + * Removes the key (and its corresponding value) from this map. + * This method does nothing if the key is not in the map. + * + * @param key the key that needs to be removed + * @return the previous value associated with <tt>key</tt>, or + * <tt>null</tt> if there was no mapping for <tt>key</tt> + * @throws NullPointerException if the specified key is null + */ + public V remove(Object key) { + int hash = hash(key.hashCode()); + return segmentFor(hash).remove(key, hash, null); + } + + /** + * {@inheritDoc} + * + * @throws NullPointerException if the specified key is null + */ + public boolean remove(Object key, Object value) { + int hash = hash(key.hashCode()); + if (value == null) + return false; + return segmentFor(hash).remove(key, hash, value) != null; + } + + /** + * {@inheritDoc} + * + * @throws NullPointerException if any of the arguments are null + */ + public boolean replace(K key, V oldValue, V newValue) { + if (oldValue == null || newValue == null) + throw new NullPointerException(); + int hash = hash(key.hashCode()); + return segmentFor(hash).replace(key, hash, oldValue, newValue); + } + + /** + * {@inheritDoc} + * + * @return the previous value associated with the specified key, + * or <tt>null</tt> if there was no mapping for the key + * @throws NullPointerException if the specified key or value is null + */ + public V replace(K key, V value) { + if (value == null) + throw new NullPointerException(); + int hash = hash(key.hashCode()); + return segmentFor(hash).replace(key, hash, value); + } + + /** + * Removes all of the mappings from this map. + */ + public void clear() { + for (int i = 0; i < segments.length; ++i) + segments[i].clear(); + } + + /** + * Returns a {@link Set} view of the keys contained in this map. + * The set is backed by the map, so changes to the map are + * reflected in the set, and vice-versa. The set supports element + * removal, which removes the corresponding mapping from this map, + * via the <tt>Iterator.remove</tt>, <tt>Set.remove</tt>, + * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> + * operations. It does not support the <tt>add</tt> or + * <tt>addAll</tt> operations. + * + * <p>The view's <tt>iterator</tt> is a "weakly consistent" iterator + * that will never throw {@link ConcurrentModificationException}, + * and guarantees to traverse elements as they existed upon + * construction of the iterator, and may (but is not guaranteed to) + * reflect any modifications subsequent to construction. + */ + public Set<K> keySet() { + Set<K> ks = keySet; + return (ks != null) ? ks : (keySet = new KeySet()); + } + + /** + * Returns a {@link Collection} view of the values contained in this map. + * The collection is backed by the map, so changes to the map are + * reflected in the collection, and vice-versa. The collection + * supports element removal, which removes the corresponding + * mapping from this map, via the <tt>Iterator.remove</tt>, + * <tt>Collection.remove</tt>, <tt>removeAll</tt>, + * <tt>retainAll</tt>, and <tt>clear</tt> operations. It does not + * support the <tt>add</tt> or <tt>addAll</tt> operations. + * + * <p>The view's <tt>iterator</tt> is a "weakly consistent" iterator + * that will never throw {@link ConcurrentModificationException}, + * and guarantees to traverse elements as they existed upon + * construction of the iterator, and may (but is not guaranteed to) + * reflect any modifications subsequent to construction. + */ + public Collection<V> values() { + Collection<V> vs = values; + return (vs != null) ? vs : (values = new Values()); + } + + /** + * Returns a {@link Set} view of the mappings contained in this map. + * The set is backed by the map, so changes to the map are + * reflected in the set, and vice-versa. The set supports element + * removal, which removes the corresponding mapping from the map, + * via the <tt>Iterator.remove</tt>, <tt>Set.remove</tt>, + * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> + * operations. It does not support the <tt>add</tt> or + * <tt>addAll</tt> operations. + * + * <p>The view's <tt>iterator</tt> is a "weakly consistent" iterator + * that will never throw {@link ConcurrentModificationException}, + * and guarantees to traverse elements as they existed upon + * construction of the iterator, and may (but is not guaranteed to) + * reflect any modifications subsequent to construction. + */ + public Set<Map.Entry<K,V>> entrySet() { + Set<Map.Entry<K,V>> es = entrySet; + return (es != null) ? es : (entrySet = new EntrySet()); + } + + /** + * Returns an enumeration of the keys in this table. + * + * @return an enumeration of the keys in this table + * @see #keySet + */ + public Enumeration<K> keys() { + return new KeyIterator(); + } + + /** + * Returns an enumeration of the values in this table. + * + * @return an enumeration of the values in this table + * @see #values + */ + public Enumeration<V> elements() { + return new ValueIterator(); + } + + /* ---------------- Iterator Support -------------- */ + + abstract class HashIterator { + int nextSegmentIndex; + int nextTableIndex; + HashEntry<K,V>[] currentTable; + HashEntry<K, V> nextEntry; + HashEntry<K, V> lastReturned; + + HashIterator() { + nextSegmentIndex = segments.length - 1; + nextTableIndex = -1; + advance(); + } + + public boolean hasMoreElements() { return hasNext(); } + + final void advance() { + if (nextEntry != null && (nextEntry = nextEntry.next) != null) + return; + + while (nextTableIndex >= 0) { + if ( (nextEntry = currentTable[nextTableIndex--]) != null) + return; + } + + while (nextSegmentIndex >= 0) { + Segment<K,V> seg = segments[nextSegmentIndex--]; + if (seg.count != 0) { + currentTable = seg.table; + for (int j = currentTable.length - 1; j >= 0; --j) { + if ( (nextEntry = currentTable[j]) != null) { + nextTableIndex = j - 1; + return; + } + } + } + } + } + + public boolean hasNext() { return nextEntry != null; } + + HashEntry<K,V> nextEntry() { + if (nextEntry == null) + throw new NoSuchElementException(); + lastReturned = nextEntry; + advance(); + return lastReturned; + } + + public void remove() { + if (lastReturned == null) + throw new IllegalStateException(); + ConcurrentHashMap.this.remove(lastReturned.key); + lastReturned = null; + } + } + + final class KeyIterator + extends HashIterator + implements Iterator<K>, Enumeration<K> + { + public K next() { return super.nextEntry().key; } + public K nextElement() { return super.nextEntry().key; } + } + + final class ValueIterator + extends HashIterator + implements Iterator<V>, Enumeration<V> + { + public V next() { return super.nextEntry().value; } + public V nextElement() { return super.nextEntry().value; } + } + + /** + * Custom Entry class used by EntryIterator.next(), that relays + * setValue changes to the underlying map. + */ + final class WriteThroughEntry + extends AbstractMap.SimpleEntry<K,V> + { + WriteThroughEntry(K k, V v) { + super(k,v); + } + + /** + * Set our entry's value and write through to the map. The + * value to return is somewhat arbitrary here. Since a + * WriteThroughEntry does not necessarily track asynchronous + * changes, the most recent "previous" value could be + * different from what we return (or could even have been + * removed in which case the put will re-establish). We do not + * and cannot guarantee more. + */ + public V setValue(V value) { + if (value == null) throw new NullPointerException(); + V v = super.setValue(value); + ConcurrentHashMap.this.put(getKey(), value); + return v; + } + } + + final class EntryIterator + extends HashIterator + implements Iterator<Entry<K,V>> + { + public Map.Entry<K,V> next() { + HashEntry<K,V> e = super.nextEntry(); + return new WriteThroughEntry(e.key, e.value); + } + } + + final class KeySet extends AbstractSet<K> { + public Iterator<K> iterator() { + return new KeyIterator(); + } + public int size() { + return ConcurrentHashMap.this.size(); + } + public boolean contains(Object o) { + return ConcurrentHashMap.this.containsKey(o); + } + public boolean remove(Object o) { + return ConcurrentHashMap.this.remove(o) != null; + } + public void clear() { + ConcurrentHashMap.this.clear(); + } + } + + final class Values extends AbstractCollection<V> { + public Iterator<V> iterator() { + return new ValueIterator(); + } + public int size() { + return ConcurrentHashMap.this.size(); + } + public boolean contains(Object o) { + return ConcurrentHashMap.this.containsValue(o); + } + public void clear() { + ConcurrentHashMap.this.clear(); + } + } + + final class EntrySet extends AbstractSet<Map.Entry<K,V>> { + public Iterator<Map.Entry<K,V>> iterator() { + return new EntryIterator(); + } + public boolean contains(Object o) { + if (!(o instanceof Map.Entry)) + return false; + Map.Entry<?,?> e = (Map.Entry<?,?>)o; + V v = ConcurrentHashMap.this.get(e.getKey()); + return v != null && v.equals(e.getValue()); + } + public boolean remove(Object o) { + if (!(o instanceof Map.Entry)) + return false; + Map.Entry<?,?> e = (Map.Entry<?,?>)o; + return ConcurrentHashMap.this.remove(e.getKey(), e.getValue()); + } + public int size() { + return ConcurrentHashMap.this.size(); + } + public void clear() { + ConcurrentHashMap.this.clear(); + } + } + + /* ---------------- Serialization Support -------------- */ + + /** + * Save the state of the <tt>ConcurrentHashMap</tt> instance to a + * stream (i.e., serialize it). + * @param s the stream + * @serialData + * the key (Object) and value (Object) + * for each key-value mapping, followed by a null pair. + * The key-value mappings are emitted in no particular order. + */ + private void writeObject(java.io.ObjectOutputStream s) throws IOException { + s.defaultWriteObject(); + + for (int k = 0; k < segments.length; ++k) { + Segment<K,V> seg = segments[k]; + seg.lock(); + try { + HashEntry<K,V>[] tab = seg.table; + for (int i = 0; i < tab.length; ++i) { + for (HashEntry<K,V> e = tab[i]; e != null; e = e.next) { + s.writeObject(e.key); + s.writeObject(e.value); + } + } + } finally { + seg.unlock(); + } + } + s.writeObject(null); + s.writeObject(null); + } + + /** + * Reconstitute the <tt>ConcurrentHashMap</tt> instance from a + * stream (i.e., deserialize it). + * @param s the stream + */ + private void readObject(java.io.ObjectInputStream s) + throws IOException, ClassNotFoundException { + s.defaultReadObject(); + + // Initialize each segment to be minimally sized, and let grow. + for (int i = 0; i < segments.length; ++i) { + segments[i].setTable(new HashEntry[1]); + } + + // Read the keys and values, and put the mappings in the table + for (;;) { + K key = (K) s.readObject(); + V value = (V) s.readObject(); + if (key == null) + break; + put(key, value); + } + } +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/ConcurrentLinkedQueue.java b/libjava/classpath/external/jsr166/java/util/concurrent/ConcurrentLinkedQueue.java new file mode 100644 index 000000000..000f4a4c9 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/ConcurrentLinkedQueue.java @@ -0,0 +1,480 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; +import java.util.*; +import java.util.concurrent.atomic.*; + + +/** + * An unbounded thread-safe {@linkplain Queue queue} based on linked nodes. + * This queue orders elements FIFO (first-in-first-out). + * The <em>head</em> of the queue is that element that has been on the + * queue the longest time. + * The <em>tail</em> of the queue is that element that has been on the + * queue the shortest time. New elements + * are inserted at the tail of the queue, and the queue retrieval + * operations obtain elements at the head of the queue. + * A <tt>ConcurrentLinkedQueue</tt> is an appropriate choice when + * many threads will share access to a common collection. + * This queue does not permit <tt>null</tt> elements. + * + * <p>This implementation employs an efficient "wait-free" + * algorithm based on one described in <a + * href="http://www.cs.rochester.edu/u/michael/PODC96.html"> Simple, + * Fast, and Practical Non-Blocking and Blocking Concurrent Queue + * Algorithms</a> by Maged M. Michael and Michael L. Scott. + * + * <p>Beware that, unlike in most collections, the <tt>size</tt> method + * is <em>NOT</em> a constant-time operation. Because of the + * asynchronous nature of these queues, determining the current number + * of elements requires a traversal of the elements. + * + * <p>This class and its iterator implement all of the + * <em>optional</em> methods of the {@link Collection} and {@link + * Iterator} interfaces. + * + * <p>Memory consistency effects: As with other concurrent + * collections, actions in a thread prior to placing an object into a + * {@code ConcurrentLinkedQueue} + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a> + * actions subsequent to the access or removal of that element from + * the {@code ConcurrentLinkedQueue} in another thread. + * + * <p>This class is a member of the + * <a href="{@docRoot}/../technotes/guides/collections/index.html"> + * Java Collections Framework</a>. + * + * @since 1.5 + * @author Doug Lea + * @param <E> the type of elements held in this collection + * + */ +public class ConcurrentLinkedQueue<E> extends AbstractQueue<E> + implements Queue<E>, java.io.Serializable { + private static final long serialVersionUID = 196745693267521676L; + + /* + * This is a straight adaptation of Michael & Scott algorithm. + * For explanation, read the paper. The only (minor) algorithmic + * difference is that this version supports lazy deletion of + * internal nodes (method remove(Object)) -- remove CAS'es item + * fields to null. The normal queue operations unlink but then + * pass over nodes with null item fields. Similarly, iteration + * methods ignore those with nulls. + * + * Also note that like most non-blocking algorithms in this + * package, this implementation relies on the fact that in garbage + * collected systems, there is no possibility of ABA problems due + * to recycled nodes, so there is no need to use "counted + * pointers" or related techniques seen in versions used in + * non-GC'ed settings. + */ + + private static class Node<E> { + private volatile E item; + private volatile Node<E> next; + + private static final + AtomicReferenceFieldUpdater<Node, Node> + nextUpdater = + AtomicReferenceFieldUpdater.newUpdater + (Node.class, Node.class, "next"); + private static final + AtomicReferenceFieldUpdater<Node, Object> + itemUpdater = + AtomicReferenceFieldUpdater.newUpdater + (Node.class, Object.class, "item"); + + Node(E x) { item = x; } + + Node(E x, Node<E> n) { item = x; next = n; } + + E getItem() { + return item; + } + + boolean casItem(E cmp, E val) { + return itemUpdater.compareAndSet(this, cmp, val); + } + + void setItem(E val) { + itemUpdater.set(this, val); + } + + Node<E> getNext() { + return next; + } + + boolean casNext(Node<E> cmp, Node<E> val) { + return nextUpdater.compareAndSet(this, cmp, val); + } + + void setNext(Node<E> val) { + nextUpdater.set(this, val); + } + + } + + private static final + AtomicReferenceFieldUpdater<ConcurrentLinkedQueue, Node> + tailUpdater = + AtomicReferenceFieldUpdater.newUpdater + (ConcurrentLinkedQueue.class, Node.class, "tail"); + private static final + AtomicReferenceFieldUpdater<ConcurrentLinkedQueue, Node> + headUpdater = + AtomicReferenceFieldUpdater.newUpdater + (ConcurrentLinkedQueue.class, Node.class, "head"); + + private boolean casTail(Node<E> cmp, Node<E> val) { + return tailUpdater.compareAndSet(this, cmp, val); + } + + private boolean casHead(Node<E> cmp, Node<E> val) { + return headUpdater.compareAndSet(this, cmp, val); + } + + + /** + * Pointer to header node, initialized to a dummy node. The first + * actual node is at head.getNext(). + */ + private transient volatile Node<E> head = new Node<E>(null, null); + + /** Pointer to last node on list **/ + private transient volatile Node<E> tail = head; + + + /** + * Creates a <tt>ConcurrentLinkedQueue</tt> that is initially empty. + */ + public ConcurrentLinkedQueue() {} + + /** + * Creates a <tt>ConcurrentLinkedQueue</tt> + * initially containing the elements of the given collection, + * added in traversal order of the collection's iterator. + * @param c the collection of elements to initially contain + * @throws NullPointerException if the specified collection or any + * of its elements are null + */ + public ConcurrentLinkedQueue(Collection<? extends E> c) { + for (Iterator<? extends E> it = c.iterator(); it.hasNext();) + add(it.next()); + } + + // Have to override just to update the javadoc + + /** + * Inserts the specified element at the tail of this queue. + * + * @return <tt>true</tt> (as specified by {@link Collection#add}) + * @throws NullPointerException if the specified element is null + */ + public boolean add(E e) { + return offer(e); + } + + /** + * Inserts the specified element at the tail of this queue. + * + * @return <tt>true</tt> (as specified by {@link Queue#offer}) + * @throws NullPointerException if the specified element is null + */ + public boolean offer(E e) { + if (e == null) throw new NullPointerException(); + Node<E> n = new Node<E>(e, null); + for (;;) { + Node<E> t = tail; + Node<E> s = t.getNext(); + if (t == tail) { + if (s == null) { + if (t.casNext(s, n)) { + casTail(t, n); + return true; + } + } else { + casTail(t, s); + } + } + } + } + + public E poll() { + for (;;) { + Node<E> h = head; + Node<E> t = tail; + Node<E> first = h.getNext(); + if (h == head) { + if (h == t) { + if (first == null) + return null; + else + casTail(t, first); + } else if (casHead(h, first)) { + E item = first.getItem(); + if (item != null) { + first.setItem(null); + return item; + } + // else skip over deleted item, continue loop, + } + } + } + } + + public E peek() { // same as poll except don't remove item + for (;;) { + Node<E> h = head; + Node<E> t = tail; + Node<E> first = h.getNext(); + if (h == head) { + if (h == t) { + if (first == null) + return null; + else + casTail(t, first); + } else { + E item = first.getItem(); + if (item != null) + return item; + else // remove deleted node and continue + casHead(h, first); + } + } + } + } + + /** + * Returns the first actual (non-header) node on list. This is yet + * another variant of poll/peek; here returning out the first + * node, not element (so we cannot collapse with peek() without + * introducing race.) + */ + Node<E> first() { + for (;;) { + Node<E> h = head; + Node<E> t = tail; + Node<E> first = h.getNext(); + if (h == head) { + if (h == t) { + if (first == null) + return null; + else + casTail(t, first); + } else { + if (first.getItem() != null) + return first; + else // remove deleted node and continue + casHead(h, first); + } + } + } + } + + + /** + * Returns <tt>true</tt> if this queue contains no elements. + * + * @return <tt>true</tt> if this queue contains no elements + */ + public boolean isEmpty() { + return first() == null; + } + + /** + * Returns the number of elements in this queue. If this queue + * contains more than <tt>Integer.MAX_VALUE</tt> elements, returns + * <tt>Integer.MAX_VALUE</tt>. + * + * <p>Beware that, unlike in most collections, this method is + * <em>NOT</em> a constant-time operation. Because of the + * asynchronous nature of these queues, determining the current + * number of elements requires an O(n) traversal. + * + * @return the number of elements in this queue + */ + public int size() { + int count = 0; + for (Node<E> p = first(); p != null; p = p.getNext()) { + if (p.getItem() != null) { + // Collections.size() spec says to max out + if (++count == Integer.MAX_VALUE) + break; + } + } + return count; + } + + /** + * Returns <tt>true</tt> if this queue contains the specified element. + * More formally, returns <tt>true</tt> if and only if this queue contains + * at least one element <tt>e</tt> such that <tt>o.equals(e)</tt>. + * + * @param o object to be checked for containment in this queue + * @return <tt>true</tt> if this queue contains the specified element + */ + public boolean contains(Object o) { + if (o == null) return false; + for (Node<E> p = first(); p != null; p = p.getNext()) { + E item = p.getItem(); + if (item != null && + o.equals(item)) + return true; + } + return false; + } + + /** + * Removes a single instance of the specified element from this queue, + * if it is present. More formally, removes an element <tt>e</tt> such + * that <tt>o.equals(e)</tt>, if this queue contains one or more such + * elements. + * Returns <tt>true</tt> if this queue contained the specified element + * (or equivalently, if this queue changed as a result of the call). + * + * @param o element to be removed from this queue, if present + * @return <tt>true</tt> if this queue changed as a result of the call + */ + public boolean remove(Object o) { + if (o == null) return false; + for (Node<E> p = first(); p != null; p = p.getNext()) { + E item = p.getItem(); + if (item != null && + o.equals(item) && + p.casItem(item, null)) + return true; + } + return false; + } + + /** + * Returns an iterator over the elements in this queue in proper sequence. + * The returned iterator is a "weakly consistent" iterator that + * will never throw {@link ConcurrentModificationException}, + * and guarantees to traverse elements as they existed upon + * construction of the iterator, and may (but is not guaranteed to) + * reflect any modifications subsequent to construction. + * + * @return an iterator over the elements in this queue in proper sequence + */ + public Iterator<E> iterator() { + return new Itr(); + } + + private class Itr implements Iterator<E> { + /** + * Next node to return item for. + */ + private Node<E> nextNode; + + /** + * nextItem holds on to item fields because once we claim + * that an element exists in hasNext(), we must return it in + * the following next() call even if it was in the process of + * being removed when hasNext() was called. + */ + private E nextItem; + + /** + * Node of the last returned item, to support remove. + */ + private Node<E> lastRet; + + Itr() { + advance(); + } + + /** + * Moves to next valid node and returns item to return for + * next(), or null if no such. + */ + private E advance() { + lastRet = nextNode; + E x = nextItem; + + Node<E> p = (nextNode == null)? first() : nextNode.getNext(); + for (;;) { + if (p == null) { + nextNode = null; + nextItem = null; + return x; + } + E item = p.getItem(); + if (item != null) { + nextNode = p; + nextItem = item; + return x; + } else // skip over nulls + p = p.getNext(); + } + } + + public boolean hasNext() { + return nextNode != null; + } + + public E next() { + if (nextNode == null) throw new NoSuchElementException(); + return advance(); + } + + public void remove() { + Node<E> l = lastRet; + if (l == null) throw new IllegalStateException(); + // rely on a future traversal to relink. + l.setItem(null); + lastRet = null; + } + } + + /** + * Save the state to a stream (that is, serialize it). + * + * @serialData All of the elements (each an <tt>E</tt>) in + * the proper order, followed by a null + * @param s the stream + */ + private void writeObject(java.io.ObjectOutputStream s) + throws java.io.IOException { + + // Write out any hidden stuff + s.defaultWriteObject(); + + // Write out all elements in the proper order. + for (Node<E> p = first(); p != null; p = p.getNext()) { + Object item = p.getItem(); + if (item != null) + s.writeObject(item); + } + + // Use trailing null as sentinel + s.writeObject(null); + } + + /** + * Reconstitute the Queue instance from a stream (that is, + * deserialize it). + * @param s the stream + */ + private void readObject(java.io.ObjectInputStream s) + throws java.io.IOException, ClassNotFoundException { + // Read in capacity, and any hidden stuff + s.defaultReadObject(); + head = new Node<E>(null, null); + tail = head; + // Read in all elements and place in queue + for (;;) { + E item = (E)s.readObject(); + if (item == null) + break; + else + offer(item); + } + } + +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/ConcurrentMap.java b/libjava/classpath/external/jsr166/java/util/concurrent/ConcurrentMap.java new file mode 100644 index 000000000..6e5bd0738 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/ConcurrentMap.java @@ -0,0 +1,134 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; +import java.util.Map; + +/** + * A {@link java.util.Map} providing additional atomic + * <tt>putIfAbsent</tt>, <tt>remove</tt>, and <tt>replace</tt> methods. + * + * <p>Memory consistency effects: As with other concurrent + * collections, actions in a thread prior to placing an object into a + * {@code ConcurrentMap} as a key or value + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a> + * actions subsequent to the access or removal of that object from + * the {@code ConcurrentMap} in another thread. + * + * <p>This interface is a member of the + * <a href="{@docRoot}/../technotes/guides/collections/index.html"> + * Java Collections Framework</a>. + * + * @since 1.5 + * @author Doug Lea + * @param <K> the type of keys maintained by this map + * @param <V> the type of mapped values + */ +public interface ConcurrentMap<K, V> extends Map<K, V> { + /** + * If the specified key is not already associated + * with a value, associate it with the given value. + * This is equivalent to + * <pre> + * if (!map.containsKey(key)) + * return map.put(key, value); + * else + * return map.get(key);</pre> + * except that the action is performed atomically. + * + * @param key key with which the specified value is to be associated + * @param value value to be associated with the specified key + * @return the previous value associated with the specified key, or + * <tt>null</tt> if there was no mapping for the key. + * (A <tt>null</tt> return can also indicate that the map + * previously associated <tt>null</tt> with the key, + * if the implementation supports null values.) + * @throws UnsupportedOperationException if the <tt>put</tt> operation + * is not supported by this map + * @throws ClassCastException if the class of the specified key or value + * prevents it from being stored in this map + * @throws NullPointerException if the specified key or value is null, + * and this map does not permit null keys or values + * @throws IllegalArgumentException if some property of the specified key + * or value prevents it from being stored in this map + * + */ + V putIfAbsent(K key, V value); + + /** + * Removes the entry for a key only if currently mapped to a given value. + * This is equivalent to + * <pre> + * if (map.containsKey(key) && map.get(key).equals(value)) { + * map.remove(key); + * return true; + * } else return false;</pre> + * except that the action is performed atomically. + * + * @param key key with which the specified value is associated + * @param value value expected to be associated with the specified key + * @return <tt>true</tt> if the value was removed + * @throws UnsupportedOperationException if the <tt>remove</tt> operation + * is not supported by this map + * @throws ClassCastException if the key or value is of an inappropriate + * type for this map (optional) + * @throws NullPointerException if the specified key or value is null, + * and this map does not permit null keys or values (optional) + */ + boolean remove(Object key, Object value); + + /** + * Replaces the entry for a key only if currently mapped to a given value. + * This is equivalent to + * <pre> + * if (map.containsKey(key) && map.get(key).equals(oldValue)) { + * map.put(key, newValue); + * return true; + * } else return false;</pre> + * except that the action is performed atomically. + * + * @param key key with which the specified value is associated + * @param oldValue value expected to be associated with the specified key + * @param newValue value to be associated with the specified key + * @return <tt>true</tt> if the value was replaced + * @throws UnsupportedOperationException if the <tt>put</tt> operation + * is not supported by this map + * @throws ClassCastException if the class of a specified key or value + * prevents it from being stored in this map + * @throws NullPointerException if a specified key or value is null, + * and this map does not permit null keys or values + * @throws IllegalArgumentException if some property of a specified key + * or value prevents it from being stored in this map + */ + boolean replace(K key, V oldValue, V newValue); + + /** + * Replaces the entry for a key only if currently mapped to some value. + * This is equivalent to + * <pre> + * if (map.containsKey(key)) { + * return map.put(key, value); + * } else return null;</pre> + * except that the action is performed atomically. + * + * @param key key with which the specified value is associated + * @param value value to be associated with the specified key + * @return the previous value associated with the specified key, or + * <tt>null</tt> if there was no mapping for the key. + * (A <tt>null</tt> return can also indicate that the map + * previously associated <tt>null</tt> with the key, + * if the implementation supports null values.) + * @throws UnsupportedOperationException if the <tt>put</tt> operation + * is not supported by this map + * @throws ClassCastException if the class of the specified key or value + * prevents it from being stored in this map + * @throws NullPointerException if the specified key or value is null, + * and this map does not permit null keys or values + * @throws IllegalArgumentException if some property of the specified key + * or value prevents it from being stored in this map + */ + V replace(K key, V value); +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/ConcurrentNavigableMap.java b/libjava/classpath/external/jsr166/java/util/concurrent/ConcurrentNavigableMap.java new file mode 100644 index 000000000..7d86afb70 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/ConcurrentNavigableMap.java @@ -0,0 +1,148 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; +import java.util.*; + +/** + * A {@link ConcurrentMap} supporting {@link NavigableMap} operations, + * and recursively so for its navigable sub-maps. + * + * <p>This interface is a member of the + * <a href="{@docRoot}/../technotes/guides/collections/index.html"> + * Java Collections Framework</a>. + * + * @author Doug Lea + * @param <K> the type of keys maintained by this map + * @param <V> the type of mapped values + * @since 1.6 + */ +public interface ConcurrentNavigableMap<K,V> + extends ConcurrentMap<K,V>, NavigableMap<K,V> +{ + /** + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + * @throws IllegalArgumentException {@inheritDoc} + */ + ConcurrentNavigableMap<K,V> subMap(K fromKey, boolean fromInclusive, + K toKey, boolean toInclusive); + + /** + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + * @throws IllegalArgumentException {@inheritDoc} + */ + ConcurrentNavigableMap<K,V> headMap(K toKey, boolean inclusive); + + + /** + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + * @throws IllegalArgumentException {@inheritDoc} + */ + ConcurrentNavigableMap<K,V> tailMap(K fromKey, boolean inclusive); + + /** + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + * @throws IllegalArgumentException {@inheritDoc} + */ + ConcurrentNavigableMap<K,V> subMap(K fromKey, K toKey); + + /** + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + * @throws IllegalArgumentException {@inheritDoc} + */ + ConcurrentNavigableMap<K,V> headMap(K toKey); + + /** + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + * @throws IllegalArgumentException {@inheritDoc} + */ + ConcurrentNavigableMap<K,V> tailMap(K fromKey); + + /** + * Returns a reverse order view of the mappings contained in this map. + * The descending map is backed by this map, so changes to the map are + * reflected in the descending map, and vice-versa. + * + * <p>The returned map has an ordering equivalent to + * <tt>{@link Collections#reverseOrder(Comparator) Collections.reverseOrder}(comparator())</tt>. + * The expression {@code m.descendingMap().descendingMap()} returns a + * view of {@code m} essentially equivalent to {@code m}. + * + * @return a reverse order view of this map + */ + ConcurrentNavigableMap<K,V> descendingMap(); + + /** + * Returns a {@link NavigableSet} view of the keys contained in this map. + * The set's iterator returns the keys in ascending order. + * The set is backed by the map, so changes to the map are + * reflected in the set, and vice-versa. The set supports element + * removal, which removes the corresponding mapping from the map, + * via the {@code Iterator.remove}, {@code Set.remove}, + * {@code removeAll}, {@code retainAll}, and {@code clear} + * operations. It does not support the {@code add} or {@code addAll} + * operations. + * + * <p>The view's {@code iterator} is a "weakly consistent" iterator + * that will never throw {@link ConcurrentModificationException}, + * and guarantees to traverse elements as they existed upon + * construction of the iterator, and may (but is not guaranteed to) + * reflect any modifications subsequent to construction. + * + * @return a navigable set view of the keys in this map + */ + public NavigableSet<K> navigableKeySet(); + + /** + * Returns a {@link NavigableSet} view of the keys contained in this map. + * The set's iterator returns the keys in ascending order. + * The set is backed by the map, so changes to the map are + * reflected in the set, and vice-versa. The set supports element + * removal, which removes the corresponding mapping from the map, + * via the {@code Iterator.remove}, {@code Set.remove}, + * {@code removeAll}, {@code retainAll}, and {@code clear} + * operations. It does not support the {@code add} or {@code addAll} + * operations. + * + * <p>The view's {@code iterator} is a "weakly consistent" iterator + * that will never throw {@link ConcurrentModificationException}, + * and guarantees to traverse elements as they existed upon + * construction of the iterator, and may (but is not guaranteed to) + * reflect any modifications subsequent to construction. + * + * <p>This method is equivalent to method {@code navigableKeySet}. + * + * @return a navigable set view of the keys in this map + */ + NavigableSet<K> keySet(); + + /** + * Returns a reverse order {@link NavigableSet} view of the keys contained in this map. + * The set's iterator returns the keys in descending order. + * The set is backed by the map, so changes to the map are + * reflected in the set, and vice-versa. The set supports element + * removal, which removes the corresponding mapping from the map, + * via the {@code Iterator.remove}, {@code Set.remove}, + * {@code removeAll}, {@code retainAll}, and {@code clear} + * operations. It does not support the {@code add} or {@code addAll} + * operations. + * + * <p>The view's {@code iterator} is a "weakly consistent" iterator + * that will never throw {@link ConcurrentModificationException}, + * and guarantees to traverse elements as they existed upon + * construction of the iterator, and may (but is not guaranteed to) + * reflect any modifications subsequent to construction. + * + * @return a reverse order navigable set view of the keys in this map + */ + public NavigableSet<K> descendingKeySet(); +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/ConcurrentSkipListMap.java b/libjava/classpath/external/jsr166/java/util/concurrent/ConcurrentSkipListMap.java new file mode 100644 index 000000000..1ad924454 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/ConcurrentSkipListMap.java @@ -0,0 +1,3114 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; +import java.util.*; +import java.util.concurrent.atomic.*; + +/** + * A scalable concurrent {@link ConcurrentNavigableMap} implementation. + * The map is sorted according to the {@linkplain Comparable natural + * ordering} of its keys, or by a {@link Comparator} provided at map + * creation time, depending on which constructor is used. + * + * <p>This class implements a concurrent variant of <a + * href="http://www.cs.umd.edu/~pugh/">SkipLists</a> providing + * expected average <i>log(n)</i> time cost for the + * <tt>containsKey</tt>, <tt>get</tt>, <tt>put</tt> and + * <tt>remove</tt> operations and their variants. Insertion, removal, + * update, and access operations safely execute concurrently by + * multiple threads. Iterators are <i>weakly consistent</i>, returning + * elements reflecting the state of the map at some point at or since + * the creation of the iterator. They do <em>not</em> throw {@link + * ConcurrentModificationException}, and may proceed concurrently with + * other operations. Ascending key ordered views and their iterators + * are faster than descending ones. + * + * <p>All <tt>Map.Entry</tt> pairs returned by methods in this class + * and its views represent snapshots of mappings at the time they were + * produced. They do <em>not</em> support the <tt>Entry.setValue</tt> + * method. (Note however that it is possible to change mappings in the + * associated map using <tt>put</tt>, <tt>putIfAbsent</tt>, or + * <tt>replace</tt>, depending on exactly which effect you need.) + * + * <p>Beware that, unlike in most collections, the <tt>size</tt> + * method is <em>not</em> a constant-time operation. Because of the + * asynchronous nature of these maps, determining the current number + * of elements requires a traversal of the elements. Additionally, + * the bulk operations <tt>putAll</tt>, <tt>equals</tt>, and + * <tt>clear</tt> are <em>not</em> guaranteed to be performed + * atomically. For example, an iterator operating concurrently with a + * <tt>putAll</tt> operation might view only some of the added + * elements. + * + * <p>This class and its views and iterators implement all of the + * <em>optional</em> methods of the {@link Map} and {@link Iterator} + * interfaces. Like most other concurrent collections, this class does + * <em>not</em> permit the use of <tt>null</tt> keys or values because some + * null return values cannot be reliably distinguished from the absence of + * elements. + * + * <p>This class is a member of the + * <a href="{@docRoot}/../technotes/guides/collections/index.html"> + * Java Collections Framework</a>. + * + * @author Doug Lea + * @param <K> the type of keys maintained by this map + * @param <V> the type of mapped values + * @since 1.6 + */ +public class ConcurrentSkipListMap<K,V> extends AbstractMap<K,V> + implements ConcurrentNavigableMap<K,V>, + Cloneable, + java.io.Serializable { + /* + * This class implements a tree-like two-dimensionally linked skip + * list in which the index levels are represented in separate + * nodes from the base nodes holding data. There are two reasons + * for taking this approach instead of the usual array-based + * structure: 1) Array based implementations seem to encounter + * more complexity and overhead 2) We can use cheaper algorithms + * for the heavily-traversed index lists than can be used for the + * base lists. Here's a picture of some of the basics for a + * possible list with 2 levels of index: + * + * Head nodes Index nodes + * +-+ right +-+ +-+ + * |2|---------------->| |--------------------->| |->null + * +-+ +-+ +-+ + * | down | | + * v v v + * +-+ +-+ +-+ +-+ +-+ +-+ + * |1|----------->| |->| |------>| |----------->| |------>| |->null + * +-+ +-+ +-+ +-+ +-+ +-+ + * v | | | | | + * Nodes next v v v v v + * +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ + * | |->|A|->|B|->|C|->|D|->|E|->|F|->|G|->|H|->|I|->|J|->|K|->null + * +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ + * + * The base lists use a variant of the HM linked ordered set + * algorithm. See Tim Harris, "A pragmatic implementation of + * non-blocking linked lists" + * http://www.cl.cam.ac.uk/~tlh20/publications.html and Maged + * Michael "High Performance Dynamic Lock-Free Hash Tables and + * List-Based Sets" + * http://www.research.ibm.com/people/m/michael/pubs.htm. The + * basic idea in these lists is to mark the "next" pointers of + * deleted nodes when deleting to avoid conflicts with concurrent + * insertions, and when traversing to keep track of triples + * (predecessor, node, successor) in order to detect when and how + * to unlink these deleted nodes. + * + * Rather than using mark-bits to mark list deletions (which can + * be slow and space-intensive using AtomicMarkedReference), nodes + * use direct CAS'able next pointers. On deletion, instead of + * marking a pointer, they splice in another node that can be + * thought of as standing for a marked pointer (indicating this by + * using otherwise impossible field values). Using plain nodes + * acts roughly like "boxed" implementations of marked pointers, + * but uses new nodes only when nodes are deleted, not for every + * link. This requires less space and supports faster + * traversal. Even if marked references were better supported by + * JVMs, traversal using this technique might still be faster + * because any search need only read ahead one more node than + * otherwise required (to check for trailing marker) rather than + * unmasking mark bits or whatever on each read. + * + * This approach maintains the essential property needed in the HM + * algorithm of changing the next-pointer of a deleted node so + * that any other CAS of it will fail, but implements the idea by + * changing the pointer to point to a different node, not by + * marking it. While it would be possible to further squeeze + * space by defining marker nodes not to have key/value fields, it + * isn't worth the extra type-testing overhead. The deletion + * markers are rarely encountered during traversal and are + * normally quickly garbage collected. (Note that this technique + * would not work well in systems without garbage collection.) + * + * In addition to using deletion markers, the lists also use + * nullness of value fields to indicate deletion, in a style + * similar to typical lazy-deletion schemes. If a node's value is + * null, then it is considered logically deleted and ignored even + * though it is still reachable. This maintains proper control of + * concurrent replace vs delete operations -- an attempted replace + * must fail if a delete beat it by nulling field, and a delete + * must return the last non-null value held in the field. (Note: + * Null, rather than some special marker, is used for value fields + * here because it just so happens to mesh with the Map API + * requirement that method get returns null if there is no + * mapping, which allows nodes to remain concurrently readable + * even when deleted. Using any other marker value here would be + * messy at best.) + * + * Here's the sequence of events for a deletion of node n with + * predecessor b and successor f, initially: + * + * +------+ +------+ +------+ + * ... | b |------>| n |----->| f | ... + * +------+ +------+ +------+ + * + * 1. CAS n's value field from non-null to null. + * From this point on, no public operations encountering + * the node consider this mapping to exist. However, other + * ongoing insertions and deletions might still modify + * n's next pointer. + * + * 2. CAS n's next pointer to point to a new marker node. + * From this point on, no other nodes can be appended to n. + * which avoids deletion errors in CAS-based linked lists. + * + * +------+ +------+ +------+ +------+ + * ... | b |------>| n |----->|marker|------>| f | ... + * +------+ +------+ +------+ +------+ + * + * 3. CAS b's next pointer over both n and its marker. + * From this point on, no new traversals will encounter n, + * and it can eventually be GCed. + * +------+ +------+ + * ... | b |----------------------------------->| f | ... + * +------+ +------+ + * + * A failure at step 1 leads to simple retry due to a lost race + * with another operation. Steps 2-3 can fail because some other + * thread noticed during a traversal a node with null value and + * helped out by marking and/or unlinking. This helping-out + * ensures that no thread can become stuck waiting for progress of + * the deleting thread. The use of marker nodes slightly + * complicates helping-out code because traversals must track + * consistent reads of up to four nodes (b, n, marker, f), not + * just (b, n, f), although the next field of a marker is + * immutable, and once a next field is CAS'ed to point to a + * marker, it never again changes, so this requires less care. + * + * Skip lists add indexing to this scheme, so that the base-level + * traversals start close to the locations being found, inserted + * or deleted -- usually base level traversals only traverse a few + * nodes. This doesn't change the basic algorithm except for the + * need to make sure base traversals start at predecessors (here, + * b) that are not (structurally) deleted, otherwise retrying + * after processing the deletion. + * + * Index levels are maintained as lists with volatile next fields, + * using CAS to link and unlink. Races are allowed in index-list + * operations that can (rarely) fail to link in a new index node + * or delete one. (We can't do this of course for data nodes.) + * However, even when this happens, the index lists remain sorted, + * so correctly serve as indices. This can impact performance, + * but since skip lists are probabilistic anyway, the net result + * is that under contention, the effective "p" value may be lower + * than its nominal value. And race windows are kept small enough + * that in practice these failures are rare, even under a lot of + * contention. + * + * The fact that retries (for both base and index lists) are + * relatively cheap due to indexing allows some minor + * simplifications of retry logic. Traversal restarts are + * performed after most "helping-out" CASes. This isn't always + * strictly necessary, but the implicit backoffs tend to help + * reduce other downstream failed CAS's enough to outweigh restart + * cost. This worsens the worst case, but seems to improve even + * highly contended cases. + * + * Unlike most skip-list implementations, index insertion and + * deletion here require a separate traversal pass occuring after + * the base-level action, to add or remove index nodes. This adds + * to single-threaded overhead, but improves contended + * multithreaded performance by narrowing interference windows, + * and allows deletion to ensure that all index nodes will be made + * unreachable upon return from a public remove operation, thus + * avoiding unwanted garbage retention. This is more important + * here than in some other data structures because we cannot null + * out node fields referencing user keys since they might still be + * read by other ongoing traversals. + * + * Indexing uses skip list parameters that maintain good search + * performance while using sparser-than-usual indices: The + * hardwired parameters k=1, p=0.5 (see method randomLevel) mean + * that about one-quarter of the nodes have indices. Of those that + * do, half have one level, a quarter have two, and so on (see + * Pugh's Skip List Cookbook, sec 3.4). The expected total space + * requirement for a map is slightly less than for the current + * implementation of java.util.TreeMap. + * + * Changing the level of the index (i.e, the height of the + * tree-like structure) also uses CAS. The head index has initial + * level/height of one. Creation of an index with height greater + * than the current level adds a level to the head index by + * CAS'ing on a new top-most head. To maintain good performance + * after a lot of removals, deletion methods heuristically try to + * reduce the height if the topmost levels appear to be empty. + * This may encounter races in which it possible (but rare) to + * reduce and "lose" a level just as it is about to contain an + * index (that will then never be encountered). This does no + * structural harm, and in practice appears to be a better option + * than allowing unrestrained growth of levels. + * + * The code for all this is more verbose than you'd like. Most + * operations entail locating an element (or position to insert an + * element). The code to do this can't be nicely factored out + * because subsequent uses require a snapshot of predecessor + * and/or successor and/or value fields which can't be returned + * all at once, at least not without creating yet another object + * to hold them -- creating such little objects is an especially + * bad idea for basic internal search operations because it adds + * to GC overhead. (This is one of the few times I've wished Java + * had macros.) Instead, some traversal code is interleaved within + * insertion and removal operations. The control logic to handle + * all the retry conditions is sometimes twisty. Most search is + * broken into 2 parts. findPredecessor() searches index nodes + * only, returning a base-level predecessor of the key. findNode() + * finishes out the base-level search. Even with this factoring, + * there is a fair amount of near-duplication of code to handle + * variants. + * + * For explanation of algorithms sharing at least a couple of + * features with this one, see Mikhail Fomitchev's thesis + * (http://www.cs.yorku.ca/~mikhail/), Keir Fraser's thesis + * (http://www.cl.cam.ac.uk/users/kaf24/), and Hakan Sundell's + * thesis (http://www.cs.chalmers.se/~phs/). + * + * Given the use of tree-like index nodes, you might wonder why + * this doesn't use some kind of search tree instead, which would + * support somewhat faster search operations. The reason is that + * there are no known efficient lock-free insertion and deletion + * algorithms for search trees. The immutability of the "down" + * links of index nodes (as opposed to mutable "left" fields in + * true trees) makes this tractable using only CAS operations. + * + * Notation guide for local variables + * Node: b, n, f for predecessor, node, successor + * Index: q, r, d for index node, right, down. + * t for another index node + * Head: h + * Levels: j + * Keys: k, key + * Values: v, value + * Comparisons: c + */ + + private static final long serialVersionUID = -8627078645895051609L; + + /** + * Generates the initial random seed for the cheaper per-instance + * random number generators used in randomLevel. + */ + private static final Random seedGenerator = new Random(); + + /** + * Special value used to identify base-level header + */ + private static final Object BASE_HEADER = new Object(); + + /** + * The topmost head index of the skiplist. + */ + private transient volatile HeadIndex<K,V> head; + + /** + * The comparator used to maintain order in this map, or null + * if using natural ordering. + * @serial + */ + private final Comparator<? super K> comparator; + + /** + * Seed for simple random number generator. Not volatile since it + * doesn't matter too much if different threads don't see updates. + */ + private transient int randomSeed; + + /** Lazily initialized key set */ + private transient KeySet keySet; + /** Lazily initialized entry set */ + private transient EntrySet entrySet; + /** Lazily initialized values collection */ + private transient Values values; + /** Lazily initialized descending key set */ + private transient ConcurrentNavigableMap<K,V> descendingMap; + + /** + * Initializes or resets state. Needed by constructors, clone, + * clear, readObject. and ConcurrentSkipListSet.clone. + * (Note that comparator must be separately initialized.) + */ + final void initialize() { + keySet = null; + entrySet = null; + values = null; + descendingMap = null; + randomSeed = seedGenerator.nextInt() | 0x0100; // ensure nonzero + head = new HeadIndex<K,V>(new Node<K,V>(null, BASE_HEADER, null), + null, null, 1); + } + + /** Updater for casHead */ + private static final + AtomicReferenceFieldUpdater<ConcurrentSkipListMap, HeadIndex> + headUpdater = AtomicReferenceFieldUpdater.newUpdater + (ConcurrentSkipListMap.class, HeadIndex.class, "head"); + + /** + * compareAndSet head node + */ + private boolean casHead(HeadIndex<K,V> cmp, HeadIndex<K,V> val) { + return headUpdater.compareAndSet(this, cmp, val); + } + + /* ---------------- Nodes -------------- */ + + /** + * Nodes hold keys and values, and are singly linked in sorted + * order, possibly with some intervening marker nodes. The list is + * headed by a dummy node accessible as head.node. The value field + * is declared only as Object because it takes special non-V + * values for marker and header nodes. + */ + static final class Node<K,V> { + final K key; + volatile Object value; + volatile Node<K,V> next; + + /** + * Creates a new regular node. + */ + Node(K key, Object value, Node<K,V> next) { + this.key = key; + this.value = value; + this.next = next; + } + + /** + * Creates a new marker node. A marker is distinguished by + * having its value field point to itself. Marker nodes also + * have null keys, a fact that is exploited in a few places, + * but this doesn't distinguish markers from the base-level + * header node (head.node), which also has a null key. + */ + Node(Node<K,V> next) { + this.key = null; + this.value = this; + this.next = next; + } + + /** Updater for casNext */ + static final AtomicReferenceFieldUpdater<Node, Node> + nextUpdater = AtomicReferenceFieldUpdater.newUpdater + (Node.class, Node.class, "next"); + + /** Updater for casValue */ + static final AtomicReferenceFieldUpdater<Node, Object> + valueUpdater = AtomicReferenceFieldUpdater.newUpdater + (Node.class, Object.class, "value"); + + /** + * compareAndSet value field + */ + boolean casValue(Object cmp, Object val) { + return valueUpdater.compareAndSet(this, cmp, val); + } + + /** + * compareAndSet next field + */ + boolean casNext(Node<K,V> cmp, Node<K,V> val) { + return nextUpdater.compareAndSet(this, cmp, val); + } + + /** + * Returns true if this node is a marker. This method isn't + * actually called in any current code checking for markers + * because callers will have already read value field and need + * to use that read (not another done here) and so directly + * test if value points to node. + * @param n a possibly null reference to a node + * @return true if this node is a marker node + */ + boolean isMarker() { + return value == this; + } + + /** + * Returns true if this node is the header of base-level list. + * @return true if this node is header node + */ + boolean isBaseHeader() { + return value == BASE_HEADER; + } + + /** + * Tries to append a deletion marker to this node. + * @param f the assumed current successor of this node + * @return true if successful + */ + boolean appendMarker(Node<K,V> f) { + return casNext(f, new Node<K,V>(f)); + } + + /** + * Helps out a deletion by appending marker or unlinking from + * predecessor. This is called during traversals when value + * field seen to be null. + * @param b predecessor + * @param f successor + */ + void helpDelete(Node<K,V> b, Node<K,V> f) { + /* + * Rechecking links and then doing only one of the + * help-out stages per call tends to minimize CAS + * interference among helping threads. + */ + if (f == next && this == b.next) { + if (f == null || f.value != f) // not already marked + appendMarker(f); + else + b.casNext(this, f.next); + } + } + + /** + * Returns value if this node contains a valid key-value pair, + * else null. + * @return this node's value if it isn't a marker or header or + * is deleted, else null. + */ + V getValidValue() { + Object v = value; + if (v == this || v == BASE_HEADER) + return null; + return (V)v; + } + + /** + * Creates and returns a new SimpleImmutableEntry holding current + * mapping if this node holds a valid value, else null. + * @return new entry or null + */ + AbstractMap.SimpleImmutableEntry<K,V> createSnapshot() { + V v = getValidValue(); + if (v == null) + return null; + return new AbstractMap.SimpleImmutableEntry<K,V>(key, v); + } + } + + /* ---------------- Indexing -------------- */ + + /** + * Index nodes represent the levels of the skip list. Note that + * even though both Nodes and Indexes have forward-pointing + * fields, they have different types and are handled in different + * ways, that can't nicely be captured by placing field in a + * shared abstract class. + */ + static class Index<K,V> { + final Node<K,V> node; + final Index<K,V> down; + volatile Index<K,V> right; + + /** + * Creates index node with given values. + */ + Index(Node<K,V> node, Index<K,V> down, Index<K,V> right) { + this.node = node; + this.down = down; + this.right = right; + } + + /** Updater for casRight */ + static final AtomicReferenceFieldUpdater<Index, Index> + rightUpdater = AtomicReferenceFieldUpdater.newUpdater + (Index.class, Index.class, "right"); + + /** + * compareAndSet right field + */ + final boolean casRight(Index<K,V> cmp, Index<K,V> val) { + return rightUpdater.compareAndSet(this, cmp, val); + } + + /** + * Returns true if the node this indexes has been deleted. + * @return true if indexed node is known to be deleted + */ + final boolean indexesDeletedNode() { + return node.value == null; + } + + /** + * Tries to CAS newSucc as successor. To minimize races with + * unlink that may lose this index node, if the node being + * indexed is known to be deleted, it doesn't try to link in. + * @param succ the expected current successor + * @param newSucc the new successor + * @return true if successful + */ + final boolean link(Index<K,V> succ, Index<K,V> newSucc) { + Node<K,V> n = node; + newSucc.right = succ; + return n.value != null && casRight(succ, newSucc); + } + + /** + * Tries to CAS right field to skip over apparent successor + * succ. Fails (forcing a retraversal by caller) if this node + * is known to be deleted. + * @param succ the expected current successor + * @return true if successful + */ + final boolean unlink(Index<K,V> succ) { + return !indexesDeletedNode() && casRight(succ, succ.right); + } + } + + /* ---------------- Head nodes -------------- */ + + /** + * Nodes heading each level keep track of their level. + */ + static final class HeadIndex<K,V> extends Index<K,V> { + final int level; + HeadIndex(Node<K,V> node, Index<K,V> down, Index<K,V> right, int level) { + super(node, down, right); + this.level = level; + } + } + + /* ---------------- Comparison utilities -------------- */ + + /** + * Represents a key with a comparator as a Comparable. + * + * Because most sorted collections seem to use natural ordering on + * Comparables (Strings, Integers, etc), most internal methods are + * geared to use them. This is generally faster than checking + * per-comparison whether to use comparator or comparable because + * it doesn't require a (Comparable) cast for each comparison. + * (Optimizers can only sometimes remove such redundant checks + * themselves.) When Comparators are used, + * ComparableUsingComparators are created so that they act in the + * same way as natural orderings. This penalizes use of + * Comparators vs Comparables, which seems like the right + * tradeoff. + */ + static final class ComparableUsingComparator<K> implements Comparable<K> { + final K actualKey; + final Comparator<? super K> cmp; + ComparableUsingComparator(K key, Comparator<? super K> cmp) { + this.actualKey = key; + this.cmp = cmp; + } + public int compareTo(K k2) { + return cmp.compare(actualKey, k2); + } + } + + /** + * If using comparator, return a ComparableUsingComparator, else + * cast key as Comparable, which may cause ClassCastException, + * which is propagated back to caller. + */ + private Comparable<? super K> comparable(Object key) throws ClassCastException { + if (key == null) + throw new NullPointerException(); + if (comparator != null) + return new ComparableUsingComparator<K>((K)key, comparator); + else + return (Comparable<? super K>)key; + } + + /** + * Compares using comparator or natural ordering. Used when the + * ComparableUsingComparator approach doesn't apply. + */ + int compare(K k1, K k2) throws ClassCastException { + Comparator<? super K> cmp = comparator; + if (cmp != null) + return cmp.compare(k1, k2); + else + return ((Comparable<? super K>)k1).compareTo(k2); + } + + /** + * Returns true if given key greater than or equal to least and + * strictly less than fence, bypassing either test if least or + * fence are null. Needed mainly in submap operations. + */ + boolean inHalfOpenRange(K key, K least, K fence) { + if (key == null) + throw new NullPointerException(); + return ((least == null || compare(key, least) >= 0) && + (fence == null || compare(key, fence) < 0)); + } + + /** + * Returns true if given key greater than or equal to least and less + * or equal to fence. Needed mainly in submap operations. + */ + boolean inOpenRange(K key, K least, K fence) { + if (key == null) + throw new NullPointerException(); + return ((least == null || compare(key, least) >= 0) && + (fence == null || compare(key, fence) <= 0)); + } + + /* ---------------- Traversal -------------- */ + + /** + * Returns a base-level node with key strictly less than given key, + * or the base-level header if there is no such node. Also + * unlinks indexes to deleted nodes found along the way. Callers + * rely on this side-effect of clearing indices to deleted nodes. + * @param key the key + * @return a predecessor of key + */ + private Node<K,V> findPredecessor(Comparable<? super K> key) { + if (key == null) + throw new NullPointerException(); // don't postpone errors + for (;;) { + Index<K,V> q = head; + Index<K,V> r = q.right; + for (;;) { + if (r != null) { + Node<K,V> n = r.node; + K k = n.key; + if (n.value == null) { + if (!q.unlink(r)) + break; // restart + r = q.right; // reread r + continue; + } + if (key.compareTo(k) > 0) { + q = r; + r = r.right; + continue; + } + } + Index<K,V> d = q.down; + if (d != null) { + q = d; + r = d.right; + } else + return q.node; + } + } + } + + /** + * Returns node holding key or null if no such, clearing out any + * deleted nodes seen along the way. Repeatedly traverses at + * base-level looking for key starting at predecessor returned + * from findPredecessor, processing base-level deletions as + * encountered. Some callers rely on this side-effect of clearing + * deleted nodes. + * + * Restarts occur, at traversal step centered on node n, if: + * + * (1) After reading n's next field, n is no longer assumed + * predecessor b's current successor, which means that + * we don't have a consistent 3-node snapshot and so cannot + * unlink any subsequent deleted nodes encountered. + * + * (2) n's value field is null, indicating n is deleted, in + * which case we help out an ongoing structural deletion + * before retrying. Even though there are cases where such + * unlinking doesn't require restart, they aren't sorted out + * here because doing so would not usually outweigh cost of + * restarting. + * + * (3) n is a marker or n's predecessor's value field is null, + * indicating (among other possibilities) that + * findPredecessor returned a deleted node. We can't unlink + * the node because we don't know its predecessor, so rely + * on another call to findPredecessor to notice and return + * some earlier predecessor, which it will do. This check is + * only strictly needed at beginning of loop, (and the + * b.value check isn't strictly needed at all) but is done + * each iteration to help avoid contention with other + * threads by callers that will fail to be able to change + * links, and so will retry anyway. + * + * The traversal loops in doPut, doRemove, and findNear all + * include the same three kinds of checks. And specialized + * versions appear in findFirst, and findLast and their + * variants. They can't easily share code because each uses the + * reads of fields held in locals occurring in the orders they + * were performed. + * + * @param key the key + * @return node holding key, or null if no such + */ + private Node<K,V> findNode(Comparable<? super K> key) { + for (;;) { + Node<K,V> b = findPredecessor(key); + Node<K,V> n = b.next; + for (;;) { + if (n == null) + return null; + Node<K,V> f = n.next; + if (n != b.next) // inconsistent read + break; + Object v = n.value; + if (v == null) { // n is deleted + n.helpDelete(b, f); + break; + } + if (v == n || b.value == null) // b is deleted + break; + int c = key.compareTo(n.key); + if (c == 0) + return n; + if (c < 0) + return null; + b = n; + n = f; + } + } + } + + /** + * Specialized variant of findNode to perform Map.get. Does a weak + * traversal, not bothering to fix any deleted index nodes, + * returning early if it happens to see key in index, and passing + * over any deleted base nodes, falling back to getUsingFindNode + * only if it would otherwise return value from an ongoing + * deletion. Also uses "bound" to eliminate need for some + * comparisons (see Pugh Cookbook). Also folds uses of null checks + * and node-skipping because markers have null keys. + * @param okey the key + * @return the value, or null if absent + */ + private V doGet(Object okey) { + Comparable<? super K> key = comparable(okey); + Node<K,V> bound = null; + Index<K,V> q = head; + Index<K,V> r = q.right; + Node<K,V> n; + K k; + int c; + for (;;) { + Index<K,V> d; + // Traverse rights + if (r != null && (n = r.node) != bound && (k = n.key) != null) { + if ((c = key.compareTo(k)) > 0) { + q = r; + r = r.right; + continue; + } else if (c == 0) { + Object v = n.value; + return (v != null)? (V)v : getUsingFindNode(key); + } else + bound = n; + } + + // Traverse down + if ((d = q.down) != null) { + q = d; + r = d.right; + } else + break; + } + + // Traverse nexts + for (n = q.node.next; n != null; n = n.next) { + if ((k = n.key) != null) { + if ((c = key.compareTo(k)) == 0) { + Object v = n.value; + return (v != null)? (V)v : getUsingFindNode(key); + } else if (c < 0) + break; + } + } + return null; + } + + /** + * Performs map.get via findNode. Used as a backup if doGet + * encounters an in-progress deletion. + * @param key the key + * @return the value, or null if absent + */ + private V getUsingFindNode(Comparable<? super K> key) { + /* + * Loop needed here and elsewhere in case value field goes + * null just as it is about to be returned, in which case we + * lost a race with a deletion, so must retry. + */ + for (;;) { + Node<K,V> n = findNode(key); + if (n == null) + return null; + Object v = n.value; + if (v != null) + return (V)v; + } + } + + /* ---------------- Insertion -------------- */ + + /** + * Main insertion method. Adds element if not present, or + * replaces value if present and onlyIfAbsent is false. + * @param kkey the key + * @param value the value that must be associated with key + * @param onlyIfAbsent if should not insert if already present + * @return the old value, or null if newly inserted + */ + private V doPut(K kkey, V value, boolean onlyIfAbsent) { + Comparable<? super K> key = comparable(kkey); + for (;;) { + Node<K,V> b = findPredecessor(key); + Node<K,V> n = b.next; + for (;;) { + if (n != null) { + Node<K,V> f = n.next; + if (n != b.next) // inconsistent read + break; + Object v = n.value; + if (v == null) { // n is deleted + n.helpDelete(b, f); + break; + } + if (v == n || b.value == null) // b is deleted + break; + int c = key.compareTo(n.key); + if (c > 0) { + b = n; + n = f; + continue; + } + if (c == 0) { + if (onlyIfAbsent || n.casValue(v, value)) + return (V)v; + else + break; // restart if lost race to replace value + } + // else c < 0; fall through + } + + Node<K,V> z = new Node<K,V>(kkey, value, n); + if (!b.casNext(n, z)) + break; // restart if lost race to append to b + int level = randomLevel(); + if (level > 0) + insertIndex(z, level); + return null; + } + } + } + + /** + * Returns a random level for inserting a new node. + * Hardwired to k=1, p=0.5, max 31 (see above and + * Pugh's "Skip List Cookbook", sec 3.4). + * + * This uses the simplest of the generators described in George + * Marsaglia's "Xorshift RNGs" paper. This is not a high-quality + * generator but is acceptable here. + */ + private int randomLevel() { + int x = randomSeed; + x ^= x << 13; + x ^= x >>> 17; + randomSeed = x ^= x << 5; + if ((x & 0x8001) != 0) // test highest and lowest bits + return 0; + int level = 1; + while (((x >>>= 1) & 1) != 0) ++level; + return level; + } + + /** + * Creates and adds index nodes for the given node. + * @param z the node + * @param level the level of the index + */ + private void insertIndex(Node<K,V> z, int level) { + HeadIndex<K,V> h = head; + int max = h.level; + + if (level <= max) { + Index<K,V> idx = null; + for (int i = 1; i <= level; ++i) + idx = new Index<K,V>(z, idx, null); + addIndex(idx, h, level); + + } else { // Add a new level + /* + * To reduce interference by other threads checking for + * empty levels in tryReduceLevel, new levels are added + * with initialized right pointers. Which in turn requires + * keeping levels in an array to access them while + * creating new head index nodes from the opposite + * direction. + */ + level = max + 1; + Index<K,V>[] idxs = (Index<K,V>[])new Index[level+1]; + Index<K,V> idx = null; + for (int i = 1; i <= level; ++i) + idxs[i] = idx = new Index<K,V>(z, idx, null); + + HeadIndex<K,V> oldh; + int k; + for (;;) { + oldh = head; + int oldLevel = oldh.level; + if (level <= oldLevel) { // lost race to add level + k = level; + break; + } + HeadIndex<K,V> newh = oldh; + Node<K,V> oldbase = oldh.node; + for (int j = oldLevel+1; j <= level; ++j) + newh = new HeadIndex<K,V>(oldbase, newh, idxs[j], j); + if (casHead(oldh, newh)) { + k = oldLevel; + break; + } + } + addIndex(idxs[k], oldh, k); + } + } + + /** + * Adds given index nodes from given level down to 1. + * @param idx the topmost index node being inserted + * @param h the value of head to use to insert. This must be + * snapshotted by callers to provide correct insertion level + * @param indexLevel the level of the index + */ + private void addIndex(Index<K,V> idx, HeadIndex<K,V> h, int indexLevel) { + // Track next level to insert in case of retries + int insertionLevel = indexLevel; + Comparable<? super K> key = comparable(idx.node.key); + if (key == null) throw new NullPointerException(); + + // Similar to findPredecessor, but adding index nodes along + // path to key. + for (;;) { + int j = h.level; + Index<K,V> q = h; + Index<K,V> r = q.right; + Index<K,V> t = idx; + for (;;) { + if (r != null) { + Node<K,V> n = r.node; + // compare before deletion check avoids needing recheck + int c = key.compareTo(n.key); + if (n.value == null) { + if (!q.unlink(r)) + break; + r = q.right; + continue; + } + if (c > 0) { + q = r; + r = r.right; + continue; + } + } + + if (j == insertionLevel) { + // Don't insert index if node already deleted + if (t.indexesDeletedNode()) { + findNode(key); // cleans up + return; + } + if (!q.link(r, t)) + break; // restart + if (--insertionLevel == 0) { + // need final deletion check before return + if (t.indexesDeletedNode()) + findNode(key); + return; + } + } + + if (--j >= insertionLevel && j < indexLevel) + t = t.down; + q = q.down; + r = q.right; + } + } + } + + /* ---------------- Deletion -------------- */ + + /** + * Main deletion method. Locates node, nulls value, appends a + * deletion marker, unlinks predecessor, removes associated index + * nodes, and possibly reduces head index level. + * + * Index nodes are cleared out simply by calling findPredecessor. + * which unlinks indexes to deleted nodes found along path to key, + * which will include the indexes to this node. This is done + * unconditionally. We can't check beforehand whether there are + * index nodes because it might be the case that some or all + * indexes hadn't been inserted yet for this node during initial + * search for it, and we'd like to ensure lack of garbage + * retention, so must call to be sure. + * + * @param okey the key + * @param value if non-null, the value that must be + * associated with key + * @return the node, or null if not found + */ + final V doRemove(Object okey, Object value) { + Comparable<? super K> key = comparable(okey); + for (;;) { + Node<K,V> b = findPredecessor(key); + Node<K,V> n = b.next; + for (;;) { + if (n == null) + return null; + Node<K,V> f = n.next; + if (n != b.next) // inconsistent read + break; + Object v = n.value; + if (v == null) { // n is deleted + n.helpDelete(b, f); + break; + } + if (v == n || b.value == null) // b is deleted + break; + int c = key.compareTo(n.key); + if (c < 0) + return null; + if (c > 0) { + b = n; + n = f; + continue; + } + if (value != null && !value.equals(v)) + return null; + if (!n.casValue(v, null)) + break; + if (!n.appendMarker(f) || !b.casNext(n, f)) + findNode(key); // Retry via findNode + else { + findPredecessor(key); // Clean index + if (head.right == null) + tryReduceLevel(); + } + return (V)v; + } + } + } + + /** + * Possibly reduce head level if it has no nodes. This method can + * (rarely) make mistakes, in which case levels can disappear even + * though they are about to contain index nodes. This impacts + * performance, not correctness. To minimize mistakes as well as + * to reduce hysteresis, the level is reduced by one only if the + * topmost three levels look empty. Also, if the removed level + * looks non-empty after CAS, we try to change it back quick + * before anyone notices our mistake! (This trick works pretty + * well because this method will practically never make mistakes + * unless current thread stalls immediately before first CAS, in + * which case it is very unlikely to stall again immediately + * afterwards, so will recover.) + * + * We put up with all this rather than just let levels grow + * because otherwise, even a small map that has undergone a large + * number of insertions and removals will have a lot of levels, + * slowing down access more than would an occasional unwanted + * reduction. + */ + private void tryReduceLevel() { + HeadIndex<K,V> h = head; + HeadIndex<K,V> d; + HeadIndex<K,V> e; + if (h.level > 3 && + (d = (HeadIndex<K,V>)h.down) != null && + (e = (HeadIndex<K,V>)d.down) != null && + e.right == null && + d.right == null && + h.right == null && + casHead(h, d) && // try to set + h.right != null) // recheck + casHead(d, h); // try to backout + } + + /* ---------------- Finding and removing first element -------------- */ + + /** + * Specialized variant of findNode to get first valid node. + * @return first node or null if empty + */ + Node<K,V> findFirst() { + for (;;) { + Node<K,V> b = head.node; + Node<K,V> n = b.next; + if (n == null) + return null; + if (n.value != null) + return n; + n.helpDelete(b, n.next); + } + } + + /** + * Removes first entry; returns its snapshot. + * @return null if empty, else snapshot of first entry + */ + Map.Entry<K,V> doRemoveFirstEntry() { + for (;;) { + Node<K,V> b = head.node; + Node<K,V> n = b.next; + if (n == null) + return null; + Node<K,V> f = n.next; + if (n != b.next) + continue; + Object v = n.value; + if (v == null) { + n.helpDelete(b, f); + continue; + } + if (!n.casValue(v, null)) + continue; + if (!n.appendMarker(f) || !b.casNext(n, f)) + findFirst(); // retry + clearIndexToFirst(); + return new AbstractMap.SimpleImmutableEntry<K,V>(n.key, (V)v); + } + } + + /** + * Clears out index nodes associated with deleted first entry. + */ + private void clearIndexToFirst() { + for (;;) { + Index<K,V> q = head; + for (;;) { + Index<K,V> r = q.right; + if (r != null && r.indexesDeletedNode() && !q.unlink(r)) + break; + if ((q = q.down) == null) { + if (head.right == null) + tryReduceLevel(); + return; + } + } + } + } + + + /* ---------------- Finding and removing last element -------------- */ + + /** + * Specialized version of find to get last valid node. + * @return last node or null if empty + */ + Node<K,V> findLast() { + /* + * findPredecessor can't be used to traverse index level + * because this doesn't use comparisons. So traversals of + * both levels are folded together. + */ + Index<K,V> q = head; + for (;;) { + Index<K,V> d, r; + if ((r = q.right) != null) { + if (r.indexesDeletedNode()) { + q.unlink(r); + q = head; // restart + } + else + q = r; + } else if ((d = q.down) != null) { + q = d; + } else { + Node<K,V> b = q.node; + Node<K,V> n = b.next; + for (;;) { + if (n == null) + return (b.isBaseHeader())? null : b; + Node<K,V> f = n.next; // inconsistent read + if (n != b.next) + break; + Object v = n.value; + if (v == null) { // n is deleted + n.helpDelete(b, f); + break; + } + if (v == n || b.value == null) // b is deleted + break; + b = n; + n = f; + } + q = head; // restart + } + } + } + + /** + * Specialized variant of findPredecessor to get predecessor of last + * valid node. Needed when removing the last entry. It is possible + * that all successors of returned node will have been deleted upon + * return, in which case this method can be retried. + * @return likely predecessor of last node + */ + private Node<K,V> findPredecessorOfLast() { + for (;;) { + Index<K,V> q = head; + for (;;) { + Index<K,V> d, r; + if ((r = q.right) != null) { + if (r.indexesDeletedNode()) { + q.unlink(r); + break; // must restart + } + // proceed as far across as possible without overshooting + if (r.node.next != null) { + q = r; + continue; + } + } + if ((d = q.down) != null) + q = d; + else + return q.node; + } + } + } + + /** + * Removes last entry; returns its snapshot. + * Specialized variant of doRemove. + * @return null if empty, else snapshot of last entry + */ + Map.Entry<K,V> doRemoveLastEntry() { + for (;;) { + Node<K,V> b = findPredecessorOfLast(); + Node<K,V> n = b.next; + if (n == null) { + if (b.isBaseHeader()) // empty + return null; + else + continue; // all b's successors are deleted; retry + } + for (;;) { + Node<K,V> f = n.next; + if (n != b.next) // inconsistent read + break; + Object v = n.value; + if (v == null) { // n is deleted + n.helpDelete(b, f); + break; + } + if (v == n || b.value == null) // b is deleted + break; + if (f != null) { + b = n; + n = f; + continue; + } + if (!n.casValue(v, null)) + break; + K key = n.key; + Comparable<? super K> ck = comparable(key); + if (!n.appendMarker(f) || !b.casNext(n, f)) + findNode(ck); // Retry via findNode + else { + findPredecessor(ck); // Clean index + if (head.right == null) + tryReduceLevel(); + } + return new AbstractMap.SimpleImmutableEntry<K,V>(key, (V)v); + } + } + } + + /* ---------------- Relational operations -------------- */ + + // Control values OR'ed as arguments to findNear + + private static final int EQ = 1; + private static final int LT = 2; + private static final int GT = 0; // Actually checked as !LT + + /** + * Utility for ceiling, floor, lower, higher methods. + * @param kkey the key + * @param rel the relation -- OR'ed combination of EQ, LT, GT + * @return nearest node fitting relation, or null if no such + */ + Node<K,V> findNear(K kkey, int rel) { + Comparable<? super K> key = comparable(kkey); + for (;;) { + Node<K,V> b = findPredecessor(key); + Node<K,V> n = b.next; + for (;;) { + if (n == null) + return ((rel & LT) == 0 || b.isBaseHeader())? null : b; + Node<K,V> f = n.next; + if (n != b.next) // inconsistent read + break; + Object v = n.value; + if (v == null) { // n is deleted + n.helpDelete(b, f); + break; + } + if (v == n || b.value == null) // b is deleted + break; + int c = key.compareTo(n.key); + if ((c == 0 && (rel & EQ) != 0) || + (c < 0 && (rel & LT) == 0)) + return n; + if ( c <= 0 && (rel & LT) != 0) + return (b.isBaseHeader())? null : b; + b = n; + n = f; + } + } + } + + /** + * Returns SimpleImmutableEntry for results of findNear. + * @param key the key + * @param rel the relation -- OR'ed combination of EQ, LT, GT + * @return Entry fitting relation, or null if no such + */ + AbstractMap.SimpleImmutableEntry<K,V> getNear(K key, int rel) { + for (;;) { + Node<K,V> n = findNear(key, rel); + if (n == null) + return null; + AbstractMap.SimpleImmutableEntry<K,V> e = n.createSnapshot(); + if (e != null) + return e; + } + } + + + /* ---------------- Constructors -------------- */ + + /** + * Constructs a new, empty map, sorted according to the + * {@linkplain Comparable natural ordering} of the keys. + */ + public ConcurrentSkipListMap() { + this.comparator = null; + initialize(); + } + + /** + * Constructs a new, empty map, sorted according to the specified + * comparator. + * + * @param comparator the comparator that will be used to order this map. + * If <tt>null</tt>, the {@linkplain Comparable natural + * ordering} of the keys will be used. + */ + public ConcurrentSkipListMap(Comparator<? super K> comparator) { + this.comparator = comparator; + initialize(); + } + + /** + * Constructs a new map containing the same mappings as the given map, + * sorted according to the {@linkplain Comparable natural ordering} of + * the keys. + * + * @param m the map whose mappings are to be placed in this map + * @throws ClassCastException if the keys in <tt>m</tt> are not + * {@link Comparable}, or are not mutually comparable + * @throws NullPointerException if the specified map or any of its keys + * or values are null + */ + public ConcurrentSkipListMap(Map<? extends K, ? extends V> m) { + this.comparator = null; + initialize(); + putAll(m); + } + + /** + * Constructs a new map containing the same mappings and using the + * same ordering as the specified sorted map. + * + * @param m the sorted map whose mappings are to be placed in this + * map, and whose comparator is to be used to sort this map + * @throws NullPointerException if the specified sorted map or any of + * its keys or values are null + */ + public ConcurrentSkipListMap(SortedMap<K, ? extends V> m) { + this.comparator = m.comparator(); + initialize(); + buildFromSorted(m); + } + + /** + * Returns a shallow copy of this <tt>ConcurrentSkipListMap</tt> + * instance. (The keys and values themselves are not cloned.) + * + * @return a shallow copy of this map + */ + public ConcurrentSkipListMap<K,V> clone() { + ConcurrentSkipListMap<K,V> clone = null; + try { + clone = (ConcurrentSkipListMap<K,V>) super.clone(); + } catch (CloneNotSupportedException e) { + throw new InternalError(); + } + + clone.initialize(); + clone.buildFromSorted(this); + return clone; + } + + /** + * Streamlined bulk insertion to initialize from elements of + * given sorted map. Call only from constructor or clone + * method. + */ + private void buildFromSorted(SortedMap<K, ? extends V> map) { + if (map == null) + throw new NullPointerException(); + + HeadIndex<K,V> h = head; + Node<K,V> basepred = h.node; + + // Track the current rightmost node at each level. Uses an + // ArrayList to avoid committing to initial or maximum level. + ArrayList<Index<K,V>> preds = new ArrayList<Index<K,V>>(); + + // initialize + for (int i = 0; i <= h.level; ++i) + preds.add(null); + Index<K,V> q = h; + for (int i = h.level; i > 0; --i) { + preds.set(i, q); + q = q.down; + } + + Iterator<? extends Map.Entry<? extends K, ? extends V>> it = + map.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry<? extends K, ? extends V> e = it.next(); + int j = randomLevel(); + if (j > h.level) j = h.level + 1; + K k = e.getKey(); + V v = e.getValue(); + if (k == null || v == null) + throw new NullPointerException(); + Node<K,V> z = new Node<K,V>(k, v, null); + basepred.next = z; + basepred = z; + if (j > 0) { + Index<K,V> idx = null; + for (int i = 1; i <= j; ++i) { + idx = new Index<K,V>(z, idx, null); + if (i > h.level) + h = new HeadIndex<K,V>(h.node, h, idx, i); + + if (i < preds.size()) { + preds.get(i).right = idx; + preds.set(i, idx); + } else + preds.add(idx); + } + } + } + head = h; + } + + /* ---------------- Serialization -------------- */ + + /** + * Save the state of this map to a stream. + * + * @serialData The key (Object) and value (Object) for each + * key-value mapping represented by the map, followed by + * <tt>null</tt>. The key-value mappings are emitted in key-order + * (as determined by the Comparator, or by the keys' natural + * ordering if no Comparator). + */ + private void writeObject(java.io.ObjectOutputStream s) + throws java.io.IOException { + // Write out the Comparator and any hidden stuff + s.defaultWriteObject(); + + // Write out keys and values (alternating) + for (Node<K,V> n = findFirst(); n != null; n = n.next) { + V v = n.getValidValue(); + if (v != null) { + s.writeObject(n.key); + s.writeObject(v); + } + } + s.writeObject(null); + } + + /** + * Reconstitute the map from a stream. + */ + private void readObject(final java.io.ObjectInputStream s) + throws java.io.IOException, ClassNotFoundException { + // Read in the Comparator and any hidden stuff + s.defaultReadObject(); + // Reset transients + initialize(); + + /* + * This is nearly identical to buildFromSorted, but is + * distinct because readObject calls can't be nicely adapted + * as the kind of iterator needed by buildFromSorted. (They + * can be, but doing so requires type cheats and/or creation + * of adaptor classes.) It is simpler to just adapt the code. + */ + + HeadIndex<K,V> h = head; + Node<K,V> basepred = h.node; + ArrayList<Index<K,V>> preds = new ArrayList<Index<K,V>>(); + for (int i = 0; i <= h.level; ++i) + preds.add(null); + Index<K,V> q = h; + for (int i = h.level; i > 0; --i) { + preds.set(i, q); + q = q.down; + } + + for (;;) { + Object k = s.readObject(); + if (k == null) + break; + Object v = s.readObject(); + if (v == null) + throw new NullPointerException(); + K key = (K) k; + V val = (V) v; + int j = randomLevel(); + if (j > h.level) j = h.level + 1; + Node<K,V> z = new Node<K,V>(key, val, null); + basepred.next = z; + basepred = z; + if (j > 0) { + Index<K,V> idx = null; + for (int i = 1; i <= j; ++i) { + idx = new Index<K,V>(z, idx, null); + if (i > h.level) + h = new HeadIndex<K,V>(h.node, h, idx, i); + + if (i < preds.size()) { + preds.get(i).right = idx; + preds.set(i, idx); + } else + preds.add(idx); + } + } + } + head = h; + } + + /* ------ Map API methods ------ */ + + /** + * Returns <tt>true</tt> if this map contains a mapping for the specified + * key. + * + * @param key key whose presence in this map is to be tested + * @return <tt>true</tt> if this map contains a mapping for the specified key + * @throws ClassCastException if the specified key cannot be compared + * with the keys currently in the map + * @throws NullPointerException if the specified key is null + */ + public boolean containsKey(Object key) { + return doGet(key) != null; + } + + /** + * Returns the value to which the specified key is mapped, + * or {@code null} if this map contains no mapping for the key. + * + * <p>More formally, if this map contains a mapping from a key + * {@code k} to a value {@code v} such that {@code key} compares + * equal to {@code k} according to the map's ordering, then this + * method returns {@code v}; otherwise it returns {@code null}. + * (There can be at most one such mapping.) + * + * @throws ClassCastException if the specified key cannot be compared + * with the keys currently in the map + * @throws NullPointerException if the specified key is null + */ + public V get(Object key) { + return doGet(key); + } + + /** + * Associates the specified value with the specified key in this map. + * If the map previously contained a mapping for the key, the old + * value is replaced. + * + * @param key key with which the specified value is to be associated + * @param value value to be associated with the specified key + * @return the previous value associated with the specified key, or + * <tt>null</tt> if there was no mapping for the key + * @throws ClassCastException if the specified key cannot be compared + * with the keys currently in the map + * @throws NullPointerException if the specified key or value is null + */ + public V put(K key, V value) { + if (value == null) + throw new NullPointerException(); + return doPut(key, value, false); + } + + /** + * Removes the mapping for the specified key from this map if present. + * + * @param key key for which mapping should be removed + * @return the previous value associated with the specified key, or + * <tt>null</tt> if there was no mapping for the key + * @throws ClassCastException if the specified key cannot be compared + * with the keys currently in the map + * @throws NullPointerException if the specified key is null + */ + public V remove(Object key) { + return doRemove(key, null); + } + + /** + * Returns <tt>true</tt> if this map maps one or more keys to the + * specified value. This operation requires time linear in the + * map size. + * + * @param value value whose presence in this map is to be tested + * @return <tt>true</tt> if a mapping to <tt>value</tt> exists; + * <tt>false</tt> otherwise + * @throws NullPointerException if the specified value is null + */ + public boolean containsValue(Object value) { + if (value == null) + throw new NullPointerException(); + for (Node<K,V> n = findFirst(); n != null; n = n.next) { + V v = n.getValidValue(); + if (v != null && value.equals(v)) + return true; + } + return false; + } + + /** + * Returns the number of key-value mappings in this map. If this map + * contains more than <tt>Integer.MAX_VALUE</tt> elements, it + * returns <tt>Integer.MAX_VALUE</tt>. + * + * <p>Beware that, unlike in most collections, this method is + * <em>NOT</em> a constant-time operation. Because of the + * asynchronous nature of these maps, determining the current + * number of elements requires traversing them all to count them. + * Additionally, it is possible for the size to change during + * execution of this method, in which case the returned result + * will be inaccurate. Thus, this method is typically not very + * useful in concurrent applications. + * + * @return the number of elements in this map + */ + public int size() { + long count = 0; + for (Node<K,V> n = findFirst(); n != null; n = n.next) { + if (n.getValidValue() != null) + ++count; + } + return (count >= Integer.MAX_VALUE)? Integer.MAX_VALUE : (int)count; + } + + /** + * Returns <tt>true</tt> if this map contains no key-value mappings. + * @return <tt>true</tt> if this map contains no key-value mappings + */ + public boolean isEmpty() { + return findFirst() == null; + } + + /** + * Removes all of the mappings from this map. + */ + public void clear() { + initialize(); + } + + /* ---------------- View methods -------------- */ + + /* + * Note: Lazy initialization works for views because view classes + * are stateless/immutable so it doesn't matter wrt correctness if + * more than one is created (which will only rarely happen). Even + * so, the following idiom conservatively ensures that the method + * returns the one it created if it does so, not one created by + * another racing thread. + */ + + /** + * Returns a {@link NavigableSet} view of the keys contained in this map. + * The set's iterator returns the keys in ascending order. + * The set is backed by the map, so changes to the map are + * reflected in the set, and vice-versa. The set supports element + * removal, which removes the corresponding mapping from the map, + * via the {@code Iterator.remove}, {@code Set.remove}, + * {@code removeAll}, {@code retainAll}, and {@code clear} + * operations. It does not support the {@code add} or {@code addAll} + * operations. + * + * <p>The view's {@code iterator} is a "weakly consistent" iterator + * that will never throw {@link ConcurrentModificationException}, + * and guarantees to traverse elements as they existed upon + * construction of the iterator, and may (but is not guaranteed to) + * reflect any modifications subsequent to construction. + * + * <p>This method is equivalent to method {@code navigableKeySet}. + * + * @return a navigable set view of the keys in this map + */ + public NavigableSet<K> keySet() { + KeySet ks = keySet; + return (ks != null) ? ks : (keySet = new KeySet(this)); + } + + public NavigableSet<K> navigableKeySet() { + KeySet ks = keySet; + return (ks != null) ? ks : (keySet = new KeySet(this)); + } + + /** + * Returns a {@link Collection} view of the values contained in this map. + * The collection's iterator returns the values in ascending order + * of the corresponding keys. + * The collection is backed by the map, so changes to the map are + * reflected in the collection, and vice-versa. The collection + * supports element removal, which removes the corresponding + * mapping from the map, via the <tt>Iterator.remove</tt>, + * <tt>Collection.remove</tt>, <tt>removeAll</tt>, + * <tt>retainAll</tt> and <tt>clear</tt> operations. It does not + * support the <tt>add</tt> or <tt>addAll</tt> operations. + * + * <p>The view's <tt>iterator</tt> is a "weakly consistent" iterator + * that will never throw {@link ConcurrentModificationException}, + * and guarantees to traverse elements as they existed upon + * construction of the iterator, and may (but is not guaranteed to) + * reflect any modifications subsequent to construction. + */ + public Collection<V> values() { + Values vs = values; + return (vs != null) ? vs : (values = new Values(this)); + } + + /** + * Returns a {@link Set} view of the mappings contained in this map. + * The set's iterator returns the entries in ascending key order. + * The set is backed by the map, so changes to the map are + * reflected in the set, and vice-versa. The set supports element + * removal, which removes the corresponding mapping from the map, + * via the <tt>Iterator.remove</tt>, <tt>Set.remove</tt>, + * <tt>removeAll</tt>, <tt>retainAll</tt> and <tt>clear</tt> + * operations. It does not support the <tt>add</tt> or + * <tt>addAll</tt> operations. + * + * <p>The view's <tt>iterator</tt> is a "weakly consistent" iterator + * that will never throw {@link ConcurrentModificationException}, + * and guarantees to traverse elements as they existed upon + * construction of the iterator, and may (but is not guaranteed to) + * reflect any modifications subsequent to construction. + * + * <p>The <tt>Map.Entry</tt> elements returned by + * <tt>iterator.next()</tt> do <em>not</em> support the + * <tt>setValue</tt> operation. + * + * @return a set view of the mappings contained in this map, + * sorted in ascending key order + */ + public Set<Map.Entry<K,V>> entrySet() { + EntrySet es = entrySet; + return (es != null) ? es : (entrySet = new EntrySet(this)); + } + + public ConcurrentNavigableMap<K,V> descendingMap() { + ConcurrentNavigableMap<K,V> dm = descendingMap; + return (dm != null) ? dm : (descendingMap = new SubMap<K,V> + (this, null, false, null, false, true)); + } + + public NavigableSet<K> descendingKeySet() { + return descendingMap().navigableKeySet(); + } + + /* ---------------- AbstractMap Overrides -------------- */ + + /** + * Compares the specified object with this map for equality. + * Returns <tt>true</tt> if the given object is also a map and the + * two maps represent the same mappings. More formally, two maps + * <tt>m1</tt> and <tt>m2</tt> represent the same mappings if + * <tt>m1.entrySet().equals(m2.entrySet())</tt>. This + * operation may return misleading results if either map is + * concurrently modified during execution of this method. + * + * @param o object to be compared for equality with this map + * @return <tt>true</tt> if the specified object is equal to this map + */ + public boolean equals(Object o) { + if (o == this) + return true; + if (!(o instanceof Map)) + return false; + Map<?,?> m = (Map<?,?>) o; + try { + for (Map.Entry<K,V> e : this.entrySet()) + if (! e.getValue().equals(m.get(e.getKey()))) + return false; + for (Map.Entry<?,?> e : m.entrySet()) { + Object k = e.getKey(); + Object v = e.getValue(); + if (k == null || v == null || !v.equals(get(k))) + return false; + } + return true; + } catch (ClassCastException unused) { + return false; + } catch (NullPointerException unused) { + return false; + } + } + + /* ------ ConcurrentMap API methods ------ */ + + /** + * {@inheritDoc} + * + * @return the previous value associated with the specified key, + * or <tt>null</tt> if there was no mapping for the key + * @throws ClassCastException if the specified key cannot be compared + * with the keys currently in the map + * @throws NullPointerException if the specified key or value is null + */ + public V putIfAbsent(K key, V value) { + if (value == null) + throw new NullPointerException(); + return doPut(key, value, true); + } + + /** + * {@inheritDoc} + * + * @throws ClassCastException if the specified key cannot be compared + * with the keys currently in the map + * @throws NullPointerException if the specified key is null + */ + public boolean remove(Object key, Object value) { + if (key == null) + throw new NullPointerException(); + if (value == null) + return false; + return doRemove(key, value) != null; + } + + /** + * {@inheritDoc} + * + * @throws ClassCastException if the specified key cannot be compared + * with the keys currently in the map + * @throws NullPointerException if any of the arguments are null + */ + public boolean replace(K key, V oldValue, V newValue) { + if (oldValue == null || newValue == null) + throw new NullPointerException(); + Comparable<? super K> k = comparable(key); + for (;;) { + Node<K,V> n = findNode(k); + if (n == null) + return false; + Object v = n.value; + if (v != null) { + if (!oldValue.equals(v)) + return false; + if (n.casValue(v, newValue)) + return true; + } + } + } + + /** + * {@inheritDoc} + * + * @return the previous value associated with the specified key, + * or <tt>null</tt> if there was no mapping for the key + * @throws ClassCastException if the specified key cannot be compared + * with the keys currently in the map + * @throws NullPointerException if the specified key or value is null + */ + public V replace(K key, V value) { + if (value == null) + throw new NullPointerException(); + Comparable<? super K> k = comparable(key); + for (;;) { + Node<K,V> n = findNode(k); + if (n == null) + return null; + Object v = n.value; + if (v != null && n.casValue(v, value)) + return (V)v; + } + } + + /* ------ SortedMap API methods ------ */ + + public Comparator<? super K> comparator() { + return comparator; + } + + /** + * @throws NoSuchElementException {@inheritDoc} + */ + public K firstKey() { + Node<K,V> n = findFirst(); + if (n == null) + throw new NoSuchElementException(); + return n.key; + } + + /** + * @throws NoSuchElementException {@inheritDoc} + */ + public K lastKey() { + Node<K,V> n = findLast(); + if (n == null) + throw new NoSuchElementException(); + return n.key; + } + + /** + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException if {@code fromKey} or {@code toKey} is null + * @throws IllegalArgumentException {@inheritDoc} + */ + public ConcurrentNavigableMap<K,V> subMap(K fromKey, + boolean fromInclusive, + K toKey, + boolean toInclusive) { + if (fromKey == null || toKey == null) + throw new NullPointerException(); + return new SubMap<K,V> + (this, fromKey, fromInclusive, toKey, toInclusive, false); + } + + /** + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException if {@code toKey} is null + * @throws IllegalArgumentException {@inheritDoc} + */ + public ConcurrentNavigableMap<K,V> headMap(K toKey, + boolean inclusive) { + if (toKey == null) + throw new NullPointerException(); + return new SubMap<K,V> + (this, null, false, toKey, inclusive, false); + } + + /** + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException if {@code fromKey} is null + * @throws IllegalArgumentException {@inheritDoc} + */ + public ConcurrentNavigableMap<K,V> tailMap(K fromKey, + boolean inclusive) { + if (fromKey == null) + throw new NullPointerException(); + return new SubMap<K,V> + (this, fromKey, inclusive, null, false, false); + } + + /** + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException if {@code fromKey} or {@code toKey} is null + * @throws IllegalArgumentException {@inheritDoc} + */ + public ConcurrentNavigableMap<K,V> subMap(K fromKey, K toKey) { + return subMap(fromKey, true, toKey, false); + } + + /** + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException if {@code toKey} is null + * @throws IllegalArgumentException {@inheritDoc} + */ + public ConcurrentNavigableMap<K,V> headMap(K toKey) { + return headMap(toKey, false); + } + + /** + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException if {@code fromKey} is null + * @throws IllegalArgumentException {@inheritDoc} + */ + public ConcurrentNavigableMap<K,V> tailMap(K fromKey) { + return tailMap(fromKey, true); + } + + /* ---------------- Relational operations -------------- */ + + /** + * Returns a key-value mapping associated with the greatest key + * strictly less than the given key, or <tt>null</tt> if there is + * no such key. The returned entry does <em>not</em> support the + * <tt>Entry.setValue</tt> method. + * + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException if the specified key is null + */ + public Map.Entry<K,V> lowerEntry(K key) { + return getNear(key, LT); + } + + /** + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException if the specified key is null + */ + public K lowerKey(K key) { + Node<K,V> n = findNear(key, LT); + return (n == null)? null : n.key; + } + + /** + * Returns a key-value mapping associated with the greatest key + * less than or equal to the given key, or <tt>null</tt> if there + * is no such key. The returned entry does <em>not</em> support + * the <tt>Entry.setValue</tt> method. + * + * @param key the key + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException if the specified key is null + */ + public Map.Entry<K,V> floorEntry(K key) { + return getNear(key, LT|EQ); + } + + /** + * @param key the key + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException if the specified key is null + */ + public K floorKey(K key) { + Node<K,V> n = findNear(key, LT|EQ); + return (n == null)? null : n.key; + } + + /** + * Returns a key-value mapping associated with the least key + * greater than or equal to the given key, or <tt>null</tt> if + * there is no such entry. The returned entry does <em>not</em> + * support the <tt>Entry.setValue</tt> method. + * + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException if the specified key is null + */ + public Map.Entry<K,V> ceilingEntry(K key) { + return getNear(key, GT|EQ); + } + + /** + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException if the specified key is null + */ + public K ceilingKey(K key) { + Node<K,V> n = findNear(key, GT|EQ); + return (n == null)? null : n.key; + } + + /** + * Returns a key-value mapping associated with the least key + * strictly greater than the given key, or <tt>null</tt> if there + * is no such key. The returned entry does <em>not</em> support + * the <tt>Entry.setValue</tt> method. + * + * @param key the key + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException if the specified key is null + */ + public Map.Entry<K,V> higherEntry(K key) { + return getNear(key, GT); + } + + /** + * @param key the key + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException if the specified key is null + */ + public K higherKey(K key) { + Node<K,V> n = findNear(key, GT); + return (n == null)? null : n.key; + } + + /** + * Returns a key-value mapping associated with the least + * key in this map, or <tt>null</tt> if the map is empty. + * The returned entry does <em>not</em> support + * the <tt>Entry.setValue</tt> method. + */ + public Map.Entry<K,V> firstEntry() { + for (;;) { + Node<K,V> n = findFirst(); + if (n == null) + return null; + AbstractMap.SimpleImmutableEntry<K,V> e = n.createSnapshot(); + if (e != null) + return e; + } + } + + /** + * Returns a key-value mapping associated with the greatest + * key in this map, or <tt>null</tt> if the map is empty. + * The returned entry does <em>not</em> support + * the <tt>Entry.setValue</tt> method. + */ + public Map.Entry<K,V> lastEntry() { + for (;;) { + Node<K,V> n = findLast(); + if (n == null) + return null; + AbstractMap.SimpleImmutableEntry<K,V> e = n.createSnapshot(); + if (e != null) + return e; + } + } + + /** + * Removes and returns a key-value mapping associated with + * the least key in this map, or <tt>null</tt> if the map is empty. + * The returned entry does <em>not</em> support + * the <tt>Entry.setValue</tt> method. + */ + public Map.Entry<K,V> pollFirstEntry() { + return doRemoveFirstEntry(); + } + + /** + * Removes and returns a key-value mapping associated with + * the greatest key in this map, or <tt>null</tt> if the map is empty. + * The returned entry does <em>not</em> support + * the <tt>Entry.setValue</tt> method. + */ + public Map.Entry<K,V> pollLastEntry() { + return doRemoveLastEntry(); + } + + + /* ---------------- Iterators -------------- */ + + /** + * Base of iterator classes: + */ + abstract class Iter<T> implements Iterator<T> { + /** the last node returned by next() */ + Node<K,V> lastReturned; + /** the next node to return from next(); */ + Node<K,V> next; + /** Cache of next value field to maintain weak consistency */ + V nextValue; + + /** Initializes ascending iterator for entire range. */ + Iter() { + for (;;) { + next = findFirst(); + if (next == null) + break; + Object x = next.value; + if (x != null && x != next) { + nextValue = (V) x; + break; + } + } + } + + public final boolean hasNext() { + return next != null; + } + + /** Advances next to higher entry. */ + final void advance() { + if ((lastReturned = next) == null) + throw new NoSuchElementException(); + for (;;) { + next = next.next; + if (next == null) + break; + Object x = next.value; + if (x != null && x != next) { + nextValue = (V) x; + break; + } + } + } + + public void remove() { + Node<K,V> l = lastReturned; + if (l == null) + throw new IllegalStateException(); + // It would not be worth all of the overhead to directly + // unlink from here. Using remove is fast enough. + ConcurrentSkipListMap.this.remove(l.key); + lastReturned = null; + } + + } + + final class ValueIterator extends Iter<V> { + public V next() { + V v = nextValue; + advance(); + return v; + } + } + + final class KeyIterator extends Iter<K> { + public K next() { + Node<K,V> n = next; + advance(); + return n.key; + } + } + + final class EntryIterator extends Iter<Map.Entry<K,V>> { + public Map.Entry<K,V> next() { + Node<K,V> n = next; + V v = nextValue; + advance(); + return new AbstractMap.SimpleImmutableEntry<K,V>(n.key, v); + } + } + + // Factory methods for iterators needed by ConcurrentSkipListSet etc + + Iterator<K> keyIterator() { + return new KeyIterator(); + } + + Iterator<V> valueIterator() { + return new ValueIterator(); + } + + Iterator<Map.Entry<K,V>> entryIterator() { + return new EntryIterator(); + } + + /* ---------------- View Classes -------------- */ + + /* + * View classes are static, delegating to a ConcurrentNavigableMap + * to allow use by SubMaps, which outweighs the ugliness of + * needing type-tests for Iterator methods. + */ + + static final <E> List<E> toList(Collection<E> c) { + // Using size() here would be a pessimization. + List<E> list = new ArrayList<E>(); + for (E e : c) + list.add(e); + return list; + } + + static final class KeySet<E> extends AbstractSet<E> implements NavigableSet<E> { + private final ConcurrentNavigableMap<E,Object> m; + KeySet(ConcurrentNavigableMap<E,Object> map) { m = map; } + public int size() { return m.size(); } + public boolean isEmpty() { return m.isEmpty(); } + public boolean contains(Object o) { return m.containsKey(o); } + public boolean remove(Object o) { return m.remove(o) != null; } + public void clear() { m.clear(); } + public E lower(E e) { return m.lowerKey(e); } + public E floor(E e) { return m.floorKey(e); } + public E ceiling(E e) { return m.ceilingKey(e); } + public E higher(E e) { return m.higherKey(e); } + public Comparator<? super E> comparator() { return m.comparator(); } + public E first() { return m.firstKey(); } + public E last() { return m.lastKey(); } + public E pollFirst() { + Map.Entry<E,Object> e = m.pollFirstEntry(); + return e == null? null : e.getKey(); + } + public E pollLast() { + Map.Entry<E,Object> e = m.pollLastEntry(); + return e == null? null : e.getKey(); + } + public Iterator<E> iterator() { + if (m instanceof ConcurrentSkipListMap) + return ((ConcurrentSkipListMap<E,Object>)m).keyIterator(); + else + return ((ConcurrentSkipListMap.SubMap<E,Object>)m).keyIterator(); + } + public boolean equals(Object o) { + if (o == this) + return true; + if (!(o instanceof Set)) + return false; + Collection<?> c = (Collection<?>) o; + try { + return containsAll(c) && c.containsAll(this); + } catch (ClassCastException unused) { + return false; + } catch (NullPointerException unused) { + return false; + } + } + public Object[] toArray() { return toList(this).toArray(); } + public <T> T[] toArray(T[] a) { return toList(this).toArray(a); } + public Iterator<E> descendingIterator() { + return descendingSet().iterator(); + } + public NavigableSet<E> subSet(E fromElement, + boolean fromInclusive, + E toElement, + boolean toInclusive) { + return new ConcurrentSkipListSet<E> + (m.subMap(fromElement, fromInclusive, + toElement, toInclusive)); + } + public NavigableSet<E> headSet(E toElement, boolean inclusive) { + return new ConcurrentSkipListSet<E>(m.headMap(toElement, inclusive)); + } + public NavigableSet<E> tailSet(E fromElement, boolean inclusive) { + return new ConcurrentSkipListSet<E>(m.tailMap(fromElement, inclusive)); + } + public NavigableSet<E> subSet(E fromElement, E toElement) { + return subSet(fromElement, true, toElement, false); + } + public NavigableSet<E> headSet(E toElement) { + return headSet(toElement, false); + } + public NavigableSet<E> tailSet(E fromElement) { + return tailSet(fromElement, true); + } + public NavigableSet<E> descendingSet() { + return new ConcurrentSkipListSet(m.descendingMap()); + } + } + + static final class Values<E> extends AbstractCollection<E> { + private final ConcurrentNavigableMap<Object, E> m; + Values(ConcurrentNavigableMap<Object, E> map) { + m = map; + } + public Iterator<E> iterator() { + if (m instanceof ConcurrentSkipListMap) + return ((ConcurrentSkipListMap<Object,E>)m).valueIterator(); + else + return ((SubMap<Object,E>)m).valueIterator(); + } + public boolean isEmpty() { + return m.isEmpty(); + } + public int size() { + return m.size(); + } + public boolean contains(Object o) { + return m.containsValue(o); + } + public void clear() { + m.clear(); + } + public Object[] toArray() { return toList(this).toArray(); } + public <T> T[] toArray(T[] a) { return toList(this).toArray(a); } + } + + static final class EntrySet<K1,V1> extends AbstractSet<Map.Entry<K1,V1>> { + private final ConcurrentNavigableMap<K1, V1> m; + EntrySet(ConcurrentNavigableMap<K1, V1> map) { + m = map; + } + + public Iterator<Map.Entry<K1,V1>> iterator() { + if (m instanceof ConcurrentSkipListMap) + return ((ConcurrentSkipListMap<K1,V1>)m).entryIterator(); + else + return ((SubMap<K1,V1>)m).entryIterator(); + } + + public boolean contains(Object o) { + if (!(o instanceof Map.Entry)) + return false; + Map.Entry<K1,V1> e = (Map.Entry<K1,V1>)o; + V1 v = m.get(e.getKey()); + return v != null && v.equals(e.getValue()); + } + public boolean remove(Object o) { + if (!(o instanceof Map.Entry)) + return false; + Map.Entry<K1,V1> e = (Map.Entry<K1,V1>)o; + return m.remove(e.getKey(), + e.getValue()); + } + public boolean isEmpty() { + return m.isEmpty(); + } + public int size() { + return m.size(); + } + public void clear() { + m.clear(); + } + public boolean equals(Object o) { + if (o == this) + return true; + if (!(o instanceof Set)) + return false; + Collection<?> c = (Collection<?>) o; + try { + return containsAll(c) && c.containsAll(this); + } catch (ClassCastException unused) { + return false; + } catch (NullPointerException unused) { + return false; + } + } + public Object[] toArray() { return toList(this).toArray(); } + public <T> T[] toArray(T[] a) { return toList(this).toArray(a); } + } + + /** + * Submaps returned by {@link ConcurrentSkipListMap} submap operations + * represent a subrange of mappings of their underlying + * maps. Instances of this class support all methods of their + * underlying maps, differing in that mappings outside their range are + * ignored, and attempts to add mappings outside their ranges result + * in {@link IllegalArgumentException}. Instances of this class are + * constructed only using the <tt>subMap</tt>, <tt>headMap</tt>, and + * <tt>tailMap</tt> methods of their underlying maps. + * + * @serial include + */ + static final class SubMap<K,V> extends AbstractMap<K,V> + implements ConcurrentNavigableMap<K,V>, Cloneable, + java.io.Serializable { + private static final long serialVersionUID = -7647078645895051609L; + + /** Underlying map */ + private final ConcurrentSkipListMap<K,V> m; + /** lower bound key, or null if from start */ + private final K lo; + /** upper bound key, or null if to end */ + private final K hi; + /** inclusion flag for lo */ + private final boolean loInclusive; + /** inclusion flag for hi */ + private final boolean hiInclusive; + /** direction */ + private final boolean isDescending; + + // Lazily initialized view holders + private transient KeySet<K> keySetView; + private transient Set<Map.Entry<K,V>> entrySetView; + private transient Collection<V> valuesView; + + /** + * Creates a new submap, initializing all fields + */ + SubMap(ConcurrentSkipListMap<K,V> map, + K fromKey, boolean fromInclusive, + K toKey, boolean toInclusive, + boolean isDescending) { + if (fromKey != null && toKey != null && + map.compare(fromKey, toKey) > 0) + throw new IllegalArgumentException("inconsistent range"); + this.m = map; + this.lo = fromKey; + this.hi = toKey; + this.loInclusive = fromInclusive; + this.hiInclusive = toInclusive; + this.isDescending = isDescending; + } + + /* ---------------- Utilities -------------- */ + + private boolean tooLow(K key) { + if (lo != null) { + int c = m.compare(key, lo); + if (c < 0 || (c == 0 && !loInclusive)) + return true; + } + return false; + } + + private boolean tooHigh(K key) { + if (hi != null) { + int c = m.compare(key, hi); + if (c > 0 || (c == 0 && !hiInclusive)) + return true; + } + return false; + } + + private boolean inBounds(K key) { + return !tooLow(key) && !tooHigh(key); + } + + private void checkKeyBounds(K key) throws IllegalArgumentException { + if (key == null) + throw new NullPointerException(); + if (!inBounds(key)) + throw new IllegalArgumentException("key out of range"); + } + + /** + * Returns true if node key is less than upper bound of range + */ + private boolean isBeforeEnd(ConcurrentSkipListMap.Node<K,V> n) { + if (n == null) + return false; + if (hi == null) + return true; + K k = n.key; + if (k == null) // pass by markers and headers + return true; + int c = m.compare(k, hi); + if (c > 0 || (c == 0 && !hiInclusive)) + return false; + return true; + } + + /** + * Returns lowest node. This node might not be in range, so + * most usages need to check bounds + */ + private ConcurrentSkipListMap.Node<K,V> loNode() { + if (lo == null) + return m.findFirst(); + else if (loInclusive) + return m.findNear(lo, m.GT|m.EQ); + else + return m.findNear(lo, m.GT); + } + + /** + * Returns highest node. This node might not be in range, so + * most usages need to check bounds + */ + private ConcurrentSkipListMap.Node<K,V> hiNode() { + if (hi == null) + return m.findLast(); + else if (hiInclusive) + return m.findNear(hi, m.LT|m.EQ); + else + return m.findNear(hi, m.LT); + } + + /** + * Returns lowest absolute key (ignoring directonality) + */ + private K lowestKey() { + ConcurrentSkipListMap.Node<K,V> n = loNode(); + if (isBeforeEnd(n)) + return n.key; + else + throw new NoSuchElementException(); + } + + /** + * Returns highest absolute key (ignoring directonality) + */ + private K highestKey() { + ConcurrentSkipListMap.Node<K,V> n = hiNode(); + if (n != null) { + K last = n.key; + if (inBounds(last)) + return last; + } + throw new NoSuchElementException(); + } + + private Map.Entry<K,V> lowestEntry() { + for (;;) { + ConcurrentSkipListMap.Node<K,V> n = loNode(); + if (!isBeforeEnd(n)) + return null; + Map.Entry<K,V> e = n.createSnapshot(); + if (e != null) + return e; + } + } + + private Map.Entry<K,V> highestEntry() { + for (;;) { + ConcurrentSkipListMap.Node<K,V> n = hiNode(); + if (n == null || !inBounds(n.key)) + return null; + Map.Entry<K,V> e = n.createSnapshot(); + if (e != null) + return e; + } + } + + private Map.Entry<K,V> removeLowest() { + for (;;) { + Node<K,V> n = loNode(); + if (n == null) + return null; + K k = n.key; + if (!inBounds(k)) + return null; + V v = m.doRemove(k, null); + if (v != null) + return new AbstractMap.SimpleImmutableEntry<K,V>(k, v); + } + } + + private Map.Entry<K,V> removeHighest() { + for (;;) { + Node<K,V> n = hiNode(); + if (n == null) + return null; + K k = n.key; + if (!inBounds(k)) + return null; + V v = m.doRemove(k, null); + if (v != null) + return new AbstractMap.SimpleImmutableEntry<K,V>(k, v); + } + } + + /** + * Submap version of ConcurrentSkipListMap.getNearEntry + */ + private Map.Entry<K,V> getNearEntry(K key, int rel) { + if (isDescending) { // adjust relation for direction + if ((rel & m.LT) == 0) + rel |= m.LT; + else + rel &= ~m.LT; + } + if (tooLow(key)) + return ((rel & m.LT) != 0)? null : lowestEntry(); + if (tooHigh(key)) + return ((rel & m.LT) != 0)? highestEntry() : null; + for (;;) { + Node<K,V> n = m.findNear(key, rel); + if (n == null || !inBounds(n.key)) + return null; + K k = n.key; + V v = n.getValidValue(); + if (v != null) + return new AbstractMap.SimpleImmutableEntry<K,V>(k, v); + } + } + + // Almost the same as getNearEntry, except for keys + private K getNearKey(K key, int rel) { + if (isDescending) { // adjust relation for direction + if ((rel & m.LT) == 0) + rel |= m.LT; + else + rel &= ~m.LT; + } + if (tooLow(key)) { + if ((rel & m.LT) == 0) { + ConcurrentSkipListMap.Node<K,V> n = loNode(); + if (isBeforeEnd(n)) + return n.key; + } + return null; + } + if (tooHigh(key)) { + if ((rel & m.LT) != 0) { + ConcurrentSkipListMap.Node<K,V> n = hiNode(); + if (n != null) { + K last = n.key; + if (inBounds(last)) + return last; + } + } + return null; + } + for (;;) { + Node<K,V> n = m.findNear(key, rel); + if (n == null || !inBounds(n.key)) + return null; + K k = n.key; + V v = n.getValidValue(); + if (v != null) + return k; + } + } + + /* ---------------- Map API methods -------------- */ + + public boolean containsKey(Object key) { + if (key == null) throw new NullPointerException(); + K k = (K)key; + return inBounds(k) && m.containsKey(k); + } + + public V get(Object key) { + if (key == null) throw new NullPointerException(); + K k = (K)key; + return ((!inBounds(k)) ? null : m.get(k)); + } + + public V put(K key, V value) { + checkKeyBounds(key); + return m.put(key, value); + } + + public V remove(Object key) { + K k = (K)key; + return (!inBounds(k))? null : m.remove(k); + } + + public int size() { + long count = 0; + for (ConcurrentSkipListMap.Node<K,V> n = loNode(); + isBeforeEnd(n); + n = n.next) { + if (n.getValidValue() != null) + ++count; + } + return count >= Integer.MAX_VALUE? Integer.MAX_VALUE : (int)count; + } + + public boolean isEmpty() { + return !isBeforeEnd(loNode()); + } + + public boolean containsValue(Object value) { + if (value == null) + throw new NullPointerException(); + for (ConcurrentSkipListMap.Node<K,V> n = loNode(); + isBeforeEnd(n); + n = n.next) { + V v = n.getValidValue(); + if (v != null && value.equals(v)) + return true; + } + return false; + } + + public void clear() { + for (ConcurrentSkipListMap.Node<K,V> n = loNode(); + isBeforeEnd(n); + n = n.next) { + if (n.getValidValue() != null) + m.remove(n.key); + } + } + + /* ---------------- ConcurrentMap API methods -------------- */ + + public V putIfAbsent(K key, V value) { + checkKeyBounds(key); + return m.putIfAbsent(key, value); + } + + public boolean remove(Object key, Object value) { + K k = (K)key; + return inBounds(k) && m.remove(k, value); + } + + public boolean replace(K key, V oldValue, V newValue) { + checkKeyBounds(key); + return m.replace(key, oldValue, newValue); + } + + public V replace(K key, V value) { + checkKeyBounds(key); + return m.replace(key, value); + } + + /* ---------------- SortedMap API methods -------------- */ + + public Comparator<? super K> comparator() { + Comparator<? super K> cmp = m.comparator(); + if (isDescending) + return Collections.reverseOrder(cmp); + else + return cmp; + } + + /** + * Utility to create submaps, where given bounds override + * unbounded(null) ones and/or are checked against bounded ones. + */ + private SubMap<K,V> newSubMap(K fromKey, + boolean fromInclusive, + K toKey, + boolean toInclusive) { + if (isDescending) { // flip senses + K tk = fromKey; + fromKey = toKey; + toKey = tk; + boolean ti = fromInclusive; + fromInclusive = toInclusive; + toInclusive = ti; + } + if (lo != null) { + if (fromKey == null) { + fromKey = lo; + fromInclusive = loInclusive; + } + else { + int c = m.compare(fromKey, lo); + if (c < 0 || (c == 0 && !loInclusive && fromInclusive)) + throw new IllegalArgumentException("key out of range"); + } + } + if (hi != null) { + if (toKey == null) { + toKey = hi; + toInclusive = hiInclusive; + } + else { + int c = m.compare(toKey, hi); + if (c > 0 || (c == 0 && !hiInclusive && toInclusive)) + throw new IllegalArgumentException("key out of range"); + } + } + return new SubMap<K,V>(m, fromKey, fromInclusive, + toKey, toInclusive, isDescending); + } + + public SubMap<K,V> subMap(K fromKey, + boolean fromInclusive, + K toKey, + boolean toInclusive) { + if (fromKey == null || toKey == null) + throw new NullPointerException(); + return newSubMap(fromKey, fromInclusive, toKey, toInclusive); + } + + public SubMap<K,V> headMap(K toKey, + boolean inclusive) { + if (toKey == null) + throw new NullPointerException(); + return newSubMap(null, false, toKey, inclusive); + } + + public SubMap<K,V> tailMap(K fromKey, + boolean inclusive) { + if (fromKey == null) + throw new NullPointerException(); + return newSubMap(fromKey, inclusive, null, false); + } + + public SubMap<K,V> subMap(K fromKey, K toKey) { + return subMap(fromKey, true, toKey, false); + } + + public SubMap<K,V> headMap(K toKey) { + return headMap(toKey, false); + } + + public SubMap<K,V> tailMap(K fromKey) { + return tailMap(fromKey, true); + } + + public SubMap<K,V> descendingMap() { + return new SubMap<K,V>(m, lo, loInclusive, + hi, hiInclusive, !isDescending); + } + + /* ---------------- Relational methods -------------- */ + + public Map.Entry<K,V> ceilingEntry(K key) { + return getNearEntry(key, (m.GT|m.EQ)); + } + + public K ceilingKey(K key) { + return getNearKey(key, (m.GT|m.EQ)); + } + + public Map.Entry<K,V> lowerEntry(K key) { + return getNearEntry(key, (m.LT)); + } + + public K lowerKey(K key) { + return getNearKey(key, (m.LT)); + } + + public Map.Entry<K,V> floorEntry(K key) { + return getNearEntry(key, (m.LT|m.EQ)); + } + + public K floorKey(K key) { + return getNearKey(key, (m.LT|m.EQ)); + } + + public Map.Entry<K,V> higherEntry(K key) { + return getNearEntry(key, (m.GT)); + } + + public K higherKey(K key) { + return getNearKey(key, (m.GT)); + } + + public K firstKey() { + return isDescending? highestKey() : lowestKey(); + } + + public K lastKey() { + return isDescending? lowestKey() : highestKey(); + } + + public Map.Entry<K,V> firstEntry() { + return isDescending? highestEntry() : lowestEntry(); + } + + public Map.Entry<K,V> lastEntry() { + return isDescending? lowestEntry() : highestEntry(); + } + + public Map.Entry<K,V> pollFirstEntry() { + return isDescending? removeHighest() : removeLowest(); + } + + public Map.Entry<K,V> pollLastEntry() { + return isDescending? removeLowest() : removeHighest(); + } + + /* ---------------- Submap Views -------------- */ + + public NavigableSet<K> keySet() { + KeySet<K> ks = keySetView; + return (ks != null) ? ks : (keySetView = new KeySet(this)); + } + + public NavigableSet<K> navigableKeySet() { + KeySet<K> ks = keySetView; + return (ks != null) ? ks : (keySetView = new KeySet(this)); + } + + public Collection<V> values() { + Collection<V> vs = valuesView; + return (vs != null) ? vs : (valuesView = new Values(this)); + } + + public Set<Map.Entry<K,V>> entrySet() { + Set<Map.Entry<K,V>> es = entrySetView; + return (es != null) ? es : (entrySetView = new EntrySet(this)); + } + + public NavigableSet<K> descendingKeySet() { + return descendingMap().navigableKeySet(); + } + + Iterator<K> keyIterator() { + return new SubMapKeyIterator(); + } + + Iterator<V> valueIterator() { + return new SubMapValueIterator(); + } + + Iterator<Map.Entry<K,V>> entryIterator() { + return new SubMapEntryIterator(); + } + + /** + * Variant of main Iter class to traverse through submaps. + */ + abstract class SubMapIter<T> implements Iterator<T> { + /** the last node returned by next() */ + Node<K,V> lastReturned; + /** the next node to return from next(); */ + Node<K,V> next; + /** Cache of next value field to maintain weak consistency */ + V nextValue; + + SubMapIter() { + for (;;) { + next = isDescending ? hiNode() : loNode(); + if (next == null) + break; + Object x = next.value; + if (x != null && x != next) { + if (! inBounds(next.key)) + next = null; + else + nextValue = (V) x; + break; + } + } + } + + public final boolean hasNext() { + return next != null; + } + + final void advance() { + if ((lastReturned = next) == null) + throw new NoSuchElementException(); + if (isDescending) + descend(); + else + ascend(); + } + + private void ascend() { + for (;;) { + next = next.next; + if (next == null) + break; + Object x = next.value; + if (x != null && x != next) { + if (tooHigh(next.key)) + next = null; + else + nextValue = (V) x; + break; + } + } + } + + private void descend() { + for (;;) { + next = m.findNear(lastReturned.key, LT); + if (next == null) + break; + Object x = next.value; + if (x != null && x != next) { + if (tooLow(next.key)) + next = null; + else + nextValue = (V) x; + break; + } + } + } + + public void remove() { + Node<K,V> l = lastReturned; + if (l == null) + throw new IllegalStateException(); + m.remove(l.key); + lastReturned = null; + } + + } + + final class SubMapValueIterator extends SubMapIter<V> { + public V next() { + V v = nextValue; + advance(); + return v; + } + } + + final class SubMapKeyIterator extends SubMapIter<K> { + public K next() { + Node<K,V> n = next; + advance(); + return n.key; + } + } + + final class SubMapEntryIterator extends SubMapIter<Map.Entry<K,V>> { + public Map.Entry<K,V> next() { + Node<K,V> n = next; + V v = nextValue; + advance(); + return new AbstractMap.SimpleImmutableEntry<K,V>(n.key, v); + } + } + } +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/ConcurrentSkipListSet.java b/libjava/classpath/external/jsr166/java/util/concurrent/ConcurrentSkipListSet.java new file mode 100644 index 000000000..7fd1c7608 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/ConcurrentSkipListSet.java @@ -0,0 +1,456 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; +import java.util.*; +import sun.misc.Unsafe; + +/** + * A scalable concurrent {@link NavigableSet} implementation based on + * a {@link ConcurrentSkipListMap}. The elements of the set are kept + * sorted according to their {@linkplain Comparable natural ordering}, + * or by a {@link Comparator} provided at set creation time, depending + * on which constructor is used. + * + * <p>This implementation provides expected average <i>log(n)</i> time + * cost for the <tt>contains</tt>, <tt>add</tt>, and <tt>remove</tt> + * operations and their variants. Insertion, removal, and access + * operations safely execute concurrently by multiple threads. + * Iterators are <i>weakly consistent</i>, returning elements + * reflecting the state of the set at some point at or since the + * creation of the iterator. They do <em>not</em> throw {@link + * ConcurrentModificationException}, and may proceed concurrently with + * other operations. Ascending ordered views and their iterators are + * faster than descending ones. + * + * <p>Beware that, unlike in most collections, the <tt>size</tt> + * method is <em>not</em> a constant-time operation. Because of the + * asynchronous nature of these sets, determining the current number + * of elements requires a traversal of the elements. Additionally, the + * bulk operations <tt>addAll</tt>, <tt>removeAll</tt>, + * <tt>retainAll</tt>, and <tt>containsAll</tt> are <em>not</em> + * guaranteed to be performed atomically. For example, an iterator + * operating concurrently with an <tt>addAll</tt> operation might view + * only some of the added elements. + * + * <p>This class and its iterators implement all of the + * <em>optional</em> methods of the {@link Set} and {@link Iterator} + * interfaces. Like most other concurrent collection implementations, + * this class does not permit the use of <tt>null</tt> elements, + * because <tt>null</tt> arguments and return values cannot be reliably + * distinguished from the absence of elements. + * + * <p>This class is a member of the + * <a href="{@docRoot}/../technotes/guides/collections/index.html"> + * Java Collections Framework</a>. + * + * @author Doug Lea + * @param <E> the type of elements maintained by this set + * @since 1.6 + */ +public class ConcurrentSkipListSet<E> + extends AbstractSet<E> + implements NavigableSet<E>, Cloneable, java.io.Serializable { + + private static final long serialVersionUID = -2479143111061671589L; + + /** + * The underlying map. Uses Boolean.TRUE as value for each + * element. This field is declared final for the sake of thread + * safety, which entails some ugliness in clone() + */ + private final ConcurrentNavigableMap<E,Object> m; + + /** + * Constructs a new, empty set that orders its elements according to + * their {@linkplain Comparable natural ordering}. + */ + public ConcurrentSkipListSet() { + m = new ConcurrentSkipListMap<E,Object>(); + } + + /** + * Constructs a new, empty set that orders its elements according to + * the specified comparator. + * + * @param comparator the comparator that will be used to order this set. + * If <tt>null</tt>, the {@linkplain Comparable natural + * ordering} of the elements will be used. + */ + public ConcurrentSkipListSet(Comparator<? super E> comparator) { + m = new ConcurrentSkipListMap<E,Object>(comparator); + } + + /** + * Constructs a new set containing the elements in the specified + * collection, that orders its elements according to their + * {@linkplain Comparable natural ordering}. + * + * @param c The elements that will comprise the new set + * @throws ClassCastException if the elements in <tt>c</tt> are + * not {@link Comparable}, or are not mutually comparable + * @throws NullPointerException if the specified collection or any + * of its elements are null + */ + public ConcurrentSkipListSet(Collection<? extends E> c) { + m = new ConcurrentSkipListMap<E,Object>(); + addAll(c); + } + + /** + * Constructs a new set containing the same elements and using the + * same ordering as the specified sorted set. + * + * @param s sorted set whose elements will comprise the new set + * @throws NullPointerException if the specified sorted set or any + * of its elements are null + */ + public ConcurrentSkipListSet(SortedSet<E> s) { + m = new ConcurrentSkipListMap<E,Object>(s.comparator()); + addAll(s); + } + + /** + * For use by submaps + */ + ConcurrentSkipListSet(ConcurrentNavigableMap<E,Object> m) { + this.m = m; + } + + /** + * Returns a shallow copy of this <tt>ConcurrentSkipListSet</tt> + * instance. (The elements themselves are not cloned.) + * + * @return a shallow copy of this set + */ + public ConcurrentSkipListSet<E> clone() { + ConcurrentSkipListSet<E> clone = null; + try { + clone = (ConcurrentSkipListSet<E>) super.clone(); + clone.setMap(new ConcurrentSkipListMap(m)); + } catch (CloneNotSupportedException e) { + throw new InternalError(); + } + + return clone; + } + + /* ---------------- Set operations -------------- */ + + /** + * Returns the number of elements in this set. If this set + * contains more than <tt>Integer.MAX_VALUE</tt> elements, it + * returns <tt>Integer.MAX_VALUE</tt>. + * + * <p>Beware that, unlike in most collections, this method is + * <em>NOT</em> a constant-time operation. Because of the + * asynchronous nature of these sets, determining the current + * number of elements requires traversing them all to count them. + * Additionally, it is possible for the size to change during + * execution of this method, in which case the returned result + * will be inaccurate. Thus, this method is typically not very + * useful in concurrent applications. + * + * @return the number of elements in this set + */ + public int size() { + return m.size(); + } + + /** + * Returns <tt>true</tt> if this set contains no elements. + * @return <tt>true</tt> if this set contains no elements + */ + public boolean isEmpty() { + return m.isEmpty(); + } + + /** + * Returns <tt>true</tt> if this set contains the specified element. + * More formally, returns <tt>true</tt> if and only if this set + * contains an element <tt>e</tt> such that <tt>o.equals(e)</tt>. + * + * @param o object to be checked for containment in this set + * @return <tt>true</tt> if this set contains the specified element + * @throws ClassCastException if the specified element cannot be + * compared with the elements currently in this set + * @throws NullPointerException if the specified element is null + */ + public boolean contains(Object o) { + return m.containsKey(o); + } + + /** + * Adds the specified element to this set if it is not already present. + * More formally, adds the specified element <tt>e</tt> to this set if + * the set contains no element <tt>e2</tt> such that <tt>e.equals(e2)</tt>. + * If this set already contains the element, the call leaves the set + * unchanged and returns <tt>false</tt>. + * + * @param e element to be added to this set + * @return <tt>true</tt> if this set did not already contain the + * specified element + * @throws ClassCastException if <tt>e</tt> cannot be compared + * with the elements currently in this set + * @throws NullPointerException if the specified element is null + */ + public boolean add(E e) { + return m.putIfAbsent(e, Boolean.TRUE) == null; + } + + /** + * Removes the specified element from this set if it is present. + * More formally, removes an element <tt>e</tt> such that + * <tt>o.equals(e)</tt>, if this set contains such an element. + * Returns <tt>true</tt> if this set contained the element (or + * equivalently, if this set changed as a result of the call). + * (This set will not contain the element once the call returns.) + * + * @param o object to be removed from this set, if present + * @return <tt>true</tt> if this set contained the specified element + * @throws ClassCastException if <tt>o</tt> cannot be compared + * with the elements currently in this set + * @throws NullPointerException if the specified element is null + */ + public boolean remove(Object o) { + return m.remove(o, Boolean.TRUE); + } + + /** + * Removes all of the elements from this set. + */ + public void clear() { + m.clear(); + } + + /** + * Returns an iterator over the elements in this set in ascending order. + * + * @return an iterator over the elements in this set in ascending order + */ + public Iterator<E> iterator() { + return m.navigableKeySet().iterator(); + } + + /** + * Returns an iterator over the elements in this set in descending order. + * + * @return an iterator over the elements in this set in descending order + */ + public Iterator<E> descendingIterator() { + return m.descendingKeySet().iterator(); + } + + + /* ---------------- AbstractSet Overrides -------------- */ + + /** + * Compares the specified object with this set for equality. Returns + * <tt>true</tt> if the specified object is also a set, the two sets + * have the same size, and every member of the specified set is + * contained in this set (or equivalently, every member of this set is + * contained in the specified set). This definition ensures that the + * equals method works properly across different implementations of the + * set interface. + * + * @param o the object to be compared for equality with this set + * @return <tt>true</tt> if the specified object is equal to this set + */ + public boolean equals(Object o) { + // Override AbstractSet version to avoid calling size() + if (o == this) + return true; + if (!(o instanceof Set)) + return false; + Collection<?> c = (Collection<?>) o; + try { + return containsAll(c) && c.containsAll(this); + } catch (ClassCastException unused) { + return false; + } catch (NullPointerException unused) { + return false; + } + } + + /** + * Removes from this set all of its elements that are contained in + * the specified collection. If the specified collection is also + * a set, this operation effectively modifies this set so that its + * value is the <i>asymmetric set difference</i> of the two sets. + * + * @param c collection containing elements to be removed from this set + * @return <tt>true</tt> if this set changed as a result of the call + * @throws ClassCastException if the types of one or more elements in this + * set are incompatible with the specified collection + * @throws NullPointerException if the specified collection or any + * of its elements are null + */ + public boolean removeAll(Collection<?> c) { + // Override AbstractSet version to avoid unnecessary call to size() + boolean modified = false; + for (Iterator<?> i = c.iterator(); i.hasNext(); ) + if (remove(i.next())) + modified = true; + return modified; + } + + /* ---------------- Relational operations -------------- */ + + /** + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException if the specified element is null + */ + public E lower(E e) { + return m.lowerKey(e); + } + + /** + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException if the specified element is null + */ + public E floor(E e) { + return m.floorKey(e); + } + + /** + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException if the specified element is null + */ + public E ceiling(E e) { + return m.ceilingKey(e); + } + + /** + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException if the specified element is null + */ + public E higher(E e) { + return m.higherKey(e); + } + + public E pollFirst() { + Map.Entry<E,Object> e = m.pollFirstEntry(); + return e == null? null : e.getKey(); + } + + public E pollLast() { + Map.Entry<E,Object> e = m.pollLastEntry(); + return e == null? null : e.getKey(); + } + + + /* ---------------- SortedSet operations -------------- */ + + + public Comparator<? super E> comparator() { + return m.comparator(); + } + + /** + * @throws NoSuchElementException {@inheritDoc} + */ + public E first() { + return m.firstKey(); + } + + /** + * @throws NoSuchElementException {@inheritDoc} + */ + public E last() { + return m.lastKey(); + } + + /** + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException if {@code fromElement} or + * {@code toElement} is null + * @throws IllegalArgumentException {@inheritDoc} + */ + public NavigableSet<E> subSet(E fromElement, + boolean fromInclusive, + E toElement, + boolean toInclusive) { + return new ConcurrentSkipListSet<E> + (m.subMap(fromElement, fromInclusive, + toElement, toInclusive)); + } + + /** + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException if {@code toElement} is null + * @throws IllegalArgumentException {@inheritDoc} + */ + public NavigableSet<E> headSet(E toElement, boolean inclusive) { + return new ConcurrentSkipListSet<E>(m.headMap(toElement, inclusive)); + } + + /** + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException if {@code fromElement} is null + * @throws IllegalArgumentException {@inheritDoc} + */ + public NavigableSet<E> tailSet(E fromElement, boolean inclusive) { + return new ConcurrentSkipListSet<E>(m.tailMap(fromElement, inclusive)); + } + + /** + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException if {@code fromElement} or + * {@code toElement} is null + * @throws IllegalArgumentException {@inheritDoc} + */ + public NavigableSet<E> subSet(E fromElement, E toElement) { + return subSet(fromElement, true, toElement, false); + } + + /** + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException if {@code toElement} is null + * @throws IllegalArgumentException {@inheritDoc} + */ + public NavigableSet<E> headSet(E toElement) { + return headSet(toElement, false); + } + + /** + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException if {@code fromElement} is null + * @throws IllegalArgumentException {@inheritDoc} + */ + public NavigableSet<E> tailSet(E fromElement) { + return tailSet(fromElement, true); + } + + /** + * Returns a reverse order view of the elements contained in this set. + * The descending set is backed by this set, so changes to the set are + * reflected in the descending set, and vice-versa. + * + * <p>The returned set has an ordering equivalent to + * <tt>{@link Collections#reverseOrder(Comparator) Collections.reverseOrder}(comparator())</tt>. + * The expression {@code s.descendingSet().descendingSet()} returns a + * view of {@code s} essentially equivalent to {@code s}. + * + * @return a reverse order view of this set + */ + public NavigableSet<E> descendingSet() { + return new ConcurrentSkipListSet(m.descendingMap()); + } + + // Support for resetting map in clone + private static final Unsafe unsafe = Unsafe.getUnsafe(); + private static final long mapOffset; + static { + try { + mapOffset = unsafe.objectFieldOffset + (ConcurrentSkipListSet.class.getDeclaredField("m")); + } catch (Exception ex) { throw new Error(ex); } + } + private void setMap(ConcurrentNavigableMap<E,Object> map) { + unsafe.putObjectVolatile(this, mapOffset, map); + } + +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/CopyOnWriteArraySet.java b/libjava/classpath/external/jsr166/java/util/concurrent/CopyOnWriteArraySet.java new file mode 100644 index 000000000..063636bd8 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/CopyOnWriteArraySet.java @@ -0,0 +1,364 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain. Use, modify, and + * redistribute this code in any way without acknowledgement. + */ + +package java.util.concurrent; +import java.util.*; + +/** + * A {@link java.util.Set} that uses an internal {@link CopyOnWriteArrayList} + * for all of its operations. Thus, it shares the same basic properties: + * <ul> + * <li>It is best suited for applications in which set sizes generally + * stay small, read-only operations + * vastly outnumber mutative operations, and you need + * to prevent interference among threads during traversal. + * <li>It is thread-safe. + * <li>Mutative operations (<tt>add</tt>, <tt>set</tt>, <tt>remove</tt>, etc.) + * are expensive since they usually entail copying the entire underlying + * array. + * <li>Iterators do not support the mutative <tt>remove</tt> operation. + * <li>Traversal via iterators is fast and cannot encounter + * interference from other threads. Iterators rely on + * unchanging snapshots of the array at the time the iterators were + * constructed. + * </ul> + * + * <p> <b>Sample Usage.</b> The following code sketch uses a + * copy-on-write set to maintain a set of Handler objects that + * perform some action upon state updates. + * + * <pre> + * class Handler { void handle(); ... } + * + * class X { + * private final CopyOnWriteArraySet<Handler> handlers + * = new CopyOnWriteArraySet<Handler>(); + * public void addHandler(Handler h) { handlers.add(h); } + * + * private long internalState; + * private synchronized void changeState() { internalState = ...; } + * + * public void update() { + * changeState(); + * for (Handler handler : handlers) + * handler.handle(); + * } + * } + * </pre> + * + * <p>This class is a member of the + * <a href="{@docRoot}/../technotes/guides/collections/index.html"> + * Java Collections Framework</a>. + * + * @see CopyOnWriteArrayList + * @since 1.5 + * @author Doug Lea + * @param <E> the type of elements held in this collection + */ +public class CopyOnWriteArraySet<E> extends AbstractSet<E> + implements java.io.Serializable { + private static final long serialVersionUID = 5457747651344034263L; + + private final CopyOnWriteArrayList<E> al; + + /** + * Creates an empty set. + */ + public CopyOnWriteArraySet() { + al = new CopyOnWriteArrayList<E>(); + } + + /** + * Creates a set containing all of the elements of the specified + * collection. + * + * @param c the collection of elements to initially contain + * @throws NullPointerException if the specified collection is null + */ + public CopyOnWriteArraySet(Collection<? extends E> c) { + al = new CopyOnWriteArrayList<E>(); + al.addAllAbsent(c); + } + + /** + * Returns the number of elements in this set. + * + * @return the number of elements in this set + */ + public int size() { + return al.size(); + } + + /** + * Returns <tt>true</tt> if this set contains no elements. + * + * @return <tt>true</tt> if this set contains no elements + */ + public boolean isEmpty() { + return al.isEmpty(); + } + + /** + * Returns <tt>true</tt> if this set contains the specified element. + * More formally, returns <tt>true</tt> if and only if this set + * contains an element <tt>e</tt> such that + * <tt>(o==null ? e==null : o.equals(e))</tt>. + * + * @param o element whose presence in this set is to be tested + * @return <tt>true</tt> if this set contains the specified element + */ + public boolean contains(Object o) { + return al.contains(o); + } + + /** + * Returns an array containing all of the elements in this set. + * If this set makes any guarantees as to what order its elements + * are returned by its iterator, this method must return the + * elements in the same order. + * + * <p>The returned array will be "safe" in that no references to it + * are maintained by this set. (In other words, this method must + * allocate a new array even if this set is backed by an array). + * The caller is thus free to modify the returned array. + * + * <p>This method acts as bridge between array-based and collection-based + * APIs. + * + * @return an array containing all the elements in this set + */ + public Object[] toArray() { + return al.toArray(); + } + + /** + * Returns an array containing all of the elements in this set; the + * runtime type of the returned array is that of the specified array. + * If the set fits in the specified array, it is returned therein. + * Otherwise, a new array is allocated with the runtime type of the + * specified array and the size of this set. + * + * <p>If this set fits in the specified array with room to spare + * (i.e., the array has more elements than this set), the element in + * the array immediately following the end of the set is set to + * <tt>null</tt>. (This is useful in determining the length of this + * set <i>only</i> if the caller knows that this set does not contain + * any null elements.) + * + * <p>If this set makes any guarantees as to what order its elements + * are returned by its iterator, this method must return the elements + * in the same order. + * + * <p>Like the {@link #toArray()} method, this method acts as bridge between + * array-based and collection-based APIs. Further, this method allows + * precise control over the runtime type of the output array, and may, + * under certain circumstances, be used to save allocation costs. + * + * <p>Suppose <tt>x</tt> is a set known to contain only strings. + * The following code can be used to dump the set into a newly allocated + * array of <tt>String</tt>: + * + * <pre> + * String[] y = x.toArray(new String[0]);</pre> + * + * Note that <tt>toArray(new Object[0])</tt> is identical in function to + * <tt>toArray()</tt>. + * + * @param a the array into which the elements of this set are to be + * stored, if it is big enough; otherwise, a new array of the same + * runtime type is allocated for this purpose. + * @return an array containing all the elements in this set + * @throws ArrayStoreException if the runtime type of the specified array + * is not a supertype of the runtime type of every element in this + * set + * @throws NullPointerException if the specified array is null + */ + public <T> T[] toArray(T[] a) { + return al.toArray(a); + } + + /** + * Removes all of the elements from this set. + * The set will be empty after this call returns. + */ + public void clear() { + al.clear(); + } + + /** + * Removes the specified element from this set if it is present. + * More formally, removes an element <tt>e</tt> such that + * <tt>(o==null ? e==null : o.equals(e))</tt>, + * if this set contains such an element. Returns <tt>true</tt> if + * this set contained the element (or equivalently, if this set + * changed as a result of the call). (This set will not contain the + * element once the call returns.) + * + * @param o object to be removed from this set, if present + * @return <tt>true</tt> if this set contained the specified element + */ + public boolean remove(Object o) { + return al.remove(o); + } + + /** + * Adds the specified element to this set if it is not already present. + * More formally, adds the specified element <tt>e</tt> to this set if + * the set contains no element <tt>e2</tt> such that + * <tt>(e==null ? e2==null : e.equals(e2))</tt>. + * If this set already contains the element, the call leaves the set + * unchanged and returns <tt>false</tt>. + * + * @param e element to be added to this set + * @return <tt>true</tt> if this set did not already contain the specified + * element + */ + public boolean add(E e) { + return al.addIfAbsent(e); + } + + /** + * Returns <tt>true</tt> if this set contains all of the elements of the + * specified collection. If the specified collection is also a set, this + * method returns <tt>true</tt> if it is a <i>subset</i> of this set. + * + * @param c collection to be checked for containment in this set + * @return <tt>true</tt> if this set contains all of the elements of the + * specified collection + * @throws NullPointerException if the specified collection is null + * @see #contains(Object) + */ + public boolean containsAll(Collection<?> c) { + return al.containsAll(c); + } + + /** + * Adds all of the elements in the specified collection to this set if + * they're not already present. If the specified collection is also a + * set, the <tt>addAll</tt> operation effectively modifies this set so + * that its value is the <i>union</i> of the two sets. The behavior of + * this operation is undefined if the specified collection is modified + * while the operation is in progress. + * + * @param c collection containing elements to be added to this set + * @return <tt>true</tt> if this set changed as a result of the call + * @throws NullPointerException if the specified collection is null + * @see #add(Object) + */ + public boolean addAll(Collection<? extends E> c) { + return al.addAllAbsent(c) > 0; + } + + /** + * Removes from this set all of its elements that are contained in the + * specified collection. If the specified collection is also a set, + * this operation effectively modifies this set so that its value is the + * <i>asymmetric set difference</i> of the two sets. + * + * @param c collection containing elements to be removed from this set + * @return <tt>true</tt> if this set changed as a result of the call + * @throws ClassCastException if the class of an element of this set + * is incompatible with the specified collection (optional) + * @throws NullPointerException if this set contains a null element and the + * specified collection does not permit null elements (optional), + * or if the specified collection is null + * @see #remove(Object) + */ + public boolean removeAll(Collection<?> c) { + return al.removeAll(c); + } + + /** + * Retains only the elements in this set that are contained in the + * specified collection. In other words, removes from this set all of + * its elements that are not contained in the specified collection. If + * the specified collection is also a set, this operation effectively + * modifies this set so that its value is the <i>intersection</i> of the + * two sets. + * + * @param c collection containing elements to be retained in this set + * @return <tt>true</tt> if this set changed as a result of the call + * @throws ClassCastException if the class of an element of this set + * is incompatible with the specified collection (optional) + * @throws NullPointerException if this set contains a null element and the + * specified collection does not permit null elements (optional), + * or if the specified collection is null + * @see #remove(Object) + */ + public boolean retainAll(Collection<?> c) { + return al.retainAll(c); + } + + /** + * Returns an iterator over the elements contained in this set + * in the order in which these elements were added. + * + * <p>The returned iterator provides a snapshot of the state of the set + * when the iterator was constructed. No synchronization is needed while + * traversing the iterator. The iterator does <em>NOT</em> support the + * <tt>remove</tt> method. + * + * @return an iterator over the elements in this set + */ + public Iterator<E> iterator() { + return al.iterator(); + } + + /** + * Compares the specified object with this set for equality. + * Returns {@code true} if the specified object is the same object + * as this object, or if it is also a {@link Set} and the elements + * returned by an {@linkplain List#iterator() iterator} over the + * specified set are the same as the elements returned by an + * iterator over this set. More formally, the two iterators are + * considered to return the same elements if they return the same + * number of elements and for every element {@code e1} returned by + * the iterator over the specified set, there is an element + * {@code e2} returned by the iterator over this set such that + * {@code (e1==null ? e2==null : e1.equals(e2))}. + * + * @param o object to be compared for equality with this set + * @return {@code true} if the specified object is equal to this set + */ + public boolean equals(Object o) { + if (o == this) + return true; + if (!(o instanceof Set)) + return false; + Set<?> set = (Set<?>)(o); + Iterator<?> it = set.iterator(); + + // Uses O(n^2) algorithm that is only appropriate + // for small sets, which CopyOnWriteArraySets should be. + + // Use a single snapshot of underlying array + Object[] elements = al.getArray(); + int len = elements.length; + // Mark matched elements to avoid re-checking + boolean[] matched = new boolean[len]; + int k = 0; + outer: while (it.hasNext()) { + if (++k > len) + return false; + Object x = it.next(); + for (int i = 0; i < len; ++i) { + if (!matched[i] && eq(x, elements[i])) { + matched[i] = true; + continue outer; + } + } + return false; + } + return k == len; + } + + /** + * Test for equality, coping with nulls. + */ + private static boolean eq(Object o1, Object o2) { + return (o1 == null ? o2 == null : o1.equals(o2)); + } +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/CountDownLatch.java b/libjava/classpath/external/jsr166/java/util/concurrent/CountDownLatch.java new file mode 100644 index 000000000..016c1a7a5 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/CountDownLatch.java @@ -0,0 +1,290 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; +import java.util.concurrent.locks.*; +import java.util.concurrent.atomic.*; + +/** + * A synchronization aid that allows one or more threads to wait until + * a set of operations being performed in other threads completes. + * + * <p>A {@code CountDownLatch} is initialized with a given <em>count</em>. + * The {@link #await await} methods block until the current count reaches + * zero due to invocations of the {@link #countDown} method, after which + * all waiting threads are released and any subsequent invocations of + * {@link #await await} return immediately. This is a one-shot phenomenon + * -- the count cannot be reset. If you need a version that resets the + * count, consider using a {@link CyclicBarrier}. + * + * <p>A {@code CountDownLatch} is a versatile synchronization tool + * and can be used for a number of purposes. A + * {@code CountDownLatch} initialized with a count of one serves as a + * simple on/off latch, or gate: all threads invoking {@link #await await} + * wait at the gate until it is opened by a thread invoking {@link + * #countDown}. A {@code CountDownLatch} initialized to <em>N</em> + * can be used to make one thread wait until <em>N</em> threads have + * completed some action, or some action has been completed N times. + * + * <p>A useful property of a {@code CountDownLatch} is that it + * doesn't require that threads calling {@code countDown} wait for + * the count to reach zero before proceeding, it simply prevents any + * thread from proceeding past an {@link #await await} until all + * threads could pass. + * + * <p><b>Sample usage:</b> Here is a pair of classes in which a group + * of worker threads use two countdown latches: + * <ul> + * <li>The first is a start signal that prevents any worker from proceeding + * until the driver is ready for them to proceed; + * <li>The second is a completion signal that allows the driver to wait + * until all workers have completed. + * </ul> + * + * <pre> + * class Driver { // ... + * void main() throws InterruptedException { + * CountDownLatch startSignal = new CountDownLatch(1); + * CountDownLatch doneSignal = new CountDownLatch(N); + * + * for (int i = 0; i < N; ++i) // create and start threads + * new Thread(new Worker(startSignal, doneSignal)).start(); + * + * doSomethingElse(); // don't let run yet + * startSignal.countDown(); // let all threads proceed + * doSomethingElse(); + * doneSignal.await(); // wait for all to finish + * } + * } + * + * class Worker implements Runnable { + * private final CountDownLatch startSignal; + * private final CountDownLatch doneSignal; + * Worker(CountDownLatch startSignal, CountDownLatch doneSignal) { + * this.startSignal = startSignal; + * this.doneSignal = doneSignal; + * } + * public void run() { + * try { + * startSignal.await(); + * doWork(); + * doneSignal.countDown(); + * } catch (InterruptedException ex) {} // return; + * } + * + * void doWork() { ... } + * } + * + * </pre> + * + * <p>Another typical usage would be to divide a problem into N parts, + * describe each part with a Runnable that executes that portion and + * counts down on the latch, and queue all the Runnables to an + * Executor. When all sub-parts are complete, the coordinating thread + * will be able to pass through await. (When threads must repeatedly + * count down in this way, instead use a {@link CyclicBarrier}.) + * + * <pre> + * class Driver2 { // ... + * void main() throws InterruptedException { + * CountDownLatch doneSignal = new CountDownLatch(N); + * Executor e = ... + * + * for (int i = 0; i < N; ++i) // create and start threads + * e.execute(new WorkerRunnable(doneSignal, i)); + * + * doneSignal.await(); // wait for all to finish + * } + * } + * + * class WorkerRunnable implements Runnable { + * private final CountDownLatch doneSignal; + * private final int i; + * WorkerRunnable(CountDownLatch doneSignal, int i) { + * this.doneSignal = doneSignal; + * this.i = i; + * } + * public void run() { + * try { + * doWork(i); + * doneSignal.countDown(); + * } catch (InterruptedException ex) {} // return; + * } + * + * void doWork() { ... } + * } + * + * </pre> + * + * <p>Memory consistency effects: Actions in a thread prior to calling + * {@code countDown()} + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a> + * actions following a successful return from a corresponding + * {@code await()} in another thread. + * + * @since 1.5 + * @author Doug Lea + */ +public class CountDownLatch { + /** + * Synchronization control For CountDownLatch. + * Uses AQS state to represent count. + */ + private static final class Sync extends AbstractQueuedSynchronizer { + private static final long serialVersionUID = 4982264981922014374L; + + Sync(int count) { + setState(count); + } + + int getCount() { + return getState(); + } + + public int tryAcquireShared(int acquires) { + return getState() == 0? 1 : -1; + } + + public boolean tryReleaseShared(int releases) { + // Decrement count; signal when transition to zero + for (;;) { + int c = getState(); + if (c == 0) + return false; + int nextc = c-1; + if (compareAndSetState(c, nextc)) + return nextc == 0; + } + } + } + + private final Sync sync; + + /** + * Constructs a {@code CountDownLatch} initialized with the given count. + * + * @param count the number of times {@link #countDown} must be invoked + * before threads can pass through {@link #await} + * @throws IllegalArgumentException if {@code count} is negative + */ + public CountDownLatch(int count) { + if (count < 0) throw new IllegalArgumentException("count < 0"); + this.sync = new Sync(count); + } + + /** + * Causes the current thread to wait until the latch has counted down to + * zero, unless the thread is {@linkplain Thread#interrupt interrupted}. + * + * <p>If the current count is zero then this method returns immediately. + * + * <p>If the current count is greater than zero then the current + * thread becomes disabled for thread scheduling purposes and lies + * dormant until one of two things happen: + * <ul> + * <li>The count reaches zero due to invocations of the + * {@link #countDown} method; or + * <li>Some other thread {@linkplain Thread#interrupt interrupts} + * the current thread. + * </ul> + * + * <p>If the current thread: + * <ul> + * <li>has its interrupted status set on entry to this method; or + * <li>is {@linkplain Thread#interrupt interrupted} while waiting, + * </ul> + * then {@link InterruptedException} is thrown and the current thread's + * interrupted status is cleared. + * + * @throws InterruptedException if the current thread is interrupted + * while waiting + */ + public void await() throws InterruptedException { + sync.acquireSharedInterruptibly(1); + } + + /** + * Causes the current thread to wait until the latch has counted down to + * zero, unless the thread is {@linkplain Thread#interrupt interrupted}, + * or the specified waiting time elapses. + * + * <p>If the current count is zero then this method returns immediately + * with the value {@code true}. + * + * <p>If the current count is greater than zero then the current + * thread becomes disabled for thread scheduling purposes and lies + * dormant until one of three things happen: + * <ul> + * <li>The count reaches zero due to invocations of the + * {@link #countDown} method; or + * <li>Some other thread {@linkplain Thread#interrupt interrupts} + * the current thread; or + * <li>The specified waiting time elapses. + * </ul> + * + * <p>If the count reaches zero then the method returns with the + * value {@code true}. + * + * <p>If the current thread: + * <ul> + * <li>has its interrupted status set on entry to this method; or + * <li>is {@linkplain Thread#interrupt interrupted} while waiting, + * </ul> + * then {@link InterruptedException} is thrown and the current thread's + * interrupted status is cleared. + * + * <p>If the specified waiting time elapses then the value {@code false} + * is returned. If the time is less than or equal to zero, the method + * will not wait at all. + * + * @param timeout the maximum time to wait + * @param unit the time unit of the {@code timeout} argument + * @return {@code true} if the count reached zero and {@code false} + * if the waiting time elapsed before the count reached zero + * @throws InterruptedException if the current thread is interrupted + * while waiting + */ + public boolean await(long timeout, TimeUnit unit) + throws InterruptedException { + return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout)); + } + + /** + * Decrements the count of the latch, releasing all waiting threads if + * the count reaches zero. + * + * <p>If the current count is greater than zero then it is decremented. + * If the new count is zero then all waiting threads are re-enabled for + * thread scheduling purposes. + * + * <p>If the current count equals zero then nothing happens. + */ + public void countDown() { + sync.releaseShared(1); + } + + /** + * Returns the current count. + * + * <p>This method is typically used for debugging and testing purposes. + * + * @return the current count + */ + public long getCount() { + return sync.getCount(); + } + + /** + * Returns a string identifying this latch, as well as its state. + * The state, in brackets, includes the String {@code "Count ="} + * followed by the current count. + * + * @return a string identifying this latch, as well as its state + */ + public String toString() { + return super.toString() + "[Count = " + sync.getCount() + "]"; + } +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/CyclicBarrier.java b/libjava/classpath/external/jsr166/java/util/concurrent/CyclicBarrier.java new file mode 100644 index 000000000..d5738c5ae --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/CyclicBarrier.java @@ -0,0 +1,454 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; +import java.util.concurrent.locks.*; + +/** + * A synchronization aid that allows a set of threads to all wait for + * each other to reach a common barrier point. CyclicBarriers are + * useful in programs involving a fixed sized party of threads that + * must occasionally wait for each other. The barrier is called + * <em>cyclic</em> because it can be re-used after the waiting threads + * are released. + * + * <p>A <tt>CyclicBarrier</tt> supports an optional {@link Runnable} command + * that is run once per barrier point, after the last thread in the party + * arrives, but before any threads are released. + * This <em>barrier action</em> is useful + * for updating shared-state before any of the parties continue. + * + * <p><b>Sample usage:</b> Here is an example of + * using a barrier in a parallel decomposition design: + * <pre> + * class Solver { + * final int N; + * final float[][] data; + * final CyclicBarrier barrier; + * + * class Worker implements Runnable { + * int myRow; + * Worker(int row) { myRow = row; } + * public void run() { + * while (!done()) { + * processRow(myRow); + * + * try { + * barrier.await(); + * } catch (InterruptedException ex) { + * return; + * } catch (BrokenBarrierException ex) { + * return; + * } + * } + * } + * } + * + * public Solver(float[][] matrix) { + * data = matrix; + * N = matrix.length; + * barrier = new CyclicBarrier(N, + * new Runnable() { + * public void run() { + * mergeRows(...); + * } + * }); + * for (int i = 0; i < N; ++i) + * new Thread(new Worker(i)).start(); + * + * waitUntilDone(); + * } + * } + * </pre> + * Here, each worker thread processes a row of the matrix then waits at the + * barrier until all rows have been processed. When all rows are processed + * the supplied {@link Runnable} barrier action is executed and merges the + * rows. If the merger + * determines that a solution has been found then <tt>done()</tt> will return + * <tt>true</tt> and each worker will terminate. + * + * <p>If the barrier action does not rely on the parties being suspended when + * it is executed, then any of the threads in the party could execute that + * action when it is released. To facilitate this, each invocation of + * {@link #await} returns the arrival index of that thread at the barrier. + * You can then choose which thread should execute the barrier action, for + * example: + * <pre> if (barrier.await() == 0) { + * // log the completion of this iteration + * }</pre> + * + * <p>The <tt>CyclicBarrier</tt> uses an all-or-none breakage model + * for failed synchronization attempts: If a thread leaves a barrier + * point prematurely because of interruption, failure, or timeout, all + * other threads waiting at that barrier point will also leave + * abnormally via {@link BrokenBarrierException} (or + * {@link InterruptedException} if they too were interrupted at about + * the same time). + * + * <p>Memory consistency effects: Actions in a thread prior to calling + * {@code await()} + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a> + * actions that are part of the barrier action, which in turn + * <i>happen-before</i> actions following a successful return from the + * corresponding {@code await()} in other threads. + * + * @since 1.5 + * @see CountDownLatch + * + * @author Doug Lea + */ +public class CyclicBarrier { + /** + * Each use of the barrier is represented as a generation instance. + * The generation changes whenever the barrier is tripped, or + * is reset. There can be many generations associated with threads + * using the barrier - due to the non-deterministic way the lock + * may be allocated to waiting threads - but only one of these + * can be active at a time (the one to which <tt>count</tt> applies) + * and all the rest are either broken or tripped. + * There need not be an active generation if there has been a break + * but no subsequent reset. + */ + private static class Generation { + boolean broken = false; + } + + /** The lock for guarding barrier entry */ + private final ReentrantLock lock = new ReentrantLock(); + /** Condition to wait on until tripped */ + private final Condition trip = lock.newCondition(); + /** The number of parties */ + private final int parties; + /* The command to run when tripped */ + private final Runnable barrierCommand; + /** The current generation */ + private Generation generation = new Generation(); + + /** + * Number of parties still waiting. Counts down from parties to 0 + * on each generation. It is reset to parties on each new + * generation or when broken. + */ + private int count; + + /** + * Updates state on barrier trip and wakes up everyone. + * Called only while holding lock. + */ + private void nextGeneration() { + // signal completion of last generation + trip.signalAll(); + // set up next generation + count = parties; + generation = new Generation(); + } + + /** + * Sets current barrier generation as broken and wakes up everyone. + * Called only while holding lock. + */ + private void breakBarrier() { + generation.broken = true; + count = parties; + trip.signalAll(); + } + + /** + * Main barrier code, covering the various policies. + */ + private int dowait(boolean timed, long nanos) + throws InterruptedException, BrokenBarrierException, + TimeoutException { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + final Generation g = generation; + + if (g.broken) + throw new BrokenBarrierException(); + + if (Thread.interrupted()) { + breakBarrier(); + throw new InterruptedException(); + } + + int index = --count; + if (index == 0) { // tripped + boolean ranAction = false; + try { + final Runnable command = barrierCommand; + if (command != null) + command.run(); + ranAction = true; + nextGeneration(); + return 0; + } finally { + if (!ranAction) + breakBarrier(); + } + } + + // loop until tripped, broken, interrupted, or timed out + for (;;) { + try { + if (!timed) + trip.await(); + else if (nanos > 0L) + nanos = trip.awaitNanos(nanos); + } catch (InterruptedException ie) { + if (g == generation && ! g.broken) { + breakBarrier(); + throw ie; + } else { + // We're about to finish waiting even if we had not + // been interrupted, so this interrupt is deemed to + // "belong" to subsequent execution. + Thread.currentThread().interrupt(); + } + } + + if (g.broken) + throw new BrokenBarrierException(); + + if (g != generation) + return index; + + if (timed && nanos <= 0L) { + breakBarrier(); + throw new TimeoutException(); + } + } + } finally { + lock.unlock(); + } + } + + /** + * Creates a new <tt>CyclicBarrier</tt> that will trip when the + * given number of parties (threads) are waiting upon it, and which + * will execute the given barrier action when the barrier is tripped, + * performed by the last thread entering the barrier. + * + * @param parties the number of threads that must invoke {@link #await} + * before the barrier is tripped + * @param barrierAction the command to execute when the barrier is + * tripped, or {@code null} if there is no action + * @throws IllegalArgumentException if {@code parties} is less than 1 + */ + public CyclicBarrier(int parties, Runnable barrierAction) { + if (parties <= 0) throw new IllegalArgumentException(); + this.parties = parties; + this.count = parties; + this.barrierCommand = barrierAction; + } + + /** + * Creates a new <tt>CyclicBarrier</tt> that will trip when the + * given number of parties (threads) are waiting upon it, and + * does not perform a predefined action when the barrier is tripped. + * + * @param parties the number of threads that must invoke {@link #await} + * before the barrier is tripped + * @throws IllegalArgumentException if {@code parties} is less than 1 + */ + public CyclicBarrier(int parties) { + this(parties, null); + } + + /** + * Returns the number of parties required to trip this barrier. + * + * @return the number of parties required to trip this barrier + */ + public int getParties() { + return parties; + } + + /** + * Waits until all {@linkplain #getParties parties} have invoked + * <tt>await</tt> on this barrier. + * + * <p>If the current thread is not the last to arrive then it is + * disabled for thread scheduling purposes and lies dormant until + * one of the following things happens: + * <ul> + * <li>The last thread arrives; or + * <li>Some other thread {@linkplain Thread#interrupt interrupts} + * the current thread; or + * <li>Some other thread {@linkplain Thread#interrupt interrupts} + * one of the other waiting threads; or + * <li>Some other thread times out while waiting for barrier; or + * <li>Some other thread invokes {@link #reset} on this barrier. + * </ul> + * + * <p>If the current thread: + * <ul> + * <li>has its interrupted status set on entry to this method; or + * <li>is {@linkplain Thread#interrupt interrupted} while waiting + * </ul> + * then {@link InterruptedException} is thrown and the current thread's + * interrupted status is cleared. + * + * <p>If the barrier is {@link #reset} while any thread is waiting, + * or if the barrier {@linkplain #isBroken is broken} when + * <tt>await</tt> is invoked, or while any thread is waiting, then + * {@link BrokenBarrierException} is thrown. + * + * <p>If any thread is {@linkplain Thread#interrupt interrupted} while waiting, + * then all other waiting threads will throw + * {@link BrokenBarrierException} and the barrier is placed in the broken + * state. + * + * <p>If the current thread is the last thread to arrive, and a + * non-null barrier action was supplied in the constructor, then the + * current thread runs the action before allowing the other threads to + * continue. + * If an exception occurs during the barrier action then that exception + * will be propagated in the current thread and the barrier is placed in + * the broken state. + * + * @return the arrival index of the current thread, where index + * <tt>{@link #getParties()} - 1</tt> indicates the first + * to arrive and zero indicates the last to arrive + * @throws InterruptedException if the current thread was interrupted + * while waiting + * @throws BrokenBarrierException if <em>another</em> thread was + * interrupted or timed out while the current thread was + * waiting, or the barrier was reset, or the barrier was + * broken when {@code await} was called, or the barrier + * action (if present) failed due an exception. + */ + public int await() throws InterruptedException, BrokenBarrierException { + try { + return dowait(false, 0L); + } catch (TimeoutException toe) { + throw new Error(toe); // cannot happen; + } + } + + /** + * Waits until all {@linkplain #getParties parties} have invoked + * <tt>await</tt> on this barrier, or the specified waiting time elapses. + * + * <p>If the current thread is not the last to arrive then it is + * disabled for thread scheduling purposes and lies dormant until + * one of the following things happens: + * <ul> + * <li>The last thread arrives; or + * <li>The specified timeout elapses; or + * <li>Some other thread {@linkplain Thread#interrupt interrupts} + * the current thread; or + * <li>Some other thread {@linkplain Thread#interrupt interrupts} + * one of the other waiting threads; or + * <li>Some other thread times out while waiting for barrier; or + * <li>Some other thread invokes {@link #reset} on this barrier. + * </ul> + * + * <p>If the current thread: + * <ul> + * <li>has its interrupted status set on entry to this method; or + * <li>is {@linkplain Thread#interrupt interrupted} while waiting + * </ul> + * then {@link InterruptedException} is thrown and the current thread's + * interrupted status is cleared. + * + * <p>If the specified waiting time elapses then {@link TimeoutException} + * is thrown. If the time is less than or equal to zero, the + * method will not wait at all. + * + * <p>If the barrier is {@link #reset} while any thread is waiting, + * or if the barrier {@linkplain #isBroken is broken} when + * <tt>await</tt> is invoked, or while any thread is waiting, then + * {@link BrokenBarrierException} is thrown. + * + * <p>If any thread is {@linkplain Thread#interrupt interrupted} while + * waiting, then all other waiting threads will throw {@link + * BrokenBarrierException} and the barrier is placed in the broken + * state. + * + * <p>If the current thread is the last thread to arrive, and a + * non-null barrier action was supplied in the constructor, then the + * current thread runs the action before allowing the other threads to + * continue. + * If an exception occurs during the barrier action then that exception + * will be propagated in the current thread and the barrier is placed in + * the broken state. + * + * @param timeout the time to wait for the barrier + * @param unit the time unit of the timeout parameter + * @return the arrival index of the current thread, where index + * <tt>{@link #getParties()} - 1</tt> indicates the first + * to arrive and zero indicates the last to arrive + * @throws InterruptedException if the current thread was interrupted + * while waiting + * @throws TimeoutException if the specified timeout elapses + * @throws BrokenBarrierException if <em>another</em> thread was + * interrupted or timed out while the current thread was + * waiting, or the barrier was reset, or the barrier was broken + * when {@code await} was called, or the barrier action (if + * present) failed due an exception + */ + public int await(long timeout, TimeUnit unit) + throws InterruptedException, + BrokenBarrierException, + TimeoutException { + return dowait(true, unit.toNanos(timeout)); + } + + /** + * Queries if this barrier is in a broken state. + * + * @return {@code true} if one or more parties broke out of this + * barrier due to interruption or timeout since + * construction or the last reset, or a barrier action + * failed due to an exception; {@code false} otherwise. + */ + public boolean isBroken() { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + return generation.broken; + } finally { + lock.unlock(); + } + } + + /** + * Resets the barrier to its initial state. If any parties are + * currently waiting at the barrier, they will return with a + * {@link BrokenBarrierException}. Note that resets <em>after</em> + * a breakage has occurred for other reasons can be complicated to + * carry out; threads need to re-synchronize in some other way, + * and choose one to perform the reset. It may be preferable to + * instead create a new barrier for subsequent use. + */ + public void reset() { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + breakBarrier(); // break the current generation + nextGeneration(); // start a new generation + } finally { + lock.unlock(); + } + } + + /** + * Returns the number of parties currently waiting at the barrier. + * This method is primarily useful for debugging and assertions. + * + * @return the number of parties currently blocked in {@link #await} + */ + public int getNumberWaiting() { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + return parties - count; + } finally { + lock.unlock(); + } + } +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/DelayQueue.java b/libjava/classpath/external/jsr166/java/util/concurrent/DelayQueue.java new file mode 100644 index 000000000..4ce7bc652 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/DelayQueue.java @@ -0,0 +1,487 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + + +package java.util.concurrent; +import java.util.concurrent.locks.*; +import java.util.*; + +/** + * An unbounded {@linkplain BlockingQueue blocking queue} of + * <tt>Delayed</tt> elements, in which an element can only be taken + * when its delay has expired. The <em>head</em> of the queue is that + * <tt>Delayed</tt> element whose delay expired furthest in the + * past. If no delay has expired there is no head and <tt>poll</tt> + * will return <tt>null</tt>. Expiration occurs when an element's + * <tt>getDelay(TimeUnit.NANOSECONDS)</tt> method returns a value less + * than or equal to zero. Even though unexpired elements cannot be + * removed using <tt>take</tt> or <tt>poll</tt>, they are otherwise + * treated as normal elements. For example, the <tt>size</tt> method + * returns the count of both expired and unexpired elements. + * This queue does not permit null elements. + * + * <p>This class and its iterator implement all of the + * <em>optional</em> methods of the {@link Collection} and {@link + * Iterator} interfaces. + * + * <p>This class is a member of the + * <a href="{@docRoot}/../technotes/guides/collections/index.html"> + * Java Collections Framework</a>. + * + * @since 1.5 + * @author Doug Lea + * @param <E> the type of elements held in this collection + */ + +public class DelayQueue<E extends Delayed> extends AbstractQueue<E> + implements BlockingQueue<E> { + + private transient final ReentrantLock lock = new ReentrantLock(); + private transient final Condition available = lock.newCondition(); + private final PriorityQueue<E> q = new PriorityQueue<E>(); + + /** + * Creates a new <tt>DelayQueue</tt> that is initially empty. + */ + public DelayQueue() {} + + /** + * Creates a <tt>DelayQueue</tt> initially containing the elements of the + * given collection of {@link Delayed} instances. + * + * @param c the collection of elements to initially contain + * @throws NullPointerException if the specified collection or any + * of its elements are null + */ + public DelayQueue(Collection<? extends E> c) { + this.addAll(c); + } + + /** + * Inserts the specified element into this delay queue. + * + * @param e the element to add + * @return <tt>true</tt> (as specified by {@link Collection#add}) + * @throws NullPointerException if the specified element is null + */ + public boolean add(E e) { + return offer(e); + } + + /** + * Inserts the specified element into this delay queue. + * + * @param e the element to add + * @return <tt>true</tt> + * @throws NullPointerException if the specified element is null + */ + public boolean offer(E e) { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + E first = q.peek(); + q.offer(e); + if (first == null || e.compareTo(first) < 0) + available.signalAll(); + return true; + } finally { + lock.unlock(); + } + } + + /** + * Inserts the specified element into this delay queue. As the queue is + * unbounded this method will never block. + * + * @param e the element to add + * @throws NullPointerException {@inheritDoc} + */ + public void put(E e) { + offer(e); + } + + /** + * Inserts the specified element into this delay queue. As the queue is + * unbounded this method will never block. + * + * @param e the element to add + * @param timeout This parameter is ignored as the method never blocks + * @param unit This parameter is ignored as the method never blocks + * @return <tt>true</tt> + * @throws NullPointerException {@inheritDoc} + */ + public boolean offer(E e, long timeout, TimeUnit unit) { + return offer(e); + } + + /** + * Retrieves and removes the head of this queue, or returns <tt>null</tt> + * if this queue has no elements with an expired delay. + * + * @return the head of this queue, or <tt>null</tt> if this + * queue has no elements with an expired delay + */ + public E poll() { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + E first = q.peek(); + if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0) + return null; + else { + E x = q.poll(); + assert x != null; + if (q.size() != 0) + available.signalAll(); + return x; + } + } finally { + lock.unlock(); + } + } + + /** + * Retrieves and removes the head of this queue, waiting if necessary + * until an element with an expired delay is available on this queue. + * + * @return the head of this queue + * @throws InterruptedException {@inheritDoc} + */ + public E take() throws InterruptedException { + final ReentrantLock lock = this.lock; + lock.lockInterruptibly(); + try { + for (;;) { + E first = q.peek(); + if (first == null) { + available.await(); + } else { + long delay = first.getDelay(TimeUnit.NANOSECONDS); + if (delay > 0) { + long tl = available.awaitNanos(delay); + } else { + E x = q.poll(); + assert x != null; + if (q.size() != 0) + available.signalAll(); // wake up other takers + return x; + + } + } + } + } finally { + lock.unlock(); + } + } + + /** + * Retrieves and removes the head of this queue, waiting if necessary + * until an element with an expired delay is available on this queue, + * or the specified wait time expires. + * + * @return the head of this queue, or <tt>null</tt> if the + * specified waiting time elapses before an element with + * an expired delay becomes available + * @throws InterruptedException {@inheritDoc} + */ + public E poll(long timeout, TimeUnit unit) throws InterruptedException { + long nanos = unit.toNanos(timeout); + final ReentrantLock lock = this.lock; + lock.lockInterruptibly(); + try { + for (;;) { + E first = q.peek(); + if (first == null) { + if (nanos <= 0) + return null; + else + nanos = available.awaitNanos(nanos); + } else { + long delay = first.getDelay(TimeUnit.NANOSECONDS); + if (delay > 0) { + if (nanos <= 0) + return null; + if (delay > nanos) + delay = nanos; + long timeLeft = available.awaitNanos(delay); + nanos -= delay - timeLeft; + } else { + E x = q.poll(); + assert x != null; + if (q.size() != 0) + available.signalAll(); + return x; + } + } + } + } finally { + lock.unlock(); + } + } + + /** + * Retrieves, but does not remove, the head of this queue, or + * returns <tt>null</tt> if this queue is empty. Unlike + * <tt>poll</tt>, if no expired elements are available in the queue, + * this method returns the element that will expire next, + * if one exists. + * + * @return the head of this queue, or <tt>null</tt> if this + * queue is empty. + */ + public E peek() { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + return q.peek(); + } finally { + lock.unlock(); + } + } + + public int size() { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + return q.size(); + } finally { + lock.unlock(); + } + } + + /** + * @throws UnsupportedOperationException {@inheritDoc} + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + * @throws IllegalArgumentException {@inheritDoc} + */ + public int drainTo(Collection<? super E> c) { + if (c == null) + throw new NullPointerException(); + if (c == this) + throw new IllegalArgumentException(); + final ReentrantLock lock = this.lock; + lock.lock(); + try { + int n = 0; + for (;;) { + E first = q.peek(); + if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0) + break; + c.add(q.poll()); + ++n; + } + if (n > 0) + available.signalAll(); + return n; + } finally { + lock.unlock(); + } + } + + /** + * @throws UnsupportedOperationException {@inheritDoc} + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + * @throws IllegalArgumentException {@inheritDoc} + */ + public int drainTo(Collection<? super E> c, int maxElements) { + if (c == null) + throw new NullPointerException(); + if (c == this) + throw new IllegalArgumentException(); + if (maxElements <= 0) + return 0; + final ReentrantLock lock = this.lock; + lock.lock(); + try { + int n = 0; + while (n < maxElements) { + E first = q.peek(); + if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0) + break; + c.add(q.poll()); + ++n; + } + if (n > 0) + available.signalAll(); + return n; + } finally { + lock.unlock(); + } + } + + /** + * Atomically removes all of the elements from this delay queue. + * The queue will be empty after this call returns. + * Elements with an unexpired delay are not waited for; they are + * simply discarded from the queue. + */ + public void clear() { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + q.clear(); + } finally { + lock.unlock(); + } + } + + /** + * Always returns <tt>Integer.MAX_VALUE</tt> because + * a <tt>DelayQueue</tt> is not capacity constrained. + * + * @return <tt>Integer.MAX_VALUE</tt> + */ + public int remainingCapacity() { + return Integer.MAX_VALUE; + } + + /** + * Returns an array containing all of the elements in this queue. + * The returned array elements are in no particular order. + * + * <p>The returned array will be "safe" in that no references to it are + * maintained by this queue. (In other words, this method must allocate + * a new array). The caller is thus free to modify the returned array. + * + * <p>This method acts as bridge between array-based and collection-based + * APIs. + * + * @return an array containing all of the elements in this queue + */ + public Object[] toArray() { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + return q.toArray(); + } finally { + lock.unlock(); + } + } + + /** + * Returns an array containing all of the elements in this queue; the + * runtime type of the returned array is that of the specified array. + * The returned array elements are in no particular order. + * If the queue fits in the specified array, it is returned therein. + * Otherwise, a new array is allocated with the runtime type of the + * specified array and the size of this queue. + * + * <p>If this queue fits in the specified array with room to spare + * (i.e., the array has more elements than this queue), the element in + * the array immediately following the end of the queue is set to + * <tt>null</tt>. + * + * <p>Like the {@link #toArray()} method, this method acts as bridge between + * array-based and collection-based APIs. Further, this method allows + * precise control over the runtime type of the output array, and may, + * under certain circumstances, be used to save allocation costs. + * + * <p>The following code can be used to dump a delay queue into a newly + * allocated array of <tt>Delayed</tt>: + * + * <pre> + * Delayed[] a = q.toArray(new Delayed[0]);</pre> + * + * Note that <tt>toArray(new Object[0])</tt> is identical in function to + * <tt>toArray()</tt>. + * + * @param a the array into which the elements of the queue are to + * be stored, if it is big enough; otherwise, a new array of the + * same runtime type is allocated for this purpose + * @return an array containing all of the elements in this queue + * @throws ArrayStoreException if the runtime type of the specified array + * is not a supertype of the runtime type of every element in + * this queue + * @throws NullPointerException if the specified array is null + */ + public <T> T[] toArray(T[] a) { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + return q.toArray(a); + } finally { + lock.unlock(); + } + } + + /** + * Removes a single instance of the specified element from this + * queue, if it is present, whether or not it has expired. + */ + public boolean remove(Object o) { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + return q.remove(o); + } finally { + lock.unlock(); + } + } + + /** + * Returns an iterator over all the elements (both expired and + * unexpired) in this queue. The iterator does not return the + * elements in any particular order. The returned + * <tt>Iterator</tt> is a "weakly consistent" iterator that will + * never throw {@link ConcurrentModificationException}, and + * guarantees to traverse elements as they existed upon + * construction of the iterator, and may (but is not guaranteed + * to) reflect any modifications subsequent to construction. + * + * @return an iterator over the elements in this queue + */ + public Iterator<E> iterator() { + return new Itr(toArray()); + } + + /** + * Snapshot iterator that works off copy of underlying q array. + */ + private class Itr implements Iterator<E> { + final Object[] array; // Array of all elements + int cursor; // index of next element to return; + int lastRet; // index of last element, or -1 if no such + + Itr(Object[] array) { + lastRet = -1; + this.array = array; + } + + public boolean hasNext() { + return cursor < array.length; + } + + public E next() { + if (cursor >= array.length) + throw new NoSuchElementException(); + lastRet = cursor; + return (E)array[cursor++]; + } + + public void remove() { + if (lastRet < 0) + throw new IllegalStateException(); + Object x = array[lastRet]; + lastRet = -1; + // Traverse underlying queue to find == element, + // not just a .equals element. + lock.lock(); + try { + for (Iterator it = q.iterator(); it.hasNext(); ) { + if (it.next() == x) { + it.remove(); + return; + } + } + } finally { + lock.unlock(); + } + } + } + +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/Delayed.java b/libjava/classpath/external/jsr166/java/util/concurrent/Delayed.java new file mode 100644 index 000000000..b1ff4eee5 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/Delayed.java @@ -0,0 +1,33 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; + +import java.util.*; + +/** + * A mix-in style interface for marking objects that should be + * acted upon after a given delay. + * + * <p>An implementation of this interface must define a + * <tt>compareTo</tt> method that provides an ordering consistent with + * its <tt>getDelay</tt> method. + * + * @since 1.5 + * @author Doug Lea + */ +public interface Delayed extends Comparable<Delayed> { + + /** + * Returns the remaining delay associated with this object, in the + * given time unit. + * + * @param unit the time unit + * @return the remaining delay; zero or negative values indicate + * that the delay has already elapsed + */ + long getDelay(TimeUnit unit); +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/Exchanger.java b/libjava/classpath/external/jsr166/java/util/concurrent/Exchanger.java new file mode 100644 index 000000000..fb917f432 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/Exchanger.java @@ -0,0 +1,656 @@ +/* + * Written by Doug Lea, Bill Scherer, and Michael Scott with + * assistance from members of JCP JSR-166 Expert Group and released to + * the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; +import java.util.concurrent.atomic.*; +import java.util.concurrent.locks.LockSupport; + +/** + * A synchronization point at which threads can pair and swap elements + * within pairs. Each thread presents some object on entry to the + * {@link #exchange exchange} method, matches with a partner thread, + * and receives its partner's object on return. An Exchanger may be + * viewed as a bidirectional form of a {@link SynchronousQueue}. + * Exchangers may be useful in applications such as genetic algorithms + * and pipeline designs. + * + * <p><b>Sample Usage:</b> + * Here are the highlights of a class that uses an {@code Exchanger} + * to swap buffers between threads so that the thread filling the + * buffer gets a freshly emptied one when it needs it, handing off the + * filled one to the thread emptying the buffer. + * <pre>{@code + * class FillAndEmpty { + * Exchanger<DataBuffer> exchanger = new Exchanger<DataBuffer>(); + * DataBuffer initialEmptyBuffer = ... a made-up type + * DataBuffer initialFullBuffer = ... + * + * class FillingLoop implements Runnable { + * public void run() { + * DataBuffer currentBuffer = initialEmptyBuffer; + * try { + * while (currentBuffer != null) { + * addToBuffer(currentBuffer); + * if (currentBuffer.isFull()) + * currentBuffer = exchanger.exchange(currentBuffer); + * } + * } catch (InterruptedException ex) { ... handle ... } + * } + * } + * + * class EmptyingLoop implements Runnable { + * public void run() { + * DataBuffer currentBuffer = initialFullBuffer; + * try { + * while (currentBuffer != null) { + * takeFromBuffer(currentBuffer); + * if (currentBuffer.isEmpty()) + * currentBuffer = exchanger.exchange(currentBuffer); + * } + * } catch (InterruptedException ex) { ... handle ...} + * } + * } + * + * void start() { + * new Thread(new FillingLoop()).start(); + * new Thread(new EmptyingLoop()).start(); + * } + * } + * }</pre> + * + * <p>Memory consistency effects: For each pair of threads that + * successfully exchange objects via an {@code Exchanger}, actions + * prior to the {@code exchange()} in each thread + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a> + * those subsequent to a return from the corresponding {@code exchange()} + * in the other thread. + * + * @since 1.5 + * @author Doug Lea and Bill Scherer and Michael Scott + * @param <V> The type of objects that may be exchanged + */ +public class Exchanger<V> { + /* + * Algorithm Description: + * + * The basic idea is to maintain a "slot", which is a reference to + * a Node containing both an Item to offer and a "hole" waiting to + * get filled in. If an incoming "occupying" thread sees that the + * slot is null, it CAS'es (compareAndSets) a Node there and waits + * for another to invoke exchange. That second "fulfilling" thread + * sees that the slot is non-null, and so CASes it back to null, + * also exchanging items by CASing the hole, plus waking up the + * occupying thread if it is blocked. In each case CAS'es may + * fail because a slot at first appears non-null but is null upon + * CAS, or vice-versa. So threads may need to retry these + * actions. + * + * This simple approach works great when there are only a few + * threads using an Exchanger, but performance rapidly + * deteriorates due to CAS contention on the single slot when + * there are lots of threads using an exchanger. So instead we use + * an "arena"; basically a kind of hash table with a dynamically + * varying number of slots, any one of which can be used by + * threads performing an exchange. Incoming threads pick slots + * based on a hash of their Thread ids. If an incoming thread + * fails to CAS in its chosen slot, it picks an alternative slot + * instead. And similarly from there. If a thread successfully + * CASes into a slot but no other thread arrives, it tries + * another, heading toward the zero slot, which always exists even + * if the table shrinks. The particular mechanics controlling this + * are as follows: + * + * Waiting: Slot zero is special in that it is the only slot that + * exists when there is no contention. A thread occupying slot + * zero will block if no thread fulfills it after a short spin. + * In other cases, occupying threads eventually give up and try + * another slot. Waiting threads spin for a while (a period that + * should be a little less than a typical context-switch time) + * before either blocking (if slot zero) or giving up (if other + * slots) and restarting. There is no reason for threads to block + * unless there are unlikely to be any other threads present. + * Occupants are mainly avoiding memory contention so sit there + * quietly polling for a shorter period than it would take to + * block and then unblock them. Non-slot-zero waits that elapse + * because of lack of other threads waste around one extra + * context-switch time per try, which is still on average much + * faster than alternative approaches. + * + * Sizing: Usually, using only a few slots suffices to reduce + * contention. Especially with small numbers of threads, using + * too many slots can lead to just as poor performance as using + * too few of them, and there's not much room for error. The + * variable "max" maintains the number of slots actually in + * use. It is increased when a thread sees too many CAS + * failures. (This is analogous to resizing a regular hash table + * based on a target load factor, except here, growth steps are + * just one-by-one rather than proportional.) Growth requires + * contention failures in each of three tried slots. Requiring + * multiple failures for expansion copes with the fact that some + * failed CASes are not due to contention but instead to simple + * races between two threads or thread pre-emptions occurring + * between reading and CASing. Also, very transient peak + * contention can be much higher than the average sustainable + * levels. The max limit is decreased on average 50% of the times + * that a non-slot-zero wait elapses without being fulfilled. + * Threads experiencing elapsed waits move closer to zero, so + * eventually find existing (or future) threads even if the table + * has been shrunk due to inactivity. The chosen mechanics and + * thresholds for growing and shrinking are intrinsically + * entangled with indexing and hashing inside the exchange code, + * and can't be nicely abstracted out. + * + * Hashing: Each thread picks its initial slot to use in accord + * with a simple hashcode. The sequence is the same on each + * encounter by any given thread, but effectively random across + * threads. Using arenas encounters the classic cost vs quality + * tradeoffs of all hash tables. Here, we use a one-step FNV-1a + * hash code based on the current thread's Thread.getId(), along + * with a cheap approximation to a mod operation to select an + * index. The downside of optimizing index selection in this way + * is that the code is hardwired to use a maximum table size of + * 32. But this value more than suffices for known platforms and + * applications. + * + * Probing: On sensed contention of a selected slot, we probe + * sequentially through the table, analogously to linear probing + * after collision in a hash table. (We move circularly, in + * reverse order, to mesh best with table growth and shrinkage + * rules.) Except that to minimize the effects of false-alarms + * and cache thrashing, we try the first selected slot twice + * before moving. + * + * Padding: Even with contention management, slots are heavily + * contended, so use cache-padding to avoid poor memory + * performance. Because of this, slots are lazily constructed + * only when used, to avoid wasting this space unnecessarily. + * While isolation of locations is not much of an issue at first + * in an application, as time goes on and garbage-collectors + * perform compaction, slots are very likely to be moved adjacent + * to each other, which can cause much thrashing of cache lines on + * MPs unless padding is employed. + * + * This is an improvement of the algorithm described in the paper + * "A Scalable Elimination-based Exchange Channel" by William + * Scherer, Doug Lea, and Michael Scott in Proceedings of SCOOL05 + * workshop. Available at: http://hdl.handle.net/1802/2104 + */ + + /** The number of CPUs, for sizing and spin control */ + private static final int NCPU = Runtime.getRuntime().availableProcessors(); + + /** + * The capacity of the arena. Set to a value that provides more + * than enough space to handle contention. On small machines + * most slots won't be used, but it is still not wasted because + * the extra space provides some machine-level address padding + * to minimize interference with heavily CAS'ed Slot locations. + * And on very large machines, performance eventually becomes + * bounded by memory bandwidth, not numbers of threads/CPUs. + * This constant cannot be changed without also modifying + * indexing and hashing algorithms. + */ + private static final int CAPACITY = 32; + + /** + * The value of "max" that will hold all threads without + * contention. When this value is less than CAPACITY, some + * otherwise wasted expansion can be avoided. + */ + private static final int FULL = + Math.max(0, Math.min(CAPACITY, NCPU / 2) - 1); + + /** + * The number of times to spin (doing nothing except polling a + * memory location) before blocking or giving up while waiting to + * be fulfilled. Should be zero on uniprocessors. On + * multiprocessors, this value should be large enough so that two + * threads exchanging items as fast as possible block only when + * one of them is stalled (due to GC or preemption), but not much + * longer, to avoid wasting CPU resources. Seen differently, this + * value is a little over half the number of cycles of an average + * context switch time on most systems. The value here is + * approximately the average of those across a range of tested + * systems. + */ + private static final int SPINS = (NCPU == 1) ? 0 : 2000; + + /** + * The number of times to spin before blocking in timed waits. + * Timed waits spin more slowly because checking the time takes + * time. The best value relies mainly on the relative rate of + * System.nanoTime vs memory accesses. The value is empirically + * derived to work well across a variety of systems. + */ + private static final int TIMED_SPINS = SPINS / 20; + + /** + * Sentinel item representing cancellation of a wait due to + * interruption, timeout, or elapsed spin-waits. This value is + * placed in holes on cancellation, and used as a return value + * from waiting methods to indicate failure to set or get hole. + */ + private static final Object CANCEL = new Object(); + + /** + * Value representing null arguments/returns from public + * methods. This disambiguates from internal requirement that + * holes start out as null to mean they are not yet set. + */ + private static final Object NULL_ITEM = new Object(); + + /** + * Nodes hold partially exchanged data. This class + * opportunistically subclasses AtomicReference to represent the + * hole. So get() returns hole, and compareAndSet CAS'es value + * into hole. This class cannot be parameterized as "V" because + * of the use of non-V CANCEL sentinels. + */ + private static final class Node extends AtomicReference<Object> { + /** The element offered by the Thread creating this node. */ + public final Object item; + + /** The Thread waiting to be signalled; null until waiting. */ + public volatile Thread waiter; + + /** + * Creates node with given item and empty hole. + * @param item the item + */ + public Node(Object item) { + this.item = item; + } + } + + /** + * A Slot is an AtomicReference with heuristic padding to lessen + * cache effects of this heavily CAS'ed location. While the + * padding adds noticeable space, all slots are created only on + * demand, and there will be more than one of them only when it + * would improve throughput more than enough to outweigh using + * extra space. + */ + private static final class Slot extends AtomicReference<Object> { + // Improve likelihood of isolation on <= 64 byte cache lines + long q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, qa, qb, qc, qd, qe; + } + + /** + * Slot array. Elements are lazily initialized when needed. + * Declared volatile to enable double-checked lazy construction. + */ + private volatile Slot[] arena = new Slot[CAPACITY]; + + /** + * The maximum slot index being used. The value sometimes + * increases when a thread experiences too many CAS contentions, + * and sometimes decreases when a spin-wait elapses. Changes + * are performed only via compareAndSet, to avoid stale values + * when a thread happens to stall right before setting. + */ + private final AtomicInteger max = new AtomicInteger(); + + /** + * Main exchange function, handling the different policy variants. + * Uses Object, not "V" as argument and return value to simplify + * handling of sentinel values. Callers from public methods decode + * and cast accordingly. + * + * @param item the (non-null) item to exchange + * @param timed true if the wait is timed + * @param nanos if timed, the maximum wait time + * @return the other thread's item, or CANCEL if interrupted or timed out + */ + private Object doExchange(Object item, boolean timed, long nanos) { + Node me = new Node(item); // Create in case occupying + int index = hashIndex(); // Index of current slot + int fails = 0; // Number of CAS failures + + for (;;) { + Object y; // Contents of current slot + Slot slot = arena[index]; + if (slot == null) // Lazily initialize slots + createSlot(index); // Continue loop to reread + else if ((y = slot.get()) != null && // Try to fulfill + slot.compareAndSet(y, null)) { + Node you = (Node)y; // Transfer item + if (you.compareAndSet(null, item)) { + LockSupport.unpark(you.waiter); + return you.item; + } // Else cancelled; continue + } + else if (y == null && // Try to occupy + slot.compareAndSet(null, me)) { + if (index == 0) // Blocking wait for slot 0 + return timed? awaitNanos(me, slot, nanos): await(me, slot); + Object v = spinWait(me, slot); // Spin wait for non-0 + if (v != CANCEL) + return v; + me = new Node(item); // Throw away cancelled node + int m = max.get(); + if (m > (index >>>= 1)) // Decrease index + max.compareAndSet(m, m - 1); // Maybe shrink table + } + else if (++fails > 1) { // Allow 2 fails on 1st slot + int m = max.get(); + if (fails > 3 && m < FULL && max.compareAndSet(m, m + 1)) + index = m + 1; // Grow on 3rd failed slot + else if (--index < 0) + index = m; // Circularly traverse + } + } + } + + /** + * Returns a hash index for the current thread. Uses a one-step + * FNV-1a hash code (http://www.isthe.com/chongo/tech/comp/fnv/) + * based on the current thread's Thread.getId(). These hash codes + * have more uniform distribution properties with respect to small + * moduli (here 1-31) than do other simple hashing functions. + * + * <p>To return an index between 0 and max, we use a cheap + * approximation to a mod operation, that also corrects for bias + * due to non-power-of-2 remaindering (see {@link + * java.util.Random#nextInt}). Bits of the hashcode are masked + * with "nbits", the ceiling power of two of table size (looked up + * in a table packed into three ints). If too large, this is + * retried after rotating the hash by nbits bits, while forcing new + * top bit to 0, which guarantees eventual termination (although + * with a non-random-bias). This requires an average of less than + * 2 tries for all table sizes, and has a maximum 2% difference + * from perfectly uniform slot probabilities when applied to all + * possible hash codes for sizes less than 32. + * + * @return a per-thread-random index, 0 <= index < max + */ + private final int hashIndex() { + long id = Thread.currentThread().getId(); + int hash = (((int)(id ^ (id >>> 32))) ^ 0x811c9dc5) * 0x01000193; + + int m = max.get(); + int nbits = (((0xfffffc00 >> m) & 4) | // Compute ceil(log2(m+1)) + ((0x000001f8 >>> m) & 2) | // The constants hold + ((0xffff00f2 >>> m) & 1)); // a lookup table + int index; + while ((index = hash & ((1 << nbits) - 1)) > m) // May retry on + hash = (hash >>> nbits) | (hash << (33 - nbits)); // non-power-2 m + return index; + } + + /** + * Creates a new slot at given index. Called only when the slot + * appears to be null. Relies on double-check using builtin + * locks, since they rarely contend. This in turn relies on the + * arena array being declared volatile. + * + * @param index the index to add slot at + */ + private void createSlot(int index) { + // Create slot outside of lock to narrow sync region + Slot newSlot = new Slot(); + Slot[] a = arena; + synchronized (a) { + if (a[index] == null) + a[index] = newSlot; + } + } + + /** + * Tries to cancel a wait for the given node waiting in the given + * slot, if so, helping clear the node from its slot to avoid + * garbage retention. + * + * @param node the waiting node + * @param the slot it is waiting in + * @return true if successfully cancelled + */ + private static boolean tryCancel(Node node, Slot slot) { + if (!node.compareAndSet(null, CANCEL)) + return false; + if (slot.get() == node) // pre-check to minimize contention + slot.compareAndSet(node, null); + return true; + } + + // Three forms of waiting. Each just different enough not to merge + // code with others. + + /** + * Spin-waits for hole for a non-0 slot. Fails if spin elapses + * before hole filled. Does not check interrupt, relying on check + * in public exchange method to abort if interrupted on entry. + * + * @param node the waiting node + * @return on success, the hole; on failure, CANCEL + */ + private static Object spinWait(Node node, Slot slot) { + int spins = SPINS; + for (;;) { + Object v = node.get(); + if (v != null) + return v; + else if (spins > 0) + --spins; + else + tryCancel(node, slot); + } + } + + /** + * Waits for (by spinning and/or blocking) and gets the hole + * filled in by another thread. Fails if interrupted before + * hole filled. + * + * When a node/thread is about to block, it sets its waiter field + * and then rechecks state at least one more time before actually + * parking, thus covering race vs fulfiller noticing that waiter + * is non-null so should be woken. + * + * Thread interruption status is checked only surrounding calls to + * park. The caller is assumed to have checked interrupt status + * on entry. + * + * @param node the waiting node + * @return on success, the hole; on failure, CANCEL + */ + private static Object await(Node node, Slot slot) { + Thread w = Thread.currentThread(); + int spins = SPINS; + for (;;) { + Object v = node.get(); + if (v != null) + return v; + else if (spins > 0) // Spin-wait phase + --spins; + else if (node.waiter == null) // Set up to block next + node.waiter = w; + else if (w.isInterrupted()) // Abort on interrupt + tryCancel(node, slot); + else // Block + LockSupport.park(node); + } + } + + /** + * Waits for (at index 0) and gets the hole filled in by another + * thread. Fails if timed out or interrupted before hole filled. + * Same basic logic as untimed version, but a bit messier. + * + * @param node the waiting node + * @param nanos the wait time + * @return on success, the hole; on failure, CANCEL + */ + private Object awaitNanos(Node node, Slot slot, long nanos) { + int spins = TIMED_SPINS; + long lastTime = 0; + Thread w = null; + for (;;) { + Object v = node.get(); + if (v != null) + return v; + long now = System.nanoTime(); + if (w == null) + w = Thread.currentThread(); + else + nanos -= now - lastTime; + lastTime = now; + if (nanos > 0) { + if (spins > 0) + --spins; + else if (node.waiter == null) + node.waiter = w; + else if (w.isInterrupted()) + tryCancel(node, slot); + else + LockSupport.parkNanos(node, nanos); + } + else if (tryCancel(node, slot) && !w.isInterrupted()) + return scanOnTimeout(node); + } + } + + /** + * Sweeps through arena checking for any waiting threads. Called + * only upon return from timeout while waiting in slot 0. When a + * thread gives up on a timed wait, it is possible that a + * previously-entered thread is still waiting in some other + * slot. So we scan to check for any. This is almost always + * overkill, but decreases the likelihood of timeouts when there + * are other threads present to far less than that in lock-based + * exchangers in which earlier-arriving threads may still be + * waiting on entry locks. + * + * @param node the waiting node + * @return another thread's item, or CANCEL + */ + private Object scanOnTimeout(Node node) { + Object y; + for (int j = arena.length - 1; j >= 0; --j) { + Slot slot = arena[j]; + if (slot != null) { + while ((y = slot.get()) != null) { + if (slot.compareAndSet(y, null)) { + Node you = (Node)y; + if (you.compareAndSet(null, node.item)) { + LockSupport.unpark(you.waiter); + return you.item; + } + } + } + } + } + return CANCEL; + } + + /** + * Creates a new Exchanger. + */ + public Exchanger() { + } + + /** + * Waits for another thread to arrive at this exchange point (unless + * the current thread is {@linkplain Thread#interrupt interrupted}), + * and then transfers the given object to it, receiving its object + * in return. + * + * <p>If another thread is already waiting at the exchange point then + * it is resumed for thread scheduling purposes and receives the object + * passed in by the current thread. The current thread returns immediately, + * receiving the object passed to the exchange by that other thread. + * + * <p>If no other thread is already waiting at the exchange then the + * current thread is disabled for thread scheduling purposes and lies + * dormant until one of two things happens: + * <ul> + * <li>Some other thread enters the exchange; or + * <li>Some other thread {@linkplain Thread#interrupt interrupts} the current + * thread. + * </ul> + * <p>If the current thread: + * <ul> + * <li>has its interrupted status set on entry to this method; or + * <li>is {@linkplain Thread#interrupt interrupted} while waiting + * for the exchange, + * </ul> + * then {@link InterruptedException} is thrown and the current thread's + * interrupted status is cleared. + * + * @param x the object to exchange + * @return the object provided by the other thread + * @throws InterruptedException if the current thread was + * interrupted while waiting + */ + public V exchange(V x) throws InterruptedException { + if (!Thread.interrupted()) { + Object v = doExchange(x == null? NULL_ITEM : x, false, 0); + if (v == NULL_ITEM) + return null; + if (v != CANCEL) + return (V)v; + Thread.interrupted(); // Clear interrupt status on IE throw + } + throw new InterruptedException(); + } + + /** + * Waits for another thread to arrive at this exchange point (unless + * the current thread is {@linkplain Thread#interrupt interrupted} or + * the specified waiting time elapses), and then transfers the given + * object to it, receiving its object in return. + * + * <p>If another thread is already waiting at the exchange point then + * it is resumed for thread scheduling purposes and receives the object + * passed in by the current thread. The current thread returns immediately, + * receiving the object passed to the exchange by that other thread. + * + * <p>If no other thread is already waiting at the exchange then the + * current thread is disabled for thread scheduling purposes and lies + * dormant until one of three things happens: + * <ul> + * <li>Some other thread enters the exchange; or + * <li>Some other thread {@linkplain Thread#interrupt interrupts} + * the current thread; or + * <li>The specified waiting time elapses. + * </ul> + * <p>If the current thread: + * <ul> + * <li>has its interrupted status set on entry to this method; or + * <li>is {@linkplain Thread#interrupt interrupted} while waiting + * for the exchange, + * </ul> + * then {@link InterruptedException} is thrown and the current thread's + * interrupted status is cleared. + * + * <p>If the specified waiting time elapses then {@link + * TimeoutException} is thrown. If the time is less than or equal + * to zero, the method will not wait at all. + * + * @param x the object to exchange + * @param timeout the maximum time to wait + * @param unit the time unit of the <tt>timeout</tt> argument + * @return the object provided by the other thread + * @throws InterruptedException if the current thread was + * interrupted while waiting + * @throws TimeoutException if the specified waiting time elapses + * before another thread enters the exchange + */ + public V exchange(V x, long timeout, TimeUnit unit) + throws InterruptedException, TimeoutException { + if (!Thread.interrupted()) { + Object v = doExchange(x == null? NULL_ITEM : x, + true, unit.toNanos(timeout)); + if (v == NULL_ITEM) + return null; + if (v != CANCEL) + return (V)v; + if (!Thread.interrupted()) + throw new TimeoutException(); + } + throw new InterruptedException(); + } +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/ExecutionException.java b/libjava/classpath/external/jsr166/java/util/concurrent/ExecutionException.java new file mode 100644 index 000000000..bc561e58e --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/ExecutionException.java @@ -0,0 +1,65 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; + +/** + * Exception thrown when attempting to retrieve the result of a task + * that aborted by throwing an exception. This exception can be + * inspected using the {@link #getCause()} method. + * + * @see Future + * @since 1.5 + * @author Doug Lea + */ +public class ExecutionException extends Exception { + private static final long serialVersionUID = 7830266012832686185L; + + /** + * Constructs an <tt>ExecutionException</tt> with no detail message. + * The cause is not initialized, and may subsequently be + * initialized by a call to {@link #initCause(Throwable) initCause}. + */ + protected ExecutionException() { } + + /** + * Constructs an <tt>ExecutionException</tt> with the specified detail + * message. The cause is not initialized, and may subsequently be + * initialized by a call to {@link #initCause(Throwable) initCause}. + * + * @param message the detail message + */ + protected ExecutionException(String message) { + super(message); + } + + /** + * Constructs an <tt>ExecutionException</tt> with the specified detail + * message and cause. + * + * @param message the detail message + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method) + */ + public ExecutionException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructs an <tt>ExecutionException</tt> with the specified cause. + * The detail message is set to: + * <pre> + * (cause == null ? null : cause.toString())</pre> + * (which typically contains the class and detail message of + * <tt>cause</tt>). + * + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method) + */ + public ExecutionException(Throwable cause) { + super(cause); + } +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/Executor.java b/libjava/classpath/external/jsr166/java/util/concurrent/Executor.java new file mode 100644 index 000000000..a61e92152 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/Executor.java @@ -0,0 +1,112 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; + +/** + * An object that executes submitted {@link Runnable} tasks. This + * interface provides a way of decoupling task submission from the + * mechanics of how each task will be run, including details of thread + * use, scheduling, etc. An <tt>Executor</tt> is normally used + * instead of explicitly creating threads. For example, rather than + * invoking <tt>new Thread(new(RunnableTask())).start()</tt> for each + * of a set of tasks, you might use: + * + * <pre> + * Executor executor = <em>anExecutor</em>; + * executor.execute(new RunnableTask1()); + * executor.execute(new RunnableTask2()); + * ... + * </pre> + * + * However, the <tt>Executor</tt> interface does not strictly + * require that execution be asynchronous. In the simplest case, an + * executor can run the submitted task immediately in the caller's + * thread: + * + * <pre> + * class DirectExecutor implements Executor { + * public void execute(Runnable r) { + * r.run(); + * } + * }</pre> + * + * More typically, tasks are executed in some thread other + * than the caller's thread. The executor below spawns a new thread + * for each task. + * + * <pre> + * class ThreadPerTaskExecutor implements Executor { + * public void execute(Runnable r) { + * new Thread(r).start(); + * } + * }</pre> + * + * Many <tt>Executor</tt> implementations impose some sort of + * limitation on how and when tasks are scheduled. The executor below + * serializes the submission of tasks to a second executor, + * illustrating a composite executor. + * + * <pre> + * class SerialExecutor implements Executor { + * final Queue<Runnable> tasks = new ArrayDeque<Runnable>(); + * final Executor executor; + * Runnable active; + * + * SerialExecutor(Executor executor) { + * this.executor = executor; + * } + * + * public synchronized void execute(final Runnable r) { + * tasks.offer(new Runnable() { + * public void run() { + * try { + * r.run(); + * } finally { + * scheduleNext(); + * } + * } + * }); + * if (active == null) { + * scheduleNext(); + * } + * } + * + * protected synchronized void scheduleNext() { + * if ((active = tasks.poll()) != null) { + * executor.execute(active); + * } + * } + * }</pre> + * + * The <tt>Executor</tt> implementations provided in this package + * implement {@link ExecutorService}, which is a more extensive + * interface. The {@link ThreadPoolExecutor} class provides an + * extensible thread pool implementation. The {@link Executors} class + * provides convenient factory methods for these Executors. + * + * <p>Memory consistency effects: Actions in a thread prior to + * submitting a {@code Runnable} object to an {@code Executor} + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a> + * its execution begins, perhaps in another thread. + * + * @since 1.5 + * @author Doug Lea + */ +public interface Executor { + + /** + * Executes the given command at some time in the future. The command + * may execute in a new thread, in a pooled thread, or in the calling + * thread, at the discretion of the <tt>Executor</tt> implementation. + * + * @param command the runnable task + * @throws RejectedExecutionException if this task cannot be + * accepted for execution. + * @throws NullPointerException if command is null + */ + void execute(Runnable command); +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/ExecutorCompletionService.java b/libjava/classpath/external/jsr166/java/util/concurrent/ExecutorCompletionService.java new file mode 100644 index 000000000..9b7a0e027 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/ExecutorCompletionService.java @@ -0,0 +1,174 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; + +/** + * A {@link CompletionService} that uses a supplied {@link Executor} + * to execute tasks. This class arranges that submitted tasks are, + * upon completion, placed on a queue accessible using <tt>take</tt>. + * The class is lightweight enough to be suitable for transient use + * when processing groups of tasks. + * + * <p> + * + * <b>Usage Examples.</b> + * + * Suppose you have a set of solvers for a certain problem, each + * returning a value of some type <tt>Result</tt>, and would like to + * run them concurrently, processing the results of each of them that + * return a non-null value, in some method <tt>use(Result r)</tt>. You + * could write this as: + * + * <pre> + * void solve(Executor e, + * Collection<Callable<Result>> solvers) + * throws InterruptedException, ExecutionException { + * CompletionService<Result> ecs + * = new ExecutorCompletionService<Result>(e); + * for (Callable<Result> s : solvers) + * ecs.submit(s); + * int n = solvers.size(); + * for (int i = 0; i < n; ++i) { + * Result r = ecs.take().get(); + * if (r != null) + * use(r); + * } + * } + * </pre> + * + * Suppose instead that you would like to use the first non-null result + * of the set of tasks, ignoring any that encounter exceptions, + * and cancelling all other tasks when the first one is ready: + * + * <pre> + * void solve(Executor e, + * Collection<Callable<Result>> solvers) + * throws InterruptedException { + * CompletionService<Result> ecs + * = new ExecutorCompletionService<Result>(e); + * int n = solvers.size(); + * List<Future<Result>> futures + * = new ArrayList<Future<Result>>(n); + * Result result = null; + * try { + * for (Callable<Result> s : solvers) + * futures.add(ecs.submit(s)); + * for (int i = 0; i < n; ++i) { + * try { + * Result r = ecs.take().get(); + * if (r != null) { + * result = r; + * break; + * } + * } catch (ExecutionException ignore) {} + * } + * } + * finally { + * for (Future<Result> f : futures) + * f.cancel(true); + * } + * + * if (result != null) + * use(result); + * } + * </pre> + */ +public class ExecutorCompletionService<V> implements CompletionService<V> { + private final Executor executor; + private final AbstractExecutorService aes; + private final BlockingQueue<Future<V>> completionQueue; + + /** + * FutureTask extension to enqueue upon completion + */ + private class QueueingFuture extends FutureTask<Void> { + QueueingFuture(RunnableFuture<V> task) { + super(task, null); + this.task = task; + } + protected void done() { completionQueue.add(task); } + private final Future<V> task; + } + + private RunnableFuture<V> newTaskFor(Callable<V> task) { + if (aes == null) + return new FutureTask<V>(task); + else + return aes.newTaskFor(task); + } + + private RunnableFuture<V> newTaskFor(Runnable task, V result) { + if (aes == null) + return new FutureTask<V>(task, result); + else + return aes.newTaskFor(task, result); + } + + /** + * Creates an ExecutorCompletionService using the supplied + * executor for base task execution and a + * {@link LinkedBlockingQueue} as a completion queue. + * + * @param executor the executor to use + * @throws NullPointerException if executor is <tt>null</tt> + */ + public ExecutorCompletionService(Executor executor) { + if (executor == null) + throw new NullPointerException(); + this.executor = executor; + this.aes = (executor instanceof AbstractExecutorService) ? + (AbstractExecutorService) executor : null; + this.completionQueue = new LinkedBlockingQueue<Future<V>>(); + } + + /** + * Creates an ExecutorCompletionService using the supplied + * executor for base task execution and the supplied queue as its + * completion queue. + * + * @param executor the executor to use + * @param completionQueue the queue to use as the completion queue + * normally one dedicated for use by this service + * @throws NullPointerException if executor or completionQueue are <tt>null</tt> + */ + public ExecutorCompletionService(Executor executor, + BlockingQueue<Future<V>> completionQueue) { + if (executor == null || completionQueue == null) + throw new NullPointerException(); + this.executor = executor; + this.aes = (executor instanceof AbstractExecutorService) ? + (AbstractExecutorService) executor : null; + this.completionQueue = completionQueue; + } + + public Future<V> submit(Callable<V> task) { + if (task == null) throw new NullPointerException(); + RunnableFuture<V> f = newTaskFor(task); + executor.execute(new QueueingFuture(f)); + return f; + } + + public Future<V> submit(Runnable task, V result) { + if (task == null) throw new NullPointerException(); + RunnableFuture<V> f = newTaskFor(task, result); + executor.execute(new QueueingFuture(f)); + return f; + } + + public Future<V> take() throws InterruptedException { + return completionQueue.take(); + } + + public Future<V> poll() { + return completionQueue.poll(); + } + + public Future<V> poll(long timeout, TimeUnit unit) throws InterruptedException { + return completionQueue.poll(timeout, unit); + } + +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/ExecutorService.java b/libjava/classpath/external/jsr166/java/util/concurrent/ExecutorService.java new file mode 100644 index 000000000..777319265 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/ExecutorService.java @@ -0,0 +1,306 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; +import java.util.List; +import java.util.Collection; +import java.security.PrivilegedAction; +import java.security.PrivilegedExceptionAction; + +/** + * An {@link Executor} that provides methods to manage termination and + * methods that can produce a {@link Future} for tracking progress of + * one or more asynchronous tasks. + * + * <p> + * An <tt>ExecutorService</tt> can be shut down, which will cause it + * to stop accepting new tasks. After being shut down, the executor + * will eventually terminate, at which point no tasks are actively + * executing, no tasks are awaiting execution, and no new tasks can be + * submitted. An unused <tt>ExecutorService</tt> should be shut down + * to allow reclamation of its resources. + * + * <p> Method <tt>submit</tt> extends base method {@link + * Executor#execute} by creating and returning a {@link Future} that + * can be used to cancel execution and/or wait for completion. + * Methods <tt>invokeAny</tt> and <tt>invokeAll</tt> perform the most + * commonly useful forms of bulk execution, executing a collection of + * tasks and then waiting for at least one, or all, to + * complete. (Class {@link ExecutorCompletionService} can be used to + * write customized variants of these methods.) + * + * <p>The {@link Executors} class provides factory methods for the + * executor services provided in this package. + * + * <h3>Usage Example</h3> + * + * Here is a sketch of a network service in which threads in a thread + * pool service incoming requests. It uses the preconfigured {@link + * Executors#newFixedThreadPool} factory method: + * + * <pre> + * class NetworkService { + * private final ServerSocket serverSocket; + * private final ExecutorService pool; + * + * public NetworkService(int port, int poolSize) + * throws IOException { + * serverSocket = new ServerSocket(port); + * pool = Executors.newFixedThreadPool(poolSize); + * } + * + * public void serve() { + * try { + * for (;;) { + * pool.execute(new Handler(serverSocket.accept())); + * } + * } catch (IOException ex) { + * pool.shutdown(); + * } + * } + * } + * + * class Handler implements Runnable { + * private final Socket socket; + * Handler(Socket socket) { this.socket = socket; } + * public void run() { + * // read and service request + * } + * } + * </pre> + * + * <p>Memory consistency effects: Actions in a thread prior to the + * submission of a {@code Runnable} or {@code Callable} task to an + * {@code ExecutorService} + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a> + * any actions taken by that task, which in turn <i>happen-before</i> the + * result is retrieved via {@code Future.get()}. + * + * @since 1.5 + * @author Doug Lea + */ +public interface ExecutorService extends Executor { + + /** + * Initiates an orderly shutdown in which previously submitted + * tasks are executed, but no new tasks will be accepted. + * Invocation has no additional effect if already shut down. + * + * @throws SecurityException if a security manager exists and + * shutting down this ExecutorService may manipulate + * threads that the caller is not permitted to modify + * because it does not hold {@link + * java.lang.RuntimePermission}<tt>("modifyThread")</tt>, + * or the security manager's <tt>checkAccess</tt> method + * denies access. + */ + void shutdown(); + + /** + * Attempts to stop all actively executing tasks, halts the + * processing of waiting tasks, and returns a list of the tasks that were + * awaiting execution. + * + * <p>There are no guarantees beyond best-effort attempts to stop + * processing actively executing tasks. For example, typical + * implementations will cancel via {@link Thread#interrupt}, so any + * task that fails to respond to interrupts may never terminate. + * + * @return list of tasks that never commenced execution + * @throws SecurityException if a security manager exists and + * shutting down this ExecutorService may manipulate + * threads that the caller is not permitted to modify + * because it does not hold {@link + * java.lang.RuntimePermission}<tt>("modifyThread")</tt>, + * or the security manager's <tt>checkAccess</tt> method + * denies access. + */ + List<Runnable> shutdownNow(); + + /** + * Returns <tt>true</tt> if this executor has been shut down. + * + * @return <tt>true</tt> if this executor has been shut down + */ + boolean isShutdown(); + + /** + * Returns <tt>true</tt> if all tasks have completed following shut down. + * Note that <tt>isTerminated</tt> is never <tt>true</tt> unless + * either <tt>shutdown</tt> or <tt>shutdownNow</tt> was called first. + * + * @return <tt>true</tt> if all tasks have completed following shut down + */ + boolean isTerminated(); + + /** + * Blocks until all tasks have completed execution after a shutdown + * request, or the timeout occurs, or the current thread is + * interrupted, whichever happens first. + * + * @param timeout the maximum time to wait + * @param unit the time unit of the timeout argument + * @return <tt>true</tt> if this executor terminated and + * <tt>false</tt> if the timeout elapsed before termination + * @throws InterruptedException if interrupted while waiting + */ + boolean awaitTermination(long timeout, TimeUnit unit) + throws InterruptedException; + + + /** + * Submits a value-returning task for execution and returns a + * Future representing the pending results of the task. The + * Future's <tt>get</tt> method will return the task's result upon + * successful completion. + * + * <p> + * If you would like to immediately block waiting + * for a task, you can use constructions of the form + * <tt>result = exec.submit(aCallable).get();</tt> + * + * <p> Note: The {@link Executors} class includes a set of methods + * that can convert some other common closure-like objects, + * for example, {@link java.security.PrivilegedAction} to + * {@link Callable} form so they can be submitted. + * + * @param task the task to submit + * @return a Future representing pending completion of the task + * @throws RejectedExecutionException if the task cannot be + * scheduled for execution + * @throws NullPointerException if the task is null + */ + <T> Future<T> submit(Callable<T> task); + + /** + * Submits a Runnable task for execution and returns a Future + * representing that task. The Future's <tt>get</tt> method will + * return the given result upon successful completion. + * + * @param task the task to submit + * @param result the result to return + * @return a Future representing pending completion of the task + * @throws RejectedExecutionException if the task cannot be + * scheduled for execution + * @throws NullPointerException if the task is null + */ + <T> Future<T> submit(Runnable task, T result); + + /** + * Submits a Runnable task for execution and returns a Future + * representing that task. The Future's <tt>get</tt> method will + * return <tt>null</tt> upon <em>successful</em> completion. + * + * @param task the task to submit + * @return a Future representing pending completion of the task + * @throws RejectedExecutionException if the task cannot be + * scheduled for execution + * @throws NullPointerException if the task is null + */ + Future<?> submit(Runnable task); + + /** + * Executes the given tasks, returning a list of Futures holding + * their status and results when all complete. + * {@link Future#isDone} is <tt>true</tt> for each + * element of the returned list. + * Note that a <em>completed</em> task could have + * terminated either normally or by throwing an exception. + * The results of this method are undefined if the given + * collection is modified while this operation is in progress. + * + * @param tasks the collection of tasks + * @return A list of Futures representing the tasks, in the same + * sequential order as produced by the iterator for the + * given task list, each of which has completed. + * @throws InterruptedException if interrupted while waiting, in + * which case unfinished tasks are cancelled. + * @throws NullPointerException if tasks or any of its elements are <tt>null</tt> + * @throws RejectedExecutionException if any task cannot be + * scheduled for execution + */ + + <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) + throws InterruptedException; + + /** + * Executes the given tasks, returning a list of Futures holding + * their status and results + * when all complete or the timeout expires, whichever happens first. + * {@link Future#isDone} is <tt>true</tt> for each + * element of the returned list. + * Upon return, tasks that have not completed are cancelled. + * Note that a <em>completed</em> task could have + * terminated either normally or by throwing an exception. + * The results of this method are undefined if the given + * collection is modified while this operation is in progress. + * + * @param tasks the collection of tasks + * @param timeout the maximum time to wait + * @param unit the time unit of the timeout argument + * @return a list of Futures representing the tasks, in the same + * sequential order as produced by the iterator for the + * given task list. If the operation did not time out, + * each task will have completed. If it did time out, some + * of these tasks will not have completed. + * @throws InterruptedException if interrupted while waiting, in + * which case unfinished tasks are cancelled + * @throws NullPointerException if tasks, any of its elements, or + * unit are <tt>null</tt> + * @throws RejectedExecutionException if any task cannot be scheduled + * for execution + */ + <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, + long timeout, TimeUnit unit) + throws InterruptedException; + + /** + * Executes the given tasks, returning the result + * of one that has completed successfully (i.e., without throwing + * an exception), if any do. Upon normal or exceptional return, + * tasks that have not completed are cancelled. + * The results of this method are undefined if the given + * collection is modified while this operation is in progress. + * + * @param tasks the collection of tasks + * @return the result returned by one of the tasks + * @throws InterruptedException if interrupted while waiting + * @throws NullPointerException if tasks or any of its elements + * are <tt>null</tt> + * @throws IllegalArgumentException if tasks is empty + * @throws ExecutionException if no task successfully completes + * @throws RejectedExecutionException if tasks cannot be scheduled + * for execution + */ + <T> T invokeAny(Collection<? extends Callable<T>> tasks) + throws InterruptedException, ExecutionException; + + /** + * Executes the given tasks, returning the result + * of one that has completed successfully (i.e., without throwing + * an exception), if any do before the given timeout elapses. + * Upon normal or exceptional return, tasks that have not + * completed are cancelled. + * The results of this method are undefined if the given + * collection is modified while this operation is in progress. + * + * @param tasks the collection of tasks + * @param timeout the maximum time to wait + * @param unit the time unit of the timeout argument + * @return the result returned by one of the tasks. + * @throws InterruptedException if interrupted while waiting + * @throws NullPointerException if tasks, any of its elements, or + * unit are <tt>null</tt> + * @throws TimeoutException if the given timeout elapses before + * any task successfully completes + * @throws ExecutionException if no task successfully completes + * @throws RejectedExecutionException if tasks cannot be scheduled + * for execution + */ + <T> T invokeAny(Collection<? extends Callable<T>> tasks, + long timeout, TimeUnit unit) + throws InterruptedException, ExecutionException, TimeoutException; +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/Executors.java b/libjava/classpath/external/jsr166/java/util/concurrent/Executors.java new file mode 100644 index 000000000..18e6b33cc --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/Executors.java @@ -0,0 +1,666 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; +import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; +import java.security.AccessControlContext; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.security.PrivilegedExceptionAction; +import java.security.AccessControlException; + +/** + * Factory and utility methods for {@link Executor}, {@link + * ExecutorService}, {@link ScheduledExecutorService}, {@link + * ThreadFactory}, and {@link Callable} classes defined in this + * package. This class supports the following kinds of methods: + * + * <ul> + * <li> Methods that create and return an {@link ExecutorService} + * set up with commonly useful configuration settings. + * <li> Methods that create and return a {@link ScheduledExecutorService} + * set up with commonly useful configuration settings. + * <li> Methods that create and return a "wrapped" ExecutorService, that + * disables reconfiguration by making implementation-specific methods + * inaccessible. + * <li> Methods that create and return a {@link ThreadFactory} + * that sets newly created threads to a known state. + * <li> Methods that create and return a {@link Callable} + * out of other closure-like forms, so they can be used + * in execution methods requiring <tt>Callable</tt>. + * </ul> + * + * @since 1.5 + * @author Doug Lea + */ +public class Executors { + + /** + * Creates a thread pool that reuses a fixed number of threads + * operating off a shared unbounded queue. At any point, at most + * <tt>nThreads</tt> threads will be active processing tasks. + * If additional tasks are submitted when all threads are active, + * they will wait in the queue until a thread is available. + * If any thread terminates due to a failure during execution + * prior to shutdown, a new one will take its place if needed to + * execute subsequent tasks. The threads in the pool will exist + * until it is explicitly {@link ExecutorService#shutdown shutdown}. + * + * @param nThreads the number of threads in the pool + * @return the newly created thread pool + * @throws IllegalArgumentException if <tt>nThreads <= 0</tt> + */ + public static ExecutorService newFixedThreadPool(int nThreads) { + return new ThreadPoolExecutor(nThreads, nThreads, + 0L, TimeUnit.MILLISECONDS, + new LinkedBlockingQueue<Runnable>()); + } + + /** + * Creates a thread pool that reuses a fixed number of threads + * operating off a shared unbounded queue, using the provided + * ThreadFactory to create new threads when needed. At any point, + * at most <tt>nThreads</tt> threads will be active processing + * tasks. If additional tasks are submitted when all threads are + * active, they will wait in the queue until a thread is + * available. If any thread terminates due to a failure during + * execution prior to shutdown, a new one will take its place if + * needed to execute subsequent tasks. The threads in the pool will + * exist until it is explicitly {@link ExecutorService#shutdown + * shutdown}. + * + * @param nThreads the number of threads in the pool + * @param threadFactory the factory to use when creating new threads + * @return the newly created thread pool + * @throws NullPointerException if threadFactory is null + * @throws IllegalArgumentException if <tt>nThreads <= 0</tt> + */ + public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) { + return new ThreadPoolExecutor(nThreads, nThreads, + 0L, TimeUnit.MILLISECONDS, + new LinkedBlockingQueue<Runnable>(), + threadFactory); + } + + /** + * Creates an Executor that uses a single worker thread operating + * off an unbounded queue. (Note however that if this single + * thread terminates due to a failure during execution prior to + * shutdown, a new one will take its place if needed to execute + * subsequent tasks.) Tasks are guaranteed to execute + * sequentially, and no more than one task will be active at any + * given time. Unlike the otherwise equivalent + * <tt>newFixedThreadPool(1)</tt> the returned executor is + * guaranteed not to be reconfigurable to use additional threads. + * + * @return the newly created single-threaded Executor + */ + public static ExecutorService newSingleThreadExecutor() { + return new FinalizableDelegatedExecutorService + (new ThreadPoolExecutor(1, 1, + 0L, TimeUnit.MILLISECONDS, + new LinkedBlockingQueue<Runnable>())); + } + + /** + * Creates an Executor that uses a single worker thread operating + * off an unbounded queue, and uses the provided ThreadFactory to + * create a new thread when needed. Unlike the otherwise + * equivalent <tt>newFixedThreadPool(1, threadFactory)</tt> the + * returned executor is guaranteed not to be reconfigurable to use + * additional threads. + * + * @param threadFactory the factory to use when creating new + * threads + * + * @return the newly created single-threaded Executor + * @throws NullPointerException if threadFactory is null + */ + public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) { + return new FinalizableDelegatedExecutorService + (new ThreadPoolExecutor(1, 1, + 0L, TimeUnit.MILLISECONDS, + new LinkedBlockingQueue<Runnable>(), + threadFactory)); + } + + /** + * Creates a thread pool that creates new threads as needed, but + * will reuse previously constructed threads when they are + * available. These pools will typically improve the performance + * of programs that execute many short-lived asynchronous tasks. + * Calls to <tt>execute</tt> will reuse previously constructed + * threads if available. If no existing thread is available, a new + * thread will be created and added to the pool. Threads that have + * not been used for sixty seconds are terminated and removed from + * the cache. Thus, a pool that remains idle for long enough will + * not consume any resources. Note that pools with similar + * properties but different details (for example, timeout parameters) + * may be created using {@link ThreadPoolExecutor} constructors. + * + * @return the newly created thread pool + */ + public static ExecutorService newCachedThreadPool() { + return new ThreadPoolExecutor(0, Integer.MAX_VALUE, + 60L, TimeUnit.SECONDS, + new SynchronousQueue<Runnable>()); + } + + /** + * Creates a thread pool that creates new threads as needed, but + * will reuse previously constructed threads when they are + * available, and uses the provided + * ThreadFactory to create new threads when needed. + * @param threadFactory the factory to use when creating new threads + * @return the newly created thread pool + * @throws NullPointerException if threadFactory is null + */ + public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) { + return new ThreadPoolExecutor(0, Integer.MAX_VALUE, + 60L, TimeUnit.SECONDS, + new SynchronousQueue<Runnable>(), + threadFactory); + } + + /** + * Creates a single-threaded executor that can schedule commands + * to run after a given delay, or to execute periodically. + * (Note however that if this single + * thread terminates due to a failure during execution prior to + * shutdown, a new one will take its place if needed to execute + * subsequent tasks.) Tasks are guaranteed to execute + * sequentially, and no more than one task will be active at any + * given time. Unlike the otherwise equivalent + * <tt>newScheduledThreadPool(1)</tt> the returned executor is + * guaranteed not to be reconfigurable to use additional threads. + * @return the newly created scheduled executor + */ + public static ScheduledExecutorService newSingleThreadScheduledExecutor() { + return new DelegatedScheduledExecutorService + (new ScheduledThreadPoolExecutor(1)); + } + + /** + * Creates a single-threaded executor that can schedule commands + * to run after a given delay, or to execute periodically. (Note + * however that if this single thread terminates due to a failure + * during execution prior to shutdown, a new one will take its + * place if needed to execute subsequent tasks.) Tasks are + * guaranteed to execute sequentially, and no more than one task + * will be active at any given time. Unlike the otherwise + * equivalent <tt>newScheduledThreadPool(1, threadFactory)</tt> + * the returned executor is guaranteed not to be reconfigurable to + * use additional threads. + * @param threadFactory the factory to use when creating new + * threads + * @return a newly created scheduled executor + * @throws NullPointerException if threadFactory is null + */ + public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory) { + return new DelegatedScheduledExecutorService + (new ScheduledThreadPoolExecutor(1, threadFactory)); + } + + /** + * Creates a thread pool that can schedule commands to run after a + * given delay, or to execute periodically. + * @param corePoolSize the number of threads to keep in the pool, + * even if they are idle. + * @return a newly created scheduled thread pool + * @throws IllegalArgumentException if <tt>corePoolSize < 0</tt> + */ + public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) { + return new ScheduledThreadPoolExecutor(corePoolSize); + } + + /** + * Creates a thread pool that can schedule commands to run after a + * given delay, or to execute periodically. + * @param corePoolSize the number of threads to keep in the pool, + * even if they are idle. + * @param threadFactory the factory to use when the executor + * creates a new thread. + * @return a newly created scheduled thread pool + * @throws IllegalArgumentException if <tt>corePoolSize < 0</tt> + * @throws NullPointerException if threadFactory is null + */ + public static ScheduledExecutorService newScheduledThreadPool( + int corePoolSize, ThreadFactory threadFactory) { + return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory); + } + + + /** + * Returns an object that delegates all defined {@link + * ExecutorService} methods to the given executor, but not any + * other methods that might otherwise be accessible using + * casts. This provides a way to safely "freeze" configuration and + * disallow tuning of a given concrete implementation. + * @param executor the underlying implementation + * @return an <tt>ExecutorService</tt> instance + * @throws NullPointerException if executor null + */ + public static ExecutorService unconfigurableExecutorService(ExecutorService executor) { + if (executor == null) + throw new NullPointerException(); + return new DelegatedExecutorService(executor); + } + + /** + * Returns an object that delegates all defined {@link + * ScheduledExecutorService} methods to the given executor, but + * not any other methods that might otherwise be accessible using + * casts. This provides a way to safely "freeze" configuration and + * disallow tuning of a given concrete implementation. + * @param executor the underlying implementation + * @return a <tt>ScheduledExecutorService</tt> instance + * @throws NullPointerException if executor null + */ + public static ScheduledExecutorService unconfigurableScheduledExecutorService(ScheduledExecutorService executor) { + if (executor == null) + throw new NullPointerException(); + return new DelegatedScheduledExecutorService(executor); + } + + /** + * Returns a default thread factory used to create new threads. + * This factory creates all new threads used by an Executor in the + * same {@link ThreadGroup}. If there is a {@link + * java.lang.SecurityManager}, it uses the group of {@link + * System#getSecurityManager}, else the group of the thread + * invoking this <tt>defaultThreadFactory</tt> method. Each new + * thread is created as a non-daemon thread with priority set to + * the smaller of <tt>Thread.NORM_PRIORITY</tt> and the maximum + * priority permitted in the thread group. New threads have names + * accessible via {@link Thread#getName} of + * <em>pool-N-thread-M</em>, where <em>N</em> is the sequence + * number of this factory, and <em>M</em> is the sequence number + * of the thread created by this factory. + * @return a thread factory + */ + public static ThreadFactory defaultThreadFactory() { + return new DefaultThreadFactory(); + } + + /** + * Returns a thread factory used to create new threads that + * have the same permissions as the current thread. + * This factory creates threads with the same settings as {@link + * Executors#defaultThreadFactory}, additionally setting the + * AccessControlContext and contextClassLoader of new threads to + * be the same as the thread invoking this + * <tt>privilegedThreadFactory</tt> method. A new + * <tt>privilegedThreadFactory</tt> can be created within an + * {@link AccessController#doPrivileged} action setting the + * current thread's access control context to create threads with + * the selected permission settings holding within that action. + * + * <p> Note that while tasks running within such threads will have + * the same access control and class loader settings as the + * current thread, they need not have the same {@link + * java.lang.ThreadLocal} or {@link + * java.lang.InheritableThreadLocal} values. If necessary, + * particular values of thread locals can be set or reset before + * any task runs in {@link ThreadPoolExecutor} subclasses using + * {@link ThreadPoolExecutor#beforeExecute}. Also, if it is + * necessary to initialize worker threads to have the same + * InheritableThreadLocal settings as some other designated + * thread, you can create a custom ThreadFactory in which that + * thread waits for and services requests to create others that + * will inherit its values. + * + * @return a thread factory + * @throws AccessControlException if the current access control + * context does not have permission to both get and set context + * class loader. + */ + public static ThreadFactory privilegedThreadFactory() { + return new PrivilegedThreadFactory(); + } + + /** + * Returns a {@link Callable} object that, when + * called, runs the given task and returns the given result. This + * can be useful when applying methods requiring a + * <tt>Callable</tt> to an otherwise resultless action. + * @param task the task to run + * @param result the result to return + * @return a callable object + * @throws NullPointerException if task null + */ + public static <T> Callable<T> callable(Runnable task, T result) { + if (task == null) + throw new NullPointerException(); + return new RunnableAdapter<T>(task, result); + } + + /** + * Returns a {@link Callable} object that, when + * called, runs the given task and returns <tt>null</tt>. + * @param task the task to run + * @return a callable object + * @throws NullPointerException if task null + */ + public static Callable<Object> callable(Runnable task) { + if (task == null) + throw new NullPointerException(); + return new RunnableAdapter<Object>(task, null); + } + + /** + * Returns a {@link Callable} object that, when + * called, runs the given privileged action and returns its result. + * @param action the privileged action to run + * @return a callable object + * @throws NullPointerException if action null + */ + public static Callable<Object> callable(final PrivilegedAction<?> action) { + if (action == null) + throw new NullPointerException(); + return new Callable<Object>() { + public Object call() { return action.run(); }}; + } + + /** + * Returns a {@link Callable} object that, when + * called, runs the given privileged exception action and returns + * its result. + * @param action the privileged exception action to run + * @return a callable object + * @throws NullPointerException if action null + */ + public static Callable<Object> callable(final PrivilegedExceptionAction<?> action) { + if (action == null) + throw new NullPointerException(); + return new Callable<Object>() { + public Object call() throws Exception { return action.run(); }}; + } + + /** + * Returns a {@link Callable} object that will, when + * called, execute the given <tt>callable</tt> under the current + * access control context. This method should normally be + * invoked within an {@link AccessController#doPrivileged} action + * to create callables that will, if possible, execute under the + * selected permission settings holding within that action; or if + * not possible, throw an associated {@link + * AccessControlException}. + * @param callable the underlying task + * @return a callable object + * @throws NullPointerException if callable null + * + */ + public static <T> Callable<T> privilegedCallable(Callable<T> callable) { + if (callable == null) + throw new NullPointerException(); + return new PrivilegedCallable<T>(callable); + } + + /** + * Returns a {@link Callable} object that will, when + * called, execute the given <tt>callable</tt> under the current + * access control context, with the current context class loader + * as the context class loader. This method should normally be + * invoked within an {@link AccessController#doPrivileged} action + * to create callables that will, if possible, execute under the + * selected permission settings holding within that action; or if + * not possible, throw an associated {@link + * AccessControlException}. + * @param callable the underlying task + * + * @return a callable object + * @throws NullPointerException if callable null + * @throws AccessControlException if the current access control + * context does not have permission to both set and get context + * class loader. + */ + public static <T> Callable<T> privilegedCallableUsingCurrentClassLoader(Callable<T> callable) { + if (callable == null) + throw new NullPointerException(); + return new PrivilegedCallableUsingCurrentClassLoader<T>(callable); + } + + // Non-public classes supporting the public methods + + /** + * A callable that runs given task and returns given result + */ + static final class RunnableAdapter<T> implements Callable<T> { + final Runnable task; + final T result; + RunnableAdapter(Runnable task, T result) { + this.task = task; + this.result = result; + } + public T call() { + task.run(); + return result; + } + } + + /** + * A callable that runs under established access control settings + */ + static final class PrivilegedCallable<T> implements Callable<T> { + private final AccessControlContext acc; + private final Callable<T> task; + private T result; + private Exception exception; + PrivilegedCallable(Callable<T> task) { + this.task = task; + this.acc = AccessController.getContext(); + } + + public T call() throws Exception { + AccessController.doPrivileged(new PrivilegedAction<T>() { + public T run() { + try { + result = task.call(); + } catch (Exception ex) { + exception = ex; + } + return null; + } + }, acc); + if (exception != null) + throw exception; + else + return result; + } + } + + /** + * A callable that runs under established access control settings and + * current ClassLoader + */ + static final class PrivilegedCallableUsingCurrentClassLoader<T> implements Callable<T> { + private final ClassLoader ccl; + private final AccessControlContext acc; + private final Callable<T> task; + private T result; + private Exception exception; + PrivilegedCallableUsingCurrentClassLoader(Callable<T> task) { + this.task = task; + this.ccl = Thread.currentThread().getContextClassLoader(); + this.acc = AccessController.getContext(); + acc.checkPermission(new RuntimePermission("getContextClassLoader")); + acc.checkPermission(new RuntimePermission("setContextClassLoader")); + } + + public T call() throws Exception { + AccessController.doPrivileged(new PrivilegedAction<T>() { + public T run() { + ClassLoader savedcl = null; + Thread t = Thread.currentThread(); + try { + ClassLoader cl = t.getContextClassLoader(); + if (ccl != cl) { + t.setContextClassLoader(ccl); + savedcl = cl; + } + result = task.call(); + } catch (Exception ex) { + exception = ex; + } finally { + if (savedcl != null) + t.setContextClassLoader(savedcl); + } + return null; + } + }, acc); + if (exception != null) + throw exception; + else + return result; + } + } + + /** + * The default thread factory + */ + static class DefaultThreadFactory implements ThreadFactory { + static final AtomicInteger poolNumber = new AtomicInteger(1); + final ThreadGroup group; + final AtomicInteger threadNumber = new AtomicInteger(1); + final String namePrefix; + + DefaultThreadFactory() { + SecurityManager s = System.getSecurityManager(); + group = (s != null)? s.getThreadGroup() : + Thread.currentThread().getThreadGroup(); + namePrefix = "pool-" + + poolNumber.getAndIncrement() + + "-thread-"; + } + + public Thread newThread(Runnable r) { + Thread t = new Thread(group, r, + namePrefix + threadNumber.getAndIncrement(), + 0); + if (t.isDaemon()) + t.setDaemon(false); + if (t.getPriority() != Thread.NORM_PRIORITY) + t.setPriority(Thread.NORM_PRIORITY); + return t; + } + } + + /** + * Thread factory capturing access control and class loader + */ + static class PrivilegedThreadFactory extends DefaultThreadFactory { + private final ClassLoader ccl; + private final AccessControlContext acc; + + PrivilegedThreadFactory() { + super(); + this.ccl = Thread.currentThread().getContextClassLoader(); + this.acc = AccessController.getContext(); + acc.checkPermission(new RuntimePermission("setContextClassLoader")); + } + + public Thread newThread(final Runnable r) { + return super.newThread(new Runnable() { + public void run() { + AccessController.doPrivileged(new PrivilegedAction<Object>() { + public Object run() { + Thread.currentThread().setContextClassLoader(ccl); + r.run(); + return null; + } + }, acc); + } + }); + } + + } + + /** + * A wrapper class that exposes only the ExecutorService methods + * of an ExecutorService implementation. + */ + static class DelegatedExecutorService extends AbstractExecutorService { + private final ExecutorService e; + DelegatedExecutorService(ExecutorService executor) { e = executor; } + public void execute(Runnable command) { e.execute(command); } + public void shutdown() { e.shutdown(); } + public List<Runnable> shutdownNow() { return e.shutdownNow(); } + public boolean isShutdown() { return e.isShutdown(); } + public boolean isTerminated() { return e.isTerminated(); } + public boolean awaitTermination(long timeout, TimeUnit unit) + throws InterruptedException { + return e.awaitTermination(timeout, unit); + } + public Future<?> submit(Runnable task) { + return e.submit(task); + } + public <T> Future<T> submit(Callable<T> task) { + return e.submit(task); + } + public <T> Future<T> submit(Runnable task, T result) { + return e.submit(task, result); + } + public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) + throws InterruptedException { + return e.invokeAll(tasks); + } + public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, + long timeout, TimeUnit unit) + throws InterruptedException { + return e.invokeAll(tasks, timeout, unit); + } + public <T> T invokeAny(Collection<? extends Callable<T>> tasks) + throws InterruptedException, ExecutionException { + return e.invokeAny(tasks); + } + public <T> T invokeAny(Collection<? extends Callable<T>> tasks, + long timeout, TimeUnit unit) + throws InterruptedException, ExecutionException, TimeoutException { + return e.invokeAny(tasks, timeout, unit); + } + } + + static class FinalizableDelegatedExecutorService + extends DelegatedExecutorService { + FinalizableDelegatedExecutorService(ExecutorService executor) { + super(executor); + } + protected void finalize() { + super.shutdown(); + } + } + + /** + * A wrapper class that exposes only the ScheduledExecutorService + * methods of a ScheduledExecutorService implementation. + */ + static class DelegatedScheduledExecutorService + extends DelegatedExecutorService + implements ScheduledExecutorService { + private final ScheduledExecutorService e; + DelegatedScheduledExecutorService(ScheduledExecutorService executor) { + super(executor); + e = executor; + } + public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) { + return e.schedule(command, delay, unit); + } + public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit) { + return e.schedule(callable, delay, unit); + } + public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) { + return e.scheduleAtFixedRate(command, initialDelay, period, unit); + } + public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) { + return e.scheduleWithFixedDelay(command, initialDelay, delay, unit); + } + } + + + /** Cannot instantiate. */ + private Executors() {} +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/Future.java b/libjava/classpath/external/jsr166/java/util/concurrent/Future.java new file mode 100644 index 000000000..0459ee453 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/Future.java @@ -0,0 +1,142 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; + +/** + * A <tt>Future</tt> represents the result of an asynchronous + * computation. Methods are provided to check if the computation is + * complete, to wait for its completion, and to retrieve the result of + * the computation. The result can only be retrieved using method + * <tt>get</tt> when the computation has completed, blocking if + * necessary until it is ready. Cancellation is performed by the + * <tt>cancel</tt> method. Additional methods are provided to + * determine if the task completed normally or was cancelled. Once a + * computation has completed, the computation cannot be cancelled. + * If you would like to use a <tt>Future</tt> for the sake + * of cancellability but not provide a usable result, you can + * declare types of the form <tt>Future<?></tt> and + * return <tt>null</tt> as a result of the underlying task. + * + * <p> + * <b>Sample Usage</b> (Note that the following classes are all + * made-up.) <p> + * <pre> + * interface ArchiveSearcher { String search(String target); } + * class App { + * ExecutorService executor = ... + * ArchiveSearcher searcher = ... + * void showSearch(final String target) + * throws InterruptedException { + * Future<String> future + * = executor.submit(new Callable<String>() { + * public String call() { + * return searcher.search(target); + * }}); + * displayOtherThings(); // do other things while searching + * try { + * displayText(future.get()); // use future + * } catch (ExecutionException ex) { cleanup(); return; } + * } + * } + * </pre> + * + * The {@link FutureTask} class is an implementation of <tt>Future</tt> that + * implements <tt>Runnable</tt>, and so may be executed by an <tt>Executor</tt>. + * For example, the above construction with <tt>submit</tt> could be replaced by: + * <pre> + * FutureTask<String> future = + * new FutureTask<String>(new Callable<String>() { + * public String call() { + * return searcher.search(target); + * }}); + * executor.execute(future); + * </pre> + * + * <p>Memory consistency effects: Actions taken by the asynchronous computation + * <a href="package-summary.html#MemoryVisibility"> <i>happen-before</i></a> + * actions following the corresponding {@code Future.get()} in another thread. + * + * @see FutureTask + * @see Executor + * @since 1.5 + * @author Doug Lea + * @param <V> The result type returned by this Future's <tt>get</tt> method + */ +public interface Future<V> { + + /** + * Attempts to cancel execution of this task. This attempt will + * fail if the task has already completed, has already been cancelled, + * or could not be cancelled for some other reason. If successful, + * and this task has not started when <tt>cancel</tt> is called, + * this task should never run. If the task has already started, + * then the <tt>mayInterruptIfRunning</tt> parameter determines + * whether the thread executing this task should be interrupted in + * an attempt to stop the task. + * + * <p>After this method returns, subsequent calls to {@link #isDone} will + * always return <tt>true</tt>. Subsequent calls to {@link #isCancelled} + * will always return <tt>true</tt> if this method returned <tt>true</tt>. + * + * @param mayInterruptIfRunning <tt>true</tt> if the thread executing this + * task should be interrupted; otherwise, in-progress tasks are allowed + * to complete + * @return <tt>false</tt> if the task could not be cancelled, + * typically because it has already completed normally; + * <tt>true</tt> otherwise + */ + boolean cancel(boolean mayInterruptIfRunning); + + /** + * Returns <tt>true</tt> if this task was cancelled before it completed + * normally. + * + * @return <tt>true</tt> if this task was cancelled before it completed + */ + boolean isCancelled(); + + /** + * Returns <tt>true</tt> if this task completed. + * + * Completion may be due to normal termination, an exception, or + * cancellation -- in all of these cases, this method will return + * <tt>true</tt>. + * + * @return <tt>true</tt> if this task completed + */ + boolean isDone(); + + /** + * Waits if necessary for the computation to complete, and then + * retrieves its result. + * + * @return the computed result + * @throws CancellationException if the computation was cancelled + * @throws ExecutionException if the computation threw an + * exception + * @throws InterruptedException if the current thread was interrupted + * while waiting + */ + V get() throws InterruptedException, ExecutionException; + + /** + * Waits if necessary for at most the given time for the computation + * to complete, and then retrieves its result, if available. + * + * @param timeout the maximum time to wait + * @param unit the time unit of the timeout argument + * @return the computed result + * @throws CancellationException if the computation was cancelled + * @throws ExecutionException if the computation threw an + * exception + * @throws InterruptedException if the current thread was interrupted + * while waiting + * @throws TimeoutException if the wait timed out + */ + V get(long timeout, TimeUnit unit) + throws InterruptedException, ExecutionException, TimeoutException; +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/FutureTask.java b/libjava/classpath/external/jsr166/java/util/concurrent/FutureTask.java new file mode 100644 index 000000000..94742405d --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/FutureTask.java @@ -0,0 +1,325 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; +import java.util.concurrent.locks.*; + +/** + * A cancellable asynchronous computation. This class provides a base + * implementation of {@link Future}, with methods to start and cancel + * a computation, query to see if the computation is complete, and + * retrieve the result of the computation. The result can only be + * retrieved when the computation has completed; the <tt>get</tt> + * method will block if the computation has not yet completed. Once + * the computation has completed, the computation cannot be restarted + * or cancelled. + * + * <p>A <tt>FutureTask</tt> can be used to wrap a {@link Callable} or + * {@link java.lang.Runnable} object. Because <tt>FutureTask</tt> + * implements <tt>Runnable</tt>, a <tt>FutureTask</tt> can be + * submitted to an {@link Executor} for execution. + * + * <p>In addition to serving as a standalone class, this class provides + * <tt>protected</tt> functionality that may be useful when creating + * customized task classes. + * + * @since 1.5 + * @author Doug Lea + * @param <V> The result type returned by this FutureTask's <tt>get</tt> method + */ +public class FutureTask<V> implements RunnableFuture<V> { + /** Synchronization control for FutureTask */ + private final Sync sync; + + /** + * Creates a <tt>FutureTask</tt> that will upon running, execute the + * given <tt>Callable</tt>. + * + * @param callable the callable task + * @throws NullPointerException if callable is null + */ + public FutureTask(Callable<V> callable) { + if (callable == null) + throw new NullPointerException(); + sync = new Sync(callable); + } + + /** + * Creates a <tt>FutureTask</tt> that will upon running, execute the + * given <tt>Runnable</tt>, and arrange that <tt>get</tt> will return the + * given result on successful completion. + * + * @param runnable the runnable task + * @param result the result to return on successful completion. If + * you don't need a particular result, consider using + * constructions of the form: + * <tt>Future<?> f = new FutureTask<Object>(runnable, null)</tt> + * @throws NullPointerException if runnable is null + */ + public FutureTask(Runnable runnable, V result) { + sync = new Sync(Executors.callable(runnable, result)); + } + + public boolean isCancelled() { + return sync.innerIsCancelled(); + } + + public boolean isDone() { + return sync.innerIsDone(); + } + + public boolean cancel(boolean mayInterruptIfRunning) { + return sync.innerCancel(mayInterruptIfRunning); + } + + /** + * @throws CancellationException {@inheritDoc} + */ + public V get() throws InterruptedException, ExecutionException { + return sync.innerGet(); + } + + /** + * @throws CancellationException {@inheritDoc} + */ + public V get(long timeout, TimeUnit unit) + throws InterruptedException, ExecutionException, TimeoutException { + return sync.innerGet(unit.toNanos(timeout)); + } + + /** + * Protected method invoked when this task transitions to state + * <tt>isDone</tt> (whether normally or via cancellation). The + * default implementation does nothing. Subclasses may override + * this method to invoke completion callbacks or perform + * bookkeeping. Note that you can query status inside the + * implementation of this method to determine whether this task + * has been cancelled. + */ + protected void done() { } + + /** + * Sets the result of this Future to the given value unless + * this future has already been set or has been cancelled. + * This method is invoked internally by the <tt>run</tt> method + * upon successful completion of the computation. + * @param v the value + */ + protected void set(V v) { + sync.innerSet(v); + } + + /** + * Causes this future to report an <tt>ExecutionException</tt> + * with the given throwable as its cause, unless this Future has + * already been set or has been cancelled. + * This method is invoked internally by the <tt>run</tt> method + * upon failure of the computation. + * @param t the cause of failure + */ + protected void setException(Throwable t) { + sync.innerSetException(t); + } + + // The following (duplicated) doc comment can be removed once + // + // 6270645: Javadoc comments should be inherited from most derived + // superinterface or superclass + // is fixed. + /** + * Sets this Future to the result of its computation + * unless it has been cancelled. + */ + public void run() { + sync.innerRun(); + } + + /** + * Executes the computation without setting its result, and then + * resets this Future to initial state, failing to do so if the + * computation encounters an exception or is cancelled. This is + * designed for use with tasks that intrinsically execute more + * than once. + * @return true if successfully run and reset + */ + protected boolean runAndReset() { + return sync.innerRunAndReset(); + } + + /** + * Synchronization control for FutureTask. Note that this must be + * a non-static inner class in order to invoke the protected + * <tt>done</tt> method. For clarity, all inner class support + * methods are same as outer, prefixed with "inner". + * + * Uses AQS sync state to represent run status + */ + private final class Sync extends AbstractQueuedSynchronizer { + private static final long serialVersionUID = -7828117401763700385L; + + /** State value representing that task is running */ + private static final int RUNNING = 1; + /** State value representing that task ran */ + private static final int RAN = 2; + /** State value representing that task was cancelled */ + private static final int CANCELLED = 4; + + /** The underlying callable */ + private final Callable<V> callable; + /** The result to return from get() */ + private V result; + /** The exception to throw from get() */ + private Throwable exception; + + /** + * The thread running task. When nulled after set/cancel, this + * indicates that the results are accessible. Must be + * volatile, to ensure visibility upon completion. + */ + private volatile Thread runner; + + Sync(Callable<V> callable) { + this.callable = callable; + } + + private boolean ranOrCancelled(int state) { + return (state & (RAN | CANCELLED)) != 0; + } + + /** + * Implements AQS base acquire to succeed if ran or cancelled + */ + protected int tryAcquireShared(int ignore) { + return innerIsDone()? 1 : -1; + } + + /** + * Implements AQS base release to always signal after setting + * final done status by nulling runner thread. + */ + protected boolean tryReleaseShared(int ignore) { + runner = null; + return true; + } + + boolean innerIsCancelled() { + return getState() == CANCELLED; + } + + boolean innerIsDone() { + return ranOrCancelled(getState()) && runner == null; + } + + V innerGet() throws InterruptedException, ExecutionException { + acquireSharedInterruptibly(0); + if (getState() == CANCELLED) + throw new CancellationException(); + if (exception != null) + throw new ExecutionException(exception); + return result; + } + + V innerGet(long nanosTimeout) throws InterruptedException, ExecutionException, TimeoutException { + if (!tryAcquireSharedNanos(0, nanosTimeout)) + throw new TimeoutException(); + if (getState() == CANCELLED) + throw new CancellationException(); + if (exception != null) + throw new ExecutionException(exception); + return result; + } + + void innerSet(V v) { + for (;;) { + int s = getState(); + if (s == RAN) + return; + if (s == CANCELLED) { + // aggressively release to set runner to null, + // in case we are racing with a cancel request + // that will try to interrupt runner + releaseShared(0); + return; + } + if (compareAndSetState(s, RAN)) { + result = v; + releaseShared(0); + done(); + return; + } + } + } + + void innerSetException(Throwable t) { + for (;;) { + int s = getState(); + if (s == RAN) + return; + if (s == CANCELLED) { + // aggressively release to set runner to null, + // in case we are racing with a cancel request + // that will try to interrupt runner + releaseShared(0); + return; + } + if (compareAndSetState(s, RAN)) { + exception = t; + result = null; + releaseShared(0); + done(); + return; + } + } + } + + boolean innerCancel(boolean mayInterruptIfRunning) { + for (;;) { + int s = getState(); + if (ranOrCancelled(s)) + return false; + if (compareAndSetState(s, CANCELLED)) + break; + } + if (mayInterruptIfRunning) { + Thread r = runner; + if (r != null) + r.interrupt(); + } + releaseShared(0); + done(); + return true; + } + + void innerRun() { + if (!compareAndSetState(0, RUNNING)) + return; + try { + runner = Thread.currentThread(); + if (getState() == RUNNING) // recheck after setting thread + innerSet(callable.call()); + else + releaseShared(0); // cancel + } catch (Throwable ex) { + innerSetException(ex); + } + } + + boolean innerRunAndReset() { + if (!compareAndSetState(0, RUNNING)) + return false; + try { + runner = Thread.currentThread(); + if (getState() == RUNNING) + callable.call(); // don't set result + runner = null; + return compareAndSetState(RUNNING, 0); + } catch (Throwable ex) { + innerSetException(ex); + return false; + } + } + } +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/LinkedBlockingDeque.java b/libjava/classpath/external/jsr166/java/util/concurrent/LinkedBlockingDeque.java new file mode 100644 index 000000000..2dc8fa877 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/LinkedBlockingDeque.java @@ -0,0 +1,1021 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; +import java.util.*; +import java.util.concurrent.locks.*; + +/** + * An optionally-bounded {@linkplain BlockingDeque blocking deque} based on + * linked nodes. + * + * <p> The optional capacity bound constructor argument serves as a + * way to prevent excessive expansion. The capacity, if unspecified, + * is equal to {@link Integer#MAX_VALUE}. Linked nodes are + * dynamically created upon each insertion unless this would bring the + * deque above capacity. + * + * <p>Most operations run in constant time (ignoring time spent + * blocking). Exceptions include {@link #remove(Object) remove}, + * {@link #removeFirstOccurrence removeFirstOccurrence}, {@link + * #removeLastOccurrence removeLastOccurrence}, {@link #contains + * contains}, {@link #iterator iterator.remove()}, and the bulk + * operations, all of which run in linear time. + * + * <p>This class and its iterator implement all of the + * <em>optional</em> methods of the {@link Collection} and {@link + * Iterator} interfaces. + * + * <p>This class is a member of the + * <a href="{@docRoot}/../technotes/guides/collections/index.html"> + * Java Collections Framework</a>. + * + * @since 1.6 + * @author Doug Lea + * @param <E> the type of elements held in this collection + */ +public class LinkedBlockingDeque<E> + extends AbstractQueue<E> + implements BlockingDeque<E>, java.io.Serializable { + + /* + * Implemented as a simple doubly-linked list protected by a + * single lock and using conditions to manage blocking. + */ + + /* + * We have "diamond" multiple interface/abstract class inheritance + * here, and that introduces ambiguities. Often we want the + * BlockingDeque javadoc combined with the AbstractQueue + * implementation, so a lot of method specs are duplicated here. + */ + + private static final long serialVersionUID = -387911632671998426L; + + /** Doubly-linked list node class */ + static final class Node<E> { + E item; + Node<E> prev; + Node<E> next; + Node(E x, Node<E> p, Node<E> n) { + item = x; + prev = p; + next = n; + } + } + + /** Pointer to first node */ + private transient Node<E> first; + /** Pointer to last node */ + private transient Node<E> last; + /** Number of items in the deque */ + private transient int count; + /** Maximum number of items in the deque */ + private final int capacity; + /** Main lock guarding all access */ + private final ReentrantLock lock = new ReentrantLock(); + /** Condition for waiting takes */ + private final Condition notEmpty = lock.newCondition(); + /** Condition for waiting puts */ + private final Condition notFull = lock.newCondition(); + + /** + * Creates a <tt>LinkedBlockingDeque</tt> with a capacity of + * {@link Integer#MAX_VALUE}. + */ + public LinkedBlockingDeque() { + this(Integer.MAX_VALUE); + } + + /** + * Creates a <tt>LinkedBlockingDeque</tt> with the given (fixed) capacity. + * + * @param capacity the capacity of this deque + * @throws IllegalArgumentException if <tt>capacity</tt> is less than 1 + */ + public LinkedBlockingDeque(int capacity) { + if (capacity <= 0) throw new IllegalArgumentException(); + this.capacity = capacity; + } + + /** + * Creates a <tt>LinkedBlockingDeque</tt> with a capacity of + * {@link Integer#MAX_VALUE}, initially containing the elements of + * the given collection, added in traversal order of the + * collection's iterator. + * + * @param c the collection of elements to initially contain + * @throws NullPointerException if the specified collection or any + * of its elements are null + */ + public LinkedBlockingDeque(Collection<? extends E> c) { + this(Integer.MAX_VALUE); + for (E e : c) + add(e); + } + + + // Basic linking and unlinking operations, called only while holding lock + + /** + * Links e as first element, or returns false if full. + */ + private boolean linkFirst(E e) { + if (count >= capacity) + return false; + ++count; + Node<E> f = first; + Node<E> x = new Node<E>(e, null, f); + first = x; + if (last == null) + last = x; + else + f.prev = x; + notEmpty.signal(); + return true; + } + + /** + * Links e as last element, or returns false if full. + */ + private boolean linkLast(E e) { + if (count >= capacity) + return false; + ++count; + Node<E> l = last; + Node<E> x = new Node<E>(e, l, null); + last = x; + if (first == null) + first = x; + else + l.next = x; + notEmpty.signal(); + return true; + } + + /** + * Removes and returns first element, or null if empty. + */ + private E unlinkFirst() { + Node<E> f = first; + if (f == null) + return null; + Node<E> n = f.next; + first = n; + if (n == null) + last = null; + else + n.prev = null; + --count; + notFull.signal(); + return f.item; + } + + /** + * Removes and returns last element, or null if empty. + */ + private E unlinkLast() { + Node<E> l = last; + if (l == null) + return null; + Node<E> p = l.prev; + last = p; + if (p == null) + first = null; + else + p.next = null; + --count; + notFull.signal(); + return l.item; + } + + /** + * Unlink e + */ + private void unlink(Node<E> x) { + Node<E> p = x.prev; + Node<E> n = x.next; + if (p == null) { + if (n == null) + first = last = null; + else { + n.prev = null; + first = n; + } + } else if (n == null) { + p.next = null; + last = p; + } else { + p.next = n; + n.prev = p; + } + --count; + notFull.signalAll(); + } + + // BlockingDeque methods + + /** + * @throws IllegalStateException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + */ + public void addFirst(E e) { + if (!offerFirst(e)) + throw new IllegalStateException("Deque full"); + } + + /** + * @throws IllegalStateException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + */ + public void addLast(E e) { + if (!offerLast(e)) + throw new IllegalStateException("Deque full"); + } + + /** + * @throws NullPointerException {@inheritDoc} + */ + public boolean offerFirst(E e) { + if (e == null) throw new NullPointerException(); + lock.lock(); + try { + return linkFirst(e); + } finally { + lock.unlock(); + } + } + + /** + * @throws NullPointerException {@inheritDoc} + */ + public boolean offerLast(E e) { + if (e == null) throw new NullPointerException(); + lock.lock(); + try { + return linkLast(e); + } finally { + lock.unlock(); + } + } + + /** + * @throws NullPointerException {@inheritDoc} + * @throws InterruptedException {@inheritDoc} + */ + public void putFirst(E e) throws InterruptedException { + if (e == null) throw new NullPointerException(); + lock.lock(); + try { + while (!linkFirst(e)) + notFull.await(); + } finally { + lock.unlock(); + } + } + + /** + * @throws NullPointerException {@inheritDoc} + * @throws InterruptedException {@inheritDoc} + */ + public void putLast(E e) throws InterruptedException { + if (e == null) throw new NullPointerException(); + lock.lock(); + try { + while (!linkLast(e)) + notFull.await(); + } finally { + lock.unlock(); + } + } + + /** + * @throws NullPointerException {@inheritDoc} + * @throws InterruptedException {@inheritDoc} + */ + public boolean offerFirst(E e, long timeout, TimeUnit unit) + throws InterruptedException { + if (e == null) throw new NullPointerException(); + long nanos = unit.toNanos(timeout); + lock.lockInterruptibly(); + try { + for (;;) { + if (linkFirst(e)) + return true; + if (nanos <= 0) + return false; + nanos = notFull.awaitNanos(nanos); + } + } finally { + lock.unlock(); + } + } + + /** + * @throws NullPointerException {@inheritDoc} + * @throws InterruptedException {@inheritDoc} + */ + public boolean offerLast(E e, long timeout, TimeUnit unit) + throws InterruptedException { + if (e == null) throw new NullPointerException(); + long nanos = unit.toNanos(timeout); + lock.lockInterruptibly(); + try { + for (;;) { + if (linkLast(e)) + return true; + if (nanos <= 0) + return false; + nanos = notFull.awaitNanos(nanos); + } + } finally { + lock.unlock(); + } + } + + /** + * @throws NoSuchElementException {@inheritDoc} + */ + public E removeFirst() { + E x = pollFirst(); + if (x == null) throw new NoSuchElementException(); + return x; + } + + /** + * @throws NoSuchElementException {@inheritDoc} + */ + public E removeLast() { + E x = pollLast(); + if (x == null) throw new NoSuchElementException(); + return x; + } + + public E pollFirst() { + lock.lock(); + try { + return unlinkFirst(); + } finally { + lock.unlock(); + } + } + + public E pollLast() { + lock.lock(); + try { + return unlinkLast(); + } finally { + lock.unlock(); + } + } + + public E takeFirst() throws InterruptedException { + lock.lock(); + try { + E x; + while ( (x = unlinkFirst()) == null) + notEmpty.await(); + return x; + } finally { + lock.unlock(); + } + } + + public E takeLast() throws InterruptedException { + lock.lock(); + try { + E x; + while ( (x = unlinkLast()) == null) + notEmpty.await(); + return x; + } finally { + lock.unlock(); + } + } + + public E pollFirst(long timeout, TimeUnit unit) + throws InterruptedException { + long nanos = unit.toNanos(timeout); + lock.lockInterruptibly(); + try { + for (;;) { + E x = unlinkFirst(); + if (x != null) + return x; + if (nanos <= 0) + return null; + nanos = notEmpty.awaitNanos(nanos); + } + } finally { + lock.unlock(); + } + } + + public E pollLast(long timeout, TimeUnit unit) + throws InterruptedException { + long nanos = unit.toNanos(timeout); + lock.lockInterruptibly(); + try { + for (;;) { + E x = unlinkLast(); + if (x != null) + return x; + if (nanos <= 0) + return null; + nanos = notEmpty.awaitNanos(nanos); + } + } finally { + lock.unlock(); + } + } + + /** + * @throws NoSuchElementException {@inheritDoc} + */ + public E getFirst() { + E x = peekFirst(); + if (x == null) throw new NoSuchElementException(); + return x; + } + + /** + * @throws NoSuchElementException {@inheritDoc} + */ + public E getLast() { + E x = peekLast(); + if (x == null) throw new NoSuchElementException(); + return x; + } + + public E peekFirst() { + lock.lock(); + try { + return (first == null) ? null : first.item; + } finally { + lock.unlock(); + } + } + + public E peekLast() { + lock.lock(); + try { + return (last == null) ? null : last.item; + } finally { + lock.unlock(); + } + } + + public boolean removeFirstOccurrence(Object o) { + if (o == null) return false; + lock.lock(); + try { + for (Node<E> p = first; p != null; p = p.next) { + if (o.equals(p.item)) { + unlink(p); + return true; + } + } + return false; + } finally { + lock.unlock(); + } + } + + public boolean removeLastOccurrence(Object o) { + if (o == null) return false; + lock.lock(); + try { + for (Node<E> p = last; p != null; p = p.prev) { + if (o.equals(p.item)) { + unlink(p); + return true; + } + } + return false; + } finally { + lock.unlock(); + } + } + + // BlockingQueue methods + + /** + * Inserts the specified element at the end of this deque unless it would + * violate capacity restrictions. When using a capacity-restricted deque, + * it is generally preferable to use method {@link #offer(Object) offer}. + * + * <p>This method is equivalent to {@link #addLast}. + * + * @throws IllegalStateException if the element cannot be added at this + * time due to capacity restrictions + * @throws NullPointerException if the specified element is null + */ + public boolean add(E e) { + addLast(e); + return true; + } + + /** + * @throws NullPointerException if the specified element is null + */ + public boolean offer(E e) { + return offerLast(e); + } + + /** + * @throws NullPointerException {@inheritDoc} + * @throws InterruptedException {@inheritDoc} + */ + public void put(E e) throws InterruptedException { + putLast(e); + } + + /** + * @throws NullPointerException {@inheritDoc} + * @throws InterruptedException {@inheritDoc} + */ + public boolean offer(E e, long timeout, TimeUnit unit) + throws InterruptedException { + return offerLast(e, timeout, unit); + } + + /** + * Retrieves and removes the head of the queue represented by this deque. + * This method differs from {@link #poll poll} only in that it throws an + * exception if this deque is empty. + * + * <p>This method is equivalent to {@link #removeFirst() removeFirst}. + * + * @return the head of the queue represented by this deque + * @throws NoSuchElementException if this deque is empty + */ + public E remove() { + return removeFirst(); + } + + public E poll() { + return pollFirst(); + } + + public E take() throws InterruptedException { + return takeFirst(); + } + + public E poll(long timeout, TimeUnit unit) throws InterruptedException { + return pollFirst(timeout, unit); + } + + /** + * Retrieves, but does not remove, the head of the queue represented by + * this deque. This method differs from {@link #peek peek} only in that + * it throws an exception if this deque is empty. + * + * <p>This method is equivalent to {@link #getFirst() getFirst}. + * + * @return the head of the queue represented by this deque + * @throws NoSuchElementException if this deque is empty + */ + public E element() { + return getFirst(); + } + + public E peek() { + return peekFirst(); + } + + /** + * Returns the number of additional elements that this deque can ideally + * (in the absence of memory or resource constraints) accept without + * blocking. This is always equal to the initial capacity of this deque + * less the current <tt>size</tt> of this deque. + * + * <p>Note that you <em>cannot</em> always tell if an attempt to insert + * an element will succeed by inspecting <tt>remainingCapacity</tt> + * because it may be the case that another thread is about to + * insert or remove an element. + */ + public int remainingCapacity() { + lock.lock(); + try { + return capacity - count; + } finally { + lock.unlock(); + } + } + + /** + * @throws UnsupportedOperationException {@inheritDoc} + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + * @throws IllegalArgumentException {@inheritDoc} + */ + public int drainTo(Collection<? super E> c) { + if (c == null) + throw new NullPointerException(); + if (c == this) + throw new IllegalArgumentException(); + lock.lock(); + try { + for (Node<E> p = first; p != null; p = p.next) + c.add(p.item); + int n = count; + count = 0; + first = last = null; + notFull.signalAll(); + return n; + } finally { + lock.unlock(); + } + } + + /** + * @throws UnsupportedOperationException {@inheritDoc} + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + * @throws IllegalArgumentException {@inheritDoc} + */ + public int drainTo(Collection<? super E> c, int maxElements) { + if (c == null) + throw new NullPointerException(); + if (c == this) + throw new IllegalArgumentException(); + lock.lock(); + try { + int n = 0; + while (n < maxElements && first != null) { + c.add(first.item); + first.prev = null; + first = first.next; + --count; + ++n; + } + if (first == null) + last = null; + notFull.signalAll(); + return n; + } finally { + lock.unlock(); + } + } + + // Stack methods + + /** + * @throws IllegalStateException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + */ + public void push(E e) { + addFirst(e); + } + + /** + * @throws NoSuchElementException {@inheritDoc} + */ + public E pop() { + return removeFirst(); + } + + // Collection methods + + /** + * Removes the first occurrence of the specified element from this deque. + * If the deque does not contain the element, it is unchanged. + * More formally, removes the first element <tt>e</tt> such that + * <tt>o.equals(e)</tt> (if such an element exists). + * Returns <tt>true</tt> if this deque contained the specified element + * (or equivalently, if this deque changed as a result of the call). + * + * <p>This method is equivalent to + * {@link #removeFirstOccurrence(Object) removeFirstOccurrence}. + * + * @param o element to be removed from this deque, if present + * @return <tt>true</tt> if this deque changed as a result of the call + */ + public boolean remove(Object o) { + return removeFirstOccurrence(o); + } + + /** + * Returns the number of elements in this deque. + * + * @return the number of elements in this deque + */ + public int size() { + lock.lock(); + try { + return count; + } finally { + lock.unlock(); + } + } + + /** + * Returns <tt>true</tt> if this deque contains the specified element. + * More formally, returns <tt>true</tt> if and only if this deque contains + * at least one element <tt>e</tt> such that <tt>o.equals(e)</tt>. + * + * @param o object to be checked for containment in this deque + * @return <tt>true</tt> if this deque contains the specified element + */ + public boolean contains(Object o) { + if (o == null) return false; + lock.lock(); + try { + for (Node<E> p = first; p != null; p = p.next) + if (o.equals(p.item)) + return true; + return false; + } finally { + lock.unlock(); + } + } + + /** + * Variant of removeFirstOccurrence needed by iterator.remove. + * Searches for the node, not its contents. + */ + boolean removeNode(Node<E> e) { + lock.lock(); + try { + for (Node<E> p = first; p != null; p = p.next) { + if (p == e) { + unlink(p); + return true; + } + } + return false; + } finally { + lock.unlock(); + } + } + + /** + * Returns an array containing all of the elements in this deque, in + * proper sequence (from first to last element). + * + * <p>The returned array will be "safe" in that no references to it are + * maintained by this deque. (In other words, this method must allocate + * a new array). The caller is thus free to modify the returned array. + * + * <p>This method acts as bridge between array-based and collection-based + * APIs. + * + * @return an array containing all of the elements in this deque + */ + public Object[] toArray() { + lock.lock(); + try { + Object[] a = new Object[count]; + int k = 0; + for (Node<E> p = first; p != null; p = p.next) + a[k++] = p.item; + return a; + } finally { + lock.unlock(); + } + } + + /** + * Returns an array containing all of the elements in this deque, in + * proper sequence; the runtime type of the returned array is that of + * the specified array. If the deque fits in the specified array, it + * is returned therein. Otherwise, a new array is allocated with the + * runtime type of the specified array and the size of this deque. + * + * <p>If this deque fits in the specified array with room to spare + * (i.e., the array has more elements than this deque), the element in + * the array immediately following the end of the deque is set to + * <tt>null</tt>. + * + * <p>Like the {@link #toArray()} method, this method acts as bridge between + * array-based and collection-based APIs. Further, this method allows + * precise control over the runtime type of the output array, and may, + * under certain circumstances, be used to save allocation costs. + * + * <p>Suppose <tt>x</tt> is a deque known to contain only strings. + * The following code can be used to dump the deque into a newly + * allocated array of <tt>String</tt>: + * + * <pre> + * String[] y = x.toArray(new String[0]);</pre> + * + * Note that <tt>toArray(new Object[0])</tt> is identical in function to + * <tt>toArray()</tt>. + * + * @param a the array into which the elements of the deque are to + * be stored, if it is big enough; otherwise, a new array of the + * same runtime type is allocated for this purpose + * @return an array containing all of the elements in this deque + * @throws ArrayStoreException if the runtime type of the specified array + * is not a supertype of the runtime type of every element in + * this deque + * @throws NullPointerException if the specified array is null + */ + public <T> T[] toArray(T[] a) { + lock.lock(); + try { + if (a.length < count) + a = (T[])java.lang.reflect.Array.newInstance( + a.getClass().getComponentType(), + count + ); + + int k = 0; + for (Node<E> p = first; p != null; p = p.next) + a[k++] = (T)p.item; + if (a.length > k) + a[k] = null; + return a; + } finally { + lock.unlock(); + } + } + + public String toString() { + lock.lock(); + try { + return super.toString(); + } finally { + lock.unlock(); + } + } + + /** + * Atomically removes all of the elements from this deque. + * The deque will be empty after this call returns. + */ + public void clear() { + lock.lock(); + try { + first = last = null; + count = 0; + notFull.signalAll(); + } finally { + lock.unlock(); + } + } + + /** + * Returns an iterator over the elements in this deque in proper sequence. + * The elements will be returned in order from first (head) to last (tail). + * The returned <tt>Iterator</tt> is a "weakly consistent" iterator that + * will never throw {@link ConcurrentModificationException}, + * and guarantees to traverse elements as they existed upon + * construction of the iterator, and may (but is not guaranteed to) + * reflect any modifications subsequent to construction. + * + * @return an iterator over the elements in this deque in proper sequence + */ + public Iterator<E> iterator() { + return new Itr(); + } + + /** + * Returns an iterator over the elements in this deque in reverse + * sequential order. The elements will be returned in order from + * last (tail) to first (head). + * The returned <tt>Iterator</tt> is a "weakly consistent" iterator that + * will never throw {@link ConcurrentModificationException}, + * and guarantees to traverse elements as they existed upon + * construction of the iterator, and may (but is not guaranteed to) + * reflect any modifications subsequent to construction. + */ + public Iterator<E> descendingIterator() { + return new DescendingItr(); + } + + /** + * Base class for Iterators for LinkedBlockingDeque + */ + private abstract class AbstractItr implements Iterator<E> { + /** + * The next node to return in next + */ + Node<E> next; + + /** + * nextItem holds on to item fields because once we claim that + * an element exists in hasNext(), we must return item read + * under lock (in advance()) even if it was in the process of + * being removed when hasNext() was called. + */ + E nextItem; + + /** + * Node returned by most recent call to next. Needed by remove. + * Reset to null if this element is deleted by a call to remove. + */ + private Node<E> lastRet; + + AbstractItr() { + advance(); // set to initial position + } + + /** + * Advances next, or if not yet initialized, sets to first node. + * Implemented to move forward vs backward in the two subclasses. + */ + abstract void advance(); + + public boolean hasNext() { + return next != null; + } + + public E next() { + if (next == null) + throw new NoSuchElementException(); + lastRet = next; + E x = nextItem; + advance(); + return x; + } + + public void remove() { + Node<E> n = lastRet; + if (n == null) + throw new IllegalStateException(); + lastRet = null; + // Note: removeNode rescans looking for this node to make + // sure it was not already removed. Otherwise, trying to + // re-remove could corrupt list. + removeNode(n); + } + } + + /** Forward iterator */ + private class Itr extends AbstractItr { + void advance() { + final ReentrantLock lock = LinkedBlockingDeque.this.lock; + lock.lock(); + try { + next = (next == null)? first : next.next; + nextItem = (next == null)? null : next.item; + } finally { + lock.unlock(); + } + } + } + + /** + * Descending iterator for LinkedBlockingDeque + */ + private class DescendingItr extends AbstractItr { + void advance() { + final ReentrantLock lock = LinkedBlockingDeque.this.lock; + lock.lock(); + try { + next = (next == null)? last : next.prev; + nextItem = (next == null)? null : next.item; + } finally { + lock.unlock(); + } + } + } + + /** + * Save the state of this deque to a stream (that is, serialize it). + * + * @serialData The capacity (int), followed by elements (each an + * <tt>Object</tt>) in the proper order, followed by a null + * @param s the stream + */ + private void writeObject(java.io.ObjectOutputStream s) + throws java.io.IOException { + lock.lock(); + try { + // Write out capacity and any hidden stuff + s.defaultWriteObject(); + // Write out all elements in the proper order. + for (Node<E> p = first; p != null; p = p.next) + s.writeObject(p.item); + // Use trailing null as sentinel + s.writeObject(null); + } finally { + lock.unlock(); + } + } + + /** + * Reconstitute this deque from a stream (that is, + * deserialize it). + * @param s the stream + */ + private void readObject(java.io.ObjectInputStream s) + throws java.io.IOException, ClassNotFoundException { + s.defaultReadObject(); + count = 0; + first = null; + last = null; + // Read in all elements and place in queue + for (;;) { + E item = (E)s.readObject(); + if (item == null) + break; + add(item); + } + } + +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/LinkedBlockingQueue.java b/libjava/classpath/external/jsr166/java/util/concurrent/LinkedBlockingQueue.java new file mode 100644 index 000000000..62018096a --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/LinkedBlockingQueue.java @@ -0,0 +1,807 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; +import java.util.concurrent.atomic.*; +import java.util.concurrent.locks.*; +import java.util.*; + +/** + * An optionally-bounded {@linkplain BlockingQueue blocking queue} based on + * linked nodes. + * This queue orders elements FIFO (first-in-first-out). + * The <em>head</em> of the queue is that element that has been on the + * queue the longest time. + * The <em>tail</em> of the queue is that element that has been on the + * queue the shortest time. New elements + * are inserted at the tail of the queue, and the queue retrieval + * operations obtain elements at the head of the queue. + * Linked queues typically have higher throughput than array-based queues but + * less predictable performance in most concurrent applications. + * + * <p> The optional capacity bound constructor argument serves as a + * way to prevent excessive queue expansion. The capacity, if unspecified, + * is equal to {@link Integer#MAX_VALUE}. Linked nodes are + * dynamically created upon each insertion unless this would bring the + * queue above capacity. + * + * <p>This class and its iterator implement all of the + * <em>optional</em> methods of the {@link Collection} and {@link + * Iterator} interfaces. + * + * <p>This class is a member of the + * <a href="{@docRoot}/../technotes/guides/collections/index.html"> + * Java Collections Framework</a>. + * + * @since 1.5 + * @author Doug Lea + * @param <E> the type of elements held in this collection + * + */ +public class LinkedBlockingQueue<E> extends AbstractQueue<E> + implements BlockingQueue<E>, java.io.Serializable { + private static final long serialVersionUID = -6903933977591709194L; + + /* + * A variant of the "two lock queue" algorithm. The putLock gates + * entry to put (and offer), and has an associated condition for + * waiting puts. Similarly for the takeLock. The "count" field + * that they both rely on is maintained as an atomic to avoid + * needing to get both locks in most cases. Also, to minimize need + * for puts to get takeLock and vice-versa, cascading notifies are + * used. When a put notices that it has enabled at least one take, + * it signals taker. That taker in turn signals others if more + * items have been entered since the signal. And symmetrically for + * takes signalling puts. Operations such as remove(Object) and + * iterators acquire both locks. + */ + + /** + * Linked list node class + */ + static class Node<E> { + /** The item, volatile to ensure barrier separating write and read */ + volatile E item; + Node<E> next; + Node(E x) { item = x; } + } + + /** The capacity bound, or Integer.MAX_VALUE if none */ + private final int capacity; + + /** Current number of elements */ + private final AtomicInteger count = new AtomicInteger(0); + + /** Head of linked list */ + private transient Node<E> head; + + /** Tail of linked list */ + private transient Node<E> last; + + /** Lock held by take, poll, etc */ + private final ReentrantLock takeLock = new ReentrantLock(); + + /** Wait queue for waiting takes */ + private final Condition notEmpty = takeLock.newCondition(); + + /** Lock held by put, offer, etc */ + private final ReentrantLock putLock = new ReentrantLock(); + + /** Wait queue for waiting puts */ + private final Condition notFull = putLock.newCondition(); + + /** + * Signals a waiting take. Called only from put/offer (which do not + * otherwise ordinarily lock takeLock.) + */ + private void signalNotEmpty() { + final ReentrantLock takeLock = this.takeLock; + takeLock.lock(); + try { + notEmpty.signal(); + } finally { + takeLock.unlock(); + } + } + + /** + * Signals a waiting put. Called only from take/poll. + */ + private void signalNotFull() { + final ReentrantLock putLock = this.putLock; + putLock.lock(); + try { + notFull.signal(); + } finally { + putLock.unlock(); + } + } + + /** + * Creates a node and links it at end of queue. + * @param x the item + */ + private void insert(E x) { + last = last.next = new Node<E>(x); + } + + /** + * Removes a node from head of queue, + * @return the node + */ + private E extract() { + Node<E> first = head.next; + head = first; + E x = first.item; + first.item = null; + return x; + } + + /** + * Lock to prevent both puts and takes. + */ + private void fullyLock() { + putLock.lock(); + takeLock.lock(); + } + + /** + * Unlock to allow both puts and takes. + */ + private void fullyUnlock() { + takeLock.unlock(); + putLock.unlock(); + } + + + /** + * Creates a <tt>LinkedBlockingQueue</tt> with a capacity of + * {@link Integer#MAX_VALUE}. + */ + public LinkedBlockingQueue() { + this(Integer.MAX_VALUE); + } + + /** + * Creates a <tt>LinkedBlockingQueue</tt> with the given (fixed) capacity. + * + * @param capacity the capacity of this queue + * @throws IllegalArgumentException if <tt>capacity</tt> is not greater + * than zero + */ + public LinkedBlockingQueue(int capacity) { + if (capacity <= 0) throw new IllegalArgumentException(); + this.capacity = capacity; + last = head = new Node<E>(null); + } + + /** + * Creates a <tt>LinkedBlockingQueue</tt> with a capacity of + * {@link Integer#MAX_VALUE}, initially containing the elements of the + * given collection, + * added in traversal order of the collection's iterator. + * + * @param c the collection of elements to initially contain + * @throws NullPointerException if the specified collection or any + * of its elements are null + */ + public LinkedBlockingQueue(Collection<? extends E> c) { + this(Integer.MAX_VALUE); + for (E e : c) + add(e); + } + + + // this doc comment is overridden to remove the reference to collections + // greater in size than Integer.MAX_VALUE + /** + * Returns the number of elements in this queue. + * + * @return the number of elements in this queue + */ + public int size() { + return count.get(); + } + + // this doc comment is a modified copy of the inherited doc comment, + // without the reference to unlimited queues. + /** + * Returns the number of additional elements that this queue can ideally + * (in the absence of memory or resource constraints) accept without + * blocking. This is always equal to the initial capacity of this queue + * less the current <tt>size</tt> of this queue. + * + * <p>Note that you <em>cannot</em> always tell if an attempt to insert + * an element will succeed by inspecting <tt>remainingCapacity</tt> + * because it may be the case that another thread is about to + * insert or remove an element. + */ + public int remainingCapacity() { + return capacity - count.get(); + } + + /** + * Inserts the specified element at the tail of this queue, waiting if + * necessary for space to become available. + * + * @throws InterruptedException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + */ + public void put(E e) throws InterruptedException { + if (e == null) throw new NullPointerException(); + // Note: convention in all put/take/etc is to preset + // local var holding count negative to indicate failure unless set. + int c = -1; + final ReentrantLock putLock = this.putLock; + final AtomicInteger count = this.count; + putLock.lockInterruptibly(); + try { + /* + * Note that count is used in wait guard even though it is + * not protected by lock. This works because count can + * only decrease at this point (all other puts are shut + * out by lock), and we (or some other waiting put) are + * signalled if it ever changes from + * capacity. Similarly for all other uses of count in + * other wait guards. + */ + try { + while (count.get() == capacity) + notFull.await(); + } catch (InterruptedException ie) { + notFull.signal(); // propagate to a non-interrupted thread + throw ie; + } + insert(e); + c = count.getAndIncrement(); + if (c + 1 < capacity) + notFull.signal(); + } finally { + putLock.unlock(); + } + if (c == 0) + signalNotEmpty(); + } + + /** + * Inserts the specified element at the tail of this queue, waiting if + * necessary up to the specified wait time for space to become available. + * + * @return <tt>true</tt> if successful, or <tt>false</tt> if + * the specified waiting time elapses before space is available. + * @throws InterruptedException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + */ + public boolean offer(E e, long timeout, TimeUnit unit) + throws InterruptedException { + + if (e == null) throw new NullPointerException(); + long nanos = unit.toNanos(timeout); + int c = -1; + final ReentrantLock putLock = this.putLock; + final AtomicInteger count = this.count; + putLock.lockInterruptibly(); + try { + for (;;) { + if (count.get() < capacity) { + insert(e); + c = count.getAndIncrement(); + if (c + 1 < capacity) + notFull.signal(); + break; + } + if (nanos <= 0) + return false; + try { + nanos = notFull.awaitNanos(nanos); + } catch (InterruptedException ie) { + notFull.signal(); // propagate to a non-interrupted thread + throw ie; + } + } + } finally { + putLock.unlock(); + } + if (c == 0) + signalNotEmpty(); + return true; + } + + /** + * Inserts the specified element at the tail of this queue if it is + * possible to do so immediately without exceeding the queue's capacity, + * returning <tt>true</tt> upon success and <tt>false</tt> if this queue + * is full. + * When using a capacity-restricted queue, this method is generally + * preferable to method {@link BlockingQueue#add add}, which can fail to + * insert an element only by throwing an exception. + * + * @throws NullPointerException if the specified element is null + */ + public boolean offer(E e) { + if (e == null) throw new NullPointerException(); + final AtomicInteger count = this.count; + if (count.get() == capacity) + return false; + int c = -1; + final ReentrantLock putLock = this.putLock; + putLock.lock(); + try { + if (count.get() < capacity) { + insert(e); + c = count.getAndIncrement(); + if (c + 1 < capacity) + notFull.signal(); + } + } finally { + putLock.unlock(); + } + if (c == 0) + signalNotEmpty(); + return c >= 0; + } + + + public E take() throws InterruptedException { + E x; + int c = -1; + final AtomicInteger count = this.count; + final ReentrantLock takeLock = this.takeLock; + takeLock.lockInterruptibly(); + try { + try { + while (count.get() == 0) + notEmpty.await(); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to a non-interrupted thread + throw ie; + } + + x = extract(); + c = count.getAndDecrement(); + if (c > 1) + notEmpty.signal(); + } finally { + takeLock.unlock(); + } + if (c == capacity) + signalNotFull(); + return x; + } + + public E poll(long timeout, TimeUnit unit) throws InterruptedException { + E x = null; + int c = -1; + long nanos = unit.toNanos(timeout); + final AtomicInteger count = this.count; + final ReentrantLock takeLock = this.takeLock; + takeLock.lockInterruptibly(); + try { + for (;;) { + if (count.get() > 0) { + x = extract(); + c = count.getAndDecrement(); + if (c > 1) + notEmpty.signal(); + break; + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to a non-interrupted thread + throw ie; + } + } + } finally { + takeLock.unlock(); + } + if (c == capacity) + signalNotFull(); + return x; + } + + public E poll() { + final AtomicInteger count = this.count; + if (count.get() == 0) + return null; + E x = null; + int c = -1; + final ReentrantLock takeLock = this.takeLock; + takeLock.lock(); + try { + if (count.get() > 0) { + x = extract(); + c = count.getAndDecrement(); + if (c > 1) + notEmpty.signal(); + } + } finally { + takeLock.unlock(); + } + if (c == capacity) + signalNotFull(); + return x; + } + + + public E peek() { + if (count.get() == 0) + return null; + final ReentrantLock takeLock = this.takeLock; + takeLock.lock(); + try { + Node<E> first = head.next; + if (first == null) + return null; + else + return first.item; + } finally { + takeLock.unlock(); + } + } + + /** + * Removes a single instance of the specified element from this queue, + * if it is present. More formally, removes an element <tt>e</tt> such + * that <tt>o.equals(e)</tt>, if this queue contains one or more such + * elements. + * Returns <tt>true</tt> if this queue contained the specified element + * (or equivalently, if this queue changed as a result of the call). + * + * @param o element to be removed from this queue, if present + * @return <tt>true</tt> if this queue changed as a result of the call + */ + public boolean remove(Object o) { + if (o == null) return false; + boolean removed = false; + fullyLock(); + try { + Node<E> trail = head; + Node<E> p = head.next; + while (p != null) { + if (o.equals(p.item)) { + removed = true; + break; + } + trail = p; + p = p.next; + } + if (removed) { + p.item = null; + trail.next = p.next; + if (last == p) + last = trail; + if (count.getAndDecrement() == capacity) + notFull.signalAll(); + } + } finally { + fullyUnlock(); + } + return removed; + } + + /** + * Returns an array containing all of the elements in this queue, in + * proper sequence. + * + * <p>The returned array will be "safe" in that no references to it are + * maintained by this queue. (In other words, this method must allocate + * a new array). The caller is thus free to modify the returned array. + * + * <p>This method acts as bridge between array-based and collection-based + * APIs. + * + * @return an array containing all of the elements in this queue + */ + public Object[] toArray() { + fullyLock(); + try { + int size = count.get(); + Object[] a = new Object[size]; + int k = 0; + for (Node<E> p = head.next; p != null; p = p.next) + a[k++] = p.item; + return a; + } finally { + fullyUnlock(); + } + } + + /** + * Returns an array containing all of the elements in this queue, in + * proper sequence; the runtime type of the returned array is that of + * the specified array. If the queue fits in the specified array, it + * is returned therein. Otherwise, a new array is allocated with the + * runtime type of the specified array and the size of this queue. + * + * <p>If this queue fits in the specified array with room to spare + * (i.e., the array has more elements than this queue), the element in + * the array immediately following the end of the queue is set to + * <tt>null</tt>. + * + * <p>Like the {@link #toArray()} method, this method acts as bridge between + * array-based and collection-based APIs. Further, this method allows + * precise control over the runtime type of the output array, and may, + * under certain circumstances, be used to save allocation costs. + * + * <p>Suppose <tt>x</tt> is a queue known to contain only strings. + * The following code can be used to dump the queue into a newly + * allocated array of <tt>String</tt>: + * + * <pre> + * String[] y = x.toArray(new String[0]);</pre> + * + * Note that <tt>toArray(new Object[0])</tt> is identical in function to + * <tt>toArray()</tt>. + * + * @param a the array into which the elements of the queue are to + * be stored, if it is big enough; otherwise, a new array of the + * same runtime type is allocated for this purpose + * @return an array containing all of the elements in this queue + * @throws ArrayStoreException if the runtime type of the specified array + * is not a supertype of the runtime type of every element in + * this queue + * @throws NullPointerException if the specified array is null + */ + public <T> T[] toArray(T[] a) { + fullyLock(); + try { + int size = count.get(); + if (a.length < size) + a = (T[])java.lang.reflect.Array.newInstance + (a.getClass().getComponentType(), size); + + int k = 0; + for (Node p = head.next; p != null; p = p.next) + a[k++] = (T)p.item; + if (a.length > k) + a[k] = null; + return a; + } finally { + fullyUnlock(); + } + } + + public String toString() { + fullyLock(); + try { + return super.toString(); + } finally { + fullyUnlock(); + } + } + + /** + * Atomically removes all of the elements from this queue. + * The queue will be empty after this call returns. + */ + public void clear() { + fullyLock(); + try { + head.next = null; + assert head.item == null; + last = head; + if (count.getAndSet(0) == capacity) + notFull.signalAll(); + } finally { + fullyUnlock(); + } + } + + /** + * @throws UnsupportedOperationException {@inheritDoc} + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + * @throws IllegalArgumentException {@inheritDoc} + */ + public int drainTo(Collection<? super E> c) { + if (c == null) + throw new NullPointerException(); + if (c == this) + throw new IllegalArgumentException(); + Node<E> first; + fullyLock(); + try { + first = head.next; + head.next = null; + assert head.item == null; + last = head; + if (count.getAndSet(0) == capacity) + notFull.signalAll(); + } finally { + fullyUnlock(); + } + // Transfer the elements outside of locks + int n = 0; + for (Node<E> p = first; p != null; p = p.next) { + c.add(p.item); + p.item = null; + ++n; + } + return n; + } + + /** + * @throws UnsupportedOperationException {@inheritDoc} + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + * @throws IllegalArgumentException {@inheritDoc} + */ + public int drainTo(Collection<? super E> c, int maxElements) { + if (c == null) + throw new NullPointerException(); + if (c == this) + throw new IllegalArgumentException(); + fullyLock(); + try { + int n = 0; + Node<E> p = head.next; + while (p != null && n < maxElements) { + c.add(p.item); + p.item = null; + p = p.next; + ++n; + } + if (n != 0) { + head.next = p; + assert head.item == null; + if (p == null) + last = head; + if (count.getAndAdd(-n) == capacity) + notFull.signalAll(); + } + return n; + } finally { + fullyUnlock(); + } + } + + /** + * Returns an iterator over the elements in this queue in proper sequence. + * The returned <tt>Iterator</tt> is a "weakly consistent" iterator that + * will never throw {@link ConcurrentModificationException}, + * and guarantees to traverse elements as they existed upon + * construction of the iterator, and may (but is not guaranteed to) + * reflect any modifications subsequent to construction. + * + * @return an iterator over the elements in this queue in proper sequence + */ + public Iterator<E> iterator() { + return new Itr(); + } + + private class Itr implements Iterator<E> { + /* + * Basic weak-consistent iterator. At all times hold the next + * item to hand out so that if hasNext() reports true, we will + * still have it to return even if lost race with a take etc. + */ + private Node<E> current; + private Node<E> lastRet; + private E currentElement; + + Itr() { + final ReentrantLock putLock = LinkedBlockingQueue.this.putLock; + final ReentrantLock takeLock = LinkedBlockingQueue.this.takeLock; + putLock.lock(); + takeLock.lock(); + try { + current = head.next; + if (current != null) + currentElement = current.item; + } finally { + takeLock.unlock(); + putLock.unlock(); + } + } + + public boolean hasNext() { + return current != null; + } + + public E next() { + final ReentrantLock putLock = LinkedBlockingQueue.this.putLock; + final ReentrantLock takeLock = LinkedBlockingQueue.this.takeLock; + putLock.lock(); + takeLock.lock(); + try { + if (current == null) + throw new NoSuchElementException(); + E x = currentElement; + lastRet = current; + current = current.next; + if (current != null) + currentElement = current.item; + return x; + } finally { + takeLock.unlock(); + putLock.unlock(); + } + } + + public void remove() { + if (lastRet == null) + throw new IllegalStateException(); + final ReentrantLock putLock = LinkedBlockingQueue.this.putLock; + final ReentrantLock takeLock = LinkedBlockingQueue.this.takeLock; + putLock.lock(); + takeLock.lock(); + try { + Node<E> node = lastRet; + lastRet = null; + Node<E> trail = head; + Node<E> p = head.next; + while (p != null && p != node) { + trail = p; + p = p.next; + } + if (p == node) { + p.item = null; + trail.next = p.next; + if (last == p) + last = trail; + int c = count.getAndDecrement(); + if (c == capacity) + notFull.signalAll(); + } + } finally { + takeLock.unlock(); + putLock.unlock(); + } + } + } + + /** + * Save the state to a stream (that is, serialize it). + * + * @serialData The capacity is emitted (int), followed by all of + * its elements (each an <tt>Object</tt>) in the proper order, + * followed by a null + * @param s the stream + */ + private void writeObject(java.io.ObjectOutputStream s) + throws java.io.IOException { + + fullyLock(); + try { + // Write out any hidden stuff, plus capacity + s.defaultWriteObject(); + + // Write out all elements in the proper order. + for (Node<E> p = head.next; p != null; p = p.next) + s.writeObject(p.item); + + // Use trailing null as sentinel + s.writeObject(null); + } finally { + fullyUnlock(); + } + } + + /** + * Reconstitute this queue instance from a stream (that is, + * deserialize it). + * @param s the stream + */ + private void readObject(java.io.ObjectInputStream s) + throws java.io.IOException, ClassNotFoundException { + // Read in capacity, and any hidden stuff + s.defaultReadObject(); + + count.set(0); + last = head = new Node<E>(null); + + // Read in all elements and place in queue + for (;;) { + E item = (E)s.readObject(); + if (item == null) + break; + add(item); + } + } +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/PriorityBlockingQueue.java b/libjava/classpath/external/jsr166/java/util/concurrent/PriorityBlockingQueue.java new file mode 100644 index 000000000..9466aa477 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/PriorityBlockingQueue.java @@ -0,0 +1,563 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; + +import java.util.concurrent.locks.*; +import java.util.*; + +/** + * An unbounded {@linkplain BlockingQueue blocking queue} that uses + * the same ordering rules as class {@link PriorityQueue} and supplies + * blocking retrieval operations. While this queue is logically + * unbounded, attempted additions may fail due to resource exhaustion + * (causing <tt>OutOfMemoryError</tt>). This class does not permit + * <tt>null</tt> elements. A priority queue relying on {@linkplain + * Comparable natural ordering} also does not permit insertion of + * non-comparable objects (doing so results in + * <tt>ClassCastException</tt>). + * + * <p>This class and its iterator implement all of the + * <em>optional</em> methods of the {@link Collection} and {@link + * Iterator} interfaces. The Iterator provided in method {@link + * #iterator()} is <em>not</em> guaranteed to traverse the elements of + * the PriorityBlockingQueue in any particular order. If you need + * ordered traversal, consider using + * <tt>Arrays.sort(pq.toArray())</tt>. Also, method <tt>drainTo</tt> + * can be used to <em>remove</em> some or all elements in priority + * order and place them in another collection. + * + * <p>Operations on this class make no guarantees about the ordering + * of elements with equal priority. If you need to enforce an + * ordering, you can define custom classes or comparators that use a + * secondary key to break ties in primary priority values. For + * example, here is a class that applies first-in-first-out + * tie-breaking to comparable elements. To use it, you would insert a + * <tt>new FIFOEntry(anEntry)</tt> instead of a plain entry object. + * + * <pre> + * class FIFOEntry<E extends Comparable<? super E>> + * implements Comparable<FIFOEntry<E>> { + * final static AtomicLong seq = new AtomicLong(); + * final long seqNum; + * final E entry; + * public FIFOEntry(E entry) { + * seqNum = seq.getAndIncrement(); + * this.entry = entry; + * } + * public E getEntry() { return entry; } + * public int compareTo(FIFOEntry<E> other) { + * int res = entry.compareTo(other.entry); + * if (res == 0 && other.entry != this.entry) + * res = (seqNum < other.seqNum ? -1 : 1); + * return res; + * } + * }</pre> + * + * <p>This class is a member of the + * <a href="{@docRoot}/../technotes/guides/collections/index.html"> + * Java Collections Framework</a>. + * + * @since 1.5 + * @author Doug Lea + * @param <E> the type of elements held in this collection + */ +public class PriorityBlockingQueue<E> extends AbstractQueue<E> + implements BlockingQueue<E>, java.io.Serializable { + private static final long serialVersionUID = 5595510919245408276L; + + private final PriorityQueue<E> q; + private final ReentrantLock lock = new ReentrantLock(true); + private final Condition notEmpty = lock.newCondition(); + + /** + * Creates a <tt>PriorityBlockingQueue</tt> with the default + * initial capacity (11) that orders its elements according to + * their {@linkplain Comparable natural ordering}. + */ + public PriorityBlockingQueue() { + q = new PriorityQueue<E>(); + } + + /** + * Creates a <tt>PriorityBlockingQueue</tt> with the specified + * initial capacity that orders its elements according to their + * {@linkplain Comparable natural ordering}. + * + * @param initialCapacity the initial capacity for this priority queue + * @throws IllegalArgumentException if <tt>initialCapacity</tt> is less + * than 1 + */ + public PriorityBlockingQueue(int initialCapacity) { + q = new PriorityQueue<E>(initialCapacity, null); + } + + /** + * Creates a <tt>PriorityBlockingQueue</tt> with the specified initial + * capacity that orders its elements according to the specified + * comparator. + * + * @param initialCapacity the initial capacity for this priority queue + * @param comparator the comparator that will be used to order this + * priority queue. If {@code null}, the {@linkplain Comparable + * natural ordering} of the elements will be used. + * @throws IllegalArgumentException if <tt>initialCapacity</tt> is less + * than 1 + */ + public PriorityBlockingQueue(int initialCapacity, + Comparator<? super E> comparator) { + q = new PriorityQueue<E>(initialCapacity, comparator); + } + + /** + * Creates a <tt>PriorityBlockingQueue</tt> containing the elements + * in the specified collection. If the specified collection is a + * {@link SortedSet} or a {@link PriorityQueue}, this + * priority queue will be ordered according to the same ordering. + * Otherwise, this priority queue will be ordered according to the + * {@linkplain Comparable natural ordering} of its elements. + * + * @param c the collection whose elements are to be placed + * into this priority queue + * @throws ClassCastException if elements of the specified collection + * cannot be compared to one another according to the priority + * queue's ordering + * @throws NullPointerException if the specified collection or any + * of its elements are null + */ + public PriorityBlockingQueue(Collection<? extends E> c) { + q = new PriorityQueue<E>(c); + } + + /** + * Inserts the specified element into this priority queue. + * + * @param e the element to add + * @return <tt>true</tt> (as specified by {@link Collection#add}) + * @throws ClassCastException if the specified element cannot be compared + * with elements currently in the priority queue according to the + * priority queue's ordering + * @throws NullPointerException if the specified element is null + */ + public boolean add(E e) { + return offer(e); + } + + /** + * Inserts the specified element into this priority queue. + * + * @param e the element to add + * @return <tt>true</tt> (as specified by {@link Queue#offer}) + * @throws ClassCastException if the specified element cannot be compared + * with elements currently in the priority queue according to the + * priority queue's ordering + * @throws NullPointerException if the specified element is null + */ + public boolean offer(E e) { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + boolean ok = q.offer(e); + assert ok; + notEmpty.signal(); + return true; + } finally { + lock.unlock(); + } + } + + /** + * Inserts the specified element into this priority queue. As the queue is + * unbounded this method will never block. + * + * @param e the element to add + * @throws ClassCastException if the specified element cannot be compared + * with elements currently in the priority queue according to the + * priority queue's ordering + * @throws NullPointerException if the specified element is null + */ + public void put(E e) { + offer(e); // never need to block + } + + /** + * Inserts the specified element into this priority queue. As the queue is + * unbounded this method will never block. + * + * @param e the element to add + * @param timeout This parameter is ignored as the method never blocks + * @param unit This parameter is ignored as the method never blocks + * @return <tt>true</tt> + * @throws ClassCastException if the specified element cannot be compared + * with elements currently in the priority queue according to the + * priority queue's ordering + * @throws NullPointerException if the specified element is null + */ + public boolean offer(E e, long timeout, TimeUnit unit) { + return offer(e); // never need to block + } + + public E poll() { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + return q.poll(); + } finally { + lock.unlock(); + } + } + + public E take() throws InterruptedException { + final ReentrantLock lock = this.lock; + lock.lockInterruptibly(); + try { + try { + while (q.size() == 0) + notEmpty.await(); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + E x = q.poll(); + assert x != null; + return x; + } finally { + lock.unlock(); + } + } + + public E poll(long timeout, TimeUnit unit) throws InterruptedException { + long nanos = unit.toNanos(timeout); + final ReentrantLock lock = this.lock; + lock.lockInterruptibly(); + try { + for (;;) { + E x = q.poll(); + if (x != null) + return x; + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + } + } finally { + lock.unlock(); + } + } + + public E peek() { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + return q.peek(); + } finally { + lock.unlock(); + } + } + + /** + * Returns the comparator used to order the elements in this queue, + * or <tt>null</tt> if this queue uses the {@linkplain Comparable + * natural ordering} of its elements. + * + * @return the comparator used to order the elements in this queue, + * or <tt>null</tt> if this queue uses the natural + * ordering of its elements + */ + public Comparator<? super E> comparator() { + return q.comparator(); + } + + public int size() { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + return q.size(); + } finally { + lock.unlock(); + } + } + + /** + * Always returns <tt>Integer.MAX_VALUE</tt> because + * a <tt>PriorityBlockingQueue</tt> is not capacity constrained. + * @return <tt>Integer.MAX_VALUE</tt> + */ + public int remainingCapacity() { + return Integer.MAX_VALUE; + } + + /** + * Removes a single instance of the specified element from this queue, + * if it is present. More formally, removes an element {@code e} such + * that {@code o.equals(e)}, if this queue contains one or more such + * elements. Returns {@code true} if and only if this queue contained + * the specified element (or equivalently, if this queue changed as a + * result of the call). + * + * @param o element to be removed from this queue, if present + * @return <tt>true</tt> if this queue changed as a result of the call + */ + public boolean remove(Object o) { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + return q.remove(o); + } finally { + lock.unlock(); + } + } + + /** + * Returns {@code true} if this queue contains the specified element. + * More formally, returns {@code true} if and only if this queue contains + * at least one element {@code e} such that {@code o.equals(e)}. + * + * @param o object to be checked for containment in this queue + * @return <tt>true</tt> if this queue contains the specified element + */ + public boolean contains(Object o) { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + return q.contains(o); + } finally { + lock.unlock(); + } + } + + /** + * Returns an array containing all of the elements in this queue. + * The returned array elements are in no particular order. + * + * <p>The returned array will be "safe" in that no references to it are + * maintained by this queue. (In other words, this method must allocate + * a new array). The caller is thus free to modify the returned array. + * + * <p>This method acts as bridge between array-based and collection-based + * APIs. + * + * @return an array containing all of the elements in this queue + */ + public Object[] toArray() { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + return q.toArray(); + } finally { + lock.unlock(); + } + } + + + public String toString() { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + return q.toString(); + } finally { + lock.unlock(); + } + } + + /** + * @throws UnsupportedOperationException {@inheritDoc} + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + * @throws IllegalArgumentException {@inheritDoc} + */ + public int drainTo(Collection<? super E> c) { + if (c == null) + throw new NullPointerException(); + if (c == this) + throw new IllegalArgumentException(); + final ReentrantLock lock = this.lock; + lock.lock(); + try { + int n = 0; + E e; + while ( (e = q.poll()) != null) { + c.add(e); + ++n; + } + return n; + } finally { + lock.unlock(); + } + } + + /** + * @throws UnsupportedOperationException {@inheritDoc} + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + * @throws IllegalArgumentException {@inheritDoc} + */ + public int drainTo(Collection<? super E> c, int maxElements) { + if (c == null) + throw new NullPointerException(); + if (c == this) + throw new IllegalArgumentException(); + if (maxElements <= 0) + return 0; + final ReentrantLock lock = this.lock; + lock.lock(); + try { + int n = 0; + E e; + while (n < maxElements && (e = q.poll()) != null) { + c.add(e); + ++n; + } + return n; + } finally { + lock.unlock(); + } + } + + /** + * Atomically removes all of the elements from this queue. + * The queue will be empty after this call returns. + */ + public void clear() { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + q.clear(); + } finally { + lock.unlock(); + } + } + + /** + * Returns an array containing all of the elements in this queue; the + * runtime type of the returned array is that of the specified array. + * The returned array elements are in no particular order. + * If the queue fits in the specified array, it is returned therein. + * Otherwise, a new array is allocated with the runtime type of the + * specified array and the size of this queue. + * + * <p>If this queue fits in the specified array with room to spare + * (i.e., the array has more elements than this queue), the element in + * the array immediately following the end of the queue is set to + * <tt>null</tt>. + * + * <p>Like the {@link #toArray()} method, this method acts as bridge between + * array-based and collection-based APIs. Further, this method allows + * precise control over the runtime type of the output array, and may, + * under certain circumstances, be used to save allocation costs. + * + * <p>Suppose <tt>x</tt> is a queue known to contain only strings. + * The following code can be used to dump the queue into a newly + * allocated array of <tt>String</tt>: + * + * <pre> + * String[] y = x.toArray(new String[0]);</pre> + * + * Note that <tt>toArray(new Object[0])</tt> is identical in function to + * <tt>toArray()</tt>. + * + * @param a the array into which the elements of the queue are to + * be stored, if it is big enough; otherwise, a new array of the + * same runtime type is allocated for this purpose + * @return an array containing all of the elements in this queue + * @throws ArrayStoreException if the runtime type of the specified array + * is not a supertype of the runtime type of every element in + * this queue + * @throws NullPointerException if the specified array is null + */ + public <T> T[] toArray(T[] a) { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + return q.toArray(a); + } finally { + lock.unlock(); + } + } + + /** + * Returns an iterator over the elements in this queue. The + * iterator does not return the elements in any particular order. + * The returned <tt>Iterator</tt> is a "weakly consistent" + * iterator that will never throw {@link + * ConcurrentModificationException}, and guarantees to traverse + * elements as they existed upon construction of the iterator, and + * may (but is not guaranteed to) reflect any modifications + * subsequent to construction. + * + * @return an iterator over the elements in this queue + */ + public Iterator<E> iterator() { + return new Itr(toArray()); + } + + /** + * Snapshot iterator that works off copy of underlying q array. + */ + private class Itr implements Iterator<E> { + final Object[] array; // Array of all elements + int cursor; // index of next element to return; + int lastRet; // index of last element, or -1 if no such + + Itr(Object[] array) { + lastRet = -1; + this.array = array; + } + + public boolean hasNext() { + return cursor < array.length; + } + + public E next() { + if (cursor >= array.length) + throw new NoSuchElementException(); + lastRet = cursor; + return (E)array[cursor++]; + } + + public void remove() { + if (lastRet < 0) + throw new IllegalStateException(); + Object x = array[lastRet]; + lastRet = -1; + // Traverse underlying queue to find == element, + // not just a .equals element. + lock.lock(); + try { + for (Iterator it = q.iterator(); it.hasNext(); ) { + if (it.next() == x) { + it.remove(); + return; + } + } + } finally { + lock.unlock(); + } + } + } + + /** + * Saves the state to a stream (that is, serializes it). This + * merely wraps default serialization within lock. The + * serialization strategy for items is left to underlying + * Queue. Note that locking is not needed on deserialization, so + * readObject is not defined, just relying on default. + */ + private void writeObject(java.io.ObjectOutputStream s) + throws java.io.IOException { + lock.lock(); + try { + s.defaultWriteObject(); + } finally { + lock.unlock(); + } + } + +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/RejectedExecutionException.java b/libjava/classpath/external/jsr166/java/util/concurrent/RejectedExecutionException.java new file mode 100644 index 000000000..30b043d66 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/RejectedExecutionException.java @@ -0,0 +1,62 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; + +/** + * Exception thrown by an {@link Executor} when a task cannot be + * accepted for execution. + * + * @since 1.5 + * @author Doug Lea + */ +public class RejectedExecutionException extends RuntimeException { + private static final long serialVersionUID = -375805702767069545L; + + /** + * Constructs a <tt>RejectedExecutionException</tt> with no detail message. + * The cause is not initialized, and may subsequently be + * initialized by a call to {@link #initCause(Throwable) initCause}. + */ + public RejectedExecutionException() { } + + /** + * Constructs a <tt>RejectedExecutionException</tt> with the + * specified detail message. The cause is not initialized, and may + * subsequently be initialized by a call to {@link + * #initCause(Throwable) initCause}. + * + * @param message the detail message + */ + public RejectedExecutionException(String message) { + super(message); + } + + /** + * Constructs a <tt>RejectedExecutionException</tt> with the + * specified detail message and cause. + * + * @param message the detail message + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method) + */ + public RejectedExecutionException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructs a <tt>RejectedExecutionException</tt> with the + * specified cause. The detail message is set to: <pre> (cause == + * null ? null : cause.toString())</pre> (which typically contains + * the class and detail message of <tt>cause</tt>). + * + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method) + */ + public RejectedExecutionException(Throwable cause) { + super(cause); + } +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/RejectedExecutionHandler.java b/libjava/classpath/external/jsr166/java/util/concurrent/RejectedExecutionHandler.java new file mode 100644 index 000000000..4b4bbeab1 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/RejectedExecutionHandler.java @@ -0,0 +1,33 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; + +/** + * A handler for tasks that cannot be executed by a {@link + * ThreadPoolExecutor}. + * + * @since 1.5 + * @author Doug Lea + */ +public interface RejectedExecutionHandler { + + /** + * Method that may be invoked by a {@link ThreadPoolExecutor} when + * <tt>execute</tt> cannot accept a task. This may occur when no + * more threads or queue slots are available because their bounds + * would be exceeded, or upon shutdown of the Executor. + * + * In the absence other alternatives, the method may throw an + * unchecked {@link RejectedExecutionException}, which will be + * propagated to the caller of <tt>execute</tt>. + * + * @param r the runnable task requested to be executed + * @param executor the executor attempting to execute this task + * @throws RejectedExecutionException if there is no remedy + */ + void rejectedExecution(Runnable r, ThreadPoolExecutor executor); +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/RunnableFuture.java b/libjava/classpath/external/jsr166/java/util/concurrent/RunnableFuture.java new file mode 100644 index 000000000..d74211d13 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/RunnableFuture.java @@ -0,0 +1,25 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; + +/** + * A {@link Future} that is {@link Runnable}. Successful execution of + * the <tt>run</tt> method causes completion of the <tt>Future</tt> + * and allows access to its results. + * @see FutureTask + * @see Executor + * @since 1.6 + * @author Doug Lea + * @param <V> The result type returned by this Future's <tt>get</tt> method + */ +public interface RunnableFuture<V> extends Runnable, Future<V> { + /** + * Sets this Future to the result of its computation + * unless it has been cancelled. + */ + void run(); +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/RunnableScheduledFuture.java b/libjava/classpath/external/jsr166/java/util/concurrent/RunnableScheduledFuture.java new file mode 100644 index 000000000..0e8cc328c --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/RunnableScheduledFuture.java @@ -0,0 +1,29 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; + +/** + * A {@link ScheduledFuture} that is {@link Runnable}. Successful + * execution of the <tt>run</tt> method causes completion of the + * <tt>Future</tt> and allows access to its results. + * @see FutureTask + * @see Executor + * @since 1.6 + * @author Doug Lea + * @param <V> The result type returned by this Future's <tt>get</tt> method + */ +public interface RunnableScheduledFuture<V> extends RunnableFuture<V>, ScheduledFuture<V> { + + /** + * Returns true if this is a periodic task. A periodic task may + * re-run according to some schedule. A non-periodic task can be + * run only once. + * + * @return true if this task is periodic + */ + boolean isPeriodic(); +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/ScheduledExecutorService.java b/libjava/classpath/external/jsr166/java/util/concurrent/ScheduledExecutorService.java new file mode 100644 index 000000000..c170c4a52 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/ScheduledExecutorService.java @@ -0,0 +1,159 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; +import java.util.concurrent.atomic.*; +import java.util.*; + +/** + * An {@link ExecutorService} that can schedule commands to run after a given + * delay, or to execute periodically. + * + * <p> The <tt>schedule</tt> methods create tasks with various delays + * and return a task object that can be used to cancel or check + * execution. The <tt>scheduleAtFixedRate</tt> and + * <tt>scheduleWithFixedDelay</tt> methods create and execute tasks + * that run periodically until cancelled. + * + * <p> Commands submitted using the {@link Executor#execute} and + * {@link ExecutorService} <tt>submit</tt> methods are scheduled with + * a requested delay of zero. Zero and negative delays (but not + * periods) are also allowed in <tt>schedule</tt> methods, and are + * treated as requests for immediate execution. + * + * <p>All <tt>schedule</tt> methods accept <em>relative</em> delays and + * periods as arguments, not absolute times or dates. It is a simple + * matter to transform an absolute time represented as a {@link + * java.util.Date} to the required form. For example, to schedule at + * a certain future <tt>date</tt>, you can use: <tt>schedule(task, + * date.getTime() - System.currentTimeMillis(), + * TimeUnit.MILLISECONDS)</tt>. Beware however that expiration of a + * relative delay need not coincide with the current <tt>Date</tt> at + * which the task is enabled due to network time synchronization + * protocols, clock drift, or other factors. + * + * The {@link Executors} class provides convenient factory methods for + * the ScheduledExecutorService implementations provided in this package. + * + * <h3>Usage Example</h3> + * + * Here is a class with a method that sets up a ScheduledExecutorService + * to beep every ten seconds for an hour: + * + * <pre> + * import static java.util.concurrent.TimeUnit.*; + * class BeeperControl { + * private final ScheduledExecutorService scheduler = + * Executors.newScheduledThreadPool(1); + * + * public void beepForAnHour() { + * final Runnable beeper = new Runnable() { + * public void run() { System.out.println("beep"); } + * }; + * final ScheduledFuture<?> beeperHandle = + * scheduler.scheduleAtFixedRate(beeper, 10, 10, SECONDS); + * scheduler.schedule(new Runnable() { + * public void run() { beeperHandle.cancel(true); } + * }, 60 * 60, SECONDS); + * } + * } + * </pre> + * + * @since 1.5 + * @author Doug Lea + */ +public interface ScheduledExecutorService extends ExecutorService { + + /** + * Creates and executes a one-shot action that becomes enabled + * after the given delay. + * + * @param command the task to execute + * @param delay the time from now to delay execution + * @param unit the time unit of the delay parameter + * @return a ScheduledFuture representing pending completion of + * the task and whose <tt>get()</tt> method will return + * <tt>null</tt> upon completion + * @throws RejectedExecutionException if the task cannot be + * scheduled for execution + * @throws NullPointerException if command is null + */ + public ScheduledFuture<?> schedule(Runnable command, + long delay, TimeUnit unit); + + /** + * Creates and executes a ScheduledFuture that becomes enabled after the + * given delay. + * + * @param callable the function to execute + * @param delay the time from now to delay execution + * @param unit the time unit of the delay parameter + * @return a ScheduledFuture that can be used to extract result or cancel + * @throws RejectedExecutionException if the task cannot be + * scheduled for execution + * @throws NullPointerException if callable is null + */ + public <V> ScheduledFuture<V> schedule(Callable<V> callable, + long delay, TimeUnit unit); + + /** + * Creates and executes a periodic action that becomes enabled first + * after the given initial delay, and subsequently with the given + * period; that is executions will commence after + * <tt>initialDelay</tt> then <tt>initialDelay+period</tt>, then + * <tt>initialDelay + 2 * period</tt>, and so on. + * If any execution of the task + * encounters an exception, subsequent executions are suppressed. + * Otherwise, the task will only terminate via cancellation or + * termination of the executor. If any execution of this task + * takes longer than its period, then subsequent executions + * may start late, but will not concurrently execute. + * + * @param command the task to execute + * @param initialDelay the time to delay first execution + * @param period the period between successive executions + * @param unit the time unit of the initialDelay and period parameters + * @return a ScheduledFuture representing pending completion of + * the task, and whose <tt>get()</tt> method will throw an + * exception upon cancellation + * @throws RejectedExecutionException if the task cannot be + * scheduled for execution + * @throws NullPointerException if command is null + * @throws IllegalArgumentException if period less than or equal to zero + */ + public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, + long initialDelay, + long period, + TimeUnit unit); + + /** + * Creates and executes a periodic action that becomes enabled first + * after the given initial delay, and subsequently with the + * given delay between the termination of one execution and the + * commencement of the next. If any execution of the task + * encounters an exception, subsequent executions are suppressed. + * Otherwise, the task will only terminate via cancellation or + * termination of the executor. + * + * @param command the task to execute + * @param initialDelay the time to delay first execution + * @param delay the delay between the termination of one + * execution and the commencement of the next + * @param unit the time unit of the initialDelay and delay parameters + * @return a ScheduledFuture representing pending completion of + * the task, and whose <tt>get()</tt> method will throw an + * exception upon cancellation + * @throws RejectedExecutionException if the task cannot be + * scheduled for execution + * @throws NullPointerException if command is null + * @throws IllegalArgumentException if delay less than or equal to zero + */ + public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, + long initialDelay, + long delay, + TimeUnit unit); + +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/ScheduledFuture.java b/libjava/classpath/external/jsr166/java/util/concurrent/ScheduledFuture.java new file mode 100644 index 000000000..239d681f6 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/ScheduledFuture.java @@ -0,0 +1,19 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; + +/** + * A delayed result-bearing action that can be cancelled. + * Usually a scheduled future is the result of scheduling + * a task with a {@link ScheduledExecutorService}. + * + * @since 1.5 + * @author Doug Lea + * @param <V> The result type returned by this Future + */ +public interface ScheduledFuture<V> extends Delayed, Future<V> { +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/ScheduledThreadPoolExecutor.java b/libjava/classpath/external/jsr166/java/util/concurrent/ScheduledThreadPoolExecutor.java new file mode 100644 index 000000000..f08b9ac2e --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/ScheduledThreadPoolExecutor.java @@ -0,0 +1,626 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; +import java.util.concurrent.atomic.*; +import java.util.*; + +/** + * A {@link ThreadPoolExecutor} that can additionally schedule + * commands to run after a given delay, or to execute + * periodically. This class is preferable to {@link java.util.Timer} + * when multiple worker threads are needed, or when the additional + * flexibility or capabilities of {@link ThreadPoolExecutor} (which + * this class extends) are required. + * + * <p> Delayed tasks execute no sooner than they are enabled, but + * without any real-time guarantees about when, after they are + * enabled, they will commence. Tasks scheduled for exactly the same + * execution time are enabled in first-in-first-out (FIFO) order of + * submission. + * + * <p>While this class inherits from {@link ThreadPoolExecutor}, a few + * of the inherited tuning methods are not useful for it. In + * particular, because it acts as a fixed-sized pool using + * <tt>corePoolSize</tt> threads and an unbounded queue, adjustments + * to <tt>maximumPoolSize</tt> have no useful effect. + * + * <p><b>Extension notes:</b> This class overrides {@link + * AbstractExecutorService} <tt>submit</tt> methods to generate + * internal objects to control per-task delays and scheduling. To + * preserve functionality, any further overrides of these methods in + * subclasses must invoke superclass versions, which effectively + * disables additional task customization. However, this class + * provides alternative protected extension method + * <tt>decorateTask</tt> (one version each for <tt>Runnable</tt> and + * <tt>Callable</tt>) that can be used to customize the concrete task + * types used to execute commands entered via <tt>execute</tt>, + * <tt>submit</tt>, <tt>schedule</tt>, <tt>scheduleAtFixedRate</tt>, + * and <tt>scheduleWithFixedDelay</tt>. By default, a + * <tt>ScheduledThreadPoolExecutor</tt> uses a task type extending + * {@link FutureTask}. However, this may be modified or replaced using + * subclasses of the form: + * + * <pre> + * public class CustomScheduledExecutor extends ScheduledThreadPoolExecutor { + * + * static class CustomTask<V> implements RunnableScheduledFuture<V> { ... } + * + * protected <V> RunnableScheduledFuture<V> decorateTask( + * Runnable r, RunnableScheduledFuture<V> task) { + * return new CustomTask<V>(r, task); + * } + * + * protected <V> RunnableScheduledFuture<V> decorateTask( + * Callable<V> c, RunnableScheduledFuture<V> task) { + * return new CustomTask<V>(c, task); + * } + * // ... add constructors, etc. + * } + * </pre> + * @since 1.5 + * @author Doug Lea + */ +public class ScheduledThreadPoolExecutor + extends ThreadPoolExecutor + implements ScheduledExecutorService { + + /** + * False if should cancel/suppress periodic tasks on shutdown. + */ + private volatile boolean continueExistingPeriodicTasksAfterShutdown; + + /** + * False if should cancel non-periodic tasks on shutdown. + */ + private volatile boolean executeExistingDelayedTasksAfterShutdown = true; + + /** + * Sequence number to break scheduling ties, and in turn to + * guarantee FIFO order among tied entries. + */ + private static final AtomicLong sequencer = new AtomicLong(0); + + /** Base of nanosecond timings, to avoid wrapping */ + private static final long NANO_ORIGIN = System.nanoTime(); + + /** + * Returns nanosecond time offset by origin + */ + final long now() { + return System.nanoTime() - NANO_ORIGIN; + } + + private class ScheduledFutureTask<V> + extends FutureTask<V> implements RunnableScheduledFuture<V> { + + /** Sequence number to break ties FIFO */ + private final long sequenceNumber; + /** The time the task is enabled to execute in nanoTime units */ + private long time; + /** + * Period in nanoseconds for repeating tasks. A positive + * value indicates fixed-rate execution. A negative value + * indicates fixed-delay execution. A value of 0 indicates a + * non-repeating task. + */ + private final long period; + + /** + * Creates a one-shot action with given nanoTime-based trigger time. + */ + ScheduledFutureTask(Runnable r, V result, long ns) { + super(r, result); + this.time = ns; + this.period = 0; + this.sequenceNumber = sequencer.getAndIncrement(); + } + + /** + * Creates a periodic action with given nano time and period. + */ + ScheduledFutureTask(Runnable r, V result, long ns, long period) { + super(r, result); + this.time = ns; + this.period = period; + this.sequenceNumber = sequencer.getAndIncrement(); + } + + /** + * Creates a one-shot action with given nanoTime-based trigger. + */ + ScheduledFutureTask(Callable<V> callable, long ns) { + super(callable); + this.time = ns; + this.period = 0; + this.sequenceNumber = sequencer.getAndIncrement(); + } + + public long getDelay(TimeUnit unit) { + long d = unit.convert(time - now(), TimeUnit.NANOSECONDS); + return d; + } + + public int compareTo(Delayed other) { + if (other == this) // compare zero ONLY if same object + return 0; + if (other instanceof ScheduledFutureTask) { + ScheduledFutureTask<?> x = (ScheduledFutureTask<?>)other; + long diff = time - x.time; + if (diff < 0) + return -1; + else if (diff > 0) + return 1; + else if (sequenceNumber < x.sequenceNumber) + return -1; + else + return 1; + } + long d = (getDelay(TimeUnit.NANOSECONDS) - + other.getDelay(TimeUnit.NANOSECONDS)); + return (d == 0)? 0 : ((d < 0)? -1 : 1); + } + + /** + * Returns true if this is a periodic (not a one-shot) action. + * + * @return true if periodic + */ + public boolean isPeriodic() { + return period != 0; + } + + /** + * Runs a periodic task. + */ + private void runPeriodic() { + boolean ok = ScheduledFutureTask.super.runAndReset(); + boolean down = isShutdown(); + // Reschedule if not cancelled and not shutdown or policy allows + if (ok && (!down || + (getContinueExistingPeriodicTasksAfterShutdownPolicy() && + !isTerminating()))) { + long p = period; + if (p > 0) + time += p; + else + time = now() - p; + // Classpath local: ecj from eclipse 3.1 does not + // compile this. + // ScheduledThreadPoolExecutor.super.getQueue().add(this); + ScheduledThreadPoolExecutor.super.getQueue().add((Runnable) this); + } + // This might have been the final executed delayed + // task. Wake up threads to check. + else if (down) + interruptIdleWorkers(); + } + + /** + * Overrides FutureTask version so as to reset/requeue if periodic. + */ + public void run() { + if (isPeriodic()) + runPeriodic(); + else + ScheduledFutureTask.super.run(); + } + } + + /** + * Specialized variant of ThreadPoolExecutor.execute for delayed tasks. + */ + private void delayedExecute(Runnable command) { + if (isShutdown()) { + reject(command); + return; + } + // Prestart a thread if necessary. We cannot prestart it + // running the task because the task (probably) shouldn't be + // run yet, so thread will just idle until delay elapses. + if (getPoolSize() < getCorePoolSize()) + prestartCoreThread(); + + super.getQueue().add(command); + } + + /** + * Cancels and clears the queue of all tasks that should not be run + * due to shutdown policy. + */ + private void cancelUnwantedTasks() { + boolean keepDelayed = getExecuteExistingDelayedTasksAfterShutdownPolicy(); + boolean keepPeriodic = getContinueExistingPeriodicTasksAfterShutdownPolicy(); + if (!keepDelayed && !keepPeriodic) + super.getQueue().clear(); + else if (keepDelayed || keepPeriodic) { + Object[] entries = super.getQueue().toArray(); + for (int i = 0; i < entries.length; ++i) { + Object e = entries[i]; + if (e instanceof RunnableScheduledFuture) { + RunnableScheduledFuture<?> t = (RunnableScheduledFuture<?>)e; + if (t.isPeriodic()? !keepPeriodic : !keepDelayed) + t.cancel(false); + } + } + entries = null; + purge(); + } + } + + public boolean remove(Runnable task) { + if (!(task instanceof RunnableScheduledFuture)) + return false; + return getQueue().remove(task); + } + + /** + * Modifies or replaces the task used to execute a runnable. + * This method can be used to override the concrete + * class used for managing internal tasks. + * The default implementation simply returns the given task. + * + * @param runnable the submitted Runnable + * @param task the task created to execute the runnable + * @return a task that can execute the runnable + * @since 1.6 + */ + protected <V> RunnableScheduledFuture<V> decorateTask( + Runnable runnable, RunnableScheduledFuture<V> task) { + return task; + } + + /** + * Modifies or replaces the task used to execute a callable. + * This method can be used to override the concrete + * class used for managing internal tasks. + * The default implementation simply returns the given task. + * + * @param callable the submitted Callable + * @param task the task created to execute the callable + * @return a task that can execute the callable + * @since 1.6 + */ + protected <V> RunnableScheduledFuture<V> decorateTask( + Callable<V> callable, RunnableScheduledFuture<V> task) { + return task; + } + + /** + * Creates a new ScheduledThreadPoolExecutor with the given core + * pool size. + * + * @param corePoolSize the number of threads to keep in the pool, + * even if they are idle + * @throws IllegalArgumentException if <tt>corePoolSize < 0</tt> + */ + public ScheduledThreadPoolExecutor(int corePoolSize) { + super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS, + new DelayedWorkQueue()); + } + + /** + * Creates a new ScheduledThreadPoolExecutor with the given + * initial parameters. + * + * @param corePoolSize the number of threads to keep in the pool, + * even if they are idle + * @param threadFactory the factory to use when the executor + * creates a new thread + * @throws IllegalArgumentException if <tt>corePoolSize < 0</tt> + * @throws NullPointerException if threadFactory is null + */ + public ScheduledThreadPoolExecutor(int corePoolSize, + ThreadFactory threadFactory) { + super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS, + new DelayedWorkQueue(), threadFactory); + } + + /** + * Creates a new ScheduledThreadPoolExecutor with the given + * initial parameters. + * + * @param corePoolSize the number of threads to keep in the pool, + * even if they are idle + * @param handler the handler to use when execution is blocked + * because the thread bounds and queue capacities are reached + * @throws IllegalArgumentException if <tt>corePoolSize < 0</tt> + * @throws NullPointerException if handler is null + */ + public ScheduledThreadPoolExecutor(int corePoolSize, + RejectedExecutionHandler handler) { + super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS, + new DelayedWorkQueue(), handler); + } + + /** + * Creates a new ScheduledThreadPoolExecutor with the given + * initial parameters. + * + * @param corePoolSize the number of threads to keep in the pool, + * even if they are idle + * @param threadFactory the factory to use when the executor + * creates a new thread + * @param handler the handler to use when execution is blocked + * because the thread bounds and queue capacities are reached. + * @throws IllegalArgumentException if <tt>corePoolSize < 0</tt> + * @throws NullPointerException if threadFactory or handler is null + */ + public ScheduledThreadPoolExecutor(int corePoolSize, + ThreadFactory threadFactory, + RejectedExecutionHandler handler) { + super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS, + new DelayedWorkQueue(), threadFactory, handler); + } + + public ScheduledFuture<?> schedule(Runnable command, + long delay, + TimeUnit unit) { + if (command == null || unit == null) + throw new NullPointerException(); + long triggerTime = now() + unit.toNanos(delay); + RunnableScheduledFuture<?> t = decorateTask(command, + new ScheduledFutureTask<Boolean>(command, null, triggerTime)); + delayedExecute(t); + return t; + } + + public <V> ScheduledFuture<V> schedule(Callable<V> callable, + long delay, + TimeUnit unit) { + if (callable == null || unit == null) + throw new NullPointerException(); + if (delay < 0) delay = 0; + long triggerTime = now() + unit.toNanos(delay); + RunnableScheduledFuture<V> t = decorateTask(callable, + new ScheduledFutureTask<V>(callable, triggerTime)); + delayedExecute(t); + return t; + } + + public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, + long initialDelay, + long period, + TimeUnit unit) { + if (command == null || unit == null) + throw new NullPointerException(); + if (period <= 0) + throw new IllegalArgumentException(); + if (initialDelay < 0) initialDelay = 0; + long triggerTime = now() + unit.toNanos(initialDelay); + RunnableScheduledFuture<?> t = decorateTask(command, + new ScheduledFutureTask<Object>(command, + null, + triggerTime, + unit.toNanos(period))); + delayedExecute(t); + return t; + } + + public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, + long initialDelay, + long delay, + TimeUnit unit) { + if (command == null || unit == null) + throw new NullPointerException(); + if (delay <= 0) + throw new IllegalArgumentException(); + if (initialDelay < 0) initialDelay = 0; + long triggerTime = now() + unit.toNanos(initialDelay); + RunnableScheduledFuture<?> t = decorateTask(command, + new ScheduledFutureTask<Boolean>(command, + null, + triggerTime, + unit.toNanos(-delay))); + delayedExecute(t); + return t; + } + + + /** + * Executes command with zero required delay. This has effect + * equivalent to <tt>schedule(command, 0, anyUnit)</tt>. Note + * that inspections of the queue and of the list returned by + * <tt>shutdownNow</tt> will access the zero-delayed + * {@link ScheduledFuture}, not the <tt>command</tt> itself. + * + * @param command the task to execute + * @throws RejectedExecutionException at discretion of + * <tt>RejectedExecutionHandler</tt>, if task cannot be accepted + * for execution because the executor has been shut down. + * @throws NullPointerException if command is null + */ + public void execute(Runnable command) { + if (command == null) + throw new NullPointerException(); + schedule(command, 0, TimeUnit.NANOSECONDS); + } + + // Override AbstractExecutorService methods + + public Future<?> submit(Runnable task) { + return schedule(task, 0, TimeUnit.NANOSECONDS); + } + + public <T> Future<T> submit(Runnable task, T result) { + return schedule(Executors.callable(task, result), + 0, TimeUnit.NANOSECONDS); + } + + public <T> Future<T> submit(Callable<T> task) { + return schedule(task, 0, TimeUnit.NANOSECONDS); + } + + /** + * Sets the policy on whether to continue executing existing periodic + * tasks even when this executor has been <tt>shutdown</tt>. In + * this case, these tasks will only terminate upon + * <tt>shutdownNow</tt>, or after setting the policy to + * <tt>false</tt> when already shutdown. This value is by default + * false. + * + * @param value if true, continue after shutdown, else don't. + * @see #getContinueExistingPeriodicTasksAfterShutdownPolicy + */ + public void setContinueExistingPeriodicTasksAfterShutdownPolicy(boolean value) { + continueExistingPeriodicTasksAfterShutdown = value; + if (!value && isShutdown()) + cancelUnwantedTasks(); + } + + /** + * Gets the policy on whether to continue executing existing + * periodic tasks even when this executor has been + * <tt>shutdown</tt>. In this case, these tasks will only + * terminate upon <tt>shutdownNow</tt> or after setting the policy + * to <tt>false</tt> when already shutdown. This value is by + * default false. + * + * @return true if will continue after shutdown + * @see #setContinueExistingPeriodicTasksAfterShutdownPolicy + */ + public boolean getContinueExistingPeriodicTasksAfterShutdownPolicy() { + return continueExistingPeriodicTasksAfterShutdown; + } + + /** + * Sets the policy on whether to execute existing delayed + * tasks even when this executor has been <tt>shutdown</tt>. In + * this case, these tasks will only terminate upon + * <tt>shutdownNow</tt>, or after setting the policy to + * <tt>false</tt> when already shutdown. This value is by default + * true. + * + * @param value if true, execute after shutdown, else don't. + * @see #getExecuteExistingDelayedTasksAfterShutdownPolicy + */ + public void setExecuteExistingDelayedTasksAfterShutdownPolicy(boolean value) { + executeExistingDelayedTasksAfterShutdown = value; + if (!value && isShutdown()) + cancelUnwantedTasks(); + } + + /** + * Gets the policy on whether to execute existing delayed + * tasks even when this executor has been <tt>shutdown</tt>. In + * this case, these tasks will only terminate upon + * <tt>shutdownNow</tt>, or after setting the policy to + * <tt>false</tt> when already shutdown. This value is by default + * true. + * + * @return true if will execute after shutdown + * @see #setExecuteExistingDelayedTasksAfterShutdownPolicy + */ + public boolean getExecuteExistingDelayedTasksAfterShutdownPolicy() { + return executeExistingDelayedTasksAfterShutdown; + } + + + /** + * Initiates an orderly shutdown in which previously submitted + * tasks are executed, but no new tasks will be accepted. If the + * <tt>ExecuteExistingDelayedTasksAfterShutdownPolicy</tt> has + * been set <tt>false</tt>, existing delayed tasks whose delays + * have not yet elapsed are cancelled. And unless the + * <tt>ContinueExistingPeriodicTasksAfterShutdownPolicy</tt> has + * been set <tt>true</tt>, future executions of existing periodic + * tasks will be cancelled. + */ + public void shutdown() { + cancelUnwantedTasks(); + super.shutdown(); + } + + /** + * Attempts to stop all actively executing tasks, halts the + * processing of waiting tasks, and returns a list of the tasks + * that were awaiting execution. + * + * <p>There are no guarantees beyond best-effort attempts to stop + * processing actively executing tasks. This implementation + * cancels tasks via {@link Thread#interrupt}, so any task that + * fails to respond to interrupts may never terminate. + * + * @return list of tasks that never commenced execution. Each + * element of this list is a {@link ScheduledFuture}, + * including those tasks submitted using <tt>execute</tt>, which + * are for scheduling purposes used as the basis of a zero-delay + * <tt>ScheduledFuture</tt>. + * @throws SecurityException {@inheritDoc} + */ + public List<Runnable> shutdownNow() { + return super.shutdownNow(); + } + + /** + * Returns the task queue used by this executor. Each element of + * this queue is a {@link ScheduledFuture}, including those + * tasks submitted using <tt>execute</tt> which are for scheduling + * purposes used as the basis of a zero-delay + * <tt>ScheduledFuture</tt>. Iteration over this queue is + * <em>not</em> guaranteed to traverse tasks in the order in + * which they will execute. + * + * @return the task queue + */ + public BlockingQueue<Runnable> getQueue() { + return super.getQueue(); + } + + /** + * An annoying wrapper class to convince javac to use a + * DelayQueue<RunnableScheduledFuture> as a BlockingQueue<Runnable> + */ + private static class DelayedWorkQueue + extends AbstractCollection<Runnable> + implements BlockingQueue<Runnable> { + + private final DelayQueue<RunnableScheduledFuture> dq = new DelayQueue<RunnableScheduledFuture>(); + public Runnable poll() { return dq.poll(); } + public Runnable peek() { return dq.peek(); } + public Runnable take() throws InterruptedException { return dq.take(); } + public Runnable poll(long timeout, TimeUnit unit) throws InterruptedException { + return dq.poll(timeout, unit); + } + + public boolean add(Runnable x) { + return dq.add((RunnableScheduledFuture)x); + } + public boolean offer(Runnable x) { + return dq.offer((RunnableScheduledFuture)x); + } + public void put(Runnable x) { + dq.put((RunnableScheduledFuture)x); + } + public boolean offer(Runnable x, long timeout, TimeUnit unit) { + return dq.offer((RunnableScheduledFuture)x, timeout, unit); + } + + public Runnable remove() { return dq.remove(); } + public Runnable element() { return dq.element(); } + public void clear() { dq.clear(); } + public int drainTo(Collection<? super Runnable> c) { return dq.drainTo(c); } + public int drainTo(Collection<? super Runnable> c, int maxElements) { + return dq.drainTo(c, maxElements); + } + + public int remainingCapacity() { return dq.remainingCapacity(); } + public boolean remove(Object x) { return dq.remove(x); } + public boolean contains(Object x) { return dq.contains(x); } + public int size() { return dq.size(); } + public boolean isEmpty() { return dq.isEmpty(); } + public Object[] toArray() { return dq.toArray(); } + public <T> T[] toArray(T[] array) { return dq.toArray(array); } + public Iterator<Runnable> iterator() { + return new Iterator<Runnable>() { + private Iterator<RunnableScheduledFuture> it = dq.iterator(); + public boolean hasNext() { return it.hasNext(); } + public Runnable next() { return it.next(); } + public void remove() { it.remove(); } + }; + } + } +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/Semaphore.java b/libjava/classpath/external/jsr166/java/util/concurrent/Semaphore.java new file mode 100644 index 000000000..105236439 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/Semaphore.java @@ -0,0 +1,681 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; +import java.util.*; +import java.util.concurrent.locks.*; +import java.util.concurrent.atomic.*; + +/** + * A counting semaphore. Conceptually, a semaphore maintains a set of + * permits. Each {@link #acquire} blocks if necessary until a permit is + * available, and then takes it. Each {@link #release} adds a permit, + * potentially releasing a blocking acquirer. + * However, no actual permit objects are used; the {@code Semaphore} just + * keeps a count of the number available and acts accordingly. + * + * <p>Semaphores are often used to restrict the number of threads than can + * access some (physical or logical) resource. For example, here is + * a class that uses a semaphore to control access to a pool of items: + * <pre> + * class Pool { + * private static final int MAX_AVAILABLE = 100; + * private final Semaphore available = new Semaphore(MAX_AVAILABLE, true); + * + * public Object getItem() throws InterruptedException { + * available.acquire(); + * return getNextAvailableItem(); + * } + * + * public void putItem(Object x) { + * if (markAsUnused(x)) + * available.release(); + * } + * + * // Not a particularly efficient data structure; just for demo + * + * protected Object[] items = ... whatever kinds of items being managed + * protected boolean[] used = new boolean[MAX_AVAILABLE]; + * + * protected synchronized Object getNextAvailableItem() { + * for (int i = 0; i < MAX_AVAILABLE; ++i) { + * if (!used[i]) { + * used[i] = true; + * return items[i]; + * } + * } + * return null; // not reached + * } + * + * protected synchronized boolean markAsUnused(Object item) { + * for (int i = 0; i < MAX_AVAILABLE; ++i) { + * if (item == items[i]) { + * if (used[i]) { + * used[i] = false; + * return true; + * } else + * return false; + * } + * } + * return false; + * } + * + * } + * </pre> + * + * <p>Before obtaining an item each thread must acquire a permit from + * the semaphore, guaranteeing that an item is available for use. When + * the thread has finished with the item it is returned back to the + * pool and a permit is returned to the semaphore, allowing another + * thread to acquire that item. Note that no synchronization lock is + * held when {@link #acquire} is called as that would prevent an item + * from being returned to the pool. The semaphore encapsulates the + * synchronization needed to restrict access to the pool, separately + * from any synchronization needed to maintain the consistency of the + * pool itself. + * + * <p>A semaphore initialized to one, and which is used such that it + * only has at most one permit available, can serve as a mutual + * exclusion lock. This is more commonly known as a <em>binary + * semaphore</em>, because it only has two states: one permit + * available, or zero permits available. When used in this way, the + * binary semaphore has the property (unlike many {@link Lock} + * implementations), that the "lock" can be released by a + * thread other than the owner (as semaphores have no notion of + * ownership). This can be useful in some specialized contexts, such + * as deadlock recovery. + * + * <p> The constructor for this class optionally accepts a + * <em>fairness</em> parameter. When set false, this class makes no + * guarantees about the order in which threads acquire permits. In + * particular, <em>barging</em> is permitted, that is, a thread + * invoking {@link #acquire} can be allocated a permit ahead of a + * thread that has been waiting - logically the new thread places itself at + * the head of the queue of waiting threads. When fairness is set true, the + * semaphore guarantees that threads invoking any of the {@link + * #acquire() acquire} methods are selected to obtain permits in the order in + * which their invocation of those methods was processed + * (first-in-first-out; FIFO). Note that FIFO ordering necessarily + * applies to specific internal points of execution within these + * methods. So, it is possible for one thread to invoke + * {@code acquire} before another, but reach the ordering point after + * the other, and similarly upon return from the method. + * Also note that the untimed {@link #tryAcquire() tryAcquire} methods do not + * honor the fairness setting, but will take any permits that are + * available. + * + * <p>Generally, semaphores used to control resource access should be + * initialized as fair, to ensure that no thread is starved out from + * accessing a resource. When using semaphores for other kinds of + * synchronization control, the throughput advantages of non-fair + * ordering often outweigh fairness considerations. + * + * <p>This class also provides convenience methods to {@link + * #acquire(int) acquire} and {@link #release(int) release} multiple + * permits at a time. Beware of the increased risk of indefinite + * postponement when these methods are used without fairness set true. + * + * <p>Memory consistency effects: Actions in a thread prior to calling + * a "release" method such as {@code release()} + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a> + * actions following a successful "acquire" method such as {@code acquire()} + * in another thread. + * + * @since 1.5 + * @author Doug Lea + * + */ + +public class Semaphore implements java.io.Serializable { + private static final long serialVersionUID = -3222578661600680210L; + /** All mechanics via AbstractQueuedSynchronizer subclass */ + private final Sync sync; + + /** + * Synchronization implementation for semaphore. Uses AQS state + * to represent permits. Subclassed into fair and nonfair + * versions. + */ + abstract static class Sync extends AbstractQueuedSynchronizer { + private static final long serialVersionUID = 1192457210091910933L; + + Sync(int permits) { + setState(permits); + } + + final int getPermits() { + return getState(); + } + + final int nonfairTryAcquireShared(int acquires) { + for (;;) { + int available = getState(); + int remaining = available - acquires; + if (remaining < 0 || + compareAndSetState(available, remaining)) + return remaining; + } + } + + protected final boolean tryReleaseShared(int releases) { + for (;;) { + int p = getState(); + if (compareAndSetState(p, p + releases)) + return true; + } + } + + final void reducePermits(int reductions) { + for (;;) { + int current = getState(); + int next = current - reductions; + if (compareAndSetState(current, next)) + return; + } + } + + final int drainPermits() { + for (;;) { + int current = getState(); + if (current == 0 || compareAndSetState(current, 0)) + return current; + } + } + } + + /** + * NonFair version + */ + final static class NonfairSync extends Sync { + private static final long serialVersionUID = -2694183684443567898L; + + NonfairSync(int permits) { + super(permits); + } + + protected int tryAcquireShared(int acquires) { + return nonfairTryAcquireShared(acquires); + } + } + + /** + * Fair version + */ + final static class FairSync extends Sync { + private static final long serialVersionUID = 2014338818796000944L; + + FairSync(int permits) { + super(permits); + } + + protected int tryAcquireShared(int acquires) { + Thread current = Thread.currentThread(); + for (;;) { + Thread first = getFirstQueuedThread(); + if (first != null && first != current) + return -1; + int available = getState(); + int remaining = available - acquires; + if (remaining < 0 || + compareAndSetState(available, remaining)) + return remaining; + } + } + } + + /** + * Creates a {@code Semaphore} with the given number of + * permits and nonfair fairness setting. + * + * @param permits the initial number of permits available. + * This value may be negative, in which case releases + * must occur before any acquires will be granted. + */ + public Semaphore(int permits) { + sync = new NonfairSync(permits); + } + + /** + * Creates a {@code Semaphore} with the given number of + * permits and the given fairness setting. + * + * @param permits the initial number of permits available. + * This value may be negative, in which case releases + * must occur before any acquires will be granted. + * @param fair {@code true} if this semaphore will guarantee + * first-in first-out granting of permits under contention, + * else {@code false} + */ + public Semaphore(int permits, boolean fair) { + sync = (fair)? new FairSync(permits) : new NonfairSync(permits); + } + + /** + * Acquires a permit from this semaphore, blocking until one is + * available, or the thread is {@linkplain Thread#interrupt interrupted}. + * + * <p>Acquires a permit, if one is available and returns immediately, + * reducing the number of available permits by one. + * + * <p>If no permit is available then the current thread becomes + * disabled for thread scheduling purposes and lies dormant until + * one of two things happens: + * <ul> + * <li>Some other thread invokes the {@link #release} method for this + * semaphore and the current thread is next to be assigned a permit; or + * <li>Some other thread {@linkplain Thread#interrupt interrupts} + * the current thread. + * </ul> + * + * <p>If the current thread: + * <ul> + * <li>has its interrupted status set on entry to this method; or + * <li>is {@linkplain Thread#interrupt interrupted} while waiting + * for a permit, + * </ul> + * then {@link InterruptedException} is thrown and the current thread's + * interrupted status is cleared. + * + * @throws InterruptedException if the current thread is interrupted + */ + public void acquire() throws InterruptedException { + sync.acquireSharedInterruptibly(1); + } + + /** + * Acquires a permit from this semaphore, blocking until one is + * available. + * + * <p>Acquires a permit, if one is available and returns immediately, + * reducing the number of available permits by one. + * + * <p>If no permit is available then the current thread becomes + * disabled for thread scheduling purposes and lies dormant until + * some other thread invokes the {@link #release} method for this + * semaphore and the current thread is next to be assigned a permit. + * + * <p>If the current thread is {@linkplain Thread#interrupt interrupted} + * while waiting for a permit then it will continue to wait, but the + * time at which the thread is assigned a permit may change compared to + * the time it would have received the permit had no interruption + * occurred. When the thread does return from this method its interrupt + * status will be set. + */ + public void acquireUninterruptibly() { + sync.acquireShared(1); + } + + /** + * Acquires a permit from this semaphore, only if one is available at the + * time of invocation. + * + * <p>Acquires a permit, if one is available and returns immediately, + * with the value {@code true}, + * reducing the number of available permits by one. + * + * <p>If no permit is available then this method will return + * immediately with the value {@code false}. + * + * <p>Even when this semaphore has been set to use a + * fair ordering policy, a call to {@code tryAcquire()} <em>will</em> + * immediately acquire a permit if one is available, whether or not + * other threads are currently waiting. + * This "barging" behavior can be useful in certain + * circumstances, even though it breaks fairness. If you want to honor + * the fairness setting, then use + * {@link #tryAcquire(long, TimeUnit) tryAcquire(0, TimeUnit.SECONDS) } + * which is almost equivalent (it also detects interruption). + * + * @return {@code true} if a permit was acquired and {@code false} + * otherwise + */ + public boolean tryAcquire() { + return sync.nonfairTryAcquireShared(1) >= 0; + } + + /** + * Acquires a permit from this semaphore, if one becomes available + * within the given waiting time and the current thread has not + * been {@linkplain Thread#interrupt interrupted}. + * + * <p>Acquires a permit, if one is available and returns immediately, + * with the value {@code true}, + * reducing the number of available permits by one. + * + * <p>If no permit is available then the current thread becomes + * disabled for thread scheduling purposes and lies dormant until + * one of three things happens: + * <ul> + * <li>Some other thread invokes the {@link #release} method for this + * semaphore and the current thread is next to be assigned a permit; or + * <li>Some other thread {@linkplain Thread#interrupt interrupts} + * the current thread; or + * <li>The specified waiting time elapses. + * </ul> + * + * <p>If a permit is acquired then the value {@code true} is returned. + * + * <p>If the current thread: + * <ul> + * <li>has its interrupted status set on entry to this method; or + * <li>is {@linkplain Thread#interrupt interrupted} while waiting + * to acquire a permit, + * </ul> + * then {@link InterruptedException} is thrown and the current thread's + * interrupted status is cleared. + * + * <p>If the specified waiting time elapses then the value {@code false} + * is returned. If the time is less than or equal to zero, the method + * will not wait at all. + * + * @param timeout the maximum time to wait for a permit + * @param unit the time unit of the {@code timeout} argument + * @return {@code true} if a permit was acquired and {@code false} + * if the waiting time elapsed before a permit was acquired + * @throws InterruptedException if the current thread is interrupted + */ + public boolean tryAcquire(long timeout, TimeUnit unit) + throws InterruptedException { + return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout)); + } + + /** + * Releases a permit, returning it to the semaphore. + * + * <p>Releases a permit, increasing the number of available permits by + * one. If any threads are trying to acquire a permit, then one is + * selected and given the permit that was just released. That thread + * is (re)enabled for thread scheduling purposes. + * + * <p>There is no requirement that a thread that releases a permit must + * have acquired that permit by calling {@link #acquire}. + * Correct usage of a semaphore is established by programming convention + * in the application. + */ + public void release() { + sync.releaseShared(1); + } + + /** + * Acquires the given number of permits from this semaphore, + * blocking until all are available, + * or the thread is {@linkplain Thread#interrupt interrupted}. + * + * <p>Acquires the given number of permits, if they are available, + * and returns immediately, reducing the number of available permits + * by the given amount. + * + * <p>If insufficient permits are available then the current thread becomes + * disabled for thread scheduling purposes and lies dormant until + * one of two things happens: + * <ul> + * <li>Some other thread invokes one of the {@link #release() release} + * methods for this semaphore, the current thread is next to be assigned + * permits and the number of available permits satisfies this request; or + * <li>Some other thread {@linkplain Thread#interrupt interrupts} + * the current thread. + * </ul> + * + * <p>If the current thread: + * <ul> + * <li>has its interrupted status set on entry to this method; or + * <li>is {@linkplain Thread#interrupt interrupted} while waiting + * for a permit, + * </ul> + * then {@link InterruptedException} is thrown and the current thread's + * interrupted status is cleared. + * Any permits that were to be assigned to this thread are instead + * assigned to other threads trying to acquire permits, as if + * permits had been made available by a call to {@link #release()}. + * + * @param permits the number of permits to acquire + * @throws InterruptedException if the current thread is interrupted + * @throws IllegalArgumentException if {@code permits} is negative + */ + public void acquire(int permits) throws InterruptedException { + if (permits < 0) throw new IllegalArgumentException(); + sync.acquireSharedInterruptibly(permits); + } + + /** + * Acquires the given number of permits from this semaphore, + * blocking until all are available. + * + * <p>Acquires the given number of permits, if they are available, + * and returns immediately, reducing the number of available permits + * by the given amount. + * + * <p>If insufficient permits are available then the current thread becomes + * disabled for thread scheduling purposes and lies dormant until + * some other thread invokes one of the {@link #release() release} + * methods for this semaphore, the current thread is next to be assigned + * permits and the number of available permits satisfies this request. + * + * <p>If the current thread is {@linkplain Thread#interrupt interrupted} + * while waiting for permits then it will continue to wait and its + * position in the queue is not affected. When the thread does return + * from this method its interrupt status will be set. + * + * @param permits the number of permits to acquire + * @throws IllegalArgumentException if {@code permits} is negative + * + */ + public void acquireUninterruptibly(int permits) { + if (permits < 0) throw new IllegalArgumentException(); + sync.acquireShared(permits); + } + + /** + * Acquires the given number of permits from this semaphore, only + * if all are available at the time of invocation. + * + * <p>Acquires the given number of permits, if they are available, and + * returns immediately, with the value {@code true}, + * reducing the number of available permits by the given amount. + * + * <p>If insufficient permits are available then this method will return + * immediately with the value {@code false} and the number of available + * permits is unchanged. + * + * <p>Even when this semaphore has been set to use a fair ordering + * policy, a call to {@code tryAcquire} <em>will</em> + * immediately acquire a permit if one is available, whether or + * not other threads are currently waiting. This + * "barging" behavior can be useful in certain + * circumstances, even though it breaks fairness. If you want to + * honor the fairness setting, then use {@link #tryAcquire(int, + * long, TimeUnit) tryAcquire(permits, 0, TimeUnit.SECONDS) } + * which is almost equivalent (it also detects interruption). + * + * @param permits the number of permits to acquire + * @return {@code true} if the permits were acquired and + * {@code false} otherwise + * @throws IllegalArgumentException if {@code permits} is negative + */ + public boolean tryAcquire(int permits) { + if (permits < 0) throw new IllegalArgumentException(); + return sync.nonfairTryAcquireShared(permits) >= 0; + } + + /** + * Acquires the given number of permits from this semaphore, if all + * become available within the given waiting time and the current + * thread has not been {@linkplain Thread#interrupt interrupted}. + * + * <p>Acquires the given number of permits, if they are available and + * returns immediately, with the value {@code true}, + * reducing the number of available permits by the given amount. + * + * <p>If insufficient permits are available then + * the current thread becomes disabled for thread scheduling + * purposes and lies dormant until one of three things happens: + * <ul> + * <li>Some other thread invokes one of the {@link #release() release} + * methods for this semaphore, the current thread is next to be assigned + * permits and the number of available permits satisfies this request; or + * <li>Some other thread {@linkplain Thread#interrupt interrupts} + * the current thread; or + * <li>The specified waiting time elapses. + * </ul> + * + * <p>If the permits are acquired then the value {@code true} is returned. + * + * <p>If the current thread: + * <ul> + * <li>has its interrupted status set on entry to this method; or + * <li>is {@linkplain Thread#interrupt interrupted} while waiting + * to acquire the permits, + * </ul> + * then {@link InterruptedException} is thrown and the current thread's + * interrupted status is cleared. + * Any permits that were to be assigned to this thread, are instead + * assigned to other threads trying to acquire permits, as if + * the permits had been made available by a call to {@link #release()}. + * + * <p>If the specified waiting time elapses then the value {@code false} + * is returned. If the time is less than or equal to zero, the method + * will not wait at all. Any permits that were to be assigned to this + * thread, are instead assigned to other threads trying to acquire + * permits, as if the permits had been made available by a call to + * {@link #release()}. + * + * @param permits the number of permits to acquire + * @param timeout the maximum time to wait for the permits + * @param unit the time unit of the {@code timeout} argument + * @return {@code true} if all permits were acquired and {@code false} + * if the waiting time elapsed before all permits were acquired + * @throws InterruptedException if the current thread is interrupted + * @throws IllegalArgumentException if {@code permits} is negative + */ + public boolean tryAcquire(int permits, long timeout, TimeUnit unit) + throws InterruptedException { + if (permits < 0) throw new IllegalArgumentException(); + return sync.tryAcquireSharedNanos(permits, unit.toNanos(timeout)); + } + + /** + * Releases the given number of permits, returning them to the semaphore. + * + * <p>Releases the given number of permits, increasing the number of + * available permits by that amount. + * If any threads are trying to acquire permits, then one + * is selected and given the permits that were just released. + * If the number of available permits satisfies that thread's request + * then that thread is (re)enabled for thread scheduling purposes; + * otherwise the thread will wait until sufficient permits are available. + * If there are still permits available + * after this thread's request has been satisfied, then those permits + * are assigned in turn to other threads trying to acquire permits. + * + * <p>There is no requirement that a thread that releases a permit must + * have acquired that permit by calling {@link Semaphore#acquire acquire}. + * Correct usage of a semaphore is established by programming convention + * in the application. + * + * @param permits the number of permits to release + * @throws IllegalArgumentException if {@code permits} is negative + */ + public void release(int permits) { + if (permits < 0) throw new IllegalArgumentException(); + sync.releaseShared(permits); + } + + /** + * Returns the current number of permits available in this semaphore. + * + * <p>This method is typically used for debugging and testing purposes. + * + * @return the number of permits available in this semaphore + */ + public int availablePermits() { + return sync.getPermits(); + } + + /** + * Acquires and returns all permits that are immediately available. + * + * @return the number of permits acquired + */ + public int drainPermits() { + return sync.drainPermits(); + } + + /** + * Shrinks the number of available permits by the indicated + * reduction. This method can be useful in subclasses that use + * semaphores to track resources that become unavailable. This + * method differs from {@code acquire} in that it does not block + * waiting for permits to become available. + * + * @param reduction the number of permits to remove + * @throws IllegalArgumentException if {@code reduction} is negative + */ + protected void reducePermits(int reduction) { + if (reduction < 0) throw new IllegalArgumentException(); + sync.reducePermits(reduction); + } + + /** + * Returns {@code true} if this semaphore has fairness set true. + * + * @return {@code true} if this semaphore has fairness set true + */ + public boolean isFair() { + return sync instanceof FairSync; + } + + /** + * Queries whether any threads are waiting to acquire. Note that + * because cancellations may occur at any time, a {@code true} + * return does not guarantee that any other thread will ever + * acquire. This method is designed primarily for use in + * monitoring of the system state. + * + * @return {@code true} if there may be other threads waiting to + * acquire the lock + */ + public final boolean hasQueuedThreads() { + return sync.hasQueuedThreads(); + } + + /** + * Returns an estimate of the number of threads waiting to acquire. + * The value is only an estimate because the number of threads may + * change dynamically while this method traverses internal data + * structures. This method is designed for use in monitoring of the + * system state, not for synchronization control. + * + * @return the estimated number of threads waiting for this lock + */ + public final int getQueueLength() { + return sync.getQueueLength(); + } + + /** + * Returns a collection containing threads that may be waiting to acquire. + * Because the actual set of threads may change dynamically while + * constructing this result, the returned collection is only a best-effort + * estimate. The elements of the returned collection are in no particular + * order. This method is designed to facilitate construction of + * subclasses that provide more extensive monitoring facilities. + * + * @return the collection of threads + */ + protected Collection<Thread> getQueuedThreads() { + return sync.getQueuedThreads(); + } + + /** + * Returns a string identifying this semaphore, as well as its state. + * The state, in brackets, includes the String {@code "Permits ="} + * followed by the number of permits. + * + * @return a string identifying this semaphore, as well as its state + */ + public String toString() { + return super.toString() + "[Permits = " + sync.getPermits() + "]"; + } +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/SynchronousQueue.java b/libjava/classpath/external/jsr166/java/util/concurrent/SynchronousQueue.java new file mode 100644 index 000000000..92f586ce8 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/SynchronousQueue.java @@ -0,0 +1,1127 @@ +/* + * Written by Doug Lea, Bill Scherer, and Michael Scott with + * assistance from members of JCP JSR-166 Expert Group and released to + * the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; +import java.util.concurrent.locks.*; +import java.util.concurrent.atomic.*; +import java.util.*; + +/** + * A {@linkplain BlockingQueue blocking queue} in which each insert + * operation must wait for a corresponding remove operation by another + * thread, and vice versa. A synchronous queue does not have any + * internal capacity, not even a capacity of one. You cannot + * <tt>peek</tt> at a synchronous queue because an element is only + * present when you try to remove it; you cannot insert an element + * (using any method) unless another thread is trying to remove it; + * you cannot iterate as there is nothing to iterate. The + * <em>head</em> of the queue is the element that the first queued + * inserting thread is trying to add to the queue; if there is no such + * queued thread then no element is available for removal and + * <tt>poll()</tt> will return <tt>null</tt>. For purposes of other + * <tt>Collection</tt> methods (for example <tt>contains</tt>), a + * <tt>SynchronousQueue</tt> acts as an empty collection. This queue + * does not permit <tt>null</tt> elements. + * + * <p>Synchronous queues are similar to rendezvous channels used in + * CSP and Ada. They are well suited for handoff designs, in which an + * object running in one thread must sync up with an object running + * in another thread in order to hand it some information, event, or + * task. + * + * <p> This class supports an optional fairness policy for ordering + * waiting producer and consumer threads. By default, this ordering + * is not guaranteed. However, a queue constructed with fairness set + * to <tt>true</tt> grants threads access in FIFO order. + * + * <p>This class and its iterator implement all of the + * <em>optional</em> methods of the {@link Collection} and {@link + * Iterator} interfaces. + * + * <p>This class is a member of the + * <a href="{@docRoot}/../technotes/guides/collections/index.html"> + * Java Collections Framework</a>. + * + * @since 1.5 + * @author Doug Lea and Bill Scherer and Michael Scott + * @param <E> the type of elements held in this collection + */ +public class SynchronousQueue<E> extends AbstractQueue<E> + implements BlockingQueue<E>, java.io.Serializable { + private static final long serialVersionUID = -3223113410248163686L; + + /* + * This class implements extensions of the dual stack and dual + * queue algorithms described in "Nonblocking Concurrent Objects + * with Condition Synchronization", by W. N. Scherer III and + * M. L. Scott. 18th Annual Conf. on Distributed Computing, + * Oct. 2004 (see also + * http://www.cs.rochester.edu/u/scott/synchronization/pseudocode/duals.html). + * The (Lifo) stack is used for non-fair mode, and the (Fifo) + * queue for fair mode. The performance of the two is generally + * similar. Fifo usually supports higher throughput under + * contention but Lifo maintains higher thread locality in common + * applications. + * + * A dual queue (and similarly stack) is one that at any given + * time either holds "data" -- items provided by put operations, + * or "requests" -- slots representing take operations, or is + * empty. A call to "fulfill" (i.e., a call requesting an item + * from a queue holding data or vice versa) dequeues a + * complementary node. The most interesting feature of these + * queues is that any operation can figure out which mode the + * queue is in, and act accordingly without needing locks. + * + * Both the queue and stack extend abstract class Transferer + * defining the single method transfer that does a put or a + * take. These are unified into a single method because in dual + * data structures, the put and take operations are symmetrical, + * so nearly all code can be combined. The resulting transfer + * methods are on the long side, but are easier to follow than + * they would be if broken up into nearly-duplicated parts. + * + * The queue and stack data structures share many conceptual + * similarities but very few concrete details. For simplicity, + * they are kept distinct so that they can later evolve + * separately. + * + * The algorithms here differ from the versions in the above paper + * in extending them for use in synchronous queues, as well as + * dealing with cancellation. The main differences include: + * + * 1. The original algorithms used bit-marked pointers, but + * the ones here use mode bits in nodes, leading to a number + * of further adaptations. + * 2. SynchronousQueues must block threads waiting to become + * fulfilled. + * 3. Support for cancellation via timeout and interrupts, + * including cleaning out cancelled nodes/threads + * from lists to avoid garbage retention and memory depletion. + * + * Blocking is mainly accomplished using LockSupport park/unpark, + * except that nodes that appear to be the next ones to become + * fulfilled first spin a bit (on multiprocessors only). On very + * busy synchronous queues, spinning can dramatically improve + * throughput. And on less busy ones, the amount of spinning is + * small enough not to be noticeable. + * + * Cleaning is done in different ways in queues vs stacks. For + * queues, we can almost always remove a node immediately in O(1) + * time (modulo retries for consistency checks) when it is + * cancelled. But if it may be pinned as the current tail, it must + * wait until some subsequent cancellation. For stacks, we need a + * potentially O(n) traversal to be sure that we can remove the + * node, but this can run concurrently with other threads + * accessing the stack. + * + * While garbage collection takes care of most node reclamation + * issues that otherwise complicate nonblocking algorithms, care + * is taken to "forget" references to data, other nodes, and + * threads that might be held on to long-term by blocked + * threads. In cases where setting to null would otherwise + * conflict with main algorithms, this is done by changing a + * node's link to now point to the node itself. This doesn't arise + * much for Stack nodes (because blocked threads do not hang on to + * old head pointers), but references in Queue nodes must be + * aggressively forgotten to avoid reachability of everything any + * node has ever referred to since arrival. + */ + + /** + * Shared internal API for dual stacks and queues. + */ + static abstract class Transferer { + /** + * Performs a put or take. + * + * @param e if non-null, the item to be handed to a consumer; + * if null, requests that transfer return an item + * offered by producer. + * @param timed if this operation should timeout + * @param nanos the timeout, in nanoseconds + * @return if non-null, the item provided or received; if null, + * the operation failed due to timeout or interrupt -- + * the caller can distinguish which of these occurred + * by checking Thread.interrupted. + */ + abstract Object transfer(Object e, boolean timed, long nanos); + } + + /** The number of CPUs, for spin control */ + static final int NCPUS = Runtime.getRuntime().availableProcessors(); + + /** + * The number of times to spin before blocking in timed waits. + * The value is empirically derived -- it works well across a + * variety of processors and OSes. Empirically, the best value + * seems not to vary with number of CPUs (beyond 2) so is just + * a constant. + */ + static final int maxTimedSpins = (NCPUS < 2)? 0 : 32; + + /** + * The number of times to spin before blocking in untimed waits. + * This is greater than timed value because untimed waits spin + * faster since they don't need to check times on each spin. + */ + static final int maxUntimedSpins = maxTimedSpins * 16; + + /** + * The number of nanoseconds for which it is faster to spin + * rather than to use timed park. A rough estimate suffices. + */ + static final long spinForTimeoutThreshold = 1000L; + + /** Dual stack */ + static final class TransferStack extends Transferer { + /* + * This extends Scherer-Scott dual stack algorithm, differing, + * among other ways, by using "covering" nodes rather than + * bit-marked pointers: Fulfilling operations push on marker + * nodes (with FULFILLING bit set in mode) to reserve a spot + * to match a waiting node. + */ + + /* Modes for SNodes, ORed together in node fields */ + /** Node represents an unfulfilled consumer */ + static final int REQUEST = 0; + /** Node represents an unfulfilled producer */ + static final int DATA = 1; + /** Node is fulfilling another unfulfilled DATA or REQUEST */ + static final int FULFILLING = 2; + + /** Return true if m has fulfilling bit set */ + static boolean isFulfilling(int m) { return (m & FULFILLING) != 0; } + + /** Node class for TransferStacks. */ + static final class SNode { + volatile SNode next; // next node in stack + volatile SNode match; // the node matched to this + volatile Thread waiter; // to control park/unpark + Object item; // data; or null for REQUESTs + int mode; + // Note: item and mode fields don't need to be volatile + // since they are always written before, and read after, + // other volatile/atomic operations. + + SNode(Object item) { + this.item = item; + } + + static final AtomicReferenceFieldUpdater<SNode, SNode> + nextUpdater = AtomicReferenceFieldUpdater.newUpdater + (SNode.class, SNode.class, "next"); + + boolean casNext(SNode cmp, SNode val) { + return (cmp == next && + nextUpdater.compareAndSet(this, cmp, val)); + } + + static final AtomicReferenceFieldUpdater<SNode, SNode> + matchUpdater = AtomicReferenceFieldUpdater.newUpdater + (SNode.class, SNode.class, "match"); + + /** + * Tries to match node s to this node, if so, waking up thread. + * Fulfillers call tryMatch to identify their waiters. + * Waiters block until they have been matched. + * + * @param s the node to match + * @return true if successfully matched to s + */ + boolean tryMatch(SNode s) { + if (match == null && + matchUpdater.compareAndSet(this, null, s)) { + Thread w = waiter; + if (w != null) { // waiters need at most one unpark + waiter = null; + LockSupport.unpark(w); + } + return true; + } + return match == s; + } + + /** + * Tries to cancel a wait by matching node to itself. + */ + void tryCancel() { + matchUpdater.compareAndSet(this, null, this); + } + + boolean isCancelled() { + return match == this; + } + } + + /** The head (top) of the stack */ + volatile SNode head; + + static final AtomicReferenceFieldUpdater<TransferStack, SNode> + headUpdater = AtomicReferenceFieldUpdater.newUpdater + (TransferStack.class, SNode.class, "head"); + + boolean casHead(SNode h, SNode nh) { + return h == head && headUpdater.compareAndSet(this, h, nh); + } + + /** + * Creates or resets fields of a node. Called only from transfer + * where the node to push on stack is lazily created and + * reused when possible to help reduce intervals between reads + * and CASes of head and to avoid surges of garbage when CASes + * to push nodes fail due to contention. + */ + static SNode snode(SNode s, Object e, SNode next, int mode) { + if (s == null) s = new SNode(e); + s.mode = mode; + s.next = next; + return s; + } + + /** + * Puts or takes an item. + */ + Object transfer(Object e, boolean timed, long nanos) { + /* + * Basic algorithm is to loop trying one of three actions: + * + * 1. If apparently empty or already containing nodes of same + * mode, try to push node on stack and wait for a match, + * returning it, or null if cancelled. + * + * 2. If apparently containing node of complementary mode, + * try to push a fulfilling node on to stack, match + * with corresponding waiting node, pop both from + * stack, and return matched item. The matching or + * unlinking might not actually be necessary because of + * other threads performing action 3: + * + * 3. If top of stack already holds another fulfilling node, + * help it out by doing its match and/or pop + * operations, and then continue. The code for helping + * is essentially the same as for fulfilling, except + * that it doesn't return the item. + */ + + SNode s = null; // constructed/reused as needed + int mode = (e == null)? REQUEST : DATA; + + for (;;) { + SNode h = head; + if (h == null || h.mode == mode) { // empty or same-mode + if (timed && nanos <= 0) { // can't wait + if (h != null && h.isCancelled()) + casHead(h, h.next); // pop cancelled node + else + return null; + } else if (casHead(h, s = snode(s, e, h, mode))) { + SNode m = awaitFulfill(s, timed, nanos); + if (m == s) { // wait was cancelled + clean(s); + return null; + } + if ((h = head) != null && h.next == s) + casHead(h, s.next); // help s's fulfiller + return mode == REQUEST? m.item : s.item; + } + } else if (!isFulfilling(h.mode)) { // try to fulfill + if (h.isCancelled()) // already cancelled + casHead(h, h.next); // pop and retry + else if (casHead(h, s=snode(s, e, h, FULFILLING|mode))) { + for (;;) { // loop until matched or waiters disappear + SNode m = s.next; // m is s's match + if (m == null) { // all waiters are gone + casHead(s, null); // pop fulfill node + s = null; // use new node next time + break; // restart main loop + } + SNode mn = m.next; + if (m.tryMatch(s)) { + casHead(s, mn); // pop both s and m + return (mode == REQUEST)? m.item : s.item; + } else // lost match + s.casNext(m, mn); // help unlink + } + } + } else { // help a fulfiller + SNode m = h.next; // m is h's match + if (m == null) // waiter is gone + casHead(h, null); // pop fulfilling node + else { + SNode mn = m.next; + if (m.tryMatch(h)) // help match + casHead(h, mn); // pop both h and m + else // lost match + h.casNext(m, mn); // help unlink + } + } + } + } + + /** + * Spins/blocks until node s is matched by a fulfill operation. + * + * @param s the waiting node + * @param timed true if timed wait + * @param nanos timeout value + * @return matched node, or s if cancelled + */ + SNode awaitFulfill(SNode s, boolean timed, long nanos) { + /* + * When a node/thread is about to block, it sets its waiter + * field and then rechecks state at least one more time + * before actually parking, thus covering race vs + * fulfiller noticing that waiter is non-null so should be + * woken. + * + * When invoked by nodes that appear at the point of call + * to be at the head of the stack, calls to park are + * preceded by spins to avoid blocking when producers and + * consumers are arriving very close in time. This can + * happen enough to bother only on multiprocessors. + * + * The order of checks for returning out of main loop + * reflects fact that interrupts have precedence over + * normal returns, which have precedence over + * timeouts. (So, on timeout, one last check for match is + * done before giving up.) Except that calls from untimed + * SynchronousQueue.{poll/offer} don't check interrupts + * and don't wait at all, so are trapped in transfer + * method rather than calling awaitFulfill. + */ + long lastTime = (timed)? System.nanoTime() : 0; + Thread w = Thread.currentThread(); + SNode h = head; + int spins = (shouldSpin(s)? + (timed? maxTimedSpins : maxUntimedSpins) : 0); + for (;;) { + if (w.isInterrupted()) + s.tryCancel(); + SNode m = s.match; + if (m != null) + return m; + if (timed) { + long now = System.nanoTime(); + nanos -= now - lastTime; + lastTime = now; + if (nanos <= 0) { + s.tryCancel(); + continue; + } + } + if (spins > 0) + spins = shouldSpin(s)? (spins-1) : 0; + else if (s.waiter == null) + s.waiter = w; // establish waiter so can park next iter + else if (!timed) + LockSupport.park(this); + else if (nanos > spinForTimeoutThreshold) + LockSupport.parkNanos(this, nanos); + } + } + + /** + * Returns true if node s is at head or there is an active + * fulfiller. + */ + boolean shouldSpin(SNode s) { + SNode h = head; + return (h == s || h == null || isFulfilling(h.mode)); + } + + /** + * Unlinks s from the stack. + */ + void clean(SNode s) { + s.item = null; // forget item + s.waiter = null; // forget thread + + /* + * At worst we may need to traverse entire stack to unlink + * s. If there are multiple concurrent calls to clean, we + * might not see s if another thread has already removed + * it. But we can stop when we see any node known to + * follow s. We use s.next unless it too is cancelled, in + * which case we try the node one past. We don't check any + * further because we don't want to doubly traverse just to + * find sentinel. + */ + + SNode past = s.next; + if (past != null && past.isCancelled()) + past = past.next; + + // Absorb cancelled nodes at head + SNode p; + while ((p = head) != null && p != past && p.isCancelled()) + casHead(p, p.next); + + // Unsplice embedded nodes + while (p != null && p != past) { + SNode n = p.next; + if (n != null && n.isCancelled()) + p.casNext(n, n.next); + else + p = n; + } + } + } + + /** Dual Queue */ + static final class TransferQueue extends Transferer { + /* + * This extends Scherer-Scott dual queue algorithm, differing, + * among other ways, by using modes within nodes rather than + * marked pointers. The algorithm is a little simpler than + * that for stacks because fulfillers do not need explicit + * nodes, and matching is done by CAS'ing QNode.item field + * from non-null to null (for put) or vice versa (for take). + */ + + /** Node class for TransferQueue. */ + static final class QNode { + volatile QNode next; // next node in queue + volatile Object item; // CAS'ed to or from null + volatile Thread waiter; // to control park/unpark + final boolean isData; + + QNode(Object item, boolean isData) { + this.item = item; + this.isData = isData; + } + + static final AtomicReferenceFieldUpdater<QNode, QNode> + nextUpdater = AtomicReferenceFieldUpdater.newUpdater + (QNode.class, QNode.class, "next"); + + boolean casNext(QNode cmp, QNode val) { + return (next == cmp && + nextUpdater.compareAndSet(this, cmp, val)); + } + + static final AtomicReferenceFieldUpdater<QNode, Object> + itemUpdater = AtomicReferenceFieldUpdater.newUpdater + (QNode.class, Object.class, "item"); + + boolean casItem(Object cmp, Object val) { + return (item == cmp && + itemUpdater.compareAndSet(this, cmp, val)); + } + + /** + * Tries to cancel by CAS'ing ref to this as item. + */ + void tryCancel(Object cmp) { + itemUpdater.compareAndSet(this, cmp, this); + } + + boolean isCancelled() { + return item == this; + } + + /** + * Returns true if this node is known to be off the queue + * because its next pointer has been forgotten due to + * an advanceHead operation. + */ + boolean isOffList() { + return next == this; + } + } + + /** Head of queue */ + transient volatile QNode head; + /** Tail of queue */ + transient volatile QNode tail; + /** + * Reference to a cancelled node that might not yet have been + * unlinked from queue because it was the last inserted node + * when it cancelled. + */ + transient volatile QNode cleanMe; + + TransferQueue() { + QNode h = new QNode(null, false); // initialize to dummy node. + head = h; + tail = h; + } + + static final AtomicReferenceFieldUpdater<TransferQueue, QNode> + headUpdater = AtomicReferenceFieldUpdater.newUpdater + (TransferQueue.class, QNode.class, "head"); + + /** + * Tries to cas nh as new head; if successful, unlink + * old head's next node to avoid garbage retention. + */ + void advanceHead(QNode h, QNode nh) { + if (h == head && headUpdater.compareAndSet(this, h, nh)) + h.next = h; // forget old next + } + + static final AtomicReferenceFieldUpdater<TransferQueue, QNode> + tailUpdater = AtomicReferenceFieldUpdater.newUpdater + (TransferQueue.class, QNode.class, "tail"); + + /** + * Tries to cas nt as new tail. + */ + void advanceTail(QNode t, QNode nt) { + if (tail == t) + tailUpdater.compareAndSet(this, t, nt); + } + + static final AtomicReferenceFieldUpdater<TransferQueue, QNode> + cleanMeUpdater = AtomicReferenceFieldUpdater.newUpdater + (TransferQueue.class, QNode.class, "cleanMe"); + + /** + * Tries to CAS cleanMe slot. + */ + boolean casCleanMe(QNode cmp, QNode val) { + return (cleanMe == cmp && + cleanMeUpdater.compareAndSet(this, cmp, val)); + } + + /** + * Puts or takes an item. + */ + Object transfer(Object e, boolean timed, long nanos) { + /* Basic algorithm is to loop trying to take either of + * two actions: + * + * 1. If queue apparently empty or holding same-mode nodes, + * try to add node to queue of waiters, wait to be + * fulfilled (or cancelled) and return matching item. + * + * 2. If queue apparently contains waiting items, and this + * call is of complementary mode, try to fulfill by CAS'ing + * item field of waiting node and dequeuing it, and then + * returning matching item. + * + * In each case, along the way, check for and try to help + * advance head and tail on behalf of other stalled/slow + * threads. + * + * The loop starts off with a null check guarding against + * seeing uninitialized head or tail values. This never + * happens in current SynchronousQueue, but could if + * callers held non-volatile/final ref to the + * transferer. The check is here anyway because it places + * null checks at top of loop, which is usually faster + * than having them implicitly interspersed. + */ + + QNode s = null; // constructed/reused as needed + boolean isData = (e != null); + + for (;;) { + QNode t = tail; + QNode h = head; + if (t == null || h == null) // saw uninitialized value + continue; // spin + + if (h == t || t.isData == isData) { // empty or same-mode + QNode tn = t.next; + if (t != tail) // inconsistent read + continue; + if (tn != null) { // lagging tail + advanceTail(t, tn); + continue; + } + if (timed && nanos <= 0) // can't wait + return null; + if (s == null) + s = new QNode(e, isData); + if (!t.casNext(null, s)) // failed to link in + continue; + + advanceTail(t, s); // swing tail and wait + Object x = awaitFulfill(s, e, timed, nanos); + if (x == s) { // wait was cancelled + clean(t, s); + return null; + } + + if (!s.isOffList()) { // not already unlinked + advanceHead(t, s); // unlink if head + if (x != null) // and forget fields + s.item = s; + s.waiter = null; + } + return (x != null)? x : e; + + } else { // complementary-mode + QNode m = h.next; // node to fulfill + if (t != tail || m == null || h != head) + continue; // inconsistent read + + Object x = m.item; + if (isData == (x != null) || // m already fulfilled + x == m || // m cancelled + !m.casItem(x, e)) { // lost CAS + advanceHead(h, m); // dequeue and retry + continue; + } + + advanceHead(h, m); // successfully fulfilled + LockSupport.unpark(m.waiter); + return (x != null)? x : e; + } + } + } + + /** + * Spins/blocks until node s is fulfilled. + * + * @param s the waiting node + * @param e the comparison value for checking match + * @param timed true if timed wait + * @param nanos timeout value + * @return matched item, or s if cancelled + */ + Object awaitFulfill(QNode s, Object e, boolean timed, long nanos) { + /* Same idea as TransferStack.awaitFulfill */ + long lastTime = (timed)? System.nanoTime() : 0; + Thread w = Thread.currentThread(); + int spins = ((head.next == s) ? + (timed? maxTimedSpins : maxUntimedSpins) : 0); + for (;;) { + if (w.isInterrupted()) + s.tryCancel(e); + Object x = s.item; + if (x != e) + return x; + if (timed) { + long now = System.nanoTime(); + nanos -= now - lastTime; + lastTime = now; + if (nanos <= 0) { + s.tryCancel(e); + continue; + } + } + if (spins > 0) + --spins; + else if (s.waiter == null) + s.waiter = w; + else if (!timed) + LockSupport.park(this); + else if (nanos > spinForTimeoutThreshold) + LockSupport.parkNanos(this, nanos); + } + } + + /** + * Gets rid of cancelled node s with original predecessor pred. + */ + void clean(QNode pred, QNode s) { + s.waiter = null; // forget thread + /* + * At any given time, exactly one node on list cannot be + * deleted -- the last inserted node. To accommodate this, + * if we cannot delete s, we save its predecessor as + * "cleanMe", deleting the previously saved version + * first. At least one of node s or the node previously + * saved can always be deleted, so this always terminates. + */ + while (pred.next == s) { // Return early if already unlinked + QNode h = head; + QNode hn = h.next; // Absorb cancelled first node as head + if (hn != null && hn.isCancelled()) { + advanceHead(h, hn); + continue; + } + QNode t = tail; // Ensure consistent read for tail + if (t == h) + return; + QNode tn = t.next; + if (t != tail) + continue; + if (tn != null) { + advanceTail(t, tn); + continue; + } + if (s != t) { // If not tail, try to unsplice + QNode sn = s.next; + if (sn == s || pred.casNext(s, sn)) + return; + } + QNode dp = cleanMe; + if (dp != null) { // Try unlinking previous cancelled node + QNode d = dp.next; + QNode dn; + if (d == null || // d is gone or + d == dp || // d is off list or + !d.isCancelled() || // d not cancelled or + (d != t && // d not tail and + (dn = d.next) != null && // has successor + dn != d && // that is on list + dp.casNext(d, dn))) // d unspliced + casCleanMe(dp, null); + if (dp == pred) + return; // s is already saved node + } else if (casCleanMe(null, pred)) + return; // Postpone cleaning s + } + } + } + + /** + * The transferer. Set only in constructor, but cannot be declared + * as final without further complicating serialization. Since + * this is accessed only at most once per public method, there + * isn't a noticeable performance penalty for using volatile + * instead of final here. + */ + private transient volatile Transferer transferer; + + /** + * Creates a <tt>SynchronousQueue</tt> with nonfair access policy. + */ + public SynchronousQueue() { + this(false); + } + + /** + * Creates a <tt>SynchronousQueue</tt> with the specified fairness policy. + * + * @param fair if true, waiting threads contend in FIFO order for + * access; otherwise the order is unspecified. + */ + public SynchronousQueue(boolean fair) { + transferer = (fair)? new TransferQueue() : new TransferStack(); + } + + /** + * Adds the specified element to this queue, waiting if necessary for + * another thread to receive it. + * + * @throws InterruptedException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + */ + public void put(E o) throws InterruptedException { + if (o == null) throw new NullPointerException(); + if (transferer.transfer(o, false, 0) == null) { + Thread.interrupted(); + throw new InterruptedException(); + } + } + + /** + * Inserts the specified element into this queue, waiting if necessary + * up to the specified wait time for another thread to receive it. + * + * @return <tt>true</tt> if successful, or <tt>false</tt> if the + * specified waiting time elapses before a consumer appears. + * @throws InterruptedException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + */ + public boolean offer(E o, long timeout, TimeUnit unit) + throws InterruptedException { + if (o == null) throw new NullPointerException(); + if (transferer.transfer(o, true, unit.toNanos(timeout)) != null) + return true; + if (!Thread.interrupted()) + return false; + throw new InterruptedException(); + } + + /** + * Inserts the specified element into this queue, if another thread is + * waiting to receive it. + * + * @param e the element to add + * @return <tt>true</tt> if the element was added to this queue, else + * <tt>false</tt> + * @throws NullPointerException if the specified element is null + */ + public boolean offer(E e) { + if (e == null) throw new NullPointerException(); + return transferer.transfer(e, true, 0) != null; + } + + /** + * Retrieves and removes the head of this queue, waiting if necessary + * for another thread to insert it. + * + * @return the head of this queue + * @throws InterruptedException {@inheritDoc} + */ + public E take() throws InterruptedException { + Object e = transferer.transfer(null, false, 0); + if (e != null) + return (E)e; + Thread.interrupted(); + throw new InterruptedException(); + } + + /** + * Retrieves and removes the head of this queue, waiting + * if necessary up to the specified wait time, for another thread + * to insert it. + * + * @return the head of this queue, or <tt>null</tt> if the + * specified waiting time elapses before an element is present. + * @throws InterruptedException {@inheritDoc} + */ + public E poll(long timeout, TimeUnit unit) throws InterruptedException { + Object e = transferer.transfer(null, true, unit.toNanos(timeout)); + if (e != null || !Thread.interrupted()) + return (E)e; + throw new InterruptedException(); + } + + /** + * Retrieves and removes the head of this queue, if another thread + * is currently making an element available. + * + * @return the head of this queue, or <tt>null</tt> if no + * element is available. + */ + public E poll() { + return (E)transferer.transfer(null, true, 0); + } + + /** + * Always returns <tt>true</tt>. + * A <tt>SynchronousQueue</tt> has no internal capacity. + * + * @return <tt>true</tt> + */ + public boolean isEmpty() { + return true; + } + + /** + * Always returns zero. + * A <tt>SynchronousQueue</tt> has no internal capacity. + * + * @return zero. + */ + public int size() { + return 0; + } + + /** + * Always returns zero. + * A <tt>SynchronousQueue</tt> has no internal capacity. + * + * @return zero. + */ + public int remainingCapacity() { + return 0; + } + + /** + * Does nothing. + * A <tt>SynchronousQueue</tt> has no internal capacity. + */ + public void clear() { + } + + /** + * Always returns <tt>false</tt>. + * A <tt>SynchronousQueue</tt> has no internal capacity. + * + * @param o the element + * @return <tt>false</tt> + */ + public boolean contains(Object o) { + return false; + } + + /** + * Always returns <tt>false</tt>. + * A <tt>SynchronousQueue</tt> has no internal capacity. + * + * @param o the element to remove + * @return <tt>false</tt> + */ + public boolean remove(Object o) { + return false; + } + + /** + * Returns <tt>false</tt> unless the given collection is empty. + * A <tt>SynchronousQueue</tt> has no internal capacity. + * + * @param c the collection + * @return <tt>false</tt> unless given collection is empty + */ + public boolean containsAll(Collection<?> c) { + return c.isEmpty(); + } + + /** + * Always returns <tt>false</tt>. + * A <tt>SynchronousQueue</tt> has no internal capacity. + * + * @param c the collection + * @return <tt>false</tt> + */ + public boolean removeAll(Collection<?> c) { + return false; + } + + /** + * Always returns <tt>false</tt>. + * A <tt>SynchronousQueue</tt> has no internal capacity. + * + * @param c the collection + * @return <tt>false</tt> + */ + public boolean retainAll(Collection<?> c) { + return false; + } + + /** + * Always returns <tt>null</tt>. + * A <tt>SynchronousQueue</tt> does not return elements + * unless actively waited on. + * + * @return <tt>null</tt> + */ + public E peek() { + return null; + } + + static class EmptyIterator<E> implements Iterator<E> { + public boolean hasNext() { + return false; + } + public E next() { + throw new NoSuchElementException(); + } + public void remove() { + throw new IllegalStateException(); + } + } + + /** + * Returns an empty iterator in which <tt>hasNext</tt> always returns + * <tt>false</tt>. + * + * @return an empty iterator + */ + public Iterator<E> iterator() { + return new EmptyIterator<E>(); + } + + /** + * Returns a zero-length array. + * @return a zero-length array + */ + public Object[] toArray() { + return new Object[0]; + } + + /** + * Sets the zeroeth element of the specified array to <tt>null</tt> + * (if the array has non-zero length) and returns it. + * + * @param a the array + * @return the specified array + * @throws NullPointerException if the specified array is null + */ + public <T> T[] toArray(T[] a) { + if (a.length > 0) + a[0] = null; + return a; + } + + /** + * @throws UnsupportedOperationException {@inheritDoc} + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + * @throws IllegalArgumentException {@inheritDoc} + */ + public int drainTo(Collection<? super E> c) { + if (c == null) + throw new NullPointerException(); + if (c == this) + throw new IllegalArgumentException(); + int n = 0; + E e; + while ( (e = poll()) != null) { + c.add(e); + ++n; + } + return n; + } + + /** + * @throws UnsupportedOperationException {@inheritDoc} + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + * @throws IllegalArgumentException {@inheritDoc} + */ + public int drainTo(Collection<? super E> c, int maxElements) { + if (c == null) + throw new NullPointerException(); + if (c == this) + throw new IllegalArgumentException(); + int n = 0; + E e; + while (n < maxElements && (e = poll()) != null) { + c.add(e); + ++n; + } + return n; + } + + /* + * To cope with serialization strategy in the 1.5 version of + * SynchronousQueue, we declare some unused classes and fields + * that exist solely to enable serializability across versions. + * These fields are never used, so are initialized only if this + * object is ever serialized or deserialized. + */ + + static class WaitQueue implements java.io.Serializable { } + static class LifoWaitQueue extends WaitQueue { + private static final long serialVersionUID = -3633113410248163686L; + } + static class FifoWaitQueue extends WaitQueue { + private static final long serialVersionUID = -3623113410248163686L; + } + private ReentrantLock qlock; + private WaitQueue waitingProducers; + private WaitQueue waitingConsumers; + + /** + * Save the state to a stream (that is, serialize it). + * + * @param s the stream + */ + private void writeObject(java.io.ObjectOutputStream s) + throws java.io.IOException { + boolean fair = transferer instanceof TransferQueue; + if (fair) { + qlock = new ReentrantLock(true); + waitingProducers = new FifoWaitQueue(); + waitingConsumers = new FifoWaitQueue(); + } + else { + qlock = new ReentrantLock(); + waitingProducers = new LifoWaitQueue(); + waitingConsumers = new LifoWaitQueue(); + } + s.defaultWriteObject(); + } + + private void readObject(final java.io.ObjectInputStream s) + throws java.io.IOException, ClassNotFoundException { + s.defaultReadObject(); + if (waitingProducers instanceof FifoWaitQueue) + transferer = new TransferQueue(); + else + transferer = new TransferStack(); + } + +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/ThreadFactory.java b/libjava/classpath/external/jsr166/java/util/concurrent/ThreadFactory.java new file mode 100644 index 000000000..eca8dceb0 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/ThreadFactory.java @@ -0,0 +1,40 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; + +/** + * An object that creates new threads on demand. Using thread factories + * removes hardwiring of calls to {@link Thread#Thread(Runnable) new Thread}, + * enabling applications to use special thread subclasses, priorities, etc. + * + * <p> + * The simplest implementation of this interface is just: + * <pre> + * class SimpleThreadFactory implements ThreadFactory { + * public Thread newThread(Runnable r) { + * return new Thread(r); + * } + * } + * </pre> + * + * The {@link Executors#defaultThreadFactory} method provides a more + * useful simple implementation, that sets the created thread context + * to known values before returning it. + * @since 1.5 + * @author Doug Lea + */ +public interface ThreadFactory { + + /** + * Constructs a new <tt>Thread</tt>. Implementations may also initialize + * priority, name, daemon status, <tt>ThreadGroup</tt>, etc. + * + * @param r a runnable to be executed by new thread instance + * @return constructed thread + */ + Thread newThread(Runnable r); +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/ThreadPoolExecutor.java b/libjava/classpath/external/jsr166/java/util/concurrent/ThreadPoolExecutor.java new file mode 100644 index 000000000..e303f14a8 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/ThreadPoolExecutor.java @@ -0,0 +1,1605 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; +import java.util.concurrent.locks.*; +import java.util.*; + +/** + * An {@link ExecutorService} that executes each submitted task using + * one of possibly several pooled threads, normally configured + * using {@link Executors} factory methods. + * + * <p>Thread pools address two different problems: they usually + * provide improved performance when executing large numbers of + * asynchronous tasks, due to reduced per-task invocation overhead, + * and they provide a means of bounding and managing the resources, + * including threads, consumed when executing a collection of tasks. + * Each <tt>ThreadPoolExecutor</tt> also maintains some basic + * statistics, such as the number of completed tasks. + * + * <p>To be useful across a wide range of contexts, this class + * provides many adjustable parameters and extensibility + * hooks. However, programmers are urged to use the more convenient + * {@link Executors} factory methods {@link + * Executors#newCachedThreadPool} (unbounded thread pool, with + * automatic thread reclamation), {@link Executors#newFixedThreadPool} + * (fixed size thread pool) and {@link + * Executors#newSingleThreadExecutor} (single background thread), that + * preconfigure settings for the most common usage + * scenarios. Otherwise, use the following guide when manually + * configuring and tuning this class: + * + * <dl> + * + * <dt>Core and maximum pool sizes</dt> + * + * <dd>A <tt>ThreadPoolExecutor</tt> will automatically adjust the + * pool size + * (see {@link ThreadPoolExecutor#getPoolSize}) + * according to the bounds set by corePoolSize + * (see {@link ThreadPoolExecutor#getCorePoolSize}) + * and + * maximumPoolSize + * (see {@link ThreadPoolExecutor#getMaximumPoolSize}). + * When a new task is submitted in method {@link + * ThreadPoolExecutor#execute}, and fewer than corePoolSize threads + * are running, a new thread is created to handle the request, even if + * other worker threads are idle. If there are more than + * corePoolSize but less than maximumPoolSize threads running, a new + * thread will be created only if the queue is full. By setting + * corePoolSize and maximumPoolSize the same, you create a fixed-size + * thread pool. By setting maximumPoolSize to an essentially unbounded + * value such as <tt>Integer.MAX_VALUE</tt>, you allow the pool to + * accommodate an arbitrary number of concurrent tasks. Most typically, + * core and maximum pool sizes are set only upon construction, but they + * may also be changed dynamically using {@link + * ThreadPoolExecutor#setCorePoolSize} and {@link + * ThreadPoolExecutor#setMaximumPoolSize}. <dd> + * + * <dt> On-demand construction + * + * <dd> By default, even core threads are initially created and + * started only when new tasks arrive, but this can be overridden + * dynamically using method {@link + * ThreadPoolExecutor#prestartCoreThread} or + * {@link ThreadPoolExecutor#prestartAllCoreThreads}. + * You probably want to prestart threads if you construct the + * pool with a non-empty queue. </dd> + * + * <dt>Creating new threads</dt> + * + * <dd>New threads are created using a {@link + * java.util.concurrent.ThreadFactory}. If not otherwise specified, a + * {@link Executors#defaultThreadFactory} is used, that creates threads to all + * be in the same {@link ThreadGroup} and with the same + * <tt>NORM_PRIORITY</tt> priority and non-daemon status. By supplying + * a different ThreadFactory, you can alter the thread's name, thread + * group, priority, daemon status, etc. If a <tt>ThreadFactory</tt> fails to create + * a thread when asked by returning null from <tt>newThread</tt>, + * the executor will continue, but might + * not be able to execute any tasks. </dd> + * + * <dt>Keep-alive times</dt> + * + * <dd>If the pool currently has more than corePoolSize threads, + * excess threads will be terminated if they have been idle for more + * than the keepAliveTime (see {@link + * ThreadPoolExecutor#getKeepAliveTime}). This provides a means of + * reducing resource consumption when the pool is not being actively + * used. If the pool becomes more active later, new threads will be + * constructed. This parameter can also be changed dynamically using + * method {@link ThreadPoolExecutor#setKeepAliveTime}. Using a value + * of <tt>Long.MAX_VALUE</tt> {@link TimeUnit#NANOSECONDS} effectively + * disables idle threads from ever terminating prior to shut down. By + * default, the keep-alive policy applies only when there are more + * than corePoolSizeThreads. But method {@link + * ThreadPoolExecutor#allowCoreThreadTimeOut} can be used to apply + * this time-out policy to core threads as well, so long as + * the keepAliveTime value is non-zero. </dd> + * + * <dt>Queuing</dt> + * + * <dd>Any {@link BlockingQueue} may be used to transfer and hold + * submitted tasks. The use of this queue interacts with pool sizing: + * + * <ul> + * + * <li> If fewer than corePoolSize threads are running, the Executor + * always prefers adding a new thread + * rather than queuing.</li> + * + * <li> If corePoolSize or more threads are running, the Executor + * always prefers queuing a request rather than adding a new + * thread.</li> + * + * <li> If a request cannot be queued, a new thread is created unless + * this would exceed maximumPoolSize, in which case, the task will be + * rejected.</li> + * + * </ul> + * + * There are three general strategies for queuing: + * <ol> + * + * <li> <em> Direct handoffs.</em> A good default choice for a work + * queue is a {@link SynchronousQueue} that hands off tasks to threads + * without otherwise holding them. Here, an attempt to queue a task + * will fail if no threads are immediately available to run it, so a + * new thread will be constructed. This policy avoids lockups when + * handling sets of requests that might have internal dependencies. + * Direct handoffs generally require unbounded maximumPoolSizes to + * avoid rejection of new submitted tasks. This in turn admits the + * possibility of unbounded thread growth when commands continue to + * arrive on average faster than they can be processed. </li> + * + * <li><em> Unbounded queues.</em> Using an unbounded queue (for + * example a {@link LinkedBlockingQueue} without a predefined + * capacity) will cause new tasks to wait in the queue when all + * corePoolSize threads are busy. Thus, no more than corePoolSize + * threads will ever be created. (And the value of the maximumPoolSize + * therefore doesn't have any effect.) This may be appropriate when + * each task is completely independent of others, so tasks cannot + * affect each others execution; for example, in a web page server. + * While this style of queuing can be useful in smoothing out + * transient bursts of requests, it admits the possibility of + * unbounded work queue growth when commands continue to arrive on + * average faster than they can be processed. </li> + * + * <li><em>Bounded queues.</em> A bounded queue (for example, an + * {@link ArrayBlockingQueue}) helps prevent resource exhaustion when + * used with finite maximumPoolSizes, but can be more difficult to + * tune and control. Queue sizes and maximum pool sizes may be traded + * off for each other: Using large queues and small pools minimizes + * CPU usage, OS resources, and context-switching overhead, but can + * lead to artificially low throughput. If tasks frequently block (for + * example if they are I/O bound), a system may be able to schedule + * time for more threads than you otherwise allow. Use of small queues + * generally requires larger pool sizes, which keeps CPUs busier but + * may encounter unacceptable scheduling overhead, which also + * decreases throughput. </li> + * + * </ol> + * + * </dd> + * + * <dt>Rejected tasks</dt> + * + * <dd> New tasks submitted in method {@link + * ThreadPoolExecutor#execute} will be <em>rejected</em> when the + * Executor has been shut down, and also when the Executor uses finite + * bounds for both maximum threads and work queue capacity, and is + * saturated. In either case, the <tt>execute</tt> method invokes the + * {@link RejectedExecutionHandler#rejectedExecution} method of its + * {@link RejectedExecutionHandler}. Four predefined handler policies + * are provided: + * + * <ol> + * + * <li> In the + * default {@link ThreadPoolExecutor.AbortPolicy}, the handler throws a + * runtime {@link RejectedExecutionException} upon rejection. </li> + * + * <li> In {@link + * ThreadPoolExecutor.CallerRunsPolicy}, the thread that invokes + * <tt>execute</tt> itself runs the task. This provides a simple + * feedback control mechanism that will slow down the rate that new + * tasks are submitted. </li> + * + * <li> In {@link ThreadPoolExecutor.DiscardPolicy}, + * a task that cannot be executed is simply dropped. </li> + * + * <li>In {@link + * ThreadPoolExecutor.DiscardOldestPolicy}, if the executor is not + * shut down, the task at the head of the work queue is dropped, and + * then execution is retried (which can fail again, causing this to be + * repeated.) </li> + * + * </ol> + * + * It is possible to define and use other kinds of {@link + * RejectedExecutionHandler} classes. Doing so requires some care + * especially when policies are designed to work only under particular + * capacity or queuing policies. </dd> + * + * <dt>Hook methods</dt> + * + * <dd>This class provides <tt>protected</tt> overridable {@link + * ThreadPoolExecutor#beforeExecute} and {@link + * ThreadPoolExecutor#afterExecute} methods that are called before and + * after execution of each task. These can be used to manipulate the + * execution environment; for example, reinitializing ThreadLocals, + * gathering statistics, or adding log entries. Additionally, method + * {@link ThreadPoolExecutor#terminated} can be overridden to perform + * any special processing that needs to be done once the Executor has + * fully terminated. + * + * <p>If hook or callback methods throw + * exceptions, internal worker threads may in turn fail and + * abruptly terminate.</dd> + * + * <dt>Queue maintenance</dt> + * + * <dd> Method {@link ThreadPoolExecutor#getQueue} allows access to + * the work queue for purposes of monitoring and debugging. Use of + * this method for any other purpose is strongly discouraged. Two + * supplied methods, {@link ThreadPoolExecutor#remove} and {@link + * ThreadPoolExecutor#purge} are available to assist in storage + * reclamation when large numbers of queued tasks become + * cancelled.</dd> + * + * <dt>Finalization</dt> + * + * <dd> A pool that is no longer referenced in a program <em>AND</em> + * has no remaining threads will be <tt>shutdown</tt> + * automatically. If you would like to ensure that unreferenced pools + * are reclaimed even if users forget to call {@link + * ThreadPoolExecutor#shutdown}, then you must arrange that unused + * threads eventually die, by setting appropriate keep-alive times, + * using a lower bound of zero core threads and/or setting {@link + * ThreadPoolExecutor#allowCoreThreadTimeOut}. </dd> </dl> + * + * <p> <b>Extension example</b>. Most extensions of this class + * override one or more of the protected hook methods. For example, + * here is a subclass that adds a simple pause/resume feature: + * + * <pre> + * class PausableThreadPoolExecutor extends ThreadPoolExecutor { + * private boolean isPaused; + * private ReentrantLock pauseLock = new ReentrantLock(); + * private Condition unpaused = pauseLock.newCondition(); + * + * public PausableThreadPoolExecutor(...) { super(...); } + * + * protected void beforeExecute(Thread t, Runnable r) { + * super.beforeExecute(t, r); + * pauseLock.lock(); + * try { + * while (isPaused) unpaused.await(); + * } catch (InterruptedException ie) { + * t.interrupt(); + * } finally { + * pauseLock.unlock(); + * } + * } + * + * public void pause() { + * pauseLock.lock(); + * try { + * isPaused = true; + * } finally { + * pauseLock.unlock(); + * } + * } + * + * public void resume() { + * pauseLock.lock(); + * try { + * isPaused = false; + * unpaused.signalAll(); + * } finally { + * pauseLock.unlock(); + * } + * } + * } + * </pre> + * @since 1.5 + * @author Doug Lea + */ +public class ThreadPoolExecutor extends AbstractExecutorService { + /** + * Only used to force toArray() to produce a Runnable[]. + */ + private static final Runnable[] EMPTY_RUNNABLE_ARRAY = new Runnable[0]; + + /** + * Permission for checking shutdown + */ + private static final RuntimePermission shutdownPerm = + new RuntimePermission("modifyThread"); + + /** + * Queue used for holding tasks and handing off to worker threads. + */ + private final BlockingQueue<Runnable> workQueue; + + /** + * Lock held on updates to poolSize, corePoolSize, maximumPoolSize, and + * workers set. + */ + private final ReentrantLock mainLock = new ReentrantLock(); + + /** + * Wait condition to support awaitTermination + */ + private final Condition termination = mainLock.newCondition(); + + /** + * Set containing all worker threads in pool. + */ + private final HashSet<Worker> workers = new HashSet<Worker>(); + + /** + * Timeout in nanoseconds for idle threads waiting for work. + * Threads use this timeout only when there are more than + * corePoolSize present. Otherwise they wait forever for new work. + */ + private volatile long keepAliveTime; + + /** + * If false (default) core threads stay alive even when idle. + * If true, core threads use keepAliveTime to time out waiting for work. + */ + private volatile boolean allowCoreThreadTimeOut; + + /** + * Core pool size, updated only while holding mainLock, + * but volatile to allow concurrent readability even + * during updates. + */ + private volatile int corePoolSize; + + /** + * Maximum pool size, updated only while holding mainLock + * but volatile to allow concurrent readability even + * during updates. + */ + private volatile int maximumPoolSize; + + /** + * Current pool size, updated only while holding mainLock + * but volatile to allow concurrent readability even + * during updates. + */ + private volatile int poolSize; + + /** + * Lifecycle state + */ + volatile int runState; + + // Special values for runState + /** Normal, not-shutdown mode */ + static final int RUNNING = 0; + /** Controlled shutdown mode */ + static final int SHUTDOWN = 1; + /** Immediate shutdown mode */ + static final int STOP = 2; + /** Final state */ + static final int TERMINATED = 3; + + /** + * Handler called when saturated or shutdown in execute. + */ + private volatile RejectedExecutionHandler handler; + + /** + * Factory for new threads. + */ + private volatile ThreadFactory threadFactory; + + /** + * Tracks largest attained pool size. + */ + private int largestPoolSize; + + /** + * Counter for completed tasks. Updated only on termination of + * worker threads. + */ + private long completedTaskCount; + + /** + * The default rejected execution handler + */ + private static final RejectedExecutionHandler defaultHandler = + new AbortPolicy(); + + /** + * Invokes the rejected execution handler for the given command. + */ + void reject(Runnable command) { + handler.rejectedExecution(command, this); + } + + /** + * Creates and returns a new thread running firstTask as its first + * task. Call only while holding mainLock. + * @param firstTask the task the new thread should run first (or + * null if none) + * @return the new thread, or null if threadFactory fails to create thread + */ + private Thread addThread(Runnable firstTask) { + if (runState == TERMINATED) // Don't create thread if terminated + return null; + Worker w = new Worker(firstTask); + Thread t = threadFactory.newThread(w); + if (t != null) { + w.thread = t; + workers.add(w); + int nt = ++poolSize; + if (nt > largestPoolSize) + largestPoolSize = nt; + } + return t; + } + + /** + * Creates and starts a new thread running firstTask as its first + * task, only if fewer than corePoolSize threads are running. + * @param firstTask the task the new thread should run first (or + * null if none) + * @return true if successful. + */ + private boolean addIfUnderCorePoolSize(Runnable firstTask) { + Thread t = null; + final ReentrantLock mainLock = this.mainLock; + mainLock.lock(); + try { + if (poolSize < corePoolSize) + t = addThread(firstTask); + } finally { + mainLock.unlock(); + } + if (t == null) + return false; + t.start(); + return true; + } + + /** + * Creates and starts a new thread only if fewer than maximumPoolSize + * threads are running. The new thread runs as its first task the + * next task in queue, or if there is none, the given task. + * @param firstTask the task the new thread should run first (or + * null if none) + * @return 0 if a new thread cannot be created, a positive number + * if firstTask will be run in a new thread, or a negative number + * if a new thread was created but is running some other task, in + * which case the caller must try some other way to run firstTask + * (perhaps by calling this method again). + */ + private int addIfUnderMaximumPoolSize(Runnable firstTask) { + Thread t = null; + int status = 0; + final ReentrantLock mainLock = this.mainLock; + mainLock.lock(); + try { + if (poolSize < maximumPoolSize) { + Runnable next = workQueue.poll(); + if (next == null) { + next = firstTask; + status = 1; + } else + status = -1; + t = addThread(next); + } + } finally { + mainLock.unlock(); + } + if (t == null) + return 0; + t.start(); + return status; + } + + + /** + * Gets the next task for a worker thread to run. + * @return the task + */ + Runnable getTask() { + for (;;) { + try { + switch (runState) { + case RUNNING: { + // untimed wait if core and not allowing core timeout + if (poolSize <= corePoolSize && !allowCoreThreadTimeOut) + return workQueue.take(); + + long timeout = keepAliveTime; + if (timeout <= 0) // die immediately for 0 timeout + return null; + Runnable r = workQueue.poll(timeout, TimeUnit.NANOSECONDS); + if (r != null) + return r; + if (poolSize > corePoolSize || allowCoreThreadTimeOut) + return null; // timed out + // Else, after timeout, the pool shrank. Retry + break; + } + + case SHUTDOWN: { + // Help drain queue + Runnable r = workQueue.poll(); + if (r != null) + return r; + + // Check if can terminate + if (workQueue.isEmpty()) { + interruptIdleWorkers(); + return null; + } + + // Else there could still be delayed tasks in queue. + return workQueue.take(); + } + + case STOP: + return null; + default: + assert false; + } + } catch (InterruptedException ie) { + // On interruption, re-check runstate + } + } + } + + /** + * Wakes up all threads that might be waiting for tasks. + */ + void interruptIdleWorkers() { + final ReentrantLock mainLock = this.mainLock; + mainLock.lock(); + try { + for (Worker w : workers) + w.interruptIfIdle(); + } finally { + mainLock.unlock(); + } + } + + /** + * Performs bookkeeping for a terminated worker thread. + * @param w the worker + */ + void workerDone(Worker w) { + final ReentrantLock mainLock = this.mainLock; + mainLock.lock(); + try { + completedTaskCount += w.completedTasks; + workers.remove(w); + if (--poolSize > 0) + return; + + // Else, this is the last thread. Deal with potential shutdown. + + int state = runState; + assert state != TERMINATED; + + if (state != STOP) { + // If there are queued tasks but no threads, create + // replacement thread. We must create it initially + // idle to avoid orphaned tasks in case addThread + // fails. This also handles case of delayed tasks + // that will sometime later become runnable. + if (!workQueue.isEmpty()) { + Thread t = addThread(null); + if (t != null) + t.start(); + return; + } + + // Otherwise, we can exit without replacement + if (state == RUNNING) + return; + } + + // Either state is STOP, or state is SHUTDOWN and there is + // no work to do. So we can terminate. + termination.signalAll(); + runState = TERMINATED; + // fall through to call terminate() outside of lock. + } finally { + mainLock.unlock(); + } + + assert runState == TERMINATED; + terminated(); + } + + /** + * Worker threads + */ + private class Worker implements Runnable { + + /** + * The runLock is acquired and released surrounding each task + * execution. It mainly protects against interrupts that are + * intended to cancel the worker thread from instead + * interrupting the task being run. + */ + private final ReentrantLock runLock = new ReentrantLock(); + + /** + * Initial task to run before entering run loop + */ + private Runnable firstTask; + + /** + * Per thread completed task counter; accumulated + * into completedTaskCount upon termination. + */ + volatile long completedTasks; + + /** + * Thread this worker is running in. Acts as a final field, + * but cannot be set until thread is created. + */ + Thread thread; + + Worker(Runnable firstTask) { + this.firstTask = firstTask; + } + + boolean isActive() { + return runLock.isLocked(); + } + + /** + * Interrupts thread if not running a task. + */ + void interruptIfIdle() { + final ReentrantLock runLock = this.runLock; + if (runLock.tryLock()) { + try { + thread.interrupt(); + } finally { + runLock.unlock(); + } + } + } + + /** + * Interrupts thread even if running a task. + */ + void interruptNow() { + thread.interrupt(); + } + + /** + * Runs a single task between before/after methods. + */ + private void runTask(Runnable task) { + final ReentrantLock runLock = this.runLock; + runLock.lock(); + try { + // If not shutting down then clear an outstanding interrupt. + if (runState != STOP && + Thread.interrupted() && + runState == STOP) // Re-interrupt if stopped after clearing + thread.interrupt(); + boolean ran = false; + beforeExecute(thread, task); + try { + task.run(); + ran = true; + afterExecute(task, null); + ++completedTasks; + } catch (RuntimeException ex) { + if (!ran) + afterExecute(task, ex); + // Else the exception occurred within + // afterExecute itself in which case we don't + // want to call it again. + throw ex; + } + } finally { + runLock.unlock(); + } + } + + /** + * Main run loop + */ + public void run() { + try { + Runnable task = firstTask; + firstTask = null; + while (task != null || (task = getTask()) != null) { + runTask(task); + task = null; // unnecessary but can help GC + } + } finally { + workerDone(this); + } + } + } + + // Public methods + + /** + * Creates a new <tt>ThreadPoolExecutor</tt> with the given initial + * parameters and default thread factory and rejected execution handler. + * It may be more convenient to use one of the {@link Executors} factory + * methods instead of this general purpose constructor. + * + * @param corePoolSize the number of threads to keep in the + * pool, even if they are idle. + * @param maximumPoolSize the maximum number of threads to allow in the + * pool. + * @param keepAliveTime when the number of threads is greater than + * the core, this is the maximum time that excess idle threads + * will wait for new tasks before terminating. + * @param unit the time unit for the keepAliveTime + * argument. + * @param workQueue the queue to use for holding tasks before they + * are executed. This queue will hold only the <tt>Runnable</tt> + * tasks submitted by the <tt>execute</tt> method. + * @throws IllegalArgumentException if corePoolSize, or + * keepAliveTime less than zero, or if maximumPoolSize less than or + * equal to zero, or if corePoolSize greater than maximumPoolSize. + * @throws NullPointerException if <tt>workQueue</tt> is null + */ + public ThreadPoolExecutor(int corePoolSize, + int maximumPoolSize, + long keepAliveTime, + TimeUnit unit, + BlockingQueue<Runnable> workQueue) { + this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, + Executors.defaultThreadFactory(), defaultHandler); + } + + /** + * Creates a new <tt>ThreadPoolExecutor</tt> with the given initial + * parameters and default rejected execution handler. + * + * @param corePoolSize the number of threads to keep in the + * pool, even if they are idle. + * @param maximumPoolSize the maximum number of threads to allow in the + * pool. + * @param keepAliveTime when the number of threads is greater than + * the core, this is the maximum time that excess idle threads + * will wait for new tasks before terminating. + * @param unit the time unit for the keepAliveTime + * argument. + * @param workQueue the queue to use for holding tasks before they + * are executed. This queue will hold only the <tt>Runnable</tt> + * tasks submitted by the <tt>execute</tt> method. + * @param threadFactory the factory to use when the executor + * creates a new thread. + * @throws IllegalArgumentException if corePoolSize, or + * keepAliveTime less than zero, or if maximumPoolSize less than or + * equal to zero, or if corePoolSize greater than maximumPoolSize. + * @throws NullPointerException if <tt>workQueue</tt> + * or <tt>threadFactory</tt> are null. + */ + public ThreadPoolExecutor(int corePoolSize, + int maximumPoolSize, + long keepAliveTime, + TimeUnit unit, + BlockingQueue<Runnable> workQueue, + ThreadFactory threadFactory) { + this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, + threadFactory, defaultHandler); + } + + /** + * Creates a new <tt>ThreadPoolExecutor</tt> with the given initial + * parameters and default thread factory. + * + * @param corePoolSize the number of threads to keep in the + * pool, even if they are idle. + * @param maximumPoolSize the maximum number of threads to allow in the + * pool. + * @param keepAliveTime when the number of threads is greater than + * the core, this is the maximum time that excess idle threads + * will wait for new tasks before terminating. + * @param unit the time unit for the keepAliveTime + * argument. + * @param workQueue the queue to use for holding tasks before they + * are executed. This queue will hold only the <tt>Runnable</tt> + * tasks submitted by the <tt>execute</tt> method. + * @param handler the handler to use when execution is blocked + * because the thread bounds and queue capacities are reached. + * @throws IllegalArgumentException if corePoolSize, or + * keepAliveTime less than zero, or if maximumPoolSize less than or + * equal to zero, or if corePoolSize greater than maximumPoolSize. + * @throws NullPointerException if <tt>workQueue</tt> + * or <tt>handler</tt> are null. + */ + public ThreadPoolExecutor(int corePoolSize, + int maximumPoolSize, + long keepAliveTime, + TimeUnit unit, + BlockingQueue<Runnable> workQueue, + RejectedExecutionHandler handler) { + this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, + Executors.defaultThreadFactory(), handler); + } + + /** + * Creates a new <tt>ThreadPoolExecutor</tt> with the given initial + * parameters. + * + * @param corePoolSize the number of threads to keep in the + * pool, even if they are idle. + * @param maximumPoolSize the maximum number of threads to allow in the + * pool. + * @param keepAliveTime when the number of threads is greater than + * the core, this is the maximum time that excess idle threads + * will wait for new tasks before terminating. + * @param unit the time unit for the keepAliveTime + * argument. + * @param workQueue the queue to use for holding tasks before they + * are executed. This queue will hold only the <tt>Runnable</tt> + * tasks submitted by the <tt>execute</tt> method. + * @param threadFactory the factory to use when the executor + * creates a new thread. + * @param handler the handler to use when execution is blocked + * because the thread bounds and queue capacities are reached. + * @throws IllegalArgumentException if corePoolSize, or + * keepAliveTime less than zero, or if maximumPoolSize less than or + * equal to zero, or if corePoolSize greater than maximumPoolSize. + * @throws NullPointerException if <tt>workQueue</tt> + * or <tt>threadFactory</tt> or <tt>handler</tt> are null. + */ + public ThreadPoolExecutor(int corePoolSize, + int maximumPoolSize, + long keepAliveTime, + TimeUnit unit, + BlockingQueue<Runnable> workQueue, + ThreadFactory threadFactory, + RejectedExecutionHandler handler) { + if (corePoolSize < 0 || + maximumPoolSize <= 0 || + maximumPoolSize < corePoolSize || + keepAliveTime < 0) + throw new IllegalArgumentException(); + if (workQueue == null || threadFactory == null || handler == null) + throw new NullPointerException(); + this.corePoolSize = corePoolSize; + this.maximumPoolSize = maximumPoolSize; + this.workQueue = workQueue; + this.keepAliveTime = unit.toNanos(keepAliveTime); + this.threadFactory = threadFactory; + this.handler = handler; + } + + + /** + * Executes the given task sometime in the future. The task + * may execute in a new thread or in an existing pooled thread. + * + * If the task cannot be submitted for execution, either because this + * executor has been shutdown or because its capacity has been reached, + * the task is handled by the current <tt>RejectedExecutionHandler</tt>. + * + * @param command the task to execute + * @throws RejectedExecutionException at discretion of + * <tt>RejectedExecutionHandler</tt>, if task cannot be accepted + * for execution + * @throws NullPointerException if command is null + */ + public void execute(Runnable command) { + if (command == null) + throw new NullPointerException(); + for (;;) { + if (runState != RUNNING) { + reject(command); + return; + } + if (poolSize < corePoolSize && addIfUnderCorePoolSize(command)) + return; + if (workQueue.offer(command)) + return; + int status = addIfUnderMaximumPoolSize(command); + if (status > 0) // created new thread + return; + if (status == 0) { // failed to create thread + reject(command); + return; + } + // Retry if created a new thread but it is busy with another task + } + } + + /** + * Initiates an orderly shutdown in which previously submitted + * tasks are executed, but no new tasks will be + * accepted. Invocation has no additional effect if already shut + * down. + * @throws SecurityException if a security manager exists and + * shutting down this ExecutorService may manipulate threads that + * the caller is not permitted to modify because it does not hold + * {@link java.lang.RuntimePermission}<tt>("modifyThread")</tt>, + * or the security manager's <tt>checkAccess</tt> method denies access. + */ + public void shutdown() { + // Fail if caller doesn't have modifyThread permission. + SecurityManager security = System.getSecurityManager(); + if (security != null) + security.checkPermission(shutdownPerm); + + boolean fullyTerminated = false; + final ReentrantLock mainLock = this.mainLock; + mainLock.lock(); + try { + if (workers.size() > 0) { + // Check if caller can modify worker threads. This + // might not be true even if passed above check, if + // the SecurityManager treats some threads specially. + if (security != null) { + for (Worker w: workers) + security.checkAccess(w.thread); + } + + int state = runState; + if (state == RUNNING) // don't override shutdownNow + runState = SHUTDOWN; + + try { + for (Worker w: workers) + w.interruptIfIdle(); + } catch (SecurityException se) { + // If SecurityManager allows above checks, but + // then unexpectedly throws exception when + // interrupting threads (which it ought not do), + // back out as cleanly as we can. Some threads may + // have been killed but we remain in non-shutdown + // state. + runState = state; + throw se; + } + } + else { // If no workers, trigger full termination now + fullyTerminated = true; + runState = TERMINATED; + termination.signalAll(); + } + } finally { + mainLock.unlock(); + } + if (fullyTerminated) + terminated(); + } + + + /** + * Attempts to stop all actively executing tasks, halts the + * processing of waiting tasks, and returns a list of the tasks + * that were awaiting execution. + * + * <p>There are no guarantees beyond best-effort attempts to stop + * processing actively executing tasks. This implementation + * cancels tasks via {@link Thread#interrupt}, so any task that + * fails to respond to interrupts may never terminate. + * + * @return list of tasks that never commenced execution + * @throws SecurityException if a security manager exists and + * shutting down this ExecutorService may manipulate threads that + * the caller is not permitted to modify because it does not hold + * {@link java.lang.RuntimePermission}<tt>("modifyThread")</tt>, + * or the security manager's <tt>checkAccess</tt> method denies access. + */ + public List<Runnable> shutdownNow() { + // Almost the same code as shutdown() + SecurityManager security = System.getSecurityManager(); + if (security != null) + security.checkPermission(shutdownPerm); + + boolean fullyTerminated = false; + final ReentrantLock mainLock = this.mainLock; + mainLock.lock(); + try { + if (workers.size() > 0) { + if (security != null) { + for (Worker w: workers) + security.checkAccess(w.thread); + } + + int state = runState; + if (state != TERMINATED) + runState = STOP; + try { + for (Worker w : workers) + w.interruptNow(); + } catch (SecurityException se) { + runState = state; // back out; + throw se; + } + } + else { // If no workers, trigger full termination now + fullyTerminated = true; + runState = TERMINATED; + termination.signalAll(); + } + } finally { + mainLock.unlock(); + } + if (fullyTerminated) + terminated(); + return Arrays.asList(workQueue.toArray(EMPTY_RUNNABLE_ARRAY)); + } + + public boolean isShutdown() { + return runState != RUNNING; + } + + /** + * Returns true if this executor is in the process of terminating + * after <tt>shutdown</tt> or <tt>shutdownNow</tt> but has not + * completely terminated. This method may be useful for + * debugging. A return of <tt>true</tt> reported a sufficient + * period after shutdown may indicate that submitted tasks have + * ignored or suppressed interruption, causing this executor not + * to properly terminate. + * @return true if terminating but not yet terminated. + */ + public boolean isTerminating() { + return runState == STOP; + } + + public boolean isTerminated() { + return runState == TERMINATED; + } + + public boolean awaitTermination(long timeout, TimeUnit unit) + throws InterruptedException { + long nanos = unit.toNanos(timeout); + final ReentrantLock mainLock = this.mainLock; + mainLock.lock(); + try { + for (;;) { + if (runState == TERMINATED) + return true; + if (nanos <= 0) + return false; + nanos = termination.awaitNanos(nanos); + } + } finally { + mainLock.unlock(); + } + } + + /** + * Invokes <tt>shutdown</tt> when this executor is no longer + * referenced. + */ + protected void finalize() { + shutdown(); + } + + /** + * Sets the thread factory used to create new threads. + * + * @param threadFactory the new thread factory + * @throws NullPointerException if threadFactory is null + * @see #getThreadFactory + */ + public void setThreadFactory(ThreadFactory threadFactory) { + if (threadFactory == null) + throw new NullPointerException(); + this.threadFactory = threadFactory; + } + + /** + * Returns the thread factory used to create new threads. + * + * @return the current thread factory + * @see #setThreadFactory + */ + public ThreadFactory getThreadFactory() { + return threadFactory; + } + + /** + * Sets a new handler for unexecutable tasks. + * + * @param handler the new handler + * @throws NullPointerException if handler is null + * @see #getRejectedExecutionHandler + */ + public void setRejectedExecutionHandler(RejectedExecutionHandler handler) { + if (handler == null) + throw new NullPointerException(); + this.handler = handler; + } + + /** + * Returns the current handler for unexecutable tasks. + * + * @return the current handler + * @see #setRejectedExecutionHandler + */ + public RejectedExecutionHandler getRejectedExecutionHandler() { + return handler; + } + + /** + * Returns the task queue used by this executor. Access to the + * task queue is intended primarily for debugging and monitoring. + * This queue may be in active use. Retrieving the task queue + * does not prevent queued tasks from executing. + * + * @return the task queue + */ + public BlockingQueue<Runnable> getQueue() { + return workQueue; + } + + /** + * Removes this task from the executor's internal queue if it is + * present, thus causing it not to be run if it has not already + * started. + * + * <p> This method may be useful as one part of a cancellation + * scheme. It may fail to remove tasks that have been converted + * into other forms before being placed on the internal queue. For + * example, a task entered using <tt>submit</tt> might be + * converted into a form that maintains <tt>Future</tt> status. + * However, in such cases, method {@link ThreadPoolExecutor#purge} + * may be used to remove those Futures that have been cancelled. + * + * @param task the task to remove + * @return true if the task was removed + */ + public boolean remove(Runnable task) { + return getQueue().remove(task); + } + + + /** + * Tries to remove from the work queue all {@link Future} + * tasks that have been cancelled. This method can be useful as a + * storage reclamation operation, that has no other impact on + * functionality. Cancelled tasks are never executed, but may + * accumulate in work queues until worker threads can actively + * remove them. Invoking this method instead tries to remove them now. + * However, this method may fail to remove tasks in + * the presence of interference by other threads. + */ + public void purge() { + // Fail if we encounter interference during traversal + try { + Iterator<Runnable> it = getQueue().iterator(); + while (it.hasNext()) { + Runnable r = it.next(); + if (r instanceof Future<?>) { + Future<?> c = (Future<?>)r; + if (c.isCancelled()) + it.remove(); + } + } + } + catch (ConcurrentModificationException ex) { + return; + } + } + + /** + * Sets the core number of threads. This overrides any value set + * in the constructor. If the new value is smaller than the + * current value, excess existing threads will be terminated when + * they next become idle. If larger, new threads will, if needed, + * be started to execute any queued tasks. + * + * @param corePoolSize the new core size + * @throws IllegalArgumentException if <tt>corePoolSize</tt> + * less than zero + * @see #getCorePoolSize + */ + public void setCorePoolSize(int corePoolSize) { + if (corePoolSize < 0) + throw new IllegalArgumentException(); + final ReentrantLock mainLock = this.mainLock; + mainLock.lock(); + try { + int extra = this.corePoolSize - corePoolSize; + this.corePoolSize = corePoolSize; + if (extra < 0) { + int n = workQueue.size(); + // We have to create initially-idle threads here + // because we otherwise have no recourse about + // what to do with a dequeued task if addThread fails. + while (extra++ < 0 && n-- > 0 && poolSize < corePoolSize ) { + Thread t = addThread(null); + if (t != null) + t.start(); + else + break; + } + } + else if (extra > 0 && poolSize > corePoolSize) { + Iterator<Worker> it = workers.iterator(); + while (it.hasNext() && + extra-- > 0 && + poolSize > corePoolSize && + workQueue.remainingCapacity() == 0) + it.next().interruptIfIdle(); + } + } finally { + mainLock.unlock(); + } + } + + /** + * Returns the core number of threads. + * + * @return the core number of threads + * @see #setCorePoolSize + */ + public int getCorePoolSize() { + return corePoolSize; + } + + /** + * Starts a core thread, causing it to idly wait for work. This + * overrides the default policy of starting core threads only when + * new tasks are executed. This method will return <tt>false</tt> + * if all core threads have already been started. + * @return true if a thread was started + */ + public boolean prestartCoreThread() { + return addIfUnderCorePoolSize(null); + } + + /** + * Starts all core threads, causing them to idly wait for work. This + * overrides the default policy of starting core threads only when + * new tasks are executed. + * @return the number of threads started. + */ + public int prestartAllCoreThreads() { + int n = 0; + while (addIfUnderCorePoolSize(null)) + ++n; + return n; + } + + /** + * Returns true if this pool allows core threads to time out and + * terminate if no tasks arrive within the keepAlive time, being + * replaced if needed when new tasks arrive. When true, the same + * keep-alive policy applying to non-core threads applies also to + * core threads. When false (the default), core threads are never + * terminated due to lack of incoming tasks. + * @return <tt>true</tt> if core threads are allowed to time out, + * else <tt>false</tt> + * + * @since 1.6 + */ + public boolean allowsCoreThreadTimeOut() { + return allowCoreThreadTimeOut; + } + + /** + * Sets the policy governing whether core threads may time out and + * terminate if no tasks arrive within the keep-alive time, being + * replaced if needed when new tasks arrive. When false, core + * threads are never terminated due to lack of incoming + * tasks. When true, the same keep-alive policy applying to + * non-core threads applies also to core threads. To avoid + * continual thread replacement, the keep-alive time must be + * greater than zero when setting <tt>true</tt>. This method + * should in general be called before the pool is actively used. + * @param value <tt>true</tt> if should time out, else <tt>false</tt> + * @throws IllegalArgumentException if value is <tt>true</tt> + * and the current keep-alive time is not greater than zero. + * + * @since 1.6 + */ + public void allowCoreThreadTimeOut(boolean value) { + if (value && keepAliveTime <= 0) + throw new IllegalArgumentException("Core threads must have nonzero keep alive times"); + + allowCoreThreadTimeOut = value; + } + + /** + * Sets the maximum allowed number of threads. This overrides any + * value set in the constructor. If the new value is smaller than + * the current value, excess existing threads will be + * terminated when they next become idle. + * + * @param maximumPoolSize the new maximum + * @throws IllegalArgumentException if the new maximum is + * less than or equal to zero, or + * less than the {@linkplain #getCorePoolSize core pool size} + * @see #getMaximumPoolSize + */ + public void setMaximumPoolSize(int maximumPoolSize) { + if (maximumPoolSize <= 0 || maximumPoolSize < corePoolSize) + throw new IllegalArgumentException(); + final ReentrantLock mainLock = this.mainLock; + mainLock.lock(); + try { + int extra = this.maximumPoolSize - maximumPoolSize; + this.maximumPoolSize = maximumPoolSize; + if (extra > 0 && poolSize > maximumPoolSize) { + Iterator<Worker> it = workers.iterator(); + while (it.hasNext() && + extra > 0 && + poolSize > maximumPoolSize) { + it.next().interruptIfIdle(); + --extra; + } + } + } finally { + mainLock.unlock(); + } + } + + /** + * Returns the maximum allowed number of threads. + * + * @return the maximum allowed number of threads + * @see #setMaximumPoolSize + */ + public int getMaximumPoolSize() { + return maximumPoolSize; + } + + /** + * Sets the time limit for which threads may remain idle before + * being terminated. If there are more than the core number of + * threads currently in the pool, after waiting this amount of + * time without processing a task, excess threads will be + * terminated. This overrides any value set in the constructor. + * @param time the time to wait. A time value of zero will cause + * excess threads to terminate immediately after executing tasks. + * @param unit the time unit of the time argument + * @throws IllegalArgumentException if time less than zero or + * if time is zero and allowsCoreThreadTimeOut + * @see #getKeepAliveTime + */ + public void setKeepAliveTime(long time, TimeUnit unit) { + if (time < 0) + throw new IllegalArgumentException(); + if (time == 0 && allowsCoreThreadTimeOut()) + throw new IllegalArgumentException("Core threads must have nonzero keep alive times"); + this.keepAliveTime = unit.toNanos(time); + } + + /** + * Returns the thread keep-alive time, which is the amount of time + * which threads in excess of the core pool size may remain + * idle before being terminated. + * + * @param unit the desired time unit of the result + * @return the time limit + * @see #setKeepAliveTime + */ + public long getKeepAliveTime(TimeUnit unit) { + return unit.convert(keepAliveTime, TimeUnit.NANOSECONDS); + } + + /* Statistics */ + + /** + * Returns the current number of threads in the pool. + * + * @return the number of threads + */ + public int getPoolSize() { + return poolSize; + } + + /** + * Returns the approximate number of threads that are actively + * executing tasks. + * + * @return the number of threads + */ + public int getActiveCount() { + final ReentrantLock mainLock = this.mainLock; + mainLock.lock(); + try { + int n = 0; + for (Worker w : workers) { + if (w.isActive()) + ++n; + } + return n; + } finally { + mainLock.unlock(); + } + } + + /** + * Returns the largest number of threads that have ever + * simultaneously been in the pool. + * + * @return the number of threads + */ + public int getLargestPoolSize() { + final ReentrantLock mainLock = this.mainLock; + mainLock.lock(); + try { + return largestPoolSize; + } finally { + mainLock.unlock(); + } + } + + /** + * Returns the approximate total number of tasks that have been + * scheduled for execution. Because the states of tasks and + * threads may change dynamically during computation, the returned + * value is only an approximation, but one that does not ever + * decrease across successive calls. + * + * @return the number of tasks + */ + public long getTaskCount() { + final ReentrantLock mainLock = this.mainLock; + mainLock.lock(); + try { + long n = completedTaskCount; + for (Worker w : workers) { + n += w.completedTasks; + if (w.isActive()) + ++n; + } + return n + workQueue.size(); + } finally { + mainLock.unlock(); + } + } + + /** + * Returns the approximate total number of tasks that have + * completed execution. Because the states of tasks and threads + * may change dynamically during computation, the returned value + * is only an approximation, but one that does not ever decrease + * across successive calls. + * + * @return the number of tasks + */ + public long getCompletedTaskCount() { + final ReentrantLock mainLock = this.mainLock; + mainLock.lock(); + try { + long n = completedTaskCount; + for (Worker w : workers) + n += w.completedTasks; + return n; + } finally { + mainLock.unlock(); + } + } + + /** + * Method invoked prior to executing the given Runnable in the + * given thread. This method is invoked by thread <tt>t</tt> that + * will execute task <tt>r</tt>, and may be used to re-initialize + * ThreadLocals, or to perform logging. + * + * <p>This implementation does nothing, but may be customized in + * subclasses. Note: To properly nest multiple overridings, subclasses + * should generally invoke <tt>super.beforeExecute</tt> at the end of + * this method. + * + * @param t the thread that will run task r. + * @param r the task that will be executed. + */ + protected void beforeExecute(Thread t, Runnable r) { } + + /** + * Method invoked upon completion of execution of the given Runnable. + * This method is invoked by the thread that executed the task. If + * non-null, the Throwable is the uncaught <tt>RuntimeException</tt> + * or <tt>Error</tt> that caused execution to terminate abruptly. + * + * <p><b>Note:</b> When actions are enclosed in tasks (such as + * {@link FutureTask}) either explicitly or via methods such as + * <tt>submit</tt>, these task objects catch and maintain + * computational exceptions, and so they do not cause abrupt + * termination, and the internal exceptions are <em>not</em> + * passed to this method. + * + * <p>This implementation does nothing, but may be customized in + * subclasses. Note: To properly nest multiple overridings, subclasses + * should generally invoke <tt>super.afterExecute</tt> at the + * beginning of this method. + * + * @param r the runnable that has completed. + * @param t the exception that caused termination, or null if + * execution completed normally. + */ + protected void afterExecute(Runnable r, Throwable t) { } + + /** + * Method invoked when the Executor has terminated. Default + * implementation does nothing. Note: To properly nest multiple + * overridings, subclasses should generally invoke + * <tt>super.terminated</tt> within this method. + */ + protected void terminated() { } + + /** + * A handler for rejected tasks that runs the rejected task + * directly in the calling thread of the <tt>execute</tt> method, + * unless the executor has been shut down, in which case the task + * is discarded. + */ + public static class CallerRunsPolicy implements RejectedExecutionHandler { + /** + * Creates a <tt>CallerRunsPolicy</tt>. + */ + public CallerRunsPolicy() { } + + /** + * Executes task r in the caller's thread, unless the executor + * has been shut down, in which case the task is discarded. + * @param r the runnable task requested to be executed + * @param e the executor attempting to execute this task + */ + public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { + if (!e.isShutdown()) { + r.run(); + } + } + } + + /** + * A handler for rejected tasks that throws a + * <tt>RejectedExecutionException</tt>. + */ + public static class AbortPolicy implements RejectedExecutionHandler { + /** + * Creates an <tt>AbortPolicy</tt>. + */ + public AbortPolicy() { } + + /** + * Always throws RejectedExecutionException. + * @param r the runnable task requested to be executed + * @param e the executor attempting to execute this task + * @throws RejectedExecutionException always. + */ + public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { + throw new RejectedExecutionException(); + } + } + + /** + * A handler for rejected tasks that silently discards the + * rejected task. + */ + public static class DiscardPolicy implements RejectedExecutionHandler { + /** + * Creates a <tt>DiscardPolicy</tt>. + */ + public DiscardPolicy() { } + + /** + * Does nothing, which has the effect of discarding task r. + * @param r the runnable task requested to be executed + * @param e the executor attempting to execute this task + */ + public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { + } + } + + /** + * A handler for rejected tasks that discards the oldest unhandled + * request and then retries <tt>execute</tt>, unless the executor + * is shut down, in which case the task is discarded. + */ + public static class DiscardOldestPolicy implements RejectedExecutionHandler { + /** + * Creates a <tt>DiscardOldestPolicy</tt> for the given executor. + */ + public DiscardOldestPolicy() { } + + /** + * Obtains and ignores the next task that the executor + * would otherwise execute, if one is immediately available, + * and then retries execution of task r, unless the executor + * is shut down, in which case task r is instead discarded. + * @param r the runnable task requested to be executed + * @param e the executor attempting to execute this task + */ + public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { + if (!e.isShutdown()) { + e.getQueue().poll(); + e.execute(r); + } + } + } +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/TimeUnit.java b/libjava/classpath/external/jsr166/java/util/concurrent/TimeUnit.java new file mode 100644 index 000000000..2cd3d06ab --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/TimeUnit.java @@ -0,0 +1,331 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; + +/** + * A <tt>TimeUnit</tt> represents time durations at a given unit of + * granularity and provides utility methods to convert across units, + * and to perform timing and delay operations in these units. A + * <tt>TimeUnit</tt> does not maintain time information, but only + * helps organize and use time representations that may be maintained + * separately across various contexts. A nanosecond is defined as one + * thousandth of a microsecond, a microsecond as one thousandth of a + * millisecond, a millisecond as one thousandth of a second, a minute + * as sixty seconds, an hour as sixty minutes, and a day as twenty four + * hours. + * + * <p>A <tt>TimeUnit</tt> is mainly used to inform time-based methods + * how a given timing parameter should be interpreted. For example, + * the following code will timeout in 50 milliseconds if the {@link + * java.util.concurrent.locks.Lock lock} is not available: + * + * <pre> Lock lock = ...; + * if ( lock.tryLock(50L, TimeUnit.MILLISECONDS) ) ... + * </pre> + * while this code will timeout in 50 seconds: + * <pre> + * Lock lock = ...; + * if ( lock.tryLock(50L, TimeUnit.SECONDS) ) ... + * </pre> + * + * Note however, that there is no guarantee that a particular timeout + * implementation will be able to notice the passage of time at the + * same granularity as the given <tt>TimeUnit</tt>. + * + * @since 1.5 + * @author Doug Lea + */ +public enum TimeUnit { + NANOSECONDS { + public long toNanos(long d) { return d; } + public long toMicros(long d) { return d/(C1/C0); } + public long toMillis(long d) { return d/(C2/C0); } + public long toSeconds(long d) { return d/(C3/C0); } + public long toMinutes(long d) { return d/(C4/C0); } + public long toHours(long d) { return d/(C5/C0); } + public long toDays(long d) { return d/(C6/C0); } + public long convert(long d, TimeUnit u) { return u.toNanos(d); } + int excessNanos(long d, long m) { return (int)(d - (m*C2)); } + }, + MICROSECONDS { + public long toNanos(long d) { return x(d, C1/C0, MAX/(C1/C0)); } + public long toMicros(long d) { return d; } + public long toMillis(long d) { return d/(C2/C1); } + public long toSeconds(long d) { return d/(C3/C1); } + public long toMinutes(long d) { return d/(C4/C1); } + public long toHours(long d) { return d/(C5/C1); } + public long toDays(long d) { return d/(C6/C1); } + public long convert(long d, TimeUnit u) { return u.toMicros(d); } + int excessNanos(long d, long m) { return (int)((d*C1) - (m*C2)); } + }, + MILLISECONDS { + public long toNanos(long d) { return x(d, C2/C0, MAX/(C2/C0)); } + public long toMicros(long d) { return x(d, C2/C1, MAX/(C2/C1)); } + public long toMillis(long d) { return d; } + public long toSeconds(long d) { return d/(C3/C2); } + public long toMinutes(long d) { return d/(C4/C2); } + public long toHours(long d) { return d/(C5/C2); } + public long toDays(long d) { return d/(C6/C2); } + public long convert(long d, TimeUnit u) { return u.toMillis(d); } + int excessNanos(long d, long m) { return 0; } + }, + SECONDS { + public long toNanos(long d) { return x(d, C3/C0, MAX/(C3/C0)); } + public long toMicros(long d) { return x(d, C3/C1, MAX/(C3/C1)); } + public long toMillis(long d) { return x(d, C3/C2, MAX/(C3/C2)); } + public long toSeconds(long d) { return d; } + public long toMinutes(long d) { return d/(C4/C3); } + public long toHours(long d) { return d/(C5/C3); } + public long toDays(long d) { return d/(C6/C3); } + public long convert(long d, TimeUnit u) { return u.toSeconds(d); } + int excessNanos(long d, long m) { return 0; } + }, + MINUTES { + public long toNanos(long d) { return x(d, C4/C0, MAX/(C4/C0)); } + public long toMicros(long d) { return x(d, C4/C1, MAX/(C4/C1)); } + public long toMillis(long d) { return x(d, C4/C2, MAX/(C4/C2)); } + public long toSeconds(long d) { return x(d, C4/C3, MAX/(C4/C3)); } + public long toMinutes(long d) { return d; } + public long toHours(long d) { return d/(C5/C4); } + public long toDays(long d) { return d/(C6/C4); } + public long convert(long d, TimeUnit u) { return u.toMinutes(d); } + int excessNanos(long d, long m) { return 0; } + }, + HOURS { + public long toNanos(long d) { return x(d, C5/C0, MAX/(C5/C0)); } + public long toMicros(long d) { return x(d, C5/C1, MAX/(C5/C1)); } + public long toMillis(long d) { return x(d, C5/C2, MAX/(C5/C2)); } + public long toSeconds(long d) { return x(d, C5/C3, MAX/(C5/C3)); } + public long toMinutes(long d) { return x(d, C5/C4, MAX/(C5/C4)); } + public long toHours(long d) { return d; } + public long toDays(long d) { return d/(C6/C5); } + public long convert(long d, TimeUnit u) { return u.toHours(d); } + int excessNanos(long d, long m) { return 0; } + }, + DAYS { + public long toNanos(long d) { return x(d, C6/C0, MAX/(C6/C0)); } + public long toMicros(long d) { return x(d, C6/C1, MAX/(C6/C1)); } + public long toMillis(long d) { return x(d, C6/C2, MAX/(C6/C2)); } + public long toSeconds(long d) { return x(d, C6/C3, MAX/(C6/C3)); } + public long toMinutes(long d) { return x(d, C6/C4, MAX/(C6/C4)); } + public long toHours(long d) { return x(d, C6/C5, MAX/(C6/C5)); } + public long toDays(long d) { return d; } + public long convert(long d, TimeUnit u) { return u.toDays(d); } + int excessNanos(long d, long m) { return 0; } + }; + + // Handy constants for conversion methods + static final long C0 = 1L; + static final long C1 = C0 * 1000L; + static final long C2 = C1 * 1000L; + static final long C3 = C2 * 1000L; + static final long C4 = C3 * 60L; + static final long C5 = C4 * 60L; + static final long C6 = C5 * 24L; + + static final long MAX = Long.MAX_VALUE; + + /** + * Scale d by m, checking for overflow. + * This has a short name to make above code more readable. + */ + static long x(long d, long m, long over) { + if (d > over) return Long.MAX_VALUE; + if (d < -over) return Long.MIN_VALUE; + return d * m; + } + + // To maintain full signature compatibility with 1.5, and to improve the + // clarity of the generated javadoc (see 6287639: Abstract methods in + // enum classes should not be listed as abstract), method convert + // etc. are not declared abstract but otherwise act as abstract methods. + + /** + * Convert the given time duration in the given unit to this + * unit. Conversions from finer to coarser granularities + * truncate, so lose precision. For example converting + * <tt>999</tt> milliseconds to seconds results in + * <tt>0</tt>. Conversions from coarser to finer granularities + * with arguments that would numerically overflow saturate to + * <tt>Long.MIN_VALUE</tt> if negative or <tt>Long.MAX_VALUE</tt> + * if positive. + * + * <p>For example, to convert 10 minutes to milliseconds, use: + * <tt>TimeUnit.MILLISECONDS.convert(10L, TimeUnit.MINUTES)</tt> + * + * @param sourceDuration the time duration in the given <tt>sourceUnit</tt> + * @param sourceUnit the unit of the <tt>sourceDuration</tt> argument + * @return the converted duration in this unit, + * or <tt>Long.MIN_VALUE</tt> if conversion would negatively + * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow. + */ + public long convert(long sourceDuration, TimeUnit sourceUnit) { + throw new AbstractMethodError(); + } + + /** + * Equivalent to <tt>NANOSECONDS.convert(duration, this)</tt>. + * @param duration the duration + * @return the converted duration, + * or <tt>Long.MIN_VALUE</tt> if conversion would negatively + * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow. + * @see #convert + */ + public long toNanos(long duration) { + throw new AbstractMethodError(); + } + + /** + * Equivalent to <tt>MICROSECONDS.convert(duration, this)</tt>. + * @param duration the duration + * @return the converted duration, + * or <tt>Long.MIN_VALUE</tt> if conversion would negatively + * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow. + * @see #convert + */ + public long toMicros(long duration) { + throw new AbstractMethodError(); + } + + /** + * Equivalent to <tt>MILLISECONDS.convert(duration, this)</tt>. + * @param duration the duration + * @return the converted duration, + * or <tt>Long.MIN_VALUE</tt> if conversion would negatively + * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow. + * @see #convert + */ + public long toMillis(long duration) { + throw new AbstractMethodError(); + } + + /** + * Equivalent to <tt>SECONDS.convert(duration, this)</tt>. + * @param duration the duration + * @return the converted duration, + * or <tt>Long.MIN_VALUE</tt> if conversion would negatively + * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow. + * @see #convert + */ + public long toSeconds(long duration) { + throw new AbstractMethodError(); + } + + /** + * Equivalent to <tt>MINUTES.convert(duration, this)</tt>. + * @param duration the duration + * @return the converted duration, + * or <tt>Long.MIN_VALUE</tt> if conversion would negatively + * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow. + * @see #convert + * @since 1.6 + */ + public long toMinutes(long duration) { + throw new AbstractMethodError(); + } + + /** + * Equivalent to <tt>HOURS.convert(duration, this)</tt>. + * @param duration the duration + * @return the converted duration, + * or <tt>Long.MIN_VALUE</tt> if conversion would negatively + * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow. + * @see #convert + * @since 1.6 + */ + public long toHours(long duration) { + throw new AbstractMethodError(); + } + + /** + * Equivalent to <tt>DAYS.convert(duration, this)</tt>. + * @param duration the duration + * @return the converted duration + * @see #convert + * @since 1.6 + */ + public long toDays(long duration) { + throw new AbstractMethodError(); + } + + /** + * Utility to compute the excess-nanosecond argument to wait, + * sleep, join. + * @param d the duration + * @param m the number of milliseconds + * @return the number of nanoseconds + */ + abstract int excessNanos(long d, long m); + + /** + * Performs a timed <tt>Object.wait</tt> using this time unit. + * This is a convenience method that converts timeout arguments + * into the form required by the <tt>Object.wait</tt> method. + * + * <p>For example, you could implement a blocking <tt>poll</tt> + * method (see {@link BlockingQueue#poll BlockingQueue.poll}) + * using: + * + * <pre> public synchronized Object poll(long timeout, TimeUnit unit) throws InterruptedException { + * while (empty) { + * unit.timedWait(this, timeout); + * ... + * } + * }</pre> + * + * @param obj the object to wait on + * @param timeout the maximum time to wait. If less than + * or equal to zero, do not wait at all. + * @throws InterruptedException if interrupted while waiting. + * @see Object#wait(long, int) + */ + public void timedWait(Object obj, long timeout) + throws InterruptedException { + if (timeout > 0) { + long ms = toMillis(timeout); + int ns = excessNanos(timeout, ms); + obj.wait(ms, ns); + } + } + + /** + * Performs a timed <tt>Thread.join</tt> using this time unit. + * This is a convenience method that converts time arguments into the + * form required by the <tt>Thread.join</tt> method. + * @param thread the thread to wait for + * @param timeout the maximum time to wait. If less than + * or equal to zero, do not wait at all. + * @throws InterruptedException if interrupted while waiting. + * @see Thread#join(long, int) + */ + public void timedJoin(Thread thread, long timeout) + throws InterruptedException { + if (timeout > 0) { + long ms = toMillis(timeout); + int ns = excessNanos(timeout, ms); + thread.join(ms, ns); + } + } + + /** + * Performs a <tt>Thread.sleep</tt> using this unit. + * This is a convenience method that converts time arguments into the + * form required by the <tt>Thread.sleep</tt> method. + * @param timeout the minimum time to sleep. If less than + * or equal to zero, do not sleep at all. + * @throws InterruptedException if interrupted while sleeping. + * @see Thread#sleep + */ + public void sleep(long timeout) throws InterruptedException { + if (timeout > 0) { + long ms = toMillis(timeout); + int ns = excessNanos(timeout, ms); + Thread.sleep(ms, ns); + } + } + +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/TimeoutException.java b/libjava/classpath/external/jsr166/java/util/concurrent/TimeoutException.java new file mode 100644 index 000000000..8b84f28e5 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/TimeoutException.java @@ -0,0 +1,38 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; + +/** + * Exception thrown when a blocking operation times out. Blocking + * operations for which a timeout is specified need a means to + * indicate that the timeout has occurred. For many such operations it + * is possible to return a value that indicates timeout; when that is + * not possible or desirable then <tt>TimeoutException</tt> should be + * declared and thrown. + * + * @since 1.5 + * @author Doug Lea + */ +public class TimeoutException extends Exception { + private static final long serialVersionUID = 1900926677490660714L; + + /** + * Constructs a <tt>TimeoutException</tt> with no specified detail + * message. + */ + public TimeoutException() {} + + /** + * Constructs a <tt>TimeoutException</tt> with the specified detail + * message. + * + * @param message the detail message + */ + public TimeoutException(String message) { + super(message); + } +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicBoolean.java b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicBoolean.java new file mode 100644 index 000000000..bd823bd2c --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicBoolean.java @@ -0,0 +1,133 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent.atomic; +import sun.misc.Unsafe; + +/** + * A <tt>boolean</tt> value that may be updated atomically. See the + * {@link java.util.concurrent.atomic} package specification for + * description of the properties of atomic variables. An + * <tt>AtomicBoolean</tt> is used in applications such as atomically + * updated flags, and cannot be used as a replacement for a + * {@link java.lang.Boolean}. + * + * @since 1.5 + * @author Doug Lea + */ +public class AtomicBoolean implements java.io.Serializable { + private static final long serialVersionUID = 4654671469794556979L; + // setup to use Unsafe.compareAndSwapInt for updates + private static final Unsafe unsafe = Unsafe.getUnsafe(); + private static final long valueOffset; + + static { + try { + valueOffset = unsafe.objectFieldOffset + (AtomicBoolean.class.getDeclaredField("value")); + } catch (Exception ex) { throw new Error(ex); } + } + + private volatile int value; + + /** + * Creates a new <tt>AtomicBoolean</tt> with the given initial value. + * + * @param initialValue the initial value + */ + public AtomicBoolean(boolean initialValue) { + value = initialValue ? 1 : 0; + } + + /** + * Creates a new <tt>AtomicBoolean</tt> with initial value <tt>false</tt>. + */ + public AtomicBoolean() { + } + + /** + * Returns the current value. + * + * @return the current value + */ + public final boolean get() { + return value != 0; + } + + /** + * Atomically sets the value to the given updated value + * if the current value <tt>==</tt> the expected value. + * + * @param expect the expected value + * @param update the new value + * @return true if successful. False return indicates that + * the actual value was not equal to the expected value. + */ + public final boolean compareAndSet(boolean expect, boolean update) { + int e = expect ? 1 : 0; + int u = update ? 1 : 0; + return unsafe.compareAndSwapInt(this, valueOffset, e, u); + } + + /** + * Atomically sets the value to the given updated value + * if the current value <tt>==</tt> the expected value. + * May fail spuriously and does not provide ordering guarantees, + * so is only rarely an appropriate alternative to <tt>compareAndSet</tt>. + * + * @param expect the expected value + * @param update the new value + * @return true if successful. + */ + public boolean weakCompareAndSet(boolean expect, boolean update) { + int e = expect ? 1 : 0; + int u = update ? 1 : 0; + return unsafe.compareAndSwapInt(this, valueOffset, e, u); + } + + /** + * Unconditionally sets to the given value. + * + * @param newValue the new value + */ + public final void set(boolean newValue) { + value = newValue ? 1 : 0; + } + + /** + * Eventually sets to the given value. + * + * @param newValue the new value + * @since 1.6 + */ + public final void lazySet(boolean newValue) { + int v = newValue ? 1 : 0; + unsafe.putOrderedInt(this, valueOffset, v); + } + + /** + * Atomically sets to the given value and returns the previous value. + * + * @param newValue the new value + * @return the previous value + */ + public final boolean getAndSet(boolean newValue) { + for (;;) { + boolean current = get(); + if (compareAndSet(current, newValue)) + return current; + } + } + + /** + * Returns the String representation of the current value. + * @return the String representation of the current value. + */ + public String toString() { + return Boolean.toString(get()); + } + +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicInteger.java b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicInteger.java new file mode 100644 index 000000000..0f723f613 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicInteger.java @@ -0,0 +1,234 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent.atomic; +import sun.misc.Unsafe; + +/** + * An <tt>int</tt> value that may be updated atomically. See the + * {@link java.util.concurrent.atomic} package specification for + * description of the properties of atomic variables. An + * <tt>AtomicInteger</tt> is used in applications such as atomically + * incremented counters, and cannot be used as a replacement for an + * {@link java.lang.Integer}. However, this class does extend + * <tt>Number</tt> to allow uniform access by tools and utilities that + * deal with numerically-based classes. + * + * @since 1.5 + * @author Doug Lea +*/ +public class AtomicInteger extends Number implements java.io.Serializable { + private static final long serialVersionUID = 6214790243416807050L; + + // setup to use Unsafe.compareAndSwapInt for updates + private static final Unsafe unsafe = Unsafe.getUnsafe(); + private static final long valueOffset; + + static { + try { + valueOffset = unsafe.objectFieldOffset + (AtomicInteger.class.getDeclaredField("value")); + } catch (Exception ex) { throw new Error(ex); } + } + + private volatile int value; + + /** + * Creates a new AtomicInteger with the given initial value. + * + * @param initialValue the initial value + */ + public AtomicInteger(int initialValue) { + value = initialValue; + } + + /** + * Creates a new AtomicInteger with initial value <tt>0</tt>. + */ + public AtomicInteger() { + } + + /** + * Gets the current value. + * + * @return the current value + */ + public final int get() { + return value; + } + + /** + * Sets to the given value. + * + * @param newValue the new value + */ + public final void set(int newValue) { + value = newValue; + } + + /** + * Eventually sets to the given value. + * + * @param newValue the new value + * @since 1.6 + */ + public final void lazySet(int newValue) { + unsafe.putOrderedInt(this, valueOffset, newValue); + } + + /** + * Atomically sets to the given value and returns the old value. + * + * @param newValue the new value + * @return the previous value + */ + public final int getAndSet(int newValue) { + for (;;) { + int current = get(); + if (compareAndSet(current, newValue)) + return current; + } + } + + /** + * Atomically sets the value to the given updated value + * if the current value <tt>==</tt> the expected value. + * + * @param expect the expected value + * @param update the new value + * @return true if successful. False return indicates that + * the actual value was not equal to the expected value. + */ + public final boolean compareAndSet(int expect, int update) { + return unsafe.compareAndSwapInt(this, valueOffset, expect, update); + } + + /** + * Atomically sets the value to the given updated value + * if the current value <tt>==</tt> the expected value. + * May fail spuriously and does not provide ordering guarantees, + * so is only rarely an appropriate alternative to <tt>compareAndSet</tt>. + * + * @param expect the expected value + * @param update the new value + * @return true if successful. + */ + public final boolean weakCompareAndSet(int expect, int update) { + return unsafe.compareAndSwapInt(this, valueOffset, expect, update); + } + + /** + * Atomically increments by one the current value. + * + * @return the previous value + */ + public final int getAndIncrement() { + for (;;) { + int current = get(); + int next = current + 1; + if (compareAndSet(current, next)) + return current; + } + } + + /** + * Atomically decrements by one the current value. + * + * @return the previous value + */ + public final int getAndDecrement() { + for (;;) { + int current = get(); + int next = current - 1; + if (compareAndSet(current, next)) + return current; + } + } + + /** + * Atomically adds the given value to the current value. + * + * @param delta the value to add + * @return the previous value + */ + public final int getAndAdd(int delta) { + for (;;) { + int current = get(); + int next = current + delta; + if (compareAndSet(current, next)) + return current; + } + } + + /** + * Atomically increments by one the current value. + * + * @return the updated value + */ + public final int incrementAndGet() { + for (;;) { + int current = get(); + int next = current + 1; + if (compareAndSet(current, next)) + return next; + } + } + + /** + * Atomically decrements by one the current value. + * + * @return the updated value + */ + public final int decrementAndGet() { + for (;;) { + int current = get(); + int next = current - 1; + if (compareAndSet(current, next)) + return next; + } + } + + /** + * Atomically adds the given value to the current value. + * + * @param delta the value to add + * @return the updated value + */ + public final int addAndGet(int delta) { + for (;;) { + int current = get(); + int next = current + delta; + if (compareAndSet(current, next)) + return next; + } + } + + /** + * Returns the String representation of the current value. + * @return the String representation of the current value. + */ + public String toString() { + return Integer.toString(get()); + } + + + public int intValue() { + return get(); + } + + public long longValue() { + return (long)get(); + } + + public float floatValue() { + return (float)get(); + } + + public double doubleValue() { + return (double)get(); + } + +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicIntegerArray.java b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicIntegerArray.java new file mode 100644 index 000000000..2ad754fda --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicIntegerArray.java @@ -0,0 +1,255 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent.atomic; +import sun.misc.Unsafe; +import java.util.*; + +/** + * An <tt>int</tt> array in which elements may be updated atomically. + * See the {@link java.util.concurrent.atomic} package + * specification for description of the properties of atomic + * variables. + * @since 1.5 + * @author Doug Lea + */ +public class AtomicIntegerArray implements java.io.Serializable { + private static final long serialVersionUID = 2862133569453604235L; + + // setup to use Unsafe.compareAndSwapInt for updates + private static final Unsafe unsafe = Unsafe.getUnsafe(); + private static final int base = unsafe.arrayBaseOffset(int[].class); + private static final int scale = unsafe.arrayIndexScale(int[].class); + private final int[] array; + + private long rawIndex(int i) { + if (i < 0 || i >= array.length) + throw new IndexOutOfBoundsException("index " + i); + return base + i * scale; + } + + /** + * Creates a new AtomicIntegerArray of given length. + * + * @param length the length of the array + */ + public AtomicIntegerArray(int length) { + array = new int[length]; + // must perform at least one volatile write to conform to JMM + if (length > 0) + unsafe.putIntVolatile(array, rawIndex(0), 0); + } + + /** + * Creates a new AtomicIntegerArray with the same length as, and + * all elements copied from, the given array. + * + * @param array the array to copy elements from + * @throws NullPointerException if array is null + */ + public AtomicIntegerArray(int[] array) { + if (array == null) + throw new NullPointerException(); + int length = array.length; + this.array = new int[length]; + if (length > 0) { + int last = length-1; + for (int i = 0; i < last; ++i) + this.array[i] = array[i]; + // Do the last write as volatile + unsafe.putIntVolatile(this.array, rawIndex(last), array[last]); + } + } + + /** + * Returns the length of the array. + * + * @return the length of the array + */ + public final int length() { + return array.length; + } + + /** + * Gets the current value at position <tt>i</tt>. + * + * @param i the index + * @return the current value + */ + public final int get(int i) { + return unsafe.getIntVolatile(array, rawIndex(i)); + } + + /** + * Sets the element at position <tt>i</tt> to the given value. + * + * @param i the index + * @param newValue the new value + */ + public final void set(int i, int newValue) { + unsafe.putIntVolatile(array, rawIndex(i), newValue); + } + + /** + * Eventually sets the element at position <tt>i</tt> to the given value. + * + * @param i the index + * @param newValue the new value + * @since 1.6 + */ + public final void lazySet(int i, int newValue) { + unsafe.putOrderedInt(array, rawIndex(i), newValue); + } + + /** + * Atomically sets the element at position <tt>i</tt> to the given + * value and returns the old value. + * + * @param i the index + * @param newValue the new value + * @return the previous value + */ + public final int getAndSet(int i, int newValue) { + while (true) { + int current = get(i); + if (compareAndSet(i, current, newValue)) + return current; + } + } + + /** + * Atomically sets the element at position <tt>i</tt> to the given + * updated value if the current value <tt>==</tt> the expected value. + * + * @param i the index + * @param expect the expected value + * @param update the new value + * @return true if successful. False return indicates that + * the actual value was not equal to the expected value. + */ + public final boolean compareAndSet(int i, int expect, int update) { + return unsafe.compareAndSwapInt(array, rawIndex(i), + expect, update); + } + + /** + * Atomically sets the element at position <tt>i</tt> to the given + * updated value if the current value <tt>==</tt> the expected value. + * May fail spuriously and does not provide ordering guarantees, + * so is only rarely an appropriate alternative to <tt>compareAndSet</tt>. + * + * @param i the index + * @param expect the expected value + * @param update the new value + * @return true if successful. + */ + public final boolean weakCompareAndSet(int i, int expect, int update) { + return compareAndSet(i, expect, update); + } + + /** + * Atomically increments by one the element at index <tt>i</tt>. + * + * @param i the index + * @return the previous value + */ + public final int getAndIncrement(int i) { + while (true) { + int current = get(i); + int next = current + 1; + if (compareAndSet(i, current, next)) + return current; + } + } + + /** + * Atomically decrements by one the element at index <tt>i</tt>. + * + * @param i the index + * @return the previous value + */ + public final int getAndDecrement(int i) { + while (true) { + int current = get(i); + int next = current - 1; + if (compareAndSet(i, current, next)) + return current; + } + } + + /** + * Atomically adds the given value to the element at index <tt>i</tt>. + * + * @param i the index + * @param delta the value to add + * @return the previous value + */ + public final int getAndAdd(int i, int delta) { + while (true) { + int current = get(i); + int next = current + delta; + if (compareAndSet(i, current, next)) + return current; + } + } + + /** + * Atomically increments by one the element at index <tt>i</tt>. + * + * @param i the index + * @return the updated value + */ + public final int incrementAndGet(int i) { + while (true) { + int current = get(i); + int next = current + 1; + if (compareAndSet(i, current, next)) + return next; + } + } + + /** + * Atomically decrements by one the element at index <tt>i</tt>. + * + * @param i the index + * @return the updated value + */ + public final int decrementAndGet(int i) { + while (true) { + int current = get(i); + int next = current - 1; + if (compareAndSet(i, current, next)) + return next; + } + } + + /** + * Atomically adds the given value to the element at index <tt>i</tt>. + * + * @param i the index + * @param delta the value to add + * @return the updated value + */ + public final int addAndGet(int i, int delta) { + while (true) { + int current = get(i); + int next = current + delta; + if (compareAndSet(i, current, next)) + return next; + } + } + + /** + * Returns the String representation of the current values of array. + * @return the String representation of the current values of array. + */ + public String toString() { + if (array.length > 0) // force volatile read + get(0); + return Arrays.toString(array); + } + +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java new file mode 100644 index 000000000..c957bbf3f --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java @@ -0,0 +1,316 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent.atomic; +import sun.misc.Unsafe; +import java.lang.reflect.*; + +/** + * A reflection-based utility that enables atomic updates to + * designated <tt>volatile int</tt> fields of designated classes. + * This class is designed for use in atomic data structures in which + * several fields of the same node are independently subject to atomic + * updates. + * + * <p>Note that the guarantees of the {@code compareAndSet} + * method in this class are weaker than in other atomic classes. + * Because this class cannot ensure that all uses of the field + * are appropriate for purposes of atomic access, it can + * guarantee atomicity only with respect to other invocations of + * {@code compareAndSet} and {@code set} on the same updater. + * + * @since 1.5 + * @author Doug Lea + * @param <T> The type of the object holding the updatable field + */ +public abstract class AtomicIntegerFieldUpdater<T> { + /** + * Creates and returns an updater for objects with the given field. + * The Class argument is needed to check that reflective types and + * generic types match. + * + * @param tclass the class of the objects holding the field + * @param fieldName the name of the field to be updated + * @return the updater + * @throws IllegalArgumentException if the field is not a + * volatile integer type + * @throws RuntimeException with a nested reflection-based + * exception if the class does not hold field or is the wrong type + */ + public static <U> AtomicIntegerFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName) { + return new AtomicIntegerFieldUpdaterImpl<U>(tclass, fieldName); + } + + /** + * Protected do-nothing constructor for use by subclasses. + */ + protected AtomicIntegerFieldUpdater() { + } + + /** + * Atomically sets the field of the given object managed by this updater + * to the given updated value if the current value <tt>==</tt> the + * expected value. This method is guaranteed to be atomic with respect to + * other calls to <tt>compareAndSet</tt> and <tt>set</tt>, but not + * necessarily with respect to other changes in the field. + * + * @param obj An object whose field to conditionally set + * @param expect the expected value + * @param update the new value + * @return true if successful + * @throws ClassCastException if <tt>obj</tt> is not an instance + * of the class possessing the field established in the constructor + */ + public abstract boolean compareAndSet(T obj, int expect, int update); + + /** + * Atomically sets the field of the given object managed by this updater + * to the given updated value if the current value <tt>==</tt> the + * expected value. This method is guaranteed to be atomic with respect to + * other calls to <tt>compareAndSet</tt> and <tt>set</tt>, but not + * necessarily with respect to other changes in the field. + * May fail spuriously and does not provide ordering guarantees, + * so is only rarely an appropriate alternative to <tt>compareAndSet</tt>. + * + * @param obj An object whose field to conditionally set + * @param expect the expected value + * @param update the new value + * @return true if successful + * @throws ClassCastException if <tt>obj</tt> is not an instance + * of the class possessing the field established in the constructor + */ + public abstract boolean weakCompareAndSet(T obj, int expect, int update); + + /** + * Sets the field of the given object managed by this updater to the + * given updated value. This operation is guaranteed to act as a volatile + * store with respect to subsequent invocations of + * <tt>compareAndSet</tt>. + * + * @param obj An object whose field to set + * @param newValue the new value + */ + public abstract void set(T obj, int newValue); + + /** + * Eventually sets the field of the given object managed by this + * updater to the given updated value. + * + * @param obj An object whose field to set + * @param newValue the new value + * @since 1.6 + */ + public abstract void lazySet(T obj, int newValue); + + + /** + * Gets the current value held in the field of the given object managed + * by this updater. + * + * @param obj An object whose field to get + * @return the current value + */ + public abstract int get(T obj); + + /** + * Atomically sets the field of the given object managed by this updater + * to the given value and returns the old value. + * + * @param obj An object whose field to get and set + * @param newValue the new value + * @return the previous value + */ + public int getAndSet(T obj, int newValue) { + for (;;) { + int current = get(obj); + if (compareAndSet(obj, current, newValue)) + return current; + } + } + + /** + * Atomically increments by one the current value of the field of the + * given object managed by this updater. + * + * @param obj An object whose field to get and set + * @return the previous value + */ + public int getAndIncrement(T obj) { + for (;;) { + int current = get(obj); + int next = current + 1; + if (compareAndSet(obj, current, next)) + return current; + } + } + + /** + * Atomically decrements by one the current value of the field of the + * given object managed by this updater. + * + * @param obj An object whose field to get and set + * @return the previous value + */ + public int getAndDecrement(T obj) { + for (;;) { + int current = get(obj); + int next = current - 1; + if (compareAndSet(obj, current, next)) + return current; + } + } + + /** + * Atomically adds the given value to the current value of the field of + * the given object managed by this updater. + * + * @param obj An object whose field to get and set + * @param delta the value to add + * @return the previous value + */ + public int getAndAdd(T obj, int delta) { + for (;;) { + int current = get(obj); + int next = current + delta; + if (compareAndSet(obj, current, next)) + return current; + } + } + + /** + * Atomically increments by one the current value of the field of the + * given object managed by this updater. + * + * @param obj An object whose field to get and set + * @return the updated value + */ + public int incrementAndGet(T obj) { + for (;;) { + int current = get(obj); + int next = current + 1; + if (compareAndSet(obj, current, next)) + return next; + } + } + + /** + * Atomically decrements by one the current value of the field of the + * given object managed by this updater. + * + * @param obj An object whose field to get and set + * @return the updated value + */ + public int decrementAndGet(T obj) { + for (;;) { + int current = get(obj); + int next = current - 1; + if (compareAndSet(obj, current, next)) + return next; + } + } + + /** + * Atomically adds the given value to the current value of the field of + * the given object managed by this updater. + * + * @param obj An object whose field to get and set + * @param delta the value to add + * @return the updated value + */ + public int addAndGet(T obj, int delta) { + for (;;) { + int current = get(obj); + int next = current + delta; + if (compareAndSet(obj, current, next)) + return next; + } + } + + /** + * Standard hotspot implementation using intrinsics + */ + private static class AtomicIntegerFieldUpdaterImpl<T> extends AtomicIntegerFieldUpdater<T> { + private static final Unsafe unsafe = Unsafe.getUnsafe(); + private final long offset; + private final Class<T> tclass; + private final Class cclass; + + AtomicIntegerFieldUpdaterImpl(Class<T> tclass, String fieldName) { + Field field = null; + Class caller = null; + int modifiers = 0; + try { + field = tclass.getDeclaredField(fieldName); + caller = sun.reflect.Reflection.getCallerClass(3); + modifiers = field.getModifiers(); + sun.reflect.misc.ReflectUtil.ensureMemberAccess( + caller, tclass, null, modifiers); + sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass); + } catch(Exception ex) { + throw new RuntimeException(ex); + } + + Class fieldt = field.getType(); + if (fieldt != int.class) + throw new IllegalArgumentException("Must be integer type"); + + if (!Modifier.isVolatile(modifiers)) + throw new IllegalArgumentException("Must be volatile type"); + + this.cclass = (Modifier.isProtected(modifiers) && + caller != tclass) ? caller : null; + this.tclass = tclass; + offset = unsafe.objectFieldOffset(field); + } + + private void fullCheck(T obj) { + if (!tclass.isInstance(obj)) + throw new ClassCastException(); + if (cclass != null) + ensureProtectedAccess(obj); + } + + public boolean compareAndSet(T obj, int expect, int update) { + if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); + return unsafe.compareAndSwapInt(obj, offset, expect, update); + } + + public boolean weakCompareAndSet(T obj, int expect, int update) { + if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); + return unsafe.compareAndSwapInt(obj, offset, expect, update); + } + + public void set(T obj, int newValue) { + if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); + unsafe.putIntVolatile(obj, offset, newValue); + } + + public void lazySet(T obj, int newValue) { + if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); + unsafe.putOrderedInt(obj, offset, newValue); + } + + public final int get(T obj) { + if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); + return unsafe.getIntVolatile(obj, offset); + } + + private void ensureProtectedAccess(T obj) { + if (cclass.isInstance(obj)) { + return; + } + throw new RuntimeException( + new IllegalAccessException("Class " + + cclass.getName() + + " can not access a protected member of class " + + tclass.getName() + + " using an instance of " + + obj.getClass().getName() + ) + ); + } + } +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicLong.java b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicLong.java new file mode 100644 index 000000000..fa254ba62 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicLong.java @@ -0,0 +1,248 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent.atomic; +import sun.misc.Unsafe; + +/** + * A <tt>long</tt> value that may be updated atomically. See the + * {@link java.util.concurrent.atomic} package specification for + * description of the properties of atomic variables. An + * <tt>AtomicLong</tt> is used in applications such as atomically + * incremented sequence numbers, and cannot be used as a replacement + * for a {@link java.lang.Long}. However, this class does extend + * <tt>Number</tt> to allow uniform access by tools and utilities that + * deal with numerically-based classes. + * + * @since 1.5 + * @author Doug Lea + */ +public class AtomicLong extends Number implements java.io.Serializable { + private static final long serialVersionUID = 1927816293512124184L; + + // setup to use Unsafe.compareAndSwapLong for updates + private static final Unsafe unsafe = Unsafe.getUnsafe(); + private static final long valueOffset; + + /** + * Records whether the underlying JVM supports lockless + * CompareAndSet for longs. While the unsafe.CompareAndSetLong + * method works in either case, some constructions should be + * handled at Java level to avoid locking user-visible locks. + */ + static final boolean VM_SUPPORTS_LONG_CAS = VMSupportsCS8(); + + /** + * Returns whether underlying JVM supports lockless CompareAndSet + * for longs. Called only once and cached in VM_SUPPORTS_LONG_CAS. + */ + private static native boolean VMSupportsCS8(); + + static { + try { + valueOffset = unsafe.objectFieldOffset + (AtomicLong.class.getDeclaredField("value")); + } catch (Exception ex) { throw new Error(ex); } + } + + private volatile long value; + + /** + * Creates a new AtomicLong with the given initial value. + * + * @param initialValue the initial value + */ + public AtomicLong(long initialValue) { + value = initialValue; + } + + /** + * Creates a new AtomicLong with initial value <tt>0</tt>. + */ + public AtomicLong() { + } + + /** + * Gets the current value. + * + * @return the current value + */ + public final long get() { + return value; + } + + /** + * Sets to the given value. + * + * @param newValue the new value + */ + public final void set(long newValue) { + value = newValue; + } + + /** + * Eventually sets to the given value. + * + * @param newValue the new value + * @since 1.6 + */ + public final void lazySet(long newValue) { + unsafe.putOrderedLong(this, valueOffset, newValue); + } + + /** + * Atomically sets to the given value and returns the old value. + * + * @param newValue the new value + * @return the previous value + */ + public final long getAndSet(long newValue) { + while (true) { + long current = get(); + if (compareAndSet(current, newValue)) + return current; + } + } + + /** + * Atomically sets the value to the given updated value + * if the current value <tt>==</tt> the expected value. + * + * @param expect the expected value + * @param update the new value + * @return true if successful. False return indicates that + * the actual value was not equal to the expected value. + */ + public final boolean compareAndSet(long expect, long update) { + return unsafe.compareAndSwapLong(this, valueOffset, expect, update); + } + + /** + * Atomically sets the value to the given updated value + * if the current value <tt>==</tt> the expected value. + * May fail spuriously and does not provide ordering guarantees, + * so is only rarely an appropriate alternative to <tt>compareAndSet</tt>. + * + * @param expect the expected value + * @param update the new value + * @return true if successful. + */ + public final boolean weakCompareAndSet(long expect, long update) { + return unsafe.compareAndSwapLong(this, valueOffset, expect, update); + } + + /** + * Atomically increments by one the current value. + * + * @return the previous value + */ + public final long getAndIncrement() { + while (true) { + long current = get(); + long next = current + 1; + if (compareAndSet(current, next)) + return current; + } + } + + /** + * Atomically decrements by one the current value. + * + * @return the previous value + */ + public final long getAndDecrement() { + while (true) { + long current = get(); + long next = current - 1; + if (compareAndSet(current, next)) + return current; + } + } + + /** + * Atomically adds the given value to the current value. + * + * @param delta the value to add + * @return the previous value + */ + public final long getAndAdd(long delta) { + while (true) { + long current = get(); + long next = current + delta; + if (compareAndSet(current, next)) + return current; + } + } + + /** + * Atomically increments by one the current value. + * + * @return the updated value + */ + public final long incrementAndGet() { + for (;;) { + long current = get(); + long next = current + 1; + if (compareAndSet(current, next)) + return next; + } + } + + /** + * Atomically decrements by one the current value. + * + * @return the updated value + */ + public final long decrementAndGet() { + for (;;) { + long current = get(); + long next = current - 1; + if (compareAndSet(current, next)) + return next; + } + } + + /** + * Atomically adds the given value to the current value. + * + * @param delta the value to add + * @return the updated value + */ + public final long addAndGet(long delta) { + for (;;) { + long current = get(); + long next = current + delta; + if (compareAndSet(current, next)) + return next; + } + } + + /** + * Returns the String representation of the current value. + * @return the String representation of the current value. + */ + public String toString() { + return Long.toString(get()); + } + + + public int intValue() { + return (int)get(); + } + + public long longValue() { + return (long)get(); + } + + public float floatValue() { + return (float)get(); + } + + public double doubleValue() { + return (double)get(); + } + +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicLongArray.java b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicLongArray.java new file mode 100644 index 000000000..c582cba54 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicLongArray.java @@ -0,0 +1,255 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent.atomic; +import sun.misc.Unsafe; +import java.util.*; + +/** + * A <tt>long</tt> array in which elements may be updated atomically. + * See the {@link java.util.concurrent.atomic} package specification + * for description of the properties of atomic variables. + * @since 1.5 + * @author Doug Lea + */ +public class AtomicLongArray implements java.io.Serializable { + private static final long serialVersionUID = -2308431214976778248L; + + // setup to use Unsafe.compareAndSwapInt for updates + private static final Unsafe unsafe = Unsafe.getUnsafe(); + private static final int base = unsafe.arrayBaseOffset(long[].class); + private static final int scale = unsafe.arrayIndexScale(long[].class); + private final long[] array; + + private long rawIndex(int i) { + if (i < 0 || i >= array.length) + throw new IndexOutOfBoundsException("index " + i); + return base + i * scale; + } + + /** + * Creates a new AtomicLongArray of given length. + * + * @param length the length of the array + */ + public AtomicLongArray(int length) { + array = new long[length]; + // must perform at least one volatile write to conform to JMM + if (length > 0) + unsafe.putLongVolatile(array, rawIndex(0), 0); + } + + /** + * Creates a new AtomicLongArray with the same length as, and + * all elements copied from, the given array. + * + * @param array the array to copy elements from + * @throws NullPointerException if array is null + */ + public AtomicLongArray(long[] array) { + if (array == null) + throw new NullPointerException(); + int length = array.length; + this.array = new long[length]; + if (length > 0) { + int last = length-1; + for (int i = 0; i < last; ++i) + this.array[i] = array[i]; + // Do the last write as volatile + unsafe.putLongVolatile(this.array, rawIndex(last), array[last]); + } + } + + /** + * Returns the length of the array. + * + * @return the length of the array + */ + public final int length() { + return array.length; + } + + /** + * Gets the current value at position <tt>i</tt>. + * + * @param i the index + * @return the current value + */ + public final long get(int i) { + return unsafe.getLongVolatile(array, rawIndex(i)); + } + + /** + * Sets the element at position <tt>i</tt> to the given value. + * + * @param i the index + * @param newValue the new value + */ + public final void set(int i, long newValue) { + unsafe.putLongVolatile(array, rawIndex(i), newValue); + } + + /** + * Eventually sets the element at position <tt>i</tt> to the given value. + * + * @param i the index + * @param newValue the new value + * @since 1.6 + */ + public final void lazySet(int i, long newValue) { + unsafe.putOrderedLong(array, rawIndex(i), newValue); + } + + + /** + * Atomically sets the element at position <tt>i</tt> to the given value + * and returns the old value. + * + * @param i the index + * @param newValue the new value + * @return the previous value + */ + public final long getAndSet(int i, long newValue) { + while (true) { + long current = get(i); + if (compareAndSet(i, current, newValue)) + return current; + } + } + + /** + * Atomically sets the value to the given updated value + * if the current value <tt>==</tt> the expected value. + * + * @param i the index + * @param expect the expected value + * @param update the new value + * @return true if successful. False return indicates that + * the actual value was not equal to the expected value. + */ + public final boolean compareAndSet(int i, long expect, long update) { + return unsafe.compareAndSwapLong(array, rawIndex(i), + expect, update); + } + + /** + * Atomically sets the value to the given updated value + * if the current value <tt>==</tt> the expected value. + * May fail spuriously and does not provide ordering guarantees, + * so is only rarely an appropriate alternative to <tt>compareAndSet</tt>. + * + * @param i the index + * @param expect the expected value + * @param update the new value + * @return true if successful. + */ + public final boolean weakCompareAndSet(int i, long expect, long update) { + return compareAndSet(i, expect, update); + } + + /** + * Atomically increments by one the element at index <tt>i</tt>. + * + * @param i the index + * @return the previous value + */ + public final long getAndIncrement(int i) { + while (true) { + long current = get(i); + long next = current + 1; + if (compareAndSet(i, current, next)) + return current; + } + } + + /** + * Atomically decrements by one the element at index <tt>i</tt>. + * + * @param i the index + * @return the previous value + */ + public final long getAndDecrement(int i) { + while (true) { + long current = get(i); + long next = current - 1; + if (compareAndSet(i, current, next)) + return current; + } + } + + /** + * Atomically adds the given value to the element at index <tt>i</tt>. + * + * @param i the index + * @param delta the value to add + * @return the previous value + */ + public final long getAndAdd(int i, long delta) { + while (true) { + long current = get(i); + long next = current + delta; + if (compareAndSet(i, current, next)) + return current; + } + } + + /** + * Atomically increments by one the element at index <tt>i</tt>. + * + * @param i the index + * @return the updated value + */ + public final long incrementAndGet(int i) { + while (true) { + long current = get(i); + long next = current + 1; + if (compareAndSet(i, current, next)) + return next; + } + } + + /** + * Atomically decrements by one the element at index <tt>i</tt>. + * + * @param i the index + * @return the updated value + */ + public final long decrementAndGet(int i) { + while (true) { + long current = get(i); + long next = current - 1; + if (compareAndSet(i, current, next)) + return next; + } + } + + /** + * Atomically adds the given value to the element at index <tt>i</tt>. + * + * @param i the index + * @param delta the value to add + * @return the updated value + */ + public long addAndGet(int i, long delta) { + while (true) { + long current = get(i); + long next = current + delta; + if (compareAndSet(i, current, next)) + return next; + } + } + + /** + * Returns the String representation of the current values of array. + * @return the String representation of the current values of array. + */ + public String toString() { + if (array.length > 0) // force volatile read + get(0); + return Arrays.toString(array); + } + +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicLongFieldUpdater.java b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicLongFieldUpdater.java new file mode 100644 index 000000000..f6135d1fc --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicLongFieldUpdater.java @@ -0,0 +1,406 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent.atomic; +import sun.misc.Unsafe; +import java.lang.reflect.*; + +/** + * A reflection-based utility that enables atomic updates to + * designated <tt>volatile long</tt> fields of designated classes. + * This class is designed for use in atomic data structures in which + * several fields of the same node are independently subject to atomic + * updates. + * + * <p>Note that the guarantees of the {@code compareAndSet} + * method in this class are weaker than in other atomic classes. + * Because this class cannot ensure that all uses of the field + * are appropriate for purposes of atomic access, it can + * guarantee atomicity only with respect to other invocations of + * {@code compareAndSet} and {@code set} on the same updater. + * + * @since 1.5 + * @author Doug Lea + * @param <T> The type of the object holding the updatable field + */ +public abstract class AtomicLongFieldUpdater<T> { + /** + * Creates and returns an updater for objects with the given field. + * The Class argument is needed to check that reflective types and + * generic types match. + * + * @param tclass the class of the objects holding the field + * @param fieldName the name of the field to be updated. + * @return the updater + * @throws IllegalArgumentException if the field is not a + * volatile long type. + * @throws RuntimeException with a nested reflection-based + * exception if the class does not hold field or is the wrong type. + */ + public static <U> AtomicLongFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName) { + if (AtomicLong.VM_SUPPORTS_LONG_CAS) + return new CASUpdater<U>(tclass, fieldName); + else + return new LockedUpdater<U>(tclass, fieldName); + } + + /** + * Protected do-nothing constructor for use by subclasses. + */ + protected AtomicLongFieldUpdater() { + } + + /** + * Atomically sets the field of the given object managed by this updater + * to the given updated value if the current value <tt>==</tt> the + * expected value. This method is guaranteed to be atomic with respect to + * other calls to <tt>compareAndSet</tt> and <tt>set</tt>, but not + * necessarily with respect to other changes in the field. + * + * @param obj An object whose field to conditionally set + * @param expect the expected value + * @param update the new value + * @return true if successful. + * @throws ClassCastException if <tt>obj</tt> is not an instance + * of the class possessing the field established in the constructor. + */ + public abstract boolean compareAndSet(T obj, long expect, long update); + + /** + * Atomically sets the field of the given object managed by this updater + * to the given updated value if the current value <tt>==</tt> the + * expected value. This method is guaranteed to be atomic with respect to + * other calls to <tt>compareAndSet</tt> and <tt>set</tt>, but not + * necessarily with respect to other changes in the field. + * May fail spuriously and does not provide ordering guarantees, + * so is only rarely an appropriate alternative to <tt>compareAndSet</tt>. + * + * @param obj An object whose field to conditionally set + * @param expect the expected value + * @param update the new value + * @return true if successful. + * @throws ClassCastException if <tt>obj</tt> is not an instance + * of the class possessing the field established in the constructor. + */ + public abstract boolean weakCompareAndSet(T obj, long expect, long update); + + /** + * Sets the field of the given object managed by this updater to the + * given updated value. This operation is guaranteed to act as a volatile + * store with respect to subsequent invocations of + * <tt>compareAndSet</tt>. + * + * @param obj An object whose field to set + * @param newValue the new value + */ + public abstract void set(T obj, long newValue); + + /** + * Eventually sets the field of the given object managed by this + * updater to the given updated value. + * + * @param obj An object whose field to set + * @param newValue the new value + * @since 1.6 + */ + public abstract void lazySet(T obj, long newValue); + + /** + * Gets the current value held in the field of the given object managed + * by this updater. + * + * @param obj An object whose field to get + * @return the current value + */ + public abstract long get(T obj); + + /** + * Atomically sets the field of the given object managed by this updater + * to the given value and returns the old value. + * + * @param obj An object whose field to get and set + * @param newValue the new value + * @return the previous value + */ + public long getAndSet(T obj, long newValue) { + for (;;) { + long current = get(obj); + if (compareAndSet(obj, current, newValue)) + return current; + } + } + + /** + * Atomically increments by one the current value of the field of the + * given object managed by this updater. + * + * @param obj An object whose field to get and set + * @return the previous value + */ + public long getAndIncrement(T obj) { + for (;;) { + long current = get(obj); + long next = current + 1; + if (compareAndSet(obj, current, next)) + return current; + } + } + + /** + * Atomically decrements by one the current value of the field of the + * given object managed by this updater. + * + * @param obj An object whose field to get and set + * @return the previous value + */ + public long getAndDecrement(T obj) { + for (;;) { + long current = get(obj); + long next = current - 1; + if (compareAndSet(obj, current, next)) + return current; + } + } + + /** + * Atomically adds the given value to the current value of the field of + * the given object managed by this updater. + * + * @param obj An object whose field to get and set + * @param delta the value to add + * @return the previous value + */ + public long getAndAdd(T obj, long delta) { + for (;;) { + long current = get(obj); + long next = current + delta; + if (compareAndSet(obj, current, next)) + return current; + } + } + + /** + * Atomically increments by one the current value of the field of the + * given object managed by this updater. + * + * @param obj An object whose field to get and set + * @return the updated value + */ + public long incrementAndGet(T obj) { + for (;;) { + long current = get(obj); + long next = current + 1; + if (compareAndSet(obj, current, next)) + return next; + } + } + + /** + * Atomically decrements by one the current value of the field of the + * given object managed by this updater. + * + * @param obj An object whose field to get and set + * @return the updated value + */ + public long decrementAndGet(T obj) { + for (;;) { + long current = get(obj); + long next = current - 1; + if (compareAndSet(obj, current, next)) + return next; + } + } + + /** + * Atomically adds the given value to the current value of the field of + * the given object managed by this updater. + * + * @param obj An object whose field to get and set + * @param delta the value to add + * @return the updated value + */ + public long addAndGet(T obj, long delta) { + for (;;) { + long current = get(obj); + long next = current + delta; + if (compareAndSet(obj, current, next)) + return next; + } + } + + private static class CASUpdater<T> extends AtomicLongFieldUpdater<T> { + private static final Unsafe unsafe = Unsafe.getUnsafe(); + private final long offset; + private final Class<T> tclass; + private final Class cclass; + + CASUpdater(Class<T> tclass, String fieldName) { + Field field = null; + Class caller = null; + int modifiers = 0; + try { + field = tclass.getDeclaredField(fieldName); + caller = sun.reflect.Reflection.getCallerClass(3); + modifiers = field.getModifiers(); + sun.reflect.misc.ReflectUtil.ensureMemberAccess( + caller, tclass, null, modifiers); + sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass); + } catch(Exception ex) { + throw new RuntimeException(ex); + } + + Class fieldt = field.getType(); + if (fieldt != long.class) + throw new IllegalArgumentException("Must be long type"); + + if (!Modifier.isVolatile(modifiers)) + throw new IllegalArgumentException("Must be volatile type"); + + this.cclass = (Modifier.isProtected(modifiers) && + caller != tclass) ? caller : null; + this.tclass = tclass; + offset = unsafe.objectFieldOffset(field); + } + + private void fullCheck(T obj) { + if (!tclass.isInstance(obj)) + throw new ClassCastException(); + if (cclass != null) + ensureProtectedAccess(obj); + } + + public boolean compareAndSet(T obj, long expect, long update) { + if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); + return unsafe.compareAndSwapLong(obj, offset, expect, update); + } + + public boolean weakCompareAndSet(T obj, long expect, long update) { + if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); + return unsafe.compareAndSwapLong(obj, offset, expect, update); + } + + public void set(T obj, long newValue) { + if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); + unsafe.putLongVolatile(obj, offset, newValue); + } + + public void lazySet(T obj, long newValue) { + if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); + unsafe.putOrderedLong(obj, offset, newValue); + } + + public long get(T obj) { + if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); + return unsafe.getLongVolatile(obj, offset); + } + + private void ensureProtectedAccess(T obj) { + if (cclass.isInstance(obj)) { + return; + } + throw new RuntimeException ( + new IllegalAccessException("Class " + + cclass.getName() + + " can not access a protected member of class " + + tclass.getName() + + " using an instance of " + + obj.getClass().getName() + ) + ); + } + } + + + private static class LockedUpdater<T> extends AtomicLongFieldUpdater<T> { + private static final Unsafe unsafe = Unsafe.getUnsafe(); + private final long offset; + private final Class<T> tclass; + private final Class cclass; + + LockedUpdater(Class<T> tclass, String fieldName) { + Field field = null; + Class caller = null; + int modifiers = 0; + try { + field = tclass.getDeclaredField(fieldName); + caller = sun.reflect.Reflection.getCallerClass(3); + modifiers = field.getModifiers(); + sun.reflect.misc.ReflectUtil.ensureMemberAccess( + caller, tclass, null, modifiers); + sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass); + } catch(Exception ex) { + throw new RuntimeException(ex); + } + + Class fieldt = field.getType(); + if (fieldt != long.class) + throw new IllegalArgumentException("Must be long type"); + + if (!Modifier.isVolatile(modifiers)) + throw new IllegalArgumentException("Must be volatile type"); + + this.cclass = (Modifier.isProtected(modifiers) && + caller != tclass) ? caller : null; + this.tclass = tclass; + offset = unsafe.objectFieldOffset(field); + } + + private void fullCheck(T obj) { + if (!tclass.isInstance(obj)) + throw new ClassCastException(); + if (cclass != null) + ensureProtectedAccess(obj); + } + + public boolean compareAndSet(T obj, long expect, long update) { + if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); + synchronized(this) { + long v = unsafe.getLong(obj, offset); + if (v != expect) + return false; + unsafe.putLong(obj, offset, update); + return true; + } + } + + public boolean weakCompareAndSet(T obj, long expect, long update) { + return compareAndSet(obj, expect, update); + } + + public void set(T obj, long newValue) { + if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); + synchronized(this) { + unsafe.putLong(obj, offset, newValue); + } + } + + public void lazySet(T obj, long newValue) { + set(obj, newValue); + } + + public long get(T obj) { + if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); + synchronized(this) { + return unsafe.getLong(obj, offset); + } + } + + private void ensureProtectedAccess(T obj) { + if (cclass.isInstance(obj)) { + return; + } + throw new RuntimeException ( + new IllegalAccessException("Class " + + cclass.getName() + + " can not access a protected member of class " + + tclass.getName() + + " using an instance of " + + obj.getClass().getName() + ) + ); + } + } +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicMarkableReference.java b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicMarkableReference.java new file mode 100644 index 000000000..85335b737 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicMarkableReference.java @@ -0,0 +1,161 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent.atomic; + +/** + * An <tt>AtomicMarkableReference</tt> maintains an object reference + * along with a mark bit, that can be updated atomically. + * <p> + * <p> Implementation note. This implementation maintains markable + * references by creating internal objects representing "boxed" + * [reference, boolean] pairs. + * + * @since 1.5 + * @author Doug Lea + * @param <V> The type of object referred to by this reference + */ +public class AtomicMarkableReference<V> { + + private static class ReferenceBooleanPair<T> { + private final T reference; + private final boolean bit; + ReferenceBooleanPair(T r, boolean i) { + reference = r; bit = i; + } + } + + private final AtomicReference<ReferenceBooleanPair<V>> atomicRef; + + /** + * Creates a new <tt>AtomicMarkableReference</tt> with the given + * initial values. + * + * @param initialRef the initial reference + * @param initialMark the initial mark + */ + public AtomicMarkableReference(V initialRef, boolean initialMark) { + atomicRef = new AtomicReference<ReferenceBooleanPair<V>> (new ReferenceBooleanPair<V>(initialRef, initialMark)); + } + + /** + * Returns the current value of the reference. + * + * @return the current value of the reference + */ + public V getReference() { + return atomicRef.get().reference; + } + + /** + * Returns the current value of the mark. + * + * @return the current value of the mark + */ + public boolean isMarked() { + return atomicRef.get().bit; + } + + /** + * Returns the current values of both the reference and the mark. + * Typical usage is <tt>boolean[1] holder; ref = v.get(holder); </tt>. + * + * @param markHolder an array of size of at least one. On return, + * <tt>markholder[0]</tt> will hold the value of the mark. + * @return the current value of the reference + */ + public V get(boolean[] markHolder) { + ReferenceBooleanPair<V> p = atomicRef.get(); + markHolder[0] = p.bit; + return p.reference; + } + + /** + * Atomically sets the value of both the reference and mark + * to the given update values if the + * current reference is <tt>==</tt> to the expected reference + * and the current mark is equal to the expected mark. + * May fail spuriously and does not provide ordering guarantees, + * so is only rarely an appropriate alternative to <tt>compareAndSet</tt>. + * + * @param expectedReference the expected value of the reference + * @param newReference the new value for the reference + * @param expectedMark the expected value of the mark + * @param newMark the new value for the mark + * @return true if successful + */ + public boolean weakCompareAndSet(V expectedReference, + V newReference, + boolean expectedMark, + boolean newMark) { + ReferenceBooleanPair<V> current = atomicRef.get(); + return expectedReference == current.reference && + expectedMark == current.bit && + ((newReference == current.reference && newMark == current.bit) || + atomicRef.weakCompareAndSet(current, + new ReferenceBooleanPair<V>(newReference, + newMark))); + } + + /** + * Atomically sets the value of both the reference and mark + * to the given update values if the + * current reference is <tt>==</tt> to the expected reference + * and the current mark is equal to the expected mark. + * + * @param expectedReference the expected value of the reference + * @param newReference the new value for the reference + * @param expectedMark the expected value of the mark + * @param newMark the new value for the mark + * @return true if successful + */ + public boolean compareAndSet(V expectedReference, + V newReference, + boolean expectedMark, + boolean newMark) { + ReferenceBooleanPair<V> current = atomicRef.get(); + return expectedReference == current.reference && + expectedMark == current.bit && + ((newReference == current.reference && newMark == current.bit) || + atomicRef.compareAndSet(current, + new ReferenceBooleanPair<V>(newReference, + newMark))); + } + + /** + * Unconditionally sets the value of both the reference and mark. + * + * @param newReference the new value for the reference + * @param newMark the new value for the mark + */ + public void set(V newReference, boolean newMark) { + ReferenceBooleanPair<V> current = atomicRef.get(); + if (newReference != current.reference || newMark != current.bit) + atomicRef.set(new ReferenceBooleanPair<V>(newReference, newMark)); + } + + /** + * Atomically sets the value of the mark to the given update value + * if the current reference is <tt>==</tt> to the expected + * reference. Any given invocation of this operation may fail + * (return <tt>false</tt>) spuriously, but repeated invocation + * when the current value holds the expected value and no other + * thread is also attempting to set the value will eventually + * succeed. + * + * @param expectedReference the expected value of the reference + * @param newMark the new value for the mark + * @return true if successful + */ + public boolean attemptMark(V expectedReference, boolean newMark) { + ReferenceBooleanPair<V> current = atomicRef.get(); + return expectedReference == current.reference && + (newMark == current.bit || + atomicRef.compareAndSet + (current, new ReferenceBooleanPair<V>(expectedReference, + newMark))); + } +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicReference.java b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicReference.java new file mode 100644 index 000000000..e7c989c2b --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicReference.java @@ -0,0 +1,124 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent.atomic; +import sun.misc.Unsafe; + +/** + * An object reference that may be updated atomically. See the {@link + * java.util.concurrent.atomic} package specification for description + * of the properties of atomic variables. + * @since 1.5 + * @author Doug Lea + * @param <V> The type of object referred to by this reference + */ +public class AtomicReference<V> implements java.io.Serializable { + private static final long serialVersionUID = -1848883965231344442L; + + private static final Unsafe unsafe = Unsafe.getUnsafe(); + private static final long valueOffset; + + static { + try { + valueOffset = unsafe.objectFieldOffset + (AtomicReference.class.getDeclaredField("value")); + } catch (Exception ex) { throw new Error(ex); } + } + + private volatile V value; + + /** + * Creates a new AtomicReference with the given initial value. + * + * @param initialValue the initial value + */ + public AtomicReference(V initialValue) { + value = initialValue; + } + + /** + * Creates a new AtomicReference with null initial value. + */ + public AtomicReference() { + } + + /** + * Gets the current value. + * + * @return the current value + */ + public final V get() { + return value; + } + + /** + * Sets to the given value. + * + * @param newValue the new value + */ + public final void set(V newValue) { + value = newValue; + } + + /** + * Eventually sets to the given value. + * + * @param newValue the new value + * @since 1.6 + */ + public final void lazySet(V newValue) { + unsafe.putOrderedObject(this, valueOffset, newValue); + } + + /** + * Atomically sets the value to the given updated value + * if the current value <tt>==</tt> the expected value. + * @param expect the expected value + * @param update the new value + * @return true if successful. False return indicates that + * the actual value was not equal to the expected value. + */ + public final boolean compareAndSet(V expect, V update) { + return unsafe.compareAndSwapObject(this, valueOffset, expect, update); + } + + /** + * Atomically sets the value to the given updated value + * if the current value <tt>==</tt> the expected value. + * May fail spuriously and does not provide ordering guarantees, + * so is only rarely an appropriate alternative to <tt>compareAndSet</tt>. + * + * @param expect the expected value + * @param update the new value + * @return true if successful. + */ + public final boolean weakCompareAndSet(V expect, V update) { + return unsafe.compareAndSwapObject(this, valueOffset, expect, update); + } + + /** + * Atomically sets to the given value and returns the old value. + * + * @param newValue the new value + * @return the previous value + */ + public final V getAndSet(V newValue) { + while (true) { + V x = get(); + if (compareAndSet(x, newValue)) + return x; + } + } + + /** + * Returns the String representation of the current value. + * @return the String representation of the current value. + */ + public String toString() { + return String.valueOf(get()); + } + +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicReferenceArray.java b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicReferenceArray.java new file mode 100644 index 000000000..91b601ed9 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicReferenceArray.java @@ -0,0 +1,163 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent.atomic; +import sun.misc.Unsafe; +import java.util.*; + +/** + * An array of object references in which elements may be updated + * atomically. See the {@link java.util.concurrent.atomic} package + * specification for description of the properties of atomic + * variables. + * @since 1.5 + * @author Doug Lea + * @param <E> The base class of elements held in this array + */ +public class AtomicReferenceArray<E> implements java.io.Serializable { + private static final long serialVersionUID = -6209656149925076980L; + + private static final Unsafe unsafe = Unsafe.getUnsafe(); + private static final int base = unsafe.arrayBaseOffset(Object[].class); + private static final int scale = unsafe.arrayIndexScale(Object[].class); + private final Object[] array; + + private long rawIndex(int i) { + if (i < 0 || i >= array.length) + throw new IndexOutOfBoundsException("index " + i); + return base + i * scale; + } + + /** + * Creates a new AtomicReferenceArray of given length. + * @param length the length of the array + */ + public AtomicReferenceArray(int length) { + array = new Object[length]; + // must perform at least one volatile write to conform to JMM + if (length > 0) + unsafe.putObjectVolatile(array, rawIndex(0), null); + } + + /** + * Creates a new AtomicReferenceArray with the same length as, and + * all elements copied from, the given array. + * + * @param array the array to copy elements from + * @throws NullPointerException if array is null + */ + public AtomicReferenceArray(E[] array) { + if (array == null) + throw new NullPointerException(); + int length = array.length; + this.array = new Object[length]; + if (length > 0) { + int last = length-1; + for (int i = 0; i < last; ++i) + this.array[i] = array[i]; + // Do the last write as volatile + E e = array[last]; + unsafe.putObjectVolatile(this.array, rawIndex(last), e); + } + } + + /** + * Returns the length of the array. + * + * @return the length of the array + */ + public final int length() { + return array.length; + } + + /** + * Gets the current value at position <tt>i</tt>. + * + * @param i the index + * @return the current value + */ + public final E get(int i) { + return (E) unsafe.getObjectVolatile(array, rawIndex(i)); + } + + /** + * Sets the element at position <tt>i</tt> to the given value. + * + * @param i the index + * @param newValue the new value + */ + public final void set(int i, E newValue) { + unsafe.putObjectVolatile(array, rawIndex(i), newValue); + } + + /** + * Eventually sets the element at position <tt>i</tt> to the given value. + * + * @param i the index + * @param newValue the new value + * @since 1.6 + */ + public final void lazySet(int i, E newValue) { + unsafe.putOrderedObject(array, rawIndex(i), newValue); + } + + + /** + * Atomically sets the element at position <tt>i</tt> to the given + * value and returns the old value. + * + * @param i the index + * @param newValue the new value + * @return the previous value + */ + public final E getAndSet(int i, E newValue) { + while (true) { + E current = get(i); + if (compareAndSet(i, current, newValue)) + return current; + } + } + + /** + * Atomically sets the element at position <tt>i</tt> to the given + * updated value if the current value <tt>==</tt> the expected value. + * @param i the index + * @param expect the expected value + * @param update the new value + * @return true if successful. False return indicates that + * the actual value was not equal to the expected value. + */ + public final boolean compareAndSet(int i, E expect, E update) { + return unsafe.compareAndSwapObject(array, rawIndex(i), + expect, update); + } + + /** + * Atomically sets the element at position <tt>i</tt> to the given + * updated value if the current value <tt>==</tt> the expected value. + * May fail spuriously and does not provide ordering guarantees, + * so is only rarely an appropriate alternative to <tt>compareAndSet</tt>. + * + * @param i the index + * @param expect the expected value + * @param update the new value + * @return true if successful. + */ + public final boolean weakCompareAndSet(int i, E expect, E update) { + return compareAndSet(i, expect, update); + } + + /** + * Returns the String representation of the current values of array. + * @return the String representation of the current values of array. + */ + public String toString() { + if (array.length > 0) // force volatile read + get(0); + return Arrays.toString(array); + } + +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java new file mode 100644 index 000000000..24014a9df --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java @@ -0,0 +1,275 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent.atomic; +import sun.misc.Unsafe; +import java.lang.reflect.*; + +/** + * A reflection-based utility that enables atomic updates to + * designated <tt>volatile</tt> reference fields of designated + * classes. This class is designed for use in atomic data structures + * in which several reference fields of the same node are + * independently subject to atomic updates. For example, a tree node + * might be declared as + * + * <pre> + * class Node { + * private volatile Node left, right; + * + * private static final AtomicReferenceFieldUpdater<Node, Node> leftUpdater = + * AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "left"); + * private static AtomicReferenceFieldUpdater<Node, Node> rightUpdater = + * AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "right"); + * + * Node getLeft() { return left; } + * boolean compareAndSetLeft(Node expect, Node update) { + * return leftUpdater.compareAndSet(this, expect, update); + * } + * // ... and so on + * } + * </pre> + * + * <p>Note that the guarantees of the {@code compareAndSet} + * method in this class are weaker than in other atomic classes. + * Because this class cannot ensure that all uses of the field + * are appropriate for purposes of atomic access, it can + * guarantee atomicity only with respect to other invocations of + * {@code compareAndSet} and {@code set} on the same updater. + * + * @since 1.5 + * @author Doug Lea + * @param <T> The type of the object holding the updatable field + * @param <V> The type of the field + */ +public abstract class AtomicReferenceFieldUpdater<T, V> { + + /** + * Creates and returns an updater for objects with the given field. + * The Class arguments are needed to check that reflective types and + * generic types match. + * + * @param tclass the class of the objects holding the field. + * @param vclass the class of the field + * @param fieldName the name of the field to be updated. + * @return the updater + * @throws IllegalArgumentException if the field is not a volatile reference type. + * @throws RuntimeException with a nested reflection-based + * exception if the class does not hold field or is the wrong type. + */ + public static <U, W> AtomicReferenceFieldUpdater<U,W> newUpdater(Class<U> tclass, Class<W> vclass, String fieldName) { + return new AtomicReferenceFieldUpdaterImpl<U,W>(tclass, + vclass, + fieldName); + } + + /** + * Protected do-nothing constructor for use by subclasses. + */ + protected AtomicReferenceFieldUpdater() { + } + + /** + * Atomically sets the field of the given object managed by this updater + * to the given updated value if the current value <tt>==</tt> the + * expected value. This method is guaranteed to be atomic with respect to + * other calls to <tt>compareAndSet</tt> and <tt>set</tt>, but not + * necessarily with respect to other changes in the field. + * + * @param obj An object whose field to conditionally set + * @param expect the expected value + * @param update the new value + * @return true if successful. + */ + public abstract boolean compareAndSet(T obj, V expect, V update); + + /** + * Atomically sets the field of the given object managed by this updater + * to the given updated value if the current value <tt>==</tt> the + * expected value. This method is guaranteed to be atomic with respect to + * other calls to <tt>compareAndSet</tt> and <tt>set</tt>, but not + * necessarily with respect to other changes in the field. + * May fail spuriously and does not provide ordering guarantees, + * so is only rarely an appropriate alternative to <tt>compareAndSet</tt>. + * + * @param obj An object whose field to conditionally set + * @param expect the expected value + * @param update the new value + * @return true if successful. + */ + public abstract boolean weakCompareAndSet(T obj, V expect, V update); + + /** + * Sets the field of the given object managed by this updater to the + * given updated value. This operation is guaranteed to act as a volatile + * store with respect to subsequent invocations of + * <tt>compareAndSet</tt>. + * + * @param obj An object whose field to set + * @param newValue the new value + */ + public abstract void set(T obj, V newValue); + + /** + * Eventually sets the field of the given object managed by this + * updater to the given updated value. + * + * @param obj An object whose field to set + * @param newValue the new value + * @since 1.6 + */ + public abstract void lazySet(T obj, V newValue); + + /** + * Gets the current value held in the field of the given object managed + * by this updater. + * + * @param obj An object whose field to get + * @return the current value + */ + public abstract V get(T obj); + + /** + * Atomically sets the field of the given object managed by this updater + * to the given value and returns the old value. + * + * @param obj An object whose field to get and set + * @param newValue the new value + * @return the previous value + */ + public V getAndSet(T obj, V newValue) { + for (;;) { + V current = get(obj); + if (compareAndSet(obj, current, newValue)) + return current; + } + } + + private static final class AtomicReferenceFieldUpdaterImpl<T,V> + extends AtomicReferenceFieldUpdater<T,V> { + private static final Unsafe unsafe = Unsafe.getUnsafe(); + private final long offset; + private final Class<T> tclass; + private final Class<V> vclass; + private final Class cclass; + + /* + * Internal type checks within all update methods contain + * internal inlined optimizations checking for the common + * cases where the class is final (in which case a simple + * getClass comparison suffices) or is of type Object (in + * which case no check is needed because all objects are + * instances of Object). The Object case is handled simply by + * setting vclass to null in constructor. The targetCheck and + * updateCheck methods are invoked when these faster + * screenings fail. + */ + + AtomicReferenceFieldUpdaterImpl(Class<T> tclass, + Class<V> vclass, + String fieldName) { + Field field = null; + Class fieldClass = null; + Class caller = null; + int modifiers = 0; + try { + field = tclass.getDeclaredField(fieldName); + caller = sun.reflect.Reflection.getCallerClass(3); + modifiers = field.getModifiers(); + sun.reflect.misc.ReflectUtil.ensureMemberAccess( + caller, tclass, null, modifiers); + sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass); + fieldClass = field.getType(); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + + if (vclass != fieldClass) + throw new ClassCastException(); + + if (!Modifier.isVolatile(modifiers)) + throw new IllegalArgumentException("Must be volatile type"); + + this.cclass = (Modifier.isProtected(modifiers) && + caller != tclass) ? caller : null; + this.tclass = tclass; + if (vclass == Object.class) + this.vclass = null; + else + this.vclass = vclass; + offset = unsafe.objectFieldOffset(field); + } + + void targetCheck(T obj) { + if (!tclass.isInstance(obj)) + throw new ClassCastException(); + if (cclass != null) + ensureProtectedAccess(obj); + } + + void updateCheck(T obj, V update) { + if (!tclass.isInstance(obj) || + (update != null && vclass != null && !vclass.isInstance(update))) + throw new ClassCastException(); + if (cclass != null) + ensureProtectedAccess(obj); + } + + public boolean compareAndSet(T obj, V expect, V update) { + if (obj == null || obj.getClass() != tclass || cclass != null || + (update != null && vclass != null && + vclass != update.getClass())) + updateCheck(obj, update); + return unsafe.compareAndSwapObject(obj, offset, expect, update); + } + + public boolean weakCompareAndSet(T obj, V expect, V update) { + // same implementation as strong form for now + if (obj == null || obj.getClass() != tclass || cclass != null || + (update != null && vclass != null && + vclass != update.getClass())) + updateCheck(obj, update); + return unsafe.compareAndSwapObject(obj, offset, expect, update); + } + + public void set(T obj, V newValue) { + if (obj == null || obj.getClass() != tclass || cclass != null || + (newValue != null && vclass != null && + vclass != newValue.getClass())) + updateCheck(obj, newValue); + unsafe.putObjectVolatile(obj, offset, newValue); + } + + public void lazySet(T obj, V newValue) { + if (obj == null || obj.getClass() != tclass || cclass != null || + (newValue != null && vclass != null && + vclass != newValue.getClass())) + updateCheck(obj, newValue); + unsafe.putOrderedObject(obj, offset, newValue); + } + + public V get(T obj) { + if (obj == null || obj.getClass() != tclass || cclass != null) + targetCheck(obj); + return (V)unsafe.getObjectVolatile(obj, offset); + } + + private void ensureProtectedAccess(T obj) { + if (cclass.isInstance(obj)) { + return; + } + throw new RuntimeException ( + new IllegalAccessException("Class " + + cclass.getName() + + " can not access a protected member of class " + + tclass.getName() + + " using an instance of " + + obj.getClass().getName() + ) + ); + } + } +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicStampedReference.java b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicStampedReference.java new file mode 100644 index 000000000..558808216 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicStampedReference.java @@ -0,0 +1,165 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent.atomic; + +/** + * An <tt>AtomicStampedReference</tt> maintains an object reference + * along with an integer "stamp", that can be updated atomically. + * + * <p> Implementation note. This implementation maintains stamped + * references by creating internal objects representing "boxed" + * [reference, integer] pairs. + * + * @since 1.5 + * @author Doug Lea + * @param <V> The type of object referred to by this reference + */ +public class AtomicStampedReference<V> { + + private static class ReferenceIntegerPair<T> { + private final T reference; + private final int integer; + ReferenceIntegerPair(T r, int i) { + reference = r; integer = i; + } + } + + private final AtomicReference<ReferenceIntegerPair<V>> atomicRef; + + /** + * Creates a new <tt>AtomicStampedReference</tt> with the given + * initial values. + * + * @param initialRef the initial reference + * @param initialStamp the initial stamp + */ + public AtomicStampedReference(V initialRef, int initialStamp) { + atomicRef = new AtomicReference<ReferenceIntegerPair<V>> + (new ReferenceIntegerPair<V>(initialRef, initialStamp)); + } + + /** + * Returns the current value of the reference. + * + * @return the current value of the reference + */ + public V getReference() { + return atomicRef.get().reference; + } + + /** + * Returns the current value of the stamp. + * + * @return the current value of the stamp + */ + public int getStamp() { + return atomicRef.get().integer; + } + + /** + * Returns the current values of both the reference and the stamp. + * Typical usage is <tt>int[1] holder; ref = v.get(holder); </tt>. + * + * @param stampHolder an array of size of at least one. On return, + * <tt>stampholder[0]</tt> will hold the value of the stamp. + * @return the current value of the reference + */ + public V get(int[] stampHolder) { + ReferenceIntegerPair<V> p = atomicRef.get(); + stampHolder[0] = p.integer; + return p.reference; + } + + /** + * Atomically sets the value of both the reference and stamp + * to the given update values if the + * current reference is <tt>==</tt> to the expected reference + * and the current stamp is equal to the expected stamp. + * May fail spuriously and does not provide ordering guarantees, + * so is only rarely an appropriate alternative to <tt>compareAndSet</tt>. + * + * @param expectedReference the expected value of the reference + * @param newReference the new value for the reference + * @param expectedStamp the expected value of the stamp + * @param newStamp the new value for the stamp + * @return true if successful + */ + public boolean weakCompareAndSet(V expectedReference, + V newReference, + int expectedStamp, + int newStamp) { + ReferenceIntegerPair<V> current = atomicRef.get(); + return expectedReference == current.reference && + expectedStamp == current.integer && + ((newReference == current.reference && + newStamp == current.integer) || + atomicRef.weakCompareAndSet(current, + new ReferenceIntegerPair<V>(newReference, + newStamp))); + } + + /** + * Atomically sets the value of both the reference and stamp + * to the given update values if the + * current reference is <tt>==</tt> to the expected reference + * and the current stamp is equal to the expected stamp. + * + * @param expectedReference the expected value of the reference + * @param newReference the new value for the reference + * @param expectedStamp the expected value of the stamp + * @param newStamp the new value for the stamp + * @return true if successful + */ + public boolean compareAndSet(V expectedReference, + V newReference, + int expectedStamp, + int newStamp) { + ReferenceIntegerPair<V> current = atomicRef.get(); + return expectedReference == current.reference && + expectedStamp == current.integer && + ((newReference == current.reference && + newStamp == current.integer) || + atomicRef.compareAndSet(current, + new ReferenceIntegerPair<V>(newReference, + newStamp))); + } + + + /** + * Unconditionally sets the value of both the reference and stamp. + * + * @param newReference the new value for the reference + * @param newStamp the new value for the stamp + */ + public void set(V newReference, int newStamp) { + ReferenceIntegerPair<V> current = atomicRef.get(); + if (newReference != current.reference || newStamp != current.integer) + atomicRef.set(new ReferenceIntegerPair<V>(newReference, newStamp)); + } + + /** + * Atomically sets the value of the stamp to the given update value + * if the current reference is <tt>==</tt> to the expected + * reference. Any given invocation of this operation may fail + * (return <tt>false</tt>) spuriously, but repeated invocation + * when the current value holds the expected value and no other + * thread is also attempting to set the value will eventually + * succeed. + * + * @param expectedReference the expected value of the reference + * @param newStamp the new value for the stamp + * @return true if successful + */ + public boolean attemptStamp(V expectedReference, int newStamp) { + ReferenceIntegerPair<V> current = atomicRef.get(); + return expectedReference == current.reference && + (newStamp == current.integer || + atomicRef.compareAndSet(current, + new ReferenceIntegerPair<V>(expectedReference, + newStamp))); + } +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/locks/AbstractOwnableSynchronizer.java b/libjava/classpath/external/jsr166/java/util/concurrent/locks/AbstractOwnableSynchronizer.java new file mode 100644 index 000000000..f3780e5a6 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/locks/AbstractOwnableSynchronizer.java @@ -0,0 +1,57 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent.locks; + +/** + * A synchronizer that may be exclusively owned by a thread. This + * class provides a basis for creating locks and related synchronizers + * that may entail a notion of ownership. The + * <tt>AbstractOwnableSynchronizer</tt> class itself does not manage or + * use this information. However, subclasses and tools may use + * appropriately maintained values to help control and monitor access + * and provide diagnostics. + * + * @since 1.6 + * @author Doug Lea + */ +public abstract class AbstractOwnableSynchronizer + implements java.io.Serializable { + + /** Use serial ID even though all fields transient. */ + private static final long serialVersionUID = 3737899427754241961L; + + /** + * Empty constructor for use by subclasses. + */ + protected AbstractOwnableSynchronizer() { } + + /** + * The current owner of exclusive mode synchronization. + */ + private transient Thread exclusiveOwnerThread; + + /** + * Sets the thread that currently owns exclusive access. A + * <tt>null</tt> argument indicates that no thread owns access. + * This method does not otherwise impose any synchronization or + * <tt>volatile</tt> field accesses. + */ + protected final void setExclusiveOwnerThread(Thread t) { + exclusiveOwnerThread = t; + } + + /** + * Returns the thread last set by + * <tt>setExclusiveOwnerThread</tt>, or <tt>null</tt> if never + * set. This method does not otherwise impose any synchronization + * or <tt>volatile</tt> field accesses. + * @return the owner thread + */ + protected final Thread getExclusiveOwnerThread() { + return exclusiveOwnerThread; + } +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java b/libjava/classpath/external/jsr166/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java new file mode 100644 index 000000000..45d744bb8 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java @@ -0,0 +1,1934 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent.locks; +import java.util.*; +import java.util.concurrent.*; +import java.util.concurrent.atomic.*; +import sun.misc.Unsafe; + +/** + * A version of {@link AbstractQueuedSynchronizer} in + * which synchronization state is maintained as a <tt>long</tt>. + * This class has exactly the same structure, properties, and methods + * as <tt>AbstractQueuedSynchronizer</tt> with the exception + * that all state-related parameters and results are defined + * as <tt>long</tt> rather than <tt>int</tt>. This class + * may be useful when creating synchronizers such as + * multilevel locks and barriers that require + * 64 bits of state. + * + * <p>See {@link AbstractQueuedSynchronizer} for usage + * notes and examples. + * + * @since 1.6 + * @author Doug Lea + */ +public abstract class AbstractQueuedLongSynchronizer + extends AbstractOwnableSynchronizer + implements java.io.Serializable { + + private static final long serialVersionUID = 7373984972572414692L; + + /* + To keep sources in sync, the remainder of this source file is + exactly cloned from AbstractQueuedSynchronizer, replacing class + name and changing ints related with sync state to longs. Please + keep it that way. + */ + + /** + * Creates a new <tt>AbstractQueuedLongSynchronizer</tt> instance + * with initial synchronization state of zero. + */ + protected AbstractQueuedLongSynchronizer() { } + + /** + * Wait queue node class. + * + * <p>The wait queue is a variant of a "CLH" (Craig, Landin, and + * Hagersten) lock queue. CLH locks are normally used for + * spinlocks. We instead use them for blocking synchronizers, but + * use the same basic tactic of holding some of the control + * information about a thread in the predecessor of its node. A + * "status" field in each node keeps track of whether a thread + * should block. A node is signalled when its predecessor + * releases. Each node of the queue otherwise serves as a + * specific-notification-style monitor holding a single waiting + * thread. The status field does NOT control whether threads are + * granted locks etc though. A thread may try to acquire if it is + * first in the queue. But being first does not guarantee success; + * it only gives the right to contend. So the currently released + * contender thread may need to rewait. + * + * <p>To enqueue into a CLH lock, you atomically splice it in as new + * tail. To dequeue, you just set the head field. + * <pre> + * +------+ prev +-----+ +-----+ + * head | | <---- | | <---- | | tail + * +------+ +-----+ +-----+ + * </pre> + * + * <p>Insertion into a CLH queue requires only a single atomic + * operation on "tail", so there is a simple atomic point of + * demarcation from unqueued to queued. Similarly, dequeing + * involves only updating the "head". However, it takes a bit + * more work for nodes to determine who their successors are, + * in part to deal with possible cancellation due to timeouts + * and interrupts. + * + * <p>The "prev" links (not used in original CLH locks), are mainly + * needed to handle cancellation. If a node is cancelled, its + * successor is (normally) relinked to a non-cancelled + * predecessor. For explanation of similar mechanics in the case + * of spin locks, see the papers by Scott and Scherer at + * http://www.cs.rochester.edu/u/scott/synchronization/ + * + * <p>We also use "next" links to implement blocking mechanics. + * The thread id for each node is kept in its own node, so a + * predecessor signals the next node to wake up by traversing + * next link to determine which thread it is. Determination of + * successor must avoid races with newly queued nodes to set + * the "next" fields of their predecessors. This is solved + * when necessary by checking backwards from the atomically + * updated "tail" when a node's successor appears to be null. + * (Or, said differently, the next-links are an optimization + * so that we don't usually need a backward scan.) + * + * <p>Cancellation introduces some conservatism to the basic + * algorithms. Since we must poll for cancellation of other + * nodes, we can miss noticing whether a cancelled node is + * ahead or behind us. This is dealt with by always unparking + * successors upon cancellation, allowing them to stabilize on + * a new predecessor. + * + * <p>CLH queues need a dummy header node to get started. But + * we don't create them on construction, because it would be wasted + * effort if there is never contention. Instead, the node + * is constructed and head and tail pointers are set upon first + * contention. + * + * <p>Threads waiting on Conditions use the same nodes, but + * use an additional link. Conditions only need to link nodes + * in simple (non-concurrent) linked queues because they are + * only accessed when exclusively held. Upon await, a node is + * inserted into a condition queue. Upon signal, the node is + * transferred to the main queue. A special value of status + * field is used to mark which queue a node is on. + * + * <p>Thanks go to Dave Dice, Mark Moir, Victor Luchangco, Bill + * Scherer and Michael Scott, along with members of JSR-166 + * expert group, for helpful ideas, discussions, and critiques + * on the design of this class. + */ + static final class Node { + /** waitStatus value to indicate thread has cancelled */ + static final int CANCELLED = 1; + /** waitStatus value to indicate successor's thread needs unparking */ + static final int SIGNAL = -1; + /** waitStatus value to indicate thread is waiting on condition */ + static final int CONDITION = -2; + /** Marker to indicate a node is waiting in shared mode */ + static final Node SHARED = new Node(); + /** Marker to indicate a node is waiting in exclusive mode */ + static final Node EXCLUSIVE = null; + + /** + * Status field, taking on only the values: + * SIGNAL: The successor of this node is (or will soon be) + * blocked (via park), so the current node must + * unpark its successor when it releases or + * cancels. To avoid races, acquire methods must + * first indicate they need a signal, + * then retry the atomic acquire, and then, + * on failure, block. + * CANCELLED: This node is cancelled due to timeout or interrupt. + * Nodes never leave this state. In particular, + * a thread with cancelled node never again blocks. + * CONDITION: This node is currently on a condition queue. + * It will not be used as a sync queue node until + * transferred. (Use of this value here + * has nothing to do with the other uses + * of the field, but simplifies mechanics.) + * 0: None of the above + * + * The values are arranged numerically to simplify use. + * Non-negative values mean that a node doesn't need to + * signal. So, most code doesn't need to check for particular + * values, just for sign. + * + * The field is initialized to 0 for normal sync nodes, and + * CONDITION for condition nodes. It is modified only using + * CAS. + */ + volatile int waitStatus; + + /** + * Link to predecessor node that current node/thread relies on + * for checking waitStatus. Assigned during enqueing, and nulled + * out (for sake of GC) only upon dequeuing. Also, upon + * cancellation of a predecessor, we short-circuit while + * finding a non-cancelled one, which will always exist + * because the head node is never cancelled: A node becomes + * head only as a result of successful acquire. A + * cancelled thread never succeeds in acquiring, and a thread only + * cancels itself, not any other node. + */ + volatile Node prev; + + /** + * Link to the successor node that the current node/thread + * unparks upon release. Assigned once during enqueuing, and + * nulled out (for sake of GC) when no longer needed. Upon + * cancellation, we cannot adjust this field, but can notice + * status and bypass the node if cancelled. The enq operation + * does not assign next field of a predecessor until after + * attachment, so seeing a null next field does not + * necessarily mean that node is at end of queue. However, if + * a next field appears to be null, we can scan prev's from + * the tail to double-check. + */ + volatile Node next; + + /** + * The thread that enqueued this node. Initialized on + * construction and nulled out after use. + */ + volatile Thread thread; + + /** + * Link to next node waiting on condition, or the special + * value SHARED. Because condition queues are accessed only + * when holding in exclusive mode, we just need a simple + * linked queue to hold nodes while they are waiting on + * conditions. They are then transferred to the queue to + * re-acquire. And because conditions can only be exclusive, + * we save a field by using special value to indicate shared + * mode. + */ + Node nextWaiter; + + /** + * Returns true if node is waiting in shared mode + */ + final boolean isShared() { + return nextWaiter == SHARED; + } + + /** + * Returns previous node, or throws NullPointerException if + * null. Use when predecessor cannot be null. + * @return the predecessor of this node + */ + final Node predecessor() throws NullPointerException { + Node p = prev; + if (p == null) + throw new NullPointerException(); + else + return p; + } + + Node() { // Used to establish initial head or SHARED marker + } + + Node(Thread thread, Node mode) { // Used by addWaiter + this.nextWaiter = mode; + this.thread = thread; + } + + Node(Thread thread, int waitStatus) { // Used by Condition + this.waitStatus = waitStatus; + this.thread = thread; + } + } + + /** + * Head of the wait queue, lazily initialized. Except for + * initialization, it is modified only via method setHead. Note: + * If head exists, its waitStatus is guaranteed not to be + * CANCELLED. + */ + private transient volatile Node head; + + /** + * Tail of the wait queue, lazily initialized. Modified only via + * method enq to add new wait node. + */ + private transient volatile Node tail; + + /** + * The synchronization state. + */ + private volatile long state; + + /** + * Returns the current value of synchronization state. + * This operation has memory semantics of a <tt>volatile</tt> read. + * @return current state value + */ + protected final long getState() { + return state; + } + + /** + * Sets the value of synchronization state. + * This operation has memory semantics of a <tt>volatile</tt> write. + * @param newState the new state value + */ + protected final void setState(long newState) { + state = newState; + } + + /** + * Atomically sets synchronization state to the given updated + * value if the current state value equals the expected value. + * This operation has memory semantics of a <tt>volatile</tt> read + * and write. + * + * @param expect the expected value + * @param update the new value + * @return true if successful. False return indicates that the actual + * value was not equal to the expected value. + */ + protected final boolean compareAndSetState(long expect, long update) { + // See below for intrinsics setup to support this + return unsafe.compareAndSwapLong(this, stateOffset, expect, update); + } + + // Queuing utilities + + /** + * The number of nanoseconds for which it is faster to spin + * rather than to use timed park. A rough estimate suffices + * to improve responsiveness with very short timeouts. + */ + static final long spinForTimeoutThreshold = 1000L; + + /** + * Inserts node into queue, initializing if necessary. See picture above. + * @param node the node to insert + * @return node's predecessor + */ + private Node enq(final Node node) { + for (;;) { + Node t = tail; + if (t == null) { // Must initialize + Node h = new Node(); // Dummy header + h.next = node; + node.prev = h; + if (compareAndSetHead(h)) { + tail = node; + return h; + } + } + else { + node.prev = t; + if (compareAndSetTail(t, node)) { + t.next = node; + return t; + } + } + } + } + + /** + * Creates and enqueues node for given thread and mode. + * + * @param current the thread + * @param mode Node.EXCLUSIVE for exclusive, Node.SHARED for shared + * @return the new node + */ + private Node addWaiter(Node mode) { + Node node = new Node(Thread.currentThread(), mode); + // Try the fast path of enq; backup to full enq on failure + Node pred = tail; + if (pred != null) { + node.prev = pred; + if (compareAndSetTail(pred, node)) { + pred.next = node; + return node; + } + } + enq(node); + return node; + } + + /** + * Sets head of queue to be node, thus dequeuing. Called only by + * acquire methods. Also nulls out unused fields for sake of GC + * and to suppress unnecessary signals and traversals. + * + * @param node the node + */ + private void setHead(Node node) { + head = node; + node.thread = null; + node.prev = null; + } + + /** + * Wakes up node's successor, if one exists. + * + * @param node the node + */ + private void unparkSuccessor(Node node) { + /* + * Try to clear status in anticipation of signalling. It is + * OK if this fails or if status is changed by waiting thread. + */ + compareAndSetWaitStatus(node, Node.SIGNAL, 0); + + /* + * Thread to unpark is held in successor, which is normally + * just the next node. But if cancelled or apparently null, + * traverse backwards from tail to find the actual + * non-cancelled successor. + */ + Node s = node.next; + if (s == null || s.waitStatus > 0) { + s = null; + for (Node t = tail; t != null && t != node; t = t.prev) + if (t.waitStatus <= 0) + s = t; + } + if (s != null) + LockSupport.unpark(s.thread); + } + + /** + * Sets head of queue, and checks if successor may be waiting + * in shared mode, if so propagating if propagate > 0. + * + * @param pred the node holding waitStatus for node + * @param node the node + * @param propagate the return value from a tryAcquireShared + */ + private void setHeadAndPropagate(Node node, long propagate) { + setHead(node); + if (propagate > 0 && node.waitStatus != 0) { + /* + * Don't bother fully figuring out successor. If it + * looks null, call unparkSuccessor anyway to be safe. + */ + Node s = node.next; + if (s == null || s.isShared()) + unparkSuccessor(node); + } + } + + // Utilities for various versions of acquire + + /** + * Cancels an ongoing attempt to acquire. + * + * @param node the node + */ + private void cancelAcquire(Node node) { + if (node != null) { // Ignore if node doesn't exist + node.thread = null; + // Can use unconditional write instead of CAS here + node.waitStatus = Node.CANCELLED; + unparkSuccessor(node); + } + } + + /** + * Checks and updates status for a node that failed to acquire. + * Returns true if thread should block. This is the main signal + * control in all acquire loops. Requires that pred == node.prev + * + * @param pred node's predecessor holding status + * @param node the node + * @return {@code true} if thread should block + */ + private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) { + int s = pred.waitStatus; + if (s < 0) + /* + * This node has already set status asking a release + * to signal it, so it can safely park + */ + return true; + if (s > 0) + /* + * Predecessor was cancelled. Move up to its predecessor + * and indicate retry. + */ + node.prev = pred.prev; + else + /* + * Indicate that we need a signal, but don't park yet. Caller + * will need to retry to make sure it cannot acquire before + * parking. + */ + compareAndSetWaitStatus(pred, 0, Node.SIGNAL); + return false; + } + + /** + * Convenience method to interrupt current thread. + */ + private static void selfInterrupt() { + Thread.currentThread().interrupt(); + } + + /** + * Convenience method to park and then check if interrupted + * + * @return {@code true} if interrupted + */ + private final boolean parkAndCheckInterrupt() { + LockSupport.park(this); + return Thread.interrupted(); + } + + /* + * Various flavors of acquire, varying in exclusive/shared and + * control modes. Each is mostly the same, but annoyingly + * different. Only a little bit of factoring is possible due to + * interactions of exception mechanics (including ensuring that we + * cancel if tryAcquire throws exception) and other control, at + * least not without hurting performance too much. + */ + + /** + * Acquires in exclusive uninterruptible mode for thread already in + * queue. Used by condition wait methods as well as acquire. + * + * @param node the node + * @param arg the acquire argument + * @return {@code true} if interrupted while waiting + */ + final boolean acquireQueued(final Node node, long arg) { + try { + boolean interrupted = false; + for (;;) { + final Node p = node.predecessor(); + if (p == head && tryAcquire(arg)) { + setHead(node); + p.next = null; // help GC + return interrupted; + } + if (shouldParkAfterFailedAcquire(p, node) && + parkAndCheckInterrupt()) + interrupted = true; + } + } catch (RuntimeException ex) { + cancelAcquire(node); + throw ex; + } + } + + /** + * Acquires in exclusive interruptible mode. + * @param arg the acquire argument + */ + private void doAcquireInterruptibly(long arg) + throws InterruptedException { + final Node node = addWaiter(Node.EXCLUSIVE); + try { + for (;;) { + final Node p = node.predecessor(); + if (p == head && tryAcquire(arg)) { + setHead(node); + p.next = null; // help GC + return; + } + if (shouldParkAfterFailedAcquire(p, node) && + parkAndCheckInterrupt()) + break; + } + } catch (RuntimeException ex) { + cancelAcquire(node); + throw ex; + } + // Arrive here only if interrupted + cancelAcquire(node); + throw new InterruptedException(); + } + + /** + * Acquires in exclusive timed mode. + * + * @param arg the acquire argument + * @param nanosTimeout max wait time + * @return {@code true} if acquired + */ + private boolean doAcquireNanos(long arg, long nanosTimeout) + throws InterruptedException { + long lastTime = System.nanoTime(); + final Node node = addWaiter(Node.EXCLUSIVE); + try { + for (;;) { + final Node p = node.predecessor(); + if (p == head && tryAcquire(arg)) { + setHead(node); + p.next = null; // help GC + return true; + } + if (nanosTimeout <= 0) { + cancelAcquire(node); + return false; + } + if (nanosTimeout > spinForTimeoutThreshold && + shouldParkAfterFailedAcquire(p, node)) + LockSupport.parkNanos(this, nanosTimeout); + long now = System.nanoTime(); + nanosTimeout -= now - lastTime; + lastTime = now; + if (Thread.interrupted()) + break; + } + } catch (RuntimeException ex) { + cancelAcquire(node); + throw ex; + } + // Arrive here only if interrupted + cancelAcquire(node); + throw new InterruptedException(); + } + + /** + * Acquires in shared uninterruptible mode. + * @param arg the acquire argument + */ + private void doAcquireShared(long arg) { + final Node node = addWaiter(Node.SHARED); + try { + boolean interrupted = false; + for (;;) { + final Node p = node.predecessor(); + if (p == head) { + long r = tryAcquireShared(arg); + if (r >= 0) { + setHeadAndPropagate(node, r); + p.next = null; // help GC + if (interrupted) + selfInterrupt(); + return; + } + } + if (shouldParkAfterFailedAcquire(p, node) && + parkAndCheckInterrupt()) + interrupted = true; + } + } catch (RuntimeException ex) { + cancelAcquire(node); + throw ex; + } + } + + /** + * Acquires in shared interruptible mode. + * @param arg the acquire argument + */ + private void doAcquireSharedInterruptibly(long arg) + throws InterruptedException { + final Node node = addWaiter(Node.SHARED); + try { + for (;;) { + final Node p = node.predecessor(); + if (p == head) { + long r = tryAcquireShared(arg); + if (r >= 0) { + setHeadAndPropagate(node, r); + p.next = null; // help GC + return; + } + } + if (shouldParkAfterFailedAcquire(p, node) && + parkAndCheckInterrupt()) + break; + } + } catch (RuntimeException ex) { + cancelAcquire(node); + throw ex; + } + // Arrive here only if interrupted + cancelAcquire(node); + throw new InterruptedException(); + } + + /** + * Acquires in shared timed mode. + * + * @param arg the acquire argument + * @param nanosTimeout max wait time + * @return {@code true} if acquired + */ + private boolean doAcquireSharedNanos(long arg, long nanosTimeout) + throws InterruptedException { + + long lastTime = System.nanoTime(); + final Node node = addWaiter(Node.SHARED); + try { + for (;;) { + final Node p = node.predecessor(); + if (p == head) { + long r = tryAcquireShared(arg); + if (r >= 0) { + setHeadAndPropagate(node, r); + p.next = null; // help GC + return true; + } + } + if (nanosTimeout <= 0) { + cancelAcquire(node); + return false; + } + if (nanosTimeout > spinForTimeoutThreshold && + shouldParkAfterFailedAcquire(p, node)) + LockSupport.parkNanos(this, nanosTimeout); + long now = System.nanoTime(); + nanosTimeout -= now - lastTime; + lastTime = now; + if (Thread.interrupted()) + break; + } + } catch (RuntimeException ex) { + cancelAcquire(node); + throw ex; + } + // Arrive here only if interrupted + cancelAcquire(node); + throw new InterruptedException(); + } + + // Main exported methods + + /** + * Attempts to acquire in exclusive mode. This method should query + * if the state of the object permits it to be acquired in the + * exclusive mode, and if so to acquire it. + * + * <p>This method is always invoked by the thread performing + * acquire. If this method reports failure, the acquire method + * may queue the thread, if it is not already queued, until it is + * signalled by a release from some other thread. This can be used + * to implement method {@link Lock#tryLock()}. + * + * <p>The default + * implementation throws {@link UnsupportedOperationException}. + * + * @param arg the acquire argument. This value is always the one + * passed to an acquire method, or is the value saved on entry + * to a condition wait. The value is otherwise uninterpreted + * and can represent anything you like. + * @return {@code true} if successful. Upon success, this object has + * been acquired. + * @throws IllegalMonitorStateException if acquiring would place this + * synchronizer in an illegal state. This exception must be + * thrown in a consistent fashion for synchronization to work + * correctly. + * @throws UnsupportedOperationException if exclusive mode is not supported + */ + protected boolean tryAcquire(long arg) { + throw new UnsupportedOperationException(); + } + + /** + * Attempts to set the state to reflect a release in exclusive + * mode. + * + * <p>This method is always invoked by the thread performing release. + * + * <p>The default implementation throws + * {@link UnsupportedOperationException}. + * + * @param arg the release argument. This value is always the one + * passed to a release method, or the current state value upon + * entry to a condition wait. The value is otherwise + * uninterpreted and can represent anything you like. + * @return {@code true} if this object is now in a fully released + * state, so that any waiting threads may attempt to acquire; + * and {@code false} otherwise. + * @throws IllegalMonitorStateException if releasing would place this + * synchronizer in an illegal state. This exception must be + * thrown in a consistent fashion for synchronization to work + * correctly. + * @throws UnsupportedOperationException if exclusive mode is not supported + */ + protected boolean tryRelease(long arg) { + throw new UnsupportedOperationException(); + } + + /** + * Attempts to acquire in shared mode. This method should query if + * the state of the object permits it to be acquired in the shared + * mode, and if so to acquire it. + * + * <p>This method is always invoked by the thread performing + * acquire. If this method reports failure, the acquire method + * may queue the thread, if it is not already queued, until it is + * signalled by a release from some other thread. + * + * <p>The default implementation throws {@link + * UnsupportedOperationException}. + * + * @param arg the acquire argument. This value is always the one + * passed to an acquire method, or is the value saved on entry + * to a condition wait. The value is otherwise uninterpreted + * and can represent anything you like. + * @return a negative value on failure; zero if acquisition in shared + * mode succeeded but no subsequent shared-mode acquire can + * succeed; and a positive value if acquisition in shared + * mode succeeded and subsequent shared-mode acquires might + * also succeed, in which case a subsequent waiting thread + * must check availability. (Support for three different + * return values enables this method to be used in contexts + * where acquires only sometimes act exclusively.) Upon + * success, this object has been acquired. + * @throws IllegalMonitorStateException if acquiring would place this + * synchronizer in an illegal state. This exception must be + * thrown in a consistent fashion for synchronization to work + * correctly. + * @throws UnsupportedOperationException if shared mode is not supported + */ + protected long tryAcquireShared(long arg) { + throw new UnsupportedOperationException(); + } + + /** + * Attempts to set the state to reflect a release in shared mode. + * + * <p>This method is always invoked by the thread performing release. + * + * <p>The default implementation throws + * {@link UnsupportedOperationException}. + * + * @param arg the release argument. This value is always the one + * passed to a release method, or the current state value upon + * entry to a condition wait. The value is otherwise + * uninterpreted and can represent anything you like. + * @return {@code true} if this release of shared mode may permit a + * waiting acquire (shared or exclusive) to succeed; and + * {@code false} otherwise + * @throws IllegalMonitorStateException if releasing would place this + * synchronizer in an illegal state. This exception must be + * thrown in a consistent fashion for synchronization to work + * correctly. + * @throws UnsupportedOperationException if shared mode is not supported + */ + protected boolean tryReleaseShared(long arg) { + throw new UnsupportedOperationException(); + } + + /** + * Returns {@code true} if synchronization is held exclusively with + * respect to the current (calling) thread. This method is invoked + * upon each call to a non-waiting {@link ConditionObject} method. + * (Waiting methods instead invoke {@link #release}.) + * + * <p>The default implementation throws {@link + * UnsupportedOperationException}. This method is invoked + * internally only within {@link ConditionObject} methods, so need + * not be defined if conditions are not used. + * + * @return {@code true} if synchronization is held exclusively; + * {@code false} otherwise + * @throws UnsupportedOperationException if conditions are not supported + */ + protected boolean isHeldExclusively() { + throw new UnsupportedOperationException(); + } + + /** + * Acquires in exclusive mode, ignoring interrupts. Implemented + * by invoking at least once {@link #tryAcquire}, + * returning on success. Otherwise the thread is queued, possibly + * repeatedly blocking and unblocking, invoking {@link + * #tryAcquire} until success. This method can be used + * to implement method {@link Lock#lock}. + * + * @param arg the acquire argument. This value is conveyed to + * {@link #tryAcquire} but is otherwise uninterpreted and + * can represent anything you like. + */ + public final void acquire(long arg) { + if (!tryAcquire(arg) && + acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) + selfInterrupt(); + } + + /** + * Acquires in exclusive mode, aborting if interrupted. + * Implemented by first checking interrupt status, then invoking + * at least once {@link #tryAcquire}, returning on + * success. Otherwise the thread is queued, possibly repeatedly + * blocking and unblocking, invoking {@link #tryAcquire} + * until success or the thread is interrupted. This method can be + * used to implement method {@link Lock#lockInterruptibly}. + * + * @param arg the acquire argument. This value is conveyed to + * {@link #tryAcquire} but is otherwise uninterpreted and + * can represent anything you like. + * @throws InterruptedException if the current thread is interrupted + */ + public final void acquireInterruptibly(long arg) throws InterruptedException { + if (Thread.interrupted()) + throw new InterruptedException(); + if (!tryAcquire(arg)) + doAcquireInterruptibly(arg); + } + + /** + * Attempts to acquire in exclusive mode, aborting if interrupted, + * and failing if the given timeout elapses. Implemented by first + * checking interrupt status, then invoking at least once {@link + * #tryAcquire}, returning on success. Otherwise, the thread is + * queued, possibly repeatedly blocking and unblocking, invoking + * {@link #tryAcquire} until success or the thread is interrupted + * or the timeout elapses. This method can be used to implement + * method {@link Lock#tryLock(long, TimeUnit)}. + * + * @param arg the acquire argument. This value is conveyed to + * {@link #tryAcquire} but is otherwise uninterpreted and + * can represent anything you like. + * @param nanosTimeout the maximum number of nanoseconds to wait + * @return {@code true} if acquired; {@code false} if timed out + * @throws InterruptedException if the current thread is interrupted + */ + public final boolean tryAcquireNanos(long arg, long nanosTimeout) throws InterruptedException { + if (Thread.interrupted()) + throw new InterruptedException(); + return tryAcquire(arg) || + doAcquireNanos(arg, nanosTimeout); + } + + /** + * Releases in exclusive mode. Implemented by unblocking one or + * more threads if {@link #tryRelease} returns true. + * This method can be used to implement method {@link Lock#unlock}. + * + * @param arg the release argument. This value is conveyed to + * {@link #tryRelease} but is otherwise uninterpreted and + * can represent anything you like. + * @return the value returned from {@link #tryRelease} + */ + public final boolean release(long arg) { + if (tryRelease(arg)) { + Node h = head; + if (h != null && h.waitStatus != 0) + unparkSuccessor(h); + return true; + } + return false; + } + + /** + * Acquires in shared mode, ignoring interrupts. Implemented by + * first invoking at least once {@link #tryAcquireShared}, + * returning on success. Otherwise the thread is queued, possibly + * repeatedly blocking and unblocking, invoking {@link + * #tryAcquireShared} until success. + * + * @param arg the acquire argument. This value is conveyed to + * {@link #tryAcquireShared} but is otherwise uninterpreted + * and can represent anything you like. + */ + public final void acquireShared(long arg) { + if (tryAcquireShared(arg) < 0) + doAcquireShared(arg); + } + + /** + * Acquires in shared mode, aborting if interrupted. Implemented + * by first checking interrupt status, then invoking at least once + * {@link #tryAcquireShared}, returning on success. Otherwise the + * thread is queued, possibly repeatedly blocking and unblocking, + * invoking {@link #tryAcquireShared} until success or the thread + * is interrupted. + * @param arg the acquire argument. + * This value is conveyed to {@link #tryAcquireShared} but is + * otherwise uninterpreted and can represent anything + * you like. + * @throws InterruptedException if the current thread is interrupted + */ + public final void acquireSharedInterruptibly(long arg) throws InterruptedException { + if (Thread.interrupted()) + throw new InterruptedException(); + if (tryAcquireShared(arg) < 0) + doAcquireSharedInterruptibly(arg); + } + + /** + * Attempts to acquire in shared mode, aborting if interrupted, and + * failing if the given timeout elapses. Implemented by first + * checking interrupt status, then invoking at least once {@link + * #tryAcquireShared}, returning on success. Otherwise, the + * thread is queued, possibly repeatedly blocking and unblocking, + * invoking {@link #tryAcquireShared} until success or the thread + * is interrupted or the timeout elapses. + * + * @param arg the acquire argument. This value is conveyed to + * {@link #tryAcquireShared} but is otherwise uninterpreted + * and can represent anything you like. + * @param nanosTimeout the maximum number of nanoseconds to wait + * @return {@code true} if acquired; {@code false} if timed out + * @throws InterruptedException if the current thread is interrupted + */ + public final boolean tryAcquireSharedNanos(long arg, long nanosTimeout) throws InterruptedException { + if (Thread.interrupted()) + throw new InterruptedException(); + return tryAcquireShared(arg) >= 0 || + doAcquireSharedNanos(arg, nanosTimeout); + } + + /** + * Releases in shared mode. Implemented by unblocking one or more + * threads if {@link #tryReleaseShared} returns true. + * + * @param arg the release argument. This value is conveyed to + * {@link #tryReleaseShared} but is otherwise uninterpreted + * and can represent anything you like. + * @return the value returned from {@link #tryReleaseShared} + */ + public final boolean releaseShared(long arg) { + if (tryReleaseShared(arg)) { + Node h = head; + if (h != null && h.waitStatus != 0) + unparkSuccessor(h); + return true; + } + return false; + } + + // Queue inspection methods + + /** + * Queries whether any threads are waiting to acquire. Note that + * because cancellations due to interrupts and timeouts may occur + * at any time, a {@code true} return does not guarantee that any + * other thread will ever acquire. + * + * <p>In this implementation, this operation returns in + * constant time. + * + * @return {@code true} if there may be other threads waiting to acquire + */ + public final boolean hasQueuedThreads() { + return head != tail; + } + + /** + * Queries whether any threads have ever contended to acquire this + * synchronizer; that is if an acquire method has ever blocked. + * + * <p>In this implementation, this operation returns in + * constant time. + * + * @return {@code true} if there has ever been contention + */ + public final boolean hasContended() { + return head != null; + } + + /** + * Returns the first (longest-waiting) thread in the queue, or + * {@code null} if no threads are currently queued. + * + * <p>In this implementation, this operation normally returns in + * constant time, but may iterate upon contention if other threads are + * concurrently modifying the queue. + * + * @return the first (longest-waiting) thread in the queue, or + * {@code null} if no threads are currently queued + */ + public final Thread getFirstQueuedThread() { + // handle only fast path, else relay + return (head == tail)? null : fullGetFirstQueuedThread(); + } + + /** + * Version of getFirstQueuedThread called when fastpath fails + */ + private Thread fullGetFirstQueuedThread() { + /* + * The first node is normally h.next. Try to get its + * thread field, ensuring consistent reads: If thread + * field is nulled out or s.prev is no longer head, then + * some other thread(s) concurrently performed setHead in + * between some of our reads. We try this twice before + * resorting to traversal. + */ + Node h, s; + Thread st; + if (((h = head) != null && (s = h.next) != null && + s.prev == head && (st = s.thread) != null) || + ((h = head) != null && (s = h.next) != null && + s.prev == head && (st = s.thread) != null)) + return st; + + /* + * Head's next field might not have been set yet, or may have + * been unset after setHead. So we must check to see if tail + * is actually first node. If not, we continue on, safely + * traversing from tail back to head to find first, + * guaranteeing termination. + */ + + Node t = tail; + Thread firstThread = null; + while (t != null && t != head) { + Thread tt = t.thread; + if (tt != null) + firstThread = tt; + t = t.prev; + } + return firstThread; + } + + /** + * Returns true if the given thread is currently queued. + * + * <p>This implementation traverses the queue to determine + * presence of the given thread. + * + * @param thread the thread + * @return {@code true} if the given thread is on the queue + * @throws NullPointerException if the thread is null + */ + public final boolean isQueued(Thread thread) { + if (thread == null) + throw new NullPointerException(); + for (Node p = tail; p != null; p = p.prev) + if (p.thread == thread) + return true; + return false; + } + + /** + * Return {@code true} if the apparent first queued thread, if one + * exists, is not waiting in exclusive mode. Used only as a heuristic + * in ReentrantReadWriteLock. + */ + final boolean apparentlyFirstQueuedIsExclusive() { + Node h, s; + return ((h = head) != null && (s = h.next) != null && + s.nextWaiter != Node.SHARED); + } + + /** + * Return {@code true} if the queue is empty or if the given thread + * is at the head of the queue. This is reliable only if + * <tt>current</tt> is actually Thread.currentThread() of caller. + */ + final boolean isFirst(Thread current) { + Node h, s; + return ((h = head) == null || + ((s = h.next) != null && s.thread == current) || + fullIsFirst(current)); + } + + final boolean fullIsFirst(Thread current) { + // same idea as fullGetFirstQueuedThread + Node h, s; + Thread firstThread = null; + if (((h = head) != null && (s = h.next) != null && + s.prev == head && (firstThread = s.thread) != null)) + return firstThread == current; + Node t = tail; + while (t != null && t != head) { + Thread tt = t.thread; + if (tt != null) + firstThread = tt; + t = t.prev; + } + return firstThread == current || firstThread == null; + } + + + // Instrumentation and monitoring methods + + /** + * Returns an estimate of the number of threads waiting to + * acquire. The value is only an estimate because the number of + * threads may change dynamically while this method traverses + * internal data structures. This method is designed for use in + * monitoring system state, not for synchronization + * control. + * + * @return the estimated number of threads waiting to acquire + */ + public final int getQueueLength() { + int n = 0; + for (Node p = tail; p != null; p = p.prev) { + if (p.thread != null) + ++n; + } + return n; + } + + /** + * Returns a collection containing threads that may be waiting to + * acquire. Because the actual set of threads may change + * dynamically while constructing this result, the returned + * collection is only a best-effort estimate. The elements of the + * returned collection are in no particular order. This method is + * designed to facilitate construction of subclasses that provide + * more extensive monitoring facilities. + * + * @return the collection of threads + */ + public final Collection<Thread> getQueuedThreads() { + ArrayList<Thread> list = new ArrayList<Thread>(); + for (Node p = tail; p != null; p = p.prev) { + Thread t = p.thread; + if (t != null) + list.add(t); + } + return list; + } + + /** + * Returns a collection containing threads that may be waiting to + * acquire in exclusive mode. This has the same properties + * as {@link #getQueuedThreads} except that it only returns + * those threads waiting due to an exclusive acquire. + * + * @return the collection of threads + */ + public final Collection<Thread> getExclusiveQueuedThreads() { + ArrayList<Thread> list = new ArrayList<Thread>(); + for (Node p = tail; p != null; p = p.prev) { + if (!p.isShared()) { + Thread t = p.thread; + if (t != null) + list.add(t); + } + } + return list; + } + + /** + * Returns a collection containing threads that may be waiting to + * acquire in shared mode. This has the same properties + * as {@link #getQueuedThreads} except that it only returns + * those threads waiting due to a shared acquire. + * + * @return the collection of threads + */ + public final Collection<Thread> getSharedQueuedThreads() { + ArrayList<Thread> list = new ArrayList<Thread>(); + for (Node p = tail; p != null; p = p.prev) { + if (p.isShared()) { + Thread t = p.thread; + if (t != null) + list.add(t); + } + } + return list; + } + + /** + * Returns a string identifying this synchronizer, as well as its state. + * The state, in brackets, includes the String {@code "State ="} + * followed by the current value of {@link #getState}, and either + * {@code "nonempty"} or {@code "empty"} depending on whether the + * queue is empty. + * + * @return a string identifying this synchronizer, as well as its state + */ + public String toString() { + long s = getState(); + String q = hasQueuedThreads()? "non" : ""; + return super.toString() + + "[State = " + s + ", " + q + "empty queue]"; + } + + + // Internal support methods for Conditions + + /** + * Returns true if a node, always one that was initially placed on + * a condition queue, is now waiting to reacquire on sync queue. + * @param node the node + * @return true if is reacquiring + */ + final boolean isOnSyncQueue(Node node) { + if (node.waitStatus == Node.CONDITION || node.prev == null) + return false; + if (node.next != null) // If has successor, it must be on queue + return true; + /* + * node.prev can be non-null, but not yet on queue because + * the CAS to place it on queue can fail. So we have to + * traverse from tail to make sure it actually made it. It + * will always be near the tail in calls to this method, and + * unless the CAS failed (which is unlikely), it will be + * there, so we hardly ever traverse much. + */ + return findNodeFromTail(node); + } + + /** + * Returns true if node is on sync queue by searching backwards from tail. + * Called only when needed by isOnSyncQueue. + * @return true if present + */ + private boolean findNodeFromTail(Node node) { + Node t = tail; + for (;;) { + if (t == node) + return true; + if (t == null) + return false; + t = t.prev; + } + } + + /** + * Transfers a node from a condition queue onto sync queue. + * Returns true if successful. + * @param node the node + * @return true if successfully transferred (else the node was + * cancelled before signal). + */ + final boolean transferForSignal(Node node) { + /* + * If cannot change waitStatus, the node has been cancelled. + */ + if (!compareAndSetWaitStatus(node, Node.CONDITION, 0)) + return false; + + /* + * Splice onto queue and try to set waitStatus of predecessor to + * indicate that thread is (probably) waiting. If cancelled or + * attempt to set waitStatus fails, wake up to resync (in which + * case the waitStatus can be transiently and harmlessly wrong). + */ + Node p = enq(node); + int c = p.waitStatus; + if (c > 0 || !compareAndSetWaitStatus(p, c, Node.SIGNAL)) + LockSupport.unpark(node.thread); + return true; + } + + /** + * Transfers node, if necessary, to sync queue after a cancelled + * wait. Returns true if thread was cancelled before being + * signalled. + * @param current the waiting thread + * @param node its node + * @return true if cancelled before the node was signalled. + */ + final boolean transferAfterCancelledWait(Node node) { + if (compareAndSetWaitStatus(node, Node.CONDITION, 0)) { + enq(node); + return true; + } + /* + * If we lost out to a signal(), then we can't proceed + * until it finishes its enq(). Cancelling during an + * incomplete transfer is both rare and transient, so just + * spin. + */ + while (!isOnSyncQueue(node)) + Thread.yield(); + return false; + } + + /** + * Invokes release with current state value; returns saved state. + * Cancels node and throws exception on failure. + * @param node the condition node for this wait + * @return previous sync state + */ + final long fullyRelease(Node node) { + try { + long savedState = getState(); + if (release(savedState)) + return savedState; + } catch (RuntimeException ex) { + node.waitStatus = Node.CANCELLED; + throw ex; + } + // reach here if release fails + node.waitStatus = Node.CANCELLED; + throw new IllegalMonitorStateException(); + } + + // Instrumentation methods for conditions + + /** + * Queries whether the given ConditionObject + * uses this synchronizer as its lock. + * + * @param condition the condition + * @return <tt>true</tt> if owned + * @throws NullPointerException if the condition is null + */ + public final boolean owns(ConditionObject condition) { + if (condition == null) + throw new NullPointerException(); + return condition.isOwnedBy(this); + } + + /** + * Queries whether any threads are waiting on the given condition + * associated with this synchronizer. Note that because timeouts + * and interrupts may occur at any time, a <tt>true</tt> return + * does not guarantee that a future <tt>signal</tt> will awaken + * any threads. This method is designed primarily for use in + * monitoring of the system state. + * + * @param condition the condition + * @return <tt>true</tt> if there are any waiting threads + * @throws IllegalMonitorStateException if exclusive synchronization + * is not held + * @throws IllegalArgumentException if the given condition is + * not associated with this synchronizer + * @throws NullPointerException if the condition is null + */ + public final boolean hasWaiters(ConditionObject condition) { + if (!owns(condition)) + throw new IllegalArgumentException("Not owner"); + return condition.hasWaiters(); + } + + /** + * Returns an estimate of the number of threads waiting on the + * given condition associated with this synchronizer. Note that + * because timeouts and interrupts may occur at any time, the + * estimate serves only as an upper bound on the actual number of + * waiters. This method is designed for use in monitoring of the + * system state, not for synchronization control. + * + * @param condition the condition + * @return the estimated number of waiting threads + * @throws IllegalMonitorStateException if exclusive synchronization + * is not held + * @throws IllegalArgumentException if the given condition is + * not associated with this synchronizer + * @throws NullPointerException if the condition is null + */ + public final int getWaitQueueLength(ConditionObject condition) { + if (!owns(condition)) + throw new IllegalArgumentException("Not owner"); + return condition.getWaitQueueLength(); + } + + /** + * Returns a collection containing those threads that may be + * waiting on the given condition associated with this + * synchronizer. Because the actual set of threads may change + * dynamically while constructing this result, the returned + * collection is only a best-effort estimate. The elements of the + * returned collection are in no particular order. + * + * @param condition the condition + * @return the collection of threads + * @throws IllegalMonitorStateException if exclusive synchronization + * is not held + * @throws IllegalArgumentException if the given condition is + * not associated with this synchronizer + * @throws NullPointerException if the condition is null + */ + public final Collection<Thread> getWaitingThreads(ConditionObject condition) { + if (!owns(condition)) + throw new IllegalArgumentException("Not owner"); + return condition.getWaitingThreads(); + } + + /** + * Condition implementation for a {@link + * AbstractQueuedLongSynchronizer} serving as the basis of a {@link + * Lock} implementation. + * + * <p>Method documentation for this class describes mechanics, + * not behavioral specifications from the point of view of Lock + * and Condition users. Exported versions of this class will in + * general need to be accompanied by documentation describing + * condition semantics that rely on those of the associated + * <tt>AbstractQueuedLongSynchronizer</tt>. + * + * <p>This class is Serializable, but all fields are transient, + * so deserialized conditions have no waiters. + * + * @since 1.6 + */ + public class ConditionObject implements Condition, java.io.Serializable { + private static final long serialVersionUID = 1173984872572414699L; + /** First node of condition queue. */ + private transient Node firstWaiter; + /** Last node of condition queue. */ + private transient Node lastWaiter; + + /** + * Creates a new <tt>ConditionObject</tt> instance. + */ + public ConditionObject() { } + + // Internal methods + + /** + * Adds a new waiter to wait queue. + * @return its new wait node + */ + private Node addConditionWaiter() { + Node node = new Node(Thread.currentThread(), Node.CONDITION); + Node t = lastWaiter; + if (t == null) + firstWaiter = node; + else + t.nextWaiter = node; + lastWaiter = node; + return node; + } + + /** + * Removes and transfers nodes until hit non-cancelled one or + * null. Split out from signal in part to encourage compilers + * to inline the case of no waiters. + * @param first (non-null) the first node on condition queue + */ + private void doSignal(Node first) { + do { + if ( (firstWaiter = first.nextWaiter) == null) + lastWaiter = null; + first.nextWaiter = null; + } while (!transferForSignal(first) && + (first = firstWaiter) != null); + } + + /** + * Removes and transfers all nodes. + * @param first (non-null) the first node on condition queue + */ + private void doSignalAll(Node first) { + lastWaiter = firstWaiter = null; + do { + Node next = first.nextWaiter; + first.nextWaiter = null; + transferForSignal(first); + first = next; + } while (first != null); + } + + /** + * Returns true if given node is on this condition queue. + * Call only when holding lock. + */ + private boolean isOnConditionQueue(Node node) { + return node.next != null || node == lastWaiter; + } + + /** + * Unlinks a cancelled waiter node from condition queue. This + * is called when cancellation occurred during condition wait, + * not lock wait, and is called only after lock has been + * re-acquired by a cancelled waiter and the node is not known + * to already have been dequeued. It is needed to avoid + * garbage retention in the absence of signals. So even though + * it may require a full traversal, it comes into play only + * when timeouts or cancellations occur in the absence of + * signals. + */ + private void unlinkCancelledWaiter(Node node) { + Node t = firstWaiter; + Node trail = null; + while (t != null) { + if (t == node) { + Node next = t.nextWaiter; + if (trail == null) + firstWaiter = next; + else + trail.nextWaiter = next; + if (lastWaiter == node) + lastWaiter = trail; + break; + } + trail = t; + t = t.nextWaiter; + } + } + + // public methods + + /** + * Moves the longest-waiting thread, if one exists, from the + * wait queue for this condition to the wait queue for the + * owning lock. + * + * @throws IllegalMonitorStateException if {@link #isHeldExclusively} + * returns {@code false} + */ + public final void signal() { + if (!isHeldExclusively()) + throw new IllegalMonitorStateException(); + Node first = firstWaiter; + if (first != null) + doSignal(first); + } + + /** + * Moves all threads from the wait queue for this condition to + * the wait queue for the owning lock. + * + * @throws IllegalMonitorStateException if {@link #isHeldExclusively} + * returns {@code false} + */ + public final void signalAll() { + if (!isHeldExclusively()) + throw new IllegalMonitorStateException(); + Node first = firstWaiter; + if (first != null) + doSignalAll(first); + } + + /** + * Implements uninterruptible condition wait. + * <ol> + * <li> Save lock state returned by {@link #getState} + * <li> Invoke {@link #release} with + * saved state as argument, throwing + * IllegalMonitorStateException if it fails. + * <li> Block until signalled + * <li> Reacquire by invoking specialized version of + * {@link #acquire} with saved state as argument. + * </ol> + */ + public final void awaitUninterruptibly() { + Node node = addConditionWaiter(); + long savedState = fullyRelease(node); + boolean interrupted = false; + while (!isOnSyncQueue(node)) { + LockSupport.park(this); + if (Thread.interrupted()) + interrupted = true; + } + if (acquireQueued(node, savedState) || interrupted) + selfInterrupt(); + } + + /* + * For interruptible waits, we need to track whether to throw + * InterruptedException, if interrupted while blocked on + * condition, versus reinterrupt current thread, if + * interrupted while blocked waiting to re-acquire. + */ + + /** Mode meaning to reinterrupt on exit from wait */ + private static final int REINTERRUPT = 1; + /** Mode meaning to throw InterruptedException on exit from wait */ + private static final int THROW_IE = -1; + + /** + * Checks for interrupt, returning THROW_IE if interrupted + * before signalled, REINTERRUPT if after signalled, or + * 0 if not interrupted. + */ + private int checkInterruptWhileWaiting(Node node) { + return (Thread.interrupted()) ? + ((transferAfterCancelledWait(node))? THROW_IE : REINTERRUPT) : + 0; + } + + /** + * Throws InterruptedException, reinterrupts current thread, or + * does nothing, depending on mode. + */ + private void reportInterruptAfterWait(int interruptMode) + throws InterruptedException { + if (interruptMode == THROW_IE) + throw new InterruptedException(); + else if (interruptMode == REINTERRUPT) + selfInterrupt(); + } + + /** + * Implements interruptible condition wait. + * <ol> + * <li> If current thread is interrupted, throw InterruptedException + * <li> Save lock state returned by {@link #getState} + * <li> Invoke {@link #release} with + * saved state as argument, throwing + * IllegalMonitorStateException if it fails. + * <li> Block until signalled or interrupted + * <li> Reacquire by invoking specialized version of + * {@link #acquire} with saved state as argument. + * <li> If interrupted while blocked in step 4, throw exception + * </ol> + */ + public final void await() throws InterruptedException { + if (Thread.interrupted()) + throw new InterruptedException(); + Node node = addConditionWaiter(); + long savedState = fullyRelease(node); + int interruptMode = 0; + while (!isOnSyncQueue(node)) { + LockSupport.park(this); + if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) + break; + } + if (acquireQueued(node, savedState) && interruptMode != THROW_IE) + interruptMode = REINTERRUPT; + if (isOnConditionQueue(node)) + unlinkCancelledWaiter(node); + if (interruptMode != 0) + reportInterruptAfterWait(interruptMode); + } + + /** + * Implements timed condition wait. + * <ol> + * <li> If current thread is interrupted, throw InterruptedException + * <li> Save lock state returned by {@link #getState} + * <li> Invoke {@link #release} with + * saved state as argument, throwing + * IllegalMonitorStateException if it fails. + * <li> Block until signalled, interrupted, or timed out + * <li> Reacquire by invoking specialized version of + * {@link #acquire} with saved state as argument. + * <li> If interrupted while blocked in step 4, throw InterruptedException + * </ol> + */ + public final long awaitNanos(long nanosTimeout) throws InterruptedException { + if (Thread.interrupted()) + throw new InterruptedException(); + Node node = addConditionWaiter(); + long savedState = fullyRelease(node); + long lastTime = System.nanoTime(); + int interruptMode = 0; + while (!isOnSyncQueue(node)) { + if (nanosTimeout <= 0L) { + transferAfterCancelledWait(node); + break; + } + LockSupport.parkNanos(this, nanosTimeout); + if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) + break; + + long now = System.nanoTime(); + nanosTimeout -= now - lastTime; + lastTime = now; + } + if (acquireQueued(node, savedState) && interruptMode != THROW_IE) + interruptMode = REINTERRUPT; + if (isOnConditionQueue(node)) + unlinkCancelledWaiter(node); + if (interruptMode != 0) + reportInterruptAfterWait(interruptMode); + return nanosTimeout - (System.nanoTime() - lastTime); + } + + /** + * Implements absolute timed condition wait. + * <ol> + * <li> If current thread is interrupted, throw InterruptedException + * <li> Save lock state returned by {@link #getState} + * <li> Invoke {@link #release} with + * saved state as argument, throwing + * IllegalMonitorStateException if it fails. + * <li> Block until signalled, interrupted, or timed out + * <li> Reacquire by invoking specialized version of + * {@link #acquire} with saved state as argument. + * <li> If interrupted while blocked in step 4, throw InterruptedException + * <li> If timed out while blocked in step 4, return false, else true + * </ol> + */ + public final boolean awaitUntil(Date deadline) throws InterruptedException { + if (deadline == null) + throw new NullPointerException(); + long abstime = deadline.getTime(); + if (Thread.interrupted()) + throw new InterruptedException(); + Node node = addConditionWaiter(); + long savedState = fullyRelease(node); + boolean timedout = false; + int interruptMode = 0; + while (!isOnSyncQueue(node)) { + if (System.currentTimeMillis() > abstime) { + timedout = transferAfterCancelledWait(node); + break; + } + LockSupport.parkUntil(this, abstime); + if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) + break; + } + if (acquireQueued(node, savedState) && interruptMode != THROW_IE) + interruptMode = REINTERRUPT; + if (isOnConditionQueue(node)) + unlinkCancelledWaiter(node); + if (interruptMode != 0) + reportInterruptAfterWait(interruptMode); + return !timedout; + } + + /** + * Implements timed condition wait. + * <ol> + * <li> If current thread is interrupted, throw InterruptedException + * <li> Save lock state returned by {@link #getState} + * <li> Invoke {@link #release} with + * saved state as argument, throwing + * IllegalMonitorStateException if it fails. + * <li> Block until signalled, interrupted, or timed out + * <li> Reacquire by invoking specialized version of + * {@link #acquire} with saved state as argument. + * <li> If interrupted while blocked in step 4, throw InterruptedException + * <li> If timed out while blocked in step 4, return false, else true + * </ol> + */ + public final boolean await(long time, TimeUnit unit) throws InterruptedException { + if (unit == null) + throw new NullPointerException(); + long nanosTimeout = unit.toNanos(time); + if (Thread.interrupted()) + throw new InterruptedException(); + Node node = addConditionWaiter(); + long savedState = fullyRelease(node); + long lastTime = System.nanoTime(); + boolean timedout = false; + int interruptMode = 0; + while (!isOnSyncQueue(node)) { + if (nanosTimeout <= 0L) { + timedout = transferAfterCancelledWait(node); + break; + } + LockSupport.parkNanos(this, nanosTimeout); + if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) + break; + long now = System.nanoTime(); + nanosTimeout -= now - lastTime; + lastTime = now; + } + if (acquireQueued(node, savedState) && interruptMode != THROW_IE) + interruptMode = REINTERRUPT; + if (isOnConditionQueue(node)) + unlinkCancelledWaiter(node); + if (interruptMode != 0) + reportInterruptAfterWait(interruptMode); + return !timedout; + } + + // support for instrumentation + + /** + * Returns true if this condition was created by the given + * synchronization object. + * + * @return {@code true} if owned + */ + final boolean isOwnedBy(AbstractQueuedLongSynchronizer sync) { + return sync == AbstractQueuedLongSynchronizer.this; + } + + /** + * Queries whether any threads are waiting on this condition. + * Implements {@link AbstractQueuedLongSynchronizer#hasWaiters}. + * + * @return {@code true} if there are any waiting threads + * @throws IllegalMonitorStateException if {@link #isHeldExclusively} + * returns {@code false} + */ + protected final boolean hasWaiters() { + if (!isHeldExclusively()) + throw new IllegalMonitorStateException(); + for (Node w = firstWaiter; w != null; w = w.nextWaiter) { + if (w.waitStatus == Node.CONDITION) + return true; + } + return false; + } + + /** + * Returns an estimate of the number of threads waiting on + * this condition. + * Implements {@link AbstractQueuedLongSynchronizer#getWaitQueueLength}. + * + * @return the estimated number of waiting threads + * @throws IllegalMonitorStateException if {@link #isHeldExclusively} + * returns {@code false} + */ + protected final int getWaitQueueLength() { + if (!isHeldExclusively()) + throw new IllegalMonitorStateException(); + int n = 0; + for (Node w = firstWaiter; w != null; w = w.nextWaiter) { + if (w.waitStatus == Node.CONDITION) + ++n; + } + return n; + } + + /** + * Returns a collection containing those threads that may be + * waiting on this Condition. + * Implements {@link AbstractQueuedLongSynchronizer#getWaitingThreads}. + * + * @return the collection of threads + * @throws IllegalMonitorStateException if {@link #isHeldExclusively} + * returns {@code false} + */ + protected final Collection<Thread> getWaitingThreads() { + if (!isHeldExclusively()) + throw new IllegalMonitorStateException(); + ArrayList<Thread> list = new ArrayList<Thread>(); + for (Node w = firstWaiter; w != null; w = w.nextWaiter) { + if (w.waitStatus == Node.CONDITION) { + Thread t = w.thread; + if (t != null) + list.add(t); + } + } + return list; + } + } + + /** + * Setup to support compareAndSet. We need to natively implement + * this here: For the sake of permitting future enhancements, we + * cannot explicitly subclass AtomicLong, which would be + * efficient and useful otherwise. So, as the lesser of evils, we + * natively implement using hotspot intrinsics API. And while we + * are at it, we do the same for other CASable fields (which could + * otherwise be done with atomic field updaters). + */ + private static final Unsafe unsafe = Unsafe.getUnsafe(); + private static final long stateOffset; + private static final long headOffset; + private static final long tailOffset; + private static final long waitStatusOffset; + + static { + try { + stateOffset = unsafe.objectFieldOffset + (AbstractQueuedLongSynchronizer.class.getDeclaredField("state")); + headOffset = unsafe.objectFieldOffset + (AbstractQueuedLongSynchronizer.class.getDeclaredField("head")); + tailOffset = unsafe.objectFieldOffset + (AbstractQueuedLongSynchronizer.class.getDeclaredField("tail")); + waitStatusOffset = unsafe.objectFieldOffset + (Node.class.getDeclaredField("waitStatus")); + + } catch (Exception ex) { throw new Error(ex); } + } + + /** + * CAS head field. Used only by enq + */ + private final boolean compareAndSetHead(Node update) { + return unsafe.compareAndSwapObject(this, headOffset, null, update); + } + + /** + * CAS tail field. Used only by enq + */ + private final boolean compareAndSetTail(Node expect, Node update) { + return unsafe.compareAndSwapObject(this, tailOffset, expect, update); + } + + /** + * CAS waitStatus field of a node. + */ + private final static boolean compareAndSetWaitStatus(Node node, + int expect, + int update) { + return unsafe.compareAndSwapInt(node, waitStatusOffset, + expect, update); + } +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/locks/AbstractQueuedSynchronizer.java b/libjava/classpath/external/jsr166/java/util/concurrent/locks/AbstractQueuedSynchronizer.java new file mode 100644 index 000000000..647f4fcbc --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/locks/AbstractQueuedSynchronizer.java @@ -0,0 +1,2159 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent.locks; +import java.util.*; +import java.util.concurrent.*; +import java.util.concurrent.atomic.*; +import sun.misc.Unsafe; + +/** + * Provides a framework for implementing blocking locks and related + * synchronizers (semaphores, events, etc) that rely on + * first-in-first-out (FIFO) wait queues. This class is designed to + * be a useful basis for most kinds of synchronizers that rely on a + * single atomic <tt>int</tt> value to represent state. Subclasses + * must define the protected methods that change this state, and which + * define what that state means in terms of this object being acquired + * or released. Given these, the other methods in this class carry + * out all queuing and blocking mechanics. Subclasses can maintain + * other state fields, but only the atomically updated <tt>int</tt> + * value manipulated using methods {@link #getState}, {@link + * #setState} and {@link #compareAndSetState} is tracked with respect + * to synchronization. + * + * <p>Subclasses should be defined as non-public internal helper + * classes that are used to implement the synchronization properties + * of their enclosing class. Class + * <tt>AbstractQueuedSynchronizer</tt> does not implement any + * synchronization interface. Instead it defines methods such as + * {@link #acquireInterruptibly} that can be invoked as + * appropriate by concrete locks and related synchronizers to + * implement their public methods. + * + * <p>This class supports either or both a default <em>exclusive</em> + * mode and a <em>shared</em> mode. When acquired in exclusive mode, + * attempted acquires by other threads cannot succeed. Shared mode + * acquires by multiple threads may (but need not) succeed. This class + * does not "understand" these differences except in the + * mechanical sense that when a shared mode acquire succeeds, the next + * waiting thread (if one exists) must also determine whether it can + * acquire as well. Threads waiting in the different modes share the + * same FIFO queue. Usually, implementation subclasses support only + * one of these modes, but both can come into play for example in a + * {@link ReadWriteLock}. Subclasses that support only exclusive or + * only shared modes need not define the methods supporting the unused mode. + * + * <p>This class defines a nested {@link ConditionObject} class that + * can be used as a {@link Condition} implementation by subclasses + * supporting exclusive mode for which method {@link + * #isHeldExclusively} reports whether synchronization is exclusively + * held with respect to the current thread, method {@link #release} + * invoked with the current {@link #getState} value fully releases + * this object, and {@link #acquire}, given this saved state value, + * eventually restores this object to its previous acquired state. No + * <tt>AbstractQueuedSynchronizer</tt> method otherwise creates such a + * condition, so if this constraint cannot be met, do not use it. The + * behavior of {@link ConditionObject} depends of course on the + * semantics of its synchronizer implementation. + * + * <p>This class provides inspection, instrumentation, and monitoring + * methods for the internal queue, as well as similar methods for + * condition objects. These can be exported as desired into classes + * using an <tt>AbstractQueuedSynchronizer</tt> for their + * synchronization mechanics. + * + * <p>Serialization of this class stores only the underlying atomic + * integer maintaining state, so deserialized objects have empty + * thread queues. Typical subclasses requiring serializability will + * define a <tt>readObject</tt> method that restores this to a known + * initial state upon deserialization. + * + * <h3>Usage</h3> + * + * <p>To use this class as the basis of a synchronizer, redefine the + * following methods, as applicable, by inspecting and/or modifying + * the synchronization state using {@link #getState}, {@link + * #setState} and/or {@link #compareAndSetState}: + * + * <ul> + * <li> {@link #tryAcquire} + * <li> {@link #tryRelease} + * <li> {@link #tryAcquireShared} + * <li> {@link #tryReleaseShared} + * <li> {@link #isHeldExclusively} + *</ul> + * + * Each of these methods by default throws {@link + * UnsupportedOperationException}. Implementations of these methods + * must be internally thread-safe, and should in general be short and + * not block. Defining these methods is the <em>only</em> supported + * means of using this class. All other methods are declared + * <tt>final</tt> because they cannot be independently varied. + * + * <p>You may also find the inherited methods from {@link + * AbstractOwnableSynchronizer} useful to keep track of the thread + * owning an exclusive synchronizer. You are encouraged to use them + * -- this enables monitoring and diagnostic tools to assist users in + * determining which threads hold locks. + * + * <p>Even though this class is based on an internal FIFO queue, it + * does not automatically enforce FIFO acquisition policies. The core + * of exclusive synchronization takes the form: + * + * <pre> + * Acquire: + * while (!tryAcquire(arg)) { + * <em>enqueue thread if it is not already queued</em>; + * <em>possibly block current thread</em>; + * } + * + * Release: + * if (tryRelease(arg)) + * <em>unblock the first queued thread</em>; + * </pre> + * + * (Shared mode is similar but may involve cascading signals.) + * + * <p>Because checks in acquire are invoked before enqueuing, a newly + * acquiring thread may <em>barge</em> ahead of others that are + * blocked and queued. However, you can, if desired, define + * <tt>tryAcquire</tt> and/or <tt>tryAcquireShared</tt> to disable + * barging by internally invoking one or more of the inspection + * methods. In particular, a strict FIFO lock can define + * <tt>tryAcquire</tt> to immediately return <tt>false</tt> if {@link + * #getFirstQueuedThread} does not return the current thread. A + * normally preferable non-strict fair version can immediately return + * <tt>false</tt> only if {@link #hasQueuedThreads} returns + * <tt>true</tt> and <tt>getFirstQueuedThread</tt> is not the current + * thread; or equivalently, that <tt>getFirstQueuedThread</tt> is both + * non-null and not the current thread. Further variations are + * possible. + * + * <p>Throughput and scalability are generally highest for the + * default barging (also known as <em>greedy</em>, + * <em>renouncement</em>, and <em>convoy-avoidance</em>) strategy. + * While this is not guaranteed to be fair or starvation-free, earlier + * queued threads are allowed to recontend before later queued + * threads, and each recontention has an unbiased chance to succeed + * against incoming threads. Also, while acquires do not + * "spin" in the usual sense, they may perform multiple + * invocations of <tt>tryAcquire</tt> interspersed with other + * computations before blocking. This gives most of the benefits of + * spins when exclusive synchronization is only briefly held, without + * most of the liabilities when it isn't. If so desired, you can + * augment this by preceding calls to acquire methods with + * "fast-path" checks, possibly prechecking {@link #hasContended} + * and/or {@link #hasQueuedThreads} to only do so if the synchronizer + * is likely not to be contended. + * + * <p>This class provides an efficient and scalable basis for + * synchronization in part by specializing its range of use to + * synchronizers that can rely on <tt>int</tt> state, acquire, and + * release parameters, and an internal FIFO wait queue. When this does + * not suffice, you can build synchronizers from a lower level using + * {@link java.util.concurrent.atomic atomic} classes, your own custom + * {@link java.util.Queue} classes, and {@link LockSupport} blocking + * support. + * + * <h3>Usage Examples</h3> + * + * <p>Here is a non-reentrant mutual exclusion lock class that uses + * the value zero to represent the unlocked state, and one to + * represent the locked state. While a non-reentrant lock + * does not strictly require recording of the current owner + * thread, this class does so anyway to make usage easier to monitor. + * It also supports conditions and exposes + * one of the instrumentation methods: + * + * <pre> + * class Mutex implements Lock, java.io.Serializable { + * + * // Our internal helper class + * private static class Sync extends AbstractQueuedSynchronizer { + * // Report whether in locked state + * protected boolean isHeldExclusively() { + * return getState() == 1; + * } + * + * // Acquire the lock if state is zero + * public boolean tryAcquire(int acquires) { + * assert acquires == 1; // Otherwise unused + * if (compareAndSetState(0, 1)) { + * setExclusiveOwnerThread(Thread.currentThread()); + * return true; + * } + * return false; + * } + * + * // Release the lock by setting state to zero + * protected boolean tryRelease(int releases) { + * assert releases == 1; // Otherwise unused + * if (getState() == 0) throw new IllegalMonitorStateException(); + * setExclusiveOwnerThread(null); + * setState(0); + * return true; + * } + * + * // Provide a Condition + * Condition newCondition() { return new ConditionObject(); } + * + * // Deserialize properly + * private void readObject(ObjectInputStream s) + * throws IOException, ClassNotFoundException { + * s.defaultReadObject(); + * setState(0); // reset to unlocked state + * } + * } + * + * // The sync object does all the hard work. We just forward to it. + * private final Sync sync = new Sync(); + * + * public void lock() { sync.acquire(1); } + * public boolean tryLock() { return sync.tryAcquire(1); } + * public void unlock() { sync.release(1); } + * public Condition newCondition() { return sync.newCondition(); } + * public boolean isLocked() { return sync.isHeldExclusively(); } + * public boolean hasQueuedThreads() { return sync.hasQueuedThreads(); } + * public void lockInterruptibly() throws InterruptedException { + * sync.acquireInterruptibly(1); + * } + * public boolean tryLock(long timeout, TimeUnit unit) + * throws InterruptedException { + * return sync.tryAcquireNanos(1, unit.toNanos(timeout)); + * } + * } + * </pre> + * + * <p>Here is a latch class that is like a {@link CountDownLatch} + * except that it only requires a single <tt>signal</tt> to + * fire. Because a latch is non-exclusive, it uses the <tt>shared</tt> + * acquire and release methods. + * + * <pre> + * class BooleanLatch { + * + * private static class Sync extends AbstractQueuedSynchronizer { + * boolean isSignalled() { return getState() != 0; } + * + * protected int tryAcquireShared(int ignore) { + * return isSignalled()? 1 : -1; + * } + * + * protected boolean tryReleaseShared(int ignore) { + * setState(1); + * return true; + * } + * } + * + * private final Sync sync = new Sync(); + * public boolean isSignalled() { return sync.isSignalled(); } + * public void signal() { sync.releaseShared(1); } + * public void await() throws InterruptedException { + * sync.acquireSharedInterruptibly(1); + * } + * } + * </pre> + * + * @since 1.5 + * @author Doug Lea + */ +public abstract class AbstractQueuedSynchronizer + extends AbstractOwnableSynchronizer + implements java.io.Serializable { + + private static final long serialVersionUID = 7373984972572414691L; + + /** + * Creates a new <tt>AbstractQueuedSynchronizer</tt> instance + * with initial synchronization state of zero. + */ + protected AbstractQueuedSynchronizer() { } + + /** + * Wait queue node class. + * + * <p>The wait queue is a variant of a "CLH" (Craig, Landin, and + * Hagersten) lock queue. CLH locks are normally used for + * spinlocks. We instead use them for blocking synchronizers, but + * use the same basic tactic of holding some of the control + * information about a thread in the predecessor of its node. A + * "status" field in each node keeps track of whether a thread + * should block. A node is signalled when its predecessor + * releases. Each node of the queue otherwise serves as a + * specific-notification-style monitor holding a single waiting + * thread. The status field does NOT control whether threads are + * granted locks etc though. A thread may try to acquire if it is + * first in the queue. But being first does not guarantee success; + * it only gives the right to contend. So the currently released + * contender thread may need to rewait. + * + * <p>To enqueue into a CLH lock, you atomically splice it in as new + * tail. To dequeue, you just set the head field. + * <pre> + * +------+ prev +-----+ +-----+ + * head | | <---- | | <---- | | tail + * +------+ +-----+ +-----+ + * </pre> + * + * <p>Insertion into a CLH queue requires only a single atomic + * operation on "tail", so there is a simple atomic point of + * demarcation from unqueued to queued. Similarly, dequeing + * involves only updating the "head". However, it takes a bit + * more work for nodes to determine who their successors are, + * in part to deal with possible cancellation due to timeouts + * and interrupts. + * + * <p>The "prev" links (not used in original CLH locks), are mainly + * needed to handle cancellation. If a node is cancelled, its + * successor is (normally) relinked to a non-cancelled + * predecessor. For explanation of similar mechanics in the case + * of spin locks, see the papers by Scott and Scherer at + * http://www.cs.rochester.edu/u/scott/synchronization/ + * + * <p>We also use "next" links to implement blocking mechanics. + * The thread id for each node is kept in its own node, so a + * predecessor signals the next node to wake up by traversing + * next link to determine which thread it is. Determination of + * successor must avoid races with newly queued nodes to set + * the "next" fields of their predecessors. This is solved + * when necessary by checking backwards from the atomically + * updated "tail" when a node's successor appears to be null. + * (Or, said differently, the next-links are an optimization + * so that we don't usually need a backward scan.) + * + * <p>Cancellation introduces some conservatism to the basic + * algorithms. Since we must poll for cancellation of other + * nodes, we can miss noticing whether a cancelled node is + * ahead or behind us. This is dealt with by always unparking + * successors upon cancellation, allowing them to stabilize on + * a new predecessor. + * + * <p>CLH queues need a dummy header node to get started. But + * we don't create them on construction, because it would be wasted + * effort if there is never contention. Instead, the node + * is constructed and head and tail pointers are set upon first + * contention. + * + * <p>Threads waiting on Conditions use the same nodes, but + * use an additional link. Conditions only need to link nodes + * in simple (non-concurrent) linked queues because they are + * only accessed when exclusively held. Upon await, a node is + * inserted into a condition queue. Upon signal, the node is + * transferred to the main queue. A special value of status + * field is used to mark which queue a node is on. + * + * <p>Thanks go to Dave Dice, Mark Moir, Victor Luchangco, Bill + * Scherer and Michael Scott, along with members of JSR-166 + * expert group, for helpful ideas, discussions, and critiques + * on the design of this class. + */ + static final class Node { + /** waitStatus value to indicate thread has cancelled */ + static final int CANCELLED = 1; + /** waitStatus value to indicate successor's thread needs unparking */ + static final int SIGNAL = -1; + /** waitStatus value to indicate thread is waiting on condition */ + static final int CONDITION = -2; + /** Marker to indicate a node is waiting in shared mode */ + static final Node SHARED = new Node(); + /** Marker to indicate a node is waiting in exclusive mode */ + static final Node EXCLUSIVE = null; + + /** + * Status field, taking on only the values: + * SIGNAL: The successor of this node is (or will soon be) + * blocked (via park), so the current node must + * unpark its successor when it releases or + * cancels. To avoid races, acquire methods must + * first indicate they need a signal, + * then retry the atomic acquire, and then, + * on failure, block. + * CANCELLED: This node is cancelled due to timeout or interrupt. + * Nodes never leave this state. In particular, + * a thread with cancelled node never again blocks. + * CONDITION: This node is currently on a condition queue. + * It will not be used as a sync queue node until + * transferred. (Use of this value here + * has nothing to do with the other uses + * of the field, but simplifies mechanics.) + * 0: None of the above + * + * The values are arranged numerically to simplify use. + * Non-negative values mean that a node doesn't need to + * signal. So, most code doesn't need to check for particular + * values, just for sign. + * + * The field is initialized to 0 for normal sync nodes, and + * CONDITION for condition nodes. It is modified only using + * CAS. + */ + volatile int waitStatus; + + /** + * Link to predecessor node that current node/thread relies on + * for checking waitStatus. Assigned during enqueing, and nulled + * out (for sake of GC) only upon dequeuing. Also, upon + * cancellation of a predecessor, we short-circuit while + * finding a non-cancelled one, which will always exist + * because the head node is never cancelled: A node becomes + * head only as a result of successful acquire. A + * cancelled thread never succeeds in acquiring, and a thread only + * cancels itself, not any other node. + */ + volatile Node prev; + + /** + * Link to the successor node that the current node/thread + * unparks upon release. Assigned once during enqueuing, and + * nulled out (for sake of GC) when no longer needed. Upon + * cancellation, we cannot adjust this field, but can notice + * status and bypass the node if cancelled. The enq operation + * does not assign next field of a predecessor until after + * attachment, so seeing a null next field does not + * necessarily mean that node is at end of queue. However, if + * a next field appears to be null, we can scan prev's from + * the tail to double-check. + */ + volatile Node next; + + /** + * The thread that enqueued this node. Initialized on + * construction and nulled out after use. + */ + volatile Thread thread; + + /** + * Link to next node waiting on condition, or the special + * value SHARED. Because condition queues are accessed only + * when holding in exclusive mode, we just need a simple + * linked queue to hold nodes while they are waiting on + * conditions. They are then transferred to the queue to + * re-acquire. And because conditions can only be exclusive, + * we save a field by using special value to indicate shared + * mode. + */ + Node nextWaiter; + + /** + * Returns true if node is waiting in shared mode + */ + final boolean isShared() { + return nextWaiter == SHARED; + } + + /** + * Returns previous node, or throws NullPointerException if + * null. Use when predecessor cannot be null. + * @return the predecessor of this node + */ + final Node predecessor() throws NullPointerException { + Node p = prev; + if (p == null) + throw new NullPointerException(); + else + return p; + } + + Node() { // Used to establish initial head or SHARED marker + } + + Node(Thread thread, Node mode) { // Used by addWaiter + this.nextWaiter = mode; + this.thread = thread; + } + + Node(Thread thread, int waitStatus) { // Used by Condition + this.waitStatus = waitStatus; + this.thread = thread; + } + } + + /** + * Head of the wait queue, lazily initialized. Except for + * initialization, it is modified only via method setHead. Note: + * If head exists, its waitStatus is guaranteed not to be + * CANCELLED. + */ + private transient volatile Node head; + + /** + * Tail of the wait queue, lazily initialized. Modified only via + * method enq to add new wait node. + */ + private transient volatile Node tail; + + /** + * The synchronization state. + */ + private volatile int state; + + /** + * Returns the current value of synchronization state. + * This operation has memory semantics of a <tt>volatile</tt> read. + * @return current state value + */ + protected final int getState() { + return state; + } + + /** + * Sets the value of synchronization state. + * This operation has memory semantics of a <tt>volatile</tt> write. + * @param newState the new state value + */ + protected final void setState(int newState) { + state = newState; + } + + /** + * Atomically sets synchronization state to the given updated + * value if the current state value equals the expected value. + * This operation has memory semantics of a <tt>volatile</tt> read + * and write. + * + * @param expect the expected value + * @param update the new value + * @return true if successful. False return indicates that the actual + * value was not equal to the expected value. + */ + protected final boolean compareAndSetState(int expect, int update) { + // See below for intrinsics setup to support this + return unsafe.compareAndSwapInt(this, stateOffset, expect, update); + } + + // Queuing utilities + + /** + * The number of nanoseconds for which it is faster to spin + * rather than to use timed park. A rough estimate suffices + * to improve responsiveness with very short timeouts. + */ + static final long spinForTimeoutThreshold = 1000L; + + /** + * Inserts node into queue, initializing if necessary. See picture above. + * @param node the node to insert + * @return node's predecessor + */ + private Node enq(final Node node) { + for (;;) { + Node t = tail; + if (t == null) { // Must initialize + Node h = new Node(); // Dummy header + h.next = node; + node.prev = h; + if (compareAndSetHead(h)) { + tail = node; + return h; + } + } + else { + node.prev = t; + if (compareAndSetTail(t, node)) { + t.next = node; + return t; + } + } + } + } + + /** + * Creates and enqueues node for given thread and mode. + * + * @param current the thread + * @param mode Node.EXCLUSIVE for exclusive, Node.SHARED for shared + * @return the new node + */ + private Node addWaiter(Node mode) { + Node node = new Node(Thread.currentThread(), mode); + // Try the fast path of enq; backup to full enq on failure + Node pred = tail; + if (pred != null) { + node.prev = pred; + if (compareAndSetTail(pred, node)) { + pred.next = node; + return node; + } + } + enq(node); + return node; + } + + /** + * Sets head of queue to be node, thus dequeuing. Called only by + * acquire methods. Also nulls out unused fields for sake of GC + * and to suppress unnecessary signals and traversals. + * + * @param node the node + */ + private void setHead(Node node) { + head = node; + node.thread = null; + node.prev = null; + } + + /** + * Wakes up node's successor, if one exists. + * + * @param node the node + */ + private void unparkSuccessor(Node node) { + /* + * Try to clear status in anticipation of signalling. It is + * OK if this fails or if status is changed by waiting thread. + */ + compareAndSetWaitStatus(node, Node.SIGNAL, 0); + + /* + * Thread to unpark is held in successor, which is normally + * just the next node. But if cancelled or apparently null, + * traverse backwards from tail to find the actual + * non-cancelled successor. + */ + Node s = node.next; + if (s == null || s.waitStatus > 0) { + s = null; + for (Node t = tail; t != null && t != node; t = t.prev) + if (t.waitStatus <= 0) + s = t; + } + if (s != null) + LockSupport.unpark(s.thread); + } + + /** + * Sets head of queue, and checks if successor may be waiting + * in shared mode, if so propagating if propagate > 0. + * + * @param pred the node holding waitStatus for node + * @param node the node + * @param propagate the return value from a tryAcquireShared + */ + private void setHeadAndPropagate(Node node, int propagate) { + setHead(node); + if (propagate > 0 && node.waitStatus != 0) { + /* + * Don't bother fully figuring out successor. If it + * looks null, call unparkSuccessor anyway to be safe. + */ + Node s = node.next; + if (s == null || s.isShared()) + unparkSuccessor(node); + } + } + + // Utilities for various versions of acquire + + /** + * Cancels an ongoing attempt to acquire. + * + * @param node the node + */ + private void cancelAcquire(Node node) { + if (node != null) { // Ignore if node doesn't exist + node.thread = null; + // Can use unconditional write instead of CAS here + node.waitStatus = Node.CANCELLED; + unparkSuccessor(node); + } + } + + /** + * Checks and updates status for a node that failed to acquire. + * Returns true if thread should block. This is the main signal + * control in all acquire loops. Requires that pred == node.prev + * + * @param pred node's predecessor holding status + * @param node the node + * @return {@code true} if thread should block + */ + private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) { + int s = pred.waitStatus; + if (s < 0) + /* + * This node has already set status asking a release + * to signal it, so it can safely park + */ + return true; + if (s > 0) + /* + * Predecessor was cancelled. Move up to its predecessor + * and indicate retry. + */ + node.prev = pred.prev; + else + /* + * Indicate that we need a signal, but don't park yet. Caller + * will need to retry to make sure it cannot acquire before + * parking. + */ + compareAndSetWaitStatus(pred, 0, Node.SIGNAL); + return false; + } + + /** + * Convenience method to interrupt current thread. + */ + private static void selfInterrupt() { + Thread.currentThread().interrupt(); + } + + /** + * Convenience method to park and then check if interrupted + * + * @return {@code true} if interrupted + */ + private final boolean parkAndCheckInterrupt() { + LockSupport.park(this); + return Thread.interrupted(); + } + + /* + * Various flavors of acquire, varying in exclusive/shared and + * control modes. Each is mostly the same, but annoyingly + * different. Only a little bit of factoring is possible due to + * interactions of exception mechanics (including ensuring that we + * cancel if tryAcquire throws exception) and other control, at + * least not without hurting performance too much. + */ + + /** + * Acquires in exclusive uninterruptible mode for thread already in + * queue. Used by condition wait methods as well as acquire. + * + * @param node the node + * @param arg the acquire argument + * @return {@code true} if interrupted while waiting + */ + final boolean acquireQueued(final Node node, int arg) { + try { + boolean interrupted = false; + for (;;) { + final Node p = node.predecessor(); + if (p == head && tryAcquire(arg)) { + setHead(node); + p.next = null; // help GC + return interrupted; + } + if (shouldParkAfterFailedAcquire(p, node) && + parkAndCheckInterrupt()) + interrupted = true; + } + } catch (RuntimeException ex) { + cancelAcquire(node); + throw ex; + } + } + + /** + * Acquires in exclusive interruptible mode. + * @param arg the acquire argument + */ + private void doAcquireInterruptibly(int arg) + throws InterruptedException { + final Node node = addWaiter(Node.EXCLUSIVE); + try { + for (;;) { + final Node p = node.predecessor(); + if (p == head && tryAcquire(arg)) { + setHead(node); + p.next = null; // help GC + return; + } + if (shouldParkAfterFailedAcquire(p, node) && + parkAndCheckInterrupt()) + break; + } + } catch (RuntimeException ex) { + cancelAcquire(node); + throw ex; + } + // Arrive here only if interrupted + cancelAcquire(node); + throw new InterruptedException(); + } + + /** + * Acquires in exclusive timed mode. + * + * @param arg the acquire argument + * @param nanosTimeout max wait time + * @return {@code true} if acquired + */ + private boolean doAcquireNanos(int arg, long nanosTimeout) + throws InterruptedException { + long lastTime = System.nanoTime(); + final Node node = addWaiter(Node.EXCLUSIVE); + try { + for (;;) { + final Node p = node.predecessor(); + if (p == head && tryAcquire(arg)) { + setHead(node); + p.next = null; // help GC + return true; + } + if (nanosTimeout <= 0) { + cancelAcquire(node); + return false; + } + if (nanosTimeout > spinForTimeoutThreshold && + shouldParkAfterFailedAcquire(p, node)) + LockSupport.parkNanos(this, nanosTimeout); + long now = System.nanoTime(); + nanosTimeout -= now - lastTime; + lastTime = now; + if (Thread.interrupted()) + break; + } + } catch (RuntimeException ex) { + cancelAcquire(node); + throw ex; + } + // Arrive here only if interrupted + cancelAcquire(node); + throw new InterruptedException(); + } + + /** + * Acquires in shared uninterruptible mode. + * @param arg the acquire argument + */ + private void doAcquireShared(int arg) { + final Node node = addWaiter(Node.SHARED); + try { + boolean interrupted = false; + for (;;) { + final Node p = node.predecessor(); + if (p == head) { + int r = tryAcquireShared(arg); + if (r >= 0) { + setHeadAndPropagate(node, r); + p.next = null; // help GC + if (interrupted) + selfInterrupt(); + return; + } + } + if (shouldParkAfterFailedAcquire(p, node) && + parkAndCheckInterrupt()) + interrupted = true; + } + } catch (RuntimeException ex) { + cancelAcquire(node); + throw ex; + } + } + + /** + * Acquires in shared interruptible mode. + * @param arg the acquire argument + */ + private void doAcquireSharedInterruptibly(int arg) + throws InterruptedException { + final Node node = addWaiter(Node.SHARED); + try { + for (;;) { + final Node p = node.predecessor(); + if (p == head) { + int r = tryAcquireShared(arg); + if (r >= 0) { + setHeadAndPropagate(node, r); + p.next = null; // help GC + return; + } + } + if (shouldParkAfterFailedAcquire(p, node) && + parkAndCheckInterrupt()) + break; + } + } catch (RuntimeException ex) { + cancelAcquire(node); + throw ex; + } + // Arrive here only if interrupted + cancelAcquire(node); + throw new InterruptedException(); + } + + /** + * Acquires in shared timed mode. + * + * @param arg the acquire argument + * @param nanosTimeout max wait time + * @return {@code true} if acquired + */ + private boolean doAcquireSharedNanos(int arg, long nanosTimeout) + throws InterruptedException { + + long lastTime = System.nanoTime(); + final Node node = addWaiter(Node.SHARED); + try { + for (;;) { + final Node p = node.predecessor(); + if (p == head) { + int r = tryAcquireShared(arg); + if (r >= 0) { + setHeadAndPropagate(node, r); + p.next = null; // help GC + return true; + } + } + if (nanosTimeout <= 0) { + cancelAcquire(node); + return false; + } + if (nanosTimeout > spinForTimeoutThreshold && + shouldParkAfterFailedAcquire(p, node)) + LockSupport.parkNanos(this, nanosTimeout); + long now = System.nanoTime(); + nanosTimeout -= now - lastTime; + lastTime = now; + if (Thread.interrupted()) + break; + } + } catch (RuntimeException ex) { + cancelAcquire(node); + throw ex; + } + // Arrive here only if interrupted + cancelAcquire(node); + throw new InterruptedException(); + } + + // Main exported methods + + /** + * Attempts to acquire in exclusive mode. This method should query + * if the state of the object permits it to be acquired in the + * exclusive mode, and if so to acquire it. + * + * <p>This method is always invoked by the thread performing + * acquire. If this method reports failure, the acquire method + * may queue the thread, if it is not already queued, until it is + * signalled by a release from some other thread. This can be used + * to implement method {@link Lock#tryLock()}. + * + * <p>The default + * implementation throws {@link UnsupportedOperationException}. + * + * @param arg the acquire argument. This value is always the one + * passed to an acquire method, or is the value saved on entry + * to a condition wait. The value is otherwise uninterpreted + * and can represent anything you like. + * @return {@code true} if successful. Upon success, this object has + * been acquired. + * @throws IllegalMonitorStateException if acquiring would place this + * synchronizer in an illegal state. This exception must be + * thrown in a consistent fashion for synchronization to work + * correctly. + * @throws UnsupportedOperationException if exclusive mode is not supported + */ + protected boolean tryAcquire(int arg) { + throw new UnsupportedOperationException(); + } + + /** + * Attempts to set the state to reflect a release in exclusive + * mode. + * + * <p>This method is always invoked by the thread performing release. + * + * <p>The default implementation throws + * {@link UnsupportedOperationException}. + * + * @param arg the release argument. This value is always the one + * passed to a release method, or the current state value upon + * entry to a condition wait. The value is otherwise + * uninterpreted and can represent anything you like. + * @return {@code true} if this object is now in a fully released + * state, so that any waiting threads may attempt to acquire; + * and {@code false} otherwise. + * @throws IllegalMonitorStateException if releasing would place this + * synchronizer in an illegal state. This exception must be + * thrown in a consistent fashion for synchronization to work + * correctly. + * @throws UnsupportedOperationException if exclusive mode is not supported + */ + protected boolean tryRelease(int arg) { + throw new UnsupportedOperationException(); + } + + /** + * Attempts to acquire in shared mode. This method should query if + * the state of the object permits it to be acquired in the shared + * mode, and if so to acquire it. + * + * <p>This method is always invoked by the thread performing + * acquire. If this method reports failure, the acquire method + * may queue the thread, if it is not already queued, until it is + * signalled by a release from some other thread. + * + * <p>The default implementation throws {@link + * UnsupportedOperationException}. + * + * @param arg the acquire argument. This value is always the one + * passed to an acquire method, or is the value saved on entry + * to a condition wait. The value is otherwise uninterpreted + * and can represent anything you like. + * @return a negative value on failure; zero if acquisition in shared + * mode succeeded but no subsequent shared-mode acquire can + * succeed; and a positive value if acquisition in shared + * mode succeeded and subsequent shared-mode acquires might + * also succeed, in which case a subsequent waiting thread + * must check availability. (Support for three different + * return values enables this method to be used in contexts + * where acquires only sometimes act exclusively.) Upon + * success, this object has been acquired. + * @throws IllegalMonitorStateException if acquiring would place this + * synchronizer in an illegal state. This exception must be + * thrown in a consistent fashion for synchronization to work + * correctly. + * @throws UnsupportedOperationException if shared mode is not supported + */ + protected int tryAcquireShared(int arg) { + throw new UnsupportedOperationException(); + } + + /** + * Attempts to set the state to reflect a release in shared mode. + * + * <p>This method is always invoked by the thread performing release. + * + * <p>The default implementation throws + * {@link UnsupportedOperationException}. + * + * @param arg the release argument. This value is always the one + * passed to a release method, or the current state value upon + * entry to a condition wait. The value is otherwise + * uninterpreted and can represent anything you like. + * @return {@code true} if this release of shared mode may permit a + * waiting acquire (shared or exclusive) to succeed; and + * {@code false} otherwise + * @throws IllegalMonitorStateException if releasing would place this + * synchronizer in an illegal state. This exception must be + * thrown in a consistent fashion for synchronization to work + * correctly. + * @throws UnsupportedOperationException if shared mode is not supported + */ + protected boolean tryReleaseShared(int arg) { + throw new UnsupportedOperationException(); + } + + /** + * Returns {@code true} if synchronization is held exclusively with + * respect to the current (calling) thread. This method is invoked + * upon each call to a non-waiting {@link ConditionObject} method. + * (Waiting methods instead invoke {@link #release}.) + * + * <p>The default implementation throws {@link + * UnsupportedOperationException}. This method is invoked + * internally only within {@link ConditionObject} methods, so need + * not be defined if conditions are not used. + * + * @return {@code true} if synchronization is held exclusively; + * {@code false} otherwise + * @throws UnsupportedOperationException if conditions are not supported + */ + protected boolean isHeldExclusively() { + throw new UnsupportedOperationException(); + } + + /** + * Acquires in exclusive mode, ignoring interrupts. Implemented + * by invoking at least once {@link #tryAcquire}, + * returning on success. Otherwise the thread is queued, possibly + * repeatedly blocking and unblocking, invoking {@link + * #tryAcquire} until success. This method can be used + * to implement method {@link Lock#lock}. + * + * @param arg the acquire argument. This value is conveyed to + * {@link #tryAcquire} but is otherwise uninterpreted and + * can represent anything you like. + */ + public final void acquire(int arg) { + if (!tryAcquire(arg) && + acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) + selfInterrupt(); + } + + /** + * Acquires in exclusive mode, aborting if interrupted. + * Implemented by first checking interrupt status, then invoking + * at least once {@link #tryAcquire}, returning on + * success. Otherwise the thread is queued, possibly repeatedly + * blocking and unblocking, invoking {@link #tryAcquire} + * until success or the thread is interrupted. This method can be + * used to implement method {@link Lock#lockInterruptibly}. + * + * @param arg the acquire argument. This value is conveyed to + * {@link #tryAcquire} but is otherwise uninterpreted and + * can represent anything you like. + * @throws InterruptedException if the current thread is interrupted + */ + public final void acquireInterruptibly(int arg) throws InterruptedException { + if (Thread.interrupted()) + throw new InterruptedException(); + if (!tryAcquire(arg)) + doAcquireInterruptibly(arg); + } + + /** + * Attempts to acquire in exclusive mode, aborting if interrupted, + * and failing if the given timeout elapses. Implemented by first + * checking interrupt status, then invoking at least once {@link + * #tryAcquire}, returning on success. Otherwise, the thread is + * queued, possibly repeatedly blocking and unblocking, invoking + * {@link #tryAcquire} until success or the thread is interrupted + * or the timeout elapses. This method can be used to implement + * method {@link Lock#tryLock(long, TimeUnit)}. + * + * @param arg the acquire argument. This value is conveyed to + * {@link #tryAcquire} but is otherwise uninterpreted and + * can represent anything you like. + * @param nanosTimeout the maximum number of nanoseconds to wait + * @return {@code true} if acquired; {@code false} if timed out + * @throws InterruptedException if the current thread is interrupted + */ + public final boolean tryAcquireNanos(int arg, long nanosTimeout) throws InterruptedException { + if (Thread.interrupted()) + throw new InterruptedException(); + return tryAcquire(arg) || + doAcquireNanos(arg, nanosTimeout); + } + + /** + * Releases in exclusive mode. Implemented by unblocking one or + * more threads if {@link #tryRelease} returns true. + * This method can be used to implement method {@link Lock#unlock}. + * + * @param arg the release argument. This value is conveyed to + * {@link #tryRelease} but is otherwise uninterpreted and + * can represent anything you like. + * @return the value returned from {@link #tryRelease} + */ + public final boolean release(int arg) { + if (tryRelease(arg)) { + Node h = head; + if (h != null && h.waitStatus != 0) + unparkSuccessor(h); + return true; + } + return false; + } + + /** + * Acquires in shared mode, ignoring interrupts. Implemented by + * first invoking at least once {@link #tryAcquireShared}, + * returning on success. Otherwise the thread is queued, possibly + * repeatedly blocking and unblocking, invoking {@link + * #tryAcquireShared} until success. + * + * @param arg the acquire argument. This value is conveyed to + * {@link #tryAcquireShared} but is otherwise uninterpreted + * and can represent anything you like. + */ + public final void acquireShared(int arg) { + if (tryAcquireShared(arg) < 0) + doAcquireShared(arg); + } + + /** + * Acquires in shared mode, aborting if interrupted. Implemented + * by first checking interrupt status, then invoking at least once + * {@link #tryAcquireShared}, returning on success. Otherwise the + * thread is queued, possibly repeatedly blocking and unblocking, + * invoking {@link #tryAcquireShared} until success or the thread + * is interrupted. + * @param arg the acquire argument. + * This value is conveyed to {@link #tryAcquireShared} but is + * otherwise uninterpreted and can represent anything + * you like. + * @throws InterruptedException if the current thread is interrupted + */ + public final void acquireSharedInterruptibly(int arg) throws InterruptedException { + if (Thread.interrupted()) + throw new InterruptedException(); + if (tryAcquireShared(arg) < 0) + doAcquireSharedInterruptibly(arg); + } + + /** + * Attempts to acquire in shared mode, aborting if interrupted, and + * failing if the given timeout elapses. Implemented by first + * checking interrupt status, then invoking at least once {@link + * #tryAcquireShared}, returning on success. Otherwise, the + * thread is queued, possibly repeatedly blocking and unblocking, + * invoking {@link #tryAcquireShared} until success or the thread + * is interrupted or the timeout elapses. + * + * @param arg the acquire argument. This value is conveyed to + * {@link #tryAcquireShared} but is otherwise uninterpreted + * and can represent anything you like. + * @param nanosTimeout the maximum number of nanoseconds to wait + * @return {@code true} if acquired; {@code false} if timed out + * @throws InterruptedException if the current thread is interrupted + */ + public final boolean tryAcquireSharedNanos(int arg, long nanosTimeout) throws InterruptedException { + if (Thread.interrupted()) + throw new InterruptedException(); + return tryAcquireShared(arg) >= 0 || + doAcquireSharedNanos(arg, nanosTimeout); + } + + /** + * Releases in shared mode. Implemented by unblocking one or more + * threads if {@link #tryReleaseShared} returns true. + * + * @param arg the release argument. This value is conveyed to + * {@link #tryReleaseShared} but is otherwise uninterpreted + * and can represent anything you like. + * @return the value returned from {@link #tryReleaseShared} + */ + public final boolean releaseShared(int arg) { + if (tryReleaseShared(arg)) { + Node h = head; + if (h != null && h.waitStatus != 0) + unparkSuccessor(h); + return true; + } + return false; + } + + // Queue inspection methods + + /** + * Queries whether any threads are waiting to acquire. Note that + * because cancellations due to interrupts and timeouts may occur + * at any time, a {@code true} return does not guarantee that any + * other thread will ever acquire. + * + * <p>In this implementation, this operation returns in + * constant time. + * + * @return {@code true} if there may be other threads waiting to acquire + */ + public final boolean hasQueuedThreads() { + return head != tail; + } + + /** + * Queries whether any threads have ever contended to acquire this + * synchronizer; that is if an acquire method has ever blocked. + * + * <p>In this implementation, this operation returns in + * constant time. + * + * @return {@code true} if there has ever been contention + */ + public final boolean hasContended() { + return head != null; + } + + /** + * Returns the first (longest-waiting) thread in the queue, or + * {@code null} if no threads are currently queued. + * + * <p>In this implementation, this operation normally returns in + * constant time, but may iterate upon contention if other threads are + * concurrently modifying the queue. + * + * @return the first (longest-waiting) thread in the queue, or + * {@code null} if no threads are currently queued + */ + public final Thread getFirstQueuedThread() { + // handle only fast path, else relay + return (head == tail)? null : fullGetFirstQueuedThread(); + } + + /** + * Version of getFirstQueuedThread called when fastpath fails + */ + private Thread fullGetFirstQueuedThread() { + /* + * The first node is normally h.next. Try to get its + * thread field, ensuring consistent reads: If thread + * field is nulled out or s.prev is no longer head, then + * some other thread(s) concurrently performed setHead in + * between some of our reads. We try this twice before + * resorting to traversal. + */ + Node h, s; + Thread st; + if (((h = head) != null && (s = h.next) != null && + s.prev == head && (st = s.thread) != null) || + ((h = head) != null && (s = h.next) != null && + s.prev == head && (st = s.thread) != null)) + return st; + + /* + * Head's next field might not have been set yet, or may have + * been unset after setHead. So we must check to see if tail + * is actually first node. If not, we continue on, safely + * traversing from tail back to head to find first, + * guaranteeing termination. + */ + + Node t = tail; + Thread firstThread = null; + while (t != null && t != head) { + Thread tt = t.thread; + if (tt != null) + firstThread = tt; + t = t.prev; + } + return firstThread; + } + + /** + * Returns true if the given thread is currently queued. + * + * <p>This implementation traverses the queue to determine + * presence of the given thread. + * + * @param thread the thread + * @return {@code true} if the given thread is on the queue + * @throws NullPointerException if the thread is null + */ + public final boolean isQueued(Thread thread) { + if (thread == null) + throw new NullPointerException(); + for (Node p = tail; p != null; p = p.prev) + if (p.thread == thread) + return true; + return false; + } + + /** + * Return {@code true} if the apparent first queued thread, if one + * exists, is not waiting in exclusive mode. Used only as a heuristic + * in ReentrantReadWriteLock. + */ + final boolean apparentlyFirstQueuedIsExclusive() { + Node h, s; + return ((h = head) != null && (s = h.next) != null && + s.nextWaiter != Node.SHARED); + } + + /** + * Return {@code true} if the queue is empty or if the given thread + * is at the head of the queue. This is reliable only if + * <tt>current</tt> is actually Thread.currentThread() of caller. + */ + final boolean isFirst(Thread current) { + Node h, s; + return ((h = head) == null || + ((s = h.next) != null && s.thread == current) || + fullIsFirst(current)); + } + + final boolean fullIsFirst(Thread current) { + // same idea as fullGetFirstQueuedThread + Node h, s; + Thread firstThread = null; + if (((h = head) != null && (s = h.next) != null && + s.prev == head && (firstThread = s.thread) != null)) + return firstThread == current; + Node t = tail; + while (t != null && t != head) { + Thread tt = t.thread; + if (tt != null) + firstThread = tt; + t = t.prev; + } + return firstThread == current || firstThread == null; + } + + + // Instrumentation and monitoring methods + + /** + * Returns an estimate of the number of threads waiting to + * acquire. The value is only an estimate because the number of + * threads may change dynamically while this method traverses + * internal data structures. This method is designed for use in + * monitoring system state, not for synchronization + * control. + * + * @return the estimated number of threads waiting to acquire + */ + public final int getQueueLength() { + int n = 0; + for (Node p = tail; p != null; p = p.prev) { + if (p.thread != null) + ++n; + } + return n; + } + + /** + * Returns a collection containing threads that may be waiting to + * acquire. Because the actual set of threads may change + * dynamically while constructing this result, the returned + * collection is only a best-effort estimate. The elements of the + * returned collection are in no particular order. This method is + * designed to facilitate construction of subclasses that provide + * more extensive monitoring facilities. + * + * @return the collection of threads + */ + public final Collection<Thread> getQueuedThreads() { + ArrayList<Thread> list = new ArrayList<Thread>(); + for (Node p = tail; p != null; p = p.prev) { + Thread t = p.thread; + if (t != null) + list.add(t); + } + return list; + } + + /** + * Returns a collection containing threads that may be waiting to + * acquire in exclusive mode. This has the same properties + * as {@link #getQueuedThreads} except that it only returns + * those threads waiting due to an exclusive acquire. + * + * @return the collection of threads + */ + public final Collection<Thread> getExclusiveQueuedThreads() { + ArrayList<Thread> list = new ArrayList<Thread>(); + for (Node p = tail; p != null; p = p.prev) { + if (!p.isShared()) { + Thread t = p.thread; + if (t != null) + list.add(t); + } + } + return list; + } + + /** + * Returns a collection containing threads that may be waiting to + * acquire in shared mode. This has the same properties + * as {@link #getQueuedThreads} except that it only returns + * those threads waiting due to a shared acquire. + * + * @return the collection of threads + */ + public final Collection<Thread> getSharedQueuedThreads() { + ArrayList<Thread> list = new ArrayList<Thread>(); + for (Node p = tail; p != null; p = p.prev) { + if (p.isShared()) { + Thread t = p.thread; + if (t != null) + list.add(t); + } + } + return list; + } + + /** + * Returns a string identifying this synchronizer, as well as its state. + * The state, in brackets, includes the String {@code "State ="} + * followed by the current value of {@link #getState}, and either + * {@code "nonempty"} or {@code "empty"} depending on whether the + * queue is empty. + * + * @return a string identifying this synchronizer, as well as its state + */ + public String toString() { + int s = getState(); + String q = hasQueuedThreads()? "non" : ""; + return super.toString() + + "[State = " + s + ", " + q + "empty queue]"; + } + + + // Internal support methods for Conditions + + /** + * Returns true if a node, always one that was initially placed on + * a condition queue, is now waiting to reacquire on sync queue. + * @param node the node + * @return true if is reacquiring + */ + final boolean isOnSyncQueue(Node node) { + if (node.waitStatus == Node.CONDITION || node.prev == null) + return false; + if (node.next != null) // If has successor, it must be on queue + return true; + /* + * node.prev can be non-null, but not yet on queue because + * the CAS to place it on queue can fail. So we have to + * traverse from tail to make sure it actually made it. It + * will always be near the tail in calls to this method, and + * unless the CAS failed (which is unlikely), it will be + * there, so we hardly ever traverse much. + */ + return findNodeFromTail(node); + } + + /** + * Returns true if node is on sync queue by searching backwards from tail. + * Called only when needed by isOnSyncQueue. + * @return true if present + */ + private boolean findNodeFromTail(Node node) { + Node t = tail; + for (;;) { + if (t == node) + return true; + if (t == null) + return false; + t = t.prev; + } + } + + /** + * Transfers a node from a condition queue onto sync queue. + * Returns true if successful. + * @param node the node + * @return true if successfully transferred (else the node was + * cancelled before signal). + */ + final boolean transferForSignal(Node node) { + /* + * If cannot change waitStatus, the node has been cancelled. + */ + if (!compareAndSetWaitStatus(node, Node.CONDITION, 0)) + return false; + + /* + * Splice onto queue and try to set waitStatus of predecessor to + * indicate that thread is (probably) waiting. If cancelled or + * attempt to set waitStatus fails, wake up to resync (in which + * case the waitStatus can be transiently and harmlessly wrong). + */ + Node p = enq(node); + int c = p.waitStatus; + if (c > 0 || !compareAndSetWaitStatus(p, c, Node.SIGNAL)) + LockSupport.unpark(node.thread); + return true; + } + + /** + * Transfers node, if necessary, to sync queue after a cancelled + * wait. Returns true if thread was cancelled before being + * signalled. + * @param current the waiting thread + * @param node its node + * @return true if cancelled before the node was signalled. + */ + final boolean transferAfterCancelledWait(Node node) { + if (compareAndSetWaitStatus(node, Node.CONDITION, 0)) { + enq(node); + return true; + } + /* + * If we lost out to a signal(), then we can't proceed + * until it finishes its enq(). Cancelling during an + * incomplete transfer is both rare and transient, so just + * spin. + */ + while (!isOnSyncQueue(node)) + Thread.yield(); + return false; + } + + /** + * Invokes release with current state value; returns saved state. + * Cancels node and throws exception on failure. + * @param node the condition node for this wait + * @return previous sync state + */ + final int fullyRelease(Node node) { + try { + int savedState = getState(); + if (release(savedState)) + return savedState; + } catch (RuntimeException ex) { + node.waitStatus = Node.CANCELLED; + throw ex; + } + // reach here if release fails + node.waitStatus = Node.CANCELLED; + throw new IllegalMonitorStateException(); + } + + // Instrumentation methods for conditions + + /** + * Queries whether the given ConditionObject + * uses this synchronizer as its lock. + * + * @param condition the condition + * @return <tt>true</tt> if owned + * @throws NullPointerException if the condition is null + */ + public final boolean owns(ConditionObject condition) { + if (condition == null) + throw new NullPointerException(); + return condition.isOwnedBy(this); + } + + /** + * Queries whether any threads are waiting on the given condition + * associated with this synchronizer. Note that because timeouts + * and interrupts may occur at any time, a <tt>true</tt> return + * does not guarantee that a future <tt>signal</tt> will awaken + * any threads. This method is designed primarily for use in + * monitoring of the system state. + * + * @param condition the condition + * @return <tt>true</tt> if there are any waiting threads + * @throws IllegalMonitorStateException if exclusive synchronization + * is not held + * @throws IllegalArgumentException if the given condition is + * not associated with this synchronizer + * @throws NullPointerException if the condition is null + */ + public final boolean hasWaiters(ConditionObject condition) { + if (!owns(condition)) + throw new IllegalArgumentException("Not owner"); + return condition.hasWaiters(); + } + + /** + * Returns an estimate of the number of threads waiting on the + * given condition associated with this synchronizer. Note that + * because timeouts and interrupts may occur at any time, the + * estimate serves only as an upper bound on the actual number of + * waiters. This method is designed for use in monitoring of the + * system state, not for synchronization control. + * + * @param condition the condition + * @return the estimated number of waiting threads + * @throws IllegalMonitorStateException if exclusive synchronization + * is not held + * @throws IllegalArgumentException if the given condition is + * not associated with this synchronizer + * @throws NullPointerException if the condition is null + */ + public final int getWaitQueueLength(ConditionObject condition) { + if (!owns(condition)) + throw new IllegalArgumentException("Not owner"); + return condition.getWaitQueueLength(); + } + + /** + * Returns a collection containing those threads that may be + * waiting on the given condition associated with this + * synchronizer. Because the actual set of threads may change + * dynamically while constructing this result, the returned + * collection is only a best-effort estimate. The elements of the + * returned collection are in no particular order. + * + * @param condition the condition + * @return the collection of threads + * @throws IllegalMonitorStateException if exclusive synchronization + * is not held + * @throws IllegalArgumentException if the given condition is + * not associated with this synchronizer + * @throws NullPointerException if the condition is null + */ + public final Collection<Thread> getWaitingThreads(ConditionObject condition) { + if (!owns(condition)) + throw new IllegalArgumentException("Not owner"); + return condition.getWaitingThreads(); + } + + /** + * Condition implementation for a {@link + * AbstractQueuedSynchronizer} serving as the basis of a {@link + * Lock} implementation. + * + * <p>Method documentation for this class describes mechanics, + * not behavioral specifications from the point of view of Lock + * and Condition users. Exported versions of this class will in + * general need to be accompanied by documentation describing + * condition semantics that rely on those of the associated + * <tt>AbstractQueuedSynchronizer</tt>. + * + * <p>This class is Serializable, but all fields are transient, + * so deserialized conditions have no waiters. + */ + public class ConditionObject implements Condition, java.io.Serializable { + private static final long serialVersionUID = 1173984872572414699L; + /** First node of condition queue. */ + private transient Node firstWaiter; + /** Last node of condition queue. */ + private transient Node lastWaiter; + + /** + * Creates a new <tt>ConditionObject</tt> instance. + */ + public ConditionObject() { } + + // Internal methods + + /** + * Adds a new waiter to wait queue. + * @return its new wait node + */ + private Node addConditionWaiter() { + Node node = new Node(Thread.currentThread(), Node.CONDITION); + Node t = lastWaiter; + if (t == null) + firstWaiter = node; + else + t.nextWaiter = node; + lastWaiter = node; + return node; + } + + /** + * Removes and transfers nodes until hit non-cancelled one or + * null. Split out from signal in part to encourage compilers + * to inline the case of no waiters. + * @param first (non-null) the first node on condition queue + */ + private void doSignal(Node first) { + do { + if ( (firstWaiter = first.nextWaiter) == null) + lastWaiter = null; + first.nextWaiter = null; + } while (!transferForSignal(first) && + (first = firstWaiter) != null); + } + + /** + * Removes and transfers all nodes. + * @param first (non-null) the first node on condition queue + */ + private void doSignalAll(Node first) { + lastWaiter = firstWaiter = null; + do { + Node next = first.nextWaiter; + first.nextWaiter = null; + transferForSignal(first); + first = next; + } while (first != null); + } + + /** + * Returns true if given node is on this condition queue. + * Call only when holding lock. + */ + private boolean isOnConditionQueue(Node node) { + return node.next != null || node == lastWaiter; + } + + /** + * Unlinks a cancelled waiter node from condition queue. This + * is called when cancellation occurred during condition wait, + * not lock wait, and is called only after lock has been + * re-acquired by a cancelled waiter and the node is not known + * to already have been dequeued. It is needed to avoid + * garbage retention in the absence of signals. So even though + * it may require a full traversal, it comes into play only + * when timeouts or cancellations occur in the absence of + * signals. + */ + private void unlinkCancelledWaiter(Node node) { + Node t = firstWaiter; + Node trail = null; + while (t != null) { + if (t == node) { + Node next = t.nextWaiter; + if (trail == null) + firstWaiter = next; + else + trail.nextWaiter = next; + if (lastWaiter == node) + lastWaiter = trail; + break; + } + trail = t; + t = t.nextWaiter; + } + } + + // public methods + + /** + * Moves the longest-waiting thread, if one exists, from the + * wait queue for this condition to the wait queue for the + * owning lock. + * + * @throws IllegalMonitorStateException if {@link #isHeldExclusively} + * returns {@code false} + */ + public final void signal() { + if (!isHeldExclusively()) + throw new IllegalMonitorStateException(); + Node first = firstWaiter; + if (first != null) + doSignal(first); + } + + /** + * Moves all threads from the wait queue for this condition to + * the wait queue for the owning lock. + * + * @throws IllegalMonitorStateException if {@link #isHeldExclusively} + * returns {@code false} + */ + public final void signalAll() { + if (!isHeldExclusively()) + throw new IllegalMonitorStateException(); + Node first = firstWaiter; + if (first != null) + doSignalAll(first); + } + + /** + * Implements uninterruptible condition wait. + * <ol> + * <li> Save lock state returned by {@link #getState} + * <li> Invoke {@link #release} with + * saved state as argument, throwing + * IllegalMonitorStateException if it fails. + * <li> Block until signalled + * <li> Reacquire by invoking specialized version of + * {@link #acquire} with saved state as argument. + * </ol> + */ + public final void awaitUninterruptibly() { + Node node = addConditionWaiter(); + int savedState = fullyRelease(node); + boolean interrupted = false; + while (!isOnSyncQueue(node)) { + LockSupport.park(this); + if (Thread.interrupted()) + interrupted = true; + } + if (acquireQueued(node, savedState) || interrupted) + selfInterrupt(); + } + + /* + * For interruptible waits, we need to track whether to throw + * InterruptedException, if interrupted while blocked on + * condition, versus reinterrupt current thread, if + * interrupted while blocked waiting to re-acquire. + */ + + /** Mode meaning to reinterrupt on exit from wait */ + private static final int REINTERRUPT = 1; + /** Mode meaning to throw InterruptedException on exit from wait */ + private static final int THROW_IE = -1; + + /** + * Checks for interrupt, returning THROW_IE if interrupted + * before signalled, REINTERRUPT if after signalled, or + * 0 if not interrupted. + */ + private int checkInterruptWhileWaiting(Node node) { + return (Thread.interrupted()) ? + ((transferAfterCancelledWait(node))? THROW_IE : REINTERRUPT) : + 0; + } + + /** + * Throws InterruptedException, reinterrupts current thread, or + * does nothing, depending on mode. + */ + private void reportInterruptAfterWait(int interruptMode) + throws InterruptedException { + if (interruptMode == THROW_IE) + throw new InterruptedException(); + else if (interruptMode == REINTERRUPT) + selfInterrupt(); + } + + /** + * Implements interruptible condition wait. + * <ol> + * <li> If current thread is interrupted, throw InterruptedException + * <li> Save lock state returned by {@link #getState} + * <li> Invoke {@link #release} with + * saved state as argument, throwing + * IllegalMonitorStateException if it fails. + * <li> Block until signalled or interrupted + * <li> Reacquire by invoking specialized version of + * {@link #acquire} with saved state as argument. + * <li> If interrupted while blocked in step 4, throw exception + * </ol> + */ + public final void await() throws InterruptedException { + if (Thread.interrupted()) + throw new InterruptedException(); + Node node = addConditionWaiter(); + int savedState = fullyRelease(node); + int interruptMode = 0; + while (!isOnSyncQueue(node)) { + LockSupport.park(this); + if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) + break; + } + if (acquireQueued(node, savedState) && interruptMode != THROW_IE) + interruptMode = REINTERRUPT; + if (isOnConditionQueue(node)) + unlinkCancelledWaiter(node); + if (interruptMode != 0) + reportInterruptAfterWait(interruptMode); + } + + /** + * Implements timed condition wait. + * <ol> + * <li> If current thread is interrupted, throw InterruptedException + * <li> Save lock state returned by {@link #getState} + * <li> Invoke {@link #release} with + * saved state as argument, throwing + * IllegalMonitorStateException if it fails. + * <li> Block until signalled, interrupted, or timed out + * <li> Reacquire by invoking specialized version of + * {@link #acquire} with saved state as argument. + * <li> If interrupted while blocked in step 4, throw InterruptedException + * </ol> + */ + public final long awaitNanos(long nanosTimeout) throws InterruptedException { + if (Thread.interrupted()) + throw new InterruptedException(); + Node node = addConditionWaiter(); + int savedState = fullyRelease(node); + long lastTime = System.nanoTime(); + int interruptMode = 0; + while (!isOnSyncQueue(node)) { + if (nanosTimeout <= 0L) { + transferAfterCancelledWait(node); + break; + } + LockSupport.parkNanos(this, nanosTimeout); + if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) + break; + + long now = System.nanoTime(); + nanosTimeout -= now - lastTime; + lastTime = now; + } + if (acquireQueued(node, savedState) && interruptMode != THROW_IE) + interruptMode = REINTERRUPT; + if (isOnConditionQueue(node)) + unlinkCancelledWaiter(node); + if (interruptMode != 0) + reportInterruptAfterWait(interruptMode); + return nanosTimeout - (System.nanoTime() - lastTime); + } + + /** + * Implements absolute timed condition wait. + * <ol> + * <li> If current thread is interrupted, throw InterruptedException + * <li> Save lock state returned by {@link #getState} + * <li> Invoke {@link #release} with + * saved state as argument, throwing + * IllegalMonitorStateException if it fails. + * <li> Block until signalled, interrupted, or timed out + * <li> Reacquire by invoking specialized version of + * {@link #acquire} with saved state as argument. + * <li> If interrupted while blocked in step 4, throw InterruptedException + * <li> If timed out while blocked in step 4, return false, else true + * </ol> + */ + public final boolean awaitUntil(Date deadline) throws InterruptedException { + if (deadline == null) + throw new NullPointerException(); + long abstime = deadline.getTime(); + if (Thread.interrupted()) + throw new InterruptedException(); + Node node = addConditionWaiter(); + int savedState = fullyRelease(node); + boolean timedout = false; + int interruptMode = 0; + while (!isOnSyncQueue(node)) { + if (System.currentTimeMillis() > abstime) { + timedout = transferAfterCancelledWait(node); + break; + } + LockSupport.parkUntil(this, abstime); + if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) + break; + } + if (acquireQueued(node, savedState) && interruptMode != THROW_IE) + interruptMode = REINTERRUPT; + if (isOnConditionQueue(node)) + unlinkCancelledWaiter(node); + if (interruptMode != 0) + reportInterruptAfterWait(interruptMode); + return !timedout; + } + + /** + * Implements timed condition wait. + * <ol> + * <li> If current thread is interrupted, throw InterruptedException + * <li> Save lock state returned by {@link #getState} + * <li> Invoke {@link #release} with + * saved state as argument, throwing + * IllegalMonitorStateException if it fails. + * <li> Block until signalled, interrupted, or timed out + * <li> Reacquire by invoking specialized version of + * {@link #acquire} with saved state as argument. + * <li> If interrupted while blocked in step 4, throw InterruptedException + * <li> If timed out while blocked in step 4, return false, else true + * </ol> + */ + public final boolean await(long time, TimeUnit unit) throws InterruptedException { + if (unit == null) + throw new NullPointerException(); + long nanosTimeout = unit.toNanos(time); + if (Thread.interrupted()) + throw new InterruptedException(); + Node node = addConditionWaiter(); + int savedState = fullyRelease(node); + long lastTime = System.nanoTime(); + boolean timedout = false; + int interruptMode = 0; + while (!isOnSyncQueue(node)) { + if (nanosTimeout <= 0L) { + timedout = transferAfterCancelledWait(node); + break; + } + LockSupport.parkNanos(this, nanosTimeout); + if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) + break; + long now = System.nanoTime(); + nanosTimeout -= now - lastTime; + lastTime = now; + } + if (acquireQueued(node, savedState) && interruptMode != THROW_IE) + interruptMode = REINTERRUPT; + if (isOnConditionQueue(node)) + unlinkCancelledWaiter(node); + if (interruptMode != 0) + reportInterruptAfterWait(interruptMode); + return !timedout; + } + + // support for instrumentation + + /** + * Returns true if this condition was created by the given + * synchronization object. + * + * @return {@code true} if owned + */ + final boolean isOwnedBy(AbstractQueuedSynchronizer sync) { + return sync == AbstractQueuedSynchronizer.this; + } + + /** + * Queries whether any threads are waiting on this condition. + * Implements {@link AbstractQueuedSynchronizer#hasWaiters}. + * + * @return {@code true} if there are any waiting threads + * @throws IllegalMonitorStateException if {@link #isHeldExclusively} + * returns {@code false} + */ + protected final boolean hasWaiters() { + if (!isHeldExclusively()) + throw new IllegalMonitorStateException(); + for (Node w = firstWaiter; w != null; w = w.nextWaiter) { + if (w.waitStatus == Node.CONDITION) + return true; + } + return false; + } + + /** + * Returns an estimate of the number of threads waiting on + * this condition. + * Implements {@link AbstractQueuedSynchronizer#getWaitQueueLength}. + * + * @return the estimated number of waiting threads + * @throws IllegalMonitorStateException if {@link #isHeldExclusively} + * returns {@code false} + */ + protected final int getWaitQueueLength() { + if (!isHeldExclusively()) + throw new IllegalMonitorStateException(); + int n = 0; + for (Node w = firstWaiter; w != null; w = w.nextWaiter) { + if (w.waitStatus == Node.CONDITION) + ++n; + } + return n; + } + + /** + * Returns a collection containing those threads that may be + * waiting on this Condition. + * Implements {@link AbstractQueuedSynchronizer#getWaitingThreads}. + * + * @return the collection of threads + * @throws IllegalMonitorStateException if {@link #isHeldExclusively} + * returns {@code false} + */ + protected final Collection<Thread> getWaitingThreads() { + if (!isHeldExclusively()) + throw new IllegalMonitorStateException(); + ArrayList<Thread> list = new ArrayList<Thread>(); + for (Node w = firstWaiter; w != null; w = w.nextWaiter) { + if (w.waitStatus == Node.CONDITION) { + Thread t = w.thread; + if (t != null) + list.add(t); + } + } + return list; + } + } + + /** + * Setup to support compareAndSet. We need to natively implement + * this here: For the sake of permitting future enhancements, we + * cannot explicitly subclass AtomicInteger, which would be + * efficient and useful otherwise. So, as the lesser of evils, we + * natively implement using hotspot intrinsics API. And while we + * are at it, we do the same for other CASable fields (which could + * otherwise be done with atomic field updaters). + */ + private static final Unsafe unsafe = Unsafe.getUnsafe(); + private static final long stateOffset; + private static final long headOffset; + private static final long tailOffset; + private static final long waitStatusOffset; + + static { + try { + stateOffset = unsafe.objectFieldOffset + (AbstractQueuedSynchronizer.class.getDeclaredField("state")); + headOffset = unsafe.objectFieldOffset + (AbstractQueuedSynchronizer.class.getDeclaredField("head")); + tailOffset = unsafe.objectFieldOffset + (AbstractQueuedSynchronizer.class.getDeclaredField("tail")); + waitStatusOffset = unsafe.objectFieldOffset + (Node.class.getDeclaredField("waitStatus")); + + } catch (Exception ex) { throw new Error(ex); } + } + + /** + * CAS head field. Used only by enq + */ + private final boolean compareAndSetHead(Node update) { + return unsafe.compareAndSwapObject(this, headOffset, null, update); + } + + /** + * CAS tail field. Used only by enq + */ + private final boolean compareAndSetTail(Node expect, Node update) { + return unsafe.compareAndSwapObject(this, tailOffset, expect, update); + } + + /** + * CAS waitStatus field of a node. + */ + private final static boolean compareAndSetWaitStatus(Node node, + int expect, + int update) { + return unsafe.compareAndSwapInt(node, waitStatusOffset, + expect, update); + } +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/locks/Condition.java b/libjava/classpath/external/jsr166/java/util/concurrent/locks/Condition.java new file mode 100644 index 000000000..5d24128e1 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/locks/Condition.java @@ -0,0 +1,435 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent.locks; +import java.util.concurrent.*; +import java.util.Date; + +/** + * {@code Condition} factors out the {@code Object} monitor + * methods ({@link Object#wait() wait}, {@link Object#notify notify} + * and {@link Object#notifyAll notifyAll}) into distinct objects to + * give the effect of having multiple wait-sets per object, by + * combining them with the use of arbitrary {@link Lock} implementations. + * Where a {@code Lock} replaces the use of {@code synchronized} methods + * and statements, a {@code Condition} replaces the use of the Object + * monitor methods. + * + * <p>Conditions (also known as <em>condition queues</em> or + * <em>condition variables</em>) provide a means for one thread to + * suspend execution (to "wait") until notified by another + * thread that some state condition may now be true. Because access + * to this shared state information occurs in different threads, it + * must be protected, so a lock of some form is associated with the + * condition. The key property that waiting for a condition provides + * is that it <em>atomically</em> releases the associated lock and + * suspends the current thread, just like {@code Object.wait}. + * + * <p>A {@code Condition} instance is intrinsically bound to a lock. + * To obtain a {@code Condition} instance for a particular {@link Lock} + * instance use its {@link Lock#newCondition newCondition()} method. + * + * <p>As an example, suppose we have a bounded buffer which supports + * {@code put} and {@code take} methods. If a + * {@code take} is attempted on an empty buffer, then the thread will block + * until an item becomes available; if a {@code put} is attempted on a + * full buffer, then the thread will block until a space becomes available. + * We would like to keep waiting {@code put} threads and {@code take} + * threads in separate wait-sets so that we can use the optimization of + * only notifying a single thread at a time when items or spaces become + * available in the buffer. This can be achieved using two + * {@link Condition} instances. + * <pre> + * class BoundedBuffer { + * <b>final Lock lock = new ReentrantLock();</b> + * final Condition notFull = <b>lock.newCondition(); </b> + * final Condition notEmpty = <b>lock.newCondition(); </b> + * + * final Object[] items = new Object[100]; + * int putptr, takeptr, count; + * + * public void put(Object x) throws InterruptedException { + * <b>lock.lock(); + * try {</b> + * while (count == items.length) + * <b>notFull.await();</b> + * items[putptr] = x; + * if (++putptr == items.length) putptr = 0; + * ++count; + * <b>notEmpty.signal();</b> + * <b>} finally { + * lock.unlock(); + * }</b> + * } + * + * public Object take() throws InterruptedException { + * <b>lock.lock(); + * try {</b> + * while (count == 0) + * <b>notEmpty.await();</b> + * Object x = items[takeptr]; + * if (++takeptr == items.length) takeptr = 0; + * --count; + * <b>notFull.signal();</b> + * return x; + * <b>} finally { + * lock.unlock(); + * }</b> + * } + * } + * </pre> + * + * (The {@link java.util.concurrent.ArrayBlockingQueue} class provides + * this functionality, so there is no reason to implement this + * sample usage class.) + * + * <p>A {@code Condition} implementation can provide behavior and semantics + * that is + * different from that of the {@code Object} monitor methods, such as + * guaranteed ordering for notifications, or not requiring a lock to be held + * when performing notifications. + * If an implementation provides such specialized semantics then the + * implementation must document those semantics. + * + * <p>Note that {@code Condition} instances are just normal objects and can + * themselves be used as the target in a {@code synchronized} statement, + * and can have their own monitor {@link Object#wait wait} and + * {@link Object#notify notification} methods invoked. + * Acquiring the monitor lock of a {@code Condition} instance, or using its + * monitor methods, has no specified relationship with acquiring the + * {@link Lock} associated with that {@code Condition} or the use of its + * {@linkplain #await waiting} and {@linkplain #signal signalling} methods. + * It is recommended that to avoid confusion you never use {@code Condition} + * instances in this way, except perhaps within their own implementation. + * + * <p>Except where noted, passing a {@code null} value for any parameter + * will result in a {@link NullPointerException} being thrown. + * + * <h3>Implementation Considerations</h3> + * + * <p>When waiting upon a {@code Condition}, a "<em>spurious + * wakeup</em>" is permitted to occur, in + * general, as a concession to the underlying platform semantics. + * This has little practical impact on most application programs as a + * {@code Condition} should always be waited upon in a loop, testing + * the state predicate that is being waited for. An implementation is + * free to remove the possibility of spurious wakeups but it is + * recommended that applications programmers always assume that they can + * occur and so always wait in a loop. + * + * <p>The three forms of condition waiting + * (interruptible, non-interruptible, and timed) may differ in their ease of + * implementation on some platforms and in their performance characteristics. + * In particular, it may be difficult to provide these features and maintain + * specific semantics such as ordering guarantees. + * Further, the ability to interrupt the actual suspension of the thread may + * not always be feasible to implement on all platforms. + * + * <p>Consequently, an implementation is not required to define exactly the + * same guarantees or semantics for all three forms of waiting, nor is it + * required to support interruption of the actual suspension of the thread. + * + * <p>An implementation is required to + * clearly document the semantics and guarantees provided by each of the + * waiting methods, and when an implementation does support interruption of + * thread suspension then it must obey the interruption semantics as defined + * in this interface. + * + * <p>As interruption generally implies cancellation, and checks for + * interruption are often infrequent, an implementation can favor responding + * to an interrupt over normal method return. This is true even if it can be + * shown that the interrupt occurred after another action may have unblocked + * the thread. An implementation should document this behavior. + * + * @since 1.5 + * @author Doug Lea + */ +public interface Condition { + + /** + * Causes the current thread to wait until it is signalled or + * {@linkplain Thread#interrupt interrupted}. + * + * <p>The lock associated with this {@code Condition} is atomically + * released and the current thread becomes disabled for thread scheduling + * purposes and lies dormant until <em>one</em> of four things happens: + * <ul> + * <li>Some other thread invokes the {@link #signal} method for this + * {@code Condition} and the current thread happens to be chosen as the + * thread to be awakened; or + * <li>Some other thread invokes the {@link #signalAll} method for this + * {@code Condition}; or + * <li>Some other thread {@linkplain Thread#interrupt interrupts} the + * current thread, and interruption of thread suspension is supported; or + * <li>A "<em>spurious wakeup</em>" occurs. + * </ul> + * + * <p>In all cases, before this method can return the current thread must + * re-acquire the lock associated with this condition. When the + * thread returns it is <em>guaranteed</em> to hold this lock. + * + * <p>If the current thread: + * <ul> + * <li>has its interrupted status set on entry to this method; or + * <li>is {@linkplain Thread#interrupt interrupted} while waiting + * and interruption of thread suspension is supported, + * </ul> + * then {@link InterruptedException} is thrown and the current thread's + * interrupted status is cleared. It is not specified, in the first + * case, whether or not the test for interruption occurs before the lock + * is released. + * + * <p><b>Implementation Considerations</b> + * + * <p>The current thread is assumed to hold the lock associated with this + * {@code Condition} when this method is called. + * It is up to the implementation to determine if this is + * the case and if not, how to respond. Typically, an exception will be + * thrown (such as {@link IllegalMonitorStateException}) and the + * implementation must document that fact. + * + * <p>An implementation can favor responding to an interrupt over normal + * method return in response to a signal. In that case the implementation + * must ensure that the signal is redirected to another waiting thread, if + * there is one. + * + * @throws InterruptedException if the current thread is interrupted + * (and interruption of thread suspension is supported) + */ + void await() throws InterruptedException; + + /** + * Causes the current thread to wait until it is signalled. + * + * <p>The lock associated with this condition is atomically + * released and the current thread becomes disabled for thread scheduling + * purposes and lies dormant until <em>one</em> of three things happens: + * <ul> + * <li>Some other thread invokes the {@link #signal} method for this + * {@code Condition} and the current thread happens to be chosen as the + * thread to be awakened; or + * <li>Some other thread invokes the {@link #signalAll} method for this + * {@code Condition}; or + * <li>A "<em>spurious wakeup</em>" occurs. + * </ul> + * + * <p>In all cases, before this method can return the current thread must + * re-acquire the lock associated with this condition. When the + * thread returns it is <em>guaranteed</em> to hold this lock. + * + * <p>If the current thread's interrupted status is set when it enters + * this method, or it is {@linkplain Thread#interrupt interrupted} + * while waiting, it will continue to wait until signalled. When it finally + * returns from this method its interrupted status will still + * be set. + * + * <p><b>Implementation Considerations</b> + * + * <p>The current thread is assumed to hold the lock associated with this + * {@code Condition} when this method is called. + * It is up to the implementation to determine if this is + * the case and if not, how to respond. Typically, an exception will be + * thrown (such as {@link IllegalMonitorStateException}) and the + * implementation must document that fact. + */ + void awaitUninterruptibly(); + + /** + * Causes the current thread to wait until it is signalled or interrupted, + * or the specified waiting time elapses. + * + * <p>The lock associated with this condition is atomically + * released and the current thread becomes disabled for thread scheduling + * purposes and lies dormant until <em>one</em> of five things happens: + * <ul> + * <li>Some other thread invokes the {@link #signal} method for this + * {@code Condition} and the current thread happens to be chosen as the + * thread to be awakened; or + * <li>Some other thread invokes the {@link #signalAll} method for this + * {@code Condition}; or + * <li>Some other thread {@linkplain Thread#interrupt interrupts} the + * current thread, and interruption of thread suspension is supported; or + * <li>The specified waiting time elapses; or + * <li>A "<em>spurious wakeup</em>" occurs. + * </ul> + * + * <p>In all cases, before this method can return the current thread must + * re-acquire the lock associated with this condition. When the + * thread returns it is <em>guaranteed</em> to hold this lock. + * + * <p>If the current thread: + * <ul> + * <li>has its interrupted status set on entry to this method; or + * <li>is {@linkplain Thread#interrupt interrupted} while waiting + * and interruption of thread suspension is supported, + * </ul> + * then {@link InterruptedException} is thrown and the current thread's + * interrupted status is cleared. It is not specified, in the first + * case, whether or not the test for interruption occurs before the lock + * is released. + * + * <p>The method returns an estimate of the number of nanoseconds + * remaining to wait given the supplied {@code nanosTimeout} + * value upon return, or a value less than or equal to zero if it + * timed out. This value can be used to determine whether and how + * long to re-wait in cases where the wait returns but an awaited + * condition still does not hold. Typical uses of this method take + * the following form: + * + * <pre> + * synchronized boolean aMethod(long timeout, TimeUnit unit) { + * long nanosTimeout = unit.toNanos(timeout); + * while (!conditionBeingWaitedFor) { + * if (nanosTimeout > 0) + * nanosTimeout = theCondition.awaitNanos(nanosTimeout); + * else + * return false; + * } + * // ... + * } + * </pre> + * + * <p> Design note: This method requires a nanosecond argument so + * as to avoid truncation errors in reporting remaining times. + * Such precision loss would make it difficult for programmers to + * ensure that total waiting times are not systematically shorter + * than specified when re-waits occur. + * + * <p><b>Implementation Considerations</b> + * + * <p>The current thread is assumed to hold the lock associated with this + * {@code Condition} when this method is called. + * It is up to the implementation to determine if this is + * the case and if not, how to respond. Typically, an exception will be + * thrown (such as {@link IllegalMonitorStateException}) and the + * implementation must document that fact. + * + * <p>An implementation can favor responding to an interrupt over normal + * method return in response to a signal, or over indicating the elapse + * of the specified waiting time. In either case the implementation + * must ensure that the signal is redirected to another waiting thread, if + * there is one. + * + * @param nanosTimeout the maximum time to wait, in nanoseconds + * @return an estimate of the {@code nanosTimeout} value minus + * the time spent waiting upon return from this method. + * A positive value may be used as the argument to a + * subsequent call to this method to finish waiting out + * the desired time. A value less than or equal to zero + * indicates that no time remains. + * @throws InterruptedException if the current thread is interrupted + * (and interruption of thread suspension is supported) + */ + long awaitNanos(long nanosTimeout) throws InterruptedException; + + /** + * Causes the current thread to wait until it is signalled or interrupted, + * or the specified waiting time elapses. This method is behaviorally + * equivalent to:<br> + * <pre> + * awaitNanos(unit.toNanos(time)) > 0 + * </pre> + * @param time the maximum time to wait + * @param unit the time unit of the {@code time} argument + * @return {@code false} if the waiting time detectably elapsed + * before return from the method, else {@code true} + * @throws InterruptedException if the current thread is interrupted + * (and interruption of thread suspension is supported) + */ + boolean await(long time, TimeUnit unit) throws InterruptedException; + + /** + * Causes the current thread to wait until it is signalled or interrupted, + * or the specified deadline elapses. + * + * <p>The lock associated with this condition is atomically + * released and the current thread becomes disabled for thread scheduling + * purposes and lies dormant until <em>one</em> of five things happens: + * <ul> + * <li>Some other thread invokes the {@link #signal} method for this + * {@code Condition} and the current thread happens to be chosen as the + * thread to be awakened; or + * <li>Some other thread invokes the {@link #signalAll} method for this + * {@code Condition}; or + * <li>Some other thread {@linkplain Thread#interrupt interrupts} the + * current thread, and interruption of thread suspension is supported; or + * <li>The specified deadline elapses; or + * <li>A "<em>spurious wakeup</em>" occurs. + * </ul> + * + * <p>In all cases, before this method can return the current thread must + * re-acquire the lock associated with this condition. When the + * thread returns it is <em>guaranteed</em> to hold this lock. + * + * + * <p>If the current thread: + * <ul> + * <li>has its interrupted status set on entry to this method; or + * <li>is {@linkplain Thread#interrupt interrupted} while waiting + * and interruption of thread suspension is supported, + * </ul> + * then {@link InterruptedException} is thrown and the current thread's + * interrupted status is cleared. It is not specified, in the first + * case, whether or not the test for interruption occurs before the lock + * is released. + * + * + * <p>The return value indicates whether the deadline has elapsed, + * which can be used as follows: + * <pre> + * synchronized boolean aMethod(Date deadline) { + * boolean stillWaiting = true; + * while (!conditionBeingWaitedFor) { + * if (stillWaiting) + * stillWaiting = theCondition.awaitUntil(deadline); + * else + * return false; + * } + * // ... + * } + * </pre> + * + * <p><b>Implementation Considerations</b> + * + * <p>The current thread is assumed to hold the lock associated with this + * {@code Condition} when this method is called. + * It is up to the implementation to determine if this is + * the case and if not, how to respond. Typically, an exception will be + * thrown (such as {@link IllegalMonitorStateException}) and the + * implementation must document that fact. + * + * <p>An implementation can favor responding to an interrupt over normal + * method return in response to a signal, or over indicating the passing + * of the specified deadline. In either case the implementation + * must ensure that the signal is redirected to another waiting thread, if + * there is one. + * + * @param deadline the absolute time to wait until + * @return {@code false} if the deadline has elapsed upon return, else + * {@code true} + * @throws InterruptedException if the current thread is interrupted + * (and interruption of thread suspension is supported) + */ + boolean awaitUntil(Date deadline) throws InterruptedException; + + /** + * Wakes up one waiting thread. + * + * <p>If any threads are waiting on this condition then one + * is selected for waking up. That thread must then re-acquire the + * lock before returning from {@code await}. + */ + void signal(); + + /** + * Wakes up all waiting threads. + * + * <p>If any threads are waiting on this condition then they are + * all woken up. Each thread must re-acquire the lock before it can + * return from {@code await}. + */ + void signalAll(); +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/locks/Lock.java b/libjava/classpath/external/jsr166/java/util/concurrent/locks/Lock.java new file mode 100644 index 000000000..4b9abd665 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/locks/Lock.java @@ -0,0 +1,327 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent.locks; +import java.util.concurrent.TimeUnit; + +/** + * {@code Lock} implementations provide more extensive locking + * operations than can be obtained using {@code synchronized} methods + * and statements. They allow more flexible structuring, may have + * quite different properties, and may support multiple associated + * {@link Condition} objects. + * + * <p>A lock is a tool for controlling access to a shared resource by + * multiple threads. Commonly, a lock provides exclusive access to a + * shared resource: only one thread at a time can acquire the lock and + * all access to the shared resource requires that the lock be + * acquired first. However, some locks may allow concurrent access to + * a shared resource, such as the read lock of a {@link ReadWriteLock}. + * + * <p>The use of {@code synchronized} methods or statements provides + * access to the implicit monitor lock associated with every object, but + * forces all lock acquisition and release to occur in a block-structured way: + * when multiple locks are acquired they must be released in the opposite + * order, and all locks must be released in the same lexical scope in which + * they were acquired. + * + * <p>While the scoping mechanism for {@code synchronized} methods + * and statements makes it much easier to program with monitor locks, + * and helps avoid many common programming errors involving locks, + * there are occasions where you need to work with locks in a more + * flexible way. For example, some algorithms for traversing + * concurrently accessed data structures require the use of + * "hand-over-hand" or "chain locking": you + * acquire the lock of node A, then node B, then release A and acquire + * C, then release B and acquire D and so on. Implementations of the + * {@code Lock} interface enable the use of such techniques by + * allowing a lock to be acquired and released in different scopes, + * and allowing multiple locks to be acquired and released in any + * order. + * + * <p>With this increased flexibility comes additional + * responsibility. The absence of block-structured locking removes the + * automatic release of locks that occurs with {@code synchronized} + * methods and statements. In most cases, the following idiom + * should be used: + * + * <pre><tt> Lock l = ...; + * l.lock(); + * try { + * // access the resource protected by this lock + * } finally { + * l.unlock(); + * } + * </tt></pre> + * + * When locking and unlocking occur in different scopes, care must be + * taken to ensure that all code that is executed while the lock is + * held is protected by try-finally or try-catch to ensure that the + * lock is released when necessary. + * + * <p>{@code Lock} implementations provide additional functionality + * over the use of {@code synchronized} methods and statements by + * providing a non-blocking attempt to acquire a lock ({@link + * #tryLock()}), an attempt to acquire the lock that can be + * interrupted ({@link #lockInterruptibly}, and an attempt to acquire + * the lock that can timeout ({@link #tryLock(long, TimeUnit)}). + * + * <p>A {@code Lock} class can also provide behavior and semantics + * that is quite different from that of the implicit monitor lock, + * such as guaranteed ordering, non-reentrant usage, or deadlock + * detection. If an implementation provides such specialized semantics + * then the implementation must document those semantics. + * + * <p>Note that {@code Lock} instances are just normal objects and can + * themselves be used as the target in a {@code synchronized} statement. + * Acquiring the + * monitor lock of a {@code Lock} instance has no specified relationship + * with invoking any of the {@link #lock} methods of that instance. + * It is recommended that to avoid confusion you never use {@code Lock} + * instances in this way, except within their own implementation. + * + * <p>Except where noted, passing a {@code null} value for any + * parameter will result in a {@link NullPointerException} being + * thrown. + * + * <h3>Memory Synchronization</h3> + * + * <p>All {@code Lock} implementations <em>must</em> enforce the same + * memory synchronization semantics as provided by the built-in monitor + * lock, as described in <a href="http://java.sun.com/docs/books/jls/"> + * The Java Language Specification, Third Edition (17.4 Memory Model)</a>: + * <ul> + * <li>A successful {@code lock} operation has the same memory + * synchronization effects as a successful <em>Lock</em> action. + * <li>A successful {@code unlock} operation has the same + * memory synchronization effects as a successful <em>Unlock</em> action. + * </ul> + * + * Unsuccessful locking and unlocking operations, and reentrant + * locking/unlocking operations, do not require any memory + * synchronization effects. + * + * <h3>Implementation Considerations</h3> + * + * <p> The three forms of lock acquisition (interruptible, + * non-interruptible, and timed) may differ in their performance + * characteristics, ordering guarantees, or other implementation + * qualities. Further, the ability to interrupt the <em>ongoing</em> + * acquisition of a lock may not be available in a given {@code Lock} + * class. Consequently, an implementation is not required to define + * exactly the same guarantees or semantics for all three forms of + * lock acquisition, nor is it required to support interruption of an + * ongoing lock acquisition. An implementation is required to clearly + * document the semantics and guarantees provided by each of the + * locking methods. It must also obey the interruption semantics as + * defined in this interface, to the extent that interruption of lock + * acquisition is supported: which is either totally, or only on + * method entry. + * + * <p>As interruption generally implies cancellation, and checks for + * interruption are often infrequent, an implementation can favor responding + * to an interrupt over normal method return. This is true even if it can be + * shown that the interrupt occurred after another action may have unblocked + * the thread. An implementation should document this behavior. + * + * @see ReentrantLock + * @see Condition + * @see ReadWriteLock + * + * @since 1.5 + * @author Doug Lea + */ +public interface Lock { + + /** + * Acquires the lock. + * + * <p>If the lock is not available then the current thread becomes + * disabled for thread scheduling purposes and lies dormant until the + * lock has been acquired. + * + * <p><b>Implementation Considerations</b> + * + * <p>A {@code Lock} implementation may be able to detect erroneous use + * of the lock, such as an invocation that would cause deadlock, and + * may throw an (unchecked) exception in such circumstances. The + * circumstances and the exception type must be documented by that + * {@code Lock} implementation. + */ + void lock(); + + /** + * Acquires the lock unless the current thread is + * {@linkplain Thread#interrupt interrupted}. + * + * <p>Acquires the lock if it is available and returns immediately. + * + * <p>If the lock is not available then the current thread becomes + * disabled for thread scheduling purposes and lies dormant until + * one of two things happens: + * + * <ul> + * <li>The lock is acquired by the current thread; or + * <li>Some other thread {@linkplain Thread#interrupt interrupts} the + * current thread, and interruption of lock acquisition is supported. + * </ul> + * + * <p>If the current thread: + * <ul> + * <li>has its interrupted status set on entry to this method; or + * <li>is {@linkplain Thread#interrupt interrupted} while acquiring the + * lock, and interruption of lock acquisition is supported, + * </ul> + * then {@link InterruptedException} is thrown and the current thread's + * interrupted status is cleared. + * + * <p><b>Implementation Considerations</b> + * + * <p>The ability to interrupt a lock acquisition in some + * implementations may not be possible, and if possible may be an + * expensive operation. The programmer should be aware that this + * may be the case. An implementation should document when this is + * the case. + * + * <p>An implementation can favor responding to an interrupt over + * normal method return. + * + * <p>A {@code Lock} implementation may be able to detect + * erroneous use of the lock, such as an invocation that would + * cause deadlock, and may throw an (unchecked) exception in such + * circumstances. The circumstances and the exception type must + * be documented by that {@code Lock} implementation. + * + * @throws InterruptedException if the current thread is + * interrupted while acquiring the lock (and interruption + * of lock acquisition is supported). + */ + void lockInterruptibly() throws InterruptedException; + + /** + * Acquires the lock only if it is free at the time of invocation. + * + * <p>Acquires the lock if it is available and returns immediately + * with the value {@code true}. + * If the lock is not available then this method will return + * immediately with the value {@code false}. + * + * <p>A typical usage idiom for this method would be: + * <pre> + * Lock lock = ...; + * if (lock.tryLock()) { + * try { + * // manipulate protected state + * } finally { + * lock.unlock(); + * } + * } else { + * // perform alternative actions + * } + * </pre> + * This usage ensures that the lock is unlocked if it was acquired, and + * doesn't try to unlock if the lock was not acquired. + * + * @return {@code true} if the lock was acquired and + * {@code false} otherwise + */ + boolean tryLock(); + + /** + * Acquires the lock if it is free within the given waiting time and the + * current thread has not been {@linkplain Thread#interrupt interrupted}. + * + * <p>If the lock is available this method returns immediately + * with the value {@code true}. + * If the lock is not available then + * the current thread becomes disabled for thread scheduling + * purposes and lies dormant until one of three things happens: + * <ul> + * <li>The lock is acquired by the current thread; or + * <li>Some other thread {@linkplain Thread#interrupt interrupts} the + * current thread, and interruption of lock acquisition is supported; or + * <li>The specified waiting time elapses + * </ul> + * + * <p>If the lock is acquired then the value {@code true} is returned. + * + * <p>If the current thread: + * <ul> + * <li>has its interrupted status set on entry to this method; or + * <li>is {@linkplain Thread#interrupt interrupted} while acquiring + * the lock, and interruption of lock acquisition is supported, + * </ul> + * then {@link InterruptedException} is thrown and the current thread's + * interrupted status is cleared. + * + * <p>If the specified waiting time elapses then the value {@code false} + * is returned. + * If the time is + * less than or equal to zero, the method will not wait at all. + * + * <p><b>Implementation Considerations</b> + * + * <p>The ability to interrupt a lock acquisition in some implementations + * may not be possible, and if possible may + * be an expensive operation. + * The programmer should be aware that this may be the case. An + * implementation should document when this is the case. + * + * <p>An implementation can favor responding to an interrupt over normal + * method return, or reporting a timeout. + * + * <p>A {@code Lock} implementation may be able to detect + * erroneous use of the lock, such as an invocation that would cause + * deadlock, and may throw an (unchecked) exception in such circumstances. + * The circumstances and the exception type must be documented by that + * {@code Lock} implementation. + * + * @param time the maximum time to wait for the lock + * @param unit the time unit of the {@code time} argument + * @return {@code true} if the lock was acquired and {@code false} + * if the waiting time elapsed before the lock was acquired + * + * @throws InterruptedException if the current thread is interrupted + * while acquiring the lock (and interruption of lock + * acquisition is supported) + */ + boolean tryLock(long time, TimeUnit unit) throws InterruptedException; + + /** + * Releases the lock. + * + * <p><b>Implementation Considerations</b> + * + * <p>A {@code Lock} implementation will usually impose + * restrictions on which thread can release a lock (typically only the + * holder of the lock can release it) and may throw + * an (unchecked) exception if the restriction is violated. + * Any restrictions and the exception + * type must be documented by that {@code Lock} implementation. + */ + void unlock(); + + /** + * Returns a new {@link Condition} instance that is bound to this + * {@code Lock} instance. + * + * <p>Before waiting on the condition the lock must be held by the + * current thread. + * A call to {@link Condition#await()} will atomically release the lock + * before waiting and re-acquire the lock before the wait returns. + * + * <p><b>Implementation Considerations</b> + * + * <p>The exact operation of the {@link Condition} instance depends on + * the {@code Lock} implementation and must be documented by that + * implementation. + * + * @return A new {@link Condition} instance for this {@code Lock} instance + * @throws UnsupportedOperationException if this {@code Lock} + * implementation does not support conditions + */ + Condition newCondition(); +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/locks/LockSupport.java b/libjava/classpath/external/jsr166/java/util/concurrent/locks/LockSupport.java new file mode 100644 index 000000000..28728ae2b --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/locks/LockSupport.java @@ -0,0 +1,352 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent.locks; +import java.util.concurrent.*; +import sun.misc.Unsafe; + + +/** + * Basic thread blocking primitives for creating locks and other + * synchronization classes. + * + * <p>This class associates, with each thread that uses it, a permit + * (in the sense of the {@link java.util.concurrent.Semaphore + * Semaphore} class). A call to {@code park} will return immediately + * if the permit is available, consuming it in the process; otherwise + * it <em>may</em> block. A call to {@code unpark} makes the permit + * available, if it was not already available. (Unlike with Semaphores + * though, permits do not accumulate. There is at most one.) + * + * <p>Methods {@code park} and {@code unpark} provide efficient + * means of blocking and unblocking threads that do not encounter the + * problems that cause the deprecated methods {@code Thread.suspend} + * and {@code Thread.resume} to be unusable for such purposes: Races + * between one thread invoking {@code park} and another thread trying + * to {@code unpark} it will preserve liveness, due to the + * permit. Additionally, {@code park} will return if the caller's + * thread was interrupted, and timeout versions are supported. The + * {@code park} method may also return at any other time, for "no + * reason", so in general must be invoked within a loop that rechecks + * conditions upon return. In this sense {@code park} serves as an + * optimization of a "busy wait" that does not waste as much time + * spinning, but must be paired with an {@code unpark} to be + * effective. + * + * <p>The three forms of {@code park} each also support a + * {@code blocker} object parameter. This object is recorded while + * the thread is blocked to permit monitoring and diagnostic tools to + * identify the reasons that threads are blocked. (Such tools may + * access blockers using method {@link #getBlocker}.) The use of these + * forms rather than the original forms without this parameter is + * strongly encouraged. The normal argument to supply as a + * {@code blocker} within a lock implementation is {@code this}. + * + * <p>These methods are designed to be used as tools for creating + * higher-level synchronization utilities, and are not in themselves + * useful for most concurrency control applications. The {@code park} + * method is designed for use only in constructions of the form: + * <pre>while (!canProceed()) { ... LockSupport.park(this); }</pre> + * where neither {@code canProceed} nor any other actions prior to the + * call to {@code park} entail locking or blocking. Because only one + * permit is associated with each thread, any intermediary uses of + * {@code park} could interfere with its intended effects. + * + * <p><b>Sample Usage.</b> Here is a sketch of a first-in-first-out + * non-reentrant lock class: + * <pre>{@code + * class FIFOMutex { + * private final AtomicBoolean locked = new AtomicBoolean(false); + * private final Queue<Thread> waiters + * = new ConcurrentLinkedQueue<Thread>(); + * + * public void lock() { + * boolean wasInterrupted = false; + * Thread current = Thread.currentThread(); + * waiters.add(current); + * + * // Block while not first in queue or cannot acquire lock + * while (waiters.peek() != current || + * !locked.compareAndSet(false, true)) { + * LockSupport.park(this); + * if (Thread.interrupted()) // ignore interrupts while waiting + * wasInterrupted = true; + * } + * + * waiters.remove(); + * if (wasInterrupted) // reassert interrupt status on exit + * current.interrupt(); + * } + * + * public void unlock() { + * locked.set(false); + * LockSupport.unpark(waiters.peek()); + * } + * }}</pre> + */ + +public class LockSupport { + private LockSupport() {} // Cannot be instantiated. + + // Hotspot implementation via intrinsics API + private static final Unsafe unsafe = Unsafe.getUnsafe(); + private static final long parkBlockerOffset; + + static { + try { + parkBlockerOffset = unsafe.objectFieldOffset + (java.lang.Thread.class.getDeclaredField("parkBlocker")); + } catch (Exception ex) { throw new Error(ex); } + } + + private static void setBlocker(Thread t, Object arg) { + // Even though volatile, hotspot doesn't need a write barrier here. + unsafe.putObject(t, parkBlockerOffset, arg); + } + + /** + * Makes available the permit for the given thread, if it + * was not already available. If the thread was blocked on + * {@code park} then it will unblock. Otherwise, its next call + * to {@code park} is guaranteed not to block. This operation + * is not guaranteed to have any effect at all if the given + * thread has not been started. + * + * @param thread the thread to unpark, or {@code null}, in which case + * this operation has no effect + */ + public static void unpark(Thread thread) { + if (thread != null) + unsafe.unpark(thread); + } + + /** + * Disables the current thread for thread scheduling purposes unless the + * permit is available. + * + * <p>If the permit is available then it is consumed and the call returns + * immediately; otherwise + * the current thread becomes disabled for thread scheduling + * purposes and lies dormant until one of three things happens: + * + * <ul> + * <li>Some other thread invokes {@link #unpark unpark} with the + * current thread as the target; or + * + * <li>Some other thread {@linkplain Thread#interrupt interrupts} + * the current thread; or + * + * <li>The call spuriously (that is, for no reason) returns. + * </ul> + * + * <p>This method does <em>not</em> report which of these caused the + * method to return. Callers should re-check the conditions which caused + * the thread to park in the first place. Callers may also determine, + * for example, the interrupt status of the thread upon return. + * + * @param blocker the synchronization object responsible for this + * thread parking + * @since 1.6 + */ + public static void park(Object blocker) { + Thread t = Thread.currentThread(); + setBlocker(t, blocker); + unsafe.park(false, 0L); + setBlocker(t, null); + } + + /** + * Disables the current thread for thread scheduling purposes, for up to + * the specified waiting time, unless the permit is available. + * + * <p>If the permit is available then it is consumed and the call + * returns immediately; otherwise the current thread becomes disabled + * for thread scheduling purposes and lies dormant until one of four + * things happens: + * + * <ul> + * <li>Some other thread invokes {@link #unpark unpark} with the + * current thread as the target; or + * + * <li>Some other thread {@linkplain Thread#interrupt interrupts} the current + * thread; or + * + * <li>The specified waiting time elapses; or + * + * <li>The call spuriously (that is, for no reason) returns. + * </ul> + * + * <p>This method does <em>not</em> report which of these caused the + * method to return. Callers should re-check the conditions which caused + * the thread to park in the first place. Callers may also determine, + * for example, the interrupt status of the thread, or the elapsed time + * upon return. + * + * @param blocker the synchronization object responsible for this + * thread parking + * @param nanos the maximum number of nanoseconds to wait + * @since 1.6 + */ + public static void parkNanos(Object blocker, long nanos) { + if (nanos > 0) { + Thread t = Thread.currentThread(); + setBlocker(t, blocker); + unsafe.park(false, nanos); + setBlocker(t, null); + } + } + + /** + * Disables the current thread for thread scheduling purposes, until + * the specified deadline, unless the permit is available. + * + * <p>If the permit is available then it is consumed and the call + * returns immediately; otherwise the current thread becomes disabled + * for thread scheduling purposes and lies dormant until one of four + * things happens: + * + * <ul> + * <li>Some other thread invokes {@link #unpark unpark} with the + * current thread as the target; or + * + * <li>Some other thread {@linkplain Thread#interrupt interrupts} the + * current thread; or + * + * <li>The specified deadline passes; or + * + * <li>The call spuriously (that is, for no reason) returns. + * </ul> + * + * <p>This method does <em>not</em> report which of these caused the + * method to return. Callers should re-check the conditions which caused + * the thread to park in the first place. Callers may also determine, + * for example, the interrupt status of the thread, or the current time + * upon return. + * + * @param blocker the synchronization object responsible for this + * thread parking + * @param deadline the absolute time, in milliseconds from the Epoch, + * to wait until + * @since 1.6 + */ + public static void parkUntil(Object blocker, long deadline) { + Thread t = Thread.currentThread(); + setBlocker(t, blocker); + unsafe.park(true, deadline); + setBlocker(t, null); + } + + /** + * Returns the blocker object supplied to the most recent + * invocation of a park method that has not yet unblocked, or null + * if not blocked. The value returned is just a momentary + * snapshot -- the thread may have since unblocked or blocked on a + * different blocker object. + * + * @return the blocker + * @since 1.6 + */ + public static Object getBlocker(Thread t) { + return unsafe.getObjectVolatile(t, parkBlockerOffset); + } + + /** + * Disables the current thread for thread scheduling purposes unless the + * permit is available. + * + * <p>If the permit is available then it is consumed and the call + * returns immediately; otherwise the current thread becomes disabled + * for thread scheduling purposes and lies dormant until one of three + * things happens: + * + * <ul> + * + * <li>Some other thread invokes {@link #unpark unpark} with the + * current thread as the target; or + * + * <li>Some other thread {@linkplain Thread#interrupt interrupts} + * the current thread; or + * + * <li>The call spuriously (that is, for no reason) returns. + * </ul> + * + * <p>This method does <em>not</em> report which of these caused the + * method to return. Callers should re-check the conditions which caused + * the thread to park in the first place. Callers may also determine, + * for example, the interrupt status of the thread upon return. + */ + public static void park() { + unsafe.park(false, 0L); + } + + /** + * Disables the current thread for thread scheduling purposes, for up to + * the specified waiting time, unless the permit is available. + * + * <p>If the permit is available then it is consumed and the call + * returns immediately; otherwise the current thread becomes disabled + * for thread scheduling purposes and lies dormant until one of four + * things happens: + * + * <ul> + * <li>Some other thread invokes {@link #unpark unpark} with the + * current thread as the target; or + * + * <li>Some other thread {@linkplain Thread#interrupt interrupts} + * the current thread; or + * + * <li>The specified waiting time elapses; or + * + * <li>The call spuriously (that is, for no reason) returns. + * </ul> + * + * <p>This method does <em>not</em> report which of these caused the + * method to return. Callers should re-check the conditions which caused + * the thread to park in the first place. Callers may also determine, + * for example, the interrupt status of the thread, or the elapsed time + * upon return. + * + * @param nanos the maximum number of nanoseconds to wait + */ + public static void parkNanos(long nanos) { + if (nanos > 0) + unsafe.park(false, nanos); + } + + /** + * Disables the current thread for thread scheduling purposes, until + * the specified deadline, unless the permit is available. + * + * <p>If the permit is available then it is consumed and the call + * returns immediately; otherwise the current thread becomes disabled + * for thread scheduling purposes and lies dormant until one of four + * things happens: + * + * <ul> + * <li>Some other thread invokes {@link #unpark unpark} with the + * current thread as the target; or + * + * <li>Some other thread {@linkplain Thread#interrupt interrupts} + * the current thread; or + * + * <li>The specified deadline passes; or + * + * <li>The call spuriously (that is, for no reason) returns. + * </ul> + * + * <p>This method does <em>not</em> report which of these caused the + * method to return. Callers should re-check the conditions which caused + * the thread to park in the first place. Callers may also determine, + * for example, the interrupt status of the thread, or the current time + * upon return. + * + * @param deadline the absolute time, in milliseconds from the Epoch, + * to wait until + */ + public static void parkUntil(long deadline) { + unsafe.park(true, deadline); + } +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/locks/ReadWriteLock.java b/libjava/classpath/external/jsr166/java/util/concurrent/locks/ReadWriteLock.java new file mode 100644 index 000000000..484f68d15 --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/locks/ReadWriteLock.java @@ -0,0 +1,104 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent.locks; + +/** + * A <tt>ReadWriteLock</tt> maintains a pair of associated {@link + * Lock locks}, one for read-only operations and one for writing. + * The {@link #readLock read lock} may be held simultaneously by + * multiple reader threads, so long as there are no writers. The + * {@link #writeLock write lock} is exclusive. + * + * <p>All <tt>ReadWriteLock</tt> implementations must guarantee that + * the memory synchronization effects of <tt>writeLock</tt> operations + * (as specified in the {@link Lock} interface) also hold with respect + * to the associated <tt>readLock</tt>. That is, a thread successfully + * acquiring the read lock will see all updates made upon previous + * release of the write lock. + * + * <p>A read-write lock allows for a greater level of concurrency in + * accessing shared data than that permitted by a mutual exclusion lock. + * It exploits the fact that while only a single thread at a time (a + * <em>writer</em> thread) can modify the shared data, in many cases any + * number of threads can concurrently read the data (hence <em>reader</em> + * threads). + * In theory, the increase in concurrency permitted by the use of a read-write + * lock will lead to performance improvements over the use of a mutual + * exclusion lock. In practice this increase in concurrency will only be fully + * realized on a multi-processor, and then only if the access patterns for + * the shared data are suitable. + * + * <p>Whether or not a read-write lock will improve performance over the use + * of a mutual exclusion lock depends on the frequency that the data is + * read compared to being modified, the duration of the read and write + * operations, and the contention for the data - that is, the number of + * threads that will try to read or write the data at the same time. + * For example, a collection that is initially populated with data and + * thereafter infrequently modified, while being frequently searched + * (such as a directory of some kind) is an ideal candidate for the use of + * a read-write lock. However, if updates become frequent then the data + * spends most of its time being exclusively locked and there is little, if any + * increase in concurrency. Further, if the read operations are too short + * the overhead of the read-write lock implementation (which is inherently + * more complex than a mutual exclusion lock) can dominate the execution + * cost, particularly as many read-write lock implementations still serialize + * all threads through a small section of code. Ultimately, only profiling + * and measurement will establish whether the use of a read-write lock is + * suitable for your application. + * + * + * <p>Although the basic operation of a read-write lock is straight-forward, + * there are many policy decisions that an implementation must make, which + * may affect the effectiveness of the read-write lock in a given application. + * Examples of these policies include: + * <ul> + * <li>Determining whether to grant the read lock or the write lock, when + * both readers and writers are waiting, at the time that a writer releases + * the write lock. Writer preference is common, as writes are expected to be + * short and infrequent. Reader preference is less common as it can lead to + * lengthy delays for a write if the readers are frequent and long-lived as + * expected. Fair, or "in-order" implementations are also possible. + * + * <li>Determining whether readers that request the read lock while a + * reader is active and a writer is waiting, are granted the read lock. + * Preference to the reader can delay the writer indefinitely, while + * preference to the writer can reduce the potential for concurrency. + * + * <li>Determining whether the locks are reentrant: can a thread with the + * write lock reacquire it? Can it acquire a read lock while holding the + * write lock? Is the read lock itself reentrant? + * + * <li>Can the write lock be downgraded to a read lock without allowing + * an intervening writer? Can a read lock be upgraded to a write lock, + * in preference to other waiting readers or writers? + * + * </ul> + * You should consider all of these things when evaluating the suitability + * of a given implementation for your application. + * + * @see ReentrantReadWriteLock + * @see Lock + * @see ReentrantLock + * + * @since 1.5 + * @author Doug Lea + */ +public interface ReadWriteLock { + /** + * Returns the lock used for reading. + * + * @return the lock used for reading. + */ + Lock readLock(); + + /** + * Returns the lock used for writing. + * + * @return the lock used for writing. + */ + Lock writeLock(); +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/locks/ReentrantLock.java b/libjava/classpath/external/jsr166/java/util/concurrent/locks/ReentrantLock.java new file mode 100644 index 000000000..4a2fc175c --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/locks/ReentrantLock.java @@ -0,0 +1,740 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent.locks; +import java.util.*; +import java.util.concurrent.*; +import java.util.concurrent.atomic.*; + +/** + * A reentrant mutual exclusion {@link Lock} with the same basic + * behavior and semantics as the implicit monitor lock accessed using + * {@code synchronized} methods and statements, but with extended + * capabilities. + * + * <p>A {@code ReentrantLock} is <em>owned</em> by the thread last + * successfully locking, but not yet unlocking it. A thread invoking + * {@code lock} will return, successfully acquiring the lock, when + * the lock is not owned by another thread. The method will return + * immediately if the current thread already owns the lock. This can + * be checked using methods {@link #isHeldByCurrentThread}, and {@link + * #getHoldCount}. + * + * <p>The constructor for this class accepts an optional + * <em>fairness</em> parameter. When set {@code true}, under + * contention, locks favor granting access to the longest-waiting + * thread. Otherwise this lock does not guarantee any particular + * access order. Programs using fair locks accessed by many threads + * may display lower overall throughput (i.e., are slower; often much + * slower) than those using the default setting, but have smaller + * variances in times to obtain locks and guarantee lack of + * starvation. Note however, that fairness of locks does not guarantee + * fairness of thread scheduling. Thus, one of many threads using a + * fair lock may obtain it multiple times in succession while other + * active threads are not progressing and not currently holding the + * lock. + * Also note that the untimed {@link #tryLock() tryLock} method does not + * honor the fairness setting. It will succeed if the lock + * is available even if other threads are waiting. + * + * <p>It is recommended practice to <em>always</em> immediately + * follow a call to {@code lock} with a {@code try} block, most + * typically in a before/after construction such as: + * + * <pre> + * class X { + * private final ReentrantLock lock = new ReentrantLock(); + * // ... + * + * public void m() { + * lock.lock(); // block until condition holds + * try { + * // ... method body + * } finally { + * lock.unlock() + * } + * } + * } + * </pre> + * + * <p>In addition to implementing the {@link Lock} interface, this + * class defines methods {@code isLocked} and + * {@code getLockQueueLength}, as well as some associated + * {@code protected} access methods that may be useful for + * instrumentation and monitoring. + * + * <p>Serialization of this class behaves in the same way as built-in + * locks: a deserialized lock is in the unlocked state, regardless of + * its state when serialized. + * + * <p>This lock supports a maximum of 2147483647 recursive locks by + * the same thread. Attempts to exceed this limit result in + * {@link Error} throws from locking methods. + * + * @since 1.5 + * @author Doug Lea + */ +public class ReentrantLock implements Lock, java.io.Serializable { + private static final long serialVersionUID = 7373984872572414699L; + /** Synchronizer providing all implementation mechanics */ + private final Sync sync; + + /** + * Base of synchronization control for this lock. Subclassed + * into fair and nonfair versions below. Uses AQS state to + * represent the number of holds on the lock. + */ + static abstract class Sync extends AbstractQueuedSynchronizer { + private static final long serialVersionUID = -5179523762034025860L; + + /** + * Performs {@link Lock#lock}. The main reason for subclassing + * is to allow fast path for nonfair version. + */ + abstract void lock(); + + /** + * Performs non-fair tryLock. tryAcquire is + * implemented in subclasses, but both need nonfair + * try for trylock method. + */ + final boolean nonfairTryAcquire(int acquires) { + final Thread current = Thread.currentThread(); + int c = getState(); + if (c == 0) { + if (compareAndSetState(0, acquires)) { + setExclusiveOwnerThread(current); + return true; + } + } + else if (current == getExclusiveOwnerThread()) { + int nextc = c + acquires; + if (nextc < 0) // overflow + throw new Error("Maximum lock count exceeded"); + setState(nextc); + return true; + } + return false; + } + + protected final boolean tryRelease(int releases) { + int c = getState() - releases; + if (Thread.currentThread() != getExclusiveOwnerThread()) + throw new IllegalMonitorStateException(); + boolean free = false; + if (c == 0) { + free = true; + setExclusiveOwnerThread(null); + } + setState(c); + return free; + } + + protected final boolean isHeldExclusively() { + // While we must in general read state before owner, + // we don't need to do so to check if current thread is owner + return getExclusiveOwnerThread() == Thread.currentThread(); + } + + final ConditionObject newCondition() { + return new ConditionObject(); + } + + // Methods relayed from outer class + + final Thread getOwner() { + return getState() == 0 ? null : getExclusiveOwnerThread(); + } + + final int getHoldCount() { + return isHeldExclusively() ? getState() : 0; + } + + final boolean isLocked() { + return getState() != 0; + } + + /** + * Reconstitutes this lock instance from a stream. + * @param s the stream + */ + private void readObject(java.io.ObjectInputStream s) + throws java.io.IOException, ClassNotFoundException { + s.defaultReadObject(); + setState(0); // reset to unlocked state + } + } + + /** + * Sync object for non-fair locks + */ + final static class NonfairSync extends Sync { + private static final long serialVersionUID = 7316153563782823691L; + + /** + * Performs lock. Try immediate barge, backing up to normal + * acquire on failure. + */ + final void lock() { + if (compareAndSetState(0, 1)) + setExclusiveOwnerThread(Thread.currentThread()); + else + acquire(1); + } + + protected final boolean tryAcquire(int acquires) { + return nonfairTryAcquire(acquires); + } + } + + /** + * Sync object for fair locks + */ + final static class FairSync extends Sync { + private static final long serialVersionUID = -3000897897090466540L; + + final void lock() { + acquire(1); + } + + /** + * Fair version of tryAcquire. Don't grant access unless + * recursive call or no waiters or is first. + */ + protected final boolean tryAcquire(int acquires) { + final Thread current = Thread.currentThread(); + int c = getState(); + if (c == 0) { + if (isFirst(current) && + compareAndSetState(0, acquires)) { + setExclusiveOwnerThread(current); + return true; + } + } + else if (current == getExclusiveOwnerThread()) { + int nextc = c + acquires; + if (nextc < 0) + throw new Error("Maximum lock count exceeded"); + setState(nextc); + return true; + } + return false; + } + } + + /** + * Creates an instance of {@code ReentrantLock}. + * This is equivalent to using {@code ReentrantLock(false)}. + */ + public ReentrantLock() { + sync = new NonfairSync(); + } + + /** + * Creates an instance of {@code ReentrantLock} with the + * given fairness policy. + * + * @param fair {@code true} if this lock should use a fair ordering policy + */ + public ReentrantLock(boolean fair) { + sync = (fair)? new FairSync() : new NonfairSync(); + } + + /** + * Acquires the lock. + * + * <p>Acquires the lock if it is not held by another thread and returns + * immediately, setting the lock hold count to one. + * + * <p>If the current thread already holds the lock then the hold + * count is incremented by one and the method returns immediately. + * + * <p>If the lock is held by another thread then the + * current thread becomes disabled for thread scheduling + * purposes and lies dormant until the lock has been acquired, + * at which time the lock hold count is set to one. + */ + public void lock() { + sync.lock(); + } + + /** + * Acquires the lock unless the current thread is + * {@linkplain Thread#interrupt interrupted}. + * + * <p>Acquires the lock if it is not held by another thread and returns + * immediately, setting the lock hold count to one. + * + * <p>If the current thread already holds this lock then the hold count + * is incremented by one and the method returns immediately. + * + * <p>If the lock is held by another thread then the + * current thread becomes disabled for thread scheduling + * purposes and lies dormant until one of two things happens: + * + * <ul> + * + * <li>The lock is acquired by the current thread; or + * + * <li>Some other thread {@linkplain Thread#interrupt interrupts} the + * current thread. + * + * </ul> + * + * <p>If the lock is acquired by the current thread then the lock hold + * count is set to one. + * + * <p>If the current thread: + * + * <ul> + * + * <li>has its interrupted status set on entry to this method; or + * + * <li>is {@linkplain Thread#interrupt interrupted} while acquiring + * the lock, + * + * </ul> + * + * then {@link InterruptedException} is thrown and the current thread's + * interrupted status is cleared. + * + * <p>In this implementation, as this method is an explicit + * interruption point, preference is given to responding to the + * interrupt over normal or reentrant acquisition of the lock. + * + * @throws InterruptedException if the current thread is interrupted + */ + public void lockInterruptibly() throws InterruptedException { + sync.acquireInterruptibly(1); + } + + /** + * Acquires the lock only if it is not held by another thread at the time + * of invocation. + * + * <p>Acquires the lock if it is not held by another thread and + * returns immediately with the value {@code true}, setting the + * lock hold count to one. Even when this lock has been set to use a + * fair ordering policy, a call to {@code tryLock()} <em>will</em> + * immediately acquire the lock if it is available, whether or not + * other threads are currently waiting for the lock. + * This "barging" behavior can be useful in certain + * circumstances, even though it breaks fairness. If you want to honor + * the fairness setting for this lock, then use + * {@link #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) } + * which is almost equivalent (it also detects interruption). + * + * <p> If the current thread already holds this lock then the hold + * count is incremented by one and the method returns {@code true}. + * + * <p>If the lock is held by another thread then this method will return + * immediately with the value {@code false}. + * + * @return {@code true} if the lock was free and was acquired by the + * current thread, or the lock was already held by the current + * thread; and {@code false} otherwise + */ + public boolean tryLock() { + return sync.nonfairTryAcquire(1); + } + + /** + * Acquires the lock if it is not held by another thread within the given + * waiting time and the current thread has not been + * {@linkplain Thread#interrupt interrupted}. + * + * <p>Acquires the lock if it is not held by another thread and returns + * immediately with the value {@code true}, setting the lock hold count + * to one. If this lock has been set to use a fair ordering policy then + * an available lock <em>will not</em> be acquired if any other threads + * are waiting for the lock. This is in contrast to the {@link #tryLock()} + * method. If you want a timed {@code tryLock} that does permit barging on + * a fair lock then combine the timed and un-timed forms together: + * + * <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... } + * </pre> + * + * <p>If the current thread + * already holds this lock then the hold count is incremented by one and + * the method returns {@code true}. + * + * <p>If the lock is held by another thread then the + * current thread becomes disabled for thread scheduling + * purposes and lies dormant until one of three things happens: + * + * <ul> + * + * <li>The lock is acquired by the current thread; or + * + * <li>Some other thread {@linkplain Thread#interrupt interrupts} + * the current thread; or + * + * <li>The specified waiting time elapses + * + * </ul> + * + * <p>If the lock is acquired then the value {@code true} is returned and + * the lock hold count is set to one. + * + * <p>If the current thread: + * + * <ul> + * + * <li>has its interrupted status set on entry to this method; or + * + * <li>is {@linkplain Thread#interrupt interrupted} while + * acquiring the lock, + * + * </ul> + * then {@link InterruptedException} is thrown and the current thread's + * interrupted status is cleared. + * + * <p>If the specified waiting time elapses then the value {@code false} + * is returned. If the time is less than or equal to zero, the method + * will not wait at all. + * + * <p>In this implementation, as this method is an explicit + * interruption point, preference is given to responding to the + * interrupt over normal or reentrant acquisition of the lock, and + * over reporting the elapse of the waiting time. + * + * @param timeout the time to wait for the lock + * @param unit the time unit of the timeout argument + * @return {@code true} if the lock was free and was acquired by the + * current thread, or the lock was already held by the current + * thread; and {@code false} if the waiting time elapsed before + * the lock could be acquired + * @throws InterruptedException if the current thread is interrupted + * @throws NullPointerException if the time unit is null + * + */ + public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException { + return sync.tryAcquireNanos(1, unit.toNanos(timeout)); + } + + /** + * Attempts to release this lock. + * + * <p>If the current thread is the holder of this lock then the hold + * count is decremented. If the hold count is now zero then the lock + * is released. If the current thread is not the holder of this + * lock then {@link IllegalMonitorStateException} is thrown. + * + * @throws IllegalMonitorStateException if the current thread does not + * hold this lock + */ + public void unlock() { + sync.release(1); + } + + /** + * Returns a {@link Condition} instance for use with this + * {@link Lock} instance. + * + * <p>The returned {@link Condition} instance supports the same + * usages as do the {@link Object} monitor methods ({@link + * Object#wait() wait}, {@link Object#notify notify}, and {@link + * Object#notifyAll notifyAll}) when used with the built-in + * monitor lock. + * + * <ul> + * + * <li>If this lock is not held when any of the {@link Condition} + * {@linkplain Condition#await() waiting} or {@linkplain + * Condition#signal signalling} methods are called, then an {@link + * IllegalMonitorStateException} is thrown. + * + * <li>When the condition {@linkplain Condition#await() waiting} + * methods are called the lock is released and, before they + * return, the lock is reacquired and the lock hold count restored + * to what it was when the method was called. + * + * <li>If a thread is {@linkplain Thread#interrupt interrupted} + * while waiting then the wait will terminate, an {@link + * InterruptedException} will be thrown, and the thread's + * interrupted status will be cleared. + * + * <li> Waiting threads are signalled in FIFO order. + * + * <li>The ordering of lock reacquisition for threads returning + * from waiting methods is the same as for threads initially + * acquiring the lock, which is in the default case not specified, + * but for <em>fair</em> locks favors those threads that have been + * waiting the longest. + * + * </ul> + * + * @return the Condition object + */ + public Condition newCondition() { + return sync.newCondition(); + } + + /** + * Queries the number of holds on this lock by the current thread. + * + * <p>A thread has a hold on a lock for each lock action that is not + * matched by an unlock action. + * + * <p>The hold count information is typically only used for testing and + * debugging purposes. For example, if a certain section of code should + * not be entered with the lock already held then we can assert that + * fact: + * + * <pre> + * class X { + * ReentrantLock lock = new ReentrantLock(); + * // ... + * public void m() { + * assert lock.getHoldCount() == 0; + * lock.lock(); + * try { + * // ... method body + * } finally { + * lock.unlock(); + * } + * } + * } + * </pre> + * + * @return the number of holds on this lock by the current thread, + * or zero if this lock is not held by the current thread + */ + public int getHoldCount() { + return sync.getHoldCount(); + } + + /** + * Queries if this lock is held by the current thread. + * + * <p>Analogous to the {@link Thread#holdsLock} method for built-in + * monitor locks, this method is typically used for debugging and + * testing. For example, a method that should only be called while + * a lock is held can assert that this is the case: + * + * <pre> + * class X { + * ReentrantLock lock = new ReentrantLock(); + * // ... + * + * public void m() { + * assert lock.isHeldByCurrentThread(); + * // ... method body + * } + * } + * </pre> + * + * <p>It can also be used to ensure that a reentrant lock is used + * in a non-reentrant manner, for example: + * + * <pre> + * class X { + * ReentrantLock lock = new ReentrantLock(); + * // ... + * + * public void m() { + * assert !lock.isHeldByCurrentThread(); + * lock.lock(); + * try { + * // ... method body + * } finally { + * lock.unlock(); + * } + * } + * } + * </pre> + * + * @return {@code true} if current thread holds this lock and + * {@code false} otherwise + */ + public boolean isHeldByCurrentThread() { + return sync.isHeldExclusively(); + } + + /** + * Queries if this lock is held by any thread. This method is + * designed for use in monitoring of the system state, + * not for synchronization control. + * + * @return {@code true} if any thread holds this lock and + * {@code false} otherwise + */ + public boolean isLocked() { + return sync.isLocked(); + } + + /** + * Returns {@code true} if this lock has fairness set true. + * + * @return {@code true} if this lock has fairness set true + */ + public final boolean isFair() { + return sync instanceof FairSync; + } + + /** + * Returns the thread that currently owns this lock, or + * {@code null} if not owned. When this method is called by a + * thread that is not the owner, the return value reflects a + * best-effort approximation of current lock status. For example, + * the owner may be momentarily {@code null} even if there are + * threads trying to acquire the lock but have not yet done so. + * This method is designed to facilitate construction of + * subclasses that provide more extensive lock monitoring + * facilities. + * + * @return the owner, or {@code null} if not owned + */ + protected Thread getOwner() { + return sync.getOwner(); + } + + /** + * Queries whether any threads are waiting to acquire this lock. Note that + * because cancellations may occur at any time, a {@code true} + * return does not guarantee that any other thread will ever + * acquire this lock. This method is designed primarily for use in + * monitoring of the system state. + * + * @return {@code true} if there may be other threads waiting to + * acquire the lock + */ + public final boolean hasQueuedThreads() { + return sync.hasQueuedThreads(); + } + + + /** + * Queries whether the given thread is waiting to acquire this + * lock. Note that because cancellations may occur at any time, a + * {@code true} return does not guarantee that this thread + * will ever acquire this lock. This method is designed primarily for use + * in monitoring of the system state. + * + * @param thread the thread + * @return {@code true} if the given thread is queued waiting for this lock + * @throws NullPointerException if the thread is null + */ + public final boolean hasQueuedThread(Thread thread) { + return sync.isQueued(thread); + } + + + /** + * Returns an estimate of the number of threads waiting to + * acquire this lock. The value is only an estimate because the number of + * threads may change dynamically while this method traverses + * internal data structures. This method is designed for use in + * monitoring of the system state, not for synchronization + * control. + * + * @return the estimated number of threads waiting for this lock + */ + public final int getQueueLength() { + return sync.getQueueLength(); + } + + /** + * Returns a collection containing threads that may be waiting to + * acquire this lock. Because the actual set of threads may change + * dynamically while constructing this result, the returned + * collection is only a best-effort estimate. The elements of the + * returned collection are in no particular order. This method is + * designed to facilitate construction of subclasses that provide + * more extensive monitoring facilities. + * + * @return the collection of threads + */ + protected Collection<Thread> getQueuedThreads() { + return sync.getQueuedThreads(); + } + + /** + * Queries whether any threads are waiting on the given condition + * associated with this lock. Note that because timeouts and + * interrupts may occur at any time, a {@code true} return does + * not guarantee that a future {@code signal} will awaken any + * threads. This method is designed primarily for use in + * monitoring of the system state. + * + * @param condition the condition + * @return {@code true} if there are any waiting threads + * @throws IllegalMonitorStateException if this lock is not held + * @throws IllegalArgumentException if the given condition is + * not associated with this lock + * @throws NullPointerException if the condition is null + */ + public boolean hasWaiters(Condition condition) { + if (condition == null) + throw new NullPointerException(); + if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject)) + throw new IllegalArgumentException("not owner"); + return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition); + } + + /** + * Returns an estimate of the number of threads waiting on the + * given condition associated with this lock. Note that because + * timeouts and interrupts may occur at any time, the estimate + * serves only as an upper bound on the actual number of waiters. + * This method is designed for use in monitoring of the system + * state, not for synchronization control. + * + * @param condition the condition + * @return the estimated number of waiting threads + * @throws IllegalMonitorStateException if this lock is not held + * @throws IllegalArgumentException if the given condition is + * not associated with this lock + * @throws NullPointerException if the condition is null + */ + public int getWaitQueueLength(Condition condition) { + if (condition == null) + throw new NullPointerException(); + if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject)) + throw new IllegalArgumentException("not owner"); + return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition); + } + + /** + * Returns a collection containing those threads that may be + * waiting on the given condition associated with this lock. + * Because the actual set of threads may change dynamically while + * constructing this result, the returned collection is only a + * best-effort estimate. The elements of the returned collection + * are in no particular order. This method is designed to + * facilitate construction of subclasses that provide more + * extensive condition monitoring facilities. + * + * @param condition the condition + * @return the collection of threads + * @throws IllegalMonitorStateException if this lock is not held + * @throws IllegalArgumentException if the given condition is + * not associated with this lock + * @throws NullPointerException if the condition is null + */ + protected Collection<Thread> getWaitingThreads(Condition condition) { + if (condition == null) + throw new NullPointerException(); + if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject)) + throw new IllegalArgumentException("not owner"); + return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition); + } + + /** + * Returns a string identifying this lock, as well as its lock state. + * The state, in brackets, includes either the String {@code "Unlocked"} + * or the String {@code "Locked by"} followed by the + * {@linkplain Thread#getName name} of the owning thread. + * + * @return a string identifying this lock, as well as its lock state + */ + public String toString() { + Thread o = sync.getOwner(); + return super.toString() + ((o == null) ? + "[Unlocked]" : + "[Locked by thread " + o.getName() + "]"); + } +} diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/locks/ReentrantReadWriteLock.java b/libjava/classpath/external/jsr166/java/util/concurrent/locks/ReentrantReadWriteLock.java new file mode 100644 index 000000000..a6eadff5b --- /dev/null +++ b/libjava/classpath/external/jsr166/java/util/concurrent/locks/ReentrantReadWriteLock.java @@ -0,0 +1,1346 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent.locks; +import java.util.concurrent.*; +import java.util.concurrent.atomic.*; +import java.util.*; + +/** + * An implementation of {@link ReadWriteLock} supporting similar + * semantics to {@link ReentrantLock}. + * <p>This class has the following properties: + * + * <ul> + * <li><b>Acquisition order</b> + * + * <p> This class does not impose a reader or writer preference + * ordering for lock access. However, it does support an optional + * <em>fairness</em> policy. + * + * <dl> + * <dt><b><i>Non-fair mode (default)</i></b> + * <dd>When constructed as non-fair (the default), the order of entry + * to the read and write lock is unspecified, subject to reentrancy + * constraints. A nonfair lock that is continously contended may + * indefinitely postpone one or more reader or writer threads, but + * will normally have higher throughput than a fair lock. + * <p> + * + * <dt><b><i>Fair mode</i></b> + * <dd> When constructed as fair, threads contend for entry using an + * approximately arrival-order policy. When the currently held lock + * is released either the longest-waiting single writer thread will + * be assigned the write lock, or if there is a group of reader threads + * waiting longer than all waiting writer threads, that group will be + * assigned the read lock. + * + * <p>A thread that tries to acquire a fair read lock (non-reentrantly) + * will block if either the write lock is held, or there is a waiting + * writer thread. The thread will not acquire the read lock until + * after the oldest currently waiting writer thread has acquired and + * released the write lock. Of course, if a waiting writer abandons + * its wait, leaving one or more reader threads as the longest waiters + * in the queue with the write lock free, then those readers will be + * assigned the read lock. + * + * <p>A thread that tries to acquire a fair write lock (non-reentrantly) + * will block unless both the read lock and write lock are free (which + * implies there are no waiting threads). (Note that the non-blocking + * {@link ReadLock#tryLock()} and {@link WriteLock#tryLock()} methods + * do not honor this fair setting and will acquire the lock if it is + * possible, regardless of waiting threads.) + * <p> + * </dl> + * + * <li><b>Reentrancy</b> + * + * <p>This lock allows both readers and writers to reacquire read or + * write locks in the style of a {@link ReentrantLock}. Non-reentrant + * readers are not allowed until all write locks held by the writing + * thread have been released. + * + * <p>Additionally, a writer can acquire the read lock, but not + * vice-versa. Among other applications, reentrancy can be useful + * when write locks are held during calls or callbacks to methods that + * perform reads under read locks. If a reader tries to acquire the + * write lock it will never succeed. + * + * <li><b>Lock downgrading</b> + * <p>Reentrancy also allows downgrading from the write lock to a read lock, + * by acquiring the write lock, then the read lock and then releasing the + * write lock. However, upgrading from a read lock to the write lock is + * <b>not</b> possible. + * + * <li><b>Interruption of lock acquisition</b> + * <p>The read lock and write lock both support interruption during lock + * acquisition. + * + * <li><b>{@link Condition} support</b> + * <p>The write lock provides a {@link Condition} implementation that + * behaves in the same way, with respect to the write lock, as the + * {@link Condition} implementation provided by + * {@link ReentrantLock#newCondition} does for {@link ReentrantLock}. + * This {@link Condition} can, of course, only be used with the write lock. + * + * <p>The read lock does not support a {@link Condition} and + * {@code readLock().newCondition()} throws + * {@code UnsupportedOperationException}. + * + * <li><b>Instrumentation</b> + * <p>This class supports methods to determine whether locks + * are held or contended. These methods are designed for monitoring + * system state, not for synchronization control. + * </ul> + * + * <p>Serialization of this class behaves in the same way as built-in + * locks: a deserialized lock is in the unlocked state, regardless of + * its state when serialized. + * + * <p><b>Sample usages</b>. Here is a code sketch showing how to exploit + * reentrancy to perform lock downgrading after updating a cache (exception + * handling is elided for simplicity): + * <pre> + * class CachedData { + * Object data; + * volatile boolean cacheValid; + * ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); + * + * void processCachedData() { + * rwl.readLock().lock(); + * if (!cacheValid) { + * // Must release read lock before acquiring write lock + * rwl.readLock().unlock(); + * rwl.writeLock().lock(); + * // Recheck state because another thread might have acquired + * // write lock and changed state before we did. + * if (!cacheValid) { + * data = ... + * cacheValid = true; + * } + * // Downgrade by acquiring read lock before releasing write lock + * rwl.readLock().lock(); + * rwl.writeLock().unlock(); // Unlock write, still hold read + * } + * + * use(data); + * rwl.readLock().unlock(); + * } + * } + * </pre> + * + * ReentrantReadWriteLocks can be used to improve concurrency in some + * uses of some kinds of Collections. This is typically worthwhile + * only when the collections are expected to be large, accessed by + * more reader threads than writer threads, and entail operations with + * overhead that outweighs synchronization overhead. For example, here + * is a class using a TreeMap that is expected to be large and + * concurrently accessed. + * + * <pre>{@code + * class RWDictionary { + * private final Map<String, Data> m = new TreeMap<String, Data>(); + * private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); + * private final Lock r = rwl.readLock(); + * private final Lock w = rwl.writeLock(); + * + * public Data get(String key) { + * r.lock(); + * try { return m.get(key); } + * finally { r.unlock(); } + * } + * public String[] allKeys() { + * r.lock(); + * try { return m.keySet().toArray(); } + * finally { r.unlock(); } + * } + * public Data put(String key, Data value) { + * w.lock(); + * try { return m.put(key, value); } + * finally { w.unlock(); } + * } + * public void clear() { + * w.lock(); + * try { m.clear(); } + * finally { w.unlock(); } + * } + * }}</pre> + * + * <h3>Implementation Notes</h3> + * + * <p>This lock supports a maximum of 65535 recursive write locks + * and 65535 read locks. Attempts to exceed these limits result in + * {@link Error} throws from locking methods. + * + * @since 1.5 + * @author Doug Lea + * + */ +public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializable { + private static final long serialVersionUID = -6992448646407690164L; + /** Inner class providing readlock */ + private final ReentrantReadWriteLock.ReadLock readerLock; + /** Inner class providing writelock */ + private final ReentrantReadWriteLock.WriteLock writerLock; + /** Performs all synchronization mechanics */ + private final Sync sync; + + /** + * Creates a new {@code ReentrantReadWriteLock} with + * default (nonfair) ordering properties. + */ + public ReentrantReadWriteLock() { + this(false); + } + + /** + * Creates a new {@code ReentrantReadWriteLock} with + * the given fairness policy. + * + * @param fair {@code true} if this lock should use a fair ordering policy + */ + public ReentrantReadWriteLock(boolean fair) { + sync = (fair)? new FairSync() : new NonfairSync(); + readerLock = new ReadLock(this); + writerLock = new WriteLock(this); + } + + public ReentrantReadWriteLock.WriteLock writeLock() { return writerLock; } + public ReentrantReadWriteLock.ReadLock readLock() { return readerLock; } + + /** + * Synchronization implementation for ReentrantReadWriteLock. + * Subclassed into fair and nonfair versions. + */ + static abstract class Sync extends AbstractQueuedSynchronizer { + private static final long serialVersionUID = 6317671515068378041L; + + /* + * Read vs write count extraction constants and functions. + * Lock state is logically divided into two shorts: The lower + * one representing the exclusive (writer) lock hold count, + * and the upper the shared (reader) hold count. + */ + + static final int SHARED_SHIFT = 16; + static final int SHARED_UNIT = (1 << SHARED_SHIFT); + static final int MAX_COUNT = (1 << SHARED_SHIFT) - 1; + static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1; + + /** Returns the number of shared holds represented in count */ + static int sharedCount(int c) { return c >>> SHARED_SHIFT; } + /** Returns the number of exclusive holds represented in count */ + static int exclusiveCount(int c) { return c & EXCLUSIVE_MASK; } + + /** + * A counter for per-thread read hold counts. + * Maintained as a ThreadLocal; cached in cachedHoldCounter + */ + static final class HoldCounter { + int count; + // Use id, not reference, to avoid garbage retention + final long tid = Thread.currentThread().getId(); + /** Decrement if positive; return previous value */ + int tryDecrement() { + int c = count; + if (c > 0) + count = c - 1; + return c; + } + } + + /** + * ThreadLocal subclass. Easiest to explicitly define for sake + * of deserialization mechanics. + */ + static final class ThreadLocalHoldCounter + extends ThreadLocal<HoldCounter> { + public HoldCounter initialValue() { + return new HoldCounter(); + } + } + + /** + * The number of read locks held by current thread. + * Initialized only in constructor and readObject. + */ + transient ThreadLocalHoldCounter readHolds; + + /** + * The hold count of the last thread to successfully acquire + * readLock. This saves ThreadLocal lookup in the common case + * where the next thread to release is the last one to + * acquire. This is non-volatile since it is just used + * as a heuristic, and would be great for threads to cache. + */ + transient HoldCounter cachedHoldCounter; + + Sync() { + readHolds = new ThreadLocalHoldCounter(); + setState(getState()); // ensures visibility of readHolds + } + + /* + * Acquires and releases use the same code for fair and + * nonfair locks, but differ in whether/how they allow barging + * when queues are non-empty. + */ + + /** + * Return true if a reader thread that is otherwise + * eligible for lock should block because of policy + * for overtaking other waiting threads. + */ + abstract boolean readerShouldBlock(Thread current); + + /** + * Return true if a writer thread that is otherwise + * eligible for lock should block because of policy + * for overtaking other waiting threads. + */ + abstract boolean writerShouldBlock(Thread current); + + /* + * Note that tryRelease and tryAcquire can be called by + * Conditions. So it is possible that their arguments contain + * both read and write holds that are all released during a + * condition wait and re-established in tryAcquire. + */ + + protected final boolean tryRelease(int releases) { + int nextc = getState() - releases; + if (Thread.currentThread() != getExclusiveOwnerThread()) + throw new IllegalMonitorStateException(); + if (exclusiveCount(nextc) == 0) { + setExclusiveOwnerThread(null); + setState(nextc); + return true; + } else { + setState(nextc); + return false; + } + } + + protected final boolean tryAcquire(int acquires) { + /* + * Walkthrough: + * 1. if read count nonzero or write count nonzero + * and owner is a different thread, fail. + * 2. If count would saturate, fail. (This can only + * happen if count is already nonzero.) + * 3. Otherwise, this thread is eligible for lock if + * it is either a reentrant acquire or + * queue policy allows it. If so, update state + * and set owner. + */ + Thread current = Thread.currentThread(); + int c = getState(); + int w = exclusiveCount(c); + if (c != 0) { + // (Note: if c != 0 and w == 0 then shared count != 0) + if (w == 0 || current != getExclusiveOwnerThread()) + return false; + if (w + exclusiveCount(acquires) > MAX_COUNT) + throw new Error("Maximum lock count exceeded"); + } + if ((w == 0 && writerShouldBlock(current)) || + !compareAndSetState(c, c + acquires)) + return false; + setExclusiveOwnerThread(current); + return true; + } + + protected final boolean tryReleaseShared(int unused) { + HoldCounter rh = cachedHoldCounter; + Thread current = Thread.currentThread(); + if (rh == null || rh.tid != current.getId()) + rh = readHolds.get(); + if (rh.tryDecrement() <= 0) + throw new IllegalMonitorStateException(); + for (;;) { + int c = getState(); + int nextc = c - SHARED_UNIT; + if (compareAndSetState(c, nextc)) + return nextc == 0; + } + } + + protected final int tryAcquireShared(int unused) { + /* + * Walkthrough: + * 1. If write lock held by another thread, fail + * 2. If count saturated, throw error + * 3. Otherwise, this thread is eligible for + * lock wrt state, so ask if it should block + * because of queue policy. If not, try + * to grant by CASing state and updating count. + * Note that step does not check for reentrant + * acquires, which is postponed to full version + * to avoid having to check hold count in + * the more typical non-reentrant case. + * 4. If step 3 fails either because thread + * apparently not eligible or CAS fails, + * chain to version with full retry loop. + */ + Thread current = Thread.currentThread(); + int c = getState(); + if (exclusiveCount(c) != 0 && + getExclusiveOwnerThread() != current) + return -1; + if (sharedCount(c) == MAX_COUNT) + throw new Error("Maximum lock count exceeded"); + if (!readerShouldBlock(current) && + compareAndSetState(c, c + SHARED_UNIT)) { + HoldCounter rh = cachedHoldCounter; + if (rh == null || rh.tid != current.getId()) + cachedHoldCounter = rh = readHolds.get(); + rh.count++; + return 1; + } + return fullTryAcquireShared(current); + } + + /** + * Full version of acquire for reads, that handles CAS misses + * and reentrant reads not dealt with in tryAcquireShared. + */ + final int fullTryAcquireShared(Thread current) { + /* + * This code is in part redundant with that in + * tryAcquireShared but is simpler overall by not + * complicating tryAcquireShared with interactions between + * retries and lazily reading hold counts. + */ + HoldCounter rh = cachedHoldCounter; + if (rh == null || rh.tid != current.getId()) + rh = readHolds.get(); + for (;;) { + int c = getState(); + int w = exclusiveCount(c); + if ((w != 0 && getExclusiveOwnerThread() != current) || + ((rh.count | w) == 0 && readerShouldBlock(current))) + return -1; + if (sharedCount(c) == MAX_COUNT) + throw new Error("Maximum lock count exceeded"); + if (compareAndSetState(c, c + SHARED_UNIT)) { + cachedHoldCounter = rh; // cache for release + rh.count++; + return 1; + } + } + } + + /** + * Performs tryLock for write, enabling barging in both modes. + * This is identical in effect to tryAcquire except for lack + * of calls to writerShouldBlock + */ + final boolean tryWriteLock() { + Thread current = Thread.currentThread(); + int c = getState(); + if (c != 0) { + int w = exclusiveCount(c); + if (w == 0 ||current != getExclusiveOwnerThread()) + return false; + if (w == MAX_COUNT) + throw new Error("Maximum lock count exceeded"); + } + if (!compareAndSetState(c, c + 1)) + return false; + setExclusiveOwnerThread(current); + return true; + } + + /** + * Performs tryLock for read, enabling barging in both modes. + * This is identical in effect to tryAcquireShared except for + * lack of calls to readerShouldBlock + */ + final boolean tryReadLock() { + Thread current = Thread.currentThread(); + for (;;) { + int c = getState(); + if (exclusiveCount(c) != 0 && + getExclusiveOwnerThread() != current) + return false; + if (sharedCount(c) == MAX_COUNT) + throw new Error("Maximum lock count exceeded"); + if (compareAndSetState(c, c + SHARED_UNIT)) { + HoldCounter rh = cachedHoldCounter; + if (rh == null || rh.tid != current.getId()) + cachedHoldCounter = rh = readHolds.get(); + rh.count++; + return true; + } + } + } + + protected final boolean isHeldExclusively() { + // While we must in general read state before owner, + // we don't need to do so to check if current thread is owner + return getExclusiveOwnerThread() == Thread.currentThread(); + } + + // Methods relayed to outer class + + final ConditionObject newCondition() { + return new ConditionObject(); + } + + final Thread getOwner() { + // Must read state before owner to ensure memory consistency + return ((exclusiveCount(getState()) == 0)? + null : + getExclusiveOwnerThread()); + } + + final int getReadLockCount() { + return sharedCount(getState()); + } + + final boolean isWriteLocked() { + return exclusiveCount(getState()) != 0; + } + + final int getWriteHoldCount() { + return isHeldExclusively() ? exclusiveCount(getState()) : 0; + } + + final int getReadHoldCount() { + return getReadLockCount() == 0? 0 : readHolds.get().count; + } + + /** + * Reconstitute this lock instance from a stream + * @param s the stream + */ + private void readObject(java.io.ObjectInputStream s) + throws java.io.IOException, ClassNotFoundException { + s.defaultReadObject(); + readHolds = new ThreadLocalHoldCounter(); + setState(0); // reset to unlocked state + } + + final int getCount() { return getState(); } + } + + /** + * Nonfair version of Sync + */ + final static class NonfairSync extends Sync { + private static final long serialVersionUID = -8159625535654395037L; + final boolean writerShouldBlock(Thread current) { + return false; // writers can always barge + } + final boolean readerShouldBlock(Thread current) { + /* As a heuristic to avoid indefinite writer starvation, + * block if the thread that momentarily appears to be head + * of queue, if one exists, is a waiting writer. This is + * only a probablistic effect since a new reader will not + * block if there is a waiting writer behind other enabled + * readers that have not yet drained from the queue. + */ + return apparentlyFirstQueuedIsExclusive(); + } + } + + /** + * Fair version of Sync + */ + final static class FairSync extends Sync { + private static final long serialVersionUID = -2274990926593161451L; + final boolean writerShouldBlock(Thread current) { + // only proceed if queue is empty or current thread at head + return !isFirst(current); + } + final boolean readerShouldBlock(Thread current) { + // only proceed if queue is empty or current thread at head + return !isFirst(current); + } + } + + /** + * The lock returned by method {@link ReentrantReadWriteLock#readLock}. + */ + public static class ReadLock implements Lock, java.io.Serializable { + private static final long serialVersionUID = -5992448646407690164L; + private final Sync sync; + + /** + * Constructor for use by subclasses + * + * @param lock the outer lock object + * @throws NullPointerException if the lock is null + */ + protected ReadLock(ReentrantReadWriteLock lock) { + sync = lock.sync; + } + + /** + * Acquires the read lock. + * + * <p>Acquires the read lock if the write lock is not held by + * another thread and returns immediately. + * + * <p>If the write lock is held by another thread then + * the current thread becomes disabled for thread scheduling + * purposes and lies dormant until the read lock has been acquired. + */ + public void lock() { + sync.acquireShared(1); + } + + /** + * Acquires the read lock unless the current thread is + * {@linkplain Thread#interrupt interrupted}. + * + * <p>Acquires the read lock if the write lock is not held + * by another thread and returns immediately. + * + * <p>If the write lock is held by another thread then the + * current thread becomes disabled for thread scheduling + * purposes and lies dormant until one of two things happens: + * + * <ul> + * + * <li>The read lock is acquired by the current thread; or + * + * <li>Some other thread {@linkplain Thread#interrupt interrupts} + * the current thread. + * + * </ul> + * + * <p>If the current thread: + * + * <ul> + * + * <li>has its interrupted status set on entry to this method; or + * + * <li>is {@linkplain Thread#interrupt interrupted} while + * acquiring the read lock, + * + * </ul> + * + * then {@link InterruptedException} is thrown and the current + * thread's interrupted status is cleared. + * + * <p>In this implementation, as this method is an explicit + * interruption point, preference is given to responding to + * the interrupt over normal or reentrant acquisition of the + * lock. + * + * @throws InterruptedException if the current thread is interrupted + */ + public void lockInterruptibly() throws InterruptedException { + sync.acquireSharedInterruptibly(1); + } + + /** + * Acquires the read lock only if the write lock is not held by + * another thread at the time of invocation. + * + * <p>Acquires the read lock if the write lock is not held by + * another thread and returns immediately with the value + * {@code true}. Even when this lock has been set to use a + * fair ordering policy, a call to {@code tryLock()} + * <em>will</em> immediately acquire the read lock if it is + * available, whether or not other threads are currently + * waiting for the read lock. This "barging" behavior + * can be useful in certain circumstances, even though it + * breaks fairness. If you want to honor the fairness setting + * for this lock, then use {@link #tryLock(long, TimeUnit) + * tryLock(0, TimeUnit.SECONDS) } which is almost equivalent + * (it also detects interruption). + * + * <p>If the write lock is held by another thread then + * this method will return immediately with the value + * {@code false}. + * + * @return {@code true} if the read lock was acquired + */ + public boolean tryLock() { + return sync.tryReadLock(); + } + + /** + * Acquires the read lock if the write lock is not held by + * another thread within the given waiting time and the + * current thread has not been {@linkplain Thread#interrupt + * interrupted}. + * + * <p>Acquires the read lock if the write lock is not held by + * another thread and returns immediately with the value + * {@code true}. If this lock has been set to use a fair + * ordering policy then an available lock <em>will not</em> be + * acquired if any other threads are waiting for the + * lock. This is in contrast to the {@link #tryLock()} + * method. If you want a timed {@code tryLock} that does + * permit barging on a fair lock then combine the timed and + * un-timed forms together: + * + * <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... } + * </pre> + * + * <p>If the write lock is held by another thread then the + * current thread becomes disabled for thread scheduling + * purposes and lies dormant until one of three things happens: + * + * <ul> + * + * <li>The read lock is acquired by the current thread; or + * + * <li>Some other thread {@linkplain Thread#interrupt interrupts} + * the current thread; or + * + * <li>The specified waiting time elapses. + * + * </ul> + * + * <p>If the read lock is acquired then the value {@code true} is + * returned. + * + * <p>If the current thread: + * + * <ul> + * + * <li>has its interrupted status set on entry to this method; or + * + * <li>is {@linkplain Thread#interrupt interrupted} while + * acquiring the read lock, + * + * </ul> then {@link InterruptedException} is thrown and the + * current thread's interrupted status is cleared. + * + * <p>If the specified waiting time elapses then the value + * {@code false} is returned. If the time is less than or + * equal to zero, the method will not wait at all. + * + * <p>In this implementation, as this method is an explicit + * interruption point, preference is given to responding to + * the interrupt over normal or reentrant acquisition of the + * lock, and over reporting the elapse of the waiting time. + * + * @param timeout the time to wait for the read lock + * @param unit the time unit of the timeout argument + * @return {@code true} if the read lock was acquired + * @throws InterruptedException if the current thread is interrupted + * @throws NullPointerException if the time unit is null + * + */ + public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException { + return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout)); + } + + /** + * Attempts to release this lock. + * + * <p> If the number of readers is now zero then the lock + * is made available for write lock attempts. + */ + public void unlock() { + sync.releaseShared(1); + } + + /** + * Throws {@code UnsupportedOperationException} because + * {@code ReadLocks} do not support conditions. + * + * @throws UnsupportedOperationException always + */ + public Condition newCondition() { + throw new UnsupportedOperationException(); + } + + /** + * Returns a string identifying this lock, as well as its lock state. + * The state, in brackets, includes the String {@code "Read locks ="} + * followed by the number of held read locks. + * + * @return a string identifying this lock, as well as its lock state + */ + public String toString() { + int r = sync.getReadLockCount(); + return super.toString() + + "[Read locks = " + r + "]"; + } + } + + /** + * The lock returned by method {@link ReentrantReadWriteLock#writeLock}. + */ + public static class WriteLock implements Lock, java.io.Serializable { + private static final long serialVersionUID = -4992448646407690164L; + private final Sync sync; + + /** + * Constructor for use by subclasses + * + * @param lock the outer lock object + * @throws NullPointerException if the lock is null + */ + protected WriteLock(ReentrantReadWriteLock lock) { + sync = lock.sync; + } + + /** + * Acquires the write lock. + * + * <p>Acquires the write lock if neither the read nor write lock + * are held by another thread + * and returns immediately, setting the write lock hold count to + * one. + * + * <p>If the current thread already holds the write lock then the + * hold count is incremented by one and the method returns + * immediately. + * + * <p>If the lock is held by another thread then the current + * thread becomes disabled for thread scheduling purposes and + * lies dormant until the write lock has been acquired, at which + * time the write lock hold count is set to one. + */ + public void lock() { + sync.acquire(1); + } + + /** + * Acquires the write lock unless the current thread is + * {@linkplain Thread#interrupt interrupted}. + * + * <p>Acquires the write lock if neither the read nor write lock + * are held by another thread + * and returns immediately, setting the write lock hold count to + * one. + * + * <p>If the current thread already holds this lock then the + * hold count is incremented by one and the method returns + * immediately. + * + * <p>If the lock is held by another thread then the current + * thread becomes disabled for thread scheduling purposes and + * lies dormant until one of two things happens: + * + * <ul> + * + * <li>The write lock is acquired by the current thread; or + * + * <li>Some other thread {@linkplain Thread#interrupt interrupts} + * the current thread. + * + * </ul> + * + * <p>If the write lock is acquired by the current thread then the + * lock hold count is set to one. + * + * <p>If the current thread: + * + * <ul> + * + * <li>has its interrupted status set on entry to this method; + * or + * + * <li>is {@linkplain Thread#interrupt interrupted} while + * acquiring the write lock, + * + * </ul> + * + * then {@link InterruptedException} is thrown and the current + * thread's interrupted status is cleared. + * + * <p>In this implementation, as this method is an explicit + * interruption point, preference is given to responding to + * the interrupt over normal or reentrant acquisition of the + * lock. + * + * @throws InterruptedException if the current thread is interrupted + */ + public void lockInterruptibly() throws InterruptedException { + sync.acquireInterruptibly(1); + } + + /** + * Acquires the write lock only if it is not held by another thread + * at the time of invocation. + * + * <p>Acquires the write lock if neither the read nor write lock + * are held by another thread + * and returns immediately with the value {@code true}, + * setting the write lock hold count to one. Even when this lock has + * been set to use a fair ordering policy, a call to + * {@code tryLock()} <em>will</em> immediately acquire the + * lock if it is available, whether or not other threads are + * currently waiting for the write lock. This "barging" + * behavior can be useful in certain circumstances, even + * though it breaks fairness. If you want to honor the + * fairness setting for this lock, then use {@link + * #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) } + * which is almost equivalent (it also detects interruption). + * + * <p> If the current thread already holds this lock then the + * hold count is incremented by one and the method returns + * {@code true}. + * + * <p>If the lock is held by another thread then this method + * will return immediately with the value {@code false}. + * + * @return {@code true} if the lock was free and was acquired + * by the current thread, or the write lock was already held + * by the current thread; and {@code false} otherwise. + */ + public boolean tryLock( ) { + return sync.tryWriteLock(); + } + + /** + * Acquires the write lock if it is not held by another thread + * within the given waiting time and the current thread has + * not been {@linkplain Thread#interrupt interrupted}. + * + * <p>Acquires the write lock if neither the read nor write lock + * are held by another thread + * and returns immediately with the value {@code true}, + * setting the write lock hold count to one. If this lock has been + * set to use a fair ordering policy then an available lock + * <em>will not</em> be acquired if any other threads are + * waiting for the write lock. This is in contrast to the {@link + * #tryLock()} method. If you want a timed {@code tryLock} + * that does permit barging on a fair lock then combine the + * timed and un-timed forms together: + * + * <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... } + * </pre> + * + * <p>If the current thread already holds this lock then the + * hold count is incremented by one and the method returns + * {@code true}. + * + * <p>If the lock is held by another thread then the current + * thread becomes disabled for thread scheduling purposes and + * lies dormant until one of three things happens: + * + * <ul> + * + * <li>The write lock is acquired by the current thread; or + * + * <li>Some other thread {@linkplain Thread#interrupt interrupts} + * the current thread; or + * + * <li>The specified waiting time elapses + * + * </ul> + * + * <p>If the write lock is acquired then the value {@code true} is + * returned and the write lock hold count is set to one. + * + * <p>If the current thread: + * + * <ul> + * + * <li>has its interrupted status set on entry to this method; + * or + * + * <li>is {@linkplain Thread#interrupt interrupted} while + * acquiring the write lock, + * + * </ul> + * + * then {@link InterruptedException} is thrown and the current + * thread's interrupted status is cleared. + * + * <p>If the specified waiting time elapses then the value + * {@code false} is returned. If the time is less than or + * equal to zero, the method will not wait at all. + * + * <p>In this implementation, as this method is an explicit + * interruption point, preference is given to responding to + * the interrupt over normal or reentrant acquisition of the + * lock, and over reporting the elapse of the waiting time. + * + * @param timeout the time to wait for the write lock + * @param unit the time unit of the timeout argument + * + * @return {@code true} if the lock was free and was acquired + * by the current thread, or the write lock was already held by the + * current thread; and {@code false} if the waiting time + * elapsed before the lock could be acquired. + * + * @throws InterruptedException if the current thread is interrupted + * @throws NullPointerException if the time unit is null + * + */ + public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException { + return sync.tryAcquireNanos(1, unit.toNanos(timeout)); + } + + /** + * Attempts to release this lock. + * + * <p>If the current thread is the holder of this lock then + * the hold count is decremented. If the hold count is now + * zero then the lock is released. If the current thread is + * not the holder of this lock then {@link + * IllegalMonitorStateException} is thrown. + * + * @throws IllegalMonitorStateException if the current thread does not + * hold this lock. + */ + public void unlock() { + sync.release(1); + } + + /** + * Returns a {@link Condition} instance for use with this + * {@link Lock} instance. + * <p>The returned {@link Condition} instance supports the same + * usages as do the {@link Object} monitor methods ({@link + * Object#wait() wait}, {@link Object#notify notify}, and {@link + * Object#notifyAll notifyAll}) when used with the built-in + * monitor lock. + * + * <ul> + * + * <li>If this write lock is not held when any {@link + * Condition} method is called then an {@link + * IllegalMonitorStateException} is thrown. (Read locks are + * held independently of write locks, so are not checked or + * affected. However it is essentially always an error to + * invoke a condition waiting method when the current thread + * has also acquired read locks, since other threads that + * could unblock it will not be able to acquire the write + * lock.) + * + * <li>When the condition {@linkplain Condition#await() waiting} + * methods are called the write lock is released and, before + * they return, the write lock is reacquired and the lock hold + * count restored to what it was when the method was called. + * + * <li>If a thread is {@linkplain Thread#interrupt interrupted} while + * waiting then the wait will terminate, an {@link + * InterruptedException} will be thrown, and the thread's + * interrupted status will be cleared. + * + * <li> Waiting threads are signalled in FIFO order. + * + * <li>The ordering of lock reacquisition for threads returning + * from waiting methods is the same as for threads initially + * acquiring the lock, which is in the default case not specified, + * but for <em>fair</em> locks favors those threads that have been + * waiting the longest. + * + * </ul> + * + * @return the Condition object + */ + public Condition newCondition() { + return sync.newCondition(); + } + + /** + * Returns a string identifying this lock, as well as its lock + * state. The state, in brackets includes either the String + * {@code "Unlocked"} or the String {@code "Locked by"} + * followed by the {@linkplain Thread#getName name} of the owning thread. + * + * @return a string identifying this lock, as well as its lock state + */ + public String toString() { + Thread o = sync.getOwner(); + return super.toString() + ((o == null) ? + "[Unlocked]" : + "[Locked by thread " + o.getName() + "]"); + } + + /** + * Queries if this write lock is held by the current thread. + * Identical in effect to {@link + * ReentrantReadWriteLock#isWriteLockedByCurrentThread}. + * + * @return {@code true} if the current thread holds this lock and + * {@code false} otherwise + * @since 1.6 + */ + public boolean isHeldByCurrentThread() { + return sync.isHeldExclusively(); + } + + /** + * Queries the number of holds on this write lock by the current + * thread. A thread has a hold on a lock for each lock action + * that is not matched by an unlock action. Identical in effect + * to {@link ReentrantReadWriteLock#getWriteHoldCount}. + * + * @return the number of holds on this lock by the current thread, + * or zero if this lock is not held by the current thread + * @since 1.6 + */ + public int getHoldCount() { + return sync.getWriteHoldCount(); + } + } + + // Instrumentation and status + + /** + * Returns {@code true} if this lock has fairness set true. + * + * @return {@code true} if this lock has fairness set true + */ + public final boolean isFair() { + return sync instanceof FairSync; + } + + /** + * Returns the thread that currently owns the write lock, or + * {@code null} if not owned. When this method is called by a + * thread that is not the owner, the return value reflects a + * best-effort approximation of current lock status. For example, + * the owner may be momentarily {@code null} even if there are + * threads trying to acquire the lock but have not yet done so. + * This method is designed to facilitate construction of + * subclasses that provide more extensive lock monitoring + * facilities. + * + * @return the owner, or {@code null} if not owned + */ + protected Thread getOwner() { + return sync.getOwner(); + } + + /** + * Queries the number of read locks held for this lock. This + * method is designed for use in monitoring system state, not for + * synchronization control. + * @return the number of read locks held. + */ + public int getReadLockCount() { + return sync.getReadLockCount(); + } + + /** + * Queries if the write lock is held by any thread. This method is + * designed for use in monitoring system state, not for + * synchronization control. + * + * @return {@code true} if any thread holds the write lock and + * {@code false} otherwise + */ + public boolean isWriteLocked() { + return sync.isWriteLocked(); + } + + /** + * Queries if the write lock is held by the current thread. + * + * @return {@code true} if the current thread holds the write lock and + * {@code false} otherwise + */ + public boolean isWriteLockedByCurrentThread() { + return sync.isHeldExclusively(); + } + + /** + * Queries the number of reentrant write holds on this lock by the + * current thread. A writer thread has a hold on a lock for + * each lock action that is not matched by an unlock action. + * + * @return the number of holds on the write lock by the current thread, + * or zero if the write lock is not held by the current thread + */ + public int getWriteHoldCount() { + return sync.getWriteHoldCount(); + } + + /** + * Queries the number of reentrant read holds on this lock by the + * current thread. A reader thread has a hold on a lock for + * each lock action that is not matched by an unlock action. + * + * @return the number of holds on the read lock by the current thread, + * or zero if the read lock is not held by the current thread + * @since 1.6 + */ + public int getReadHoldCount() { + return sync.getReadHoldCount(); + } + + /** + * Returns a collection containing threads that may be waiting to + * acquire the write lock. Because the actual set of threads may + * change dynamically while constructing this result, the returned + * collection is only a best-effort estimate. The elements of the + * returned collection are in no particular order. This method is + * designed to facilitate construction of subclasses that provide + * more extensive lock monitoring facilities. + * + * @return the collection of threads + */ + protected Collection<Thread> getQueuedWriterThreads() { + return sync.getExclusiveQueuedThreads(); + } + + /** + * Returns a collection containing threads that may be waiting to + * acquire the read lock. Because the actual set of threads may + * change dynamically while constructing this result, the returned + * collection is only a best-effort estimate. The elements of the + * returned collection are in no particular order. This method is + * designed to facilitate construction of subclasses that provide + * more extensive lock monitoring facilities. + * + * @return the collection of threads + */ + protected Collection<Thread> getQueuedReaderThreads() { + return sync.getSharedQueuedThreads(); + } + + /** + * Queries whether any threads are waiting to acquire the read or + * write lock. Note that because cancellations may occur at any + * time, a {@code true} return does not guarantee that any other + * thread will ever acquire a lock. This method is designed + * primarily for use in monitoring of the system state. + * + * @return {@code true} if there may be other threads waiting to + * acquire the lock + */ + public final boolean hasQueuedThreads() { + return sync.hasQueuedThreads(); + } + + /** + * Queries whether the given thread is waiting to acquire either + * the read or write lock. Note that because cancellations may + * occur at any time, a {@code true} return does not guarantee + * that this thread will ever acquire a lock. This method is + * designed primarily for use in monitoring of the system state. + * + * @param thread the thread + * @return {@code true} if the given thread is queued waiting for this lock + * @throws NullPointerException if the thread is null + */ + public final boolean hasQueuedThread(Thread thread) { + return sync.isQueued(thread); + } + + /** + * Returns an estimate of the number of threads waiting to acquire + * either the read or write lock. The value is only an estimate + * because the number of threads may change dynamically while this + * method traverses internal data structures. This method is + * designed for use in monitoring of the system state, not for + * synchronization control. + * + * @return the estimated number of threads waiting for this lock + */ + public final int getQueueLength() { + return sync.getQueueLength(); + } + + /** + * Returns a collection containing threads that may be waiting to + * acquire either the read or write lock. Because the actual set + * of threads may change dynamically while constructing this + * result, the returned collection is only a best-effort estimate. + * The elements of the returned collection are in no particular + * order. This method is designed to facilitate construction of + * subclasses that provide more extensive monitoring facilities. + * + * @return the collection of threads + */ + protected Collection<Thread> getQueuedThreads() { + return sync.getQueuedThreads(); + } + + /** + * Queries whether any threads are waiting on the given condition + * associated with the write lock. Note that because timeouts and + * interrupts may occur at any time, a {@code true} return does + * not guarantee that a future {@code signal} will awaken any + * threads. This method is designed primarily for use in + * monitoring of the system state. + * + * @param condition the condition + * @return {@code true} if there are any waiting threads + * @throws IllegalMonitorStateException if this lock is not held + * @throws IllegalArgumentException if the given condition is + * not associated with this lock + * @throws NullPointerException if the condition is null + */ + public boolean hasWaiters(Condition condition) { + if (condition == null) + throw new NullPointerException(); + if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject)) + throw new IllegalArgumentException("not owner"); + return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition); + } + + /** + * Returns an estimate of the number of threads waiting on the + * given condition associated with the write lock. Note that because + * timeouts and interrupts may occur at any time, the estimate + * serves only as an upper bound on the actual number of waiters. + * This method is designed for use in monitoring of the system + * state, not for synchronization control. + * + * @param condition the condition + * @return the estimated number of waiting threads + * @throws IllegalMonitorStateException if this lock is not held + * @throws IllegalArgumentException if the given condition is + * not associated with this lock + * @throws NullPointerException if the condition is null + */ + public int getWaitQueueLength(Condition condition) { + if (condition == null) + throw new NullPointerException(); + if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject)) + throw new IllegalArgumentException("not owner"); + return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition); + } + + /** + * Returns a collection containing those threads that may be + * waiting on the given condition associated with the write lock. + * Because the actual set of threads may change dynamically while + * constructing this result, the returned collection is only a + * best-effort estimate. The elements of the returned collection + * are in no particular order. This method is designed to + * facilitate construction of subclasses that provide more + * extensive condition monitoring facilities. + * + * @param condition the condition + * @return the collection of threads + * @throws IllegalMonitorStateException if this lock is not held + * @throws IllegalArgumentException if the given condition is + * not associated with this lock + * @throws NullPointerException if the condition is null + */ + protected Collection<Thread> getWaitingThreads(Condition condition) { + if (condition == null) + throw new NullPointerException(); + if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject)) + throw new IllegalArgumentException("not owner"); + return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition); + } + + /** + * Returns a string identifying this lock, as well as its lock state. + * The state, in brackets, includes the String {@code "Write locks ="} + * followed by the number of reentrantly held write locks, and the + * String {@code "Read locks ="} followed by the number of held + * read locks. + * + * @return a string identifying this lock, as well as its lock state + */ + public String toString() { + int c = sync.getCount(); + int w = Sync.exclusiveCount(c); + int r = Sync.sharedCount(c); + + return super.toString() + + "[Write locks = " + w + ", Read locks = " + r + "]"; + } + +} diff --git a/libjava/classpath/external/jsr166/readme b/libjava/classpath/external/jsr166/readme new file mode 100644 index 000000000..eef3c9169 --- /dev/null +++ b/libjava/classpath/external/jsr166/readme @@ -0,0 +1,45 @@ +The software comprising JSR166 was written by Doug Lea with assistance +from members of JCP JSR-166 Expert roup and released to the public +domain, as explained at: +http://creativecommons.org/licenses/publicdomain, excepting portions +of the class java.util.concurrent.CopyOnWriteArrayList, which were +adapted from class java.util.ArrayList, written by Sun Microsystems, +Inc, which are used with kind permission, and subject to the +following: + +Copyright 2002-2004 Sun Microsystems, Inc. All rights reserved. Use is +subject to the following license terms. + + "Sun hereby grants you a non-exclusive, worldwide, non-transferrable + license to use and distribute the Java Software technologies as part + of a larger work in source and binary forms, with or without + modification, provided that the following conditions are met: + + -Neither the name of or trademarks of Sun may be used to endorse or + promote products derived from the Java Software technology without + specific prior written permission. + + -Redistributions of source or binary code must be accompanied by the + following notice and disclaimers: + + Portions copyright Sun Microsystems, Inc. Used with kind permission. + + This software is provided AS IS, without a warranty of any kind. ALL + EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PUPOSE OR + NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + MICROSYSTEMS, INC. AND ITS LICENSORS SHALL NOT BE LIABLE + FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + USING, MODIFYING OR DISTRIBUTING THE SOFTWARE OR ITS + DERIVATIVES. IN NO EVENT WILL SUN MICROSYSTEMS, INC. OR + ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR + DATA, OR FOR DIRECT, INDIRECT,CONSQUENTIAL, INCIDENTAL + OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF + THE THEORY OR LIABILITY, ARISING OUT OF THE USE OF OR + INABILITY TO USE SOFTWARE, EVEN IF SUN MICROSYSTEMS, INC. + HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + + You acknowledge that Software is not designed, licensed or intended for + use in the design, construction, operation or maintenance of any nuclear + facility." diff --git a/libjava/classpath/external/relaxngDatatype/.cvsignore b/libjava/classpath/external/relaxngDatatype/.cvsignore new file mode 100644 index 000000000..282522db0 --- /dev/null +++ b/libjava/classpath/external/relaxngDatatype/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/libjava/classpath/external/relaxngDatatype/Makefile.am b/libjava/classpath/external/relaxngDatatype/Makefile.am new file mode 100644 index 000000000..8afce6597 --- /dev/null +++ b/libjava/classpath/external/relaxngDatatype/Makefile.am @@ -0,0 +1,14 @@ +## Input file for automake to generate the Makefile.in used by configure + +EXTRA_DIST = README.txt \ +copying.txt \ +org/relaxng/datatype/Datatype.java \ +org/relaxng/datatype/DatatypeBuilder.java \ +org/relaxng/datatype/DatatypeException.java \ +org/relaxng/datatype/DatatypeLibrary.java \ +org/relaxng/datatype/DatatypeLibraryFactory.java \ +org/relaxng/datatype/DatatypeStreamingValidator.java \ +org/relaxng/datatype/ValidationContext.java \ +org/relaxng/datatype/helpers/DatatypeLibraryLoader.java \ +org/relaxng/datatype/helpers/ParameterlessDatatypeBuilder.java \ +org/relaxng/datatype/helpers/StreamingValidatorImpl.java diff --git a/libjava/classpath/external/relaxngDatatype/Makefile.in b/libjava/classpath/external/relaxngDatatype/Makefile.in new file mode 100644 index 000000000..f90913716 --- /dev/null +++ b/libjava/classpath/external/relaxngDatatype/Makefile.in @@ -0,0 +1,450 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = external/relaxngDatatype +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/../../config/depstand.m4 \ + $(top_srcdir)/../../config/lead-dot.m4 \ + $(top_srcdir)/../../config/lib-ld.m4 \ + $(top_srcdir)/../../config/lib-link.m4 \ + $(top_srcdir)/../../config/lib-prefix.m4 \ + $(top_srcdir)/../../config/multi.m4 \ + $(top_srcdir)/../../config/no-executables.m4 \ + $(top_srcdir)/../../config/override.m4 \ + $(top_srcdir)/../../libtool.m4 \ + $(top_srcdir)/../../ltoptions.m4 \ + $(top_srcdir)/../../ltsugar.m4 \ + $(top_srcdir)/../../ltversion.m4 \ + $(top_srcdir)/../../lt~obsolete.m4 \ + $(top_srcdir)/m4/ac_prog_antlr.m4 \ + $(top_srcdir)/m4/ac_prog_java.m4 \ + $(top_srcdir)/m4/ac_prog_java_works.m4 \ + $(top_srcdir)/m4/ac_prog_javac.m4 \ + $(top_srcdir)/m4/ac_prog_javac_works.m4 \ + $(top_srcdir)/m4/acattribute.m4 $(top_srcdir)/m4/accross.m4 \ + $(top_srcdir)/m4/acinclude.m4 \ + $(top_srcdir)/m4/ax_create_stdint_h.m4 \ + $(top_srcdir)/m4/ax_func_which_gethostbyname_r.m4 \ + $(top_srcdir)/m4/gcc_attribute.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/../../mkinstalldirs +CONFIG_HEADER = $(top_builddir)/include/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +ANTLR = @ANTLR@ +ANTLR_JAR = @ANTLR_JAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CAIRO_CFLAGS = @CAIRO_CFLAGS@ +CAIRO_LIBS = @CAIRO_LIBS@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLASSPATH_CONVENIENCE = @CLASSPATH_CONVENIENCE@ +CLASSPATH_INCLUDES = @CLASSPATH_INCLUDES@ +CLASSPATH_MODULE = @CLASSPATH_MODULE@ +COLLECTIONS_PREFIX = @COLLECTIONS_PREFIX@ +CP = @CP@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATE = @DATE@ +DEFAULT_PREFS_PEER = @DEFAULT_PREFS_PEER@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +ECJ_JAR = @ECJ_JAR@ +EGREP = @EGREP@ +ERROR_CFLAGS = @ERROR_CFLAGS@ +EXAMPLESDIR = @EXAMPLESDIR@ +EXEEXT = @EXEEXT@ +EXTRA_CFLAGS = @EXTRA_CFLAGS@ +FGREP = @FGREP@ +FIND = @FIND@ +FREETYPE2_CFLAGS = @FREETYPE2_CFLAGS@ +FREETYPE2_LIBS = @FREETYPE2_LIBS@ +GCONF_CFLAGS = @GCONF_CFLAGS@ +GCONF_LIBS = @GCONF_LIBS@ +GDK_CFLAGS = @GDK_CFLAGS@ +GDK_LIBS = @GDK_LIBS@ +GJDOC = @GJDOC@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +GMP_CFLAGS = @GMP_CFLAGS@ +GMP_LIBS = @GMP_LIBS@ +GREP = @GREP@ +GSTREAMER_BASE_CFLAGS = @GSTREAMER_BASE_CFLAGS@ +GSTREAMER_BASE_LIBS = @GSTREAMER_BASE_LIBS@ +GSTREAMER_CFLAGS = @GSTREAMER_CFLAGS@ +GSTREAMER_FILE_READER = @GSTREAMER_FILE_READER@ +GSTREAMER_LIBS = @GSTREAMER_LIBS@ +GSTREAMER_MIXER_PROVIDER = @GSTREAMER_MIXER_PROVIDER@ +GSTREAMER_PLUGINS_BASE_CFLAGS = @GSTREAMER_PLUGINS_BASE_CFLAGS@ +GSTREAMER_PLUGINS_BASE_LIBS = @GSTREAMER_PLUGINS_BASE_LIBS@ +GST_PLUGIN_LDFLAGS = @GST_PLUGIN_LDFLAGS@ +GTK_CFLAGS = @GTK_CFLAGS@ +GTK_LIBS = @GTK_LIBS@ +INIT_LOAD_LIBRARY = @INIT_LOAD_LIBRARY@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JAR = @JAR@ +JAVA = @JAVA@ +JAVAC = @JAVAC@ +JAVAC_IS_GCJ = @JAVAC_IS_GCJ@ +JAVAC_MEM_OPT = @JAVAC_MEM_OPT@ +JAVA_LANG_SYSTEM_EXPLICIT_INITIALIZATION = @JAVA_LANG_SYSTEM_EXPLICIT_INITIALIZATION@ +JAY = @JAY@ +JAY_SKELETON = @JAY_SKELETON@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBDEBUG = @LIBDEBUG@ +LIBICONV = @LIBICONV@ +LIBMAGIC = @LIBMAGIC@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBVERSION = @LIBVERSION@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR = @MKDIR@ +MKDIR_P = @MKDIR_P@ +MOC = @MOC@ +MOZILLA_CFLAGS = @MOZILLA_CFLAGS@ +MOZILLA_LIBS = @MOZILLA_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PANGOFT2_CFLAGS = @PANGOFT2_CFLAGS@ +PANGOFT2_LIBS = @PANGOFT2_LIBS@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PATH_TO_ESCHER = @PATH_TO_ESCHER@ +PATH_TO_GLIBJ_ZIP = @PATH_TO_GLIBJ_ZIP@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PLUGIN_DIR = @PLUGIN_DIR@ +QT_CFLAGS = @QT_CFLAGS@ +QT_LIBS = @QT_LIBS@ +RANLIB = @RANLIB@ +REMOVE = @REMOVE@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRICT_WARNING_CFLAGS = @STRICT_WARNING_CFLAGS@ +STRIP = @STRIP@ +TOOLSDIR = @TOOLSDIR@ +USER_JAVAH = @USER_JAVAH@ +VERSION = @VERSION@ +WANT_NATIVE_BIG_INTEGER = @WANT_NATIVE_BIG_INTEGER@ +WARNING_CFLAGS = @WARNING_CFLAGS@ +XMKMF = @XMKMF@ +XML_CFLAGS = @XML_CFLAGS@ +XML_LIBS = @XML_LIBS@ +XSLT_CFLAGS = @XSLT_CFLAGS@ +XSLT_LIBS = @XSLT_LIBS@ +XTEST_LIBS = @XTEST_LIBS@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +ZIP = @ZIP@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_ANTLR = @ac_ct_ANTLR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +default_toolkit = @default_toolkit@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +glibjdir = @glibjdir@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +multi_basedir = @multi_basedir@ +nativeexeclibdir = @nativeexeclibdir@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +toolexeclibdir = @toolexeclibdir@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +uudecode = @uudecode@ +vm_classes = @vm_classes@ +EXTRA_DIST = README.txt \ +copying.txt \ +org/relaxng/datatype/Datatype.java \ +org/relaxng/datatype/DatatypeBuilder.java \ +org/relaxng/datatype/DatatypeException.java \ +org/relaxng/datatype/DatatypeLibrary.java \ +org/relaxng/datatype/DatatypeLibraryFactory.java \ +org/relaxng/datatype/DatatypeStreamingValidator.java \ +org/relaxng/datatype/ValidationContext.java \ +org/relaxng/datatype/helpers/DatatypeLibraryLoader.java \ +org/relaxng/datatype/helpers/ParameterlessDatatypeBuilder.java \ +org/relaxng/datatype/helpers/StreamingValidatorImpl.java + +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu external/relaxngDatatype/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu external/relaxngDatatype/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libjava/classpath/external/relaxngDatatype/README.txt b/libjava/classpath/external/relaxngDatatype/README.txt new file mode 100755 index 000000000..70d49b5fa --- /dev/null +++ b/libjava/classpath/external/relaxngDatatype/README.txt @@ -0,0 +1,54 @@ +======================================================================
+ README FILE FOR DATATYPE INTERFACES FOR RELAX NG
+======================================================================
+
+
+
+RELAX NG supports multiple datatype vocabularies. To achive this, an
+interface between datatype vocabularies and schema processors is
+necessary. This interface is intended to be a standard Java interface
+for this purpose.
+
+
+----------------------------------------------------------------------
+LICENSE
+----------------------------------------------------------------------
+
+See copying.txt.
+
+Note: this license is the BSD license.
+
+
+
+----------------------------------------------------------------------
+FOR DEVELOPER
+----------------------------------------------------------------------
+
+If you are planning to implement a datatype library, A sample datatype
+library implementation by James Clark is available at [1], which
+comes with documentation and source code.
+
+If you are planning to implement a schema processor, then don't forget
+to check out org.relaxng.datatype.helpers.DatatypeLibraryLoader, as
+this allows you to dynamically locate datatype implementations.
+
+
+----------------------------------------------------------------------
+LINKS
+----------------------------------------------------------------------
+
+* OASIS RELAX NG TC
+ http://www.oasis-open.org/committees/relax-ng/
+* RELAX home page
+ http://www.xml.gr.jp/relax/
+
+
+----------------------------------------------------------------------
+REFERENCES
+----------------------------------------------------------------------
+[1] Sample datatype library implementation by James Clark
+ http://www.thaiopensource.com/relaxng/datatype-sample.zip
+
+Document written by Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
+======================================================================
+END OF README
diff --git a/libjava/classpath/external/relaxngDatatype/copying.txt b/libjava/classpath/external/relaxngDatatype/copying.txt new file mode 100755 index 000000000..1b86eab60 --- /dev/null +++ b/libjava/classpath/external/relaxngDatatype/copying.txt @@ -0,0 +1,30 @@ +Copyright (c) 2001, Thai Open Source Software Center Ltd, Sun Microsystems.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the names of the copyright holders nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/Datatype.java b/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/Datatype.java new file mode 100755 index 000000000..325384c27 --- /dev/null +++ b/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/Datatype.java @@ -0,0 +1,237 @@ +package org.relaxng.datatype; + +/** + * Datatype object. + * + * This object has the following functionality: + * + * <ol> + * <li> functionality to identify a class of character sequences. This is + * done through the isValid method. + * + * <li> functionality to produce a "value object" from a character sequence and + * context information. + * + * <li> functionality to test the equality of two value objects. + * </ol> + * + * This interface also defines the createStreamingValidator method, + * which is intended to efficiently support the validation of + * large character sequences. + * + * @author <a href="mailto:jjc@jclark.com">James Clark</a> + * @author <a href="mailto:kohsuke.kawaguchi@sun.com">Kohsuke KAWAGUCHI</a> + */ +public interface Datatype { + + /** + * Checks if the specified 'literal' matches this Datatype + * with respect to the current context. + * + * @param literal + * the lexical representation to be checked. + * @param context + * If this datatype is context-dependent + * (i.e. the {@link #isContextDependent} method returns true), + * then the caller must provide a non-null valid context object. + * Otherwise, the caller can pass null. + * + * @return + * true if the 'literal' is a member of this Datatype; + * false if it's not a member of this Datatype. + */ + boolean isValid( String literal, ValidationContext context ); + + /** + * Similar to the isValid method but throws an exception with diagnosis + * in case of errors. + * + * <p> + * If the specified 'literal' is a valid lexical representation for this + * datatype, then this method must return without throwing any exception. + * If not, the callee must throw an exception (with diagnosis message, + * if possible.) + * + * <p> + * The application can use this method to provide detailed error message + * to users. This method is kept separate from the isValid method to + * achieve higher performance during normal validation. + * + * @exception DatatypeException + * If the given literal is invalid, then this exception is thrown. + * If the callee supports error diagnosis, then the exception should + * contain a diagnosis message. + */ + void checkValid( String literal, ValidationContext context ) + throws DatatypeException; + + /** + * Creates an instance of a streaming validator for this type. + * + * <p> + * By using streaming validators instead of the isValid method, + * the caller can avoid keeping the entire string, which is + * sometimes quite big, in memory. + * + * @param context + * If this datatype is context-dependent + * (i.e. the {@link #isContextDependent} method returns true), + * then the caller must provide a non-null valid context object. + * Otherwise, the caller can pass null. + * The callee may keep a reference to this context object + * only while the returned streaming validator is being used. + */ + DatatypeStreamingValidator createStreamingValidator( ValidationContext context ); + + /** + * Converts lexcial value and the current context to the corresponding + * value object. + * + * <p> + * The caller cannot generally assume that the value object is + * a meaningful Java object. For example, the caller cannot expect + * this method to return <code>java.lang.Number</code> type for + * the "integer" type of XML Schema Part 2. + * + * <p> + * Also, the caller cannot assume that the equals method and + * the hashCode method of the value object are consistent with + * the semantics of the datatype. For that purpose, the sameValue + * method and the valueHashCode method have to be used. Note that + * this means you cannot use classes like + * <code>java.util.Hashtable</code> to store the value objects. + * + * <p> + * The returned value object should be used solely for the sameValue + * and valueHashCode methods. + * + * @param context + * If this datatype is context-dependent + * (when the {@link #isContextDependent} method returns true), + * then the caller must provide a non-null valid context object. + * Otherwise, the caller can pass null. + * + * @return null + * when the given lexical value is not a valid lexical + * value for this type. + */ + Object createValue( String literal, ValidationContext context ); + + /** + * Tests the equality of two value objects which were originally + * created by the createValue method of this object. + * + * The behavior is undefined if objects not created by this type + * are passed. It is the caller's responsibility to ensure that + * value objects belong to this type. + * + * @return + * true if two value objects are considered equal according to + * the definition of this datatype; false if otherwise. + */ + boolean sameValue( Object value1, Object value2 ); + + + /** + * Computes the hash code for a value object, + * which is consistent with the sameValue method. + * + * @return + * hash code for the specified value object. + */ + int valueHashCode( Object value ); + + + + + /** + * Indicates that the datatype doesn't have ID/IDREF semantics. + * + * This value is one of the possible return values of the + * {@link #getIdType} method. + */ + public static final int ID_TYPE_NULL = 0; + + /** + * Indicates that RELAX NG compatibility processors should + * treat this datatype as having ID semantics. + * + * This value is one of the possible return values of the + * {@link #getIdType} method. + */ + public static final int ID_TYPE_ID = 1; + + /** + * Indicates that RELAX NG compatibility processors should + * treat this datatype as having IDREF semantics. + * + * This value is one of the possible return values of the + * {@link #getIdType} method. + */ + public static final int ID_TYPE_IDREF = 2; + + /** + * Indicates that RELAX NG compatibility processors should + * treat this datatype as having IDREFS semantics. + * + * This value is one of the possible return values of the + * {@link #getIdType} method. + */ + public static final int ID_TYPE_IDREFS = 3; + + /** + * Checks if the ID/IDREF semantics is associated with this + * datatype. + * + * <p> + * This method is introduced to support the RELAX NG DTD + * compatibility spec. (Of course it's always free to use + * this method for other purposes.) + * + * <p> + * If you are implementing a datatype library and have no idea about + * the "RELAX NG DTD compatibility" thing, just return + * <code>ID_TYPE_NULL</code> is fine. + * + * @return + * If this datatype doesn't have any ID/IDREF semantics, + * it returns {@link #ID_TYPE_NULL}. If it has such a semantics + * (for example, XSD:ID, XSD:IDREF and comp:ID type), then + * it returns {@link #ID_TYPE_ID}, {@link #ID_TYPE_IDREF} or + * {@link #ID_TYPE_IDREFS}. + */ + public int getIdType(); + + + /** + * Checks if this datatype may need a context object for + * the validation. + * + * <p> + * The callee must return true even when the context + * is not always necessary. (For example, the "QName" type + * doesn't need a context object when validating unprefixed + * string. But nonetheless QName must return true.) + * + * <p> + * XSD's <code>string</code> and <code>short</code> types + * are examples of context-independent datatypes. + * Its <code>QName</code> and <code>ENTITY</code> types + * are examples of context-dependent datatypes. + * + * <p> + * When a datatype is context-independent, then + * the {@link #isValid} method, the {@link #checkValid} method, + * the {@link #createStreamingValidator} method and + * the {@link #createValue} method can be called without + * providing a context object. + * + * @return + * <b>true</b> if this datatype is context-dependent + * (it needs a context object sometimes); + * + * <b>false</b> if this datatype is context-<b>in</b>dependent + * (it never needs a context object). + */ + public boolean isContextDependent(); +} diff --git a/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/DatatypeBuilder.java b/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/DatatypeBuilder.java new file mode 100755 index 000000000..0a2b55e2e --- /dev/null +++ b/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/DatatypeBuilder.java @@ -0,0 +1,45 @@ +package org.relaxng.datatype; + +/** + * Creates a user-defined type by adding parameters to + * the pre-defined type. + * + * @author <a href="mailto:jjc@jclark.com">James Clark</a> + * @author <a href="mailto:kohsuke.kawaguchi@sun.com">Kohsuke KAWAGUCHI</a> + */ +public interface DatatypeBuilder { + + /** + * Adds a new parameter. + * + * @param name + * The name of the parameter to be added. + * @param strValue + * The raw value of the parameter. Caller may not normalize + * this value because any white space is potentially significant. + * @param context + * The context information which can be used by the callee to + * acquire additional information. This context object is + * valid only during this method call. The callee may not + * keep a reference to this object. + * @exception DatatypeException + * When the given parameter is inappropriate for some reason. + * The callee is responsible to recover from this error. + * That is, the object should behave as if no such error + * was occured. + */ + void addParameter( String name, String strValue, ValidationContext context ) + throws DatatypeException; + + /** + * Derives a new Datatype from a Datatype by parameters that + * were already set through the addParameter method. + * + * @exception DatatypeException + * DatatypeException must be thrown if the derivation is + * somehow invalid. For example, a required parameter is missing, + * etc. The exception should contain a diagnosis message + * if possible. + */ + Datatype createDatatype() throws DatatypeException; +} diff --git a/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/DatatypeException.java b/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/DatatypeException.java new file mode 100755 index 000000000..554385fe4 --- /dev/null +++ b/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/DatatypeException.java @@ -0,0 +1,39 @@ +package org.relaxng.datatype; + +/** + * Signals Datatype related exceptions. + * + * @author <a href="mailto:jjc@jclark.com">James Clark</a> + * @author <a href="mailto:kohsuke.kawaguchi@sun.com">Kohsuke KAWAGUCHI</a> + */ +public class DatatypeException extends Exception { + + public DatatypeException( int index, String msg ) { + super(msg); + this.index = index; + } + public DatatypeException( String msg ) { + this(UNKNOWN,msg); + } + /** + * A constructor for those datatype libraries which don't support any + * diagnostic information at all. + */ + public DatatypeException() { + this(UNKNOWN,null); + } + + + private final int index; + + public static final int UNKNOWN = -1; + + /** + * Gets the index of the content where the error occured. + * UNKNOWN can be returned to indicate that no index information + * is available. + */ + public int getIndex() { + return index; + } +} diff --git a/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/DatatypeLibrary.java b/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/DatatypeLibrary.java new file mode 100755 index 000000000..3a9b4d0bb --- /dev/null +++ b/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/DatatypeLibrary.java @@ -0,0 +1,37 @@ +package org.relaxng.datatype; + +/** + * A Datatype library + * + * @author <a href="mailto:jjc@jclark.com">James Clark</a> + * @author <a href="mailto:kohsuke.kawaguchi@sun.com">Kohsuke KAWAGUCHI</a> + */ +public interface DatatypeLibrary { + + /** + * Creates a new instance of DatatypeBuilder. + * + * The callee should throw a DatatypeException in case of an error. + * + * @param baseTypeLocalName + * The local name of the base type. + * + * @return + * A non-null valid datatype object. + */ + DatatypeBuilder createDatatypeBuilder( String baseTypeLocalName ) + throws DatatypeException; + + /** + * Gets or creates a pre-defined type. + * + * This is just a short-cut of + * <code>createDatatypeBuilder(typeLocalName).createDatatype();</code> + * + * The callee should throw a DatatypeException in case of an error. + * + * @return + * A non-null valid datatype object. + */ + Datatype createDatatype( String typeLocalName ) throws DatatypeException; +} diff --git a/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/DatatypeLibraryFactory.java b/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/DatatypeLibraryFactory.java new file mode 100755 index 000000000..ebc9b910b --- /dev/null +++ b/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/DatatypeLibraryFactory.java @@ -0,0 +1,26 @@ +package org.relaxng.datatype; + +/** + * Factory class for the DatatypeLibrary class. + * + * <p> + * The datatype library should provide the implementation of + * this interface if it wants to be found by the schema processors. + * The implementor also have to place a file in your jar file. + * See the reference datatype library implementation for detail. + * + * @author <a href="mailto:jjc@jclark.com">James Clark</a> + * @author <a href="mailto:kohsuke.kawaguchi@sun.com">Kohsuke KAWAGUCHI</a> + */ +public interface DatatypeLibraryFactory +{ + /** + * Creates a new instance of a DatatypeLibrary that supports + * the specified namespace URI. + * + * @return + * <code>null</code> if the specified namespace URI is not + * supported. + */ + DatatypeLibrary createDatatypeLibrary( String namespaceURI ); +} diff --git a/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/DatatypeStreamingValidator.java b/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/DatatypeStreamingValidator.java new file mode 100755 index 000000000..d181b0329 --- /dev/null +++ b/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/DatatypeStreamingValidator.java @@ -0,0 +1,46 @@ +package org.relaxng.datatype; + +/** + * Datatype streaming validator. + * + * <p> + * The streaming validator is an optional feature that is useful for + * certain Datatypes. It allows the caller to incrementally provide + * the literal. + * + * @author <a href="mailto:jjc@jclark.com">James Clark</a> + * @author <a href="mailto:kohsuke.kawaguchi@sun.com">Kohsuke KAWAGUCHI</a> + */ +public interface DatatypeStreamingValidator { + + /** + * Passes an additional fragment of the literal. + * + * <p> + * The application can call this method several times, then call + * the isValid method (or the checkValid method) to check the validity + * of the accumulated characters. + */ + void addCharacters( char[] buf, int start, int len ); + + /** + * Tells if the accumulated literal is valid with respect to + * the underlying Datatype. + * + * @return + * True if it is valid. False if otherwise. + */ + boolean isValid(); + + /** + * Similar to the isValid method, but this method throws + * Exception (with possibly diagnostic information), instead of + * returning false. + * + * @exception DatatypeException + * If the callee supports the diagnosis and the accumulated + * literal is invalid, then this exception that possibly + * contains diagnosis information is thrown. + */ + void checkValid() throws DatatypeException; +} diff --git a/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/ValidationContext.java b/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/ValidationContext.java new file mode 100755 index 000000000..b25df7c7a --- /dev/null +++ b/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/ValidationContext.java @@ -0,0 +1,66 @@ +package org.relaxng.datatype; + +/** + * An interface that must be implemented by caller to + * provide context information that is necessary to + * perform validation of some Datatypes. + * + * @author <a href="mailto:jjc@jclark.com">James Clark</a> + * @author <a href="mailto:kohsuke.kawaguchi@sun.com">Kohsuke KAWAGUCHI</a> + */ +public interface ValidationContext { + + /** + * Resolves a namespace prefix to the corresponding namespace URI. + * + * This method is used for validating the QName type, for example. + * + * <p> + * If the prefix is "" (empty string), it indicates + * an unprefixed value. The callee + * should resolve it as for an unprefixed + * element, rather than for an unprefixed attribute. + * + * <p> + * If the prefix is "xml", then the callee must resolve + * this prefix into "http://www.w3.org/XML/1998/namespace", + * as defined in the XML Namespaces Recommendation. + * + * @return + * namespace URI of this prefix. + * If the specified prefix is not declared, + * the implementation must return null. + */ + String resolveNamespacePrefix( String prefix ); + + /** + * Returns the base URI of the context. The null string may be returned + * if no base URI is known. + */ + String getBaseUri(); + + /** + * Checks if an unparsed entity is declared with the + * specified name. + * + * @return + * true + * if the DTD has an unparsed entity declaration for + * the specified name. + * false + * otherwise. + */ + boolean isUnparsedEntity( String entityName ); + + /** + * Checks if a notation is declared with the + * specified name. + * + * @return + * true + * if the DTD has a notation declaration for the specified name. + * false + * otherwise. + */ + boolean isNotation( String notationName ); +} diff --git a/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/helpers/DatatypeLibraryLoader.java b/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/helpers/DatatypeLibraryLoader.java new file mode 100755 index 000000000..3aa7c0481 --- /dev/null +++ b/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/helpers/DatatypeLibraryLoader.java @@ -0,0 +1,261 @@ +/** + * Copyright (c) 2001, Thai Open Source Software Center Ltd + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Thai Open Source Software Center Ltd nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.relaxng.datatype.helpers; + +import org.relaxng.datatype.DatatypeLibraryFactory; +import org.relaxng.datatype.DatatypeLibrary; +import java.util.Enumeration; +import java.util.NoSuchElementException; +import java.util.Vector; +import java.io.Reader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URL; + +/** + * Discovers the datatype library implementation from the classpath. + * + * <p> + * The call of the createDatatypeLibrary method finds an implementation + * from a given datatype library URI at run-time. + */ +public class DatatypeLibraryLoader implements DatatypeLibraryFactory { + private final Service service = new Service(DatatypeLibraryFactory.class); + + public DatatypeLibrary createDatatypeLibrary(String uri) { + for (Enumeration e = service.getProviders(); + e.hasMoreElements();) { + DatatypeLibraryFactory factory + = (DatatypeLibraryFactory)e.nextElement(); + DatatypeLibrary library = factory.createDatatypeLibrary(uri); + if (library != null) + return library; + } + return null; + } + + private static class Service { + private final Class serviceClass; + private final Enumeration configFiles; + private Enumeration classNames = null; + private final Vector providers = new Vector(); + private Loader loader; + + private class ProviderEnumeration implements Enumeration { + private int nextIndex = 0; + + public boolean hasMoreElements() { + return nextIndex < providers.size() || moreProviders(); + } + + public Object nextElement() { + try { + return providers.elementAt(nextIndex++); + } + catch (ArrayIndexOutOfBoundsException e) { + throw new NoSuchElementException(); + } + } + } + + private static class Singleton implements Enumeration { + private Object obj; + private Singleton(Object obj) { + this.obj = obj; + } + + public boolean hasMoreElements() { + return obj != null; + } + + public Object nextElement() { + if (obj == null) + throw new NoSuchElementException(); + Object tem = obj; + obj = null; + return tem; + } + } + + // JDK 1.1 + private static class Loader { + Enumeration getResources(String resName) { + ClassLoader cl = Loader.class.getClassLoader(); + URL url; + if (cl == null) + url = ClassLoader.getSystemResource(resName); + else + url = cl.getResource(resName); + return new Singleton(url); + } + + Class loadClass(String name) throws ClassNotFoundException { + return Class.forName(name); + } + } + + // JDK 1.2+ + private static class Loader2 extends Loader { + private ClassLoader cl; + + Loader2() { + cl = Loader2.class.getClassLoader(); + // If the thread context class loader has the class loader + // of this class as an ancestor, use the thread context class + // loader. Otherwise, the thread context class loader + // probably hasn't been set up properly, so don't use it. + ClassLoader clt = Thread.currentThread().getContextClassLoader(); + for (ClassLoader tem = clt; tem != null; tem = tem.getParent()) + if (tem == cl) { + cl = clt; + break; + } + } + + Enumeration getResources(String resName) { + try { + return cl.getResources(resName); + } + catch (IOException e) { + return new Singleton(null); + } + } + + Class loadClass(String name) throws ClassNotFoundException { + return Class.forName(name, true, cl); + } + } + + public Service(Class cls) { + try { + loader = new Loader2(); + } + catch (NoSuchMethodError e) { + loader = new Loader(); + } + serviceClass = cls; + String resName = "META-INF/services/" + serviceClass.getName(); + configFiles = loader.getResources(resName); + } + + public Enumeration getProviders() { + return new ProviderEnumeration(); + } + + synchronized private boolean moreProviders() { + for (;;) { + while (classNames == null) { + if (!configFiles.hasMoreElements()) + return false; + classNames = parseConfigFile((URL)configFiles.nextElement()); + } + while (classNames.hasMoreElements()) { + String className = (String)classNames.nextElement(); + try { + Class cls = loader.loadClass(className); + Object obj = cls.newInstance(); + if (serviceClass.isInstance(obj)) { + providers.addElement(obj); + return true; + } + } + catch (ClassNotFoundException e) { } + catch (InstantiationException e) { } + catch (IllegalAccessException e) { } + catch (LinkageError e) { } + } + classNames = null; + } + } + + private static final int START = 0; + private static final int IN_NAME = 1; + private static final int IN_COMMENT = 2; + + private static Enumeration parseConfigFile(URL url) { + try { + InputStream in = url.openStream(); + Reader r; + try { + r = new InputStreamReader(in, "UTF-8"); + } + catch (UnsupportedEncodingException e) { + r = new InputStreamReader(in, "UTF8"); + } + r = new BufferedReader(r); + Vector tokens = new Vector(); + StringBuffer tokenBuf = new StringBuffer(); + int state = START; + for (;;) { + int n = r.read(); + if (n < 0) + break; + char c = (char)n; + switch (c) { + case '\r': + case '\n': + state = START; + break; + case ' ': + case '\t': + break; + case '#': + state = IN_COMMENT; + break; + default: + if (state != IN_COMMENT) { + state = IN_NAME; + tokenBuf.append(c); + } + break; + } + if (tokenBuf.length() != 0 && state != IN_NAME) { + tokens.addElement(tokenBuf.toString()); + tokenBuf.setLength(0); + } + } + if (tokenBuf.length() != 0) + tokens.addElement(tokenBuf.toString()); + return tokens.elements(); + } + catch (IOException e) { + return null; + } + } + } + +} diff --git a/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/helpers/ParameterlessDatatypeBuilder.java b/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/helpers/ParameterlessDatatypeBuilder.java new file mode 100755 index 000000000..c59b09355 --- /dev/null +++ b/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/helpers/ParameterlessDatatypeBuilder.java @@ -0,0 +1,42 @@ +package org.relaxng.datatype.helpers; + +import org.relaxng.datatype.*; + +/** + * Dummy implementation of {@link DatatypeBuilder}. + * + * This implementation can be used for Datatypes which have no parameters. + * Any attempt to add parameters will be rejected. + * + * <p> + * Typical usage would be: + * <PRE><XMP> + * class MyDatatypeLibrary implements DatatypeLibrary { + * .... + * DatatypeBuilder createDatatypeBuilder( String typeName ) { + * return new ParameterleessDatatypeBuilder(createDatatype(typeName)); + * } + * .... + * } + * </XMP></PRE> + * + * @author <a href="mailto:kohsuke.kawaguchi@sun.com">Kohsuke KAWAGUCHI</a> + */ +public final class ParameterlessDatatypeBuilder implements DatatypeBuilder { + + /** This type object is returned for the derive method. */ + private final Datatype baseType; + + public ParameterlessDatatypeBuilder( Datatype baseType ) { + this.baseType = baseType; + } + + public void addParameter( String name, String strValue, ValidationContext context ) + throws DatatypeException { + throw new DatatypeException(); + } + + public Datatype createDatatype() throws DatatypeException { + return baseType; + } +} diff --git a/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/helpers/StreamingValidatorImpl.java b/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/helpers/StreamingValidatorImpl.java new file mode 100755 index 000000000..f553e908e --- /dev/null +++ b/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/helpers/StreamingValidatorImpl.java @@ -0,0 +1,55 @@ +package org.relaxng.datatype.helpers; + +import org.relaxng.datatype.*; + +/** + * Dummy implementation of {@link DatatypeStreamingValidator}. + * + * <p> + * This implementation can be used as a quick hack when the performance + * of streaming validation is not important. And this implementation + * also shows you how to implement the DatatypeStreamingValidator interface. + * + * <p> + * Typical usage would be: + * <PRE><XMP> + * class MyDatatype implements Datatype { + * .... + * public DatatypeStreamingValidator createStreamingValidator( ValidationContext context ) { + * return new StreamingValidatorImpl(this,context); + * } + * .... + * } + * </XMP></PRE> + * + * @author <a href="mailto:kohsuke.kawaguchi@sun.com">Kohsuke KAWAGUCHI</a> + */ +public final class StreamingValidatorImpl implements DatatypeStreamingValidator { + + /** This buffer accumulates characters. */ + private final StringBuffer buffer = new StringBuffer(); + + /** Datatype obejct that creates this streaming validator. */ + private final Datatype baseType; + + /** The current context. */ + private final ValidationContext context; + + public void addCharacters( char[] buf, int start, int len ) { + // append characters to the current buffer. + buffer.append(buf,start,len); + } + + public boolean isValid() { + return baseType.isValid(buffer.toString(),context); + } + + public void checkValid() throws DatatypeException { + baseType.checkValid(buffer.toString(),context); + } + + public StreamingValidatorImpl( Datatype baseType, ValidationContext context ) { + this.baseType = baseType; + this.context = context; + } +} diff --git a/libjava/classpath/external/sax/.cvsignore b/libjava/classpath/external/sax/.cvsignore new file mode 100644 index 000000000..282522db0 --- /dev/null +++ b/libjava/classpath/external/sax/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/libjava/classpath/external/sax/Makefile.am b/libjava/classpath/external/sax/Makefile.am new file mode 100644 index 000000000..81e80d16d --- /dev/null +++ b/libjava/classpath/external/sax/Makefile.am @@ -0,0 +1,42 @@ +## Input file for automake to generate the Makefile.in used by configure + +EXTRA_DIST = README \ +org/xml/sax/ext/Attributes2.java \ +org/xml/sax/ext/Attributes2Impl.java \ +org/xml/sax/ext/DeclHandler.java \ +org/xml/sax/ext/DefaultHandler2.java \ +org/xml/sax/ext/EntityResolver2.java \ +org/xml/sax/ext/LexicalHandler.java \ +org/xml/sax/ext/Locator2.java \ +org/xml/sax/ext/Locator2Impl.java \ +org/xml/sax/ext/package.html \ +org/xml/sax/helpers/AttributeListImpl.java \ +org/xml/sax/helpers/AttributesImpl.java \ +org/xml/sax/helpers/DefaultHandler.java \ +org/xml/sax/helpers/LocatorImpl.java \ +org/xml/sax/helpers/NamespaceSupport.java \ +org/xml/sax/helpers/NewInstance.java \ +org/xml/sax/helpers/ParserAdapter.java \ +org/xml/sax/helpers/ParserFactory.java \ +org/xml/sax/helpers/XMLFilterImpl.java \ +org/xml/sax/helpers/XMLReaderAdapter.java \ +org/xml/sax/helpers/XMLReaderFactory.java \ +org/xml/sax/helpers/package.html \ +org/xml/sax/AttributeList.java \ +org/xml/sax/Attributes.java \ +org/xml/sax/ContentHandler.java \ +org/xml/sax/DTDHandler.java \ +org/xml/sax/DocumentHandler.java \ +org/xml/sax/EntityResolver.java \ +org/xml/sax/ErrorHandler.java \ +org/xml/sax/HandlerBase.java \ +org/xml/sax/InputSource.java \ +org/xml/sax/Locator.java \ +org/xml/sax/Parser.java \ +org/xml/sax/SAXException.java \ +org/xml/sax/SAXNotRecognizedException.java \ +org/xml/sax/SAXNotSupportedException.java \ +org/xml/sax/SAXParseException.java \ +org/xml/sax/XMLFilter.java \ +org/xml/sax/XMLReader.java \ +org/xml/sax/package.html diff --git a/libjava/classpath/external/sax/Makefile.in b/libjava/classpath/external/sax/Makefile.in new file mode 100644 index 000000000..a4a0595fd --- /dev/null +++ b/libjava/classpath/external/sax/Makefile.in @@ -0,0 +1,478 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = external/sax +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/../../config/depstand.m4 \ + $(top_srcdir)/../../config/lead-dot.m4 \ + $(top_srcdir)/../../config/lib-ld.m4 \ + $(top_srcdir)/../../config/lib-link.m4 \ + $(top_srcdir)/../../config/lib-prefix.m4 \ + $(top_srcdir)/../../config/multi.m4 \ + $(top_srcdir)/../../config/no-executables.m4 \ + $(top_srcdir)/../../config/override.m4 \ + $(top_srcdir)/../../libtool.m4 \ + $(top_srcdir)/../../ltoptions.m4 \ + $(top_srcdir)/../../ltsugar.m4 \ + $(top_srcdir)/../../ltversion.m4 \ + $(top_srcdir)/../../lt~obsolete.m4 \ + $(top_srcdir)/m4/ac_prog_antlr.m4 \ + $(top_srcdir)/m4/ac_prog_java.m4 \ + $(top_srcdir)/m4/ac_prog_java_works.m4 \ + $(top_srcdir)/m4/ac_prog_javac.m4 \ + $(top_srcdir)/m4/ac_prog_javac_works.m4 \ + $(top_srcdir)/m4/acattribute.m4 $(top_srcdir)/m4/accross.m4 \ + $(top_srcdir)/m4/acinclude.m4 \ + $(top_srcdir)/m4/ax_create_stdint_h.m4 \ + $(top_srcdir)/m4/ax_func_which_gethostbyname_r.m4 \ + $(top_srcdir)/m4/gcc_attribute.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/../../mkinstalldirs +CONFIG_HEADER = $(top_builddir)/include/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +ANTLR = @ANTLR@ +ANTLR_JAR = @ANTLR_JAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CAIRO_CFLAGS = @CAIRO_CFLAGS@ +CAIRO_LIBS = @CAIRO_LIBS@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLASSPATH_CONVENIENCE = @CLASSPATH_CONVENIENCE@ +CLASSPATH_INCLUDES = @CLASSPATH_INCLUDES@ +CLASSPATH_MODULE = @CLASSPATH_MODULE@ +COLLECTIONS_PREFIX = @COLLECTIONS_PREFIX@ +CP = @CP@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATE = @DATE@ +DEFAULT_PREFS_PEER = @DEFAULT_PREFS_PEER@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +ECJ_JAR = @ECJ_JAR@ +EGREP = @EGREP@ +ERROR_CFLAGS = @ERROR_CFLAGS@ +EXAMPLESDIR = @EXAMPLESDIR@ +EXEEXT = @EXEEXT@ +EXTRA_CFLAGS = @EXTRA_CFLAGS@ +FGREP = @FGREP@ +FIND = @FIND@ +FREETYPE2_CFLAGS = @FREETYPE2_CFLAGS@ +FREETYPE2_LIBS = @FREETYPE2_LIBS@ +GCONF_CFLAGS = @GCONF_CFLAGS@ +GCONF_LIBS = @GCONF_LIBS@ +GDK_CFLAGS = @GDK_CFLAGS@ +GDK_LIBS = @GDK_LIBS@ +GJDOC = @GJDOC@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +GMP_CFLAGS = @GMP_CFLAGS@ +GMP_LIBS = @GMP_LIBS@ +GREP = @GREP@ +GSTREAMER_BASE_CFLAGS = @GSTREAMER_BASE_CFLAGS@ +GSTREAMER_BASE_LIBS = @GSTREAMER_BASE_LIBS@ +GSTREAMER_CFLAGS = @GSTREAMER_CFLAGS@ +GSTREAMER_FILE_READER = @GSTREAMER_FILE_READER@ +GSTREAMER_LIBS = @GSTREAMER_LIBS@ +GSTREAMER_MIXER_PROVIDER = @GSTREAMER_MIXER_PROVIDER@ +GSTREAMER_PLUGINS_BASE_CFLAGS = @GSTREAMER_PLUGINS_BASE_CFLAGS@ +GSTREAMER_PLUGINS_BASE_LIBS = @GSTREAMER_PLUGINS_BASE_LIBS@ +GST_PLUGIN_LDFLAGS = @GST_PLUGIN_LDFLAGS@ +GTK_CFLAGS = @GTK_CFLAGS@ +GTK_LIBS = @GTK_LIBS@ +INIT_LOAD_LIBRARY = @INIT_LOAD_LIBRARY@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JAR = @JAR@ +JAVA = @JAVA@ +JAVAC = @JAVAC@ +JAVAC_IS_GCJ = @JAVAC_IS_GCJ@ +JAVAC_MEM_OPT = @JAVAC_MEM_OPT@ +JAVA_LANG_SYSTEM_EXPLICIT_INITIALIZATION = @JAVA_LANG_SYSTEM_EXPLICIT_INITIALIZATION@ +JAY = @JAY@ +JAY_SKELETON = @JAY_SKELETON@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBDEBUG = @LIBDEBUG@ +LIBICONV = @LIBICONV@ +LIBMAGIC = @LIBMAGIC@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBVERSION = @LIBVERSION@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR = @MKDIR@ +MKDIR_P = @MKDIR_P@ +MOC = @MOC@ +MOZILLA_CFLAGS = @MOZILLA_CFLAGS@ +MOZILLA_LIBS = @MOZILLA_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PANGOFT2_CFLAGS = @PANGOFT2_CFLAGS@ +PANGOFT2_LIBS = @PANGOFT2_LIBS@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PATH_TO_ESCHER = @PATH_TO_ESCHER@ +PATH_TO_GLIBJ_ZIP = @PATH_TO_GLIBJ_ZIP@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PLUGIN_DIR = @PLUGIN_DIR@ +QT_CFLAGS = @QT_CFLAGS@ +QT_LIBS = @QT_LIBS@ +RANLIB = @RANLIB@ +REMOVE = @REMOVE@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRICT_WARNING_CFLAGS = @STRICT_WARNING_CFLAGS@ +STRIP = @STRIP@ +TOOLSDIR = @TOOLSDIR@ +USER_JAVAH = @USER_JAVAH@ +VERSION = @VERSION@ +WANT_NATIVE_BIG_INTEGER = @WANT_NATIVE_BIG_INTEGER@ +WARNING_CFLAGS = @WARNING_CFLAGS@ +XMKMF = @XMKMF@ +XML_CFLAGS = @XML_CFLAGS@ +XML_LIBS = @XML_LIBS@ +XSLT_CFLAGS = @XSLT_CFLAGS@ +XSLT_LIBS = @XSLT_LIBS@ +XTEST_LIBS = @XTEST_LIBS@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +ZIP = @ZIP@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_ANTLR = @ac_ct_ANTLR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +default_toolkit = @default_toolkit@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +glibjdir = @glibjdir@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +multi_basedir = @multi_basedir@ +nativeexeclibdir = @nativeexeclibdir@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +toolexeclibdir = @toolexeclibdir@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +uudecode = @uudecode@ +vm_classes = @vm_classes@ +EXTRA_DIST = README \ +org/xml/sax/ext/Attributes2.java \ +org/xml/sax/ext/Attributes2Impl.java \ +org/xml/sax/ext/DeclHandler.java \ +org/xml/sax/ext/DefaultHandler2.java \ +org/xml/sax/ext/EntityResolver2.java \ +org/xml/sax/ext/LexicalHandler.java \ +org/xml/sax/ext/Locator2.java \ +org/xml/sax/ext/Locator2Impl.java \ +org/xml/sax/ext/package.html \ +org/xml/sax/helpers/AttributeListImpl.java \ +org/xml/sax/helpers/AttributesImpl.java \ +org/xml/sax/helpers/DefaultHandler.java \ +org/xml/sax/helpers/LocatorImpl.java \ +org/xml/sax/helpers/NamespaceSupport.java \ +org/xml/sax/helpers/NewInstance.java \ +org/xml/sax/helpers/ParserAdapter.java \ +org/xml/sax/helpers/ParserFactory.java \ +org/xml/sax/helpers/XMLFilterImpl.java \ +org/xml/sax/helpers/XMLReaderAdapter.java \ +org/xml/sax/helpers/XMLReaderFactory.java \ +org/xml/sax/helpers/package.html \ +org/xml/sax/AttributeList.java \ +org/xml/sax/Attributes.java \ +org/xml/sax/ContentHandler.java \ +org/xml/sax/DTDHandler.java \ +org/xml/sax/DocumentHandler.java \ +org/xml/sax/EntityResolver.java \ +org/xml/sax/ErrorHandler.java \ +org/xml/sax/HandlerBase.java \ +org/xml/sax/InputSource.java \ +org/xml/sax/Locator.java \ +org/xml/sax/Parser.java \ +org/xml/sax/SAXException.java \ +org/xml/sax/SAXNotRecognizedException.java \ +org/xml/sax/SAXNotSupportedException.java \ +org/xml/sax/SAXParseException.java \ +org/xml/sax/XMLFilter.java \ +org/xml/sax/XMLReader.java \ +org/xml/sax/package.html + +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu external/sax/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu external/sax/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libjava/classpath/external/sax/README b/libjava/classpath/external/sax/README new file mode 100644 index 000000000..4b39d2364 --- /dev/null +++ b/libjava/classpath/external/sax/README @@ -0,0 +1,71 @@ +Simple API for XML (SAX), a standard application interface for processing XML. +SAX is not maintained as part of GNU Classpath, but is used with GNU Classpath. + +Last imported version sax2r3 final from http://www.saxproject.org/ + +All files are distributed with the following short notice: + + NO WARRANTY! This class is in the Public Domain. + +The www.saxproject.org explains: + + Copyright Status + + SAX is free! + + In fact, it's not possible to own a license to SAX, since it's been + placed in the public domain. + + No Warranty + + Because SAX is released to the public domain, there is no warranty + for the design or for the software implementation, to the extent + permitted by applicable law. Except when otherwise stated in writing + the copyright holders and/or other parties provide SAX "as is" without + warranty of any kind, either expressed or implied, including, but not + limited to, the implied warranties of merchantability and fitness for + a particular purpose. The entire risk as to the quality and + performance of SAX is with you. Should SAX prove defective, you assume + the cost of all necessary servicing, repair or correction. + + In no event unless required by applicable law or agreed to in + writing will any copyright holder, or any other party who may modify + and/or redistribute SAX, be liable to you for damages, including any + general, special, incidental or consequential damages arising out of + the use or inability to use SAX (including but not limited to loss of + data or data being rendered inaccurate or losses sustained by you or + third parties or a failure of the SAX to operate with any other + programs), even if such holder or other party has been advised of the + possibility of such damages. + + Copyright Disclaimers + + This page includes statements to that effect by David Megginson, who + would have been able to claim copyright for the original work. + + SAX 1.0 + + Version 1.0 of the Simple API for XML (SAX), created collectively by + the membership of the XML-DEV mailing list, is hereby released into + the public domain. + + No one owns SAX: you may use it freely in both commercial and + non-commercial applications, bundle it with your software + distribution, include it on a CD-ROM, list the source code in a book, + mirror the documentation at your own web site, or use it in any other + way you see fit. + + David Megginson, sax@megginson.com + 1998-05-11 + + SAX 2.0 + + I hereby abandon any property rights to SAX 2.0 (the Simple API for + XML), and release all of the SAX 2.0 source code, compiled code, and + documentation contained in this distribution into the Public + Domain. SAX comes with NO WARRANTY or guarantee of fitness for any + purpose. + + David Megginson, david@megginson.com + 2000-05-05 + diff --git a/libjava/classpath/external/sax/org/xml/sax/AttributeList.java b/libjava/classpath/external/sax/org/xml/sax/AttributeList.java new file mode 100644 index 000000000..cceac8983 --- /dev/null +++ b/libjava/classpath/external/sax/org/xml/sax/AttributeList.java @@ -0,0 +1,193 @@ +// SAX Attribute List Interface. +// http://www.saxproject.org +// No warranty; no copyright -- use this as you will. +// $Id: AttributeList.java,v 1.1 2004/12/23 22:38:42 mark Exp $ + +package org.xml.sax; + +/** + * Interface for an element's attribute specifications. + * + * <blockquote> + * <em>This module, both source code and documentation, is in the + * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> + * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a> + * for further information. + * </blockquote> + * + * <p>This is the original SAX1 interface for reporting an element's + * attributes. Unlike the new {@link org.xml.sax.Attributes Attributes} + * interface, it does not support Namespace-related information.</p> + * + * <p>When an attribute list is supplied as part of a + * {@link org.xml.sax.DocumentHandler#startElement startElement} + * event, the list will return valid results only during the + * scope of the event; once the event handler returns control + * to the parser, the attribute list is invalid. To save a + * persistent copy of the attribute list, use the SAX1 + * {@link org.xml.sax.helpers.AttributeListImpl AttributeListImpl} + * helper class.</p> + * + * <p>An attribute list includes only attributes that have been + * specified or defaulted: #IMPLIED attributes will not be included.</p> + * + * <p>There are two ways for the SAX application to obtain information + * from the AttributeList. First, it can iterate through the entire + * list:</p> + * + * <pre> + * public void startElement (String name, AttributeList atts) { + * for (int i = 0; i < atts.getLength(); i++) { + * String name = atts.getName(i); + * String type = atts.getType(i); + * String value = atts.getValue(i); + * [...] + * } + * } + * </pre> + * + * <p>(Note that the result of getLength() will be zero if there + * are no attributes.) + * + * <p>As an alternative, the application can request the value or + * type of specific attributes:</p> + * + * <pre> + * public void startElement (String name, AttributeList atts) { + * String identifier = atts.getValue("id"); + * String label = atts.getValue("label"); + * [...] + * } + * </pre> + * + * @deprecated This interface has been replaced by the SAX2 + * {@link org.xml.sax.Attributes Attributes} + * interface, which includes Namespace support. + * @since SAX 1.0 + * @author David Megginson + * @version 2.0.1 (sax2r2) + * @see org.xml.sax.DocumentHandler#startElement startElement + * @see org.xml.sax.helpers.AttributeListImpl AttributeListImpl + */ +public interface AttributeList { + + + //////////////////////////////////////////////////////////////////// + // Iteration methods. + //////////////////////////////////////////////////////////////////// + + + /** + * Return the number of attributes in this list. + * + * <p>The SAX parser may provide attributes in any + * arbitrary order, regardless of the order in which they were + * declared or specified. The number of attributes may be + * zero.</p> + * + * @return The number of attributes in the list. + */ + public abstract int getLength (); + + + /** + * Return the name of an attribute in this list (by position). + * + * <p>The names must be unique: the SAX parser shall not include the + * same attribute twice. Attributes without values (those declared + * #IMPLIED without a value specified in the start tag) will be + * omitted from the list.</p> + * + * <p>If the attribute name has a namespace prefix, the prefix + * will still be attached.</p> + * + * @param i The index of the attribute in the list (starting at 0). + * @return The name of the indexed attribute, or null + * if the index is out of range. + * @see #getLength + */ + public abstract String getName (int i); + + + /** + * Return the type of an attribute in the list (by position). + * + * <p>The attribute type is one of the strings "CDATA", "ID", + * "IDREF", "IDREFS", "NMTOKEN", "NMTOKENS", "ENTITY", "ENTITIES", + * or "NOTATION" (always in upper case).</p> + * + * <p>If the parser has not read a declaration for the attribute, + * or if the parser does not report attribute types, then it must + * return the value "CDATA" as stated in the XML 1.0 Recommentation + * (clause 3.3.3, "Attribute-Value Normalization").</p> + * + * <p>For an enumerated attribute that is not a notation, the + * parser will report the type as "NMTOKEN".</p> + * + * @param i The index of the attribute in the list (starting at 0). + * @return The attribute type as a string, or + * null if the index is out of range. + * @see #getLength + * @see #getType(java.lang.String) + */ + public abstract String getType (int i); + + + /** + * Return the value of an attribute in the list (by position). + * + * <p>If the attribute value is a list of tokens (IDREFS, + * ENTITIES, or NMTOKENS), the tokens will be concatenated + * into a single string separated by whitespace.</p> + * + * @param i The index of the attribute in the list (starting at 0). + * @return The attribute value as a string, or + * null if the index is out of range. + * @see #getLength + * @see #getValue(java.lang.String) + */ + public abstract String getValue (int i); + + + + //////////////////////////////////////////////////////////////////// + // Lookup methods. + //////////////////////////////////////////////////////////////////// + + + /** + * Return the type of an attribute in the list (by name). + * + * <p>The return value is the same as the return value for + * getType(int).</p> + * + * <p>If the attribute name has a namespace prefix in the document, + * the application must include the prefix here.</p> + * + * @param name The name of the attribute. + * @return The attribute type as a string, or null if no + * such attribute exists. + * @see #getType(int) + */ + public abstract String getType (String name); + + + /** + * Return the value of an attribute in the list (by name). + * + * <p>The return value is the same as the return value for + * getValue(int).</p> + * + * <p>If the attribute name has a namespace prefix in the document, + * the application must include the prefix here.</p> + * + * @param name the name of the attribute to return + * @return The attribute value as a string, or null if + * no such attribute exists. + * @see #getValue(int) + */ + public abstract String getValue (String name); + +} + +// end of AttributeList.java diff --git a/libjava/classpath/external/sax/org/xml/sax/Attributes.java b/libjava/classpath/external/sax/org/xml/sax/Attributes.java new file mode 100644 index 000000000..0f3c23682 --- /dev/null +++ b/libjava/classpath/external/sax/org/xml/sax/Attributes.java @@ -0,0 +1,257 @@ +// Attributes.java - attribute list with Namespace support +// http://www.saxproject.org +// Written by David Megginson +// NO WARRANTY! This class is in the public domain. +// $Id: Attributes.java,v 1.1 2004/12/23 22:38:42 mark Exp $ + +package org.xml.sax; + + +/** + * Interface for a list of XML attributes. + * + * <blockquote> + * <em>This module, both source code and documentation, is in the + * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> + * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a> + * for further information. + * </blockquote> + * + * <p>This interface allows access to a list of attributes in + * three different ways:</p> + * + * <ol> + * <li>by attribute index;</li> + * <li>by Namespace-qualified name; or</li> + * <li>by qualified (prefixed) name.</li> + * </ol> + * + * <p>The list will not contain attributes that were declared + * #IMPLIED but not specified in the start tag. It will also not + * contain attributes used as Namespace declarations (xmlns*) unless + * the <code>http://xml.org/sax/features/namespace-prefixes</code> + * feature is set to <var>true</var> (it is <var>false</var> by + * default). + * Because SAX2 conforms to the original "Namespaces in XML" + * recommendation, it normally does not + * give namespace declaration attributes a namespace URI. + * </p> + * + * <p>Some SAX2 parsers may support using an optional feature flag + * (<code>http://xml.org/sax/features/xmlns-uris</code>) to request + * that those attributes be given URIs, conforming to a later + * backwards-incompatible revision of that recommendation. (The + * attribute's "local name" will be the prefix, or "xmlns" when + * defining a default element namespace.) For portability, handler + * code should always resolve that conflict, rather than requiring + * parsers that can change the setting of that feature flag. </p> + * + * <p>If the namespace-prefixes feature (see above) is + * <var>false</var>, access by qualified name may not be available; if + * the <code>http://xml.org/sax/features/namespaces</code> feature is + * <var>false</var>, access by Namespace-qualified names may not be + * available.</p> + * + * <p>This interface replaces the now-deprecated SAX1 {@link + * org.xml.sax.AttributeList AttributeList} interface, which does not + * contain Namespace support. In addition to Namespace support, it + * adds the <var>getIndex</var> methods (below).</p> + * + * <p>The order of attributes in the list is unspecified, and will + * vary from implementation to implementation.</p> + * + * @since SAX 2.0 + * @author David Megginson + * @version 2.0.1 (sax2r2) + * @see org.xml.sax.helpers.AttributesImpl + * @see org.xml.sax.ext.DeclHandler#attributeDecl + */ +public interface Attributes +{ + + + //////////////////////////////////////////////////////////////////// + // Indexed access. + //////////////////////////////////////////////////////////////////// + + + /** + * Return the number of attributes in the list. + * + * <p>Once you know the number of attributes, you can iterate + * through the list.</p> + * + * @return The number of attributes in the list. + * @see #getURI(int) + * @see #getLocalName(int) + * @see #getQName(int) + * @see #getType(int) + * @see #getValue(int) + */ + public abstract int getLength (); + + + /** + * Look up an attribute's Namespace URI by index. + * + * @param index The attribute index (zero-based). + * @return The Namespace URI, or the empty string if none + * is available, or null if the index is out of + * range. + * @see #getLength + */ + public abstract String getURI (int index); + + + /** + * Look up an attribute's local name by index. + * + * @param index The attribute index (zero-based). + * @return The local name, or the empty string if Namespace + * processing is not being performed, or null + * if the index is out of range. + * @see #getLength + */ + public abstract String getLocalName (int index); + + + /** + * Look up an attribute's XML qualified (prefixed) name by index. + * + * @param index The attribute index (zero-based). + * @return The XML qualified name, or the empty string + * if none is available, or null if the index + * is out of range. + * @see #getLength + */ + public abstract String getQName (int index); + + + /** + * Look up an attribute's type by index. + * + * <p>The attribute type is one of the strings "CDATA", "ID", + * "IDREF", "IDREFS", "NMTOKEN", "NMTOKENS", "ENTITY", "ENTITIES", + * or "NOTATION" (always in upper case).</p> + * + * <p>If the parser has not read a declaration for the attribute, + * or if the parser does not report attribute types, then it must + * return the value "CDATA" as stated in the XML 1.0 Recommendation + * (clause 3.3.3, "Attribute-Value Normalization").</p> + * + * <p>For an enumerated attribute that is not a notation, the + * parser will report the type as "NMTOKEN".</p> + * + * @param index The attribute index (zero-based). + * @return The attribute's type as a string, or null if the + * index is out of range. + * @see #getLength + */ + public abstract String getType (int index); + + + /** + * Look up an attribute's value by index. + * + * <p>If the attribute value is a list of tokens (IDREFS, + * ENTITIES, or NMTOKENS), the tokens will be concatenated + * into a single string with each token separated by a + * single space.</p> + * + * @param index The attribute index (zero-based). + * @return The attribute's value as a string, or null if the + * index is out of range. + * @see #getLength + */ + public abstract String getValue (int index); + + + + //////////////////////////////////////////////////////////////////// + // Name-based query. + //////////////////////////////////////////////////////////////////// + + + /** + * Look up the index of an attribute by Namespace name. + * + * @param uri The Namespace URI, or the empty string if + * the name has no Namespace URI. + * @param localName The attribute's local name. + * @return The index of the attribute, or -1 if it does not + * appear in the list. + */ + public int getIndex (String uri, String localName); + + + /** + * Look up the index of an attribute by XML qualified (prefixed) name. + * + * @param qName The qualified (prefixed) name. + * @return The index of the attribute, or -1 if it does not + * appear in the list. + */ + public int getIndex (String qName); + + + /** + * Look up an attribute's type by Namespace name. + * + * <p>See {@link #getType(int) getType(int)} for a description + * of the possible types.</p> + * + * @param uri The Namespace URI, or the empty String if the + * name has no Namespace URI. + * @param localName The local name of the attribute. + * @return The attribute type as a string, or null if the + * attribute is not in the list or if Namespace + * processing is not being performed. + */ + public abstract String getType (String uri, String localName); + + + /** + * Look up an attribute's type by XML qualified (prefixed) name. + * + * <p>See {@link #getType(int) getType(int)} for a description + * of the possible types.</p> + * + * @param qName The XML qualified name. + * @return The attribute type as a string, or null if the + * attribute is not in the list or if qualified names + * are not available. + */ + public abstract String getType (String qName); + + + /** + * Look up an attribute's value by Namespace name. + * + * <p>See {@link #getValue(int) getValue(int)} for a description + * of the possible values.</p> + * + * @param uri The Namespace URI, or the empty String if the + * name has no Namespace URI. + * @param localName The local name of the attribute. + * @return The attribute value as a string, or null if the + * attribute is not in the list. + */ + public abstract String getValue (String uri, String localName); + + + /** + * Look up an attribute's value by XML qualified (prefixed) name. + * + * <p>See {@link #getValue(int) getValue(int)} for a description + * of the possible values.</p> + * + * @param qName The XML qualified name. + * @return The attribute value as a string, or null if the + * attribute is not in the list or if qualified names + * are not available. + */ + public abstract String getValue (String qName); + +} + +// end of Attributes.java diff --git a/libjava/classpath/external/sax/org/xml/sax/ContentHandler.java b/libjava/classpath/external/sax/org/xml/sax/ContentHandler.java new file mode 100644 index 000000000..f5f439d78 --- /dev/null +++ b/libjava/classpath/external/sax/org/xml/sax/ContentHandler.java @@ -0,0 +1,419 @@ +// ContentHandler.java - handle main document content. +// http://www.saxproject.org +// Written by David Megginson +// NO WARRANTY! This class is in the public domain. +// $Id: ContentHandler.java,v 1.1 2004/12/23 22:38:42 mark Exp $ + +package org.xml.sax; + + +/** + * Receive notification of the logical content of a document. + * + * <blockquote> + * <em>This module, both source code and documentation, is in the + * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> + * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a> + * for further information. + * </blockquote> + * + * <p>This is the main interface that most SAX applications + * implement: if the application needs to be informed of basic parsing + * events, it implements this interface and registers an instance with + * the SAX parser using the {@link org.xml.sax.XMLReader#setContentHandler + * setContentHandler} method. The parser uses the instance to report + * basic document-related events like the start and end of elements + * and character data.</p> + * + * <p>The order of events in this interface is very important, and + * mirrors the order of information in the document itself. For + * example, all of an element's content (character data, processing + * instructions, and/or subelements) will appear, in order, between + * the startElement event and the corresponding endElement event.</p> + * + * <p>This interface is similar to the now-deprecated SAX 1.0 + * DocumentHandler interface, but it adds support for Namespaces + * and for reporting skipped entities (in non-validating XML + * processors).</p> + * + * <p>Implementors should note that there is also a + * <code>ContentHandler</code> class in the <code>java.net</code> + * package; that means that it's probably a bad idea to do</p> + * + * <pre>import java.net.*; + * import org.xml.sax.*; + * </pre> + * + * <p>In fact, "import ...*" is usually a sign of sloppy programming + * anyway, so the user should consider this a feature rather than a + * bug.</p> + * + * @since SAX 2.0 + * @author David Megginson + * @version 2.0.1+ (sax2r3pre1) + * @see org.xml.sax.XMLReader + * @see org.xml.sax.DTDHandler + * @see org.xml.sax.ErrorHandler + */ +public interface ContentHandler +{ + + /** + * Receive an object for locating the origin of SAX document events. + * + * <p>SAX parsers are strongly encouraged (though not absolutely + * required) to supply a locator: if it does so, it must supply + * the locator to the application by invoking this method before + * invoking any of the other methods in the ContentHandler + * interface.</p> + * + * <p>The locator allows the application to determine the end + * position of any document-related event, even if the parser is + * not reporting an error. Typically, the application will + * use this information for reporting its own errors (such as + * character content that does not match an application's + * business rules). The information returned by the locator + * is probably not sufficient for use with a search engine.</p> + * + * <p>Note that the locator will return correct information only + * during the invocation SAX event callbacks after + * {@link #startDocument startDocument} returns and before + * {@link #endDocument endDocument} is called. The + * application should not attempt to use it at any other time.</p> + * + * @param locator an object that can return the location of + * any SAX document event + * @see org.xml.sax.Locator + */ + public void setDocumentLocator (Locator locator); + + + /** + * Receive notification of the beginning of a document. + * + * <p>The SAX parser will invoke this method only once, before any + * other event callbacks (except for {@link #setDocumentLocator + * setDocumentLocator}).</p> + * + * @throws org.xml.sax.SAXException any SAX exception, possibly + * wrapping another exception + * @see #endDocument + */ + public void startDocument () + throws SAXException; + + + /** + * Receive notification of the end of a document. + * + * <p><strong>There is an apparent contradiction between the + * documentation for this method and the documentation for {@link + * org.xml.sax.ErrorHandler#fatalError}. Until this ambiguity is + * resolved in a future major release, clients should make no + * assumptions about whether endDocument() will or will not be + * invoked when the parser has reported a fatalError() or thrown + * an exception.</strong></p> + * + * <p>The SAX parser will invoke this method only once, and it will + * be the last method invoked during the parse. The parser shall + * not invoke this method until it has either abandoned parsing + * (because of an unrecoverable error) or reached the end of + * input.</p> + * + * @throws org.xml.sax.SAXException any SAX exception, possibly + * wrapping another exception + * @see #startDocument + */ + public void endDocument() + throws SAXException; + + + /** + * Begin the scope of a prefix-URI Namespace mapping. + * + * <p>The information from this event is not necessary for + * normal Namespace processing: the SAX XML reader will + * automatically replace prefixes for element and attribute + * names when the <code>http://xml.org/sax/features/namespaces</code> + * feature is <var>true</var> (the default).</p> + * + * <p>There are cases, however, when applications need to + * use prefixes in character data or in attribute values, + * where they cannot safely be expanded automatically; the + * start/endPrefixMapping event supplies the information + * to the application to expand prefixes in those contexts + * itself, if necessary.</p> + * + * <p>Note that start/endPrefixMapping events are not + * guaranteed to be properly nested relative to each other: + * all startPrefixMapping events will occur immediately before the + * corresponding {@link #startElement startElement} event, + * and all {@link #endPrefixMapping endPrefixMapping} + * events will occur immediately after the corresponding + * {@link #endElement endElement} event, + * but their order is not otherwise + * guaranteed.</p> + * + * <p>There should never be start/endPrefixMapping events for the + * "xml" prefix, since it is predeclared and immutable.</p> + * + * @param prefix the Namespace prefix being declared. + * An empty string is used for the default element namespace, + * which has no prefix. + * @param uri the Namespace URI the prefix is mapped to + * @throws org.xml.sax.SAXException the client may throw + * an exception during processing + * @see #endPrefixMapping + * @see #startElement + */ + public void startPrefixMapping (String prefix, String uri) + throws SAXException; + + + /** + * End the scope of a prefix-URI mapping. + * + * <p>See {@link #startPrefixMapping startPrefixMapping} for + * details. These events will always occur immediately after the + * corresponding {@link #endElement endElement} event, but the order of + * {@link #endPrefixMapping endPrefixMapping} events is not otherwise + * guaranteed.</p> + * + * @param prefix the prefix that was being mapped. + * This is the empty string when a default mapping scope ends. + * @throws org.xml.sax.SAXException the client may throw + * an exception during processing + * @see #startPrefixMapping + * @see #endElement + */ + public void endPrefixMapping (String prefix) + throws SAXException; + + + /** + * Receive notification of the beginning of an element. + * + * <p>The Parser will invoke this method at the beginning of every + * element in the XML document; there will be a corresponding + * {@link #endElement endElement} event for every startElement event + * (even when the element is empty). All of the element's content will be + * reported, in order, before the corresponding endElement + * event.</p> + * + * <p>This event allows up to three name components for each + * element:</p> + * + * <ol> + * <li>the Namespace URI;</li> + * <li>the local name; and</li> + * <li>the qualified (prefixed) name.</li> + * </ol> + * + * <p>Any or all of these may be provided, depending on the + * values of the <var>http://xml.org/sax/features/namespaces</var> + * and the <var>http://xml.org/sax/features/namespace-prefixes</var> + * properties:</p> + * + * <ul> + * <li>the Namespace URI and local name are required when + * the namespaces property is <var>true</var> (the default), and are + * optional when the namespaces property is <var>false</var> (if one is + * specified, both must be);</li> + * <li>the qualified name is required when the namespace-prefixes property + * is <var>true</var>, and is optional when the namespace-prefixes property + * is <var>false</var> (the default).</li> + * </ul> + * + * <p>Note that the attribute list provided will contain only + * attributes with explicit values (specified or defaulted): + * #IMPLIED attributes will be omitted. The attribute list + * will contain attributes used for Namespace declarations + * (xmlns* attributes) only if the + * <code>http://xml.org/sax/features/namespace-prefixes</code> + * property is true (it is false by default, and support for a + * true value is optional).</p> + * + * <p>Like {@link #characters characters()}, attribute values may have + * characters that need more than one <code>char</code> value. </p> + * + * @param uri the Namespace URI, or the empty string if the + * element has no Namespace URI or if Namespace + * processing is not being performed + * @param localName the local name (without prefix), or the + * empty string if Namespace processing is not being + * performed + * @param qName the qualified name (with prefix), or the + * empty string if qualified names are not available + * @param atts the attributes attached to the element. If + * there are no attributes, it shall be an empty + * Attributes object. The value of this object after + * startElement returns is undefined + * @throws org.xml.sax.SAXException any SAX exception, possibly + * wrapping another exception + * @see #endElement + * @see org.xml.sax.Attributes + * @see org.xml.sax.helpers.AttributesImpl + */ + public void startElement (String uri, String localName, + String qName, Attributes atts) + throws SAXException; + + + /** + * Receive notification of the end of an element. + * + * <p>The SAX parser will invoke this method at the end of every + * element in the XML document; there will be a corresponding + * {@link #startElement startElement} event for every endElement + * event (even when the element is empty).</p> + * + * <p>For information on the names, see startElement.</p> + * + * @param uri the Namespace URI, or the empty string if the + * element has no Namespace URI or if Namespace + * processing is not being performed + * @param localName the local name (without prefix), or the + * empty string if Namespace processing is not being + * performed + * @param qName the qualified XML name (with prefix), or the + * empty string if qualified names are not available + * @throws org.xml.sax.SAXException any SAX exception, possibly + * wrapping another exception + */ + public void endElement (String uri, String localName, + String qName) + throws SAXException; + + + /** + * Receive notification of character data. + * + * <p>The Parser will call this method to report each chunk of + * character data. SAX parsers may return all contiguous character + * data in a single chunk, or they may split it into several + * chunks; however, all of the characters in any single event + * must come from the same external entity so that the Locator + * provides useful information.</p> + * + * <p>The application must not attempt to read from the array + * outside of the specified range.</p> + * + * <p>Individual characters may consist of more than one Java + * <code>char</code> value. There are two important cases where this + * happens, because characters can't be represented in just sixteen bits. + * In one case, characters are represented in a <em>Surrogate Pair</em>, + * using two special Unicode values. Such characters are in the so-called + * "Astral Planes", with a code point above U+FFFF. A second case involves + * composite characters, such as a base character combining with one or + * more accent characters. </p> + * + * <p> Your code should not assume that algorithms using + * <code>char</code>-at-a-time idioms will be working in character + * units; in some cases they will split characters. This is relevant + * wherever XML permits arbitrary characters, such as attribute values, + * processing instruction data, and comments as well as in data reported + * from this method. It's also generally relevant whenever Java code + * manipulates internationalized text; the issue isn't unique to XML.</p> + * + * <p>Note that some parsers will report whitespace in element + * content using the {@link #ignorableWhitespace ignorableWhitespace} + * method rather than this one (validating parsers <em>must</em> + * do so).</p> + * + * @param ch the characters from the XML document + * @param start the start position in the array + * @param length the number of characters to read from the array + * @throws org.xml.sax.SAXException any SAX exception, possibly + * wrapping another exception + * @see #ignorableWhitespace + * @see org.xml.sax.Locator + */ + public void characters (char ch[], int start, int length) + throws SAXException; + + + /** + * Receive notification of ignorable whitespace in element content. + * + * <p>Validating Parsers must use this method to report each chunk + * of whitespace in element content (see the W3C XML 1.0 + * recommendation, section 2.10): non-validating parsers may also + * use this method if they are capable of parsing and using + * content models.</p> + * + * <p>SAX parsers may return all contiguous whitespace in a single + * chunk, or they may split it into several chunks; however, all of + * the characters in any single event must come from the same + * external entity, so that the Locator provides useful + * information.</p> + * + * <p>The application must not attempt to read from the array + * outside of the specified range.</p> + * + * @param ch the characters from the XML document + * @param start the start position in the array + * @param length the number of characters to read from the array + * @throws org.xml.sax.SAXException any SAX exception, possibly + * wrapping another exception + * @see #characters + */ + public void ignorableWhitespace (char ch[], int start, int length) + throws SAXException; + + + /** + * Receive notification of a processing instruction. + * + * <p>The Parser will invoke this method once for each processing + * instruction found: note that processing instructions may occur + * before or after the main document element.</p> + * + * <p>A SAX parser must never report an XML declaration (XML 1.0, + * section 2.8) or a text declaration (XML 1.0, section 4.3.1) + * using this method.</p> + * + * <p>Like {@link #characters characters()}, processing instruction + * data may have characters that need more than one <code>char</code> + * value. </p> + * + * @param target the processing instruction target + * @param data the processing instruction data, or null if + * none was supplied. The data does not include any + * whitespace separating it from the target + * @throws org.xml.sax.SAXException any SAX exception, possibly + * wrapping another exception + */ + public void processingInstruction (String target, String data) + throws SAXException; + + + /** + * Receive notification of a skipped entity. + * This is not called for entity references within markup constructs + * such as element start tags or markup declarations. (The XML + * recommendation requires reporting skipped external entities. + * SAX also reports internal entity expansion/non-expansion, except + * within markup constructs.) + * + * <p>The Parser will invoke this method each time the entity is + * skipped. Non-validating processors may skip entities if they + * have not seen the declarations (because, for example, the + * entity was declared in an external DTD subset). All processors + * may skip external entities, depending on the values of the + * <code>http://xml.org/sax/features/external-general-entities</code> + * and the + * <code>http://xml.org/sax/features/external-parameter-entities</code> + * properties.</p> + * + * @param name the name of the skipped entity. If it is a + * parameter entity, the name will begin with '%', and if + * it is the external DTD subset, it will be the string + * "[dtd]" + * @throws org.xml.sax.SAXException any SAX exception, possibly + * wrapping another exception + */ + public void skippedEntity (String name) + throws SAXException; +} + +// end of ContentHandler.java diff --git a/libjava/classpath/external/sax/org/xml/sax/DTDHandler.java b/libjava/classpath/external/sax/org/xml/sax/DTDHandler.java new file mode 100644 index 000000000..67f5bd6a3 --- /dev/null +++ b/libjava/classpath/external/sax/org/xml/sax/DTDHandler.java @@ -0,0 +1,117 @@ +// SAX DTD handler. +// http://www.saxproject.org +// No warranty; no copyright -- use this as you will. +// $Id: DTDHandler.java,v 1.1 2004/12/23 22:38:42 mark Exp $ + +package org.xml.sax; + +/** + * Receive notification of basic DTD-related events. + * + * <blockquote> + * <em>This module, both source code and documentation, is in the + * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> + * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a> + * for further information. + * </blockquote> + * + * <p>If a SAX application needs information about notations and + * unparsed entities, then the application implements this + * interface and registers an instance with the SAX parser using + * the parser's setDTDHandler method. The parser uses the + * instance to report notation and unparsed entity declarations to + * the application.</p> + * + * <p>Note that this interface includes only those DTD events that + * the XML recommendation <em>requires</em> processors to report: + * notation and unparsed entity declarations.</p> + * + * <p>The SAX parser may report these events in any order, regardless + * of the order in which the notations and unparsed entities were + * declared; however, all DTD events must be reported after the + * document handler's startDocument event, and before the first + * startElement event. + * (If the {@link org.xml.sax.ext.LexicalHandler LexicalHandler} is + * used, these events must also be reported before the endDTD event.) + * </p> + * + * <p>It is up to the application to store the information for + * future use (perhaps in a hash table or object tree). + * If the application encounters attributes of type "NOTATION", + * "ENTITY", or "ENTITIES", it can use the information that it + * obtained through this interface to find the entity and/or + * notation corresponding with the attribute value.</p> + * + * @since SAX 1.0 + * @author David Megginson + * @version 2.0.1 (sax2r2) + * @see org.xml.sax.XMLReader#setDTDHandler + */ +public interface DTDHandler { + + + /** + * Receive notification of a notation declaration event. + * + * <p>It is up to the application to record the notation for later + * reference, if necessary; + * notations may appear as attribute values and in unparsed entity + * declarations, and are sometime used with processing instruction + * target names.</p> + * + * <p>At least one of publicId and systemId must be non-null. + * If a system identifier is present, and it is a URL, the SAX + * parser must resolve it fully before passing it to the + * application through this event.</p> + * + * <p>There is no guarantee that the notation declaration will be + * reported before any unparsed entities that use it.</p> + * + * @param name The notation name. + * @param publicId The notation's public identifier, or null if + * none was given. + * @param systemId The notation's system identifier, or null if + * none was given. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + * @see #unparsedEntityDecl + * @see org.xml.sax.Attributes + */ + public abstract void notationDecl (String name, + String publicId, + String systemId) + throws SAXException; + + + /** + * Receive notification of an unparsed entity declaration event. + * + * <p>Note that the notation name corresponds to a notation + * reported by the {@link #notationDecl notationDecl} event. + * It is up to the application to record the entity for later + * reference, if necessary; + * unparsed entities may appear as attribute values. + * </p> + * + * <p>If the system identifier is a URL, the parser must resolve it + * fully before passing it to the application.</p> + * + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + * @param name The unparsed entity's name. + * @param publicId The entity's public identifier, or null if none + * was given. + * @param systemId The entity's system identifier. + * @param notationName The name of the associated notation. + * @see #notationDecl + * @see org.xml.sax.Attributes + */ + public abstract void unparsedEntityDecl (String name, + String publicId, + String systemId, + String notationName) + throws SAXException; + +} + +// end of DTDHandler.java diff --git a/libjava/classpath/external/sax/org/xml/sax/DocumentHandler.java b/libjava/classpath/external/sax/org/xml/sax/DocumentHandler.java new file mode 100644 index 000000000..339a0ea65 --- /dev/null +++ b/libjava/classpath/external/sax/org/xml/sax/DocumentHandler.java @@ -0,0 +1,232 @@ +// SAX document handler. +// http://www.saxproject.org +// No warranty; no copyright -- use this as you will. +// $Id: DocumentHandler.java,v 1.1 2004/12/23 22:38:42 mark Exp $ + +package org.xml.sax; + +/** + * Receive notification of general document events. + * + * <blockquote> + * <em>This module, both source code and documentation, is in the + * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> + * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a> + * for further information. + * </blockquote> + * + * <p>This was the main event-handling interface for SAX1; in + * SAX2, it has been replaced by {@link org.xml.sax.ContentHandler + * ContentHandler}, which provides Namespace support and reporting + * of skipped entities. This interface is included in SAX2 only + * to support legacy SAX1 applications.</p> + * + * <p>The order of events in this interface is very important, and + * mirrors the order of information in the document itself. For + * example, all of an element's content (character data, processing + * instructions, and/or subelements) will appear, in order, between + * the startElement event and the corresponding endElement event.</p> + * + * <p>Application writers who do not want to implement the entire + * interface can derive a class from HandlerBase, which implements + * the default functionality; parser writers can instantiate + * HandlerBase to obtain a default handler. The application can find + * the location of any document event using the Locator interface + * supplied by the Parser through the setDocumentLocator method.</p> + * + * @deprecated This interface has been replaced by the SAX2 + * {@link org.xml.sax.ContentHandler ContentHandler} + * interface, which includes Namespace support. + * @since SAX 1.0 + * @author David Megginson + * @version 2.0.1 (sax2r2) + * @see org.xml.sax.Parser#setDocumentHandler + * @see org.xml.sax.Locator + * @see org.xml.sax.HandlerBase + */ +public interface DocumentHandler { + + + /** + * Receive an object for locating the origin of SAX document events. + * + * <p>SAX parsers are strongly encouraged (though not absolutely + * required) to supply a locator: if it does so, it must supply + * the locator to the application by invoking this method before + * invoking any of the other methods in the DocumentHandler + * interface.</p> + * + * <p>The locator allows the application to determine the end + * position of any document-related event, even if the parser is + * not reporting an error. Typically, the application will + * use this information for reporting its own errors (such as + * character content that does not match an application's + * business rules). The information returned by the locator + * is probably not sufficient for use with a search engine.</p> + * + * <p>Note that the locator will return correct information only + * during the invocation of the events in this interface. The + * application should not attempt to use it at any other time.</p> + * + * @param locator An object that can return the location of + * any SAX document event. + * @see org.xml.sax.Locator + */ + public abstract void setDocumentLocator (Locator locator); + + + /** + * Receive notification of the beginning of a document. + * + * <p>The SAX parser will invoke this method only once, before any + * other methods in this interface or in DTDHandler (except for + * setDocumentLocator).</p> + * + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + */ + public abstract void startDocument () + throws SAXException; + + + /** + * Receive notification of the end of a document. + * + * <p>The SAX parser will invoke this method only once, and it will + * be the last method invoked during the parse. The parser shall + * not invoke this method until it has either abandoned parsing + * (because of an unrecoverable error) or reached the end of + * input.</p> + * + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + */ + public abstract void endDocument () + throws SAXException; + + + /** + * Receive notification of the beginning of an element. + * + * <p>The Parser will invoke this method at the beginning of every + * element in the XML document; there will be a corresponding + * endElement() event for every startElement() event (even when the + * element is empty). All of the element's content will be + * reported, in order, before the corresponding endElement() + * event.</p> + * + * <p>If the element name has a namespace prefix, the prefix will + * still be attached. Note that the attribute list provided will + * contain only attributes with explicit values (specified or + * defaulted): #IMPLIED attributes will be omitted.</p> + * + * @param name The element type name. + * @param atts The attributes attached to the element, if any. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + * @see #endElement + * @see org.xml.sax.AttributeList + */ + public abstract void startElement (String name, AttributeList atts) + throws SAXException; + + + /** + * Receive notification of the end of an element. + * + * <p>The SAX parser will invoke this method at the end of every + * element in the XML document; there will be a corresponding + * startElement() event for every endElement() event (even when the + * element is empty).</p> + * + * <p>If the element name has a namespace prefix, the prefix will + * still be attached to the name.</p> + * + * @param name The element type name + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + */ + public abstract void endElement (String name) + throws SAXException; + + + /** + * Receive notification of character data. + * + * <p>The Parser will call this method to report each chunk of + * character data. SAX parsers may return all contiguous character + * data in a single chunk, or they may split it into several + * chunks; however, all of the characters in any single event + * must come from the same external entity, so that the Locator + * provides useful information.</p> + * + * <p>The application must not attempt to read from the array + * outside of the specified range.</p> + * + * <p>Note that some parsers will report whitespace using the + * ignorableWhitespace() method rather than this one (validating + * parsers must do so).</p> + * + * @param ch The characters from the XML document. + * @param start The start position in the array. + * @param length The number of characters to read from the array. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + * @see #ignorableWhitespace + * @see org.xml.sax.Locator + */ + public abstract void characters (char ch[], int start, int length) + throws SAXException; + + + /** + * Receive notification of ignorable whitespace in element content. + * + * <p>Validating Parsers must use this method to report each chunk + * of ignorable whitespace (see the W3C XML 1.0 recommendation, + * section 2.10): non-validating parsers may also use this method + * if they are capable of parsing and using content models.</p> + * + * <p>SAX parsers may return all contiguous whitespace in a single + * chunk, or they may split it into several chunks; however, all of + * the characters in any single event must come from the same + * external entity, so that the Locator provides useful + * information.</p> + * + * <p>The application must not attempt to read from the array + * outside of the specified range.</p> + * + * @param ch The characters from the XML document. + * @param start The start position in the array. + * @param length The number of characters to read from the array. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + * @see #characters + */ + public abstract void ignorableWhitespace (char ch[], int start, int length) + throws SAXException; + + + /** + * Receive notification of a processing instruction. + * + * <p>The Parser will invoke this method once for each processing + * instruction found: note that processing instructions may occur + * before or after the main document element.</p> + * + * <p>A SAX parser should never report an XML declaration (XML 1.0, + * section 2.8) or a text declaration (XML 1.0, section 4.3.1) + * using this method.</p> + * + * @param target The processing instruction target. + * @param data The processing instruction data, or null if + * none was supplied. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + */ + public abstract void processingInstruction (String target, String data) + throws SAXException; + +} + +// end of DocumentHandler.java diff --git a/libjava/classpath/external/sax/org/xml/sax/EntityResolver.java b/libjava/classpath/external/sax/org/xml/sax/EntityResolver.java new file mode 100644 index 000000000..f1953d5ba --- /dev/null +++ b/libjava/classpath/external/sax/org/xml/sax/EntityResolver.java @@ -0,0 +1,119 @@ +// SAX entity resolver. +// http://www.saxproject.org +// No warranty; no copyright -- use this as you will. +// $Id: EntityResolver.java,v 1.1 2004/12/23 22:38:42 mark Exp $ + +package org.xml.sax; + +import java.io.IOException; + + +/** + * Basic interface for resolving entities. + * + * <blockquote> + * <em>This module, both source code and documentation, is in the + * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> + * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a> + * for further information. + * </blockquote> + * + * <p>If a SAX application needs to implement customized handling + * for external entities, it must implement this interface and + * register an instance with the SAX driver using the + * {@link org.xml.sax.XMLReader#setEntityResolver setEntityResolver} + * method.</p> + * + * <p>The XML reader will then allow the application to intercept any + * external entities (including the external DTD subset and external + * parameter entities, if any) before including them.</p> + * + * <p>Many SAX applications will not need to implement this interface, + * but it will be especially useful for applications that build + * XML documents from databases or other specialised input sources, + * or for applications that use URI types other than URLs.</p> + * + * <p>The following resolver would provide the application + * with a special character stream for the entity with the system + * identifier "http://www.myhost.com/today":</p> + * + * <pre> + * import org.xml.sax.EntityResolver; + * import org.xml.sax.InputSource; + * + * public class MyResolver implements EntityResolver { + * public InputSource resolveEntity (String publicId, String systemId) + * { + * if (systemId.equals("http://www.myhost.com/today")) { + * // return a special input source + * MyReader reader = new MyReader(); + * return new InputSource(reader); + * } else { + * // use the default behaviour + * return null; + * } + * } + * } + * </pre> + * + * <p>The application can also use this interface to redirect system + * identifiers to local URIs or to look up replacements in a catalog + * (possibly by using the public identifier).</p> + * + * @since SAX 1.0 + * @author David Megginson + * @version 2.0.1 (sax2r2) + * @see org.xml.sax.XMLReader#setEntityResolver + * @see org.xml.sax.InputSource + */ +public interface EntityResolver { + + + /** + * Allow the application to resolve external entities. + * + * <p>The parser will call this method before opening any external + * entity except the top-level document entity. Such entities include + * the external DTD subset and external parameter entities referenced + * within the DTD (in either case, only if the parser reads external + * parameter entities), and external general entities referenced + * within the document element (if the parser reads external general + * entities). The application may request that the parser locate + * the entity itself, that it use an alternative URI, or that it + * use data provided by the application (as a character or byte + * input stream).</p> + * + * <p>Application writers can use this method to redirect external + * system identifiers to secure and/or local URIs, to look up + * public identifiers in a catalogue, or to read an entity from a + * database or other input source (including, for example, a dialog + * box). Neither XML nor SAX specifies a preferred policy for using + * public or system IDs to resolve resources. However, SAX specifies + * how to interpret any InputSource returned by this method, and that + * if none is returned, then the system ID will be dereferenced as + * a URL. </p> + * + * <p>If the system identifier is a URL, the SAX parser must + * resolve it fully before reporting it to the application.</p> + * + * @param publicId The public identifier of the external entity + * being referenced, or null if none was supplied. + * @param systemId The system identifier of the external entity + * being referenced. + * @return An InputSource object describing the new input source, + * or null to request that the parser open a regular + * URI connection to the system identifier. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + * @exception java.io.IOException A Java-specific IO exception, + * possibly the result of creating a new InputStream + * or Reader for the InputSource. + * @see org.xml.sax.InputSource + */ + public abstract InputSource resolveEntity (String publicId, + String systemId) + throws SAXException, IOException; + +} + +// end of EntityResolver.java diff --git a/libjava/classpath/external/sax/org/xml/sax/ErrorHandler.java b/libjava/classpath/external/sax/org/xml/sax/ErrorHandler.java new file mode 100644 index 000000000..b315ec06d --- /dev/null +++ b/libjava/classpath/external/sax/org/xml/sax/ErrorHandler.java @@ -0,0 +1,139 @@ +// SAX error handler. +// http://www.saxproject.org +// No warranty; no copyright -- use this as you will. +// $Id: ErrorHandler.java,v 1.1 2004/12/23 22:38:42 mark Exp $ + +package org.xml.sax; + + +/** + * Basic interface for SAX error handlers. + * + * <blockquote> + * <em>This module, both source code and documentation, is in the + * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> + * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a> + * for further information. + * </blockquote> + * + * <p>If a SAX application needs to implement customized error + * handling, it must implement this interface and then register an + * instance with the XML reader using the + * {@link org.xml.sax.XMLReader#setErrorHandler setErrorHandler} + * method. The parser will then report all errors and warnings + * through this interface.</p> + * + * <p><strong>WARNING:</strong> If an application does <em>not</em> + * register an ErrorHandler, XML parsing errors will go unreported, + * except that <em>SAXParseException</em>s will be thrown for fatal errors. + * In order to detect validity errors, an ErrorHandler that does something + * with {@link #error error()} calls must be registered.</p> + * + * <p>For XML processing errors, a SAX driver must use this interface + * in preference to throwing an exception: it is up to the application + * to decide whether to throw an exception for different types of + * errors and warnings. Note, however, that there is no requirement that + * the parser continue to report additional errors after a call to + * {@link #fatalError fatalError}. In other words, a SAX driver class + * may throw an exception after reporting any fatalError. + * Also parsers may throw appropriate exceptions for non-XML errors. + * For example, {@link XMLReader#parse XMLReader.parse()} would throw + * an IOException for errors accessing entities or the document.</p> + * + * @since SAX 1.0 + * @author David Megginson + * @version 2.0.1+ (sax2r3pre1) + * @see org.xml.sax.XMLReader#setErrorHandler + * @see org.xml.sax.SAXParseException + */ +public interface ErrorHandler { + + + /** + * Receive notification of a warning. + * + * <p>SAX parsers will use this method to report conditions that + * are not errors or fatal errors as defined by the XML + * recommendation. The default behaviour is to take no + * action.</p> + * + * <p>The SAX parser must continue to provide normal parsing events + * after invoking this method: it should still be possible for the + * application to process the document through to the end.</p> + * + * <p>Filters may use this method to report other, non-XML warnings + * as well.</p> + * + * @param exception The warning information encapsulated in a + * SAX parse exception. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + * @see org.xml.sax.SAXParseException + */ + public abstract void warning (SAXParseException exception) + throws SAXException; + + + /** + * Receive notification of a recoverable error. + * + * <p>This corresponds to the definition of "error" in section 1.2 + * of the W3C XML 1.0 Recommendation. For example, a validating + * parser would use this callback to report the violation of a + * validity constraint. The default behaviour is to take no + * action.</p> + * + * <p>The SAX parser must continue to provide normal parsing + * events after invoking this method: it should still be possible + * for the application to process the document through to the end. + * If the application cannot do so, then the parser should report + * a fatal error even if the XML recommendation does not require + * it to do so.</p> + * + * <p>Filters may use this method to report other, non-XML errors + * as well.</p> + * + * @param exception The error information encapsulated in a + * SAX parse exception. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + * @see org.xml.sax.SAXParseException + */ + public abstract void error (SAXParseException exception) + throws SAXException; + + + /** + * Receive notification of a non-recoverable error. + * + * <p><strong>There is an apparent contradiction between the + * documentation for this method and the documentation for {@link + * org.xml.sax.ContentHandler#endDocument}. Until this ambiguity + * is resolved in a future major release, clients should make no + * assumptions about whether endDocument() will or will not be + * invoked when the parser has reported a fatalError() or thrown + * an exception.</strong></p> + * + * <p>This corresponds to the definition of "fatal error" in + * section 1.2 of the W3C XML 1.0 Recommendation. For example, a + * parser would use this callback to report the violation of a + * well-formedness constraint.</p> + * + * <p>The application must assume that the document is unusable + * after the parser has invoked this method, and should continue + * (if at all) only for the sake of collecting additional error + * messages: in fact, SAX parsers are free to stop reporting any + * other events once this method has been invoked.</p> + * + * @param exception The error information encapsulated in a + * SAX parse exception. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + * @see org.xml.sax.SAXParseException + */ + public abstract void fatalError (SAXParseException exception) + throws SAXException; + +} + +// end of ErrorHandler.java diff --git a/libjava/classpath/external/sax/org/xml/sax/HandlerBase.java b/libjava/classpath/external/sax/org/xml/sax/HandlerBase.java new file mode 100644 index 000000000..da27249fd --- /dev/null +++ b/libjava/classpath/external/sax/org/xml/sax/HandlerBase.java @@ -0,0 +1,369 @@ +// SAX default handler base class. +// http://www.saxproject.org +// No warranty; no copyright -- use this as you will. +// $Id: HandlerBase.java,v 1.1 2004/12/23 22:38:42 mark Exp $ + +package org.xml.sax; + +/** + * Default base class for handlers. + * + * <blockquote> + * <em>This module, both source code and documentation, is in the + * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> + * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a> + * for further information. + * </blockquote> + * + * <p>This class implements the default behaviour for four SAX1 + * interfaces: EntityResolver, DTDHandler, DocumentHandler, + * and ErrorHandler. It is now obsolete, but is included in SAX2 to + * support legacy SAX1 applications. SAX2 applications should use + * the {@link org.xml.sax.helpers.DefaultHandler DefaultHandler} + * class instead.</p> + * + * <p>Application writers can extend this class when they need to + * implement only part of an interface; parser writers can + * instantiate this class to provide default handlers when the + * application has not supplied its own.</p> + * + * <p>Note that the use of this class is optional.</p> + * + * @deprecated This class works with the deprecated + * {@link org.xml.sax.DocumentHandler DocumentHandler} + * interface. It has been replaced by the SAX2 + * {@link org.xml.sax.helpers.DefaultHandler DefaultHandler} + * class. + * @since SAX 1.0 + * @author David Megginson + * @version 2.0.1 (sax2r2) + * @see org.xml.sax.EntityResolver + * @see org.xml.sax.DTDHandler + * @see org.xml.sax.DocumentHandler + * @see org.xml.sax.ErrorHandler + */ +public class HandlerBase + implements EntityResolver, DTDHandler, DocumentHandler, ErrorHandler +{ + + + //////////////////////////////////////////////////////////////////// + // Default implementation of the EntityResolver interface. + //////////////////////////////////////////////////////////////////// + + /** + * Resolve an external entity. + * + * <p>Always return null, so that the parser will use the system + * identifier provided in the XML document. This method implements + * the SAX default behaviour: application writers can override it + * in a subclass to do special translations such as catalog lookups + * or URI redirection.</p> + * + * @param publicId The public identifer, or null if none is + * available. + * @param systemId The system identifier provided in the XML + * document. + * @return The new input source, or null to require the + * default behaviour. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + * @see org.xml.sax.EntityResolver#resolveEntity + */ + public InputSource resolveEntity (String publicId, String systemId) + throws SAXException + { + return null; + } + + + + //////////////////////////////////////////////////////////////////// + // Default implementation of DTDHandler interface. + //////////////////////////////////////////////////////////////////// + + + /** + * Receive notification of a notation declaration. + * + * <p>By default, do nothing. Application writers may override this + * method in a subclass if they wish to keep track of the notations + * declared in a document.</p> + * + * @param name The notation name. + * @param publicId The notation public identifier, or null if not + * available. + * @param systemId The notation system identifier. + * @see org.xml.sax.DTDHandler#notationDecl + */ + public void notationDecl (String name, String publicId, String systemId) + { + // no op + } + + + /** + * Receive notification of an unparsed entity declaration. + * + * <p>By default, do nothing. Application writers may override this + * method in a subclass to keep track of the unparsed entities + * declared in a document.</p> + * + * @param name The entity name. + * @param publicId The entity public identifier, or null if not + * available. + * @param systemId The entity system identifier. + * @param notationName The name of the associated notation. + * @see org.xml.sax.DTDHandler#unparsedEntityDecl + */ + public void unparsedEntityDecl (String name, String publicId, + String systemId, String notationName) + { + // no op + } + + + + //////////////////////////////////////////////////////////////////// + // Default implementation of DocumentHandler interface. + //////////////////////////////////////////////////////////////////// + + + /** + * Receive a Locator object for document events. + * + * <p>By default, do nothing. Application writers may override this + * method in a subclass if they wish to store the locator for use + * with other document events.</p> + * + * @param locator A locator for all SAX document events. + * @see org.xml.sax.DocumentHandler#setDocumentLocator + * @see org.xml.sax.Locator + */ + public void setDocumentLocator (Locator locator) + { + // no op + } + + + /** + * Receive notification of the beginning of the document. + * + * <p>By default, do nothing. Application writers may override this + * method in a subclass to take specific actions at the beginning + * of a document (such as allocating the root node of a tree or + * creating an output file).</p> + * + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + * @see org.xml.sax.DocumentHandler#startDocument + */ + public void startDocument () + throws SAXException + { + // no op + } + + + /** + * Receive notification of the end of the document. + * + * <p>By default, do nothing. Application writers may override this + * method in a subclass to take specific actions at the beginning + * of a document (such as finalising a tree or closing an output + * file).</p> + * + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + * @see org.xml.sax.DocumentHandler#endDocument + */ + public void endDocument () + throws SAXException + { + // no op + } + + + /** + * Receive notification of the start of an element. + * + * <p>By default, do nothing. Application writers may override this + * method in a subclass to take specific actions at the start of + * each element (such as allocating a new tree node or writing + * output to a file).</p> + * + * @param name The element type name. + * @param attributes The specified or defaulted attributes. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + * @see org.xml.sax.DocumentHandler#startElement + */ + public void startElement (String name, AttributeList attributes) + throws SAXException + { + // no op + } + + + /** + * Receive notification of the end of an element. + * + * <p>By default, do nothing. Application writers may override this + * method in a subclass to take specific actions at the end of + * each element (such as finalising a tree node or writing + * output to a file).</p> + * + * @param name the element name + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + * @see org.xml.sax.DocumentHandler#endElement + */ + public void endElement (String name) + throws SAXException + { + // no op + } + + + /** + * Receive notification of character data inside an element. + * + * <p>By default, do nothing. Application writers may override this + * method to take specific actions for each chunk of character data + * (such as adding the data to a node or buffer, or printing it to + * a file).</p> + * + * @param ch The characters. + * @param start The start position in the character array. + * @param length The number of characters to use from the + * character array. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + * @see org.xml.sax.DocumentHandler#characters + */ + public void characters (char ch[], int start, int length) + throws SAXException + { + // no op + } + + + /** + * Receive notification of ignorable whitespace in element content. + * + * <p>By default, do nothing. Application writers may override this + * method to take specific actions for each chunk of ignorable + * whitespace (such as adding data to a node or buffer, or printing + * it to a file).</p> + * + * @param ch The whitespace characters. + * @param start The start position in the character array. + * @param length The number of characters to use from the + * character array. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + * @see org.xml.sax.DocumentHandler#ignorableWhitespace + */ + public void ignorableWhitespace (char ch[], int start, int length) + throws SAXException + { + // no op + } + + + /** + * Receive notification of a processing instruction. + * + * <p>By default, do nothing. Application writers may override this + * method in a subclass to take specific actions for each + * processing instruction, such as setting status variables or + * invoking other methods.</p> + * + * @param target The processing instruction target. + * @param data The processing instruction data, or null if + * none is supplied. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + * @see org.xml.sax.DocumentHandler#processingInstruction + */ + public void processingInstruction (String target, String data) + throws SAXException + { + // no op + } + + + + //////////////////////////////////////////////////////////////////// + // Default implementation of the ErrorHandler interface. + //////////////////////////////////////////////////////////////////// + + + /** + * Receive notification of a parser warning. + * + * <p>The default implementation does nothing. Application writers + * may override this method in a subclass to take specific actions + * for each warning, such as inserting the message in a log file or + * printing it to the console.</p> + * + * @param e The warning information encoded as an exception. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + * @see org.xml.sax.ErrorHandler#warning + * @see org.xml.sax.SAXParseException + */ + public void warning (SAXParseException e) + throws SAXException + { + // no op + } + + + /** + * Receive notification of a recoverable parser error. + * + * <p>The default implementation does nothing. Application writers + * may override this method in a subclass to take specific actions + * for each error, such as inserting the message in a log file or + * printing it to the console.</p> + * + * @param e The warning information encoded as an exception. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + * @see org.xml.sax.ErrorHandler#warning + * @see org.xml.sax.SAXParseException + */ + public void error (SAXParseException e) + throws SAXException + { + // no op + } + + + /** + * Report a fatal XML parsing error. + * + * <p>The default implementation throws a SAXParseException. + * Application writers may override this method in a subclass if + * they need to take specific actions for each fatal error (such as + * collecting all of the errors into a single report): in any case, + * the application must stop all regular processing when this + * method is invoked, since the document is no longer reliable, and + * the parser may no longer report parsing events.</p> + * + * @param e The error information encoded as an exception. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + * @see org.xml.sax.ErrorHandler#fatalError + * @see org.xml.sax.SAXParseException + */ + public void fatalError (SAXParseException e) + throws SAXException + { + throw e; + } + +} + +// end of HandlerBase.java diff --git a/libjava/classpath/external/sax/org/xml/sax/InputSource.java b/libjava/classpath/external/sax/org/xml/sax/InputSource.java new file mode 100644 index 000000000..b5474921c --- /dev/null +++ b/libjava/classpath/external/sax/org/xml/sax/InputSource.java @@ -0,0 +1,336 @@ +// SAX input source. +// http://www.saxproject.org +// No warranty; no copyright -- use this as you will. +// $Id: InputSource.java,v 1.1 2004/12/23 22:38:42 mark Exp $ + +package org.xml.sax; + +import java.io.Reader; +import java.io.InputStream; + +/** + * A single input source for an XML entity. + * + * <blockquote> + * <em>This module, both source code and documentation, is in the + * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> + * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a> + * for further information. + * </blockquote> + * + * <p>This class allows a SAX application to encapsulate information + * about an input source in a single object, which may include + * a public identifier, a system identifier, a byte stream (possibly + * with a specified encoding), and/or a character stream.</p> + * + * <p>There are two places that the application can deliver an + * input source to the parser: as the argument to the Parser.parse + * method, or as the return value of the EntityResolver.resolveEntity + * method.</p> + * + * <p>The SAX parser will use the InputSource object to determine how + * to read XML input. If there is a character stream available, the + * parser will read that stream directly, disregarding any text + * encoding declaration found in that stream. + * If there is no character stream, but there is + * a byte stream, the parser will use that byte stream, using the + * encoding specified in the InputSource or else (if no encoding is + * specified) autodetecting the character encoding using an algorithm + * such as the one in the XML specification. If neither a character + * stream nor a + * byte stream is available, the parser will attempt to open a URI + * connection to the resource identified by the system + * identifier.</p> + * + * <p>An InputSource object belongs to the application: the SAX parser + * shall never modify it in any way (it may modify a copy if + * necessary). However, standard processing of both byte and + * character streams is to close them on as part of end-of-parse cleanup, + * so applications should not attempt to re-use such streams after they + * have been handed to a parser. </p> + * + * @since SAX 1.0 + * @author David Megginson + * @version 2.0.1 (sax2r2) + * @see org.xml.sax.XMLReader#parse(org.xml.sax.InputSource) + * @see org.xml.sax.EntityResolver#resolveEntity + * @see java.io.InputStream + * @see java.io.Reader + */ +public class InputSource { + + /** + * Zero-argument default constructor. + * + * @see #setPublicId + * @see #setSystemId + * @see #setByteStream + * @see #setCharacterStream + * @see #setEncoding + */ + public InputSource () + { + } + + + /** + * Create a new input source with a system identifier. + * + * <p>Applications may use setPublicId to include a + * public identifier as well, or setEncoding to specify + * the character encoding, if known.</p> + * + * <p>If the system identifier is a URL, it must be fully + * resolved (it may not be a relative URL).</p> + * + * @param systemId The system identifier (URI). + * @see #setPublicId + * @see #setSystemId + * @see #setByteStream + * @see #setEncoding + * @see #setCharacterStream + */ + public InputSource (String systemId) + { + setSystemId(systemId); + } + + + /** + * Create a new input source with a byte stream. + * + * <p>Application writers should use setSystemId() to provide a base + * for resolving relative URIs, may use setPublicId to include a + * public identifier, and may use setEncoding to specify the object's + * character encoding.</p> + * + * @param byteStream The raw byte stream containing the document. + * @see #setPublicId + * @see #setSystemId + * @see #setEncoding + * @see #setByteStream + * @see #setCharacterStream + */ + public InputSource (InputStream byteStream) + { + setByteStream(byteStream); + } + + + /** + * Create a new input source with a character stream. + * + * <p>Application writers should use setSystemId() to provide a base + * for resolving relative URIs, and may use setPublicId to include a + * public identifier.</p> + * + * <p>The character stream shall not include a byte order mark.</p> + * + * @see #setPublicId + * @see #setSystemId + * @see #setByteStream + * @see #setCharacterStream + */ + public InputSource (Reader characterStream) + { + setCharacterStream(characterStream); + } + + + /** + * Set the public identifier for this input source. + * + * <p>The public identifier is always optional: if the application + * writer includes one, it will be provided as part of the + * location information.</p> + * + * @param publicId The public identifier as a string. + * @see #getPublicId + * @see org.xml.sax.Locator#getPublicId + * @see org.xml.sax.SAXParseException#getPublicId + */ + public void setPublicId (String publicId) + { + this.publicId = publicId; + } + + + /** + * Get the public identifier for this input source. + * + * @return The public identifier, or null if none was supplied. + * @see #setPublicId + */ + public String getPublicId () + { + return publicId; + } + + + /** + * Set the system identifier for this input source. + * + * <p>The system identifier is optional if there is a byte stream + * or a character stream, but it is still useful to provide one, + * since the application can use it to resolve relative URIs + * and can include it in error messages and warnings (the parser + * will attempt to open a connection to the URI only if + * there is no byte stream or character stream specified).</p> + * + * <p>If the application knows the character encoding of the + * object pointed to by the system identifier, it can register + * the encoding using the setEncoding method.</p> + * + * <p>If the system identifier is a URL, it must be fully + * resolved (it may not be a relative URL).</p> + * + * @param systemId The system identifier as a string. + * @see #setEncoding + * @see #getSystemId + * @see org.xml.sax.Locator#getSystemId + * @see org.xml.sax.SAXParseException#getSystemId + */ + public void setSystemId (String systemId) + { + this.systemId = systemId; + } + + + /** + * Get the system identifier for this input source. + * + * <p>The getEncoding method will return the character encoding + * of the object pointed to, or null if unknown.</p> + * + * <p>If the system ID is a URL, it will be fully resolved.</p> + * + * @return The system identifier, or null if none was supplied. + * @see #setSystemId + * @see #getEncoding + */ + public String getSystemId () + { + return systemId; + } + + + /** + * Set the byte stream for this input source. + * + * <p>The SAX parser will ignore this if there is also a character + * stream specified, but it will use a byte stream in preference + * to opening a URI connection itself.</p> + * + * <p>If the application knows the character encoding of the + * byte stream, it should set it with the setEncoding method.</p> + * + * @param byteStream A byte stream containing an XML document or + * other entity. + * @see #setEncoding + * @see #getByteStream + * @see #getEncoding + * @see java.io.InputStream + */ + public void setByteStream (InputStream byteStream) + { + this.byteStream = byteStream; + } + + + /** + * Get the byte stream for this input source. + * + * <p>The getEncoding method will return the character + * encoding for this byte stream, or null if unknown.</p> + * + * @return The byte stream, or null if none was supplied. + * @see #getEncoding + * @see #setByteStream + */ + public InputStream getByteStream () + { + return byteStream; + } + + + /** + * Set the character encoding, if known. + * + * <p>The encoding must be a string acceptable for an + * XML encoding declaration (see section 4.3.3 of the XML 1.0 + * recommendation).</p> + * + * <p>This method has no effect when the application provides a + * character stream.</p> + * + * @param encoding A string describing the character encoding. + * @see #setSystemId + * @see #setByteStream + * @see #getEncoding + */ + public void setEncoding (String encoding) + { + this.encoding = encoding; + } + + + /** + * Get the character encoding for a byte stream or URI. + * This value will be ignored when the application provides a + * character stream. + * + * @return The encoding, or null if none was supplied. + * @see #setByteStream + * @see #getSystemId + * @see #getByteStream + */ + public String getEncoding () + { + return encoding; + } + + + /** + * Set the character stream for this input source. + * + * <p>If there is a character stream specified, the SAX parser + * will ignore any byte stream and will not attempt to open + * a URI connection to the system identifier.</p> + * + * @param characterStream The character stream containing the + * XML document or other entity. + * @see #getCharacterStream + * @see java.io.Reader + */ + public void setCharacterStream (Reader characterStream) + { + this.characterStream = characterStream; + } + + + /** + * Get the character stream for this input source. + * + * @return The character stream, or null if none was supplied. + * @see #setCharacterStream + */ + public Reader getCharacterStream () + { + return characterStream; + } + + + + //////////////////////////////////////////////////////////////////// + // Internal state. + //////////////////////////////////////////////////////////////////// + + private String publicId; + private String systemId; + private InputStream byteStream; + private String encoding; + private Reader characterStream; + +} + +// end of InputSource.java diff --git a/libjava/classpath/external/sax/org/xml/sax/Locator.java b/libjava/classpath/external/sax/org/xml/sax/Locator.java new file mode 100644 index 000000000..910f0d294 --- /dev/null +++ b/libjava/classpath/external/sax/org/xml/sax/Locator.java @@ -0,0 +1,136 @@ +// SAX locator interface for document events. +// http://www.saxproject.org +// No warranty; no copyright -- use this as you will. +// $Id: Locator.java,v 1.1 2004/12/23 22:38:42 mark Exp $ + +package org.xml.sax; + + +/** + * Interface for associating a SAX event with a document location. + * + * <blockquote> + * <em>This module, both source code and documentation, is in the + * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> + * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a> + * for further information. + * </blockquote> + * + * <p>If a SAX parser provides location information to the SAX + * application, it does so by implementing this interface and then + * passing an instance to the application using the content + * handler's {@link org.xml.sax.ContentHandler#setDocumentLocator + * setDocumentLocator} method. The application can use the + * object to obtain the location of any other SAX event + * in the XML source document.</p> + * + * <p>Note that the results returned by the object will be valid only + * during the scope of each callback method: the application + * will receive unpredictable results if it attempts to use the + * locator at any other time, or after parsing completes.</p> + * + * <p>SAX parsers are not required to supply a locator, but they are + * very strongly encouraged to do so. If the parser supplies a + * locator, it must do so before reporting any other document events. + * If no locator has been set by the time the application receives + * the {@link org.xml.sax.ContentHandler#startDocument startDocument} + * event, the application should assume that a locator is not + * available.</p> + * + * @since SAX 1.0 + * @author David Megginson + * @version 2.0.1 (sax2r2) + * @see org.xml.sax.ContentHandler#setDocumentLocator + */ +public interface Locator { + + + /** + * Return the public identifier for the current document event. + * + * <p>The return value is the public identifier of the document + * entity or of the external parsed entity in which the markup + * triggering the event appears.</p> + * + * @return A string containing the public identifier, or + * null if none is available. + * @see #getSystemId + */ + public abstract String getPublicId (); + + + /** + * Return the system identifier for the current document event. + * + * <p>The return value is the system identifier of the document + * entity or of the external parsed entity in which the markup + * triggering the event appears.</p> + * + * <p>If the system identifier is a URL, the parser must resolve it + * fully before passing it to the application. For example, a file + * name must always be provided as a <em>file:...</em> URL, and other + * kinds of relative URI are also resolved against their bases.</p> + * + * @return A string containing the system identifier, or null + * if none is available. + * @see #getPublicId + */ + public abstract String getSystemId (); + + + /** + * Return the line number where the current document event ends. + * Lines are delimited by line ends, which are defined in + * the XML specification. + * + * <p><strong>Warning:</strong> The return value from the method + * is intended only as an approximation for the sake of diagnostics; + * it is not intended to provide sufficient information + * to edit the character content of the original XML document. + * In some cases, these "line" numbers match what would be displayed + * as columns, and in others they may not match the source text + * due to internal entity expansion. </p> + * + * <p>The return value is an approximation of the line number + * in the document entity or external parsed entity where the + * markup triggering the event appears.</p> + * + * <p>If possible, the SAX driver should provide the line position + * of the first character after the text associated with the document + * event. The first line is line 1.</p> + * + * @return The line number, or -1 if none is available. + * @see #getColumnNumber + */ + public abstract int getLineNumber (); + + + /** + * Return the column number where the current document event ends. + * This is one-based number of Java <code>char</code> values since + * the last line end. + * + * <p><strong>Warning:</strong> The return value from the method + * is intended only as an approximation for the sake of diagnostics; + * it is not intended to provide sufficient information + * to edit the character content of the original XML document. + * For example, when lines contain combining character sequences, wide + * characters, surrogate pairs, or bi-directional text, the value may + * not correspond to the column in a text editor's display. </p> + * + * <p>The return value is an approximation of the column number + * in the document entity or external parsed entity where the + * markup triggering the event appears.</p> + * + * <p>If possible, the SAX driver should provide the line position + * of the first character after the text associated with the document + * event. The first column in each line is column 1.</p> + * + * @return The column number, or -1 if none is available. + * @see #getLineNumber + */ + public abstract int getColumnNumber (); + +} + +// end of Locator.java diff --git a/libjava/classpath/external/sax/org/xml/sax/Parser.java b/libjava/classpath/external/sax/org/xml/sax/Parser.java new file mode 100644 index 000000000..994648897 --- /dev/null +++ b/libjava/classpath/external/sax/org/xml/sax/Parser.java @@ -0,0 +1,209 @@ +// SAX parser interface. +// http://www.saxproject.org +// No warranty; no copyright -- use this as you will. +// $Id: Parser.java,v 1.1 2004/12/23 22:38:42 mark Exp $ + +package org.xml.sax; + +import java.io.IOException; +import java.util.Locale; + + +/** + * Basic interface for SAX (Simple API for XML) parsers. + * + * <blockquote> + * <em>This module, both source code and documentation, is in the + * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> + * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a> + * for further information. + * </blockquote> + * + * <p>This was the main event supplier interface for SAX1; it has + * been replaced in SAX2 by {@link org.xml.sax.XMLReader XMLReader}, + * which includes Namespace support and sophisticated configurability + * and extensibility.</p> + * + * <p>All SAX1 parsers must implement this basic interface: it allows + * applications to register handlers for different types of events + * and to initiate a parse from a URI, or a character stream.</p> + * + * <p>All SAX1 parsers must also implement a zero-argument constructor + * (though other constructors are also allowed).</p> + * + * <p>SAX1 parsers are reusable but not re-entrant: the application + * may reuse a parser object (possibly with a different input source) + * once the first parse has completed successfully, but it may not + * invoke the parse() methods recursively within a parse.</p> + * + * @deprecated This interface has been replaced by the SAX2 + * {@link org.xml.sax.XMLReader XMLReader} + * interface, which includes Namespace support. + * @since SAX 1.0 + * @author David Megginson + * @version 2.0.1 (sax2r2) + * @see org.xml.sax.EntityResolver + * @see org.xml.sax.DTDHandler + * @see org.xml.sax.DocumentHandler + * @see org.xml.sax.ErrorHandler + * @see org.xml.sax.HandlerBase + * @see org.xml.sax.InputSource + */ +public interface Parser +{ + + /** + * Allow an application to request a locale for errors and warnings. + * + * <p>SAX parsers are not required to provide localisation for errors + * and warnings; if they cannot support the requested locale, + * however, they must throw a SAX exception. Applications may + * not request a locale change in the middle of a parse.</p> + * + * @param locale A Java Locale object. + * @exception org.xml.sax.SAXException Throws an exception + * (using the previous or default locale) if the + * requested locale is not supported. + * @see org.xml.sax.SAXException + * @see org.xml.sax.SAXParseException + */ + public abstract void setLocale (Locale locale) + throws SAXException; + + + /** + * Allow an application to register a custom entity resolver. + * + * <p>If the application does not register an entity resolver, the + * SAX parser will resolve system identifiers and open connections + * to entities itself (this is the default behaviour implemented in + * HandlerBase).</p> + * + * <p>Applications may register a new or different entity resolver + * in the middle of a parse, and the SAX parser must begin using + * the new resolver immediately.</p> + * + * @param resolver The object for resolving entities. + * @see EntityResolver + * @see HandlerBase + */ + public abstract void setEntityResolver (EntityResolver resolver); + + + /** + * Allow an application to register a DTD event handler. + * + * <p>If the application does not register a DTD handler, all DTD + * events reported by the SAX parser will be silently + * ignored (this is the default behaviour implemented by + * HandlerBase).</p> + * + * <p>Applications may register a new or different + * handler in the middle of a parse, and the SAX parser must + * begin using the new handler immediately.</p> + * + * @param handler The DTD handler. + * @see DTDHandler + * @see HandlerBase + */ + public abstract void setDTDHandler (DTDHandler handler); + + + /** + * Allow an application to register a document event handler. + * + * <p>If the application does not register a document handler, all + * document events reported by the SAX parser will be silently + * ignored (this is the default behaviour implemented by + * HandlerBase).</p> + * + * <p>Applications may register a new or different handler in the + * middle of a parse, and the SAX parser must begin using the new + * handler immediately.</p> + * + * @param handler The document handler. + * @see DocumentHandler + * @see HandlerBase + */ + public abstract void setDocumentHandler (DocumentHandler handler); + + + /** + * Allow an application to register an error event handler. + * + * <p>If the application does not register an error event handler, + * all error events reported by the SAX parser will be silently + * ignored, except for fatalError, which will throw a SAXException + * (this is the default behaviour implemented by HandlerBase).</p> + * + * <p>Applications may register a new or different handler in the + * middle of a parse, and the SAX parser must begin using the new + * handler immediately.</p> + * + * @param handler The error handler. + * @see ErrorHandler + * @see SAXException + * @see HandlerBase + */ + public abstract void setErrorHandler (ErrorHandler handler); + + + /** + * Parse an XML document. + * + * <p>The application can use this method to instruct the SAX parser + * to begin parsing an XML document from any valid input + * source (a character stream, a byte stream, or a URI).</p> + * + * <p>Applications may not invoke this method while a parse is in + * progress (they should create a new Parser instead for each + * additional XML document). Once a parse is complete, an + * application may reuse the same Parser object, possibly with a + * different input source.</p> + * + * @param source The input source for the top-level of the + * XML document. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + * @exception java.io.IOException An IO exception from the parser, + * possibly from a byte stream or character stream + * supplied by the application. + * @see org.xml.sax.InputSource + * @see #parse(java.lang.String) + * @see #setEntityResolver + * @see #setDTDHandler + * @see #setDocumentHandler + * @see #setErrorHandler + */ + public abstract void parse (InputSource source) + throws SAXException, IOException; + + + /** + * Parse an XML document from a system identifier (URI). + * + * <p>This method is a shortcut for the common case of reading a + * document from a system identifier. It is the exact + * equivalent of the following:</p> + * + * <pre> + * parse(new InputSource(systemId)); + * </pre> + * + * <p>If the system identifier is a URL, it must be fully resolved + * by the application before it is passed to the parser.</p> + * + * @param systemId The system identifier (URI). + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + * @exception java.io.IOException An IO exception from the parser, + * possibly from a byte stream or character stream + * supplied by the application. + * @see #parse(org.xml.sax.InputSource) + */ + public abstract void parse (String systemId) + throws SAXException, IOException; + +} + +// end of Parser.java diff --git a/libjava/classpath/external/sax/org/xml/sax/SAXException.java b/libjava/classpath/external/sax/org/xml/sax/SAXException.java new file mode 100644 index 000000000..f8691bc57 --- /dev/null +++ b/libjava/classpath/external/sax/org/xml/sax/SAXException.java @@ -0,0 +1,153 @@ +// SAX exception class. +// http://www.saxproject.org +// No warranty; no copyright -- use this as you will. +// $Id: SAXException.java,v 1.1 2004/12/23 22:38:42 mark Exp $ + +package org.xml.sax; + +/** + * Encapsulate a general SAX error or warning. + * + * <blockquote> + * <em>This module, both source code and documentation, is in the + * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> + * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a> + * for further information. + * </blockquote> + * + * <p>This class can contain basic error or warning information from + * either the XML parser or the application: a parser writer or + * application writer can subclass it to provide additional + * functionality. SAX handlers may throw this exception or + * any exception subclassed from it.</p> + * + * <p>If the application needs to pass through other types of + * exceptions, it must wrap those exceptions in a SAXException + * or an exception derived from a SAXException.</p> + * + * <p>If the parser or application needs to include information about a + * specific location in an XML document, it should use the + * {@link org.xml.sax.SAXParseException SAXParseException} subclass.</p> + * + * @since SAX 1.0 + * @author David Megginson + * @version 2.0.1 (sax2r2) + * @see org.xml.sax.SAXParseException + */ +public class SAXException extends Exception { + + + /** + * Create a new SAXException. + */ + public SAXException () + { + super(); + this.exception = null; + } + + + /** + * Create a new SAXException. + * + * @param message The error or warning message. + */ + public SAXException (String message) { + super(message); + this.exception = null; + } + + + /** + * Create a new SAXException wrapping an existing exception. + * + * <p>The existing exception will be embedded in the new + * one, and its message will become the default message for + * the SAXException.</p> + * + * @param e The exception to be wrapped in a SAXException. + */ + public SAXException (Exception e) + { + super(); + this.exception = e; + } + + + /** + * Create a new SAXException from an existing exception. + * + * <p>The existing exception will be embedded in the new + * one, but the new exception will have its own message.</p> + * + * @param message The detail message. + * @param e The exception to be wrapped in a SAXException. + */ + public SAXException (String message, Exception e) + { + super(message); + this.exception = e; + } + + + /** + * Return a detail message for this exception. + * + * <p>If there is an embedded exception, and if the SAXException + * has no detail message of its own, this method will return + * the detail message from the embedded exception.</p> + * + * @return The error or warning message. + */ + public String getMessage () + { + String message = super.getMessage(); + + if (message == null && exception != null) { + return exception.getMessage(); + } else { + return message; + } + } + + + /** + * Return the embedded exception, if any. + * + * @return The embedded exception, or null if there is none. + */ + public Exception getException () + { + return exception; + } + + + /** + * Override toString to pick up any embedded exception. + * + * @return A string representation of this exception. + */ + public String toString () + { + if (exception != null) { + return exception.toString(); + } else { + return super.toString(); + } + } + + + + ////////////////////////////////////////////////////////////////////// + // Internal state. + ////////////////////////////////////////////////////////////////////// + + + /** + * @serial The embedded exception if tunnelling, or null. + */ + private Exception exception; + +} + +// end of SAXException.java diff --git a/libjava/classpath/external/sax/org/xml/sax/SAXNotRecognizedException.java b/libjava/classpath/external/sax/org/xml/sax/SAXNotRecognizedException.java new file mode 100644 index 000000000..b512288ec --- /dev/null +++ b/libjava/classpath/external/sax/org/xml/sax/SAXNotRecognizedException.java @@ -0,0 +1,53 @@ +// SAXNotRecognizedException.java - unrecognized feature or value. +// http://www.saxproject.org +// Written by David Megginson +// NO WARRANTY! This class is in the Public Domain. +// $Id: SAXNotRecognizedException.java,v 1.1 2004/12/23 22:38:42 mark Exp $ + +package org.xml.sax; + + +/** + * Exception class for an unrecognized identifier. + * + * <blockquote> + * <em>This module, both source code and documentation, is in the + * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> + * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a> + * for further information. + * </blockquote> + * + * <p>An XMLReader will throw this exception when it finds an + * unrecognized feature or property identifier; SAX applications and + * extensions may use this class for other, similar purposes.</p> + * + * @since SAX 2.0 + * @author David Megginson + * @version 2.0.1 (sax2r2) + * @see org.xml.sax.SAXNotSupportedException + */ +public class SAXNotRecognizedException extends SAXException +{ + + /** + * Default constructor. + */ + public SAXNotRecognizedException () + { + super(); + } + + + /** + * Construct a new exception with the given message. + * + * @param message The text message of the exception. + */ + public SAXNotRecognizedException (String message) + { + super(message); + } + +} + +// end of SAXNotRecognizedException.java diff --git a/libjava/classpath/external/sax/org/xml/sax/SAXNotSupportedException.java b/libjava/classpath/external/sax/org/xml/sax/SAXNotSupportedException.java new file mode 100644 index 000000000..e59fd40e0 --- /dev/null +++ b/libjava/classpath/external/sax/org/xml/sax/SAXNotSupportedException.java @@ -0,0 +1,53 @@ +// SAXNotSupportedException.java - unsupported feature or value. +// http://www.saxproject.org +// Written by David Megginson +// NO WARRANTY! This class is in the Public Domain. +// $Id: SAXNotSupportedException.java,v 1.1 2004/12/23 22:38:42 mark Exp $ + +package org.xml.sax; + +/** + * Exception class for an unsupported operation. + * + * <blockquote> + * <em>This module, both source code and documentation, is in the + * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> + * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a> + * for further information. + * </blockquote> + * + * <p>An XMLReader will throw this exception when it recognizes a + * feature or property identifier, but cannot perform the requested + * operation (setting a state or value). Other SAX2 applications and + * extensions may use this class for similar purposes.</p> + * + * @since SAX 2.0 + * @author David Megginson + * @version 2.0.1 (sax2r2) + * @see org.xml.sax.SAXNotRecognizedException + */ +public class SAXNotSupportedException extends SAXException +{ + + /** + * Construct a new exception with no message. + */ + public SAXNotSupportedException () + { + super(); + } + + + /** + * Construct a new exception with the given message. + * + * @param message The text message of the exception. + */ + public SAXNotSupportedException (String message) + { + super(message); + } + +} + +// end of SAXNotSupportedException.java diff --git a/libjava/classpath/external/sax/org/xml/sax/SAXParseException.java b/libjava/classpath/external/sax/org/xml/sax/SAXParseException.java new file mode 100644 index 000000000..0921be762 --- /dev/null +++ b/libjava/classpath/external/sax/org/xml/sax/SAXParseException.java @@ -0,0 +1,269 @@ +// SAX exception class. +// http://www.saxproject.org +// No warranty; no copyright -- use this as you will. +// $Id: SAXParseException.java,v 1.1 2004/12/23 22:38:42 mark Exp $ + +package org.xml.sax; + +/** + * Encapsulate an XML parse error or warning. + * + * <blockquote> + * <em>This module, both source code and documentation, is in the + * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> + * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a> + * for further information. + * </blockquote> + * + * <p>This exception may include information for locating the error + * in the original XML document, as if it came from a {@link Locator} + * object. Note that although the application + * will receive a SAXParseException as the argument to the handlers + * in the {@link org.xml.sax.ErrorHandler ErrorHandler} interface, + * the application is not actually required to throw the exception; + * instead, it can simply read the information in it and take a + * different action.</p> + * + * <p>Since this exception is a subclass of {@link org.xml.sax.SAXException + * SAXException}, it inherits the ability to wrap another exception.</p> + * + * @since SAX 1.0 + * @author David Megginson + * @version 2.0.1 (sax2r2) + * @see org.xml.sax.SAXException + * @see org.xml.sax.Locator + * @see org.xml.sax.ErrorHandler + */ +public class SAXParseException extends SAXException { + + + ////////////////////////////////////////////////////////////////////// + // Constructors. + ////////////////////////////////////////////////////////////////////// + + + /** + * Create a new SAXParseException from a message and a Locator. + * + * <p>This constructor is especially useful when an application is + * creating its own exception from within a {@link org.xml.sax.ContentHandler + * ContentHandler} callback.</p> + * + * @param message The error or warning message. + * @param locator The locator object for the error or warning (may be + * null). + * @see org.xml.sax.Locator + */ + public SAXParseException (String message, Locator locator) { + super(message); + if (locator != null) { + init(locator.getPublicId(), locator.getSystemId(), + locator.getLineNumber(), locator.getColumnNumber()); + } else { + init(null, null, -1, -1); + } + } + + + /** + * Wrap an existing exception in a SAXParseException. + * + * <p>This constructor is especially useful when an application is + * creating its own exception from within a {@link org.xml.sax.ContentHandler + * ContentHandler} callback, and needs to wrap an existing exception that is not a + * subclass of {@link org.xml.sax.SAXException SAXException}.</p> + * + * @param message The error or warning message, or null to + * use the message from the embedded exception. + * @param locator The locator object for the error or warning (may be + * null). + * @param e Any exception. + * @see org.xml.sax.Locator + */ + public SAXParseException (String message, Locator locator, + Exception e) { + super(message, e); + if (locator != null) { + init(locator.getPublicId(), locator.getSystemId(), + locator.getLineNumber(), locator.getColumnNumber()); + } else { + init(null, null, -1, -1); + } + } + + + /** + * Create a new SAXParseException. + * + * <p>This constructor is most useful for parser writers.</p> + * + * <p>All parameters except the message are as if + * they were provided by a {@link Locator}. For example, if the + * system identifier is a URL (including relative filename), the + * caller must resolve it fully before creating the exception.</p> + * + * + * @param message The error or warning message. + * @param publicId The public identifier of the entity that generated + * the error or warning. + * @param systemId The system identifier of the entity that generated + * the error or warning. + * @param lineNumber The line number of the end of the text that + * caused the error or warning. + * @param columnNumber The column number of the end of the text that + * cause the error or warning. + */ + public SAXParseException (String message, String publicId, String systemId, + int lineNumber, int columnNumber) + { + super(message); + init(publicId, systemId, lineNumber, columnNumber); + } + + + /** + * Create a new SAXParseException with an embedded exception. + * + * <p>This constructor is most useful for parser writers who + * need to wrap an exception that is not a subclass of + * {@link org.xml.sax.SAXException SAXException}.</p> + * + * <p>All parameters except the message and exception are as if + * they were provided by a {@link Locator}. For example, if the + * system identifier is a URL (including relative filename), the + * caller must resolve it fully before creating the exception.</p> + * + * @param message The error or warning message, or null to use + * the message from the embedded exception. + * @param publicId The public identifier of the entity that generated + * the error or warning. + * @param systemId The system identifier of the entity that generated + * the error or warning. + * @param lineNumber The line number of the end of the text that + * caused the error or warning. + * @param columnNumber The column number of the end of the text that + * cause the error or warning. + * @param e Another exception to embed in this one. + */ + public SAXParseException (String message, String publicId, String systemId, + int lineNumber, int columnNumber, Exception e) + { + super(message, e); + init(publicId, systemId, lineNumber, columnNumber); + } + + + /** + * Internal initialization method. + * + * @param publicId The public identifier of the entity which generated the exception, + * or null. + * @param systemId The system identifier of the entity which generated the exception, + * or null. + * @param lineNumber The line number of the error, or -1. + * @param columnNumber The column number of the error, or -1. + */ + private void init (String publicId, String systemId, + int lineNumber, int columnNumber) + { + this.publicId = publicId; + this.systemId = systemId; + this.lineNumber = lineNumber; + this.columnNumber = columnNumber; + } + + + /** + * Get the public identifier of the entity where the exception occurred. + * + * @return A string containing the public identifier, or null + * if none is available. + * @see org.xml.sax.Locator#getPublicId + */ + public String getPublicId () + { + return this.publicId; + } + + + /** + * Get the system identifier of the entity where the exception occurred. + * + * <p>If the system identifier is a URL, it will have been resolved + * fully.</p> + * + * @return A string containing the system identifier, or null + * if none is available. + * @see org.xml.sax.Locator#getSystemId + */ + public String getSystemId () + { + return this.systemId; + } + + + /** + * The line number of the end of the text where the exception occurred. + * + * <p>The first line is line 1.</p> + * + * @return An integer representing the line number, or -1 + * if none is available. + * @see org.xml.sax.Locator#getLineNumber + */ + public int getLineNumber () + { + return this.lineNumber; + } + + + /** + * The column number of the end of the text where the exception occurred. + * + * <p>The first column in a line is position 1.</p> + * + * @return An integer representing the column number, or -1 + * if none is available. + * @see org.xml.sax.Locator#getColumnNumber + */ + public int getColumnNumber () + { + return this.columnNumber; + } + + + ////////////////////////////////////////////////////////////////////// + // Internal state. + ////////////////////////////////////////////////////////////////////// + + + /** + * @serial The public identifier, or null. + * @see #getPublicId + */ + private String publicId; + + + /** + * @serial The system identifier, or null. + * @see #getSystemId + */ + private String systemId; + + + /** + * @serial The line number, or -1. + * @see #getLineNumber + */ + private int lineNumber; + + + /** + * @serial The column number, or -1. + * @see #getColumnNumber + */ + private int columnNumber; + +} + +// end of SAXParseException.java diff --git a/libjava/classpath/external/sax/org/xml/sax/XMLFilter.java b/libjava/classpath/external/sax/org/xml/sax/XMLFilter.java new file mode 100644 index 000000000..363328e2d --- /dev/null +++ b/libjava/classpath/external/sax/org/xml/sax/XMLFilter.java @@ -0,0 +1,65 @@ +// XMLFilter.java - filter SAX2 events. +// http://www.saxproject.org +// Written by David Megginson +// NO WARRANTY! This class is in the Public Domain. +// $Id: XMLFilter.java,v 1.1 2004/12/23 22:38:42 mark Exp $ + +package org.xml.sax; + + +/** + * Interface for an XML filter. + * + * <blockquote> + * <em>This module, both source code and documentation, is in the + * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> + * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a> + * for further information. + * </blockquote> + * + * <p>An XML filter is like an XML reader, except that it obtains its + * events from another XML reader rather than a primary source like + * an XML document or database. Filters can modify a stream of + * events as they pass on to the final application.</p> + * + * <p>The XMLFilterImpl helper class provides a convenient base + * for creating SAX2 filters, by passing on all {@link org.xml.sax.EntityResolver + * EntityResolver}, {@link org.xml.sax.DTDHandler DTDHandler}, + * {@link org.xml.sax.ContentHandler ContentHandler} and {@link org.xml.sax.ErrorHandler + * ErrorHandler} events automatically.</p> + * + * @since SAX 2.0 + * @author David Megginson + * @version 2.0.1 (sax2r2) + * @see org.xml.sax.helpers.XMLFilterImpl + */ +public interface XMLFilter extends XMLReader +{ + + /** + * Set the parent reader. + * + * <p>This method allows the application to link the filter to + * a parent reader (which may be another filter). The argument + * may not be null.</p> + * + * @param parent The parent reader. + */ + public abstract void setParent (XMLReader parent); + + + /** + * Get the parent reader. + * + * <p>This method allows the application to query the parent + * reader (which may be another filter). It is generally a + * bad idea to perform any operations on the parent reader + * directly: they should all pass through this filter.</p> + * + * @return The parent filter, or null if none has been set. + */ + public abstract XMLReader getParent (); + +} + +// end of XMLFilter.java diff --git a/libjava/classpath/external/sax/org/xml/sax/XMLReader.java b/libjava/classpath/external/sax/org/xml/sax/XMLReader.java new file mode 100644 index 000000000..d334f03fb --- /dev/null +++ b/libjava/classpath/external/sax/org/xml/sax/XMLReader.java @@ -0,0 +1,404 @@ +// XMLReader.java - read an XML document. +// http://www.saxproject.org +// Written by David Megginson +// NO WARRANTY! This class is in the Public Domain. +// $Id: XMLReader.java,v 1.1 2004/12/23 22:38:42 mark Exp $ + +package org.xml.sax; + +import java.io.IOException; + + +/** + * Interface for reading an XML document using callbacks. + * + * <blockquote> + * <em>This module, both source code and documentation, is in the + * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> + * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a> + * for further information. + * </blockquote> + * + * <p><strong>Note:</strong> despite its name, this interface does + * <em>not</em> extend the standard Java {@link java.io.Reader Reader} + * interface, because reading XML is a fundamentally different activity + * than reading character data.</p> + * + * <p>XMLReader is the interface that an XML parser's SAX2 driver must + * implement. This interface allows an application to set and + * query features and properties in the parser, to register + * event handlers for document processing, and to initiate + * a document parse.</p> + * + * <p>All SAX interfaces are assumed to be synchronous: the + * {@link #parse parse} methods must not return until parsing + * is complete, and readers must wait for an event-handler callback + * to return before reporting the next event.</p> + * + * <p>This interface replaces the (now deprecated) SAX 1.0 {@link + * org.xml.sax.Parser Parser} interface. The XMLReader interface + * contains two important enhancements over the old Parser + * interface (as well as some minor ones):</p> + * + * <ol> + * <li>it adds a standard way to query and set features and + * properties; and</li> + * <li>it adds Namespace support, which is required for many + * higher-level XML standards.</li> + * </ol> + * + * <p>There are adapters available to convert a SAX1 Parser to + * a SAX2 XMLReader and vice-versa.</p> + * + * @since SAX 2.0 + * @author David Megginson + * @version 2.0.1+ (sax2r3pre1) + * @see org.xml.sax.XMLFilter + * @see org.xml.sax.helpers.ParserAdapter + * @see org.xml.sax.helpers.XMLReaderAdapter + */ +public interface XMLReader +{ + + + //////////////////////////////////////////////////////////////////// + // Configuration. + //////////////////////////////////////////////////////////////////// + + + /** + * Look up the value of a feature flag. + * + * <p>The feature name is any fully-qualified URI. It is + * possible for an XMLReader to recognize a feature name but + * temporarily be unable to return its value. + * Some feature values may be available only in specific + * contexts, such as before, during, or after a parse. + * Also, some feature values may not be programmatically accessible. + * (In the case of an adapter for SAX1 {@link Parser}, there is no + * implementation-independent way to expose whether the underlying + * parser is performing validation, expanding external entities, + * and so forth.) </p> + * + * <p>All XMLReaders are required to recognize the + * http://xml.org/sax/features/namespaces and the + * http://xml.org/sax/features/namespace-prefixes feature names.</p> + * + * <p>Typical usage is something like this:</p> + * + * <pre> + * XMLReader r = new MySAXDriver(); + * + * // try to activate validation + * try { + * r.setFeature("http://xml.org/sax/features/validation", true); + * } catch (SAXException e) { + * System.err.println("Cannot activate validation."); + * } + * + * // register event handlers + * r.setContentHandler(new MyContentHandler()); + * r.setErrorHandler(new MyErrorHandler()); + * + * // parse the first document + * try { + * r.parse("http://www.foo.com/mydoc.xml"); + * } catch (IOException e) { + * System.err.println("I/O exception reading XML document"); + * } catch (SAXException e) { + * System.err.println("XML exception reading document."); + * } + * </pre> + * + * <p>Implementors are free (and encouraged) to invent their own features, + * using names built on their own URIs.</p> + * + * @param name The feature name, which is a fully-qualified URI. + * @return The current value of the feature (true or false). + * @exception org.xml.sax.SAXNotRecognizedException If the feature + * value can't be assigned or retrieved. + * @exception org.xml.sax.SAXNotSupportedException When the + * XMLReader recognizes the feature name but + * cannot determine its value at this time. + * @see #setFeature + */ + public boolean getFeature (String name) + throws SAXNotRecognizedException, SAXNotSupportedException; + + + /** + * Set the value of a feature flag. + * + * <p>The feature name is any fully-qualified URI. It is + * possible for an XMLReader to expose a feature value but + * to be unable to change the current value. + * Some feature values may be immutable or mutable only + * in specific contexts, such as before, during, or after + * a parse.</p> + * + * <p>All XMLReaders are required to support setting + * http://xml.org/sax/features/namespaces to true and + * http://xml.org/sax/features/namespace-prefixes to false.</p> + * + * @param name The feature name, which is a fully-qualified URI. + * @param value The requested value of the feature (true or false). + * @exception org.xml.sax.SAXNotRecognizedException If the feature + * value can't be assigned or retrieved. + * @exception org.xml.sax.SAXNotSupportedException When the + * XMLReader recognizes the feature name but + * cannot set the requested value. + * @see #getFeature + */ + public void setFeature (String name, boolean value) + throws SAXNotRecognizedException, SAXNotSupportedException; + + + /** + * Look up the value of a property. + * + * <p>The property name is any fully-qualified URI. It is + * possible for an XMLReader to recognize a property name but + * temporarily be unable to return its value. + * Some property values may be available only in specific + * contexts, such as before, during, or after a parse.</p> + * + * <p>XMLReaders are not required to recognize any specific + * property names, though an initial core set is documented for + * SAX2.</p> + * + * <p>Implementors are free (and encouraged) to invent their own properties, + * using names built on their own URIs.</p> + * + * @param name The property name, which is a fully-qualified URI. + * @return The current value of the property. + * @exception org.xml.sax.SAXNotRecognizedException If the property + * value can't be assigned or retrieved. + * @exception org.xml.sax.SAXNotSupportedException When the + * XMLReader recognizes the property name but + * cannot determine its value at this time. + * @see #setProperty + */ + public Object getProperty (String name) + throws SAXNotRecognizedException, SAXNotSupportedException; + + + /** + * Set the value of a property. + * + * <p>The property name is any fully-qualified URI. It is + * possible for an XMLReader to recognize a property name but + * to be unable to change the current value. + * Some property values may be immutable or mutable only + * in specific contexts, such as before, during, or after + * a parse.</p> + * + * <p>XMLReaders are not required to recognize setting + * any specific property names, though a core set is defined by + * SAX2.</p> + * + * <p>This method is also the standard mechanism for setting + * extended handlers.</p> + * + * @param name The property name, which is a fully-qualified URI. + * @param value The requested value for the property. + * @exception org.xml.sax.SAXNotRecognizedException If the property + * value can't be assigned or retrieved. + * @exception org.xml.sax.SAXNotSupportedException When the + * XMLReader recognizes the property name but + * cannot set the requested value. + */ + public void setProperty (String name, Object value) + throws SAXNotRecognizedException, SAXNotSupportedException; + + + + //////////////////////////////////////////////////////////////////// + // Event handlers. + //////////////////////////////////////////////////////////////////// + + + /** + * Allow an application to register an entity resolver. + * + * <p>If the application does not register an entity resolver, + * the XMLReader will perform its own default resolution.</p> + * + * <p>Applications may register a new or different resolver in the + * middle of a parse, and the SAX parser must begin using the new + * resolver immediately.</p> + * + * @param resolver The entity resolver. + * @see #getEntityResolver + */ + public void setEntityResolver (EntityResolver resolver); + + + /** + * Return the current entity resolver. + * + * @return The current entity resolver, or null if none + * has been registered. + * @see #setEntityResolver + */ + public EntityResolver getEntityResolver (); + + + /** + * Allow an application to register a DTD event handler. + * + * <p>If the application does not register a DTD handler, all DTD + * events reported by the SAX parser will be silently ignored.</p> + * + * <p>Applications may register a new or different handler in the + * middle of a parse, and the SAX parser must begin using the new + * handler immediately.</p> + * + * @param handler The DTD handler. + * @see #getDTDHandler + */ + public void setDTDHandler (DTDHandler handler); + + + /** + * Return the current DTD handler. + * + * @return The current DTD handler, or null if none + * has been registered. + * @see #setDTDHandler + */ + public DTDHandler getDTDHandler (); + + + /** + * Allow an application to register a content event handler. + * + * <p>If the application does not register a content handler, all + * content events reported by the SAX parser will be silently + * ignored.</p> + * + * <p>Applications may register a new or different handler in the + * middle of a parse, and the SAX parser must begin using the new + * handler immediately.</p> + * + * @param handler The content handler. + * @see #getContentHandler + */ + public void setContentHandler (ContentHandler handler); + + + /** + * Return the current content handler. + * + * @return The current content handler, or null if none + * has been registered. + * @see #setContentHandler + */ + public ContentHandler getContentHandler (); + + + /** + * Allow an application to register an error event handler. + * + * <p>If the application does not register an error handler, all + * error events reported by the SAX parser will be silently + * ignored; however, normal processing may not continue. It is + * highly recommended that all SAX applications implement an + * error handler to avoid unexpected bugs.</p> + * + * <p>Applications may register a new or different handler in the + * middle of a parse, and the SAX parser must begin using the new + * handler immediately.</p> + * + * @param handler The error handler. + * @see #getErrorHandler + */ + public void setErrorHandler (ErrorHandler handler); + + + /** + * Return the current error handler. + * + * @return The current error handler, or null if none + * has been registered. + * @see #setErrorHandler + */ + public ErrorHandler getErrorHandler (); + + + + //////////////////////////////////////////////////////////////////// + // Parsing. + //////////////////////////////////////////////////////////////////// + + /** + * Parse an XML document. + * + * <p>The application can use this method to instruct the XML + * reader to begin parsing an XML document from any valid input + * source (a character stream, a byte stream, or a URI).</p> + * + * <p>Applications may not invoke this method while a parse is in + * progress (they should create a new XMLReader instead for each + * nested XML document). Once a parse is complete, an + * application may reuse the same XMLReader object, possibly with a + * different input source. + * Configuration of the XMLReader object (such as handler bindings and + * values established for feature flags and properties) is unchanged + * by completion of a parse, unless the definition of that aspect of + * the configuration explicitly specifies other behavior. + * (For example, feature flags or properties exposing + * characteristics of the document being parsed.) + * </p> + * + * <p>During the parse, the XMLReader will provide information + * about the XML document through the registered event + * handlers.</p> + * + * <p>This method is synchronous: it will not return until parsing + * has ended. If a client application wants to terminate + * parsing early, it should throw an exception.</p> + * + * @param input The input source for the top-level of the + * XML document. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + * @exception java.io.IOException An IO exception from the parser, + * possibly from a byte stream or character stream + * supplied by the application. + * @see org.xml.sax.InputSource + * @see #parse(java.lang.String) + * @see #setEntityResolver + * @see #setDTDHandler + * @see #setContentHandler + * @see #setErrorHandler + */ + public void parse (InputSource input) + throws IOException, SAXException; + + + /** + * Parse an XML document from a system identifier (URI). + * + * <p>This method is a shortcut for the common case of reading a + * document from a system identifier. It is the exact + * equivalent of the following:</p> + * + * <pre> + * parse(new InputSource(systemId)); + * </pre> + * + * <p>If the system identifier is a URL, it must be fully resolved + * by the application before it is passed to the parser.</p> + * + * @param systemId The system identifier (URI). + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + * @exception java.io.IOException An IO exception from the parser, + * possibly from a byte stream or character stream + * supplied by the application. + * @see #parse(org.xml.sax.InputSource) + */ + public void parse (String systemId) + throws IOException, SAXException; + +} diff --git a/libjava/classpath/external/sax/org/xml/sax/ext/Attributes2.java b/libjava/classpath/external/sax/org/xml/sax/ext/Attributes2.java new file mode 100644 index 000000000..a814d9de3 --- /dev/null +++ b/libjava/classpath/external/sax/org/xml/sax/ext/Attributes2.java @@ -0,0 +1,132 @@ +// Attributes2.java - extended Attributes +// http://www.saxproject.org +// Public Domain: no warranty. +// $Id: Attributes2.java,v 1.1 2004/12/23 22:38:42 mark Exp $ + +package org.xml.sax.ext; + +import org.xml.sax.Attributes; + + +/** + * SAX2 extension to augment the per-attribute information + * provided though {@link Attributes}. + * If an implementation supports this extension, the attributes + * provided in {@link org.xml.sax.ContentHandler#startElement + * ContentHandler.startElement() } will implement this interface, + * and the <em>http://xml.org/sax/features/use-attributes2</em> + * feature flag will have the value <em>true</em>. + * + * <blockquote> + * <em>This module, both source code and documentation, is in the + * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> + * </blockquote> + * + * <p> XMLReader implementations are not required to support this + * information, and it is not part of core-only SAX2 distributions.</p> + * + * <p>Note that if an attribute was defaulted (<em>!isSpecified()</em>) + * it will of necessity also have been declared (<em>isDeclared()</em>) + * in the DTD. + * Similarly if an attribute's type is anything except CDATA, then it + * must have been declared. + * </p> + * + * @since SAX 2.0 (extensions 1.1 alpha) + * @author David Brownell + * @version TBS + */ +public interface Attributes2 extends Attributes +{ + /** + * Returns false unless the attribute was declared in the DTD. + * This helps distinguish two kinds of attributes that SAX reports + * as CDATA: ones that were declared (and hence are usually valid), + * and those that were not (and which are never valid). + * + * @param index The attribute index (zero-based). + * @return true if the attribute was declared in the DTD, + * false otherwise. + * @exception java.lang.ArrayIndexOutOfBoundsException When the + * supplied index does not identify an attribute. + */ + public boolean isDeclared (int index); + + /** + * Returns false unless the attribute was declared in the DTD. + * This helps distinguish two kinds of attributes that SAX reports + * as CDATA: ones that were declared (and hence are usually valid), + * and those that were not (and which are never valid). + * + * @param qName The XML qualified (prefixed) name. + * @return true if the attribute was declared in the DTD, + * false otherwise. + * @exception java.lang.IllegalArgumentException When the + * supplied name does not identify an attribute. + */ + public boolean isDeclared (String qName); + + /** + * Returns false unless the attribute was declared in the DTD. + * This helps distinguish two kinds of attributes that SAX reports + * as CDATA: ones that were declared (and hence are usually valid), + * and those that were not (and which are never valid). + * + * <p>Remember that since DTDs do not "understand" namespaces, the + * namespace URI associated with an attribute may not have come from + * the DTD. The declaration will have applied to the attribute's + * <em>qName</em>. + * + * @param uri The Namespace URI, or the empty string if + * the name has no Namespace URI. + * @param localName The attribute's local name. + * @return true if the attribute was declared in the DTD, + * false otherwise. + * @exception java.lang.IllegalArgumentException When the + * supplied names do not identify an attribute. + */ + public boolean isDeclared (String uri, String localName); + + /** + * Returns true unless the attribute value was provided + * by DTD defaulting. + * + * @param index The attribute index (zero-based). + * @return true if the value was found in the XML text, + * false if the value was provided by DTD defaulting. + * @exception java.lang.ArrayIndexOutOfBoundsException When the + * supplied index does not identify an attribute. + */ + public boolean isSpecified (int index); + + /** + * Returns true unless the attribute value was provided + * by DTD defaulting. + * + * <p>Remember that since DTDs do not "understand" namespaces, the + * namespace URI associated with an attribute may not have come from + * the DTD. The declaration will have applied to the attribute's + * <em>qName</em>. + * + * @param uri The Namespace URI, or the empty string if + * the name has no Namespace URI. + * @param localName The attribute's local name. + * @return true if the value was found in the XML text, + * false if the value was provided by DTD defaulting. + * @exception java.lang.IllegalArgumentException When the + * supplied names do not identify an attribute. + */ + public boolean isSpecified (String uri, String localName); + + /** + * Returns true unless the attribute value was provided + * by DTD defaulting. + * + * @param qName The XML qualified (prefixed) name. + * @return true if the value was found in the XML text, + * false if the value was provided by DTD defaulting. + * @exception java.lang.IllegalArgumentException When the + * supplied name does not identify an attribute. + */ + public boolean isSpecified (String qName); +} diff --git a/libjava/classpath/external/sax/org/xml/sax/ext/Attributes2Impl.java b/libjava/classpath/external/sax/org/xml/sax/ext/Attributes2Impl.java new file mode 100644 index 000000000..082255933 --- /dev/null +++ b/libjava/classpath/external/sax/org/xml/sax/ext/Attributes2Impl.java @@ -0,0 +1,301 @@ +// Attributes2Impl.java - extended AttributesImpl +// http://www.saxproject.org +// Public Domain: no warranty. +// $Id: Attributes2Impl.java,v 1.1 2004/12/23 22:38:42 mark Exp $ + +package org.xml.sax.ext; + +import org.xml.sax.Attributes; +import org.xml.sax.helpers.AttributesImpl; + + +/** + * SAX2 extension helper for additional Attributes information, + * implementing the {@link Attributes2} interface. + * + * <blockquote> + * <em>This module, both source code and documentation, is in the + * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> + * </blockquote> + * + * <p>This is not part of core-only SAX2 distributions.</p> + * + * <p>The <em>specified</em> flag for each attribute will always + * be true, unless it has been set to false in the copy constructor + * or using {@link #setSpecified}. + * Similarly, the <em>declared</em> flag for each attribute will + * always be false, except for defaulted attributes (<em>specified</em> + * is false), non-CDATA attributes, or when it is set to true using + * {@link #setDeclared}. + * If you change an attribute's type by hand, you may need to modify + * its <em>declared</em> flag to match. + * </p> + * + * @since SAX 2.0 (extensions 1.1 alpha) + * @author David Brownell + * @version TBS + */ +public class Attributes2Impl extends AttributesImpl implements Attributes2 +{ + private boolean declared []; + private boolean specified []; + + + /** + * Construct a new, empty Attributes2Impl object. + */ + public Attributes2Impl () { } + + + /** + * Copy an existing Attributes or Attributes2 object. + * If the object implements Attributes2, values of the + * <em>specified</em> and <em>declared</em> flags for each + * attribute are copied. + * Otherwise the flag values are defaulted to assume no DTD was used, + * unless there is evidence to the contrary (such as attributes with + * type other than CDATA, which must have been <em>declared</em>). + * + * <p>This constructor is especially useful inside a + * {@link org.xml.sax.ContentHandler#startElement startElement} event.</p> + * + * @param atts The existing Attributes object. + */ + public Attributes2Impl (Attributes atts) + { + super (atts); + } + + + //////////////////////////////////////////////////////////////////// + // Implementation of Attributes2 + //////////////////////////////////////////////////////////////////// + + + /** + * Returns the current value of the attribute's "declared" flag. + */ + // javadoc mostly from interface + public boolean isDeclared (int index) + { + if (index < 0 || index >= getLength ()) + throw new ArrayIndexOutOfBoundsException ( + "No attribute at index: " + index); + return declared [index]; + } + + + /** + * Returns the current value of the attribute's "declared" flag. + */ + // javadoc mostly from interface + public boolean isDeclared (String uri, String localName) + { + int index = getIndex (uri, localName); + + if (index < 0) + throw new IllegalArgumentException ( + "No such attribute: local=" + localName + + ", namespace=" + uri); + return declared [index]; + } + + + /** + * Returns the current value of the attribute's "declared" flag. + */ + // javadoc mostly from interface + public boolean isDeclared (String qName) + { + int index = getIndex (qName); + + if (index < 0) + throw new IllegalArgumentException ( + "No such attribute: " + qName); + return declared [index]; + } + + + /** + * Returns the current value of an attribute's "specified" flag. + * + * @param index The attribute index (zero-based). + * @return current flag value + * @exception java.lang.ArrayIndexOutOfBoundsException When the + * supplied index does not identify an attribute. + */ + public boolean isSpecified (int index) + { + if (index < 0 || index >= getLength ()) + throw new ArrayIndexOutOfBoundsException ( + "No attribute at index: " + index); + return specified [index]; + } + + + /** + * Returns the current value of an attribute's "specified" flag. + * + * @param uri The Namespace URI, or the empty string if + * the name has no Namespace URI. + * @param localName The attribute's local name. + * @return current flag value + * @exception java.lang.IllegalArgumentException When the + * supplied names do not identify an attribute. + */ + public boolean isSpecified (String uri, String localName) + { + int index = getIndex (uri, localName); + + if (index < 0) + throw new IllegalArgumentException ( + "No such attribute: local=" + localName + + ", namespace=" + uri); + return specified [index]; + } + + + /** + * Returns the current value of an attribute's "specified" flag. + * + * @param qName The XML qualified (prefixed) name. + * @return current flag value + * @exception java.lang.IllegalArgumentException When the + * supplied name does not identify an attribute. + */ + public boolean isSpecified (String qName) + { + int index = getIndex (qName); + + if (index < 0) + throw new IllegalArgumentException ( + "No such attribute: " + qName); + return specified [index]; + } + + + //////////////////////////////////////////////////////////////////// + // Manipulators + //////////////////////////////////////////////////////////////////// + + + /** + * Copy an entire Attributes object. The "specified" flags are + * assigned as true, and "declared" flags as false (except when + * an attribute's type is not CDATA), + * unless the object is an Attributes2 object. + * In that case those flag values are all copied. + * + * @see AttributesImpl#setAttributes + */ + public void setAttributes (Attributes atts) + { + int length = atts.getLength (); + + super.setAttributes (atts); + declared = new boolean [length]; + specified = new boolean [length]; + + if (atts instanceof Attributes2) { + Attributes2 a2 = (Attributes2) atts; + for (int i = 0; i < length; i++) { + declared [i] = a2.isDeclared (i); + specified [i] = a2.isSpecified (i); + } + } else { + for (int i = 0; i < length; i++) { + declared [i] = !"CDATA".equals (atts.getType (i)); + specified [i] = true; + } + } + } + + + /** + * Add an attribute to the end of the list, setting its + * "specified" flag to true. To set that flag's value + * to false, use {@link #setSpecified}. + * + * <p>Unless the attribute <em>type</em> is CDATA, this attribute + * is marked as being declared in the DTD. To set that flag's value + * to true for CDATA attributes, use {@link #setDeclared}. + * + * @see AttributesImpl#addAttribute + */ + public void addAttribute (String uri, String localName, String qName, + String type, String value) + { + super.addAttribute (uri, localName, qName, type, value); + + int length = getLength (); + + if (length < specified.length) { + boolean newFlags []; + + newFlags = new boolean [length]; + System.arraycopy (declared, 0, newFlags, 0, declared.length); + declared = newFlags; + + newFlags = new boolean [length]; + System.arraycopy (specified, 0, newFlags, 0, specified.length); + specified = newFlags; + } + + specified [length - 1] = true; + declared [length - 1] = !"CDATA".equals (type); + } + + + // javadoc entirely from superclass + public void removeAttribute (int index) + { + int origMax = getLength () - 1; + + super.removeAttribute (index); + if (index != origMax) { + System.arraycopy (declared, index + 1, declared, index, + origMax - index); + System.arraycopy (specified, index + 1, specified, index, + origMax - index); + } + } + + + /** + * Assign a value to the "declared" flag of a specific attribute. + * This is normally needed only for attributes of type CDATA, + * including attributes whose type is changed to or from CDATA. + * + * @param index The index of the attribute (zero-based). + * @param value The desired flag value. + * @exception java.lang.ArrayIndexOutOfBoundsException When the + * supplied index does not identify an attribute. + * @see #setType + */ + public void setDeclared (int index, boolean value) + { + if (index < 0 || index >= getLength ()) + throw new ArrayIndexOutOfBoundsException ( + "No attribute at index: " + index); + declared [index] = value; + } + + + /** + * Assign a value to the "specified" flag of a specific attribute. + * This is the only way this flag can be cleared, except clearing + * by initialization with the copy constructor. + * + * @param index The index of the attribute (zero-based). + * @param value The desired flag value. + * @exception java.lang.ArrayIndexOutOfBoundsException When the + * supplied index does not identify an attribute. + */ + public void setSpecified (int index, boolean value) + { + if (index < 0 || index >= getLength ()) + throw new ArrayIndexOutOfBoundsException ( + "No attribute at index: " + index); + specified [index] = value; + } +} diff --git a/libjava/classpath/external/sax/org/xml/sax/ext/DeclHandler.java b/libjava/classpath/external/sax/org/xml/sax/ext/DeclHandler.java new file mode 100644 index 000000000..42d92269f --- /dev/null +++ b/libjava/classpath/external/sax/org/xml/sax/ext/DeclHandler.java @@ -0,0 +1,146 @@ +// DeclHandler.java - Optional handler for DTD declaration events. +// http://www.saxproject.org +// Public Domain: no warranty. +// $Id: DeclHandler.java,v 1.1 2004/12/23 22:38:42 mark Exp $ + +package org.xml.sax.ext; + +import org.xml.sax.SAXException; + + +/** + * SAX2 extension handler for DTD declaration events. + * + * <blockquote> + * <em>This module, both source code and documentation, is in the + * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> + * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a> + * for further information. + * </blockquote> + * + * <p>This is an optional extension handler for SAX2 to provide more + * complete information about DTD declarations in an XML document. + * XML readers are not required to recognize this handler, and it + * is not part of core-only SAX2 distributions.</p> + * + * <p>Note that data-related DTD declarations (unparsed entities and + * notations) are already reported through the {@link + * org.xml.sax.DTDHandler DTDHandler} interface.</p> + * + * <p>If you are using the declaration handler together with a lexical + * handler, all of the events will occur between the + * {@link org.xml.sax.ext.LexicalHandler#startDTD startDTD} and the + * {@link org.xml.sax.ext.LexicalHandler#endDTD endDTD} events.</p> + * + * <p>To set the DeclHandler for an XML reader, use the + * {@link org.xml.sax.XMLReader#setProperty setProperty} method + * with the property name + * <code>http://xml.org/sax/properties/declaration-handler</code> + * and an object implementing this interface (or null) as the value. + * If the reader does not report declaration events, it will throw a + * {@link org.xml.sax.SAXNotRecognizedException SAXNotRecognizedException} + * when you attempt to register the handler.</p> + * + * @since SAX 2.0 (extensions 1.0) + * @author David Megginson + * @version 2.0.1 (sax2r2) + */ +public interface DeclHandler +{ + + /** + * Report an element type declaration. + * + * <p>The content model will consist of the string "EMPTY", the + * string "ANY", or a parenthesised group, optionally followed + * by an occurrence indicator. The model will be normalized so + * that all parameter entities are fully resolved and all whitespace + * is removed,and will include the enclosing parentheses. Other + * normalization (such as removing redundant parentheses or + * simplifying occurrence indicators) is at the discretion of the + * parser.</p> + * + * @param name The element type name. + * @param model The content model as a normalized string. + * @exception SAXException The application may raise an exception. + */ + public abstract void elementDecl (String name, String model) + throws SAXException; + + + /** + * Report an attribute type declaration. + * + * <p>Only the effective (first) declaration for an attribute will + * be reported. The type will be one of the strings "CDATA", + * "ID", "IDREF", "IDREFS", "NMTOKEN", "NMTOKENS", "ENTITY", + * "ENTITIES", a parenthesized token group with + * the separator "|" and all whitespace removed, or the word + * "NOTATION" followed by a space followed by a parenthesized + * token group with all whitespace removed.</p> + * + * <p>The value will be the value as reported to applications, + * appropriately normalized and with entity and character + * references expanded. </p> + * + * @param eName The name of the associated element. + * @param aName The name of the attribute. + * @param type A string representing the attribute type. + * @param mode A string representing the attribute defaulting mode + * ("#IMPLIED", "#REQUIRED", or "#FIXED") or null if + * none of these applies. + * @param value A string representing the attribute's default value, + * or null if there is none. + * @exception SAXException The application may raise an exception. + */ + public abstract void attributeDecl (String eName, + String aName, + String type, + String mode, + String value) + throws SAXException; + + + /** + * Report an internal entity declaration. + * + * <p>Only the effective (first) declaration for each entity + * will be reported. All parameter entities in the value + * will be expanded, but general entities will not.</p> + * + * @param name The name of the entity. If it is a parameter + * entity, the name will begin with '%'. + * @param value The replacement text of the entity. + * @exception SAXException The application may raise an exception. + * @see #externalEntityDecl + * @see org.xml.sax.DTDHandler#unparsedEntityDecl + */ + public abstract void internalEntityDecl (String name, String value) + throws SAXException; + + + /** + * Report a parsed external entity declaration. + * + * <p>Only the effective (first) declaration for each entity + * will be reported.</p> + * + * <p>If the system identifier is a URL, the parser must resolve it + * fully before passing it to the application.</p> + * + * @param name The name of the entity. If it is a parameter + * entity, the name will begin with '%'. + * @param publicId The entity's public identifier, or null if none + * was given. + * @param systemId The entity's system identifier. + * @exception SAXException The application may raise an exception. + * @see #internalEntityDecl + * @see org.xml.sax.DTDHandler#unparsedEntityDecl + */ + public abstract void externalEntityDecl (String name, String publicId, + String systemId) + throws SAXException; + +} + +// end of DeclHandler.java diff --git a/libjava/classpath/external/sax/org/xml/sax/ext/DefaultHandler2.java b/libjava/classpath/external/sax/org/xml/sax/ext/DefaultHandler2.java new file mode 100644 index 000000000..bf47ea889 --- /dev/null +++ b/libjava/classpath/external/sax/org/xml/sax/ext/DefaultHandler2.java @@ -0,0 +1,130 @@ +// DefaultHandler2.java - extended DefaultHandler +// http://www.saxproject.org +// Public Domain: no warranty. +// $Id: DefaultHandler2.java,v 1.1 2004/12/23 22:38:42 mark Exp $ + +package org.xml.sax.ext; + +import java.io.IOException; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + + +/** + * This class extends the SAX2 base handler class to support the + * SAX2 {@link LexicalHandler}, {@link DeclHandler}, and + * {@link EntityResolver2} extensions. Except for overriding the + * original SAX1 {@link DefaultHandler#resolveEntity resolveEntity()} + * method the added handler methods just return. Subclassers may + * override everything on a method-by-method basis. + * + * <blockquote> + * <em>This module, both source code and documentation, is in the + * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> + * </blockquote> + * + * <p> <em>Note:</em> this class might yet learn that the + * <em>ContentHandler.setDocumentLocator()</em> call might be passed a + * {@link Locator2} object, and that the + * <em>ContentHandler.startElement()</em> call might be passed a + * {@link Attributes2} object. + * + * @since SAX 2.0 (extensions 1.1 alpha) + * @author David Brownell + * @version TBS + */ +public class DefaultHandler2 extends DefaultHandler + implements LexicalHandler, DeclHandler, EntityResolver2 +{ + /** Constructs a handler which ignores all parsing events. */ + public DefaultHandler2 () { } + + + // SAX2 ext-1.0 LexicalHandler + + public void startCDATA () + throws SAXException + {} + + public void endCDATA () + throws SAXException + {} + + public void startDTD (String name, String publicId, String systemId) + throws SAXException + {} + + public void endDTD () + throws SAXException + {} + + public void startEntity (String name) + throws SAXException + {} + + public void endEntity (String name) + throws SAXException + {} + + public void comment (char ch [], int start, int length) + throws SAXException + { } + + + // SAX2 ext-1.0 DeclHandler + + public void attributeDecl (String eName, String aName, + String type, String mode, String value) + throws SAXException + {} + + public void elementDecl (String name, String model) + throws SAXException + {} + + public void externalEntityDecl (String name, + String publicId, String systemId) + throws SAXException + {} + + public void internalEntityDecl (String name, String value) + throws SAXException + {} + + // SAX2 ext-1.1 EntityResolver2 + + /** + * Tells the parser that if no external subset has been declared + * in the document text, none should be used. + */ + public InputSource getExternalSubset (String name, String baseURI) + throws SAXException, IOException + { return null; } + + /** + * Tells the parser to resolve the systemId against the baseURI + * and read the entity text from that resulting absolute URI. + * Note that because the older + * {@link DefaultHandler#resolveEntity DefaultHandler.resolveEntity()}, + * method is overridden to call this one, this method may sometimes + * be invoked with null <em>name</em> and <em>baseURI</em>, and + * with the <em>systemId</em> already absolutized. + */ + public InputSource resolveEntity (String name, String publicId, + String baseURI, String systemId) + throws SAXException, IOException + { return null; } + + // SAX1 EntityResolver + + /** + * Invokes + * {@link EntityResolver2#resolveEntity EntityResolver2.resolveEntity()} + * with null entity name and base URI. + * You only need to override that method to use this class. + */ + public InputSource resolveEntity (String publicId, String systemId) + throws SAXException, IOException + { return resolveEntity (null, publicId, null, systemId); } +} diff --git a/libjava/classpath/external/sax/org/xml/sax/ext/EntityResolver2.java b/libjava/classpath/external/sax/org/xml/sax/ext/EntityResolver2.java new file mode 100644 index 000000000..96dcf6779 --- /dev/null +++ b/libjava/classpath/external/sax/org/xml/sax/ext/EntityResolver2.java @@ -0,0 +1,197 @@ +// EntityResolver2.java - Extended SAX entity resolver. +// http://www.saxproject.org +// No warranty; no copyright -- use this as you will. +// $Id: EntityResolver2.java,v 1.2 2006/12/10 20:25:41 gnu_andrew Exp $ + +package org.xml.sax.ext; + +import java.io.IOException; + +import org.xml.sax.EntityResolver; +import org.xml.sax.InputSource; +import org.xml.sax.XMLReader; +import org.xml.sax.SAXException; + + +/** + * Extended interface for mapping external entity references to input + * sources, or providing a missing external subset. The + * {@link XMLReader#setEntityResolver XMLReader.setEntityResolver()} method + * is used to provide implementations of this interface to parsers. + * When a parser uses the methods in this interface, the + * {@link EntityResolver2#resolveEntity EntityResolver2.resolveEntity()} + * method (in this interface) is used <em>instead of</em> the older (SAX 1.0) + * {@link EntityResolver#resolveEntity EntityResolver.resolveEntity()} method. + * + * <blockquote> + * <em>This module, both source code and documentation, is in the + * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> + * </blockquote> + * + * <p>If a SAX application requires the customized handling which this + * interface defines for external entities, it must ensure that it uses + * an XMLReader with the + * <em>http://xml.org/sax/features/use-entity-resolver2</em> feature flag + * set to <em>true</em> (which is its default value when the feature is + * recognized). If that flag is unrecognized, or its value is false, + * or the resolver does not implement this interface, then only the + * {@link EntityResolver} method will be used. + * </p> + * + * <p>That supports three categories of application that modify entity + * resolution. <em>Old Style</em> applications won't know about this interface; + * they will provide an EntityResolver. + * <em>Transitional Mode</em> provide an EntityResolver2 and automatically + * get the benefit of its methods in any systems (parsers or other tools) + * supporting it, due to polymorphism. + * Both <em>Old Style</em> and <em>Transitional Mode</em> applications will + * work with any SAX2 parser. + * <em>New style</em> applications will fail to run except on SAX2 parsers + * that support this particular feature. + * They will insist that feature flag have a value of "true", and the + * EntityResolver2 implementation they provide might throw an exception + * if the original SAX 1.0 style entity resolution method is invoked. + * </p> + * + * @see org.xml.sax.XMLReader#setEntityResolver + * + * @since SAX 2.0 (extensions 1.1 alpha) + * @author David Brownell + * @version TBD + */ +public interface EntityResolver2 extends EntityResolver +{ + /** + * Allows applications to provide an external subset for documents + * that don't explicitly define one. Documents with DOCTYPE declarations + * that omit an external subset can thus augment the declarations + * available for validation, entity processing, and attribute processing + * (normalization, defaulting, and reporting types including ID). + * This augmentation is reported + * through the {@link LexicalHandler#startDTD startDTD()} method as if + * the document text had originally included the external subset; + * this callback is made before any internal subset data or errors + * are reported.</p> + * + * <p>This method can also be used with documents that have no DOCTYPE + * declaration. When the root element is encountered, + * but no DOCTYPE declaration has been seen, this method is + * invoked. If it returns a value for the external subset, that root + * element is declared to be the root element, giving the effect of + * splicing a DOCTYPE declaration at the end the prolog of a document + * that could not otherwise be valid. The sequence of parser callbacks + * in that case logically resembles this:</p> + * + * <pre> + * ... comments and PIs from the prolog (as usual) + * startDTD ("rootName", source.getPublicId (), source.getSystemId ()); + * startEntity ("[dtd]"); + * ... declarations, comments, and PIs from the external subset + * endEntity ("[dtd]"); + * endDTD (); + * ... then the rest of the document (as usual) + * startElement (..., "rootName", ...); + * </pre> + * + * <p>Note that the InputSource gets no further resolution. + * Implementations of this method may wish to invoke + * {@link #resolveEntity resolveEntity()} to gain benefits such as use + * of local caches of DTD entities. Also, this method will never be + * used by a (non-validating) processor that is not including external + * parameter entities. </p> + * + * <p>Uses for this method include facilitating data validation when + * interoperating with XML processors that would always require + * undesirable network accesses for external entities, or which for + * other reasons adopt a "no DTDs" policy. + * Non-validation motives include forcing documents to include DTDs so + * that attributes are handled consistently. + * For example, an XPath processor needs to know which attibutes have + * type "ID" before it can process a widely used type of reference.</p> + * + * <p><strong>Warning:</strong> Returning an external subset modifies + * the input document. By providing definitions for general entities, + * it can make a malformed document appear to be well formed. + * </p> + * + * @param name Identifies the document root element. This name comes + * from a DOCTYPE declaration (where available) or from the actual + * root element. + * @param baseURI The document's base URI, serving as an additional + * hint for selecting the external subset. This is always an absolute + * URI, unless it is null because the XMLReader was given an InputSource + * without one. + * + * @return An InputSource object describing the new external subset + * to be used by the parser, or null to indicate that no external + * subset is provided. + * + * @exception SAXException Any SAX exception, possibly wrapping + * another exception. + * @exception IOException Probably indicating a failure to create + * a new InputStream or Reader, or an illegal URL. + */ + public InputSource getExternalSubset (String name, String baseURI) + throws SAXException, IOException; + + /** + * Allows applications to map references to external entities into input + * sources, or tell the parser it should use conventional URI resolution. + * This method is only called for external entities which have been + * properly declared. + * This method provides more flexibility than the {@link EntityResolver} + * interface, supporting implementations of more complex catalogue + * schemes such as the one defined by the <a href= + "http://www.oasis-open.org/committees/entity/spec-2001-08-06.html" + >OASIS XML Catalogs</a> specification.</p> + * + * <p>Parsers configured to use this resolver method will call it + * to determine the input source to use for any external entity + * being included because of a reference in the XML text. + * That excludes the document entity, and any external entity returned + * by {@link #getExternalSubset getExternalSubset()}. + * When a (non-validating) processor is configured not to include + * a class of entities (parameter or general) through use of feature + * flags, this method is not invoked for such entities. </p> + * + * <p>Note that the entity naming scheme used here is the same one + * used in the {@link LexicalHandler}, or in the {@link + org.xml.sax.ContentHandler#skippedEntity + ContentHandler.skippedEntity()} + * method. </p> + * + * @param name Identifies the external entity being resolved. + * Either "[dtd]" for the external subset, or a name starting + * with "%" to indicate a parameter entity, or else the name of + * a general entity. This is never null when invoked by a SAX2 + * parser. + * @param publicId The public identifier of the external entity being + * referenced (normalized as required by the XML specification), or + * null if none was supplied. + * @param baseURI The URI with respect to which relative systemIDs + * are interpreted. This is always an absolute URI, unless it is + * null (likely because the XMLReader was given an InputSource without + * one). This URI is defined by the XML specification to be the one + * associated with the "<" starting the relevant declaration. + * @param systemId The system identifier of the external entity + * being referenced; either a relative or absolute URI. + * This is never null when invoked by a SAX2 parser; only declared + * entities, and any external subset, are resolved by such parsers. + * + * @return An InputSource object describing the new input source to + * be used by the parser. Returning null directs the parser to + * resolve the system ID against the base URI and open a connection + * to resulting URI. + * + * @exception SAXException Any SAX exception, possibly wrapping + * another exception. + * @exception IOException Probably indicating a failure to create + * a new InputStream or Reader, or an illegal URL. + */ + public InputSource resolveEntity ( + String name, + String publicId, + String baseURI, + String systemId + ) throws SAXException, IOException; +} diff --git a/libjava/classpath/external/sax/org/xml/sax/ext/LexicalHandler.java b/libjava/classpath/external/sax/org/xml/sax/ext/LexicalHandler.java new file mode 100644 index 000000000..376d1c8d0 --- /dev/null +++ b/libjava/classpath/external/sax/org/xml/sax/ext/LexicalHandler.java @@ -0,0 +1,212 @@ +// LexicalHandler.java - optional handler for lexical parse events. +// http://www.saxproject.org +// Public Domain: no warranty. +// $Id: LexicalHandler.java,v 1.1 2004/12/23 22:38:42 mark Exp $ + +package org.xml.sax.ext; + +import org.xml.sax.SAXException; + +/** + * SAX2 extension handler for lexical events. + * + * <blockquote> + * <em>This module, both source code and documentation, is in the + * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> + * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a> + * for further information. + * </blockquote> + * + * <p>This is an optional extension handler for SAX2 to provide + * lexical information about an XML document, such as comments + * and CDATA section boundaries. + * XML readers are not required to recognize this handler, and it + * is not part of core-only SAX2 distributions.</p> + * + * <p>The events in the lexical handler apply to the entire document, + * not just to the document element, and all lexical handler events + * must appear between the content handler's startDocument and + * endDocument events.</p> + * + * <p>To set the LexicalHandler for an XML reader, use the + * {@link org.xml.sax.XMLReader#setProperty setProperty} method + * with the property name + * <code>http://xml.org/sax/properties/lexical-handler</code> + * and an object implementing this interface (or null) as the value. + * If the reader does not report lexical events, it will throw a + * {@link org.xml.sax.SAXNotRecognizedException SAXNotRecognizedException} + * when you attempt to register the handler.</p> + * + * @since SAX 2.0 (extensions 1.0) + * @author David Megginson + * @version 2.0.1 (sax2r2) + */ +public interface LexicalHandler +{ + + /** + * Report the start of DTD declarations, if any. + * + * <p>This method is intended to report the beginning of the + * DOCTYPE declaration; if the document has no DOCTYPE declaration, + * this method will not be invoked.</p> + * + * <p>All declarations reported through + * {@link org.xml.sax.DTDHandler DTDHandler} or + * {@link org.xml.sax.ext.DeclHandler DeclHandler} events must appear + * between the startDTD and {@link #endDTD endDTD} events. + * Declarations are assumed to belong to the internal DTD subset + * unless they appear between {@link #startEntity startEntity} + * and {@link #endEntity endEntity} events. Comments and + * processing instructions from the DTD should also be reported + * between the startDTD and endDTD events, in their original + * order of (logical) occurrence; they are not required to + * appear in their correct locations relative to DTDHandler + * or DeclHandler events, however.</p> + * + * <p>Note that the start/endDTD events will appear within + * the start/endDocument events from ContentHandler and + * before the first + * {@link org.xml.sax.ContentHandler#startElement startElement} + * event.</p> + * + * @param name The document type name. + * @param publicId The declared public identifier for the + * external DTD subset, or null if none was declared. + * @param systemId The declared system identifier for the + * external DTD subset, or null if none was declared. + * (Note that this is not resolved against the document + * base URI.) + * @exception SAXException The application may raise an + * exception. + * @see #endDTD + * @see #startEntity + */ + public abstract void startDTD (String name, String publicId, + String systemId) + throws SAXException; + + + /** + * Report the end of DTD declarations. + * + * <p>This method is intended to report the end of the + * DOCTYPE declaration; if the document has no DOCTYPE declaration, + * this method will not be invoked.</p> + * + * @exception SAXException The application may raise an exception. + * @see #startDTD + */ + public abstract void endDTD () + throws SAXException; + + + /** + * Report the beginning of some internal and external XML entities. + * + * <p>The reporting of parameter entities (including + * the external DTD subset) is optional, and SAX2 drivers that + * report LexicalHandler events may not implement it; you can use the + * <code + * >http://xml.org/sax/features/lexical-handler/parameter-entities</code> + * feature to query or control the reporting of parameter entities.</p> + * + * <p>General entities are reported with their regular names, + * parameter entities have '%' prepended to their names, and + * the external DTD subset has the pseudo-entity name "[dtd]".</p> + * + * <p>When a SAX2 driver is providing these events, all other + * events must be properly nested within start/end entity + * events. There is no additional requirement that events from + * {@link org.xml.sax.ext.DeclHandler DeclHandler} or + * {@link org.xml.sax.DTDHandler DTDHandler} be properly ordered.</p> + * + * <p>Note that skipped entities will be reported through the + * {@link org.xml.sax.ContentHandler#skippedEntity skippedEntity} + * event, which is part of the ContentHandler interface.</p> + * + * <p>Because of the streaming event model that SAX uses, some + * entity boundaries cannot be reported under any + * circumstances:</p> + * + * <ul> + * <li>general entities within attribute values</li> + * <li>parameter entities within declarations</li> + * </ul> + * + * <p>These will be silently expanded, with no indication of where + * the original entity boundaries were.</p> + * + * <p>Note also that the boundaries of character references (which + * are not really entities anyway) are not reported.</p> + * + * <p>All start/endEntity events must be properly nested. + * + * @param name The name of the entity. If it is a parameter + * entity, the name will begin with '%', and if it is the + * external DTD subset, it will be "[dtd]". + * @exception SAXException The application may raise an exception. + * @see #endEntity + * @see org.xml.sax.ext.DeclHandler#internalEntityDecl + * @see org.xml.sax.ext.DeclHandler#externalEntityDecl + */ + public abstract void startEntity (String name) + throws SAXException; + + + /** + * Report the end of an entity. + * + * @param name The name of the entity that is ending. + * @exception SAXException The application may raise an exception. + * @see #startEntity + */ + public abstract void endEntity (String name) + throws SAXException; + + + /** + * Report the start of a CDATA section. + * + * <p>The contents of the CDATA section will be reported through + * the regular {@link org.xml.sax.ContentHandler#characters + * characters} event; this event is intended only to report + * the boundary.</p> + * + * @exception SAXException The application may raise an exception. + * @see #endCDATA + */ + public abstract void startCDATA () + throws SAXException; + + + /** + * Report the end of a CDATA section. + * + * @exception SAXException The application may raise an exception. + * @see #startCDATA + */ + public abstract void endCDATA () + throws SAXException; + + + /** + * Report an XML comment anywhere in the document. + * + * <p>This callback will be used for comments inside or outside the + * document element, including comments in the external DTD + * subset (if read). Comments in the DTD must be properly + * nested inside start/endDTD and start/endEntity events (if + * used).</p> + * + * @param ch An array holding the characters in the comment. + * @param start The starting position in the array. + * @param length The number of characters to use from the array. + * @exception SAXException The application may raise an exception. + */ + public abstract void comment (char ch[], int start, int length) + throws SAXException; + +} + +// end of LexicalHandler.java diff --git a/libjava/classpath/external/sax/org/xml/sax/ext/Locator2.java b/libjava/classpath/external/sax/org/xml/sax/ext/Locator2.java new file mode 100644 index 000000000..b186d3a28 --- /dev/null +++ b/libjava/classpath/external/sax/org/xml/sax/ext/Locator2.java @@ -0,0 +1,75 @@ +// Locator2.java - extended Locator +// http://www.saxproject.org +// Public Domain: no warranty. +// $Id: Locator2.java,v 1.1 2004/12/23 22:38:42 mark Exp $ + +package org.xml.sax.ext; + +import org.xml.sax.Locator; + + +/** + * SAX2 extension to augment the entity information provided + * though a {@link Locator}. + * If an implementation supports this extension, the Locator + * provided in {@link org.xml.sax.ContentHandler#setDocumentLocator + * ContentHandler.setDocumentLocator() } will implement this + * interface, and the + * <em>http://xml.org/sax/features/use-locator2</em> feature + * flag will have the value <em>true</em>. + * + * <blockquote> + * <em>This module, both source code and documentation, is in the + * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> + * </blockquote> + * + * <p> XMLReader implementations are not required to support this + * information, and it is not part of core-only SAX2 distributions.</p> + * + * @since SAX 2.0 (extensions 1.1 alpha) + * @author David Brownell + * @version TBS + */ +public interface Locator2 extends Locator +{ + /** + * Returns the version of XML used for the entity. This will + * normally be the identifier from the current entity's + * <em><?xml version='...' ...?></em> declaration, + * or be defaulted by the parser. + * + * @return Identifier for the XML version being used to interpret + * the entity's text, or null if that information is not yet + * available in the current parsing state. + */ + public String getXMLVersion (); + + /** + * Returns the name of the character encoding for the entity. + * If the encoding was declared externally (for example, in a MIME + * Content-Type header), that will be the name returned. Else if there + * was an <em><?xml ...encoding='...'?></em> declaration at + * the start of the document, that encoding name will be returned. + * Otherwise the encoding will been inferred (normally to be UTF-8, or + * some UTF-16 variant), and that inferred name will be returned. + * + * <p>When an {@link org.xml.sax.InputSource InputSource} is used + * to provide an entity's character stream, this method returns the + * encoding provided in that input stream. + * + * <p> Note that some recent W3C specifications require that text + * in some encodings be normalized, using Unicode Normalization + * Form C, before processing. Such normalization must be performed + * by applications, and would normally be triggered based on the + * value returned by this method. + * + * <p> Encoding names may be those used by the underlying JVM, + * and comparisons should be case-insensitive. + * + * @return Name of the character encoding being used to interpret + * * the entity's text, or null if this was not provided for a * + * character stream passed through an InputSource or is otherwise + * not yet available in the current parsing state. + */ + public String getEncoding (); +} diff --git a/libjava/classpath/external/sax/org/xml/sax/ext/Locator2Impl.java b/libjava/classpath/external/sax/org/xml/sax/ext/Locator2Impl.java new file mode 100644 index 000000000..d3c751114 --- /dev/null +++ b/libjava/classpath/external/sax/org/xml/sax/ext/Locator2Impl.java @@ -0,0 +1,101 @@ +// Locator2Impl.java - extended LocatorImpl +// http://www.saxproject.org +// Public Domain: no warranty. +// $Id: Locator2Impl.java,v 1.2 2006/12/10 20:25:41 gnu_andrew Exp $ + +package org.xml.sax.ext; + +import org.xml.sax.Locator; +import org.xml.sax.helpers.LocatorImpl; + + +/** + * SAX2 extension helper for holding additional Entity information, + * implementing the {@link Locator2} interface. + * + * <blockquote> + * <em>This module, both source code and documentation, is in the + * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> + * </blockquote> + * + * <p> This is not part of core-only SAX2 distributions.</p> + * + * @since SAX 2.0.2 + * @author David Brownell + * @version TBS + */ +public class Locator2Impl extends LocatorImpl implements Locator2 +{ + private String encoding; + private String version; + + + /** + * Construct a new, empty Locator2Impl object. + * This will not normally be useful, since the main purpose + * of this class is to make a snapshot of an existing Locator. + */ + public Locator2Impl () { } + + /** + * Copy an existing Locator or Locator2 object. + * If the object implements Locator2, values of the + * <em>encoding</em> and <em>version</em>strings are copied, + * otherwise they set to <em>null</em>. + * + * @param locator The existing Locator object. + */ + public Locator2Impl (Locator locator) + { + super (locator); + if (locator instanceof Locator2) { + Locator2 l2 = (Locator2) locator; + + version = l2.getXMLVersion (); + encoding = l2.getEncoding (); + } + } + + //////////////////////////////////////////////////////////////////// + // Locator2 method implementations + //////////////////////////////////////////////////////////////////// + + /** + * Returns the current value of the version property. + * + * @see #setXMLVersion + */ + public String getXMLVersion () + { return version; } + + /** + * Returns the current value of the encoding property. + * + * @see #setEncoding + */ + public String getEncoding () + { return encoding; } + + + //////////////////////////////////////////////////////////////////// + // Setters + //////////////////////////////////////////////////////////////////// + + /** + * Assigns the current value of the version property. + * + * @param version the new "version" value + * @see #getXMLVersion + */ + public void setXMLVersion (String version) + { this.version = version; } + + /** + * Assigns the current value of the encoding property. + * + * @param encoding the new "encoding" value + * @see #getEncoding + */ + public void setEncoding (String encoding) + { this.encoding = encoding; } +} diff --git a/libjava/classpath/external/sax/org/xml/sax/ext/package.html b/libjava/classpath/external/sax/org/xml/sax/ext/package.html new file mode 100644 index 000000000..0b7448001 --- /dev/null +++ b/libjava/classpath/external/sax/org/xml/sax/ext/package.html @@ -0,0 +1,46 @@ +<HTML><HEAD> +<!-- $Id: package.html,v 1.1 2004/12/23 22:38:42 mark Exp $ --> +</HEAD><BODY> + +<p> +This package contains interfaces to SAX2 facilities that +conformant SAX drivers won't necessarily support. + +<p>See <a href='http://www.saxproject.org'>http://www.saxproject.org</a> +for more information about SAX.</p> + +<p> This package is independent of the SAX2 core, though the functionality +exposed generally needs to be implemented within a parser core. +That independence has several consequences:</p> + +<ul> + +<li>SAX2 drivers are <em>not</em> required to recognize these handlers. +</li> + +<li>You cannot assume that the class files will be present in every SAX2 +installation.</li> + +<li>This package may be updated independently of SAX2 (i.e. new +handlers and classes may be added without updating SAX2 itself).</li> + +<li>The new handlers are not implemented by the SAX2 +<code>org.xml.sax.helpers.DefaultHandler</code> or +<code>org.xml.sax.helpers.XMLFilterImpl</code> classes. +You can subclass these if you need such behavior, or +use the helper classes found here.</li> + +<li>The handlers need to be registered differently than core SAX2 +handlers.</li> + +</ul> + +<p>This package, SAX2-ext, is a standardized extension to SAX2. It is +designed both to allow SAX parsers to pass certain types of information +to applications, and to serve as a simple model for other SAX2 parser +extension packages. Not all such extension packages should need to +be recognized directly by parsers, however. +As an example, most validation systems can be cleanly layered on top +of parsers supporting the standardized SAX2 interfaces. </p> + +</BODY></HTML> diff --git a/libjava/classpath/external/sax/org/xml/sax/helpers/AttributeListImpl.java b/libjava/classpath/external/sax/org/xml/sax/helpers/AttributeListImpl.java new file mode 100644 index 000000000..decf3abc1 --- /dev/null +++ b/libjava/classpath/external/sax/org/xml/sax/helpers/AttributeListImpl.java @@ -0,0 +1,312 @@ +// SAX default implementation for AttributeList. +// http://www.saxproject.org +// No warranty; no copyright -- use this as you will. +// $Id: AttributeListImpl.java,v 1.1 2004/12/23 22:38:42 mark Exp $ + +package org.xml.sax.helpers; + +import org.xml.sax.AttributeList; + +import java.util.Vector; + + +/** + * Default implementation for AttributeList. + * + * <blockquote> + * <em>This module, both source code and documentation, is in the + * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> + * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a> + * for further information. + * </blockquote> + * + * <p>AttributeList implements the deprecated SAX1 {@link + * org.xml.sax.AttributeList AttributeList} interface, and has been + * replaced by the new SAX2 {@link org.xml.sax.helpers.AttributesImpl + * AttributesImpl} interface.</p> + * + * <p>This class provides a convenience implementation of the SAX + * {@link org.xml.sax.AttributeList AttributeList} interface. This + * implementation is useful both for SAX parser writers, who can use + * it to provide attributes to the application, and for SAX application + * writers, who can use it to create a persistent copy of an element's + * attribute specifications:</p> + * + * <pre> + * private AttributeList myatts; + * + * public void startElement (String name, AttributeList atts) + * { + * // create a persistent copy of the attribute list + * // for use outside this method + * myatts = new AttributeListImpl(atts); + * [...] + * } + * </pre> + * + * <p>Please note that SAX parsers are not required to use this + * class to provide an implementation of AttributeList; it is + * supplied only as an optional convenience. In particular, + * parser writers are encouraged to invent more efficient + * implementations.</p> + * + * @deprecated This class implements a deprecated interface, + * {@link org.xml.sax.AttributeList AttributeList}; + * that interface has been replaced by + * {@link org.xml.sax.Attributes Attributes}, + * which is implemented in the + * {@link org.xml.sax.helpers.AttributesImpl + * AttributesImpl} helper class. + * @since SAX 1.0 + * @author David Megginson + * @version 2.0.1 (sax2r2) + * @see org.xml.sax.AttributeList + * @see org.xml.sax.DocumentHandler#startElement + */ +public class AttributeListImpl implements AttributeList +{ + + /** + * Create an empty attribute list. + * + * <p>This constructor is most useful for parser writers, who + * will use it to create a single, reusable attribute list that + * can be reset with the clear method between elements.</p> + * + * @see #addAttribute + * @see #clear + */ + public AttributeListImpl () + { + } + + + /** + * Construct a persistent copy of an existing attribute list. + * + * <p>This constructor is most useful for application writers, + * who will use it to create a persistent copy of an existing + * attribute list.</p> + * + * @param atts The attribute list to copy + * @see org.xml.sax.DocumentHandler#startElement + */ + public AttributeListImpl (AttributeList atts) + { + setAttributeList(atts); + } + + + + //////////////////////////////////////////////////////////////////// + // Methods specific to this class. + //////////////////////////////////////////////////////////////////// + + + /** + * Set the attribute list, discarding previous contents. + * + * <p>This method allows an application writer to reuse an + * attribute list easily.</p> + * + * @param atts The attribute list to copy. + */ + public void setAttributeList (AttributeList atts) + { + int count = atts.getLength(); + + clear(); + + for (int i = 0; i < count; i++) { + addAttribute(atts.getName(i), atts.getType(i), atts.getValue(i)); + } + } + + + /** + * Add an attribute to an attribute list. + * + * <p>This method is provided for SAX parser writers, to allow them + * to build up an attribute list incrementally before delivering + * it to the application.</p> + * + * @param name The attribute name. + * @param type The attribute type ("NMTOKEN" for an enumeration). + * @param value The attribute value (must not be null). + * @see #removeAttribute + * @see org.xml.sax.DocumentHandler#startElement + */ + public void addAttribute (String name, String type, String value) + { + names.addElement(name); + types.addElement(type); + values.addElement(value); + } + + + /** + * Remove an attribute from the list. + * + * <p>SAX application writers can use this method to filter an + * attribute out of an AttributeList. Note that invoking this + * method will change the length of the attribute list and + * some of the attribute's indices.</p> + * + * <p>If the requested attribute is not in the list, this is + * a no-op.</p> + * + * @param name The attribute name. + * @see #addAttribute + */ + public void removeAttribute (String name) + { + int i = names.indexOf(name); + + if (i >= 0) { + names.removeElementAt(i); + types.removeElementAt(i); + values.removeElementAt(i); + } + } + + + /** + * Clear the attribute list. + * + * <p>SAX parser writers can use this method to reset the attribute + * list between DocumentHandler.startElement events. Normally, + * it will make sense to reuse the same AttributeListImpl object + * rather than allocating a new one each time.</p> + * + * @see org.xml.sax.DocumentHandler#startElement + */ + public void clear () + { + names.removeAllElements(); + types.removeAllElements(); + values.removeAllElements(); + } + + + + //////////////////////////////////////////////////////////////////// + // Implementation of org.xml.sax.AttributeList + //////////////////////////////////////////////////////////////////// + + + /** + * Return the number of attributes in the list. + * + * @return The number of attributes in the list. + * @see org.xml.sax.AttributeList#getLength + */ + public int getLength () + { + return names.size(); + } + + + /** + * Get the name of an attribute (by position). + * + * @param i The position of the attribute in the list. + * @return The attribute name as a string, or null if there + * is no attribute at that position. + * @see org.xml.sax.AttributeList#getName(int) + */ + public String getName (int i) + { + if (i < 0) { + return null; + } + try { + return (String)names.elementAt(i); + } catch (ArrayIndexOutOfBoundsException e) { + return null; + } + } + + + /** + * Get the type of an attribute (by position). + * + * @param i The position of the attribute in the list. + * @return The attribute type as a string ("NMTOKEN" for an + * enumeration, and "CDATA" if no declaration was + * read), or null if there is no attribute at + * that position. + * @see org.xml.sax.AttributeList#getType(int) + */ + public String getType (int i) + { + if (i < 0) { + return null; + } + try { + return (String)types.elementAt(i); + } catch (ArrayIndexOutOfBoundsException e) { + return null; + } + } + + + /** + * Get the value of an attribute (by position). + * + * @param i The position of the attribute in the list. + * @return The attribute value as a string, or null if + * there is no attribute at that position. + * @see org.xml.sax.AttributeList#getValue(int) + */ + public String getValue (int i) + { + if (i < 0) { + return null; + } + try { + return (String)values.elementAt(i); + } catch (ArrayIndexOutOfBoundsException e) { + return null; + } + } + + + /** + * Get the type of an attribute (by name). + * + * @param name The attribute name. + * @return The attribute type as a string ("NMTOKEN" for an + * enumeration, and "CDATA" if no declaration was + * read). + * @see org.xml.sax.AttributeList#getType(java.lang.String) + */ + public String getType (String name) + { + return getType(names.indexOf(name)); + } + + + /** + * Get the value of an attribute (by name). + * + * @param name The attribute name. + * @see org.xml.sax.AttributeList#getValue(java.lang.String) + */ + public String getValue (String name) + { + return getValue(names.indexOf(name)); + } + + + + //////////////////////////////////////////////////////////////////// + // Internal state. + //////////////////////////////////////////////////////////////////// + + Vector names = new Vector(); + Vector types = new Vector(); + Vector values = new Vector(); + +} + +// end of AttributeListImpl.java diff --git a/libjava/classpath/external/sax/org/xml/sax/helpers/AttributesImpl.java b/libjava/classpath/external/sax/org/xml/sax/helpers/AttributesImpl.java new file mode 100644 index 000000000..589b9209f --- /dev/null +++ b/libjava/classpath/external/sax/org/xml/sax/helpers/AttributesImpl.java @@ -0,0 +1,617 @@ +// AttributesImpl.java - default implementation of Attributes. +// http://www.saxproject.org +// Written by David Megginson +// NO WARRANTY! This class is in the public domain. +// $Id: AttributesImpl.java,v 1.1 2004/12/23 22:38:42 mark Exp $ + +package org.xml.sax.helpers; + +import org.xml.sax.Attributes; + + +/** + * Default implementation of the Attributes interface. + * + * <blockquote> + * <em>This module, both source code and documentation, is in the + * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> + * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a> + * for further information. + * </blockquote> + * + * <p>This class provides a default implementation of the SAX2 + * {@link org.xml.sax.Attributes Attributes} interface, with the + * addition of manipulators so that the list can be modified or + * reused.</p> + * + * <p>There are two typical uses of this class:</p> + * + * <ol> + * <li>to take a persistent snapshot of an Attributes object + * in a {@link org.xml.sax.ContentHandler#startElement startElement} event; or</li> + * <li>to construct or modify an Attributes object in a SAX2 driver or filter.</li> + * </ol> + * + * <p>This class replaces the now-deprecated SAX1 {@link + * org.xml.sax.helpers.AttributeListImpl AttributeListImpl} + * class; in addition to supporting the updated Attributes + * interface rather than the deprecated {@link org.xml.sax.AttributeList + * AttributeList} interface, it also includes a much more efficient + * implementation using a single array rather than a set of Vectors.</p> + * + * @since SAX 2.0 + * @author David Megginson + * @version 2.0.1 (sax2r2) + */ +public class AttributesImpl implements Attributes +{ + + + //////////////////////////////////////////////////////////////////// + // Constructors. + //////////////////////////////////////////////////////////////////// + + + /** + * Construct a new, empty AttributesImpl object. + */ + public AttributesImpl () + { + length = 0; + data = null; + } + + + /** + * Copy an existing Attributes object. + * + * <p>This constructor is especially useful inside a + * {@link org.xml.sax.ContentHandler#startElement startElement} event.</p> + * + * @param atts The existing Attributes object. + */ + public AttributesImpl (Attributes atts) + { + setAttributes(atts); + } + + + + //////////////////////////////////////////////////////////////////// + // Implementation of org.xml.sax.Attributes. + //////////////////////////////////////////////////////////////////// + + + /** + * Return the number of attributes in the list. + * + * @return The number of attributes in the list. + * @see org.xml.sax.Attributes#getLength + */ + public int getLength () + { + return length; + } + + + /** + * Return an attribute's Namespace URI. + * + * @param index The attribute's index (zero-based). + * @return The Namespace URI, the empty string if none is + * available, or null if the index is out of range. + * @see org.xml.sax.Attributes#getURI + */ + public String getURI (int index) + { + if (index >= 0 && index < length) { + return data[index*5]; + } else { + return null; + } + } + + + /** + * Return an attribute's local name. + * + * @param index The attribute's index (zero-based). + * @return The attribute's local name, the empty string if + * none is available, or null if the index if out of range. + * @see org.xml.sax.Attributes#getLocalName + */ + public String getLocalName (int index) + { + if (index >= 0 && index < length) { + return data[index*5+1]; + } else { + return null; + } + } + + + /** + * Return an attribute's qualified (prefixed) name. + * + * @param index The attribute's index (zero-based). + * @return The attribute's qualified name, the empty string if + * none is available, or null if the index is out of bounds. + * @see org.xml.sax.Attributes#getQName + */ + public String getQName (int index) + { + if (index >= 0 && index < length) { + return data[index*5+2]; + } else { + return null; + } + } + + + /** + * Return an attribute's type by index. + * + * @param index The attribute's index (zero-based). + * @return The attribute's type, "CDATA" if the type is unknown, or null + * if the index is out of bounds. + * @see org.xml.sax.Attributes#getType(int) + */ + public String getType (int index) + { + if (index >= 0 && index < length) { + return data[index*5+3]; + } else { + return null; + } + } + + + /** + * Return an attribute's value by index. + * + * @param index The attribute's index (zero-based). + * @return The attribute's value or null if the index is out of bounds. + * @see org.xml.sax.Attributes#getValue(int) + */ + public String getValue (int index) + { + if (index >= 0 && index < length) { + return data[index*5+4]; + } else { + return null; + } + } + + + /** + * Look up an attribute's index by Namespace name. + * + * <p>In many cases, it will be more efficient to look up the name once and + * use the index query methods rather than using the name query methods + * repeatedly.</p> + * + * @param uri The attribute's Namespace URI, or the empty + * string if none is available. + * @param localName The attribute's local name. + * @return The attribute's index, or -1 if none matches. + * @see org.xml.sax.Attributes#getIndex(java.lang.String,java.lang.String) + */ + public int getIndex (String uri, String localName) + { + int max = length * 5; + for (int i = 0; i < max; i += 5) { + if (data[i].equals(uri) && data[i+1].equals(localName)) { + return i / 5; + } + } + return -1; + } + + + /** + * Look up an attribute's index by qualified (prefixed) name. + * + * @param qName The qualified name. + * @return The attribute's index, or -1 if none matches. + * @see org.xml.sax.Attributes#getIndex(java.lang.String) + */ + public int getIndex (String qName) + { + int max = length * 5; + for (int i = 0; i < max; i += 5) { + if (data[i+2].equals(qName)) { + return i / 5; + } + } + return -1; + } + + + /** + * Look up an attribute's type by Namespace-qualified name. + * + * @param uri The Namespace URI, or the empty string for a name + * with no explicit Namespace URI. + * @param localName The local name. + * @return The attribute's type, or null if there is no + * matching attribute. + * @see org.xml.sax.Attributes#getType(java.lang.String,java.lang.String) + */ + public String getType (String uri, String localName) + { + int max = length * 5; + for (int i = 0; i < max; i += 5) { + if (data[i].equals(uri) && data[i+1].equals(localName)) { + return data[i+3]; + } + } + return null; + } + + + /** + * Look up an attribute's type by qualified (prefixed) name. + * + * @param qName The qualified name. + * @return The attribute's type, or null if there is no + * matching attribute. + * @see org.xml.sax.Attributes#getType(java.lang.String) + */ + public String getType (String qName) + { + int max = length * 5; + for (int i = 0; i < max; i += 5) { + if (data[i+2].equals(qName)) { + return data[i+3]; + } + } + return null; + } + + + /** + * Look up an attribute's value by Namespace-qualified name. + * + * @param uri The Namespace URI, or the empty string for a name + * with no explicit Namespace URI. + * @param localName The local name. + * @return The attribute's value, or null if there is no + * matching attribute. + * @see org.xml.sax.Attributes#getValue(java.lang.String,java.lang.String) + */ + public String getValue (String uri, String localName) + { + int max = length * 5; + for (int i = 0; i < max; i += 5) { + if (data[i].equals(uri) && data[i+1].equals(localName)) { + return data[i+4]; + } + } + return null; + } + + + /** + * Look up an attribute's value by qualified (prefixed) name. + * + * @param qName The qualified name. + * @return The attribute's value, or null if there is no + * matching attribute. + * @see org.xml.sax.Attributes#getValue(java.lang.String) + */ + public String getValue (String qName) + { + int max = length * 5; + for (int i = 0; i < max; i += 5) { + if (data[i+2].equals(qName)) { + return data[i+4]; + } + } + return null; + } + + + + //////////////////////////////////////////////////////////////////// + // Manipulators. + //////////////////////////////////////////////////////////////////// + + + /** + * Clear the attribute list for reuse. + * + * <p>Note that little memory is freed by this call: + * the current array is kept so it can be + * reused.</p> + */ + public void clear () + { + if (data != null) { + for (int i = 0; i < (length * 5); i++) + data [i] = null; + } + length = 0; + } + + + /** + * Copy an entire Attributes object. + * + * <p>It may be more efficient to reuse an existing object + * rather than constantly allocating new ones.</p> + * + * @param atts The attributes to copy. + */ + public void setAttributes (Attributes atts) + { + clear(); + length = atts.getLength(); + if (length > 0) { + data = new String[length*5]; + for (int i = 0; i < length; i++) { + data[i*5] = atts.getURI(i); + data[i*5+1] = atts.getLocalName(i); + data[i*5+2] = atts.getQName(i); + data[i*5+3] = atts.getType(i); + data[i*5+4] = atts.getValue(i); + } + } + } + + + /** + * Add an attribute to the end of the list. + * + * <p>For the sake of speed, this method does no checking + * to see if the attribute is already in the list: that is + * the responsibility of the application.</p> + * + * @param uri The Namespace URI, or the empty string if + * none is available or Namespace processing is not + * being performed. + * @param localName The local name, or the empty string if + * Namespace processing is not being performed. + * @param qName The qualified (prefixed) name, or the empty string + * if qualified names are not available. + * @param type The attribute type as a string. + * @param value The attribute value. + */ + public void addAttribute (String uri, String localName, String qName, + String type, String value) + { + ensureCapacity(length+1); + data[length*5] = uri; + data[length*5+1] = localName; + data[length*5+2] = qName; + data[length*5+3] = type; + data[length*5+4] = value; + length++; + } + + + /** + * Set an attribute in the list. + * + * <p>For the sake of speed, this method does no checking + * for name conflicts or well-formedness: such checks are the + * responsibility of the application.</p> + * + * @param index The index of the attribute (zero-based). + * @param uri The Namespace URI, or the empty string if + * none is available or Namespace processing is not + * being performed. + * @param localName The local name, or the empty string if + * Namespace processing is not being performed. + * @param qName The qualified name, or the empty string + * if qualified names are not available. + * @param type The attribute type as a string. + * @param value The attribute value. + * @exception java.lang.ArrayIndexOutOfBoundsException When the + * supplied index does not point to an attribute + * in the list. + */ + public void setAttribute (int index, String uri, String localName, + String qName, String type, String value) + { + if (index >= 0 && index < length) { + data[index*5] = uri; + data[index*5+1] = localName; + data[index*5+2] = qName; + data[index*5+3] = type; + data[index*5+4] = value; + } else { + badIndex(index); + } + } + + + /** + * Remove an attribute from the list. + * + * @param index The index of the attribute (zero-based). + * @exception java.lang.ArrayIndexOutOfBoundsException When the + * supplied index does not point to an attribute + * in the list. + */ + public void removeAttribute (int index) + { + if (index >= 0 && index < length) { + if (index < length - 1) { + System.arraycopy(data, (index+1)*5, data, index*5, + (length-index-1)*5); + } + index = (length - 1) * 5; + data [index++] = null; + data [index++] = null; + data [index++] = null; + data [index++] = null; + data [index] = null; + length--; + } else { + badIndex(index); + } + } + + + /** + * Set the Namespace URI of a specific attribute. + * + * @param index The index of the attribute (zero-based). + * @param uri The attribute's Namespace URI, or the empty + * string for none. + * @exception java.lang.ArrayIndexOutOfBoundsException When the + * supplied index does not point to an attribute + * in the list. + */ + public void setURI (int index, String uri) + { + if (index >= 0 && index < length) { + data[index*5] = uri; + } else { + badIndex(index); + } + } + + + /** + * Set the local name of a specific attribute. + * + * @param index The index of the attribute (zero-based). + * @param localName The attribute's local name, or the empty + * string for none. + * @exception java.lang.ArrayIndexOutOfBoundsException When the + * supplied index does not point to an attribute + * in the list. + */ + public void setLocalName (int index, String localName) + { + if (index >= 0 && index < length) { + data[index*5+1] = localName; + } else { + badIndex(index); + } + } + + + /** + * Set the qualified name of a specific attribute. + * + * @param index The index of the attribute (zero-based). + * @param qName The attribute's qualified name, or the empty + * string for none. + * @exception java.lang.ArrayIndexOutOfBoundsException When the + * supplied index does not point to an attribute + * in the list. + */ + public void setQName (int index, String qName) + { + if (index >= 0 && index < length) { + data[index*5+2] = qName; + } else { + badIndex(index); + } + } + + + /** + * Set the type of a specific attribute. + * + * @param index The index of the attribute (zero-based). + * @param type The attribute's type. + * @exception java.lang.ArrayIndexOutOfBoundsException When the + * supplied index does not point to an attribute + * in the list. + */ + public void setType (int index, String type) + { + if (index >= 0 && index < length) { + data[index*5+3] = type; + } else { + badIndex(index); + } + } + + + /** + * Set the value of a specific attribute. + * + * @param index The index of the attribute (zero-based). + * @param value The attribute's value. + * @exception java.lang.ArrayIndexOutOfBoundsException When the + * supplied index does not point to an attribute + * in the list. + */ + public void setValue (int index, String value) + { + if (index >= 0 && index < length) { + data[index*5+4] = value; + } else { + badIndex(index); + } + } + + + + //////////////////////////////////////////////////////////////////// + // Internal methods. + //////////////////////////////////////////////////////////////////// + + + /** + * Ensure the internal array's capacity. + * + * @param n The minimum number of attributes that the array must + * be able to hold. + */ + private void ensureCapacity (int n) { + if (n <= 0) { + return; + } + int max; + if (data == null || data.length == 0) { + max = 25; + } + else if (data.length >= n * 5) { + return; + } + else { + max = data.length; + } + while (max < n * 5) { + max *= 2; + } + + String newData[] = new String[max]; + if (length > 0) { + System.arraycopy(data, 0, newData, 0, length*5); + } + data = newData; + } + + + /** + * Report a bad array index in a manipulator. + * + * @param index The index to report. + * @exception java.lang.ArrayIndexOutOfBoundsException Always. + */ + private void badIndex (int index) + throws ArrayIndexOutOfBoundsException + { + String msg = + "Attempt to modify attribute at illegal index: " + index; + throw new ArrayIndexOutOfBoundsException(msg); + } + + + + //////////////////////////////////////////////////////////////////// + // Internal state. + //////////////////////////////////////////////////////////////////// + + int length; + String data []; + +} + +// end of AttributesImpl.java diff --git a/libjava/classpath/external/sax/org/xml/sax/helpers/DefaultHandler.java b/libjava/classpath/external/sax/org/xml/sax/helpers/DefaultHandler.java new file mode 100644 index 000000000..f3d6eae44 --- /dev/null +++ b/libjava/classpath/external/sax/org/xml/sax/helpers/DefaultHandler.java @@ -0,0 +1,467 @@ +// DefaultHandler.java - default implementation of the core handlers. +// http://www.saxproject.org +// Written by David Megginson +// NO WARRANTY! This class is in the public domain. +// $Id: DefaultHandler.java,v 1.1 2004/12/23 22:38:42 mark Exp $ + +package org.xml.sax.helpers; + +import java.io.IOException; + +import org.xml.sax.InputSource; +import org.xml.sax.Locator; +import org.xml.sax.Attributes; +import org.xml.sax.EntityResolver; +import org.xml.sax.DTDHandler; +import org.xml.sax.ContentHandler; +import org.xml.sax.ErrorHandler; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + + +/** + * Default base class for SAX2 event handlers. + * + * <blockquote> + * <em>This module, both source code and documentation, is in the + * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> + * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a> + * for further information. + * </blockquote> + * + * <p>This class is available as a convenience base class for SAX2 + * applications: it provides default implementations for all of the + * callbacks in the four core SAX2 handler classes:</p> + * + * <ul> + * <li>{@link org.xml.sax.EntityResolver EntityResolver}</li> + * <li>{@link org.xml.sax.DTDHandler DTDHandler}</li> + * <li>{@link org.xml.sax.ContentHandler ContentHandler}</li> + * <li>{@link org.xml.sax.ErrorHandler ErrorHandler}</li> + * </ul> + * + * <p>Application writers can extend this class when they need to + * implement only part of an interface; parser writers can + * instantiate this class to provide default handlers when the + * application has not supplied its own.</p> + * + * <p>This class replaces the deprecated SAX1 + * {@link org.xml.sax.HandlerBase HandlerBase} class.</p> + * + * @since SAX 2.0 + * @author David Megginson, + * @version 2.0.1 (sax2r2) + * @see org.xml.sax.EntityResolver + * @see org.xml.sax.DTDHandler + * @see org.xml.sax.ContentHandler + * @see org.xml.sax.ErrorHandler + */ +public class DefaultHandler + implements EntityResolver, DTDHandler, ContentHandler, ErrorHandler +{ + + + //////////////////////////////////////////////////////////////////// + // Default implementation of the EntityResolver interface. + //////////////////////////////////////////////////////////////////// + + /** + * Resolve an external entity. + * + * <p>Always return null, so that the parser will use the system + * identifier provided in the XML document. This method implements + * the SAX default behaviour: application writers can override it + * in a subclass to do special translations such as catalog lookups + * or URI redirection.</p> + * + * @param publicId The public identifer, or null if none is + * available. + * @param systemId The system identifier provided in the XML + * document. + * @return The new input source, or null to require the + * default behaviour. + * @exception java.io.IOException If there is an error setting + * up the new input source. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + * @see org.xml.sax.EntityResolver#resolveEntity + */ + public InputSource resolveEntity (String publicId, String systemId) + throws IOException, SAXException + { + return null; + } + + + + //////////////////////////////////////////////////////////////////// + // Default implementation of DTDHandler interface. + //////////////////////////////////////////////////////////////////// + + + /** + * Receive notification of a notation declaration. + * + * <p>By default, do nothing. Application writers may override this + * method in a subclass if they wish to keep track of the notations + * declared in a document.</p> + * + * @param name The notation name. + * @param publicId The notation public identifier, or null if not + * available. + * @param systemId The notation system identifier. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + * @see org.xml.sax.DTDHandler#notationDecl + */ + public void notationDecl (String name, String publicId, String systemId) + throws SAXException + { + // no op + } + + + /** + * Receive notification of an unparsed entity declaration. + * + * <p>By default, do nothing. Application writers may override this + * method in a subclass to keep track of the unparsed entities + * declared in a document.</p> + * + * @param name The entity name. + * @param publicId The entity public identifier, or null if not + * available. + * @param systemId The entity system identifier. + * @param notationName The name of the associated notation. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + * @see org.xml.sax.DTDHandler#unparsedEntityDecl + */ + public void unparsedEntityDecl (String name, String publicId, + String systemId, String notationName) + throws SAXException + { + // no op + } + + + + //////////////////////////////////////////////////////////////////// + // Default implementation of ContentHandler interface. + //////////////////////////////////////////////////////////////////// + + + /** + * Receive a Locator object for document events. + * + * <p>By default, do nothing. Application writers may override this + * method in a subclass if they wish to store the locator for use + * with other document events.</p> + * + * @param locator A locator for all SAX document events. + * @see org.xml.sax.ContentHandler#setDocumentLocator + * @see org.xml.sax.Locator + */ + public void setDocumentLocator (Locator locator) + { + // no op + } + + + /** + * Receive notification of the beginning of the document. + * + * <p>By default, do nothing. Application writers may override this + * method in a subclass to take specific actions at the beginning + * of a document (such as allocating the root node of a tree or + * creating an output file).</p> + * + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + * @see org.xml.sax.ContentHandler#startDocument + */ + public void startDocument () + throws SAXException + { + // no op + } + + + /** + * Receive notification of the end of the document. + * + * <p>By default, do nothing. Application writers may override this + * method in a subclass to take specific actions at the end + * of a document (such as finalising a tree or closing an output + * file).</p> + * + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + * @see org.xml.sax.ContentHandler#endDocument + */ + public void endDocument () + throws SAXException + { + // no op + } + + + /** + * Receive notification of the start of a Namespace mapping. + * + * <p>By default, do nothing. Application writers may override this + * method in a subclass to take specific actions at the start of + * each Namespace prefix scope (such as storing the prefix mapping).</p> + * + * @param prefix The Namespace prefix being declared. + * @param uri The Namespace URI mapped to the prefix. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + * @see org.xml.sax.ContentHandler#startPrefixMapping + */ + public void startPrefixMapping (String prefix, String uri) + throws SAXException + { + // no op + } + + + /** + * Receive notification of the end of a Namespace mapping. + * + * <p>By default, do nothing. Application writers may override this + * method in a subclass to take specific actions at the end of + * each prefix mapping.</p> + * + * @param prefix The Namespace prefix being declared. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + * @see org.xml.sax.ContentHandler#endPrefixMapping + */ + public void endPrefixMapping (String prefix) + throws SAXException + { + // no op + } + + + /** + * Receive notification of the start of an element. + * + * <p>By default, do nothing. Application writers may override this + * method in a subclass to take specific actions at the start of + * each element (such as allocating a new tree node or writing + * output to a file).</p> + * + * @param uri The Namespace URI, or the empty string if the + * element has no Namespace URI or if Namespace + * processing is not being performed. + * @param localName The local name (without prefix), or the + * empty string if Namespace processing is not being + * performed. + * @param qName The qualified name (with prefix), or the + * empty string if qualified names are not available. + * @param attributes The attributes attached to the element. If + * there are no attributes, it shall be an empty + * Attributes object. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + * @see org.xml.sax.ContentHandler#startElement + */ + public void startElement (String uri, String localName, + String qName, Attributes attributes) + throws SAXException + { + // no op + } + + + /** + * Receive notification of the end of an element. + * + * <p>By default, do nothing. Application writers may override this + * method in a subclass to take specific actions at the end of + * each element (such as finalising a tree node or writing + * output to a file).</p> + * + * @param uri The Namespace URI, or the empty string if the + * element has no Namespace URI or if Namespace + * processing is not being performed. + * @param localName The local name (without prefix), or the + * empty string if Namespace processing is not being + * performed. + * @param qName The qualified name (with prefix), or the + * empty string if qualified names are not available. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + * @see org.xml.sax.ContentHandler#endElement + */ + public void endElement (String uri, String localName, String qName) + throws SAXException + { + // no op + } + + + /** + * Receive notification of character data inside an element. + * + * <p>By default, do nothing. Application writers may override this + * method to take specific actions for each chunk of character data + * (such as adding the data to a node or buffer, or printing it to + * a file).</p> + * + * @param ch The characters. + * @param start The start position in the character array. + * @param length The number of characters to use from the + * character array. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + * @see org.xml.sax.ContentHandler#characters + */ + public void characters (char ch[], int start, int length) + throws SAXException + { + // no op + } + + + /** + * Receive notification of ignorable whitespace in element content. + * + * <p>By default, do nothing. Application writers may override this + * method to take specific actions for each chunk of ignorable + * whitespace (such as adding data to a node or buffer, or printing + * it to a file).</p> + * + * @param ch The whitespace characters. + * @param start The start position in the character array. + * @param length The number of characters to use from the + * character array. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + * @see org.xml.sax.ContentHandler#ignorableWhitespace + */ + public void ignorableWhitespace (char ch[], int start, int length) + throws SAXException + { + // no op + } + + + /** + * Receive notification of a processing instruction. + * + * <p>By default, do nothing. Application writers may override this + * method in a subclass to take specific actions for each + * processing instruction, such as setting status variables or + * invoking other methods.</p> + * + * @param target The processing instruction target. + * @param data The processing instruction data, or null if + * none is supplied. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + * @see org.xml.sax.ContentHandler#processingInstruction + */ + public void processingInstruction (String target, String data) + throws SAXException + { + // no op + } + + + /** + * Receive notification of a skipped entity. + * + * <p>By default, do nothing. Application writers may override this + * method in a subclass to take specific actions for each + * processing instruction, such as setting status variables or + * invoking other methods.</p> + * + * @param name The name of the skipped entity. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + * @see org.xml.sax.ContentHandler#processingInstruction + */ + public void skippedEntity (String name) + throws SAXException + { + // no op + } + + + + //////////////////////////////////////////////////////////////////// + // Default implementation of the ErrorHandler interface. + //////////////////////////////////////////////////////////////////// + + + /** + * Receive notification of a parser warning. + * + * <p>The default implementation does nothing. Application writers + * may override this method in a subclass to take specific actions + * for each warning, such as inserting the message in a log file or + * printing it to the console.</p> + * + * @param e The warning information encoded as an exception. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + * @see org.xml.sax.ErrorHandler#warning + * @see org.xml.sax.SAXParseException + */ + public void warning (SAXParseException e) + throws SAXException + { + // no op + } + + + /** + * Receive notification of a recoverable parser error. + * + * <p>The default implementation does nothing. Application writers + * may override this method in a subclass to take specific actions + * for each error, such as inserting the message in a log file or + * printing it to the console.</p> + * + * @param e The warning information encoded as an exception. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + * @see org.xml.sax.ErrorHandler#warning + * @see org.xml.sax.SAXParseException + */ + public void error (SAXParseException e) + throws SAXException + { + // no op + } + + + /** + * Report a fatal XML parsing error. + * + * <p>The default implementation throws a SAXParseException. + * Application writers may override this method in a subclass if + * they need to take specific actions for each fatal error (such as + * collecting all of the errors into a single report): in any case, + * the application must stop all regular processing when this + * method is invoked, since the document is no longer reliable, and + * the parser may no longer report parsing events.</p> + * + * @param e The error information encoded as an exception. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + * @see org.xml.sax.ErrorHandler#fatalError + * @see org.xml.sax.SAXParseException + */ + public void fatalError (SAXParseException e) + throws SAXException + { + throw e; + } + +} + +// end of DefaultHandler.java diff --git a/libjava/classpath/external/sax/org/xml/sax/helpers/LocatorImpl.java b/libjava/classpath/external/sax/org/xml/sax/helpers/LocatorImpl.java new file mode 100644 index 000000000..d45813e5b --- /dev/null +++ b/libjava/classpath/external/sax/org/xml/sax/helpers/LocatorImpl.java @@ -0,0 +1,214 @@ +// SAX default implementation for Locator. +// http://www.saxproject.org +// No warranty; no copyright -- use this as you will. +// $Id: LocatorImpl.java,v 1.1 2004/12/23 22:38:42 mark Exp $ + +package org.xml.sax.helpers; + +import org.xml.sax.Locator; + + +/** + * Provide an optional convenience implementation of Locator. + * + * <blockquote> + * <em>This module, both source code and documentation, is in the + * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> + * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a> + * for further information. + * </blockquote> + * + * <p>This class is available mainly for application writers, who + * can use it to make a persistent snapshot of a locator at any + * point during a document parse:</p> + * + * <pre> + * Locator locator; + * Locator startloc; + * + * public void setLocator (Locator locator) + * { + * // note the locator + * this.locator = locator; + * } + * + * public void startDocument () + * { + * // save the location of the start of the document + * // for future use. + * Locator startloc = new LocatorImpl(locator); + * } + *</pre> + * + * <p>Normally, parser writers will not use this class, since it + * is more efficient to provide location information only when + * requested, rather than constantly updating a Locator object.</p> + * + * @since SAX 1.0 + * @author David Megginson + * @version 2.0.1 (sax2r2) + * @see org.xml.sax.Locator Locator + */ +public class LocatorImpl implements Locator +{ + + + /** + * Zero-argument constructor. + * + * <p>This will not normally be useful, since the main purpose + * of this class is to make a snapshot of an existing Locator.</p> + */ + public LocatorImpl () + { + } + + + /** + * Copy constructor. + * + * <p>Create a persistent copy of the current state of a locator. + * When the original locator changes, this copy will still keep + * the original values (and it can be used outside the scope of + * DocumentHandler methods).</p> + * + * @param locator The locator to copy. + */ + public LocatorImpl (Locator locator) + { + setPublicId(locator.getPublicId()); + setSystemId(locator.getSystemId()); + setLineNumber(locator.getLineNumber()); + setColumnNumber(locator.getColumnNumber()); + } + + + + //////////////////////////////////////////////////////////////////// + // Implementation of org.xml.sax.Locator + //////////////////////////////////////////////////////////////////// + + + /** + * Return the saved public identifier. + * + * @return The public identifier as a string, or null if none + * is available. + * @see org.xml.sax.Locator#getPublicId + * @see #setPublicId + */ + public String getPublicId () + { + return publicId; + } + + + /** + * Return the saved system identifier. + * + * @return The system identifier as a string, or null if none + * is available. + * @see org.xml.sax.Locator#getSystemId + * @see #setSystemId + */ + public String getSystemId () + { + return systemId; + } + + + /** + * Return the saved line number (1-based). + * + * @return The line number as an integer, or -1 if none is available. + * @see org.xml.sax.Locator#getLineNumber + * @see #setLineNumber + */ + public int getLineNumber () + { + return lineNumber; + } + + + /** + * Return the saved column number (1-based). + * + * @return The column number as an integer, or -1 if none is available. + * @see org.xml.sax.Locator#getColumnNumber + * @see #setColumnNumber + */ + public int getColumnNumber () + { + return columnNumber; + } + + + + //////////////////////////////////////////////////////////////////// + // Setters for the properties (not in org.xml.sax.Locator) + //////////////////////////////////////////////////////////////////// + + + /** + * Set the public identifier for this locator. + * + * @param publicId The new public identifier, or null + * if none is available. + * @see #getPublicId + */ + public void setPublicId (String publicId) + { + this.publicId = publicId; + } + + + /** + * Set the system identifier for this locator. + * + * @param systemId The new system identifier, or null + * if none is available. + * @see #getSystemId + */ + public void setSystemId (String systemId) + { + this.systemId = systemId; + } + + + /** + * Set the line number for this locator (1-based). + * + * @param lineNumber The line number, or -1 if none is available. + * @see #getLineNumber + */ + public void setLineNumber (int lineNumber) + { + this.lineNumber = lineNumber; + } + + + /** + * Set the column number for this locator (1-based). + * + * @param columnNumber The column number, or -1 if none is available. + * @see #getColumnNumber + */ + public void setColumnNumber (int columnNumber) + { + this.columnNumber = columnNumber; + } + + + + //////////////////////////////////////////////////////////////////// + // Internal state. + //////////////////////////////////////////////////////////////////// + + private String publicId; + private String systemId; + private int lineNumber; + private int columnNumber; + +} + +// end of LocatorImpl.java diff --git a/libjava/classpath/external/sax/org/xml/sax/helpers/NamespaceSupport.java b/libjava/classpath/external/sax/org/xml/sax/helpers/NamespaceSupport.java new file mode 100644 index 000000000..d1e74639a --- /dev/null +++ b/libjava/classpath/external/sax/org/xml/sax/helpers/NamespaceSupport.java @@ -0,0 +1,835 @@ +// NamespaceSupport.java - generic Namespace support for SAX. +// http://www.saxproject.org +// Written by David Megginson +// This class is in the Public Domain. NO WARRANTY! +// $Id: NamespaceSupport.java,v 1.1 2004/12/23 22:38:42 mark Exp $ + +package org.xml.sax.helpers; + +import java.util.EmptyStackException; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Vector; + + +/** + * Encapsulate Namespace logic for use by applications using SAX, + * or internally by SAX drivers. + * + * <blockquote> + * <em>This module, both source code and documentation, is in the + * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> + * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a> + * for further information. + * </blockquote> + * + * <p>This class encapsulates the logic of Namespace processing: it + * tracks the declarations currently in force for each context and + * automatically processes qualified XML names into their Namespace + * parts; it can also be used in reverse for generating XML qnames + * from Namespaces.</p> + * + * <p>Namespace support objects are reusable, but the reset method + * must be invoked between each session.</p> + * + * <p>Here is a simple session:</p> + * + * <pre> + * String parts[] = new String[3]; + * NamespaceSupport support = new NamespaceSupport(); + * + * support.pushContext(); + * support.declarePrefix("", "http://www.w3.org/1999/xhtml"); + * support.declarePrefix("dc", "http://www.purl.org/dc#"); + * + * parts = support.processName("p", parts, false); + * System.out.println("Namespace URI: " + parts[0]); + * System.out.println("Local name: " + parts[1]); + * System.out.println("Raw name: " + parts[2]); + * + * parts = support.processName("dc:title", parts, false); + * System.out.println("Namespace URI: " + parts[0]); + * System.out.println("Local name: " + parts[1]); + * System.out.println("Raw name: " + parts[2]); + * + * support.popContext(); + * </pre> + * + * <p>Note that this class is optimized for the use case where most + * elements do not contain Namespace declarations: if the same + * prefix/URI mapping is repeated for each context (for example), this + * class will be somewhat less efficient.</p> + * + * <p>Although SAX drivers (parsers) may choose to use this class to + * implement namespace handling, they are not required to do so. + * Applications must track namespace information themselves if they + * want to use namespace information. + * + * @since SAX 2.0 + * @author David Megginson + * @version 2.0.1 (sax2r2) + */ +public class NamespaceSupport +{ + + + //////////////////////////////////////////////////////////////////// + // Constants. + //////////////////////////////////////////////////////////////////// + + + /** + * The XML Namespace URI as a constant. + * The value is <code>http://www.w3.org/XML/1998/namespace</code> + * as defined in the "Namespaces in XML" * recommendation. + * + * <p>This is the Namespace URI that is automatically mapped + * to the "xml" prefix.</p> + */ + public final static String XMLNS = + "http://www.w3.org/XML/1998/namespace"; + + + /** + * The namespace declaration URI as a constant. + * The value is <code>http://www.w3.org/xmlns/2000/</code>, as defined + * in a backwards-incompatible erratum to the "Namespaces in XML" + * recommendation. Because that erratum postdated SAX2, SAX2 defaults + * to the original recommendation, and does not normally use this URI. + * + * + * <p>This is the Namespace URI that is optionally applied to + * <em>xmlns</em> and <em>xmlns:*</em> attributes, which are used to + * declare namespaces. </p> + * + * @since SAX 2.1alpha + * @see #setNamespaceDeclUris + * @see #isNamespaceDeclUris + */ + public final static String NSDECL = + "http://www.w3.org/xmlns/2000/"; + + + /** + * An empty enumeration. + */ + private final static Enumeration EMPTY_ENUMERATION = + new Vector().elements(); + + + //////////////////////////////////////////////////////////////////// + // Constructor. + //////////////////////////////////////////////////////////////////// + + + /** + * Create a new Namespace support object. + */ + public NamespaceSupport () + { + reset(); + } + + + + //////////////////////////////////////////////////////////////////// + // Context management. + //////////////////////////////////////////////////////////////////// + + + /** + * Reset this Namespace support object for reuse. + * + * <p>It is necessary to invoke this method before reusing the + * Namespace support object for a new session. If namespace + * declaration URIs are to be supported, that flag must also + * be set to a non-default value. + * </p> + * + * @see #setNamespaceDeclUris + */ + public void reset () + { + contexts = new Context[32]; + namespaceDeclUris = false; + contextPos = 0; + contexts[contextPos] = currentContext = new Context(); + currentContext.declarePrefix("xml", XMLNS); + } + + + /** + * Start a new Namespace context. + * The new context will automatically inherit + * the declarations of its parent context, but it will also keep + * track of which declarations were made within this context. + * + * <p>Event callback code should start a new context once per element. + * This means being ready to call this in either of two places. + * For elements that don't include namespace declarations, the + * <em>ContentHandler.startElement()</em> callback is the right place. + * For elements with such a declaration, it'd done in the first + * <em>ContentHandler.startPrefixMapping()</em> callback. + * A boolean flag can be used to + * track whether a context has been started yet. When either of + * those methods is called, it checks the flag to see if a new context + * needs to be started. If so, it starts the context and sets the + * flag. After <em>ContentHandler.startElement()</em> + * does that, it always clears the flag. + * + * <p>Normally, SAX drivers would push a new context at the beginning + * of each XML element. Then they perform a first pass over the + * attributes to process all namespace declarations, making + * <em>ContentHandler.startPrefixMapping()</em> callbacks. + * Then a second pass is made, to determine the namespace-qualified + * names for all attributes and for the element name. + * Finally all the information for the + * <em>ContentHandler.startElement()</em> callback is available, + * so it can then be made. + * + * <p>The Namespace support object always starts with a base context + * already in force: in this context, only the "xml" prefix is + * declared.</p> + * + * @see org.xml.sax.ContentHandler + * @see #popContext + */ + public void pushContext () + { + int max = contexts.length; + + contexts [contextPos].declsOK = false; + contextPos++; + + // Extend the array if necessary + if (contextPos >= max) { + Context newContexts[] = new Context[max*2]; + System.arraycopy(contexts, 0, newContexts, 0, max); + max *= 2; + contexts = newContexts; + } + + // Allocate the context if necessary. + currentContext = contexts[contextPos]; + if (currentContext == null) { + contexts[contextPos] = currentContext = new Context(); + } + + // Set the parent, if any. + if (contextPos > 0) { + currentContext.setParent(contexts[contextPos - 1]); + } + } + + + /** + * Revert to the previous Namespace context. + * + * <p>Normally, you should pop the context at the end of each + * XML element. After popping the context, all Namespace prefix + * mappings that were previously in force are restored.</p> + * + * <p>You must not attempt to declare additional Namespace + * prefixes after popping a context, unless you push another + * context first.</p> + * + * @see #pushContext + */ + public void popContext () + { + contexts[contextPos].clear(); + contextPos--; + if (contextPos < 0) { + throw new EmptyStackException(); + } + currentContext = contexts[contextPos]; + } + + + + //////////////////////////////////////////////////////////////////// + // Operations within a context. + //////////////////////////////////////////////////////////////////// + + + /** + * Declare a Namespace prefix. All prefixes must be declared + * before they are referenced. For example, a SAX driver (parser) + * would scan an element's attributes + * in two passes: first for namespace declarations, + * then a second pass using {@link #processName processName()} to + * interpret prefixes against (potentially redefined) prefixes. + * + * <p>This method declares a prefix in the current Namespace + * context; the prefix will remain in force until this context + * is popped, unless it is shadowed in a descendant context.</p> + * + * <p>To declare the default element Namespace, use the empty string as + * the prefix.</p> + * + * <p>Note that you must <em>not</em> declare a prefix after + * you've pushed and popped another Namespace context, or + * treated the declarations phase as complete by processing + * a prefixed name.</p> + * + * <p>Note that there is an asymmetry in this library: {@link + * #getPrefix getPrefix} will not return the "" prefix, + * even if you have declared a default element namespace. + * To check for a default namespace, + * you have to look it up explicitly using {@link #getURI getURI}. + * This asymmetry exists to make it easier to look up prefixes + * for attribute names, where the default prefix is not allowed.</p> + * + * @param prefix The prefix to declare, or the empty string to + * indicate the default element namespace. This may never have + * the value "xml" or "xmlns". + * @param uri The Namespace URI to associate with the prefix. + * @return true if the prefix was legal, false otherwise + * + * @see #processName + * @see #getURI + * @see #getPrefix + */ + public boolean declarePrefix (String prefix, String uri) + { + if (prefix.equals("xml") || prefix.equals("xmlns")) { + return false; + } else { + currentContext.declarePrefix(prefix, uri); + return true; + } + } + + + /** + * Process a raw XML qualified name, after all declarations in the + * current context have been handled by {@link #declarePrefix + * declarePrefix()}. + * + * <p>This method processes a raw XML qualified name in the + * current context by removing the prefix and looking it up among + * the prefixes currently declared. The return value will be the + * array supplied by the caller, filled in as follows:</p> + * + * <dl> + * <dt>parts[0]</dt> + * <dd>The Namespace URI, or an empty string if none is + * in use.</dd> + * <dt>parts[1]</dt> + * <dd>The local name (without prefix).</dd> + * <dt>parts[2]</dt> + * <dd>The original raw name.</dd> + * </dl> + * + * <p>All of the strings in the array will be internalized. If + * the raw name has a prefix that has not been declared, then + * the return value will be null.</p> + * + * <p>Note that attribute names are processed differently than + * element names: an unprefixed element name will receive the + * default Namespace (if any), while an unprefixed attribute name + * will not.</p> + * + * @param qName The XML qualified name to be processed. + * @param parts An array supplied by the caller, capable of + * holding at least three members. + * @param isAttribute A flag indicating whether this is an + * attribute name (true) or an element name (false). + * @return The supplied array holding three internalized strings + * representing the Namespace URI (or empty string), the + * local name, and the XML qualified name; or null if there + * is an undeclared prefix. + * @see #declarePrefix + * @see java.lang.String#intern */ + public String [] processName (String qName, String parts[], + boolean isAttribute) + { + String myParts[] = currentContext.processName(qName, isAttribute); + if (myParts == null) { + return null; + } else { + parts[0] = myParts[0]; + parts[1] = myParts[1]; + parts[2] = myParts[2]; + return parts; + } + } + + + /** + * Look up a prefix and get the currently-mapped Namespace URI. + * + * <p>This method looks up the prefix in the current context. + * Use the empty string ("") for the default Namespace.</p> + * + * @param prefix The prefix to look up. + * @return The associated Namespace URI, or null if the prefix + * is undeclared in this context. + * @see #getPrefix + * @see #getPrefixes + */ + public String getURI (String prefix) + { + return currentContext.getURI(prefix); + } + + + /** + * Return an enumeration of all prefixes whose declarations are + * active in the current context. + * This includes declarations from parent contexts that have + * not been overridden. + * + * <p><strong>Note:</strong> if there is a default prefix, it will not be + * returned in this enumeration; check for the default prefix + * using the {@link #getURI getURI} with an argument of "".</p> + * + * @return An enumeration of prefixes (never empty). + * @see #getDeclaredPrefixes + * @see #getURI + */ + public Enumeration getPrefixes () + { + return currentContext.getPrefixes(); + } + + + /** + * Return one of the prefixes mapped to a Namespace URI. + * + * <p>If more than one prefix is currently mapped to the same + * URI, this method will make an arbitrary selection; if you + * want all of the prefixes, use the {@link #getPrefixes} + * method instead.</p> + * + * <p><strong>Note:</strong> this will never return the empty (default) prefix; + * to check for a default prefix, use the {@link #getURI getURI} + * method with an argument of "".</p> + * + * @param uri the namespace URI + * @return one of the prefixes currently mapped to the URI supplied, + * or null if none is mapped or if the URI is assigned to + * the default namespace + * @see #getPrefixes(java.lang.String) + * @see #getURI + */ + public String getPrefix (String uri) + { + return currentContext.getPrefix(uri); + } + + + /** + * Return an enumeration of all prefixes for a given URI whose + * declarations are active in the current context. + * This includes declarations from parent contexts that have + * not been overridden. + * + * <p>This method returns prefixes mapped to a specific Namespace + * URI. The xml: prefix will be included. If you want only one + * prefix that's mapped to the Namespace URI, and you don't care + * which one you get, use the {@link #getPrefix getPrefix} + * method instead.</p> + * + * <p><strong>Note:</strong> the empty (default) prefix is <em>never</em> included + * in this enumeration; to check for the presence of a default + * Namespace, use the {@link #getURI getURI} method with an + * argument of "".</p> + * + * @param uri The Namespace URI. + * @return An enumeration of prefixes (never empty). + * @see #getPrefix + * @see #getDeclaredPrefixes + * @see #getURI + */ + public Enumeration getPrefixes (String uri) + { + Vector prefixes = new Vector(); + Enumeration allPrefixes = getPrefixes(); + while (allPrefixes.hasMoreElements()) { + String prefix = (String)allPrefixes.nextElement(); + if (uri.equals(getURI(prefix))) { + prefixes.addElement(prefix); + } + } + return prefixes.elements(); + } + + + /** + * Return an enumeration of all prefixes declared in this context. + * + * <p>The empty (default) prefix will be included in this + * enumeration; note that this behaviour differs from that of + * {@link #getPrefix} and {@link #getPrefixes}.</p> + * + * @return An enumeration of all prefixes declared in this + * context. + * @see #getPrefixes + * @see #getURI + */ + public Enumeration getDeclaredPrefixes () + { + return currentContext.getDeclaredPrefixes(); + } + + /** + * Controls whether namespace declaration attributes are placed + * into the {@link #NSDECL NSDECL} namespace + * by {@link #processName processName()}. This may only be + * changed before any contexts have been pushed. + * + * @since SAX 2.1alpha + * + * @exception IllegalStateException when attempting to set this + * after any context has been pushed. + */ + public void setNamespaceDeclUris (boolean value) + { + if (contextPos != 0) + throw new IllegalStateException (); + if (value == namespaceDeclUris) + return; + namespaceDeclUris = value; + if (value) + currentContext.declarePrefix ("xmlns", NSDECL); + else { + contexts[contextPos] = currentContext = new Context(); + currentContext.declarePrefix("xml", XMLNS); + } + } + + /** + * Returns true if namespace declaration attributes are placed into + * a namespace. This behavior is not the default. + * + * @since SAX 2.1alpha + */ + public boolean isNamespaceDeclUris () + { return namespaceDeclUris; } + + + + //////////////////////////////////////////////////////////////////// + // Internal state. + //////////////////////////////////////////////////////////////////// + + private Context contexts[]; + private Context currentContext; + private int contextPos; + private boolean namespaceDeclUris; + + + //////////////////////////////////////////////////////////////////// + // Internal classes. + //////////////////////////////////////////////////////////////////// + + /** + * Internal class for a single Namespace context. + * + * <p>This module caches and reuses Namespace contexts, + * so the number allocated + * will be equal to the element depth of the document, not to the total + * number of elements (i.e. 5-10 rather than tens of thousands). + * Also, data structures used to represent contexts are shared when + * possible (child contexts without declarations) to further reduce + * the amount of memory that's consumed. + * </p> + */ + final class Context { + + /** + * Create the root-level Namespace context. + */ + Context () + { + copyTables(); + } + + + /** + * (Re)set the parent of this Namespace context. + * The context must either have been freshly constructed, + * or must have been cleared. + * + * @param context The parent Namespace context object. + */ + void setParent (Context parent) + { + this.parent = parent; + declarations = null; + prefixTable = parent.prefixTable; + uriTable = parent.uriTable; + elementNameTable = parent.elementNameTable; + attributeNameTable = parent.attributeNameTable; + defaultNS = parent.defaultNS; + declSeen = false; + declsOK = true; + } + + /** + * Makes associated state become collectible, + * invalidating this context. + * {@link #setParent} must be called before + * this context may be used again. + */ + void clear () + { + parent = null; + prefixTable = null; + uriTable = null; + elementNameTable = null; + attributeNameTable = null; + defaultNS = null; + } + + + /** + * Declare a Namespace prefix for this context. + * + * @param prefix The prefix to declare. + * @param uri The associated Namespace URI. + * @see org.xml.sax.helpers.NamespaceSupport#declarePrefix + */ + void declarePrefix (String prefix, String uri) + { + // Lazy processing... + if (!declsOK) + throw new IllegalStateException ( + "can't declare any more prefixes in this context"); + if (!declSeen) { + copyTables(); + } + if (declarations == null) { + declarations = new Vector(); + } + + prefix = prefix.intern(); + uri = uri.intern(); + if ("".equals(prefix)) { + if ("".equals(uri)) { + defaultNS = null; + } else { + defaultNS = uri; + } + } else { + prefixTable.put(prefix, uri); + uriTable.put(uri, prefix); // may wipe out another prefix + } + declarations.addElement(prefix); + } + + + /** + * Process an XML qualified name in this context. + * + * @param qName The XML qualified name. + * @param isAttribute true if this is an attribute name. + * @return An array of three strings containing the + * URI part (or empty string), the local part, + * and the raw name, all internalized, or null + * if there is an undeclared prefix. + * @see org.xml.sax.helpers.NamespaceSupport#processName + */ + String [] processName (String qName, boolean isAttribute) + { + String name[]; + Hashtable table; + + // detect errors in call sequence + declsOK = false; + + // Select the appropriate table. + if (isAttribute) { + table = attributeNameTable; + } else { + table = elementNameTable; + } + + // Start by looking in the cache, and + // return immediately if the name + // is already known in this content + name = (String[])table.get(qName); + if (name != null) { + return name; + } + + // We haven't seen this name in this + // context before. Maybe in the parent + // context, but we can't assume prefix + // bindings are the same. + name = new String[3]; + name[2] = qName.intern(); + int index = qName.indexOf(':'); + + + // No prefix. + if (index == -1) { + if (isAttribute) { + if (qName == "xmlns" && namespaceDeclUris) + name[0] = NSDECL; + else + name[0] = ""; + } else if (defaultNS == null) { + name[0] = ""; + } else { + name[0] = defaultNS; + } + name[1] = name[2]; + } + + // Prefix + else { + String prefix = qName.substring(0, index); + String local = qName.substring(index+1); + String uri; + if ("".equals(prefix)) { + uri = defaultNS; + } else { + uri = (String)prefixTable.get(prefix); + } + if (uri == null + || (!isAttribute && "xmlns".equals (prefix))) { + return null; + } + name[0] = uri; + name[1] = local.intern(); + } + + // Save in the cache for future use. + // (Could be shared with parent context...) + table.put(name[2], name); + return name; + } + + + /** + * Look up the URI associated with a prefix in this context. + * + * @param prefix The prefix to look up. + * @return The associated Namespace URI, or null if none is + * declared. + * @see org.xml.sax.helpers.NamespaceSupport#getURI + */ + String getURI (String prefix) + { + if ("".equals(prefix)) { + return defaultNS; + } else if (prefixTable == null) { + return null; + } else { + return (String)prefixTable.get(prefix); + } + } + + + /** + * Look up one of the prefixes associated with a URI in this context. + * + * <p>Since many prefixes may be mapped to the same URI, + * the return value may be unreliable.</p> + * + * @param uri The URI to look up. + * @return The associated prefix, or null if none is declared. + * @see org.xml.sax.helpers.NamespaceSupport#getPrefix + */ + String getPrefix (String uri) + { + if (uriTable == null) { + return null; + } else { + return (String)uriTable.get(uri); + } + } + + + /** + * Return an enumeration of prefixes declared in this context. + * + * @return An enumeration of prefixes (possibly empty). + * @see org.xml.sax.helpers.NamespaceSupport#getDeclaredPrefixes + */ + Enumeration getDeclaredPrefixes () + { + if (declarations == null) { + return EMPTY_ENUMERATION; + } else { + return declarations.elements(); + } + } + + + /** + * Return an enumeration of all prefixes currently in force. + * + * <p>The default prefix, if in force, is <em>not</em> + * returned, and will have to be checked for separately.</p> + * + * @return An enumeration of prefixes (never empty). + * @see org.xml.sax.helpers.NamespaceSupport#getPrefixes + */ + Enumeration getPrefixes () + { + if (prefixTable == null) { + return EMPTY_ENUMERATION; + } else { + return prefixTable.keys(); + } + } + + + + //////////////////////////////////////////////////////////////// + // Internal methods. + //////////////////////////////////////////////////////////////// + + + /** + * Copy on write for the internal tables in this context. + * + * <p>This class is optimized for the normal case where most + * elements do not contain Namespace declarations.</p> + */ + private void copyTables () + { + if (prefixTable != null) { + prefixTable = (Hashtable)prefixTable.clone(); + } else { + prefixTable = new Hashtable(); + } + if (uriTable != null) { + uriTable = (Hashtable)uriTable.clone(); + } else { + uriTable = new Hashtable(); + } + elementNameTable = new Hashtable(); + attributeNameTable = new Hashtable(); + declSeen = true; + } + + + + //////////////////////////////////////////////////////////////// + // Protected state. + //////////////////////////////////////////////////////////////// + + Hashtable prefixTable; + Hashtable uriTable; + Hashtable elementNameTable; + Hashtable attributeNameTable; + String defaultNS = null; + boolean declsOK = true; + + + + //////////////////////////////////////////////////////////////// + // Internal state. + //////////////////////////////////////////////////////////////// + + private Vector declarations = null; + private boolean declSeen = false; + private Context parent = null; + } +} + +// end of NamespaceSupport.java diff --git a/libjava/classpath/external/sax/org/xml/sax/helpers/NewInstance.java b/libjava/classpath/external/sax/org/xml/sax/helpers/NewInstance.java new file mode 100644 index 000000000..211f47f1c --- /dev/null +++ b/libjava/classpath/external/sax/org/xml/sax/helpers/NewInstance.java @@ -0,0 +1,79 @@ +// NewInstance.java - create a new instance of a class by name. +// http://www.saxproject.org +// Written by Edwin Goei, edwingo@apache.org +// and by David Brownell, dbrownell@users.sourceforge.net +// NO WARRANTY! This class is in the Public Domain. +// $Id: NewInstance.java,v 1.1 2004/12/23 22:38:42 mark Exp $ + +package org.xml.sax.helpers; + +import java.lang.reflect.Method; +import java.lang.reflect.InvocationTargetException; + +/** + * Create a new instance of a class by name. + * + * <blockquote> + * <em>This module, both source code and documentation, is in the + * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> + * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a> + * for further information. + * </blockquote> + * + * <p>This class contains a static method for creating an instance of a + * class from an explicit class name. It tries to use the thread's context + * ClassLoader if possible and falls back to using + * Class.forName(String).</p> + * + * <p>This code is designed to compile and run on JDK version 1.1 and later + * including versions of Java 2.</p> + * + * @author Edwin Goei, David Brownell + * @version 2.0.1 (sax2r2) + */ +class NewInstance { + + /** + * Creates a new instance of the specified class name + * + * Package private so this code is not exposed at the API level. + */ + static Object newInstance (ClassLoader classLoader, String className) + throws ClassNotFoundException, IllegalAccessException, + InstantiationException + { + Class driverClass; + if (classLoader == null) { + driverClass = Class.forName(className); + } else { + driverClass = classLoader.loadClass(className); + } + return driverClass.newInstance(); + } + + /** + * Figure out which ClassLoader to use. For JDK 1.2 and later use + * the context ClassLoader. + */ + static ClassLoader getClassLoader () + { + Method m = null; + + try { + m = Thread.class.getMethod("getContextClassLoader", null); + } catch (NoSuchMethodException e) { + // Assume that we are running JDK 1.1, use the current ClassLoader + return NewInstance.class.getClassLoader(); + } + + try { + return (ClassLoader) m.invoke(Thread.currentThread(), null); + } catch (IllegalAccessException e) { + // assert(false) + throw new UnknownError(e.getMessage()); + } catch (InvocationTargetException e) { + // assert(e.getTargetException() instanceof SecurityException) + throw new UnknownError(e.getMessage()); + } + } +} diff --git a/libjava/classpath/external/sax/org/xml/sax/helpers/ParserAdapter.java b/libjava/classpath/external/sax/org/xml/sax/helpers/ParserAdapter.java new file mode 100644 index 000000000..cc0695d27 --- /dev/null +++ b/libjava/classpath/external/sax/org/xml/sax/helpers/ParserAdapter.java @@ -0,0 +1,1046 @@ +// ParserAdapter.java - adapt a SAX1 Parser to a SAX2 XMLReader. +// http://www.saxproject.org +// Written by David Megginson +// NO WARRANTY! This class is in the public domain. +// $Id: ParserAdapter.java,v 1.1 2004/12/23 22:38:42 mark Exp $ + +package org.xml.sax.helpers; + +import java.io.IOException; +import java.util.Enumeration; +import java.util.Vector; + +import org.xml.sax.Parser; // deprecated +import org.xml.sax.InputSource; +import org.xml.sax.Locator; +import org.xml.sax.AttributeList; // deprecated +import org.xml.sax.EntityResolver; +import org.xml.sax.DTDHandler; +import org.xml.sax.DocumentHandler; // deprecated +import org.xml.sax.ErrorHandler; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +import org.xml.sax.XMLReader; +import org.xml.sax.Attributes; +import org.xml.sax.ContentHandler; +import org.xml.sax.SAXNotRecognizedException; +import org.xml.sax.SAXNotSupportedException; + + +/** + * Adapt a SAX1 Parser as a SAX2 XMLReader. + * + * <blockquote> + * <em>This module, both source code and documentation, is in the + * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> + * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a> + * for further information. + * </blockquote> + * + * <p>This class wraps a SAX1 {@link org.xml.sax.Parser Parser} + * and makes it act as a SAX2 {@link org.xml.sax.XMLReader XMLReader}, + * with feature, property, and Namespace support. Note + * that it is not possible to report {@link org.xml.sax.ContentHandler#skippedEntity + * skippedEntity} events, since SAX1 does not make that information available.</p> + * + * <p>This adapter does not test for duplicate Namespace-qualified + * attribute names.</p> + * + * @since SAX 2.0 + * @author David Megginson + * @version 2.0.1 (sax2r2) + * @see org.xml.sax.helpers.XMLReaderAdapter + * @see org.xml.sax.XMLReader + * @see org.xml.sax.Parser + */ +public class ParserAdapter implements XMLReader, DocumentHandler +{ + + + //////////////////////////////////////////////////////////////////// + // Constructors. + //////////////////////////////////////////////////////////////////// + + + /** + * Construct a new parser adapter. + * + * <p>Use the "org.xml.sax.parser" property to locate the + * embedded SAX1 driver.</p> + * + * @exception SAXException If the embedded driver + * cannot be instantiated or if the + * org.xml.sax.parser property is not specified. + */ + public ParserAdapter () + throws SAXException + { + super(); + + String driver = System.getProperty("org.xml.sax.parser"); + + try { + setup(ParserFactory.makeParser()); + } catch (ClassNotFoundException e1) { + throw new + SAXException("Cannot find SAX1 driver class " + + driver, e1); + } catch (IllegalAccessException e2) { + throw new + SAXException("SAX1 driver class " + + driver + + " found but cannot be loaded", e2); + } catch (InstantiationException e3) { + throw new + SAXException("SAX1 driver class " + + driver + + " loaded but cannot be instantiated", e3); + } catch (ClassCastException e4) { + throw new + SAXException("SAX1 driver class " + + driver + + " does not implement org.xml.sax.Parser"); + } catch (NullPointerException e5) { + throw new + SAXException("System property org.xml.sax.parser not specified"); + } + } + + + /** + * Construct a new parser adapter. + * + * <p>Note that the embedded parser cannot be changed once the + * adapter is created; to embed a different parser, allocate + * a new ParserAdapter.</p> + * + * @param parser The SAX1 parser to embed. + * @exception java.lang.NullPointerException If the parser parameter + * is null. + */ + public ParserAdapter (Parser parser) + { + super(); + setup(parser); + } + + + /** + * Internal setup method. + * + * @param parser The embedded parser. + * @exception java.lang.NullPointerException If the parser parameter + * is null. + */ + private void setup (Parser parser) + { + if (parser == null) { + throw new + NullPointerException("Parser argument must not be null"); + } + this.parser = parser; + atts = new AttributesImpl(); + nsSupport = new NamespaceSupport(); + attAdapter = new AttributeListAdapter(); + } + + + + //////////////////////////////////////////////////////////////////// + // Implementation of org.xml.sax.XMLReader. + //////////////////////////////////////////////////////////////////// + + + // + // Internal constants for the sake of convenience. + // + private final static String FEATURES = "http://xml.org/sax/features/"; + private final static String NAMESPACES = FEATURES + "namespaces"; + private final static String NAMESPACE_PREFIXES = FEATURES + "namespace-prefixes"; + private final static String XMLNS_URIs = FEATURES + "xmlns-uris"; + + + /** + * Set a feature flag for the parser. + * + * <p>The only features recognized are namespaces and + * namespace-prefixes.</p> + * + * @param name The feature name, as a complete URI. + * @param value The requested feature value. + * @exception SAXNotRecognizedException If the feature + * can't be assigned or retrieved. + * @exception SAXNotSupportedException If the feature + * can't be assigned that value. + * @see org.xml.sax.XMLReader#setFeature + */ + public void setFeature (String name, boolean value) + throws SAXNotRecognizedException, SAXNotSupportedException + { + if (name.equals(NAMESPACES)) { + checkNotParsing("feature", name); + namespaces = value; + if (!namespaces && !prefixes) { + prefixes = true; + } + } else if (name.equals(NAMESPACE_PREFIXES)) { + checkNotParsing("feature", name); + prefixes = value; + if (!prefixes && !namespaces) { + namespaces = true; + } + } else if (name.equals(XMLNS_URIs)) { + checkNotParsing("feature", name); + uris = value; + } else { + throw new SAXNotRecognizedException("Feature: " + name); + } + } + + + /** + * Check a parser feature flag. + * + * <p>The only features recognized are namespaces and + * namespace-prefixes.</p> + * + * @param name The feature name, as a complete URI. + * @return The current feature value. + * @exception SAXNotRecognizedException If the feature + * value can't be assigned or retrieved. + * @exception SAXNotSupportedException If the + * feature is not currently readable. + * @see org.xml.sax.XMLReader#setFeature + */ + public boolean getFeature (String name) + throws SAXNotRecognizedException, SAXNotSupportedException + { + if (name.equals(NAMESPACES)) { + return namespaces; + } else if (name.equals(NAMESPACE_PREFIXES)) { + return prefixes; + } else if (name.equals(XMLNS_URIs)) { + return uris; + } else { + throw new SAXNotRecognizedException("Feature: " + name); + } + } + + + /** + * Set a parser property. + * + * <p>No properties are currently recognized.</p> + * + * @param name The property name. + * @param value The property value. + * @exception SAXNotRecognizedException If the property + * value can't be assigned or retrieved. + * @exception SAXNotSupportedException If the property + * can't be assigned that value. + * @see org.xml.sax.XMLReader#setProperty + */ + public void setProperty (String name, Object value) + throws SAXNotRecognizedException, SAXNotSupportedException + { + throw new SAXNotRecognizedException("Property: " + name); + } + + + /** + * Get a parser property. + * + * <p>No properties are currently recognized.</p> + * + * @param name The property name. + * @return The property value. + * @exception SAXNotRecognizedException If the property + * value can't be assigned or retrieved. + * @exception SAXNotSupportedException If the property + * value is not currently readable. + * @see org.xml.sax.XMLReader#getProperty + */ + public Object getProperty (String name) + throws SAXNotRecognizedException, SAXNotSupportedException + { + throw new SAXNotRecognizedException("Property: " + name); + } + + + /** + * Set the entity resolver. + * + * @param resolver The new entity resolver. + * @see org.xml.sax.XMLReader#setEntityResolver + */ + public void setEntityResolver (EntityResolver resolver) + { + entityResolver = resolver; + } + + + /** + * Return the current entity resolver. + * + * @return The current entity resolver, or null if none was supplied. + * @see org.xml.sax.XMLReader#getEntityResolver + */ + public EntityResolver getEntityResolver () + { + return entityResolver; + } + + + /** + * Set the DTD handler. + * + * @param handler the new DTD handler + * @see org.xml.sax.XMLReader#setEntityResolver + */ + public void setDTDHandler (DTDHandler handler) + { + dtdHandler = handler; + } + + + /** + * Return the current DTD handler. + * + * @return the current DTD handler, or null if none was supplied + * @see org.xml.sax.XMLReader#getEntityResolver + */ + public DTDHandler getDTDHandler () + { + return dtdHandler; + } + + + /** + * Set the content handler. + * + * @param handler the new content handler + * @see org.xml.sax.XMLReader#setEntityResolver + */ + public void setContentHandler (ContentHandler handler) + { + contentHandler = handler; + } + + + /** + * Return the current content handler. + * + * @return The current content handler, or null if none was supplied. + * @see org.xml.sax.XMLReader#getEntityResolver + */ + public ContentHandler getContentHandler () + { + return contentHandler; + } + + + /** + * Set the error handler. + * + * @param handler The new error handler. + * @see org.xml.sax.XMLReader#setEntityResolver + */ + public void setErrorHandler (ErrorHandler handler) + { + errorHandler = handler; + } + + + /** + * Return the current error handler. + * + * @return The current error handler, or null if none was supplied. + * @see org.xml.sax.XMLReader#getEntityResolver + */ + public ErrorHandler getErrorHandler () + { + return errorHandler; + } + + + /** + * Parse an XML document. + * + * @param systemId The absolute URL of the document. + * @exception java.io.IOException If there is a problem reading + * the raw content of the document. + * @exception SAXException If there is a problem + * processing the document. + * @see #parse(org.xml.sax.InputSource) + * @see org.xml.sax.Parser#parse(java.lang.String) + */ + public void parse (String systemId) + throws IOException, SAXException + { + parse(new InputSource(systemId)); + } + + + /** + * Parse an XML document. + * + * @param input An input source for the document. + * @exception java.io.IOException If there is a problem reading + * the raw content of the document. + * @exception SAXException If there is a problem + * processing the document. + * @see #parse(java.lang.String) + * @see org.xml.sax.Parser#parse(org.xml.sax.InputSource) + */ + public void parse (InputSource input) + throws IOException, SAXException + { + if (parsing) { + throw new SAXException("Parser is already in use"); + } + setupParser(); + parsing = true; + try { + parser.parse(input); + } finally { + parsing = false; + } + parsing = false; + } + + + + //////////////////////////////////////////////////////////////////// + // Implementation of org.xml.sax.DocumentHandler. + //////////////////////////////////////////////////////////////////// + + + /** + * Adapter implementation method; do not call. + * Adapt a SAX1 document locator event. + * + * @param locator A document locator. + * @see org.xml.sax.ContentHandler#setDocumentLocator + */ + public void setDocumentLocator (Locator locator) + { + this.locator = locator; + if (contentHandler != null) { + contentHandler.setDocumentLocator(locator); + } + } + + + /** + * Adapter implementation method; do not call. + * Adapt a SAX1 start document event. + * + * @exception SAXException The client may raise a + * processing exception. + * @see org.xml.sax.DocumentHandler#startDocument + */ + public void startDocument () + throws SAXException + { + if (contentHandler != null) { + contentHandler.startDocument(); + } + } + + + /** + * Adapter implementation method; do not call. + * Adapt a SAX1 end document event. + * + * @exception SAXException The client may raise a + * processing exception. + * @see org.xml.sax.DocumentHandler#endDocument + */ + public void endDocument () + throws SAXException + { + if (contentHandler != null) { + contentHandler.endDocument(); + } + } + + + /** + * Adapter implementation method; do not call. + * Adapt a SAX1 startElement event. + * + * <p>If necessary, perform Namespace processing.</p> + * + * @param qName The qualified (prefixed) name. + * @param qAtts The XML attribute list (with qnames). + * @exception SAXException The client may raise a + * processing exception. + */ + public void startElement (String qName, AttributeList qAtts) + throws SAXException + { + // These are exceptions from the + // first pass; they should be + // ignored if there's a second pass, + // but reported otherwise. + Vector exceptions = null; + + // If we're not doing Namespace + // processing, dispatch this quickly. + if (!namespaces) { + if (contentHandler != null) { + attAdapter.setAttributeList(qAtts); + contentHandler.startElement("", "", qName.intern(), + attAdapter); + } + return; + } + + + // OK, we're doing Namespace processing. + nsSupport.pushContext(); + int length = qAtts.getLength(); + + // First pass: handle NS decls + for (int i = 0; i < length; i++) { + String attQName = qAtts.getName(i); + + if (!attQName.startsWith("xmlns")) + continue; + // Could be a declaration... + String prefix; + int n = attQName.indexOf(':'); + + // xmlns=... + if (n == -1 && attQName.length () == 5) { + prefix = ""; + } else if (n != 5) { + // XML namespaces spec doesn't discuss "xmlnsf:oo" + // (and similarly named) attributes ... at most, warn + continue; + } else // xmlns:foo=... + prefix = attQName.substring(n+1); + + String value = qAtts.getValue(i); + if (!nsSupport.declarePrefix(prefix, value)) { + reportError("Illegal Namespace prefix: " + prefix); + continue; + } + if (contentHandler != null) + contentHandler.startPrefixMapping(prefix, value); + } + + // Second pass: copy all relevant + // attributes into the SAX2 AttributeList + // using updated prefix bindings + atts.clear(); + for (int i = 0; i < length; i++) { + String attQName = qAtts.getName(i); + String type = qAtts.getType(i); + String value = qAtts.getValue(i); + + // Declaration? + if (attQName.startsWith("xmlns")) { + String prefix; + int n = attQName.indexOf(':'); + + if (n == -1 && attQName.length () == 5) { + prefix = ""; + } else if (n != 5) { + // XML namespaces spec doesn't discuss "xmlnsf:oo" + // (and similarly named) attributes ... ignore + prefix = null; + } else { + prefix = attQName.substring(6); + } + // Yes, decl: report or prune + if (prefix != null) { + if (prefixes) { + if (uris) + // note funky case: localname can be null + // when declaring the default prefix, and + // yet the uri isn't null. + atts.addAttribute (nsSupport.XMLNS, prefix, + attQName.intern(), type, value); + else + atts.addAttribute ("", "", + attQName.intern(), type, value); + } + continue; + } + } + + // Not a declaration -- report + try { + String attName[] = processName(attQName, true, true); + atts.addAttribute(attName[0], attName[1], attName[2], + type, value); + } catch (SAXException e) { + if (exceptions == null) + exceptions = new Vector(); + exceptions.addElement(e); + atts.addAttribute("", attQName, attQName, type, value); + } + } + + // now handle the deferred exception reports + if (exceptions != null && errorHandler != null) { + for (int i = 0; i < exceptions.size(); i++) + errorHandler.error((SAXParseException) + (exceptions.elementAt(i))); + } + + // OK, finally report the event. + if (contentHandler != null) { + String name[] = processName(qName, false, false); + contentHandler.startElement(name[0], name[1], name[2], atts); + } + } + + + /** + * Adapter implementation method; do not call. + * Adapt a SAX1 end element event. + * + * @param qName The qualified (prefixed) name. + * @exception SAXException The client may raise a + * processing exception. + * @see org.xml.sax.DocumentHandler#endElement + */ + public void endElement (String qName) + throws SAXException + { + // If we're not doing Namespace + // processing, dispatch this quickly. + if (!namespaces) { + if (contentHandler != null) { + contentHandler.endElement("", "", qName.intern()); + } + return; + } + + // Split the name. + String names[] = processName(qName, false, false); + if (contentHandler != null) { + contentHandler.endElement(names[0], names[1], names[2]); + Enumeration prefixes = nsSupport.getDeclaredPrefixes(); + while (prefixes.hasMoreElements()) { + String prefix = (String)prefixes.nextElement(); + contentHandler.endPrefixMapping(prefix); + } + } + nsSupport.popContext(); + } + + + /** + * Adapter implementation method; do not call. + * Adapt a SAX1 characters event. + * + * @param ch An array of characters. + * @param start The starting position in the array. + * @param length The number of characters to use. + * @exception SAXException The client may raise a + * processing exception. + * @see org.xml.sax.DocumentHandler#characters + */ + public void characters (char ch[], int start, int length) + throws SAXException + { + if (contentHandler != null) { + contentHandler.characters(ch, start, length); + } + } + + + /** + * Adapter implementation method; do not call. + * Adapt a SAX1 ignorable whitespace event. + * + * @param ch An array of characters. + * @param start The starting position in the array. + * @param length The number of characters to use. + * @exception SAXException The client may raise a + * processing exception. + * @see org.xml.sax.DocumentHandler#ignorableWhitespace + */ + public void ignorableWhitespace (char ch[], int start, int length) + throws SAXException + { + if (contentHandler != null) { + contentHandler.ignorableWhitespace(ch, start, length); + } + } + + + /** + * Adapter implementation method; do not call. + * Adapt a SAX1 processing instruction event. + * + * @param target The processing instruction target. + * @param data The remainder of the processing instruction + * @exception SAXException The client may raise a + * processing exception. + * @see org.xml.sax.DocumentHandler#processingInstruction + */ + public void processingInstruction (String target, String data) + throws SAXException + { + if (contentHandler != null) { + contentHandler.processingInstruction(target, data); + } + } + + + + //////////////////////////////////////////////////////////////////// + // Internal utility methods. + //////////////////////////////////////////////////////////////////// + + + /** + * Initialize the parser before each run. + */ + private void setupParser () + { + // catch an illegal "nonsense" state. + if (!prefixes && !namespaces) + throw new IllegalStateException (); + + nsSupport.reset(); + if (uris) + nsSupport.setNamespaceDeclUris (true); + + if (entityResolver != null) { + parser.setEntityResolver(entityResolver); + } + if (dtdHandler != null) { + parser.setDTDHandler(dtdHandler); + } + if (errorHandler != null) { + parser.setErrorHandler(errorHandler); + } + parser.setDocumentHandler(this); + locator = null; + } + + + /** + * Process a qualified (prefixed) name. + * + * <p>If the name has an undeclared prefix, use only the qname + * and make an ErrorHandler.error callback in case the app is + * interested.</p> + * + * @param qName The qualified (prefixed) name. + * @param isAttribute true if this is an attribute name. + * @return The name split into three parts. + * @exception SAXException The client may throw + * an exception if there is an error callback. + */ + private String [] processName (String qName, boolean isAttribute, + boolean useException) + throws SAXException + { + String parts[] = nsSupport.processName(qName, nameParts, + isAttribute); + if (parts == null) { + if (useException) + throw makeException("Undeclared prefix: " + qName); + reportError("Undeclared prefix: " + qName); + parts = new String[3]; + parts[0] = parts[1] = ""; + parts[2] = qName.intern(); + } + return parts; + } + + + /** + * Report a non-fatal error. + * + * @param message The error message. + * @exception SAXException The client may throw + * an exception. + */ + void reportError (String message) + throws SAXException + { + if (errorHandler != null) + errorHandler.error(makeException(message)); + } + + + /** + * Construct an exception for the current context. + * + * @param message The error message. + */ + private SAXParseException makeException (String message) + { + if (locator != null) { + return new SAXParseException(message, locator); + } else { + return new SAXParseException(message, null, null, -1, -1); + } + } + + + /** + * Throw an exception if we are parsing. + * + * <p>Use this method to detect illegal feature or + * property changes.</p> + * + * @param type The type of thing (feature or property). + * @param name The feature or property name. + * @exception SAXNotSupportedException If a + * document is currently being parsed. + */ + private void checkNotParsing (String type, String name) + throws SAXNotSupportedException + { + if (parsing) { + throw new SAXNotSupportedException("Cannot change " + + type + ' ' + + name + " while parsing"); + + } + } + + + + //////////////////////////////////////////////////////////////////// + // Internal state. + //////////////////////////////////////////////////////////////////// + + private NamespaceSupport nsSupport; + private AttributeListAdapter attAdapter; + + private boolean parsing = false; + private String nameParts[] = new String[3]; + + private Parser parser = null; + + private AttributesImpl atts = null; + + // Features + private boolean namespaces = true; + private boolean prefixes = false; + private boolean uris = false; + + // Properties + + // Handlers + Locator locator; + + EntityResolver entityResolver = null; + DTDHandler dtdHandler = null; + ContentHandler contentHandler = null; + ErrorHandler errorHandler = null; + + + + //////////////////////////////////////////////////////////////////// + // Inner class to wrap an AttributeList when not doing NS proc. + //////////////////////////////////////////////////////////////////// + + + /** + * Adapt a SAX1 AttributeList as a SAX2 Attributes object. + * + * <p>This class is in the Public Domain, and comes with NO + * WARRANTY of any kind.</p> + * + * <p>This wrapper class is used only when Namespace support + * is disabled -- it provides pretty much a direct mapping + * from SAX1 to SAX2, except that names and types are + * interned whenever requested.</p> + */ + final class AttributeListAdapter implements Attributes + { + + /** + * Construct a new adapter. + */ + AttributeListAdapter () + { + } + + + /** + * Set the embedded AttributeList. + * + * <p>This method must be invoked before any of the others + * can be used.</p> + * + * @param The SAX1 attribute list (with qnames). + */ + void setAttributeList (AttributeList qAtts) + { + this.qAtts = qAtts; + } + + + /** + * Return the length of the attribute list. + * + * @return The number of attributes in the list. + * @see org.xml.sax.Attributes#getLength + */ + public int getLength () + { + return qAtts.getLength(); + } + + + /** + * Return the Namespace URI of the specified attribute. + * + * @param The attribute's index. + * @return Always the empty string. + * @see org.xml.sax.Attributes#getURI + */ + public String getURI (int i) + { + return ""; + } + + + /** + * Return the local name of the specified attribute. + * + * @param The attribute's index. + * @return Always the empty string. + * @see org.xml.sax.Attributes#getLocalName + */ + public String getLocalName (int i) + { + return ""; + } + + + /** + * Return the qualified (prefixed) name of the specified attribute. + * + * @param The attribute's index. + * @return The attribute's qualified name, internalized. + */ + public String getQName (int i) + { + return qAtts.getName(i).intern(); + } + + + /** + * Return the type of the specified attribute. + * + * @param The attribute's index. + * @return The attribute's type as an internalized string. + */ + public String getType (int i) + { + return qAtts.getType(i).intern(); + } + + + /** + * Return the value of the specified attribute. + * + * @param The attribute's index. + * @return The attribute's value. + */ + public String getValue (int i) + { + return qAtts.getValue(i); + } + + + /** + * Look up an attribute index by Namespace name. + * + * @param uri The Namespace URI or the empty string. + * @param localName The local name. + * @return The attributes index, or -1 if none was found. + * @see org.xml.sax.Attributes#getIndex(java.lang.String,java.lang.String) + */ + public int getIndex (String uri, String localName) + { + return -1; + } + + + /** + * Look up an attribute index by qualified (prefixed) name. + * + * @param qName The qualified name. + * @return The attributes index, or -1 if none was found. + * @see org.xml.sax.Attributes#getIndex(java.lang.String) + */ + public int getIndex (String qName) + { + int max = atts.getLength(); + for (int i = 0; i < max; i++) { + if (qAtts.getName(i).equals(qName)) { + return i; + } + } + return -1; + } + + + /** + * Look up the type of an attribute by Namespace name. + * + * @param uri The Namespace URI + * @param localName The local name. + * @return The attribute's type as an internalized string. + */ + public String getType (String uri, String localName) + { + return null; + } + + + /** + * Look up the type of an attribute by qualified (prefixed) name. + * + * @param qName The qualified name. + * @return The attribute's type as an internalized string. + */ + public String getType (String qName) + { + return qAtts.getType(qName).intern(); + } + + + /** + * Look up the value of an attribute by Namespace name. + * + * @param uri The Namespace URI + * @param localName The local name. + * @return The attribute's value. + */ + public String getValue (String uri, String localName) + { + return null; + } + + + /** + * Look up the value of an attribute by qualified (prefixed) name. + * + * @param qName The qualified name. + * @return The attribute's value. + */ + public String getValue (String qName) + { + return qAtts.getValue(qName); + } + + private AttributeList qAtts; + } +} + +// end of ParserAdapter.java diff --git a/libjava/classpath/external/sax/org/xml/sax/helpers/ParserFactory.java b/libjava/classpath/external/sax/org/xml/sax/helpers/ParserFactory.java new file mode 100644 index 000000000..ec822b540 --- /dev/null +++ b/libjava/classpath/external/sax/org/xml/sax/helpers/ParserFactory.java @@ -0,0 +1,128 @@ +// SAX parser factory. +// http://www.saxproject.org +// No warranty; no copyright -- use this as you will. +// $Id: ParserFactory.java,v 1.1 2004/12/23 22:38:42 mark Exp $ + +package org.xml.sax.helpers; + +import java.lang.ClassNotFoundException; +import java.lang.IllegalAccessException; +import java.lang.InstantiationException; +import java.lang.SecurityException; +import java.lang.ClassCastException; + +import org.xml.sax.Parser; + + +/** + * Java-specific class for dynamically loading SAX parsers. + * + * <blockquote> + * <em>This module, both source code and documentation, is in the + * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> + * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a> + * for further information. + * </blockquote> + * + * <p><strong>Note:</strong> This class is designed to work with the now-deprecated + * SAX1 {@link org.xml.sax.Parser Parser} class. SAX2 applications should use + * {@link org.xml.sax.helpers.XMLReaderFactory XMLReaderFactory} instead.</p> + * + * <p>ParserFactory is not part of the platform-independent definition + * of SAX; it is an additional convenience class designed + * specifically for Java XML application writers. SAX applications + * can use the static methods in this class to allocate a SAX parser + * dynamically at run-time based either on the value of the + * `org.xml.sax.parser' system property or on a string containing the class + * name.</p> + * + * <p>Note that the application still requires an XML parser that + * implements SAX1.</p> + * + * @deprecated This class works with the deprecated + * {@link org.xml.sax.Parser Parser} + * interface. + * @since SAX 1.0 + * @author David Megginson + * @version 2.0.1 (sax2r2) + */ +public class ParserFactory { + + + /** + * Private null constructor. + */ + private ParserFactory () + { + } + + + /** + * Create a new SAX parser using the `org.xml.sax.parser' system property. + * + * <p>The named class must exist and must implement the + * {@link org.xml.sax.Parser Parser} interface.</p> + * + * @exception java.lang.NullPointerException There is no value + * for the `org.xml.sax.parser' system property. + * @exception java.lang.ClassNotFoundException The SAX parser + * class was not found (check your CLASSPATH). + * @exception IllegalAccessException The SAX parser class was + * found, but you do not have permission to load + * it. + * @exception InstantiationException The SAX parser class was + * found but could not be instantiated. + * @exception java.lang.ClassCastException The SAX parser class + * was found and instantiated, but does not implement + * org.xml.sax.Parser. + * @see #makeParser(java.lang.String) + * @see org.xml.sax.Parser + */ + public static Parser makeParser () + throws ClassNotFoundException, + IllegalAccessException, + InstantiationException, + NullPointerException, + ClassCastException + { + String className = System.getProperty("org.xml.sax.parser"); + if (className == null) { + throw new NullPointerException("No value for sax.parser property"); + } else { + return makeParser(className); + } + } + + + /** + * Create a new SAX parser object using the class name provided. + * + * <p>The named class must exist and must implement the + * {@link org.xml.sax.Parser Parser} interface.</p> + * + * @param className A string containing the name of the + * SAX parser class. + * @exception java.lang.ClassNotFoundException The SAX parser + * class was not found (check your CLASSPATH). + * @exception IllegalAccessException The SAX parser class was + * found, but you do not have permission to load + * it. + * @exception InstantiationException The SAX parser class was + * found but could not be instantiated. + * @exception java.lang.ClassCastException The SAX parser class + * was found and instantiated, but does not implement + * org.xml.sax.Parser. + * @see #makeParser() + * @see org.xml.sax.Parser + */ + public static Parser makeParser (String className) + throws ClassNotFoundException, + IllegalAccessException, + InstantiationException, + ClassCastException + { + return (Parser) NewInstance.newInstance ( + NewInstance.getClassLoader (), className); + } + +} diff --git a/libjava/classpath/external/sax/org/xml/sax/helpers/XMLFilterImpl.java b/libjava/classpath/external/sax/org/xml/sax/helpers/XMLFilterImpl.java new file mode 100644 index 000000000..4b4aba092 --- /dev/null +++ b/libjava/classpath/external/sax/org/xml/sax/helpers/XMLFilterImpl.java @@ -0,0 +1,713 @@ +// XMLFilterImpl.java - base SAX2 filter implementation. +// http://www.saxproject.org +// Written by David Megginson +// NO WARRANTY! This class is in the Public Domain. +// $Id: XMLFilterImpl.java,v 1.1 2004/12/23 22:38:42 mark Exp $ + +package org.xml.sax.helpers; + +import java.io.IOException; + +import org.xml.sax.XMLReader; +import org.xml.sax.XMLFilter; +import org.xml.sax.InputSource; +import org.xml.sax.Locator; +import org.xml.sax.Attributes; +import org.xml.sax.EntityResolver; +import org.xml.sax.DTDHandler; +import org.xml.sax.ContentHandler; +import org.xml.sax.ErrorHandler; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; +import org.xml.sax.SAXNotSupportedException; +import org.xml.sax.SAXNotRecognizedException; + + +/** + * Base class for deriving an XML filter. + * + * <blockquote> + * <em>This module, both source code and documentation, is in the + * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> + * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a> + * for further information. + * </blockquote> + * + * <p>This class is designed to sit between an {@link org.xml.sax.XMLReader + * XMLReader} and the client application's event handlers. By default, it + * does nothing but pass requests up to the reader and events + * on to the handlers unmodified, but subclasses can override + * specific methods to modify the event stream or the configuration + * requests as they pass through.</p> + * + * @since SAX 2.0 + * @author David Megginson + * @version 2.0.1 (sax2r2) + * @see org.xml.sax.XMLFilter + * @see org.xml.sax.XMLReader + * @see org.xml.sax.EntityResolver + * @see org.xml.sax.DTDHandler + * @see org.xml.sax.ContentHandler + * @see org.xml.sax.ErrorHandler + */ +public class XMLFilterImpl + implements XMLFilter, EntityResolver, DTDHandler, ContentHandler, ErrorHandler +{ + + + //////////////////////////////////////////////////////////////////// + // Constructors. + //////////////////////////////////////////////////////////////////// + + + /** + * Construct an empty XML filter, with no parent. + * + * <p>This filter will have no parent: you must assign a parent + * before you start a parse or do any configuration with + * setFeature or setProperty, unless you use this as a pure event + * consumer rather than as an {@link XMLReader}.</p> + * + * @see org.xml.sax.XMLReader#setFeature + * @see org.xml.sax.XMLReader#setProperty + * @see #setParent + */ + public XMLFilterImpl () + { + super(); + } + + + /** + * Construct an XML filter with the specified parent. + * + * @see #setParent + * @see #getParent + */ + public XMLFilterImpl (XMLReader parent) + { + super(); + setParent(parent); + } + + + + //////////////////////////////////////////////////////////////////// + // Implementation of org.xml.sax.XMLFilter. + //////////////////////////////////////////////////////////////////// + + + /** + * Set the parent reader. + * + * <p>This is the {@link org.xml.sax.XMLReader XMLReader} from which + * this filter will obtain its events and to which it will pass its + * configuration requests. The parent may itself be another filter.</p> + * + * <p>If there is no parent reader set, any attempt to parse + * or to set or get a feature or property will fail.</p> + * + * @param parent The parent XML reader. + * @see #getParent + */ + public void setParent (XMLReader parent) + { + this.parent = parent; + } + + + /** + * Get the parent reader. + * + * @return The parent XML reader, or null if none is set. + * @see #setParent + */ + public XMLReader getParent () + { + return parent; + } + + + + //////////////////////////////////////////////////////////////////// + // Implementation of org.xml.sax.XMLReader. + //////////////////////////////////////////////////////////////////// + + + /** + * Set the value of a feature. + * + * <p>This will always fail if the parent is null.</p> + * + * @param name The feature name. + * @param value The requested feature value. + * @exception org.xml.sax.SAXNotRecognizedException If the feature + * value can't be assigned or retrieved from the parent. + * @exception org.xml.sax.SAXNotSupportedException When the + * parent recognizes the feature name but + * cannot set the requested value. + */ + public void setFeature (String name, boolean value) + throws SAXNotRecognizedException, SAXNotSupportedException + { + if (parent != null) { + parent.setFeature(name, value); + } else { + throw new SAXNotRecognizedException("Feature: " + name); + } + } + + + /** + * Look up the value of a feature. + * + * <p>This will always fail if the parent is null.</p> + * + * @param name The feature name. + * @return The current value of the feature. + * @exception org.xml.sax.SAXNotRecognizedException If the feature + * value can't be assigned or retrieved from the parent. + * @exception org.xml.sax.SAXNotSupportedException When the + * parent recognizes the feature name but + * cannot determine its value at this time. + */ + public boolean getFeature (String name) + throws SAXNotRecognizedException, SAXNotSupportedException + { + if (parent != null) { + return parent.getFeature(name); + } else { + throw new SAXNotRecognizedException("Feature: " + name); + } + } + + + /** + * Set the value of a property. + * + * <p>This will always fail if the parent is null.</p> + * + * @param name The property name. + * @param value The requested property value. + * @exception org.xml.sax.SAXNotRecognizedException If the property + * value can't be assigned or retrieved from the parent. + * @exception org.xml.sax.SAXNotSupportedException When the + * parent recognizes the property name but + * cannot set the requested value. + */ + public void setProperty (String name, Object value) + throws SAXNotRecognizedException, SAXNotSupportedException + { + if (parent != null) { + parent.setProperty(name, value); + } else { + throw new SAXNotRecognizedException("Property: " + name); + } + } + + + /** + * Look up the value of a property. + * + * @param name The property name. + * @return The current value of the property. + * @exception org.xml.sax.SAXNotRecognizedException If the property + * value can't be assigned or retrieved from the parent. + * @exception org.xml.sax.SAXNotSupportedException When the + * parent recognizes the property name but + * cannot determine its value at this time. + */ + public Object getProperty (String name) + throws SAXNotRecognizedException, SAXNotSupportedException + { + if (parent != null) { + return parent.getProperty(name); + } else { + throw new SAXNotRecognizedException("Property: " + name); + } + } + + + /** + * Set the entity resolver. + * + * @param resolver The new entity resolver. + */ + public void setEntityResolver (EntityResolver resolver) + { + entityResolver = resolver; + } + + + /** + * Get the current entity resolver. + * + * @return The current entity resolver, or null if none was set. + */ + public EntityResolver getEntityResolver () + { + return entityResolver; + } + + + /** + * Set the DTD event handler. + * + * @param handler the new DTD handler + */ + public void setDTDHandler (DTDHandler handler) + { + dtdHandler = handler; + } + + + /** + * Get the current DTD event handler. + * + * @return The current DTD handler, or null if none was set. + */ + public DTDHandler getDTDHandler () + { + return dtdHandler; + } + + + /** + * Set the content event handler. + * + * @param handler the new content handler + */ + public void setContentHandler (ContentHandler handler) + { + contentHandler = handler; + } + + + /** + * Get the content event handler. + * + * @return The current content handler, or null if none was set. + */ + public ContentHandler getContentHandler () + { + return contentHandler; + } + + + /** + * Set the error event handler. + * + * @param handler the new error handler + */ + public void setErrorHandler (ErrorHandler handler) + { + errorHandler = handler; + } + + + /** + * Get the current error event handler. + * + * @return The current error handler, or null if none was set. + */ + public ErrorHandler getErrorHandler () + { + return errorHandler; + } + + + /** + * Parse a document. + * + * @param input The input source for the document entity. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + * @exception java.io.IOException An IO exception from the parser, + * possibly from a byte stream or character stream + * supplied by the application. + */ + public void parse (InputSource input) + throws SAXException, IOException + { + setupParse(); + parent.parse(input); + } + + + /** + * Parse a document. + * + * @param systemId The system identifier as a fully-qualified URI. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + * @exception java.io.IOException An IO exception from the parser, + * possibly from a byte stream or character stream + * supplied by the application. + */ + public void parse (String systemId) + throws SAXException, IOException + { + parse(new InputSource(systemId)); + } + + + + //////////////////////////////////////////////////////////////////// + // Implementation of org.xml.sax.EntityResolver. + //////////////////////////////////////////////////////////////////// + + + /** + * Filter an external entity resolution. + * + * @param publicId The entity's public identifier, or null. + * @param systemId The entity's system identifier. + * @return A new InputSource or null for the default. + * @exception org.xml.sax.SAXException The client may throw + * an exception during processing. + * @exception java.io.IOException The client may throw an + * I/O-related exception while obtaining the + * new InputSource. + */ + public InputSource resolveEntity (String publicId, String systemId) + throws SAXException, IOException + { + if (entityResolver != null) { + return entityResolver.resolveEntity(publicId, systemId); + } else { + return null; + } + } + + + + //////////////////////////////////////////////////////////////////// + // Implementation of org.xml.sax.DTDHandler. + //////////////////////////////////////////////////////////////////// + + + /** + * Filter a notation declaration event. + * + * @param name The notation name. + * @param publicId The notation's public identifier, or null. + * @param systemId The notation's system identifier, or null. + * @exception org.xml.sax.SAXException The client may throw + * an exception during processing. + */ + public void notationDecl (String name, String publicId, String systemId) + throws SAXException + { + if (dtdHandler != null) { + dtdHandler.notationDecl(name, publicId, systemId); + } + } + + + /** + * Filter an unparsed entity declaration event. + * + * @param name The entity name. + * @param publicId The entity's public identifier, or null. + * @param systemId The entity's system identifier, or null. + * @param notationName The name of the associated notation. + * @exception org.xml.sax.SAXException The client may throw + * an exception during processing. + */ + public void unparsedEntityDecl (String name, String publicId, + String systemId, String notationName) + throws SAXException + { + if (dtdHandler != null) { + dtdHandler.unparsedEntityDecl(name, publicId, systemId, + notationName); + } + } + + + + //////////////////////////////////////////////////////////////////// + // Implementation of org.xml.sax.ContentHandler. + //////////////////////////////////////////////////////////////////// + + + /** + * Filter a new document locator event. + * + * @param locator The document locator. + */ + public void setDocumentLocator (Locator locator) + { + this.locator = locator; + if (contentHandler != null) { + contentHandler.setDocumentLocator(locator); + } + } + + + /** + * Filter a start document event. + * + * @exception org.xml.sax.SAXException The client may throw + * an exception during processing. + */ + public void startDocument () + throws SAXException + { + if (contentHandler != null) { + contentHandler.startDocument(); + } + } + + + /** + * Filter an end document event. + * + * @exception org.xml.sax.SAXException The client may throw + * an exception during processing. + */ + public void endDocument () + throws SAXException + { + if (contentHandler != null) { + contentHandler.endDocument(); + } + } + + + /** + * Filter a start Namespace prefix mapping event. + * + * @param prefix The Namespace prefix. + * @param uri The Namespace URI. + * @exception org.xml.sax.SAXException The client may throw + * an exception during processing. + */ + public void startPrefixMapping (String prefix, String uri) + throws SAXException + { + if (contentHandler != null) { + contentHandler.startPrefixMapping(prefix, uri); + } + } + + + /** + * Filter an end Namespace prefix mapping event. + * + * @param prefix The Namespace prefix. + * @exception org.xml.sax.SAXException The client may throw + * an exception during processing. + */ + public void endPrefixMapping (String prefix) + throws SAXException + { + if (contentHandler != null) { + contentHandler.endPrefixMapping(prefix); + } + } + + + /** + * Filter a start element event. + * + * @param uri The element's Namespace URI, or the empty string. + * @param localName The element's local name, or the empty string. + * @param qName The element's qualified (prefixed) name, or the empty + * string. + * @param atts The element's attributes. + * @exception org.xml.sax.SAXException The client may throw + * an exception during processing. + */ + public void startElement (String uri, String localName, String qName, + Attributes atts) + throws SAXException + { + if (contentHandler != null) { + contentHandler.startElement(uri, localName, qName, atts); + } + } + + + /** + * Filter an end element event. + * + * @param uri The element's Namespace URI, or the empty string. + * @param localName The element's local name, or the empty string. + * @param qName The element's qualified (prefixed) name, or the empty + * string. + * @exception org.xml.sax.SAXException The client may throw + * an exception during processing. + */ + public void endElement (String uri, String localName, String qName) + throws SAXException + { + if (contentHandler != null) { + contentHandler.endElement(uri, localName, qName); + } + } + + + /** + * Filter a character data event. + * + * @param ch An array of characters. + * @param start The starting position in the array. + * @param length The number of characters to use from the array. + * @exception org.xml.sax.SAXException The client may throw + * an exception during processing. + */ + public void characters (char ch[], int start, int length) + throws SAXException + { + if (contentHandler != null) { + contentHandler.characters(ch, start, length); + } + } + + + /** + * Filter an ignorable whitespace event. + * + * @param ch An array of characters. + * @param start The starting position in the array. + * @param length The number of characters to use from the array. + * @exception org.xml.sax.SAXException The client may throw + * an exception during processing. + */ + public void ignorableWhitespace (char ch[], int start, int length) + throws SAXException + { + if (contentHandler != null) { + contentHandler.ignorableWhitespace(ch, start, length); + } + } + + + /** + * Filter a processing instruction event. + * + * @param target The processing instruction target. + * @param data The text following the target. + * @exception org.xml.sax.SAXException The client may throw + * an exception during processing. + */ + public void processingInstruction (String target, String data) + throws SAXException + { + if (contentHandler != null) { + contentHandler.processingInstruction(target, data); + } + } + + + /** + * Filter a skipped entity event. + * + * @param name The name of the skipped entity. + * @exception org.xml.sax.SAXException The client may throw + * an exception during processing. + */ + public void skippedEntity (String name) + throws SAXException + { + if (contentHandler != null) { + contentHandler.skippedEntity(name); + } + } + + + + //////////////////////////////////////////////////////////////////// + // Implementation of org.xml.sax.ErrorHandler. + //////////////////////////////////////////////////////////////////// + + + /** + * Filter a warning event. + * + * @param e The warning as an exception. + * @exception org.xml.sax.SAXException The client may throw + * an exception during processing. + */ + public void warning (SAXParseException e) + throws SAXException + { + if (errorHandler != null) { + errorHandler.warning(e); + } + } + + + /** + * Filter an error event. + * + * @param e The error as an exception. + * @exception org.xml.sax.SAXException The client may throw + * an exception during processing. + */ + public void error (SAXParseException e) + throws SAXException + { + if (errorHandler != null) { + errorHandler.error(e); + } + } + + + /** + * Filter a fatal error event. + * + * @param e The error as an exception. + * @exception org.xml.sax.SAXException The client may throw + * an exception during processing. + */ + public void fatalError (SAXParseException e) + throws SAXException + { + if (errorHandler != null) { + errorHandler.fatalError(e); + } + } + + + + //////////////////////////////////////////////////////////////////// + // Internal methods. + //////////////////////////////////////////////////////////////////// + + + /** + * Set up before a parse. + * + * <p>Before every parse, check whether the parent is + * non-null, and re-register the filter for all of the + * events.</p> + */ + private void setupParse () + { + if (parent == null) { + throw new NullPointerException("No parent for filter"); + } + parent.setEntityResolver(this); + parent.setDTDHandler(this); + parent.setContentHandler(this); + parent.setErrorHandler(this); + } + + + + //////////////////////////////////////////////////////////////////// + // Internal state. + //////////////////////////////////////////////////////////////////// + + private XMLReader parent = null; + private Locator locator = null; + private EntityResolver entityResolver = null; + private DTDHandler dtdHandler = null; + private ContentHandler contentHandler = null; + private ErrorHandler errorHandler = null; + +} + +// end of XMLFilterImpl.java diff --git a/libjava/classpath/external/sax/org/xml/sax/helpers/XMLReaderAdapter.java b/libjava/classpath/external/sax/org/xml/sax/helpers/XMLReaderAdapter.java new file mode 100644 index 000000000..8ab909a77 --- /dev/null +++ b/libjava/classpath/external/sax/org/xml/sax/helpers/XMLReaderAdapter.java @@ -0,0 +1,538 @@ +// XMLReaderAdapter.java - adapt an SAX2 XMLReader to a SAX1 Parser +// http://www.saxproject.org +// Written by David Megginson +// NO WARRANTY! This class is in the public domain. +// $Id: XMLReaderAdapter.java,v 1.2 2006/12/10 20:25:41 gnu_andrew Exp $ + +package org.xml.sax.helpers; + +import java.io.IOException; +import java.util.Locale; + +import org.xml.sax.Parser; // deprecated +import org.xml.sax.Locator; +import org.xml.sax.InputSource; +import org.xml.sax.AttributeList; // deprecated +import org.xml.sax.EntityResolver; +import org.xml.sax.DTDHandler; +import org.xml.sax.DocumentHandler; // deprecated +import org.xml.sax.ErrorHandler; +import org.xml.sax.SAXException; + +import org.xml.sax.XMLReader; +import org.xml.sax.Attributes; +import org.xml.sax.ContentHandler; +import org.xml.sax.SAXNotSupportedException; + + +/** + * Adapt a SAX2 XMLReader as a SAX1 Parser. + * + * <blockquote> + * <em>This module, both source code and documentation, is in the + * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> + * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a> + * for further information. + * </blockquote> + * + * <p>This class wraps a SAX2 {@link org.xml.sax.XMLReader XMLReader} + * and makes it act as a SAX1 {@link org.xml.sax.Parser Parser}. The XMLReader + * must support a true value for the + * http://xml.org/sax/features/namespace-prefixes property or parsing will fail + * with a {@link org.xml.sax.SAXException SAXException}; if the XMLReader + * supports a false value for the http://xml.org/sax/features/namespaces + * property, that will also be used to improve efficiency.</p> + * + * @since SAX 2.0 + * @author David Megginson + * @version 2.0.1 (sax2r2) + * @see org.xml.sax.Parser + * @see org.xml.sax.XMLReader + */ +public class XMLReaderAdapter implements Parser, ContentHandler +{ + + + //////////////////////////////////////////////////////////////////// + // Constructor. + //////////////////////////////////////////////////////////////////// + + + /** + * Create a new adapter. + * + * <p>Use the "org.xml.sax.driver" property to locate the SAX2 + * driver to embed.</p> + * + * @exception org.xml.sax.SAXException If the embedded driver + * cannot be instantiated or if the + * org.xml.sax.driver property is not specified. + */ + public XMLReaderAdapter () + throws SAXException + { + setup(XMLReaderFactory.createXMLReader()); + } + + + /** + * Create a new adapter. + * + * <p>Create a new adapter, wrapped around a SAX2 XMLReader. + * The adapter will make the XMLReader act like a SAX1 + * Parser.</p> + * + * @param xmlReader The SAX2 XMLReader to wrap. + * @exception java.lang.NullPointerException If the argument is null. + */ + public XMLReaderAdapter (XMLReader xmlReader) + { + setup(xmlReader); + } + + + + /** + * Internal setup. + * + * @param xmlReader The embedded XMLReader. + */ + private void setup (XMLReader xmlReader) + { + if (xmlReader == null) { + throw new NullPointerException("XMLReader must not be null"); + } + this.xmlReader = xmlReader; + qAtts = new AttributesAdapter(); + } + + + + //////////////////////////////////////////////////////////////////// + // Implementation of org.xml.sax.Parser. + //////////////////////////////////////////////////////////////////// + + + /** + * Set the locale for error reporting. + * + * <p>This is not supported in SAX2, and will always throw + * an exception.</p> + * + * @param locale the locale for error reporting. + * @see org.xml.sax.Parser#setLocale + * @exception org.xml.sax.SAXException Thrown unless overridden. + */ + public void setLocale (Locale locale) + throws SAXException + { + throw new SAXNotSupportedException("setLocale not supported"); + } + + + /** + * Register the entity resolver. + * + * @param resolver The new resolver. + * @see org.xml.sax.Parser#setEntityResolver + */ + public void setEntityResolver (EntityResolver resolver) + { + xmlReader.setEntityResolver(resolver); + } + + + /** + * Register the DTD event handler. + * + * @param handler The new DTD event handler. + * @see org.xml.sax.Parser#setDTDHandler + */ + public void setDTDHandler (DTDHandler handler) + { + xmlReader.setDTDHandler(handler); + } + + + /** + * Register the SAX1 document event handler. + * + * <p>Note that the SAX1 document handler has no Namespace + * support.</p> + * + * @param handler The new SAX1 document event handler. + * @see org.xml.sax.Parser#setDocumentHandler + */ + public void setDocumentHandler (DocumentHandler handler) + { + documentHandler = handler; + } + + + /** + * Register the error event handler. + * + * @param handler The new error event handler. + * @see org.xml.sax.Parser#setErrorHandler + */ + public void setErrorHandler (ErrorHandler handler) + { + xmlReader.setErrorHandler(handler); + } + + + /** + * Parse the document. + * + * <p>This method will throw an exception if the embedded + * XMLReader does not support the + * http://xml.org/sax/features/namespace-prefixes property.</p> + * + * @param systemId The absolute URL of the document. + * @exception java.io.IOException If there is a problem reading + * the raw content of the document. + * @exception org.xml.sax.SAXException If there is a problem + * processing the document. + * @see #parse(org.xml.sax.InputSource) + * @see org.xml.sax.Parser#parse(java.lang.String) + */ + public void parse (String systemId) + throws IOException, SAXException + { + parse(new InputSource(systemId)); + } + + + /** + * Parse the document. + * + * <p>This method will throw an exception if the embedded + * XMLReader does not support the + * http://xml.org/sax/features/namespace-prefixes property.</p> + * + * @param input An input source for the document. + * @exception java.io.IOException If there is a problem reading + * the raw content of the document. + * @exception org.xml.sax.SAXException If there is a problem + * processing the document. + * @see #parse(java.lang.String) + * @see org.xml.sax.Parser#parse(org.xml.sax.InputSource) + */ + public void parse (InputSource input) + throws IOException, SAXException + { + setupXMLReader(); + xmlReader.parse(input); + } + + + /** + * Set up the XML reader. + */ + private void setupXMLReader () + throws SAXException + { + xmlReader.setFeature("http://xml.org/sax/features/namespace-prefixes", true); + try { + xmlReader.setFeature("http://xml.org/sax/features/namespaces", + false); + } catch (SAXException e) { + // NO OP: it's just extra information, and we can ignore it + } + xmlReader.setContentHandler(this); + } + + + + //////////////////////////////////////////////////////////////////// + // Implementation of org.xml.sax.ContentHandler. + //////////////////////////////////////////////////////////////////// + + + /** + * Set a document locator. + * + * @param locator The document locator. + * @see org.xml.sax.ContentHandler#setDocumentLocator + */ + public void setDocumentLocator (Locator locator) + { + if (documentHandler != null) + documentHandler.setDocumentLocator(locator); + } + + + /** + * Start document event. + * + * @exception org.xml.sax.SAXException The client may raise a + * processing exception. + * @see org.xml.sax.ContentHandler#startDocument + */ + public void startDocument () + throws SAXException + { + if (documentHandler != null) + documentHandler.startDocument(); + } + + + /** + * End document event. + * + * @exception org.xml.sax.SAXException The client may raise a + * processing exception. + * @see org.xml.sax.ContentHandler#endDocument + */ + public void endDocument () + throws SAXException + { + if (documentHandler != null) + documentHandler.endDocument(); + } + + + /** + * Adapt a SAX2 start prefix mapping event. + * + * @param prefix The prefix being mapped. + * @param uri The Namespace URI being mapped to. + * @see org.xml.sax.ContentHandler#startPrefixMapping + */ + public void startPrefixMapping (String prefix, String uri) + { + } + + + /** + * Adapt a SAX2 end prefix mapping event. + * + * @param prefix The prefix being mapped. + * @see org.xml.sax.ContentHandler#endPrefixMapping + */ + public void endPrefixMapping (String prefix) + { + } + + + /** + * Adapt a SAX2 start element event. + * + * @param uri The Namespace URI. + * @param localName The Namespace local name. + * @param qName The qualified (prefixed) name. + * @param atts The SAX2 attributes. + * @exception org.xml.sax.SAXException The client may raise a + * processing exception. + * @see org.xml.sax.ContentHandler#endDocument + */ + public void startElement (String uri, String localName, + String qName, Attributes atts) + throws SAXException + { + if (documentHandler != null) { + qAtts.setAttributes(atts); + documentHandler.startElement(qName, qAtts); + } + } + + + /** + * Adapt a SAX2 end element event. + * + * @param uri The Namespace URI. + * @param localName The Namespace local name. + * @param qName The qualified (prefixed) name. + * @exception org.xml.sax.SAXException The client may raise a + * processing exception. + * @see org.xml.sax.ContentHandler#endElement + */ + public void endElement (String uri, String localName, + String qName) + throws SAXException + { + if (documentHandler != null) + documentHandler.endElement(qName); + } + + + /** + * Adapt a SAX2 characters event. + * + * @param ch An array of characters. + * @param start The starting position in the array. + * @param length The number of characters to use. + * @exception org.xml.sax.SAXException The client may raise a + * processing exception. + * @see org.xml.sax.ContentHandler#characters + */ + public void characters (char ch[], int start, int length) + throws SAXException + { + if (documentHandler != null) + documentHandler.characters(ch, start, length); + } + + + /** + * Adapt a SAX2 ignorable whitespace event. + * + * @param ch An array of characters. + * @param start The starting position in the array. + * @param length The number of characters to use. + * @exception org.xml.sax.SAXException The client may raise a + * processing exception. + * @see org.xml.sax.ContentHandler#ignorableWhitespace + */ + public void ignorableWhitespace (char ch[], int start, int length) + throws SAXException + { + if (documentHandler != null) + documentHandler.ignorableWhitespace(ch, start, length); + } + + + /** + * Adapt a SAX2 processing instruction event. + * + * @param target The processing instruction target. + * @param data The remainder of the processing instruction + * @exception org.xml.sax.SAXException The client may raise a + * processing exception. + * @see org.xml.sax.ContentHandler#processingInstruction + */ + public void processingInstruction (String target, String data) + throws SAXException + { + if (documentHandler != null) + documentHandler.processingInstruction(target, data); + } + + + /** + * Adapt a SAX2 skipped entity event. + * + * @param name The name of the skipped entity. + * @see org.xml.sax.ContentHandler#skippedEntity + * @exception org.xml.sax.SAXException Throwable by subclasses. + */ + public void skippedEntity (String name) + throws SAXException + { + } + + + + //////////////////////////////////////////////////////////////////// + // Internal state. + //////////////////////////////////////////////////////////////////// + + XMLReader xmlReader; + DocumentHandler documentHandler; + AttributesAdapter qAtts; + + + + //////////////////////////////////////////////////////////////////// + // Internal class. + //////////////////////////////////////////////////////////////////// + + + /** + * Internal class to wrap a SAX2 Attributes object for SAX1. + */ + final class AttributesAdapter implements AttributeList + { + AttributesAdapter () + { + } + + + /** + * Set the embedded Attributes object. + * + * @param The embedded SAX2 Attributes. + */ + void setAttributes (Attributes attributes) + { + this.attributes = attributes; + } + + + /** + * Return the number of attributes. + * + * @return The length of the attribute list. + * @see org.xml.sax.AttributeList#getLength + */ + public int getLength () + { + return attributes.getLength(); + } + + + /** + * Return the qualified (prefixed) name of an attribute by position. + * + * @return The qualified name. + * @see org.xml.sax.AttributeList#getName + */ + public String getName (int i) + { + return attributes.getQName(i); + } + + + /** + * Return the type of an attribute by position. + * + * @return The type. + * @see org.xml.sax.AttributeList#getType(int) + */ + public String getType (int i) + { + return attributes.getType(i); + } + + + /** + * Return the value of an attribute by position. + * + * @return The value. + * @see org.xml.sax.AttributeList#getValue(int) + */ + public String getValue (int i) + { + return attributes.getValue(i); + } + + + /** + * Return the type of an attribute by qualified (prefixed) name. + * + * @return The type. + * @see org.xml.sax.AttributeList#getType(java.lang.String) + */ + public String getType (String qName) + { + return attributes.getType(qName); + } + + + /** + * Return the value of an attribute by qualified (prefixed) name. + * + * @return The value. + * @see org.xml.sax.AttributeList#getValue(java.lang.String) + */ + public String getValue (String qName) + { + return attributes.getValue(qName); + } + + private Attributes attributes; + } + +} + +// end of XMLReaderAdapter.java diff --git a/libjava/classpath/external/sax/org/xml/sax/helpers/XMLReaderFactory.java b/libjava/classpath/external/sax/org/xml/sax/helpers/XMLReaderFactory.java new file mode 100644 index 000000000..9a04f9b0d --- /dev/null +++ b/libjava/classpath/external/sax/org/xml/sax/helpers/XMLReaderFactory.java @@ -0,0 +1,207 @@ +// XMLReaderFactory.java - factory for creating a new reader. +// http://www.saxproject.org +// Written by David Megginson +// and by David Brownell +// NO WARRANTY! This class is in the Public Domain. +// $Id: XMLReaderFactory.java,v 1.1 2004/12/23 22:38:42 mark Exp $ + +package org.xml.sax.helpers; +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import org.xml.sax.XMLReader; +import org.xml.sax.SAXException; + + +/** + * Factory for creating an XML reader. + * + * <blockquote> + * <em>This module, both source code and documentation, is in the + * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> + * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a> + * for further information. + * </blockquote> + * + * <p>This class contains static methods for creating an XML reader + * from an explicit class name, or based on runtime defaults:</p> + * + * <pre> + * try { + * XMLReader myReader = XMLReaderFactory.createXMLReader(); + * } catch (SAXException e) { + * System.err.println(e.getMessage()); + * } + * </pre> + * + * <p><strong>Note to Distributions bundled with parsers:</strong> + * You should modify the implementation of the no-arguments + * <em>createXMLReader</em> to handle cases where the external + * configuration mechanisms aren't set up. That method should do its + * best to return a parser when one is in the class path, even when + * nothing bound its class name to <code>org.xml.sax.driver</code> so + * those configuration mechanisms would see it.</p> + * + * @since SAX 2.0 + * @author David Megginson, David Brownell + * @version 2.0.1 (sax2r2) + */ +final public class XMLReaderFactory +{ + /** + * Private constructor. + * + * <p>This constructor prevents the class from being instantiated.</p> + */ + private XMLReaderFactory () + { + } + + private static final String property = "org.xml.sax.driver"; + + /** + * Attempt to create an XMLReader from system defaults. + * In environments which can support it, the name of the XMLReader + * class is determined by trying each these options in order, and + * using the first one which succeeds:</p> <ul> + * + * <li>If the system property <code>org.xml.sax.driver</code> + * has a value, that is used as an XMLReader class name. </li> + * + * <li>The JAR "Services API" is used to look for a class name + * in the <em>META-INF/services/org.xml.sax.driver</em> file in + * jarfiles available to the runtime.</li> + * + * <li> SAX parser distributions are strongly encouraged to provide + * a default XMLReader class name that will take effect only when + * previous options (on this list) are not successful.</li> + * + * <li>Finally, if {@link ParserFactory#makeParser()} can + * return a system default SAX1 parser, that parser is wrapped in + * a {@link ParserAdapter}. (This is a migration aid for SAX1 + * environments, where the <code>org.xml.sax.parser</code> system + * property will often be usable.) </li> + * + * </ul> + * + * <p> In environments such as small embedded systems, which can not + * support that flexibility, other mechanisms to determine the default + * may be used. </p> + * + * <p>Note that many Java environments allow system properties to be + * initialized on a command line. This means that <em>in most cases</em> + * setting a good value for that property ensures that calls to this + * method will succeed, except when security policies intervene. + * This will also maximize application portability to older SAX + * environments, with less robust implementations of this method. + * </p> + * + * @return A new XMLReader. + * @exception org.xml.sax.SAXException If no default XMLReader class + * can be identified and instantiated. + * @see #createXMLReader(java.lang.String) + */ + public static XMLReader createXMLReader () + throws SAXException + { + String className = null; + ClassLoader loader = NewInstance.getClassLoader (); + + // 1. try the JVM-instance-wide system property + try { className = System.getProperty (property); } + catch (RuntimeException e) { /* normally fails for applets */ } + + // 2. if that fails, try META-INF/services/ + if (className == null) { + try { + String service = "META-INF/services/" + property; + InputStream in; + BufferedReader reader; + + if (loader == null) + in = ClassLoader.getSystemResourceAsStream (service); + else + in = loader.getResourceAsStream (service); + + if (in != null) { + reader = new BufferedReader ( + new InputStreamReader (in, "UTF8")); + className = reader.readLine (); + in.close (); + } + } catch (Exception e) { + } + } + + // 3. Distro-specific fallback + if (className == null) { +// BEGIN DISTRIBUTION-SPECIFIC + + // CLASSPATH LOCAL: have to code in the backup. + // Among other things, see PR 31303, and this thread: + // http://gcc.gnu.org/ml/java-patches/2007-q1/msg00661.html + className = "gnu.xml.stream.SAXParser"; + + // EXAMPLE: + // className = "com.example.sax.XmlReader"; + // or a $JAVA_HOME/jre/lib/*properties setting... + +// END DISTRIBUTION-SPECIFIC + } + + // do we know the XMLReader implementation class yet? + if (className != null) + return loadClass (loader, className); + + // 4. panic -- adapt any SAX1 parser + try { + return new ParserAdapter (ParserFactory.makeParser ()); + } catch (Exception e) { + throw new SAXException ("Can't create default XMLReader; " + + "is system property org.xml.sax.driver set?"); + } + } + + + /** + * Attempt to create an XML reader from a class name. + * + * <p>Given a class name, this method attempts to load + * and instantiate the class as an XML reader.</p> + * + * <p>Note that this method will not be usable in environments where + * the caller (perhaps an applet) is not permitted to load classes + * dynamically.</p> + * + * @return A new XML reader. + * @exception org.xml.sax.SAXException If the class cannot be + * loaded, instantiated, and cast to XMLReader. + * @see #createXMLReader() + */ + public static XMLReader createXMLReader (String className) + throws SAXException + { + return loadClass (NewInstance.getClassLoader (), className); + } + + private static XMLReader loadClass (ClassLoader loader, String className) + throws SAXException + { + try { + return (XMLReader) NewInstance.newInstance (loader, className); + } catch (ClassNotFoundException e1) { + throw new SAXException("SAX2 driver class " + className + + " not found", e1); + } catch (IllegalAccessException e2) { + throw new SAXException("SAX2 driver class " + className + + " found but cannot be loaded", e2); + } catch (InstantiationException e3) { + throw new SAXException("SAX2 driver class " + className + + " loaded but cannot be instantiated (no empty public constructor?)", + e3); + } catch (ClassCastException e4) { + throw new SAXException("SAX2 driver class " + className + + " does not implement XMLReader", e4); + } + } +} diff --git a/libjava/classpath/external/sax/org/xml/sax/helpers/package.html b/libjava/classpath/external/sax/org/xml/sax/helpers/package.html new file mode 100644 index 000000000..06d4a30a6 --- /dev/null +++ b/libjava/classpath/external/sax/org/xml/sax/helpers/package.html @@ -0,0 +1,11 @@ +<HTML><HEAD> +<!-- $Id: package.html,v 1.1 2004/12/23 22:38:42 mark Exp $ --> +</HEAD><BODY> + +<p>This package contains "helper" classes, including +support for bootstrapping SAX-based applications. + +<p>See <a href='http://www.saxproject.org'>http://www.saxproject.org</a> +for more information about SAX.</p> + +</BODY></HTML> diff --git a/libjava/classpath/external/sax/org/xml/sax/package.html b/libjava/classpath/external/sax/org/xml/sax/package.html new file mode 100644 index 000000000..b71f67fdd --- /dev/null +++ b/libjava/classpath/external/sax/org/xml/sax/package.html @@ -0,0 +1,297 @@ +<html><head> +<!-- $Id: package.html,v 1.1 2004/12/23 22:38:42 mark Exp $ --> +</head><body> + +<p> This package provides the core SAX APIs. +Some SAX1 APIs are deprecated to encourage integration of +namespace-awareness into designs of new applications +and into maintenance of existing infrastructure. </p> + +<p>See <a href='http://www.saxproject.org'>http://www.saxproject.org</a> +for more information about SAX.</p> + + +<h2> SAX2 Standard Feature Flags </h2> + +<p> One of the essential characteristics of SAX2 is that it added +feature flags which can be used to examine and perhaps modify +parser modes, in particular modes such as validation. +Since features are identified by (absolute) URIs, anyone +can define such features. +Currently defined standard feature URIs have the prefix +<code>http://xml.org/sax/features/</code> before an identifier such as +<code>validation</code>. Turn features on or off using +<em>setFeature</em>. Those standard identifiers are: </p> + + +<table border="1" cellpadding="3" cellspacing="0" width="100%"> + <tr align="center" bgcolor="#ccccff"> + <th>Feature ID</th> + <th>Access</th> + <th>Default</th> + <th>Description</th> + </tr> + + <tr> + <td>external-general-entities</td> + <td><em>read/write</em></td> + <td><em>unspecified</em></td> + <td> Reports whether this parser processes external + general entities; always true if validating. + </td> + </tr> + + <tr> + <td>external-parameter-entities</td> + <td><em>read/write</em></td> + <td><em>unspecified</em></td> + <td> Reports whether this parser processes external + parameter entities; always true if validating. + </td> + </tr> + + <tr> + <td>is-standalone</td> + <td>(parsing) <em>read-only</em>, (not parsing) <em>none</em></td> + <td>not applicable</td> + <td> May be examined only during a parse, after the + <em>startDocument()</em> callback has been completed; read-only. + The value is true if the document specified standalone="yes" in + its XML declaration, and otherwise is false. + </td> + </tr> + + <tr> + <td>lexical-handler/parameter-entities</td> + <td><em>read/write</em></td> + <td><em>unspecified</em></td> + <td> A value of "true" indicates that the LexicalHandler will report + the beginning and end of parameter entities. + </td> + </tr> + + <tr> + <td>namespaces</td> + <td><em>read/write</em></td> + <td>true</td> + <td> A value of "true" indicates namespace URIs and unprefixed local names + for element and attribute names will be available. + </td> + </tr> + + <tr> + <td>namespace-prefixes</td> + <td><em>read/write</em></td> + <td>false</td> + <td> A value of "true" indicates that XML qualified names (with prefixes) and + attributes (including <em>xmlns*</em> attributes) will be available. + </td> + </tr> + + <tr> + <td>resolve-dtd-uris</td> + <td><em>read/write</em></td> + <td><em>true</em></td> + <td> A value of "true" indicates that system IDs in declarations will + be absolutized (relative to their base URIs) before reporting. + (That is the default behavior for all SAX2 XML parsers.) + A value of "false" indicates those IDs will not be absolutized; + parsers will provide the base URI from + <em>Locator.getSystemId()</em>. + This applies to system IDs passed in <ul> + <li><em>DTDHandler.notationDecl()</em>, + <li><em>DTDHandler.unparsedEntityDecl()</em>, and + <li><em>DeclHandler.externalEntityDecl()</em>. + </ul> + It does not apply to <em>EntityResolver.resolveEntity()</em>, + which is not used to report declarations, or to + <em>LexicalHandler.startDTD()</em>, which already provides + the non-absolutized URI. + </td> + </tr> + + <tr> + <td>string-interning</td> + <td><em>read/write</em></td> + <td><em>unspecified</em></td> + <td> Has a value of "true" if all XML names (for elements, prefixes, + attributes, entities, notations, and local names), + as well as Namespace URIs, will have been interned + using <em>java.lang.String.intern</em>. This supports fast + testing of equality/inequality against string constants, + rather than forcing slower calls to <em>String.equals()</em>. + </td> + </tr> + + <tr> + <td>unicode-normalization-checking</td> + <td><em>read/write</em></td> + <td><em>false</em></td> + <td> Controls whether the parser reports Unicode normalization + errors as described in section 2.13 and Appendix B of the + XML 1.1 Recommendation. If true, Unicode normalization + errors are reported using the ErrorHandler.error() callback. + Such errors are not fatal in themselves (though, obviously, + other Unicode-related encoding errors may be). + </td> + </tr> + + <tr> + <td>use-attributes2</td> + <td><em>read-only</em></td> + <td>not applicable</td> + <td> Returns "true" if the <em>Attributes</em> objects passed by + this parser in <em>ContentHandler.startElement()</em> + implement the <a href="ext/Attributes2.html" + ><em>org.xml.sax.ext.Attributes2</em></a> interface. + That interface exposes additional DTD-related information, + such as whether the attribute was specified in the + source text rather than defaulted. + </td> + </tr> + + <tr> + <td>use-locator2</td> + <td><em>read-only</em></td> + <td>not applicable</td> + <td> Returns "true" if the <em>Locator</em> objects passed by + this parser in <em>ContentHandler.setDocumentLocator()</em> + implement the <a href="ext/Locator2.html" + ><em>org.xml.sax.ext.Locator2</em></a> interface. + That interface exposes additional entity information, + such as the character encoding and XML version used. + </td> + </tr> + + <tr> + <td>use-entity-resolver2</td> + <td><em>read/write</em></td> + <td><em>true</em></td> + <td> Returns "true" if, when <em>setEntityResolver</em> is given + an object implementing the <a href="ext/EntityResolver2.html" + ><em>org.xml.sax.ext.EntityResolver2</em></a> interface, + those new methods will be used. + Returns "false" to indicate that those methods will not be used. + </td> + </tr> + + <tr> + <td>validation</td> + <td><em>read/write</em></td> + <td><em>unspecified</em></td> + <td> Controls whether the parser is reporting all validity + errors; if true, all external entities will be read. + </td> + </tr> + + <tr> + <td>xmlns-uris</td> + <td><em>read/write</em></td> + <td><em>false</em></td> + <td> Controls whether, when the <em>namespace-prefixes</em> feature + is set, the parser treats namespace declaration attributes as + being in the <em>http://www.w3.org/2000/xmlns/</em> namespace. + By default, SAX2 conforms to the original "Namespaces in XML" + Recommendation, which explicitly states that such attributes are + not in any namespace. + Setting this optional flag to "true" makes the SAX2 events conform to + a later backwards-incompatible revision of that recommendation, + placing those attributes in a namespace. + </td> + </tr> + + <tr> + <td>xml-1.1</td> + <td><em>read-only</em></td> + <td>not applicable</td> + <td> Returns "true" if the parser supports both XML 1.1 and XML 1.0. + Returns "false" if the parser supports only XML 1.0. + </td> + </tr> + +</table> + +<p> Support for the default values of the +<em>namespaces</em> and <em>namespace-prefixes</em> +properties is required. +Support for any other feature flags is entirely optional. +</p> + +<p> For default values not specified by SAX2, +each XMLReader implementation specifies its default, +or may choose not to expose the feature flag. +Unless otherwise specified here, +implementations may support changing current values +of these standard feature flags, but not while parsing. +</p> + +<h2> SAX2 Standard Handler and Property IDs </h2> + +<p> For parser interface characteristics that are described +as objects, a separate namespace is defined. The +objects in this namespace are again identified by URI, and +the standard property URIs have the prefix +<code>http://xml.org/sax/properties/</code> before an identifier such as +<code>lexical-handler</code> or +<code>dom-node</code>. Manage those properties using +<em>setProperty()</em>. Those identifiers are: </p> + +<table border="1" cellpadding="3" cellspacing="0" width="100%"> + <tr align="center" bgcolor="#ccccff"> + <th>Property ID</th> + <th>Description</th> + </tr> + + <tr> + <td>declaration-handler</td> + <td> Used to see most DTD declarations except those treated + as lexical ("document element name is ...") or which are + mandatory for all SAX parsers (<em>DTDHandler</em>). + The Object must implement <a href="ext/DeclHandler.html" + ><em>org.xml.sax.ext.DeclHandler</em></a>. + </td> + </tr> + + <tr> + <td>document-xml-version</td> + <td> May be examined only during a parse, after the startDocument() + callback has been completed; read-only. This property is a + literal string describing the actual XML version of the document, + such as "1.0" or "1.1". + </td> + </tr> + + <tr> + <td>dom-node</td> + <td> For "DOM Walker" style parsers, which ignore their + <em>parser.parse()</em> parameters, this is used to + specify the DOM (sub)tree being walked by the parser. + The Object must implement the + <em>org.w3c.dom.Node</em> interface. + </td> + </tr> + + <tr> + <td>lexical-handler</td> + <td> Used to see some syntax events that are essential in some + applications: comments, CDATA delimiters, selected general + entity inclusions, and the start and end of the DTD + (and declaration of document element name). + The Object must implement <a href="ext/LexicalHandler.html" + ><em>org.xml.sax.ext.LexicalHandler</em></a>. + </td> + </tr> + + <tr> + <td>xml-string</td> + <td> Readable only during a parser callback, this exposes a <b>TBS</b> + chunk of characters responsible for the current event. </td> + </tr> + +</table> + +<p> All of these standard properties are optional; +XMLReader implementations need not support them. +</p> + +</body></html>
\ No newline at end of file diff --git a/libjava/classpath/external/w3c_dom/.cvsignore b/libjava/classpath/external/w3c_dom/.cvsignore new file mode 100644 index 000000000..282522db0 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/libjava/classpath/external/w3c_dom/Makefile.am b/libjava/classpath/external/w3c_dom/Makefile.am new file mode 100644 index 000000000..701cbe474 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/Makefile.am @@ -0,0 +1,149 @@ +## Input file for automake to generate the Makefile.in used by configure + +EXTRA_DIST = README \ +org/w3c/dom/Attr.java \ +org/w3c/dom/CDATASection.java \ +org/w3c/dom/CharacterData.java \ +org/w3c/dom/Comment.java \ +org/w3c/dom/DOMConfiguration.java \ +org/w3c/dom/DOMError.java \ +org/w3c/dom/DOMErrorHandler.java \ +org/w3c/dom/DOMException.java \ +org/w3c/dom/DOMImplementation.java \ +org/w3c/dom/DOMImplementationList.java \ +org/w3c/dom/DOMImplementationSource.java \ +org/w3c/dom/DOMLocator.java \ +org/w3c/dom/DOMStringList.java \ +org/w3c/dom/Document.java \ +org/w3c/dom/DocumentFragment.java \ +org/w3c/dom/DocumentType.java \ +org/w3c/dom/Element.java \ +org/w3c/dom/Entity.java \ +org/w3c/dom/EntityReference.java \ +org/w3c/dom/NameList.java \ +org/w3c/dom/NamedNodeMap.java \ +org/w3c/dom/Node.java \ +org/w3c/dom/NodeList.java \ +org/w3c/dom/Notation.java \ +org/w3c/dom/ProcessingInstruction.java \ +org/w3c/dom/Text.java \ +org/w3c/dom/TypeInfo.java \ +org/w3c/dom/UserDataHandler.java \ +org/w3c/dom/bootstrap/DOMImplementationRegistry.java \ +org/w3c/dom/css/CSS2Properties.java \ +org/w3c/dom/css/CSSCharsetRule.java \ +org/w3c/dom/css/CSSFontFaceRule.java \ +org/w3c/dom/css/CSSImportRule.java \ +org/w3c/dom/css/CSSMediaRule.java \ +org/w3c/dom/css/CSSPageRule.java \ +org/w3c/dom/css/CSSPrimitiveValue.java \ +org/w3c/dom/css/CSSRule.java \ +org/w3c/dom/css/CSSRuleList.java \ +org/w3c/dom/css/CSSStyleDeclaration.java \ +org/w3c/dom/css/CSSStyleRule.java \ +org/w3c/dom/css/CSSStyleSheet.java \ +org/w3c/dom/css/CSSUnknownRule.java \ +org/w3c/dom/css/CSSValue.java \ +org/w3c/dom/css/CSSValueList.java \ +org/w3c/dom/css/Counter.java \ +org/w3c/dom/css/DOMImplementationCSS.java \ +org/w3c/dom/css/DocumentCSS.java \ +org/w3c/dom/css/ElementCSSInlineStyle.java \ +org/w3c/dom/css/RGBColor.java \ +org/w3c/dom/css/Rect.java \ +org/w3c/dom/css/ViewCSS.java \ +org/w3c/dom/events/DocumentEvent.java \ +org/w3c/dom/events/Event.java \ +org/w3c/dom/events/EventException.java \ +org/w3c/dom/events/EventListener.java \ +org/w3c/dom/events/EventTarget.java \ +org/w3c/dom/events/MouseEvent.java \ +org/w3c/dom/events/MutationEvent.java \ +org/w3c/dom/events/UIEvent.java \ +org/w3c/dom/html2/HTMLAnchorElement.java \ +org/w3c/dom/html2/HTMLAppletElement.java \ +org/w3c/dom/html2/HTMLAreaElement.java \ +org/w3c/dom/html2/HTMLBRElement.java \ +org/w3c/dom/html2/HTMLBaseElement.java \ +org/w3c/dom/html2/HTMLBaseFontElement.java \ +org/w3c/dom/html2/HTMLBodyElement.java \ +org/w3c/dom/html2/HTMLButtonElement.java \ +org/w3c/dom/html2/HTMLCollection.java \ +org/w3c/dom/html2/HTMLDListElement.java \ +org/w3c/dom/html2/HTMLDirectoryElement.java \ +org/w3c/dom/html2/HTMLDivElement.java \ +org/w3c/dom/html2/HTMLDocument.java \ +org/w3c/dom/html2/HTMLElement.java \ +org/w3c/dom/html2/HTMLFieldSetElement.java \ +org/w3c/dom/html2/HTMLFontElement.java \ +org/w3c/dom/html2/HTMLFormElement.java \ +org/w3c/dom/html2/HTMLFrameElement.java \ +org/w3c/dom/html2/HTMLFrameSetElement.java \ +org/w3c/dom/html2/HTMLHRElement.java \ +org/w3c/dom/html2/HTMLHeadElement.java \ +org/w3c/dom/html2/HTMLHeadingElement.java \ +org/w3c/dom/html2/HTMLHtmlElement.java \ +org/w3c/dom/html2/HTMLIFrameElement.java \ +org/w3c/dom/html2/HTMLImageElement.java \ +org/w3c/dom/html2/HTMLInputElement.java \ +org/w3c/dom/html2/HTMLIsIndexElement.java \ +org/w3c/dom/html2/HTMLLIElement.java \ +org/w3c/dom/html2/HTMLLabelElement.java \ +org/w3c/dom/html2/HTMLLegendElement.java \ +org/w3c/dom/html2/HTMLLinkElement.java \ +org/w3c/dom/html2/HTMLMapElement.java \ +org/w3c/dom/html2/HTMLMenuElement.java \ +org/w3c/dom/html2/HTMLMetaElement.java \ +org/w3c/dom/html2/HTMLModElement.java \ +org/w3c/dom/html2/HTMLOListElement.java \ +org/w3c/dom/html2/HTMLObjectElement.java \ +org/w3c/dom/html2/HTMLOptGroupElement.java \ +org/w3c/dom/html2/HTMLOptionElement.java \ +org/w3c/dom/html2/HTMLOptionsCollection.java \ +org/w3c/dom/html2/HTMLParagraphElement.java \ +org/w3c/dom/html2/HTMLParamElement.java \ +org/w3c/dom/html2/HTMLPreElement.java \ +org/w3c/dom/html2/HTMLQuoteElement.java \ +org/w3c/dom/html2/HTMLScriptElement.java \ +org/w3c/dom/html2/HTMLSelectElement.java \ +org/w3c/dom/html2/HTMLStyleElement.java \ +org/w3c/dom/html2/HTMLTableCaptionElement.java \ +org/w3c/dom/html2/HTMLTableCellElement.java \ +org/w3c/dom/html2/HTMLTableColElement.java \ +org/w3c/dom/html2/HTMLTableElement.java \ +org/w3c/dom/html2/HTMLTableRowElement.java \ +org/w3c/dom/html2/HTMLTableSectionElement.java \ +org/w3c/dom/html2/HTMLTextAreaElement.java \ +org/w3c/dom/html2/HTMLTitleElement.java \ +org/w3c/dom/html2/HTMLUListElement.java \ +org/w3c/dom/ls/DOMImplementationLS.java \ +org/w3c/dom/ls/LSException.java \ +org/w3c/dom/ls/LSInput.java \ +org/w3c/dom/ls/LSLoadEvent.java \ +org/w3c/dom/ls/LSOutput.java \ +org/w3c/dom/ls/LSParser.java \ +org/w3c/dom/ls/LSParserFilter.java \ +org/w3c/dom/ls/LSProgressEvent.java \ +org/w3c/dom/ls/LSResourceResolver.java \ +org/w3c/dom/ls/LSSerializer.java \ +org/w3c/dom/ls/LSSerializerFilter.java \ +org/w3c/dom/ranges/DocumentRange.java \ +org/w3c/dom/ranges/Range.java \ +org/w3c/dom/ranges/RangeException.java \ +org/w3c/dom/stylesheets/DocumentStyle.java \ +org/w3c/dom/stylesheets/LinkStyle.java \ +org/w3c/dom/stylesheets/MediaList.java \ +org/w3c/dom/stylesheets/StyleSheet.java \ +org/w3c/dom/stylesheets/StyleSheetList.java \ +org/w3c/dom/traversal/DocumentTraversal.java \ +org/w3c/dom/traversal/NodeFilter.java \ +org/w3c/dom/traversal/NodeIterator.java \ +org/w3c/dom/traversal/TreeWalker.java \ +org/w3c/dom/views/AbstractView.java \ +org/w3c/dom/views/DocumentView.java \ +org/w3c/dom/xpath/XPathEvaluator.java \ +org/w3c/dom/xpath/XPathException.java \ +org/w3c/dom/xpath/XPathExpression.java \ +org/w3c/dom/xpath/XPathNSResolver.java \ +org/w3c/dom/xpath/XPathNamespace.java \ +org/w3c/dom/xpath/XPathResult.java diff --git a/libjava/classpath/external/w3c_dom/Makefile.in b/libjava/classpath/external/w3c_dom/Makefile.in new file mode 100644 index 000000000..68eecef99 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/Makefile.in @@ -0,0 +1,585 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = external/w3c_dom +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/../../config/depstand.m4 \ + $(top_srcdir)/../../config/lead-dot.m4 \ + $(top_srcdir)/../../config/lib-ld.m4 \ + $(top_srcdir)/../../config/lib-link.m4 \ + $(top_srcdir)/../../config/lib-prefix.m4 \ + $(top_srcdir)/../../config/multi.m4 \ + $(top_srcdir)/../../config/no-executables.m4 \ + $(top_srcdir)/../../config/override.m4 \ + $(top_srcdir)/../../libtool.m4 \ + $(top_srcdir)/../../ltoptions.m4 \ + $(top_srcdir)/../../ltsugar.m4 \ + $(top_srcdir)/../../ltversion.m4 \ + $(top_srcdir)/../../lt~obsolete.m4 \ + $(top_srcdir)/m4/ac_prog_antlr.m4 \ + $(top_srcdir)/m4/ac_prog_java.m4 \ + $(top_srcdir)/m4/ac_prog_java_works.m4 \ + $(top_srcdir)/m4/ac_prog_javac.m4 \ + $(top_srcdir)/m4/ac_prog_javac_works.m4 \ + $(top_srcdir)/m4/acattribute.m4 $(top_srcdir)/m4/accross.m4 \ + $(top_srcdir)/m4/acinclude.m4 \ + $(top_srcdir)/m4/ax_create_stdint_h.m4 \ + $(top_srcdir)/m4/ax_func_which_gethostbyname_r.m4 \ + $(top_srcdir)/m4/gcc_attribute.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/../../mkinstalldirs +CONFIG_HEADER = $(top_builddir)/include/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +ANTLR = @ANTLR@ +ANTLR_JAR = @ANTLR_JAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CAIRO_CFLAGS = @CAIRO_CFLAGS@ +CAIRO_LIBS = @CAIRO_LIBS@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLASSPATH_CONVENIENCE = @CLASSPATH_CONVENIENCE@ +CLASSPATH_INCLUDES = @CLASSPATH_INCLUDES@ +CLASSPATH_MODULE = @CLASSPATH_MODULE@ +COLLECTIONS_PREFIX = @COLLECTIONS_PREFIX@ +CP = @CP@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATE = @DATE@ +DEFAULT_PREFS_PEER = @DEFAULT_PREFS_PEER@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +ECJ_JAR = @ECJ_JAR@ +EGREP = @EGREP@ +ERROR_CFLAGS = @ERROR_CFLAGS@ +EXAMPLESDIR = @EXAMPLESDIR@ +EXEEXT = @EXEEXT@ +EXTRA_CFLAGS = @EXTRA_CFLAGS@ +FGREP = @FGREP@ +FIND = @FIND@ +FREETYPE2_CFLAGS = @FREETYPE2_CFLAGS@ +FREETYPE2_LIBS = @FREETYPE2_LIBS@ +GCONF_CFLAGS = @GCONF_CFLAGS@ +GCONF_LIBS = @GCONF_LIBS@ +GDK_CFLAGS = @GDK_CFLAGS@ +GDK_LIBS = @GDK_LIBS@ +GJDOC = @GJDOC@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +GMP_CFLAGS = @GMP_CFLAGS@ +GMP_LIBS = @GMP_LIBS@ +GREP = @GREP@ +GSTREAMER_BASE_CFLAGS = @GSTREAMER_BASE_CFLAGS@ +GSTREAMER_BASE_LIBS = @GSTREAMER_BASE_LIBS@ +GSTREAMER_CFLAGS = @GSTREAMER_CFLAGS@ +GSTREAMER_FILE_READER = @GSTREAMER_FILE_READER@ +GSTREAMER_LIBS = @GSTREAMER_LIBS@ +GSTREAMER_MIXER_PROVIDER = @GSTREAMER_MIXER_PROVIDER@ +GSTREAMER_PLUGINS_BASE_CFLAGS = @GSTREAMER_PLUGINS_BASE_CFLAGS@ +GSTREAMER_PLUGINS_BASE_LIBS = @GSTREAMER_PLUGINS_BASE_LIBS@ +GST_PLUGIN_LDFLAGS = @GST_PLUGIN_LDFLAGS@ +GTK_CFLAGS = @GTK_CFLAGS@ +GTK_LIBS = @GTK_LIBS@ +INIT_LOAD_LIBRARY = @INIT_LOAD_LIBRARY@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JAR = @JAR@ +JAVA = @JAVA@ +JAVAC = @JAVAC@ +JAVAC_IS_GCJ = @JAVAC_IS_GCJ@ +JAVAC_MEM_OPT = @JAVAC_MEM_OPT@ +JAVA_LANG_SYSTEM_EXPLICIT_INITIALIZATION = @JAVA_LANG_SYSTEM_EXPLICIT_INITIALIZATION@ +JAY = @JAY@ +JAY_SKELETON = @JAY_SKELETON@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBDEBUG = @LIBDEBUG@ +LIBICONV = @LIBICONV@ +LIBMAGIC = @LIBMAGIC@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBVERSION = @LIBVERSION@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR = @MKDIR@ +MKDIR_P = @MKDIR_P@ +MOC = @MOC@ +MOZILLA_CFLAGS = @MOZILLA_CFLAGS@ +MOZILLA_LIBS = @MOZILLA_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PANGOFT2_CFLAGS = @PANGOFT2_CFLAGS@ +PANGOFT2_LIBS = @PANGOFT2_LIBS@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PATH_TO_ESCHER = @PATH_TO_ESCHER@ +PATH_TO_GLIBJ_ZIP = @PATH_TO_GLIBJ_ZIP@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PLUGIN_DIR = @PLUGIN_DIR@ +QT_CFLAGS = @QT_CFLAGS@ +QT_LIBS = @QT_LIBS@ +RANLIB = @RANLIB@ +REMOVE = @REMOVE@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRICT_WARNING_CFLAGS = @STRICT_WARNING_CFLAGS@ +STRIP = @STRIP@ +TOOLSDIR = @TOOLSDIR@ +USER_JAVAH = @USER_JAVAH@ +VERSION = @VERSION@ +WANT_NATIVE_BIG_INTEGER = @WANT_NATIVE_BIG_INTEGER@ +WARNING_CFLAGS = @WARNING_CFLAGS@ +XMKMF = @XMKMF@ +XML_CFLAGS = @XML_CFLAGS@ +XML_LIBS = @XML_LIBS@ +XSLT_CFLAGS = @XSLT_CFLAGS@ +XSLT_LIBS = @XSLT_LIBS@ +XTEST_LIBS = @XTEST_LIBS@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +ZIP = @ZIP@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_ANTLR = @ac_ct_ANTLR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +default_toolkit = @default_toolkit@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +glibjdir = @glibjdir@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +multi_basedir = @multi_basedir@ +nativeexeclibdir = @nativeexeclibdir@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +toolexeclibdir = @toolexeclibdir@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +uudecode = @uudecode@ +vm_classes = @vm_classes@ +EXTRA_DIST = README \ +org/w3c/dom/Attr.java \ +org/w3c/dom/CDATASection.java \ +org/w3c/dom/CharacterData.java \ +org/w3c/dom/Comment.java \ +org/w3c/dom/DOMConfiguration.java \ +org/w3c/dom/DOMError.java \ +org/w3c/dom/DOMErrorHandler.java \ +org/w3c/dom/DOMException.java \ +org/w3c/dom/DOMImplementation.java \ +org/w3c/dom/DOMImplementationList.java \ +org/w3c/dom/DOMImplementationSource.java \ +org/w3c/dom/DOMLocator.java \ +org/w3c/dom/DOMStringList.java \ +org/w3c/dom/Document.java \ +org/w3c/dom/DocumentFragment.java \ +org/w3c/dom/DocumentType.java \ +org/w3c/dom/Element.java \ +org/w3c/dom/Entity.java \ +org/w3c/dom/EntityReference.java \ +org/w3c/dom/NameList.java \ +org/w3c/dom/NamedNodeMap.java \ +org/w3c/dom/Node.java \ +org/w3c/dom/NodeList.java \ +org/w3c/dom/Notation.java \ +org/w3c/dom/ProcessingInstruction.java \ +org/w3c/dom/Text.java \ +org/w3c/dom/TypeInfo.java \ +org/w3c/dom/UserDataHandler.java \ +org/w3c/dom/bootstrap/DOMImplementationRegistry.java \ +org/w3c/dom/css/CSS2Properties.java \ +org/w3c/dom/css/CSSCharsetRule.java \ +org/w3c/dom/css/CSSFontFaceRule.java \ +org/w3c/dom/css/CSSImportRule.java \ +org/w3c/dom/css/CSSMediaRule.java \ +org/w3c/dom/css/CSSPageRule.java \ +org/w3c/dom/css/CSSPrimitiveValue.java \ +org/w3c/dom/css/CSSRule.java \ +org/w3c/dom/css/CSSRuleList.java \ +org/w3c/dom/css/CSSStyleDeclaration.java \ +org/w3c/dom/css/CSSStyleRule.java \ +org/w3c/dom/css/CSSStyleSheet.java \ +org/w3c/dom/css/CSSUnknownRule.java \ +org/w3c/dom/css/CSSValue.java \ +org/w3c/dom/css/CSSValueList.java \ +org/w3c/dom/css/Counter.java \ +org/w3c/dom/css/DOMImplementationCSS.java \ +org/w3c/dom/css/DocumentCSS.java \ +org/w3c/dom/css/ElementCSSInlineStyle.java \ +org/w3c/dom/css/RGBColor.java \ +org/w3c/dom/css/Rect.java \ +org/w3c/dom/css/ViewCSS.java \ +org/w3c/dom/events/DocumentEvent.java \ +org/w3c/dom/events/Event.java \ +org/w3c/dom/events/EventException.java \ +org/w3c/dom/events/EventListener.java \ +org/w3c/dom/events/EventTarget.java \ +org/w3c/dom/events/MouseEvent.java \ +org/w3c/dom/events/MutationEvent.java \ +org/w3c/dom/events/UIEvent.java \ +org/w3c/dom/html2/HTMLAnchorElement.java \ +org/w3c/dom/html2/HTMLAppletElement.java \ +org/w3c/dom/html2/HTMLAreaElement.java \ +org/w3c/dom/html2/HTMLBRElement.java \ +org/w3c/dom/html2/HTMLBaseElement.java \ +org/w3c/dom/html2/HTMLBaseFontElement.java \ +org/w3c/dom/html2/HTMLBodyElement.java \ +org/w3c/dom/html2/HTMLButtonElement.java \ +org/w3c/dom/html2/HTMLCollection.java \ +org/w3c/dom/html2/HTMLDListElement.java \ +org/w3c/dom/html2/HTMLDirectoryElement.java \ +org/w3c/dom/html2/HTMLDivElement.java \ +org/w3c/dom/html2/HTMLDocument.java \ +org/w3c/dom/html2/HTMLElement.java \ +org/w3c/dom/html2/HTMLFieldSetElement.java \ +org/w3c/dom/html2/HTMLFontElement.java \ +org/w3c/dom/html2/HTMLFormElement.java \ +org/w3c/dom/html2/HTMLFrameElement.java \ +org/w3c/dom/html2/HTMLFrameSetElement.java \ +org/w3c/dom/html2/HTMLHRElement.java \ +org/w3c/dom/html2/HTMLHeadElement.java \ +org/w3c/dom/html2/HTMLHeadingElement.java \ +org/w3c/dom/html2/HTMLHtmlElement.java \ +org/w3c/dom/html2/HTMLIFrameElement.java \ +org/w3c/dom/html2/HTMLImageElement.java \ +org/w3c/dom/html2/HTMLInputElement.java \ +org/w3c/dom/html2/HTMLIsIndexElement.java \ +org/w3c/dom/html2/HTMLLIElement.java \ +org/w3c/dom/html2/HTMLLabelElement.java \ +org/w3c/dom/html2/HTMLLegendElement.java \ +org/w3c/dom/html2/HTMLLinkElement.java \ +org/w3c/dom/html2/HTMLMapElement.java \ +org/w3c/dom/html2/HTMLMenuElement.java \ +org/w3c/dom/html2/HTMLMetaElement.java \ +org/w3c/dom/html2/HTMLModElement.java \ +org/w3c/dom/html2/HTMLOListElement.java \ +org/w3c/dom/html2/HTMLObjectElement.java \ +org/w3c/dom/html2/HTMLOptGroupElement.java \ +org/w3c/dom/html2/HTMLOptionElement.java \ +org/w3c/dom/html2/HTMLOptionsCollection.java \ +org/w3c/dom/html2/HTMLParagraphElement.java \ +org/w3c/dom/html2/HTMLParamElement.java \ +org/w3c/dom/html2/HTMLPreElement.java \ +org/w3c/dom/html2/HTMLQuoteElement.java \ +org/w3c/dom/html2/HTMLScriptElement.java \ +org/w3c/dom/html2/HTMLSelectElement.java \ +org/w3c/dom/html2/HTMLStyleElement.java \ +org/w3c/dom/html2/HTMLTableCaptionElement.java \ +org/w3c/dom/html2/HTMLTableCellElement.java \ +org/w3c/dom/html2/HTMLTableColElement.java \ +org/w3c/dom/html2/HTMLTableElement.java \ +org/w3c/dom/html2/HTMLTableRowElement.java \ +org/w3c/dom/html2/HTMLTableSectionElement.java \ +org/w3c/dom/html2/HTMLTextAreaElement.java \ +org/w3c/dom/html2/HTMLTitleElement.java \ +org/w3c/dom/html2/HTMLUListElement.java \ +org/w3c/dom/ls/DOMImplementationLS.java \ +org/w3c/dom/ls/LSException.java \ +org/w3c/dom/ls/LSInput.java \ +org/w3c/dom/ls/LSLoadEvent.java \ +org/w3c/dom/ls/LSOutput.java \ +org/w3c/dom/ls/LSParser.java \ +org/w3c/dom/ls/LSParserFilter.java \ +org/w3c/dom/ls/LSProgressEvent.java \ +org/w3c/dom/ls/LSResourceResolver.java \ +org/w3c/dom/ls/LSSerializer.java \ +org/w3c/dom/ls/LSSerializerFilter.java \ +org/w3c/dom/ranges/DocumentRange.java \ +org/w3c/dom/ranges/Range.java \ +org/w3c/dom/ranges/RangeException.java \ +org/w3c/dom/stylesheets/DocumentStyle.java \ +org/w3c/dom/stylesheets/LinkStyle.java \ +org/w3c/dom/stylesheets/MediaList.java \ +org/w3c/dom/stylesheets/StyleSheet.java \ +org/w3c/dom/stylesheets/StyleSheetList.java \ +org/w3c/dom/traversal/DocumentTraversal.java \ +org/w3c/dom/traversal/NodeFilter.java \ +org/w3c/dom/traversal/NodeIterator.java \ +org/w3c/dom/traversal/TreeWalker.java \ +org/w3c/dom/views/AbstractView.java \ +org/w3c/dom/views/DocumentView.java \ +org/w3c/dom/xpath/XPathEvaluator.java \ +org/w3c/dom/xpath/XPathException.java \ +org/w3c/dom/xpath/XPathExpression.java \ +org/w3c/dom/xpath/XPathNSResolver.java \ +org/w3c/dom/xpath/XPathNamespace.java \ +org/w3c/dom/xpath/XPathResult.java + +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu external/w3c_dom/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu external/w3c_dom/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libjava/classpath/external/w3c_dom/README b/libjava/classpath/external/w3c_dom/README new file mode 100644 index 000000000..6670651ef --- /dev/null +++ b/libjava/classpath/external/w3c_dom/README @@ -0,0 +1,97 @@ +Bindings for the Document Object Model (DOM). +DOM is not maintained as part of GNU Classpath, but is used with GNU Classpath. + +The packages includes are: + +Document Object Model (DOM) Level 3 Core Specification +http://www.w3.org/TR/DOM-Level-3-Core/ +(07 April 2004) + +Document Object Model (DOM) Level 3 Load and Save Specification +http://www.w3.org/TR/DOM-Level-3-LS/ +(07 April 2004) + +Document Object Model (DOM) Level 2 Events Specification +http://www.w3.org/TR/DOM-Level-2-Events/ +(13 November 2000) +Latest errata: 20021016 + +Document Object Model (DOM) Level 2 Views Specification +http://www.w3.org/TR/DOM-Level-2-Views/ +(13 November 2000) +Latest errata: 20021016 + +Document Object Model (DOM) Level 2 Style Specification +http://www.w3.org/TR/DOM-Level-2-Style/ +(13 November 2000) +Latest errata: 20021016 + +Document Object Model (DOM) Level 2 Traversal and Range Specification +http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ +(13 November 2000) +Latest errata: 20021016 + +Document Object Model (DOM) Level 2 HTML Specification +http://www.w3.org/TR/DOM-Level-2-HTML/ +(09 January 2003) + +Document Object Model (DOM) Level 3 XPath Specification +http://www.w3.org/TR/DOM-Level-3-XPath/ +(26 February 2004) + +Errata can be found at: +http://www.w3.org/2000/11/DOM-Level-2-errata +http://www.w3.org/2004/01/DOM-Level-3-errata + +The only change to the sources is setting the additional fallback for +org.w3c.dom.bootstrap.DOMImplementationRegistry.newInstance() to +gnu.xml.dom.ImplementationSource. + +When importing new versions don't forget to update the Makefile.am +to list any new files (or to remove old ones). + +All files are distributed under the following +W3C Software Short Notice: + + Copyright (c) 2004 World Wide Web Consortium, + + (Massachusetts Institute of Technology, European Research Consortium for + Informatics and Mathematics, Keio University). All Rights Reserved. This + work is distributed under the W3C(r) Software License [1] 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. + + [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + + Permission to copy, modify, and distribute this software and its + documentation, with or without modification, for any purpose and + without fee or royalty is hereby granted, provided that you include + the following on ALL copies of the software and documentation or + portions thereof, including modifications: + + 1. The full text of this NOTICE in a location viewable to users of + the redistributed or derivative work. + 2. Any pre-existing intellectual property disclaimers, notices, or + terms and conditions. If none exist, the W3C Software Short Notice + should be included (hypertext is preferred, text is permitted) within + the body of any redistributed or derivative code. + 3. Notice of any changes or modifications to the files, including + the date changes were made. (We recommend you provide URIs to the + location from which the code is derived.) + + THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT + HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS + FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE OR + DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS. + + COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL + OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR + DOCUMENTATION. + + The name and trademarks of copyright holders may NOT be used in + advertising or publicity pertaining to the software without specific, + written prior permission. Title to copyright in this software and any + associated documentation will at all times remain with copyright + holders. diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/Attr.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/Attr.java new file mode 100644 index 000000000..944045129 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/Attr.java @@ -0,0 +1,275 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom; + +/** + * The <code>Attr</code> interface represents an attribute in an + * <code>Element</code> object. Typically the allowable values for the + * attribute are defined in a schema associated with the document. + * <p><code>Attr</code> objects inherit the <code>Node</code> interface, but + * since they are not actually child nodes of the element they describe, the + * DOM does not consider them part of the document tree. Thus, the + * <code>Node</code> attributes <code>parentNode</code>, + * <code>previousSibling</code>, and <code>nextSibling</code> have a + * <code>null</code> value for <code>Attr</code> objects. The DOM takes the + * view that attributes are properties of elements rather than having a + * separate identity from the elements they are associated with; this should + * make it more efficient to implement such features as default attributes + * associated with all elements of a given type. Furthermore, + * <code>Attr</code> nodes may not be immediate children of a + * <code>DocumentFragment</code>. However, they can be associated with + * <code>Element</code> nodes contained within a + * <code>DocumentFragment</code>. In short, users and implementors of the + * DOM need to be aware that <code>Attr</code> nodes have some things in + * common with other objects inheriting the <code>Node</code> interface, but + * they also are quite distinct. + * <p>The attribute's effective value is determined as follows: if this + * attribute has been explicitly assigned any value, that value is the + * attribute's effective value; otherwise, if there is a declaration for + * this attribute, and that declaration includes a default value, then that + * default value is the attribute's effective value; otherwise, the + * attribute does not exist on this element in the structure model until it + * has been explicitly added. Note that the <code>Node.nodeValue</code> + * attribute on the <code>Attr</code> instance can also be used to retrieve + * the string version of the attribute's value(s). + * <p> If the attribute was not explicitly given a value in the instance + * document but has a default value provided by the schema associated with + * the document, an attribute node will be created with + * <code>specified</code> set to <code>false</code>. Removing attribute + * nodes for which a default value is defined in the schema generates a new + * attribute node with the default value and <code>specified</code> set to + * <code>false</code>. If validation occurred while invoking + * <code>Document.normalizeDocument()</code>, attribute nodes with + * <code>specified</code> equals to <code>false</code> are recomputed + * according to the default attribute values provided by the schema. If no + * default value is associate with this attribute in the schema, the + * attribute node is discarded. + * <p>In XML, where the value of an attribute can contain entity references, + * the child nodes of the <code>Attr</code> node may be either + * <code>Text</code> or <code>EntityReference</code> nodes (when these are + * in use; see the description of <code>EntityReference</code> for + * discussion). + * <p>The DOM Core represents all attribute values as simple strings, even if + * the DTD or schema associated with the document declares them of some + * specific type such as tokenized. + * <p>The way attribute value normalization is performed by the DOM + * implementation depends on how much the implementation knows about the + * schema in use. Typically, the <code>value</code> and + * <code>nodeValue</code> attributes of an <code>Attr</code> node initially + * returns the normalized value given by the parser. It is also the case + * after <code>Document.normalizeDocument()</code> is called (assuming the + * right options have been set). But this may not be the case after + * mutation, independently of whether the mutation is performed by setting + * the string value directly or by changing the <code>Attr</code> child + * nodes. In particular, this is true when <a href='http://www.w3.org/TR/2004/REC-xml-20040204#dt-charref'>character + * references</a> are involved, given that they are not represented in the DOM and they + * impact attribute value normalization. On the other hand, if the + * implementation knows about the schema in use when the attribute value is + * changed, and it is of a different type than CDATA, it may normalize it + * again at that time. This is especially true of specialized DOM + * implementations, such as SVG DOM implementations, which store attribute + * values in an internal form different from a string. + * <p>The following table gives some examples of the relations between the + * attribute value in the original document (parsed attribute), the value as + * exposed in the DOM, and the serialization of the value: + * <table border='1' cellpadding='3'> + * <tr> + * <th>Examples</th> + * <th>Parsed + * attribute value</th> + * <th>Initial <code>Attr.value</code></th> + * <th>Serialized attribute value</th> + * </tr> + * <tr> + * <td valign='top' rowspan='1' colspan='1'> + * Character reference</td> + * <td valign='top' rowspan='1' colspan='1'> + * <pre>"x&#178;=5"</pre> + * </td> + * <td valign='top' rowspan='1' colspan='1'> + * <pre>"x\u00b2=5"</pre> + * </td> + * <td valign='top' rowspan='1' colspan='1'> + * <pre>"x&#178;=5"</pre> + * </td> + * </tr> + * <tr> + * <td valign='top' rowspan='1' colspan='1'>Built-in + * character entity</td> + * <td valign='top' rowspan='1' colspan='1'> + * <pre>"y&lt;6"</pre> + * </td> + * <td valign='top' rowspan='1' colspan='1'> + * <pre>"y<6"</pre> + * </td> + * <td valign='top' rowspan='1' colspan='1'> + * <pre>"y&lt;6"</pre> + * </td> + * </tr> + * <tr> + * <td valign='top' rowspan='1' colspan='1'>Literal newline between</td> + * <td valign='top' rowspan='1' colspan='1'> + * <pre> + * "x=5&#10;y=6"</pre> + * </td> + * <td valign='top' rowspan='1' colspan='1'> + * <pre>"x=5 y=6"</pre> + * </td> + * <td valign='top' rowspan='1' colspan='1'> + * <pre>"x=5&#10;y=6"</pre> + * </td> + * </tr> + * <tr> + * <td valign='top' rowspan='1' colspan='1'>Normalized newline between</td> + * <td valign='top' rowspan='1' colspan='1'> + * <pre>"x=5 + * y=6"</pre> + * </td> + * <td valign='top' rowspan='1' colspan='1'> + * <pre>"x=5 y=6"</pre> + * </td> + * <td valign='top' rowspan='1' colspan='1'> + * <pre>"x=5 y=6"</pre> + * </td> + * </tr> + * <tr> + * <td valign='top' rowspan='1' colspan='1'>Entity <code>e</code> with literal newline</td> + * <td valign='top' rowspan='1' colspan='1'> + * <pre> + * <!ENTITY e '...&#10;...'> [...]> "x=5&e;y=6"</pre> + * </td> + * <td valign='top' rowspan='1' colspan='1'><em>Dependent on Implementation and Load Options</em></td> + * <td valign='top' rowspan='1' colspan='1'><em>Dependent on Implementation and Load/Save Options</em></td> + * </tr> + * </table> + * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document Object Model (DOM) Level 3 Core Specification</a>. + */ +public interface Attr extends Node { + /** + * Returns the name of this attribute. If <code>Node.localName</code> is + * different from <code>null</code>, this attribute is a qualified name. + */ + public String getName(); + + /** + * <code>True</code> if this attribute was explicitly given a value in + * the instance document, <code>false</code> otherwise. If the + * application changed the value of this attribute node (even if it ends + * up having the same value as the default value) then it is set to + * <code>true</code>. The implementation may handle attributes with + * default values from other schemas similarly but applications should + * use <code>Document.normalizeDocument()</code> to guarantee this + * information is up-to-date. + */ + public boolean getSpecified(); + + /** + * On retrieval, the value of the attribute is returned as a string. + * Character and general entity references are replaced with their + * values. See also the method <code>getAttribute</code> on the + * <code>Element</code> interface. + * <br>On setting, this creates a <code>Text</code> node with the unparsed + * contents of the string, i.e. any characters that an XML processor + * would recognize as markup are instead treated as literal text. See + * also the method <code>Element.setAttribute()</code>. + * <br> Some specialized implementations, such as some [<a href='http://www.w3.org/TR/2003/REC-SVG11-20030114/'>SVG 1.1</a>] + * implementations, may do normalization automatically, even after + * mutation; in such case, the value on retrieval may differ from the + * value on setting. + */ + public String getValue(); + /** + * On retrieval, the value of the attribute is returned as a string. + * Character and general entity references are replaced with their + * values. See also the method <code>getAttribute</code> on the + * <code>Element</code> interface. + * <br>On setting, this creates a <code>Text</code> node with the unparsed + * contents of the string, i.e. any characters that an XML processor + * would recognize as markup are instead treated as literal text. See + * also the method <code>Element.setAttribute()</code>. + * <br> Some specialized implementations, such as some [<a href='http://www.w3.org/TR/2003/REC-SVG11-20030114/'>SVG 1.1</a>] + * implementations, may do normalization automatically, even after + * mutation; in such case, the value on retrieval may differ from the + * value on setting. + * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly. + */ + public void setValue(String value) + throws DOMException; + + /** + * The <code>Element</code> node this attribute is attached to or + * <code>null</code> if this attribute is not in use. + * @since DOM Level 2 + */ + public Element getOwnerElement(); + + /** + * The type information associated with this attribute. While the type + * information contained in this attribute is guarantee to be correct + * after loading the document or invoking + * <code>Document.normalizeDocument()</code>, <code>schemaTypeInfo</code> + * may not be reliable if the node was moved. + * @since DOM Level 3 + */ + public TypeInfo getSchemaTypeInfo(); + + /** + * Returns whether this attribute is known to be of type ID (i.e. to + * contain an identifier for its owner element) or not. When it is and + * its value is unique, the <code>ownerElement</code> of this attribute + * can be retrieved using the method <code>Document.getElementById</code> + * . The implementation could use several ways to determine if an + * attribute node is known to contain an identifier: + * <ul> + * <li> If validation + * occurred using an XML Schema [<a href='http://www.w3.org/TR/2001/REC-xmlschema-1-20010502/'>XML Schema Part 1</a>] + * while loading the document or while invoking + * <code>Document.normalizeDocument()</code>, the post-schema-validation + * infoset contributions (PSVI contributions) values are used to + * determine if this attribute is a schema-determined ID attribute using + * the <a href='http://www.w3.org/TR/2003/REC-xptr-framework-20030325/#term-sdi'> + * schema-determined ID</a> definition in [<a href='http://www.w3.org/TR/2003/REC-xptr-framework-20030325/'>XPointer</a>] + * . + * </li> + * <li> If validation occurred using a DTD while loading the document or + * while invoking <code>Document.normalizeDocument()</code>, the infoset <b>[type definition]</b> value is used to determine if this attribute is a DTD-determined ID + * attribute using the <a href='http://www.w3.org/TR/2003/REC-xptr-framework-20030325/#term-ddi'> + * DTD-determined ID</a> definition in [<a href='http://www.w3.org/TR/2003/REC-xptr-framework-20030325/'>XPointer</a>] + * . + * </li> + * <li> from the use of the methods <code>Element.setIdAttribute()</code>, + * <code>Element.setIdAttributeNS()</code>, or + * <code>Element.setIdAttributeNode()</code>, i.e. it is an + * user-determined ID attribute; + * <p ><b>Note:</b> XPointer framework (see section 3.2 in [<a href='http://www.w3.org/TR/2003/REC-xptr-framework-20030325/'>XPointer</a>] + * ) consider the DOM user-determined ID attribute as being part of the + * XPointer externally-determined ID definition. + * </li> + * <li> using mechanisms that + * are outside the scope of this specification, it is then an + * externally-determined ID attribute. This includes using schema + * languages different from XML schema and DTD. + * </li> + * </ul> + * <br> If validation occurred while invoking + * <code>Document.normalizeDocument()</code>, all user-determined ID + * attributes are reset and all attribute nodes ID information are then + * reevaluated in accordance to the schema used. As a consequence, if + * the <code>Attr.schemaTypeInfo</code> attribute contains an ID type, + * <code>isId</code> will always return true. + * @since DOM Level 3 + */ + public boolean isId(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/CDATASection.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/CDATASection.java new file mode 100644 index 000000000..ce4b346eb --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/CDATASection.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom; + +/** + * CDATA sections are used to escape blocks of text containing characters that + * would otherwise be regarded as markup. The only delimiter that is + * recognized in a CDATA section is the "]]>" string that ends the CDATA + * section. CDATA sections cannot be nested. Their primary purpose is for + * including material such as XML fragments, without needing to escape all + * the delimiters. + * <p>The <code>CharacterData.data</code> attribute holds the text that is + * contained by the CDATA section. Note that this <em>may</em> contain characters that need to be escaped outside of CDATA sections and + * that, depending on the character encoding ("charset") chosen for + * serialization, it may be impossible to write out some characters as part + * of a CDATA section. + * <p>The <code>CDATASection</code> interface inherits from the + * <code>CharacterData</code> interface through the <code>Text</code> + * interface. Adjacent <code>CDATASection</code> nodes are not merged by use + * of the <code>normalize</code> method of the <code>Node</code> interface. + * <p> No lexical check is done on the content of a CDATA section and it is + * therefore possible to have the character sequence <code>"]]>"</code> + * in the content, which is illegal in a CDATA section per section 2.7 of [<a href='http://www.w3.org/TR/2004/REC-xml-20040204'>XML 1.0</a>]. The + * presence of this character sequence must generate a fatal error during + * serialization or the cdata section must be splitted before the + * serialization (see also the parameter <code>"split-cdata-sections"</code> + * in the <code>DOMConfiguration</code> interface). + * <p ><b>Note:</b> Because no markup is recognized within a + * <code>CDATASection</code>, character numeric references cannot be used as + * an escape mechanism when serializing. Therefore, action needs to be taken + * when serializing a <code>CDATASection</code> with a character encoding + * where some of the contained characters cannot be represented. Failure to + * do so would not produce well-formed XML. + * <p ><b>Note:</b> One potential solution in the serialization process is to + * end the CDATA section before the character, output the character using a + * character reference or entity reference, and open a new CDATA section for + * any further characters in the text node. Note, however, that some code + * conversion libraries at the time of writing do not return an error or + * exception when a character is missing from the encoding, making the task + * of ensuring that data is not corrupted on serialization more difficult. + * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document Object Model (DOM) Level 3 Core Specification</a>. + */ +public interface CDATASection extends Text { +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/CharacterData.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/CharacterData.java new file mode 100644 index 000000000..37aa8dffa --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/CharacterData.java @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom; + +/** + * The <code>CharacterData</code> interface extends Node with a set of + * attributes and methods for accessing character data in the DOM. For + * clarity this set is defined here rather than on each object that uses + * these attributes and methods. No DOM objects correspond directly to + * <code>CharacterData</code>, though <code>Text</code> and others do + * inherit the interface from it. All <code>offsets</code> in this interface + * start from <code>0</code>. + * <p>As explained in the <code>DOMString</code> interface, text strings in + * the DOM are represented in UTF-16, i.e. as a sequence of 16-bit units. In + * the following, the term 16-bit units is used whenever necessary to + * indicate that indexing on CharacterData is done in 16-bit units. + * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document Object Model (DOM) Level 3 Core Specification</a>. + */ +public interface CharacterData extends Node { + /** + * The character data of the node that implements this interface. The DOM + * implementation may not put arbitrary limits on the amount of data + * that may be stored in a <code>CharacterData</code> node. However, + * implementation limits may mean that the entirety of a node's data may + * not fit into a single <code>DOMString</code>. In such cases, the user + * may call <code>substringData</code> to retrieve the data in + * appropriately sized pieces. + * @exception DOMException + * DOMSTRING_SIZE_ERR: Raised when it would return more characters than + * fit in a <code>DOMString</code> variable on the implementation + * platform. + */ + public String getData() + throws DOMException; + /** + * The character data of the node that implements this interface. The DOM + * implementation may not put arbitrary limits on the amount of data + * that may be stored in a <code>CharacterData</code> node. However, + * implementation limits may mean that the entirety of a node's data may + * not fit into a single <code>DOMString</code>. In such cases, the user + * may call <code>substringData</code> to retrieve the data in + * appropriately sized pieces. + * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly. + */ + public void setData(String data) + throws DOMException; + + /** + * The number of 16-bit units that are available through <code>data</code> + * and the <code>substringData</code> method below. This may have the + * value zero, i.e., <code>CharacterData</code> nodes may be empty. + */ + public int getLength(); + + /** + * Extracts a range of data from the node. + * @param offset Start offset of substring to extract. + * @param count The number of 16-bit units to extract. + * @return The specified substring. If the sum of <code>offset</code> and + * <code>count</code> exceeds the <code>length</code>, then all 16-bit + * units to the end of the data are returned. + * @exception DOMException + * INDEX_SIZE_ERR: Raised if the specified <code>offset</code> is + * negative or greater than the number of 16-bit units in + * <code>data</code>, or if the specified <code>count</code> is + * negative. + * <br>DOMSTRING_SIZE_ERR: Raised if the specified range of text does + * not fit into a <code>DOMString</code>. + */ + public String substringData(int offset, + int count) + throws DOMException; + + /** + * Append the string to the end of the character data of the node. Upon + * success, <code>data</code> provides access to the concatenation of + * <code>data</code> and the <code>DOMString</code> specified. + * @param arg The <code>DOMString</code> to append. + * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly. + */ + public void appendData(String arg) + throws DOMException; + + /** + * Insert a string at the specified 16-bit unit offset. + * @param offset The character offset at which to insert. + * @param arg The <code>DOMString</code> to insert. + * @exception DOMException + * INDEX_SIZE_ERR: Raised if the specified <code>offset</code> is + * negative or greater than the number of 16-bit units in + * <code>data</code>. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly. + */ + public void insertData(int offset, + String arg) + throws DOMException; + + /** + * Remove a range of 16-bit units from the node. Upon success, + * <code>data</code> and <code>length</code> reflect the change. + * @param offset The offset from which to start removing. + * @param count The number of 16-bit units to delete. If the sum of + * <code>offset</code> and <code>count</code> exceeds + * <code>length</code> then all 16-bit units from <code>offset</code> + * to the end of the data are deleted. + * @exception DOMException + * INDEX_SIZE_ERR: Raised if the specified <code>offset</code> is + * negative or greater than the number of 16-bit units in + * <code>data</code>, or if the specified <code>count</code> is + * negative. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly. + */ + public void deleteData(int offset, + int count) + throws DOMException; + + /** + * Replace the characters starting at the specified 16-bit unit offset + * with the specified string. + * @param offset The offset from which to start replacing. + * @param count The number of 16-bit units to replace. If the sum of + * <code>offset</code> and <code>count</code> exceeds + * <code>length</code>, then all 16-bit units to the end of the data + * are replaced; (i.e., the effect is the same as a <code>remove</code> + * method call with the same range, followed by an <code>append</code> + * method invocation). + * @param arg The <code>DOMString</code> with which the range must be + * replaced. + * @exception DOMException + * INDEX_SIZE_ERR: Raised if the specified <code>offset</code> is + * negative or greater than the number of 16-bit units in + * <code>data</code>, or if the specified <code>count</code> is + * negative. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly. + */ + public void replaceData(int offset, + int count, + String arg) + throws DOMException; + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/Comment.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/Comment.java new file mode 100644 index 000000000..40b75274b --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/Comment.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom; + +/** + * This interface inherits from <code>CharacterData</code> and represents the + * content of a comment, i.e., all the characters between the starting ' + * <code><!--</code>' and ending '<code>--></code>'. Note that this is + * the definition of a comment in XML, and, in practice, HTML, although some + * HTML tools may implement the full SGML comment structure. + * <p> No lexical check is done on the content of a comment and it is + * therefore possible to have the character sequence <code>"--"</code> + * (double-hyphen) in the content, which is illegal in a comment per section + * 2.5 of [<a href='http://www.w3.org/TR/2004/REC-xml-20040204'>XML 1.0</a>]. The + * presence of this character sequence must generate a fatal error during + * serialization. + * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document Object Model (DOM) Level 3 Core Specification</a>. + */ +public interface Comment extends CharacterData { +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/DOMConfiguration.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/DOMConfiguration.java new file mode 100644 index 000000000..d05257868 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/DOMConfiguration.java @@ -0,0 +1,413 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom; + +/** + * The <code>DOMConfiguration</code> interface represents the configuration + * of a document and maintains a table of recognized parameters. Using the + * configuration, it is possible to change + * <code>Document.normalizeDocument()</code> behavior, such as replacing the + * <code>CDATASection</code> nodes with <code>Text</code> nodes or + * specifying the type of the schema that must be used when the validation + * of the <code>Document</code> is requested. <code>DOMConfiguration</code> + * objects are also used in [<a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-LS-20040407'>DOM Level 3 Load and Save</a>] + * in the <code>DOMParser</code> and <code>DOMSerializer</code> interfaces. + * <p> The parameter names used by the <code>DOMConfiguration</code> object + * are defined throughout the DOM Level 3 specifications. Names are + * case-insensitive. To avoid possible conflicts, as a convention, names + * referring to parameters defined outside the DOM specification should be + * made unique. Because parameters are exposed as properties in the , names + * are recommended to follow the section 5.16 Identifiers of [Unicode] with the addition of the character '-' (HYPHEN-MINUS) but it is not + * enforced by the DOM implementation. DOM Level 3 Core Implementations are + * required to recognize all parameters defined in this specification. Some + * parameter values may also be required to be supported by the + * implementation. Refer to the definition of the parameter to know if a + * value must be supported or not. + * <p ><b>Note:</b> Parameters are similar to features and properties used in + * SAX2 [<a href='http://www.saxproject.org/'>SAX</a>]. + * <p> The following list of parameters defined in the DOM: + * <dl> + * <dt> + * <code>"canonical-form"</code></dt> + * <dd> + * <dl> + * <dt><code>true</code></dt> + * <dd>[<em>optional</em>] Canonicalize the document according to the rules specified in [<a href='http://www.w3.org/TR/2001/REC-xml-c14n-20010315'>Canonical XML</a>], + * such as removing the <code>DocumentType</code> node (if any) from the + * tree, or removing superfluous namespace declarations from each element. + * Note that this is limited to what can be represented in the DOM; in + * particular, there is no way to specify the order of the attributes in the + * DOM. In addition, Setting this parameter to <code>true</code> will also + * set the state of the parameters listed below. Later changes to the state + * of one of those parameters will revert "canonical-form" back to + * <code>false</code>. Parameters set to <code>false</code>: "entities", " + * normalize-characters", "cdata-sections". Parameters set to + * <code>true</code>: "namespaces", "namespace-declarations", "well-formed", + * "element-content-whitespace". Other parameters are not changed unless + * explicitly specified in the description of the parameters.</dd> + * <dt> + * <code>false</code></dt> + * <dd>[<em>required</em>] (<em>default</em>)Do not canonicalize the document.</dd> + * </dl></dd> + * <dt><code>"cdata-sections"</code></dt> + * <dd> + * <dl> + * <dt> + * <code>true</code></dt> + * <dd>[<em>required</em>] (<em>default</em>)Keep <code>CDATASection</code> nodes in the document.</dd> + * <dt><code>false</code></dt> + * <dd>[<em>required</em>]Transform <code>CDATASection</code> nodes in the document into + * <code>Text</code> nodes. The new <code>Text</code> node is then combined + * with any adjacent <code>Text</code> node.</dd> + * </dl></dd> + * <dt> + * <code>"check-character-normalization"</code></dt> + * <dd> + * <dl> + * <dt><code>true</code></dt> + * <dd>[<em>optional</em>] Check if the characters in the document are <a href='http://www.w3.org/TR/2004/REC-xml11-20040204/#dt-fullnorm'>fully + * normalized</a>, as defined in appendix B of [<a href='http://www.w3.org/TR/2004/REC-xml11-20040204/'>XML 1.1</a>]. When a + * sequence of characters is encountered that fails normalization checking, + * an error with the <code>DOMError.type</code> equals to + * "check-character-normalization-failure" is issued. </dd> + * <dt><code>false</code></dt> + * <dd>[<em>required</em>] (<em>default</em>)Do not check if characters are normalized.</dd> + * </dl></dd> + * <dt><code>"comments"</code></dt> + * <dd> + * <dl> + * <dt> + * <code>true</code></dt> + * <dd>[<em>required</em>] (<em>default</em>)Keep <code>Comment</code> nodes in the document.</dd> + * <dt><code>false</code></dt> + * <dd>[<em>required</em>]Discard <code>Comment</code> nodes in the document.</dd> + * </dl></dd> + * <dt> + * <code>"datatype-normalization"</code></dt> + * <dd> + * <dl> + * <dt><code>true</code></dt> + * <dd>[<em>optional</em>] Expose schema normalized values in the tree, such as <a href='http://www.w3.org/TR/2001/REC-xmlschema-1-20010502/#key-nv'>XML + * Schema normalized values</a> in the case of XML Schema. Since this parameter requires to have schema + * information, the "validate" parameter will also be set to + * <code>true</code>. Having this parameter activated when "validate" is + * <code>false</code> has no effect and no schema-normalization will happen. + * <p ><b>Note:</b> Since the document contains the result of the XML 1.0 + * processing, this parameter does not apply to attribute value + * normalization as defined in section 3.3.3 of [<a href='http://www.w3.org/TR/2004/REC-xml-20040204'>XML 1.0</a>] and is only + * meant for schema languages other than Document Type Definition (DTD). </dd> + * <dt> + * <code>false</code></dt> + * <dd>[<em>required</em>] (<em>default</em>) Do not perform schema normalization on the tree. </dd> + * </dl></dd> + * <dt> + * <code>"element-content-whitespace"</code></dt> + * <dd> + * <dl> + * <dt><code>true</code></dt> + * <dd>[<em>required</em>] (<em>default</em>)Keep all whitespaces in the document.</dd> + * <dt><code>false</code></dt> + * <dd>[<em>optional</em>] Discard all <code>Text</code> nodes that contain whitespaces in element + * content, as described in <a href='http://www.w3.org/TR/2004/REC-xml-infoset-20040204#infoitem.character'> + * [element content whitespace]</a>. The implementation is expected to use the attribute + * <code>Text.isElementContentWhitespace</code> to determine if a + * <code>Text</code> node should be discarded or not.</dd> + * </dl></dd> + * <dt><code>"entities"</code></dt> + * <dd> + * <dl> + * <dt> + * <code>true</code></dt> + * <dd>[<em>required</em>] (<em>default</em>)Keep <code>EntityReference</code> nodes in the document.</dd> + * <dt> + * <code>false</code></dt> + * <dd>[<em>required</em>] Remove all <code>EntityReference</code> nodes from the document, + * putting the entity expansions directly in their place. <code>Text</code> + * nodes are normalized, as defined in <code>Node.normalize</code>. Only <a href='http://www.w3.org/TR/2004/REC-xml-infoset-20040204/#infoitem.rse'> + * unexpanded entity references</a> are kept in the document. </dd> + * </dl> + * <p ><b>Note:</b> This parameter does not affect <code>Entity</code> nodes. </dd> + * <dt> + * <code>"error-handler"</code></dt> + * <dd>[<em>required</em>] Contains a <code>DOMErrorHandler</code> object. If an error is + * encountered in the document, the implementation will call back the + * <code>DOMErrorHandler</code> registered using this parameter. The + * implementation may provide a default <code>DOMErrorHandler</code> object. + * When called, <code>DOMError.relatedData</code> will contain the closest + * node to where the error occurred. If the implementation is unable to + * determine the node where the error occurs, + * <code>DOMError.relatedData</code> will contain the <code>Document</code> + * node. Mutations to the document from within an error handler will result + * in implementation dependent behavior. </dd> + * <dt><code>"infoset"</code></dt> + * <dd> + * <dl> + * <dt> + * <code>true</code></dt> + * <dd>[<em>required</em>]Keep in the document the information defined in the XML Information Set [<a href='http://www.w3.org/TR/2004/REC-xml-infoset-20040204/'>XML Information Set</a>] + * .This forces the following parameters to <code>false</code>: " + * validate-if-schema", "entities", "datatype-normalization", "cdata-sections + * ".This forces the following parameters to <code>true</code>: " + * namespace-declarations", "well-formed", "element-content-whitespace", " + * comments", "namespaces".Other parameters are not changed unless + * explicitly specified in the description of the parameters. Note that + * querying this parameter with <code>getParameter</code> returns + * <code>true</code> only if the individual parameters specified above are + * appropriately set.</dd> + * <dt><code>false</code></dt> + * <dd>Setting <code>infoset</code> to + * <code>false</code> has no effect.</dd> + * </dl></dd> + * <dt><code>"namespaces"</code></dt> + * <dd> + * <dl> + * <dt> + * <code>true</code></dt> + * <dd>[<em>required</em>] (<em>default</em>) Perform the namespace processing as defined in . </dd> + * <dt><code>false</code></dt> + * <dd>[<em>optional</em>] Do not perform the namespace processing. </dd> + * </dl></dd> + * <dt> + * <code>"namespace-declarations"</code></dt> + * <dd> This parameter has no effect if the + * parameter "namespaces" is set to <code>false</code>. + * <dl> + * <dt><code>true</code></dt> + * <dd>[<em>required</em>] (<em>default</em>) Include namespace declaration attributes, specified or defaulted from + * the schema, in the document. See also the sections "Declaring Namespaces" + * in [<a href='http://www.w3.org/TR/1999/REC-xml-names-19990114/'>XML Namespaces</a>] + * and [<a href='http://www.w3.org/TR/2004/REC-xml-names11-20040204/'>XML Namespaces 1.1</a>] + * .</dd> + * <dt><code>false</code></dt> + * <dd>[<em>required</em>]Discard all namespace declaration attributes. The namespace prefixes ( + * <code>Node.prefix</code>) are retained even if this parameter is set to + * <code>false</code>.</dd> + * </dl></dd> + * <dt><code>"normalize-characters"</code></dt> + * <dd> + * <dl> + * <dt><code>true</code></dt> + * <dd>[<em>optional</em>] <a href='http://www.w3.org/TR/2004/REC-xml11-20040204/#dt-fullnorm'>Fully + * normalized</a> the characters in the document as defined in appendix B of [<a href='http://www.w3.org/TR/2004/REC-xml11-20040204/'>XML 1.1</a>]. </dd> + * <dt> + * <code>false</code></dt> + * <dd>[<em>required</em>] (<em>default</em>)Do not perform character normalization.</dd> + * </dl></dd> + * <dt><code>"schema-location"</code></dt> + * <dd>[<em>optional</em>] Represent a <code>DOMString</code> object containing a list of URIs, + * separated by whitespaces (characters matching the <a href='http://www.w3.org/TR/2004/REC-xml-20040204#NT-S'>nonterminal + * production S</a> defined in section 2.3 [<a href='http://www.w3.org/TR/2004/REC-xml-20040204'>XML 1.0</a>]), that + * represents the schemas against which validation should occur, i.e. the + * current schema. The types of schemas referenced in this list must match + * the type specified with <code>schema-type</code>, otherwise the behavior + * of an implementation is undefined. The schemas specified using this + * property take precedence to the schema information specified in the + * document itself. For namespace aware schema, if a schema specified using + * this property and a schema specified in the document instance (i.e. using + * the <code>schemaLocation</code> attribute) in a schema document (i.e. + * using schema <code>import</code> mechanisms) share the same + * <code>targetNamespace</code>, the schema specified by the user using this + * property will be used. If two schemas specified using this property share + * the same <code>targetNamespace</code> or have no namespace, the behavior + * is implementation dependent. If no location has been provided, this + * parameter is <code>null</code>. + * <p ><b>Note:</b> The <code>"schema-location"</code> parameter is ignored + * unless the "schema-type" parameter value is set. It is strongly + * recommended that <code>Document.documentURI</code> will be set so that an + * implementation can successfully resolve any external entities referenced. </dd> + * <dt> + * <code>"schema-type"</code></dt> + * <dd>[<em>optional</em>] Represent a <code>DOMString</code> object containing an absolute URI + * and representing the type of the schema language used to validate a + * document against. Note that no lexical checking is done on the absolute + * URI. If this parameter is not set, a default value may be provided by + * the implementation, based on the schema languages supported and on the + * schema language used at load time. If no value is provided, this + * parameter is <code>null</code>. + * <p ><b>Note:</b> For XML Schema [<a href='http://www.w3.org/TR/2001/REC-xmlschema-1-20010502/'>XML Schema Part 1</a>] + * , applications must use the value + * <code>"http://www.w3.org/2001/XMLSchema"</code>. For XML DTD [<a href='http://www.w3.org/TR/2004/REC-xml-20040204'>XML 1.0</a>], + * applications must use the value + * <code>"http://www.w3.org/TR/REC-xml"</code>. Other schema languages are + * outside the scope of the W3C and therefore should recommend an absolute + * URI in order to use this method. </dd> + * <dt><code>"split-cdata-sections"</code></dt> + * <dd> + * <dl> + * <dt> + * <code>true</code></dt> + * <dd>[<em>required</em>] (<em>default</em>)Split CDATA sections containing the CDATA section termination marker + * ']]>'. When a CDATA section is split a warning is issued with a + * <code>DOMError.type</code> equals to + * <code>"cdata-sections-splitted"</code> and + * <code>DOMError.relatedData</code> equals to the first + * <code>CDATASection</code> node in document order resulting from the split.</dd> + * <dt> + * <code>false</code></dt> + * <dd>[<em>required</em>]Signal an error if a <code>CDATASection</code> contains an + * unrepresentable character.</dd> + * </dl></dd> + * <dt><code>"validate"</code></dt> + * <dd> + * <dl> + * <dt><code>true</code></dt> + * <dd>[<em>optional</em>] Require the validation against a schema (i.e. XML schema, DTD, any + * other type or representation of schema) of the document as it is being + * normalized as defined by [<a href='http://www.w3.org/TR/2004/REC-xml-20040204'>XML 1.0</a>]. If + * validation errors are found, or no schema was found, the error handler is + * notified. Schema-normalized values will not be exposed according to the + * schema in used unless the parameter "datatype-normalization" is + * <code>true</code>. This parameter will reevaluate: + * <ul> + * <li> Attribute nodes with + * <code>Attr.specified</code> equals to <code>false</code>, as specified in + * the description of the <code>Attr</code> interface; + * </li> + * <li> The value of the + * attribute <code>Text.isElementContentWhitespace</code> for all + * <code>Text</code> nodes; + * </li> + * <li> The value of the attribute + * <code>Attr.isId</code> for all <code>Attr</code> nodes; + * </li> + * <li> The attributes + * <code>Element.schemaTypeInfo</code> and <code>Attr.schemaTypeInfo</code>. + * </li> + * </ul> + * <p ><b>Note:</b> "validate-if-schema" and "validate" are mutually + * exclusive, setting one of them to <code>true</code> will set the other + * one to <code>false</code>. Applications should also consider setting the + * parameter "well-formed" to <code>true</code>, which is the default for + * that option, when validating the document. </dd> + * <dt><code>false</code></dt> + * <dd>[<em>required</em>] (<em>default</em>) Do not accomplish schema processing, including the internal subset + * processing. Default attribute values information are kept. Note that + * validation might still happen if "validate-if-schema" is <code>true</code> + * . </dd> + * </dl></dd> + * <dt><code>"validate-if-schema"</code></dt> + * <dd> + * <dl> + * <dt><code>true</code></dt> + * <dd>[<em>optional</em>]Enable validation only if a declaration for the document element can be + * found in a schema (independently of where it is found, i.e. XML schema, + * DTD, or any other type or representation of schema). If validation is + * enabled, this parameter has the same behavior as the parameter "validate" + * set to <code>true</code>. + * <p ><b>Note:</b> "validate-if-schema" and "validate" are mutually + * exclusive, setting one of them to <code>true</code> will set the other + * one to <code>false</code>. </dd> + * <dt><code>false</code></dt> + * <dd>[<em>required</em>] (<em>default</em>) No schema processing should be performed if the document has a schema, + * including internal subset processing. Default attribute values + * information are kept. Note that validation must still happen if "validate + * " is <code>true</code>. </dd> + * </dl></dd> + * <dt><code>"well-formed"</code></dt> + * <dd> + * <dl> + * <dt><code>true</code></dt> + * <dd>[<em>required</em>] (<em>default</em>) Check if all nodes are XML well formed according to the XML version in + * use in <code>Document.xmlVersion</code>: + * <ul> + * <li> check if the attribute + * <code>Node.nodeName</code> contains invalid characters according to its + * node type and generate a <code>DOMError</code> of type + * <code>"wf-invalid-character-in-node-name"</code>, with a + * <code>DOMError.SEVERITY_ERROR</code> severity, if necessary; + * </li> + * <li> check if + * the text content inside <code>Attr</code>, <code>Element</code>, + * <code>Comment</code>, <code>Text</code>, <code>CDATASection</code> nodes + * for invalid characters and generate a <code>DOMError</code> of type + * <code>"wf-invalid-character"</code>, with a + * <code>DOMError.SEVERITY_ERROR</code> severity, if necessary; + * </li> + * <li> check if + * the data inside <code>ProcessingInstruction</code> nodes for invalid + * characters and generate a <code>DOMError</code> of type + * <code>"wf-invalid-character"</code>, with a + * <code>DOMError.SEVERITY_ERROR</code> severity, if necessary; + * </li> + * </ul></dd> + * <dt> + * <code>false</code></dt> + * <dd>[<em>optional</em>] Do not check for XML well-formedness. </dd> + * </dl></dd> + * </dl> + * <p> The resolution of the system identifiers associated with entities is + * done using <code>Document.documentURI</code>. However, when the feature + * "LS" defined in [<a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-LS-20040407'>DOM Level 3 Load and Save</a>] + * is supported by the DOM implementation, the parameter + * "resource-resolver" can also be used on <code>DOMConfiguration</code> + * objects attached to <code>Document</code> nodes. If this parameter is + * set, <code>Document.normalizeDocument()</code> will invoke the resource + * resolver instead of using <code>Document.documentURI</code>. + * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document Object Model (DOM) Level 3 Core Specification</a>. + * @since DOM Level 3 + */ +public interface DOMConfiguration { + /** + * Set the value of a parameter. + * @param name The name of the parameter to set. + * @param value The new value or <code>null</code> if the user wishes to + * unset the parameter. While the type of the value parameter is + * defined as <code>DOMUserData</code>, the object type must match the + * type defined by the definition of the parameter. For example, if + * the parameter is "error-handler", the value must be of type + * <code>DOMErrorHandler</code>. + * @exception DOMException + * NOT_FOUND_ERR: Raised when the parameter name is not recognized. + * <br> NOT_SUPPORTED_ERR: Raised when the parameter name is recognized + * but the requested value cannot be set. + * <br> TYPE_MISMATCH_ERR: Raised if the value type for this parameter + * name is incompatible with the expected value type. + */ + public void setParameter(String name, + Object value) + throws DOMException; + + /** + * Return the value of a parameter if known. + * @param name The name of the parameter. + * @return The current object associated with the specified parameter or + * <code>null</code> if no object has been associated or if the + * parameter is not supported. + * @exception DOMException + * NOT_FOUND_ERR: Raised when the parameter name is not recognized. + */ + public Object getParameter(String name) + throws DOMException; + + /** + * Check if setting a parameter to a specific value is supported. + * @param name The name of the parameter to check. + * @param value An object. if <code>null</code>, the returned value is + * <code>true</code>. + * @return <code>true</code> if the parameter could be successfully set + * to the specified value, or <code>false</code> if the parameter is + * not recognized or the requested value is not supported. This does + * not change the current value of the parameter itself. + */ + public boolean canSetParameter(String name, + Object value); + + /** + * The list of the parameters supported by this + * <code>DOMConfiguration</code> object and for which at least one value + * can be set by the application. Note that this list can also contain + * parameter names defined outside this specification. + */ + public DOMStringList getParameterNames(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/DOMError.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/DOMError.java new file mode 100644 index 000000000..2634df37c --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/DOMError.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom; + +/** + * <code>DOMError</code> is an interface that describes an error. + * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document Object Model (DOM) Level 3 Core Specification</a>. + * @since DOM Level 3 + */ +public interface DOMError { + // ErrorSeverity + /** + * The severity of the error described by the <code>DOMError</code> is + * warning. A <code>SEVERITY_WARNING</code> will not cause the + * processing to stop, unless <code>DOMErrorHandler.handleError()</code> + * returns <code>false</code>. + */ + public static final short SEVERITY_WARNING = 1; + /** + * The severity of the error described by the <code>DOMError</code> is + * error. A <code>SEVERITY_ERROR</code> may not cause the processing to + * stop if the error can be recovered, unless + * <code>DOMErrorHandler.handleError()</code> returns <code>false</code>. + */ + public static final short SEVERITY_ERROR = 2; + /** + * The severity of the error described by the <code>DOMError</code> is + * fatal error. A <code>SEVERITY_FATAL_ERROR</code> will cause the + * normal processing to stop. The return value of + * <code>DOMErrorHandler.handleError()</code> is ignored unless the + * implementation chooses to continue, in which case the behavior + * becomes undefined. + */ + public static final short SEVERITY_FATAL_ERROR = 3; + + /** + * The severity of the error, either <code>SEVERITY_WARNING</code>, + * <code>SEVERITY_ERROR</code>, or <code>SEVERITY_FATAL_ERROR</code>. + */ + public short getSeverity(); + + /** + * An implementation specific string describing the error that occurred. + */ + public String getMessage(); + + /** + * A <code>DOMString</code> indicating which related data is expected in + * <code>relatedData</code>. Users should refer to the specification of + * the error in order to find its <code>DOMString</code> type and + * <code>relatedData</code> definitions if any. + * <p ><b>Note:</b> As an example, + * <code>Document.normalizeDocument()</code> does generate warnings when + * the "split-cdata-sections" parameter is in use. Therefore, the method + * generates a <code>SEVERITY_WARNING</code> with <code>type</code> + * <code>"cdata-sections-splitted"</code> and the first + * <code>CDATASection</code> node in document order resulting from the + * split is returned by the <code>relatedData</code> attribute. + */ + public String getType(); + + /** + * The related platform dependent exception if any. + */ + public Object getRelatedException(); + + /** + * The related <code>DOMError.type</code> dependent data if any. + */ + public Object getRelatedData(); + + /** + * The location of the error. + */ + public DOMLocator getLocation(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/DOMErrorHandler.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/DOMErrorHandler.java new file mode 100644 index 000000000..7dcc90152 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/DOMErrorHandler.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom; + +/** + * <code>DOMErrorHandler</code> is a callback interface that the DOM + * implementation can call when reporting errors that happens while + * processing XML data, or when doing some other processing (e.g. validating + * a document). A <code>DOMErrorHandler</code> object can be attached to a + * <code>Document</code> using the "error-handler" on the + * <code>DOMConfiguration</code> interface. If more than one error needs to + * be reported during an operation, the sequence and numbers of the errors + * passed to the error handler are implementation dependent. + * <p> The application that is using the DOM implementation is expected to + * implement this interface. + * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document Object Model (DOM) Level 3 Core Specification</a>. + * @since DOM Level 3 + */ +public interface DOMErrorHandler { + /** + * This method is called on the error handler when an error occurs. + * <br> If an exception is thrown from this method, it is considered to be + * equivalent of returning <code>true</code>. + * @param error The error object that describes the error. This object + * may be reused by the DOM implementation across multiple calls to + * the <code>handleError</code> method. + * @return If the <code>handleError</code> method returns + * <code>false</code>, the DOM implementation should stop the current + * processing when possible. If the method returns <code>true</code>, + * the processing may continue depending on + * <code>DOMError.severity</code>. + */ + public boolean handleError(DOMError error); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/DOMException.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/DOMException.java new file mode 100644 index 000000000..23c70c400 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/DOMException.java @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom; + +/** + * DOM operations only raise exceptions in "exceptional" circumstances, i.e., + * when an operation is impossible to perform (either for logical reasons, + * because data is lost, or because the implementation has become unstable). + * In general, DOM methods return specific error values in ordinary + * processing situations, such as out-of-bound errors when using + * <code>NodeList</code>. + * <p>Implementations should raise other exceptions under other circumstances. + * For example, implementations should raise an implementation-dependent + * exception if a <code>null</code> argument is passed when <code>null</code> + * was not expected. + * <p>Some languages and object systems do not support the concept of + * exceptions. For such systems, error conditions may be indicated using + * native error reporting mechanisms. For some bindings, for example, + * methods may return error codes similar to those listed in the + * corresponding method descriptions. + * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document Object Model (DOM) Level 3 Core Specification</a>. + */ +public class DOMException extends RuntimeException { + public DOMException(short code, String message) { + super(message); + this.code = code; + } + public short code; + // ExceptionCode + /** + * If index or size is negative, or greater than the allowed value. + */ + public static final short INDEX_SIZE_ERR = 1; + /** + * If the specified range of text does not fit into a + * <code>DOMString</code>. + */ + public static final short DOMSTRING_SIZE_ERR = 2; + /** + * If any <code>Node</code> is inserted somewhere it doesn't belong. + */ + public static final short HIERARCHY_REQUEST_ERR = 3; + /** + * If a <code>Node</code> is used in a different document than the one + * that created it (that doesn't support it). + */ + public static final short WRONG_DOCUMENT_ERR = 4; + /** + * If an invalid or illegal character is specified, such as in an XML name. + */ + public static final short INVALID_CHARACTER_ERR = 5; + /** + * If data is specified for a <code>Node</code> which does not support + * data. + */ + public static final short NO_DATA_ALLOWED_ERR = 6; + /** + * If an attempt is made to modify an object where modifications are not + * allowed. + */ + public static final short NO_MODIFICATION_ALLOWED_ERR = 7; + /** + * If an attempt is made to reference a <code>Node</code> in a context + * where it does not exist. + */ + public static final short NOT_FOUND_ERR = 8; + /** + * If the implementation does not support the requested type of object or + * operation. + */ + public static final short NOT_SUPPORTED_ERR = 9; + /** + * If an attempt is made to add an attribute that is already in use + * elsewhere. + */ + public static final short INUSE_ATTRIBUTE_ERR = 10; + /** + * If an attempt is made to use an object that is not, or is no longer, + * usable. + * @since DOM Level 2 + */ + public static final short INVALID_STATE_ERR = 11; + /** + * If an invalid or illegal string is specified. + * @since DOM Level 2 + */ + public static final short SYNTAX_ERR = 12; + /** + * If an attempt is made to modify the type of the underlying object. + * @since DOM Level 2 + */ + public static final short INVALID_MODIFICATION_ERR = 13; + /** + * If an attempt is made to create or change an object in a way which is + * incorrect with regard to namespaces. + * @since DOM Level 2 + */ + public static final short NAMESPACE_ERR = 14; + /** + * If a parameter or an operation is not supported by the underlying + * object. + * @since DOM Level 2 + */ + public static final short INVALID_ACCESS_ERR = 15; + /** + * If a call to a method such as <code>insertBefore</code> or + * <code>removeChild</code> would make the <code>Node</code> invalid + * with respect to "partial validity", this exception would be raised + * and the operation would not be done. This code is used in [<a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Val-20040127/'>DOM Level 3 Validation</a>] + * . Refer to this specification for further information. + * @since DOM Level 3 + */ + public static final short VALIDATION_ERR = 16; + /** + * If the type of an object is incompatible with the expected type of the + * parameter associated to the object. + * @since DOM Level 3 + */ + public static final short TYPE_MISMATCH_ERR = 17; + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/DOMImplementation.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/DOMImplementation.java new file mode 100644 index 000000000..9b0757433 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/DOMImplementation.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom; + +/** + * The <code>DOMImplementation</code> interface provides a number of methods + * for performing operations that are independent of any particular instance + * of the document object model. + * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document Object Model (DOM) Level 3 Core Specification</a>. + */ +public interface DOMImplementation { + /** + * Test if the DOM implementation implements a specific feature and + * version, as specified in . + * @param feature The name of the feature to test. + * @param version This is the version number of the feature to test. + * @return <code>true</code> if the feature is implemented in the + * specified version, <code>false</code> otherwise. + */ + public boolean hasFeature(String feature, + String version); + + /** + * Creates an empty <code>DocumentType</code> node. Entity declarations + * and notations are not made available. Entity reference expansions and + * default attribute additions do not occur.. + * @param qualifiedName The qualified name of the document type to be + * created. + * @param publicId The external subset public identifier. + * @param systemId The external subset system identifier. + * @return A new <code>DocumentType</code> node with + * <code>Node.ownerDocument</code> set to <code>null</code>. + * @exception DOMException + * INVALID_CHARACTER_ERR: Raised if the specified qualified name is not + * an XML name according to [<a href='http://www.w3.org/TR/2004/REC-xml-20040204'>XML 1.0</a>]. + * <br>NAMESPACE_ERR: Raised if the <code>qualifiedName</code> is + * malformed. + * <br>NOT_SUPPORTED_ERR: May be raised if the implementation does not + * support the feature "XML" and the language exposed through the + * Document does not support XML Namespaces (such as [<a href='http://www.w3.org/TR/1999/REC-html401-19991224/'>HTML 4.01</a>]). + * @since DOM Level 2 + */ + public DocumentType createDocumentType(String qualifiedName, + String publicId, + String systemId) + throws DOMException; + + /** + * Creates a DOM Document object of the specified type with its document + * element. + * <br>Note that based on the <code>DocumentType</code> given to create + * the document, the implementation may instantiate specialized + * <code>Document</code> objects that support additional features than + * the "Core", such as "HTML" [<a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>DOM Level 2 HTML</a>] + * . On the other hand, setting the <code>DocumentType</code> after the + * document was created makes this very unlikely to happen. + * Alternatively, specialized <code>Document</code> creation methods, + * such as <code>createHTMLDocument</code> [<a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>DOM Level 2 HTML</a>] + * , can be used to obtain specific types of <code>Document</code> + * objects. + * @param namespaceURI The namespace URI of the document element to + * create or <code>null</code>. + * @param qualifiedName The qualified name of the document element to be + * created or <code>null</code>. + * @param doctype The type of document to be created or <code>null</code>. + * When <code>doctype</code> is not <code>null</code>, its + * <code>Node.ownerDocument</code> attribute is set to the document + * being created. + * @return A new <code>Document</code> object with its document element. + * If the <code>NamespaceURI</code>, <code>qualifiedName</code>, and + * <code>doctype</code> are <code>null</code>, the returned + * <code>Document</code> is empty with no document element. + * @exception DOMException + * INVALID_CHARACTER_ERR: Raised if the specified qualified name is not + * an XML name according to [<a href='http://www.w3.org/TR/2004/REC-xml-20040204'>XML 1.0</a>]. + * <br>NAMESPACE_ERR: Raised if the <code>qualifiedName</code> is + * malformed, if the <code>qualifiedName</code> has a prefix and the + * <code>namespaceURI</code> is <code>null</code>, or if the + * <code>qualifiedName</code> is <code>null</code> and the + * <code>namespaceURI</code> is different from <code>null</code>, or + * if the <code>qualifiedName</code> has a prefix that is "xml" and + * the <code>namespaceURI</code> is different from "<a href='http://www.w3.org/XML/1998/namespace'> + * http://www.w3.org/XML/1998/namespace</a>" [<a href='http://www.w3.org/TR/1999/REC-xml-names-19990114/'>XML Namespaces</a>] + * , or if the DOM implementation does not support the + * <code>"XML"</code> feature but a non-null namespace URI was + * provided, since namespaces were defined by XML. + * <br>WRONG_DOCUMENT_ERR: Raised if <code>doctype</code> has already + * been used with a different document or was created from a different + * implementation. + * <br>NOT_SUPPORTED_ERR: May be raised if the implementation does not + * support the feature "XML" and the language exposed through the + * Document does not support XML Namespaces (such as [<a href='http://www.w3.org/TR/1999/REC-html401-19991224/'>HTML 4.01</a>]). + * @since DOM Level 2 + */ + public Document createDocument(String namespaceURI, + String qualifiedName, + DocumentType doctype) + throws DOMException; + + /** + * This method returns a specialized object which implements the + * specialized APIs of the specified feature and version, as specified + * in . The specialized object may also be obtained by using + * binding-specific casting methods but is not necessarily expected to, + * as discussed in . This method also allow the implementation to + * provide specialized objects which do not support the + * <code>DOMImplementation</code> interface. + * @param feature The name of the feature requested. Note that any plus + * sign "+" prepended to the name of the feature will be ignored since + * it is not significant in the context of this method. + * @param version This is the version number of the feature to test. + * @return Returns an object which implements the specialized APIs of + * the specified feature and version, if any, or <code>null</code> if + * there is no object which implements interfaces associated with that + * feature. If the <code>DOMObject</code> returned by this method + * implements the <code>DOMImplementation</code> interface, it must + * delegate to the primary core <code>DOMImplementation</code> and not + * return results inconsistent with the primary core + * <code>DOMImplementation</code> such as <code>hasFeature</code>, + * <code>getFeature</code>, etc. + * @since DOM Level 3 + */ + public Object getFeature(String feature, + String version); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/DOMImplementationList.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/DOMImplementationList.java new file mode 100644 index 000000000..877de6efe --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/DOMImplementationList.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom; + +/** + * The <code>DOMImplementationList</code> interface provides the abstraction + * of an ordered collection of DOM implementations, without defining or + * constraining how this collection is implemented. The items in the + * <code>DOMImplementationList</code> are accessible via an integral index, + * starting from 0. + * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document Object Model (DOM) Level 3 Core Specification</a>. + * @since DOM Level 3 + */ +public interface DOMImplementationList { + /** + * Returns the <code>index</code>th item in the collection. If + * <code>index</code> is greater than or equal to the number of + * <code>DOMImplementation</code>s in the list, this returns + * <code>null</code>. + * @param index Index into the collection. + * @return The <code>DOMImplementation</code> at the <code>index</code> + * th position in the <code>DOMImplementationList</code>, or + * <code>null</code> if that is not a valid index. + */ + public DOMImplementation item(int index); + + /** + * The number of <code>DOMImplementation</code>s in the list. The range + * of valid child node indices is 0 to <code>length-1</code> inclusive. + */ + public int getLength(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/DOMImplementationSource.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/DOMImplementationSource.java new file mode 100644 index 000000000..1c5c0b2fe --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/DOMImplementationSource.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom; + +/** + * This interface permits a DOM implementer to supply one or more + * implementations, based upon requested features and versions, as specified + * in . Each implemented <code>DOMImplementationSource</code> object is + * listed in the binding-specific list of available sources so that its + * <code>DOMImplementation</code> objects are made available. + * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document Object Model (DOM) Level 3 Core Specification</a>. + * @since DOM Level 3 + */ +public interface DOMImplementationSource { + /** + * A method to request the first DOM implementation that supports the + * specified features. + * @param features A string that specifies which features and versions + * are required. This is a space separated list in which each feature + * is specified by its name optionally followed by a space and a + * version number. This method returns the first item of the list + * returned by <code>getDOMImplementationList</code>. As an example, + * the string <code>"XML 3.0 Traversal +Events 2.0"</code> will + * request a DOM implementation that supports the module "XML" for its + * 3.0 version, a module that support of the "Traversal" module for + * any version, and the module "Events" for its 2.0 version. The + * module "Events" must be accessible using the method + * <code>Node.getFeature()</code> and + * <code>DOMImplementation.getFeature()</code>. + * @return The first DOM implementation that support the desired + * features, or <code>null</code> if this source has none. + */ + public DOMImplementation getDOMImplementation(String features); + + /** + * A method to request a list of DOM implementations that support the + * specified features and versions, as specified in . + * @param features A string that specifies which features and versions + * are required. This is a space separated list in which each feature + * is specified by its name optionally followed by a space and a + * version number. This is something like: "XML 3.0 Traversal +Events + * 2.0" + * @return A list of DOM implementations that support the desired + * features. + */ + public DOMImplementationList getDOMImplementationList(String features); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/DOMLocator.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/DOMLocator.java new file mode 100644 index 000000000..50cd7d240 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/DOMLocator.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom; + +/** + * <code>DOMLocator</code> is an interface that describes a location (e.g. + * where an error occurred). + * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document Object Model (DOM) Level 3 Core Specification</a>. + * @since DOM Level 3 + */ +public interface DOMLocator { + /** + * The line number this locator is pointing to, or <code>-1</code> if + * there is no column number available. + */ + public int getLineNumber(); + + /** + * The column number this locator is pointing to, or <code>-1</code> if + * there is no column number available. + */ + public int getColumnNumber(); + + /** + * The byte offset into the input source this locator is pointing to or + * <code>-1</code> if there is no byte offset available. + */ + public int getByteOffset(); + + /** + * The UTF-16, as defined in [Unicode] and Amendment 1 of [ISO/IEC 10646], offset into the input source this locator is pointing to or + * <code>-1</code> if there is no UTF-16 offset available. + */ + public int getUtf16Offset(); + + /** + * The node this locator is pointing to, or <code>null</code> if no node + * is available. + */ + public Node getRelatedNode(); + + /** + * The URI this locator is pointing to, or <code>null</code> if no URI is + * available. + */ + public String getUri(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/DOMStringList.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/DOMStringList.java new file mode 100644 index 000000000..53a40964e --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/DOMStringList.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom; + +/** + * The <code>DOMStringList</code> interface provides the abstraction of an + * ordered collection of <code>DOMString</code> values, without defining or + * constraining how this collection is implemented. The items in the + * <code>DOMStringList</code> are accessible via an integral index, starting + * from 0. + * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document Object Model (DOM) Level 3 Core Specification</a>. + * @since DOM Level 3 + */ +public interface DOMStringList { + /** + * Returns the <code>index</code>th item in the collection. If + * <code>index</code> is greater than or equal to the number of + * <code>DOMString</code>s in the list, this returns <code>null</code>. + * @param index Index into the collection. + * @return The <code>DOMString</code> at the <code>index</code>th + * position in the <code>DOMStringList</code>, or <code>null</code> if + * that is not a valid index. + */ + public String item(int index); + + /** + * The number of <code>DOMString</code>s in the list. The range of valid + * child node indices is 0 to <code>length-1</code> inclusive. + */ + public int getLength(); + + /** + * Test if a string is part of this <code>DOMStringList</code>. + * @param str The string to look for. + * @return <code>true</code> if the string has been found, + * <code>false</code> otherwise. + */ + public boolean contains(String str); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/Document.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/Document.java new file mode 100644 index 000000000..3193fa260 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/Document.java @@ -0,0 +1,814 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom; + +/** + * The <code>Document</code> interface represents the entire HTML or XML + * document. Conceptually, it is the root of the document tree, and provides + * the primary access to the document's data. + * <p>Since elements, text nodes, comments, processing instructions, etc. + * cannot exist outside the context of a <code>Document</code>, the + * <code>Document</code> interface also contains the factory methods needed + * to create these objects. The <code>Node</code> objects created have a + * <code>ownerDocument</code> attribute which associates them with the + * <code>Document</code> within whose context they were created. + * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document Object Model (DOM) Level 3 Core Specification</a>. + */ +public interface Document extends Node { + /** + * The Document Type Declaration (see <code>DocumentType</code>) + * associated with this document. For XML documents without a document + * type declaration this returns <code>null</code>. For HTML documents, + * a <code>DocumentType</code> object may be returned, independently of + * the presence or absence of document type declaration in the HTML + * document. + * <br>This provides direct access to the <code>DocumentType</code> node, + * child node of this <code>Document</code>. This node can be set at + * document creation time and later changed through the use of child + * nodes manipulation methods, such as <code>Node.insertBefore</code>, + * or <code>Node.replaceChild</code>. Note, however, that while some + * implementations may instantiate different types of + * <code>Document</code> objects supporting additional features than the + * "Core", such as "HTML" [<a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>DOM Level 2 HTML</a>] + * , based on the <code>DocumentType</code> specified at creation time, + * changing it afterwards is very unlikely to result in a change of the + * features supported. + * @version DOM Level 3 + */ + public DocumentType getDoctype(); + + /** + * The <code>DOMImplementation</code> object that handles this document. A + * DOM application may use objects from multiple implementations. + */ + public DOMImplementation getImplementation(); + + /** + * This is a convenience attribute that allows direct access to the child + * node that is the document element of the document. + */ + public Element getDocumentElement(); + + /** + * Creates an element of the type specified. Note that the instance + * returned implements the <code>Element</code> interface, so attributes + * can be specified directly on the returned object. + * <br>In addition, if there are known attributes with default values, + * <code>Attr</code> nodes representing them are automatically created + * and attached to the element. + * <br>To create an element with a qualified name and namespace URI, use + * the <code>createElementNS</code> method. + * @param tagName The name of the element type to instantiate. For XML, + * this is case-sensitive, otherwise it depends on the + * case-sensitivity of the markup language in use. In that case, the + * name is mapped to the canonical form of that markup by the DOM + * implementation. + * @return A new <code>Element</code> object with the + * <code>nodeName</code> attribute set to <code>tagName</code>, and + * <code>localName</code>, <code>prefix</code>, and + * <code>namespaceURI</code> set to <code>null</code>. + * @exception DOMException + * INVALID_CHARACTER_ERR: Raised if the specified name is not an XML + * name according to the XML version in use specified in the + * <code>Document.xmlVersion</code> attribute. + */ + public Element createElement(String tagName) + throws DOMException; + + /** + * Creates an empty <code>DocumentFragment</code> object. + * @return A new <code>DocumentFragment</code>. + */ + public DocumentFragment createDocumentFragment(); + + /** + * Creates a <code>Text</code> node given the specified string. + * @param data The data for the node. + * @return The new <code>Text</code> object. + */ + public Text createTextNode(String data); + + /** + * Creates a <code>Comment</code> node given the specified string. + * @param data The data for the node. + * @return The new <code>Comment</code> object. + */ + public Comment createComment(String data); + + /** + * Creates a <code>CDATASection</code> node whose value is the specified + * string. + * @param data The data for the <code>CDATASection</code> contents. + * @return The new <code>CDATASection</code> object. + * @exception DOMException + * NOT_SUPPORTED_ERR: Raised if this document is an HTML document. + */ + public CDATASection createCDATASection(String data) + throws DOMException; + + /** + * Creates a <code>ProcessingInstruction</code> node given the specified + * name and data strings. + * @param target The target part of the processing instruction.Unlike + * <code>Document.createElementNS</code> or + * <code>Document.createAttributeNS</code>, no namespace well-formed + * checking is done on the target name. Applications should invoke + * <code>Document.normalizeDocument()</code> with the parameter " + * namespaces" set to <code>true</code> in order to ensure that the + * target name is namespace well-formed. + * @param data The data for the node. + * @return The new <code>ProcessingInstruction</code> object. + * @exception DOMException + * INVALID_CHARACTER_ERR: Raised if the specified target is not an XML + * name according to the XML version in use specified in the + * <code>Document.xmlVersion</code> attribute. + * <br>NOT_SUPPORTED_ERR: Raised if this document is an HTML document. + */ + public ProcessingInstruction createProcessingInstruction(String target, + String data) + throws DOMException; + + /** + * Creates an <code>Attr</code> of the given name. Note that the + * <code>Attr</code> instance can then be set on an <code>Element</code> + * using the <code>setAttributeNode</code> method. + * <br>To create an attribute with a qualified name and namespace URI, use + * the <code>createAttributeNS</code> method. + * @param name The name of the attribute. + * @return A new <code>Attr</code> object with the <code>nodeName</code> + * attribute set to <code>name</code>, and <code>localName</code>, + * <code>prefix</code>, and <code>namespaceURI</code> set to + * <code>null</code>. The value of the attribute is the empty string. + * @exception DOMException + * INVALID_CHARACTER_ERR: Raised if the specified name is not an XML + * name according to the XML version in use specified in the + * <code>Document.xmlVersion</code> attribute. + */ + public Attr createAttribute(String name) + throws DOMException; + + /** + * Creates an <code>EntityReference</code> object. In addition, if the + * referenced entity is known, the child list of the + * <code>EntityReference</code> node is made the same as that of the + * corresponding <code>Entity</code> node. + * <p ><b>Note:</b> If any descendant of the <code>Entity</code> node has + * an unbound namespace prefix, the corresponding descendant of the + * created <code>EntityReference</code> node is also unbound; (its + * <code>namespaceURI</code> is <code>null</code>). The DOM Level 2 and + * 3 do not support any mechanism to resolve namespace prefixes in this + * case. + * @param name The name of the entity to reference.Unlike + * <code>Document.createElementNS</code> or + * <code>Document.createAttributeNS</code>, no namespace well-formed + * checking is done on the entity name. Applications should invoke + * <code>Document.normalizeDocument()</code> with the parameter " + * namespaces" set to <code>true</code> in order to ensure that the + * entity name is namespace well-formed. + * @return The new <code>EntityReference</code> object. + * @exception DOMException + * INVALID_CHARACTER_ERR: Raised if the specified name is not an XML + * name according to the XML version in use specified in the + * <code>Document.xmlVersion</code> attribute. + * <br>NOT_SUPPORTED_ERR: Raised if this document is an HTML document. + */ + public EntityReference createEntityReference(String name) + throws DOMException; + + /** + * Returns a <code>NodeList</code> of all the <code>Elements</code> in + * document order with a given tag name and are contained in the + * document. + * @param tagname The name of the tag to match on. The special value "*" + * matches all tags. For XML, the <code>tagname</code> parameter is + * case-sensitive, otherwise it depends on the case-sensitivity of the + * markup language in use. + * @return A new <code>NodeList</code> object containing all the matched + * <code>Elements</code>. + */ + public NodeList getElementsByTagName(String tagname); + + /** + * Imports a node from another document to this document, without altering + * or removing the source node from the original document; this method + * creates a new copy of the source node. The returned node has no + * parent; (<code>parentNode</code> is <code>null</code>). + * <br>For all nodes, importing a node creates a node object owned by the + * importing document, with attribute values identical to the source + * node's <code>nodeName</code> and <code>nodeType</code>, plus the + * attributes related to namespaces (<code>prefix</code>, + * <code>localName</code>, and <code>namespaceURI</code>). As in the + * <code>cloneNode</code> operation, the source node is not altered. + * User data associated to the imported node is not carried over. + * However, if any <code>UserDataHandlers</code> has been specified + * along with the associated data these handlers will be called with the + * appropriate parameters before this method returns. + * <br>Additional information is copied as appropriate to the + * <code>nodeType</code>, attempting to mirror the behavior expected if + * a fragment of XML or HTML source was copied from one document to + * another, recognizing that the two documents may have different DTDs + * in the XML case. The following list describes the specifics for each + * type of node. + * <dl> + * <dt>ATTRIBUTE_NODE</dt> + * <dd>The <code>ownerElement</code> attribute + * is set to <code>null</code> and the <code>specified</code> flag is + * set to <code>true</code> on the generated <code>Attr</code>. The + * descendants of the source <code>Attr</code> are recursively imported + * and the resulting nodes reassembled to form the corresponding subtree. + * Note that the <code>deep</code> parameter has no effect on + * <code>Attr</code> nodes; they always carry their children with them + * when imported.</dd> + * <dt>DOCUMENT_FRAGMENT_NODE</dt> + * <dd>If the <code>deep</code> option + * was set to <code>true</code>, the descendants of the source + * <code>DocumentFragment</code> are recursively imported and the + * resulting nodes reassembled under the imported + * <code>DocumentFragment</code> to form the corresponding subtree. + * Otherwise, this simply generates an empty + * <code>DocumentFragment</code>.</dd> + * <dt>DOCUMENT_NODE</dt> + * <dd><code>Document</code> + * nodes cannot be imported.</dd> + * <dt>DOCUMENT_TYPE_NODE</dt> + * <dd><code>DocumentType</code> + * nodes cannot be imported.</dd> + * <dt>ELEMENT_NODE</dt> + * <dd><em>Specified</em> attribute nodes of the source element are imported, and the generated + * <code>Attr</code> nodes are attached to the generated + * <code>Element</code>. Default attributes are <em>not</em> copied, though if the document being imported into defines default + * attributes for this element name, those are assigned. If the + * <code>importNode</code> <code>deep</code> parameter was set to + * <code>true</code>, the descendants of the source element are + * recursively imported and the resulting nodes reassembled to form the + * corresponding subtree.</dd> + * <dt>ENTITY_NODE</dt> + * <dd><code>Entity</code> nodes can be + * imported, however in the current release of the DOM the + * <code>DocumentType</code> is readonly. Ability to add these imported + * nodes to a <code>DocumentType</code> will be considered for addition + * to a future release of the DOM.On import, the <code>publicId</code>, + * <code>systemId</code>, and <code>notationName</code> attributes are + * copied. If a <code>deep</code> import is requested, the descendants + * of the the source <code>Entity</code> are recursively imported and + * the resulting nodes reassembled to form the corresponding subtree.</dd> + * <dt> + * ENTITY_REFERENCE_NODE</dt> + * <dd>Only the <code>EntityReference</code> itself is + * copied, even if a <code>deep</code> import is requested, since the + * source and destination documents might have defined the entity + * differently. If the document being imported into provides a + * definition for this entity name, its value is assigned.</dd> + * <dt>NOTATION_NODE</dt> + * <dd> + * <code>Notation</code> nodes can be imported, however in the current + * release of the DOM the <code>DocumentType</code> is readonly. Ability + * to add these imported nodes to a <code>DocumentType</code> will be + * considered for addition to a future release of the DOM.On import, the + * <code>publicId</code> and <code>systemId</code> attributes are copied. + * Note that the <code>deep</code> parameter has no effect on this type + * of nodes since they cannot have any children.</dd> + * <dt> + * PROCESSING_INSTRUCTION_NODE</dt> + * <dd>The imported node copies its + * <code>target</code> and <code>data</code> values from those of the + * source node.Note that the <code>deep</code> parameter has no effect + * on this type of nodes since they cannot have any children.</dd> + * <dt>TEXT_NODE, + * CDATA_SECTION_NODE, COMMENT_NODE</dt> + * <dd>These three types of nodes inheriting + * from <code>CharacterData</code> copy their <code>data</code> and + * <code>length</code> attributes from those of the source node.Note + * that the <code>deep</code> parameter has no effect on these types of + * nodes since they cannot have any children.</dd> + * </dl> + * @param importedNode The node to import. + * @param deep If <code>true</code>, recursively import the subtree under + * the specified node; if <code>false</code>, import only the node + * itself, as explained above. This has no effect on nodes that cannot + * have any children, and on <code>Attr</code>, and + * <code>EntityReference</code> nodes. + * @return The imported node that belongs to this <code>Document</code>. + * @exception DOMException + * NOT_SUPPORTED_ERR: Raised if the type of node being imported is not + * supported. + * <br>INVALID_CHARACTER_ERR: Raised if one of the imported names is not + * an XML name according to the XML version in use specified in the + * <code>Document.xmlVersion</code> attribute. This may happen when + * importing an XML 1.1 [<a href='http://www.w3.org/TR/2004/REC-xml11-20040204/'>XML 1.1</a>] element + * into an XML 1.0 document, for instance. + * @since DOM Level 2 + */ + public Node importNode(Node importedNode, + boolean deep) + throws DOMException; + + /** + * Creates an element of the given qualified name and namespace URI. + * <br>Per [<a href='http://www.w3.org/TR/1999/REC-xml-names-19990114/'>XML Namespaces</a>] + * , applications must use the value <code>null</code> as the + * namespaceURI parameter for methods if they wish to have no namespace. + * @param namespaceURI The namespace URI of the element to create. + * @param qualifiedName The qualified name of the element type to + * instantiate. + * @return A new <code>Element</code> object with the following + * attributes: + * <table border='1' cellpadding='3'> + * <tr> + * <th>Attribute</th> + * <th>Value</th> + * </tr> + * <tr> + * <td valign='top' rowspan='1' colspan='1'><code>Node.nodeName</code></td> + * <td valign='top' rowspan='1' colspan='1'> + * <code>qualifiedName</code></td> + * </tr> + * <tr> + * <td valign='top' rowspan='1' colspan='1'><code>Node.namespaceURI</code></td> + * <td valign='top' rowspan='1' colspan='1'> + * <code>namespaceURI</code></td> + * </tr> + * <tr> + * <td valign='top' rowspan='1' colspan='1'><code>Node.prefix</code></td> + * <td valign='top' rowspan='1' colspan='1'>prefix, extracted + * from <code>qualifiedName</code>, or <code>null</code> if there is + * no prefix</td> + * </tr> + * <tr> + * <td valign='top' rowspan='1' colspan='1'><code>Node.localName</code></td> + * <td valign='top' rowspan='1' colspan='1'>local name, extracted from + * <code>qualifiedName</code></td> + * </tr> + * <tr> + * <td valign='top' rowspan='1' colspan='1'><code>Element.tagName</code></td> + * <td valign='top' rowspan='1' colspan='1'> + * <code>qualifiedName</code></td> + * </tr> + * </table> + * @exception DOMException + * INVALID_CHARACTER_ERR: Raised if the specified + * <code>qualifiedName</code> is not an XML name according to the XML + * version in use specified in the <code>Document.xmlVersion</code> + * attribute. + * <br>NAMESPACE_ERR: Raised if the <code>qualifiedName</code> is a + * malformed qualified name, if the <code>qualifiedName</code> has a + * prefix and the <code>namespaceURI</code> is <code>null</code>, or + * if the <code>qualifiedName</code> has a prefix that is "xml" and + * the <code>namespaceURI</code> is different from "<a href='http://www.w3.org/XML/1998/namespace'> + * http://www.w3.org/XML/1998/namespace</a>" [<a href='http://www.w3.org/TR/1999/REC-xml-names-19990114/'>XML Namespaces</a>] + * , or if the <code>qualifiedName</code> or its prefix is "xmlns" and + * the <code>namespaceURI</code> is different from "<a href='http://www.w3.org/2000/xmlns/'>http://www.w3.org/2000/xmlns/</a>", or if the <code>namespaceURI</code> is "<a href='http://www.w3.org/2000/xmlns/'>http://www.w3.org/2000/xmlns/</a>" and neither the <code>qualifiedName</code> nor its prefix is "xmlns". + * <br>NOT_SUPPORTED_ERR: Always thrown if the current document does not + * support the <code>"XML"</code> feature, since namespaces were + * defined by XML. + * @since DOM Level 2 + */ + public Element createElementNS(String namespaceURI, + String qualifiedName) + throws DOMException; + + /** + * Creates an attribute of the given qualified name and namespace URI. + * <br>Per [<a href='http://www.w3.org/TR/1999/REC-xml-names-19990114/'>XML Namespaces</a>] + * , applications must use the value <code>null</code> as the + * <code>namespaceURI</code> parameter for methods if they wish to have + * no namespace. + * @param namespaceURI The namespace URI of the attribute to create. + * @param qualifiedName The qualified name of the attribute to + * instantiate. + * @return A new <code>Attr</code> object with the following attributes: + * <table border='1' cellpadding='3'> + * <tr> + * <th> + * Attribute</th> + * <th>Value</th> + * </tr> + * <tr> + * <td valign='top' rowspan='1' colspan='1'><code>Node.nodeName</code></td> + * <td valign='top' rowspan='1' colspan='1'>qualifiedName</td> + * </tr> + * <tr> + * <td valign='top' rowspan='1' colspan='1'> + * <code>Node.namespaceURI</code></td> + * <td valign='top' rowspan='1' colspan='1'><code>namespaceURI</code></td> + * </tr> + * <tr> + * <td valign='top' rowspan='1' colspan='1'> + * <code>Node.prefix</code></td> + * <td valign='top' rowspan='1' colspan='1'>prefix, extracted from + * <code>qualifiedName</code>, or <code>null</code> if there is no + * prefix</td> + * </tr> + * <tr> + * <td valign='top' rowspan='1' colspan='1'><code>Node.localName</code></td> + * <td valign='top' rowspan='1' colspan='1'>local name, extracted from + * <code>qualifiedName</code></td> + * </tr> + * <tr> + * <td valign='top' rowspan='1' colspan='1'><code>Attr.name</code></td> + * <td valign='top' rowspan='1' colspan='1'> + * <code>qualifiedName</code></td> + * </tr> + * <tr> + * <td valign='top' rowspan='1' colspan='1'><code>Node.nodeValue</code></td> + * <td valign='top' rowspan='1' colspan='1'>the empty + * string</td> + * </tr> + * </table> + * @exception DOMException + * INVALID_CHARACTER_ERR: Raised if the specified + * <code>qualifiedName</code> is not an XML name according to the XML + * version in use specified in the <code>Document.xmlVersion</code> + * attribute. + * <br>NAMESPACE_ERR: Raised if the <code>qualifiedName</code> is a + * malformed qualified name, if the <code>qualifiedName</code> has a + * prefix and the <code>namespaceURI</code> is <code>null</code>, if + * the <code>qualifiedName</code> has a prefix that is "xml" and the + * <code>namespaceURI</code> is different from "<a href='http://www.w3.org/XML/1998/namespace'> + * http://www.w3.org/XML/1998/namespace</a>", if the <code>qualifiedName</code> or its prefix is "xmlns" and the + * <code>namespaceURI</code> is different from "<a href='http://www.w3.org/2000/xmlns/'>http://www.w3.org/2000/xmlns/</a>", or if the <code>namespaceURI</code> is "<a href='http://www.w3.org/2000/xmlns/'>http://www.w3.org/2000/xmlns/</a>" and neither the <code>qualifiedName</code> nor its prefix is "xmlns". + * <br>NOT_SUPPORTED_ERR: Always thrown if the current document does not + * support the <code>"XML"</code> feature, since namespaces were + * defined by XML. + * @since DOM Level 2 + */ + public Attr createAttributeNS(String namespaceURI, + String qualifiedName) + throws DOMException; + + /** + * Returns a <code>NodeList</code> of all the <code>Elements</code> with a + * given local name and namespace URI in document order. + * @param namespaceURI The namespace URI of the elements to match on. The + * special value <code>"*"</code> matches all namespaces. + * @param localName The local name of the elements to match on. The + * special value "*" matches all local names. + * @return A new <code>NodeList</code> object containing all the matched + * <code>Elements</code>. + * @since DOM Level 2 + */ + public NodeList getElementsByTagNameNS(String namespaceURI, + String localName); + + /** + * Returns the <code>Element</code> that has an ID attribute with the + * given value. If no such element exists, this returns <code>null</code> + * . If more than one element has an ID attribute with that value, what + * is returned is undefined. + * <br> The DOM implementation is expected to use the attribute + * <code>Attr.isId</code> to determine if an attribute is of type ID. + * <p ><b>Note:</b> Attributes with the name "ID" or "id" are not of type + * ID unless so defined. + * @param elementId The unique <code>id</code> value for an element. + * @return The matching element or <code>null</code> if there is none. + * @since DOM Level 2 + */ + public Element getElementById(String elementId); + + /** + * An attribute specifying the encoding used for this document at the time + * of the parsing. This is <code>null</code> when it is not known, such + * as when the <code>Document</code> was created in memory. + * @since DOM Level 3 + */ + public String getInputEncoding(); + + /** + * An attribute specifying, as part of the <a href='http://www.w3.org/TR/2004/REC-xml-20040204#NT-XMLDecl'>XML declaration</a>, the encoding of this document. This is <code>null</code> when + * unspecified or when it is not known, such as when the + * <code>Document</code> was created in memory. + * @since DOM Level 3 + */ + public String getXmlEncoding(); + + /** + * An attribute specifying, as part of the <a href='http://www.w3.org/TR/2004/REC-xml-20040204#NT-XMLDecl'>XML declaration</a>, whether this document is standalone. This is <code>false</code> when + * unspecified. + * <p ><b>Note:</b> No verification is done on the value when setting + * this attribute. Applications should use + * <code>Document.normalizeDocument()</code> with the "validate" + * parameter to verify if the value matches the <a href='http://www.w3.org/TR/2004/REC-xml-20040204#sec-rmd'>validity + * constraint for standalone document declaration</a> as defined in [<a href='http://www.w3.org/TR/2004/REC-xml-20040204'>XML 1.0</a>]. + * @since DOM Level 3 + */ + public boolean getXmlStandalone(); + /** + * An attribute specifying, as part of the <a href='http://www.w3.org/TR/2004/REC-xml-20040204#NT-XMLDecl'>XML declaration</a>, whether this document is standalone. This is <code>false</code> when + * unspecified. + * <p ><b>Note:</b> No verification is done on the value when setting + * this attribute. Applications should use + * <code>Document.normalizeDocument()</code> with the "validate" + * parameter to verify if the value matches the <a href='http://www.w3.org/TR/2004/REC-xml-20040204#sec-rmd'>validity + * constraint for standalone document declaration</a> as defined in [<a href='http://www.w3.org/TR/2004/REC-xml-20040204'>XML 1.0</a>]. + * @exception DOMException + * NOT_SUPPORTED_ERR: Raised if this document does not support the + * "XML" feature. + * @since DOM Level 3 + */ + public void setXmlStandalone(boolean xmlStandalone) + throws DOMException; + + /** + * An attribute specifying, as part of the <a href='http://www.w3.org/TR/2004/REC-xml-20040204#NT-XMLDecl'>XML declaration</a>, the version number of this document. If there is no declaration and if + * this document supports the "XML" feature, the value is + * <code>"1.0"</code>. If this document does not support the "XML" + * feature, the value is always <code>null</code>. Changing this + * attribute will affect methods that check for invalid characters in + * XML names. Application should invoke + * <code>Document.normalizeDocument()</code> in order to check for + * invalid characters in the <code>Node</code>s that are already part of + * this <code>Document</code>. + * <br> DOM applications may use the + * <code>DOMImplementation.hasFeature(feature, version)</code> method + * with parameter values "XMLVersion" and "1.0" (respectively) to + * determine if an implementation supports [<a href='http://www.w3.org/TR/2004/REC-xml-20040204'>XML 1.0</a>]. DOM + * applications may use the same method with parameter values + * "XMLVersion" and "1.1" (respectively) to determine if an + * implementation supports [<a href='http://www.w3.org/TR/2004/REC-xml11-20040204/'>XML 1.1</a>]. In both + * cases, in order to support XML, an implementation must also support + * the "XML" feature defined in this specification. <code>Document</code> + * objects supporting a version of the "XMLVersion" feature must not + * raise a <code>NOT_SUPPORTED_ERR</code> exception for the same version + * number when using <code>Document.xmlVersion</code>. + * @since DOM Level 3 + */ + public String getXmlVersion(); + /** + * An attribute specifying, as part of the <a href='http://www.w3.org/TR/2004/REC-xml-20040204#NT-XMLDecl'>XML declaration</a>, the version number of this document. If there is no declaration and if + * this document supports the "XML" feature, the value is + * <code>"1.0"</code>. If this document does not support the "XML" + * feature, the value is always <code>null</code>. Changing this + * attribute will affect methods that check for invalid characters in + * XML names. Application should invoke + * <code>Document.normalizeDocument()</code> in order to check for + * invalid characters in the <code>Node</code>s that are already part of + * this <code>Document</code>. + * <br> DOM applications may use the + * <code>DOMImplementation.hasFeature(feature, version)</code> method + * with parameter values "XMLVersion" and "1.0" (respectively) to + * determine if an implementation supports [<a href='http://www.w3.org/TR/2004/REC-xml-20040204'>XML 1.0</a>]. DOM + * applications may use the same method with parameter values + * "XMLVersion" and "1.1" (respectively) to determine if an + * implementation supports [<a href='http://www.w3.org/TR/2004/REC-xml11-20040204/'>XML 1.1</a>]. In both + * cases, in order to support XML, an implementation must also support + * the "XML" feature defined in this specification. <code>Document</code> + * objects supporting a version of the "XMLVersion" feature must not + * raise a <code>NOT_SUPPORTED_ERR</code> exception for the same version + * number when using <code>Document.xmlVersion</code>. + * @exception DOMException + * NOT_SUPPORTED_ERR: Raised if the version is set to a value that is + * not supported by this <code>Document</code> or if this document + * does not support the "XML" feature. + * @since DOM Level 3 + */ + public void setXmlVersion(String xmlVersion) + throws DOMException; + + /** + * An attribute specifying whether error checking is enforced or not. When + * set to <code>false</code>, the implementation is free to not test + * every possible error case normally defined on DOM operations, and not + * raise any <code>DOMException</code> on DOM operations or report + * errors while using <code>Document.normalizeDocument()</code>. In case + * of error, the behavior is undefined. This attribute is + * <code>true</code> by default. + * @since DOM Level 3 + */ + public boolean getStrictErrorChecking(); + /** + * An attribute specifying whether error checking is enforced or not. When + * set to <code>false</code>, the implementation is free to not test + * every possible error case normally defined on DOM operations, and not + * raise any <code>DOMException</code> on DOM operations or report + * errors while using <code>Document.normalizeDocument()</code>. In case + * of error, the behavior is undefined. This attribute is + * <code>true</code> by default. + * @since DOM Level 3 + */ + public void setStrictErrorChecking(boolean strictErrorChecking); + + /** + * The location of the document or <code>null</code> if undefined or if + * the <code>Document</code> was created using + * <code>DOMImplementation.createDocument</code>. No lexical checking is + * performed when setting this attribute; this could result in a + * <code>null</code> value returned when using <code>Node.baseURI</code> + * . + * <br> Beware that when the <code>Document</code> supports the feature + * "HTML" [<a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>DOM Level 2 HTML</a>] + * , the href attribute of the HTML BASE element takes precedence over + * this attribute when computing <code>Node.baseURI</code>. + * @since DOM Level 3 + */ + public String getDocumentURI(); + /** + * The location of the document or <code>null</code> if undefined or if + * the <code>Document</code> was created using + * <code>DOMImplementation.createDocument</code>. No lexical checking is + * performed when setting this attribute; this could result in a + * <code>null</code> value returned when using <code>Node.baseURI</code> + * . + * <br> Beware that when the <code>Document</code> supports the feature + * "HTML" [<a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>DOM Level 2 HTML</a>] + * , the href attribute of the HTML BASE element takes precedence over + * this attribute when computing <code>Node.baseURI</code>. + * @since DOM Level 3 + */ + public void setDocumentURI(String documentURI); + + /** + * Attempts to adopt a node from another document to this document. If + * supported, it changes the <code>ownerDocument</code> of the source + * node, its children, as well as the attached attribute nodes if there + * are any. If the source node has a parent it is first removed from the + * child list of its parent. This effectively allows moving a subtree + * from one document to another (unlike <code>importNode()</code> which + * create a copy of the source node instead of moving it). When it + * fails, applications should use <code>Document.importNode()</code> + * instead. Note that if the adopted node is already part of this + * document (i.e. the source and target document are the same), this + * method still has the effect of removing the source node from the + * child list of its parent, if any. The following list describes the + * specifics for each type of node. + * <dl> + * <dt>ATTRIBUTE_NODE</dt> + * <dd>The + * <code>ownerElement</code> attribute is set to <code>null</code> and + * the <code>specified</code> flag is set to <code>true</code> on the + * adopted <code>Attr</code>. The descendants of the source + * <code>Attr</code> are recursively adopted.</dd> + * <dt>DOCUMENT_FRAGMENT_NODE</dt> + * <dd>The + * descendants of the source node are recursively adopted.</dd> + * <dt>DOCUMENT_NODE</dt> + * <dd> + * <code>Document</code> nodes cannot be adopted.</dd> + * <dt>DOCUMENT_TYPE_NODE</dt> + * <dd> + * <code>DocumentType</code> nodes cannot be adopted.</dd> + * <dt>ELEMENT_NODE</dt> + * <dd><em>Specified</em> attribute nodes of the source element are adopted. Default attributes + * are discarded, though if the document being adopted into defines + * default attributes for this element name, those are assigned. The + * descendants of the source element are recursively adopted.</dd> + * <dt>ENTITY_NODE</dt> + * <dd> + * <code>Entity</code> nodes cannot be adopted.</dd> + * <dt>ENTITY_REFERENCE_NODE</dt> + * <dd>Only + * the <code>EntityReference</code> node itself is adopted, the + * descendants are discarded, since the source and destination documents + * might have defined the entity differently. If the document being + * imported into provides a definition for this entity name, its value + * is assigned.</dd> + * <dt>NOTATION_NODE</dt> + * <dd><code>Notation</code> nodes cannot be + * adopted.</dd> + * <dt>PROCESSING_INSTRUCTION_NODE, TEXT_NODE, CDATA_SECTION_NODE, + * COMMENT_NODE</dt> + * <dd>These nodes can all be adopted. No specifics.</dd> + * </dl> + * <p ><b>Note:</b> Since it does not create new nodes unlike the + * <code>Document.importNode()</code> method, this method does not raise + * an <code>INVALID_CHARACTER_ERR</code> exception, and applications + * should use the <code>Document.normalizeDocument()</code> method to + * check if an imported name is not an XML name according to the XML + * version in use. + * @param source The node to move into this document. + * @return The adopted node, or <code>null</code> if this operation + * fails, such as when the source node comes from a different + * implementation. + * @exception DOMException + * NOT_SUPPORTED_ERR: Raised if the source node is of type + * <code>DOCUMENT</code>, <code>DOCUMENT_TYPE</code>. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised when the source node is + * readonly. + * @since DOM Level 3 + */ + public Node adoptNode(Node source) + throws DOMException; + + /** + * The configuration used when <code>Document.normalizeDocument()</code> + * is invoked. + * @since DOM Level 3 + */ + public DOMConfiguration getDomConfig(); + + /** + * This method acts as if the document was going through a save and load + * cycle, putting the document in a "normal" form. As a consequence, + * this method updates the replacement tree of + * <code>EntityReference</code> nodes and normalizes <code>Text</code> + * nodes, as defined in the method <code>Node.normalize()</code>. + * <br> Otherwise, the actual result depends on the features being set on + * the <code>Document.domConfig</code> object and governing what + * operations actually take place. Noticeably this method could also + * make the document namespace well-formed according to the algorithm + * described in , check the character normalization, remove the + * <code>CDATASection</code> nodes, etc. See + * <code>DOMConfiguration</code> for details. + * <pre>// Keep in the document + * the information defined // in the XML Information Set (Java example) + * DOMConfiguration docConfig = myDocument.getDomConfig(); + * docConfig.setParameter("infoset", Boolean.TRUE); + * myDocument.normalizeDocument();</pre> + * + * <br>Mutation events, when supported, are generated to reflect the + * changes occurring on the document. + * <br> If errors occur during the invocation of this method, such as an + * attempt to update a read-only node or a <code>Node.nodeName</code> + * contains an invalid character according to the XML version in use, + * errors or warnings (<code>DOMError.SEVERITY_ERROR</code> or + * <code>DOMError.SEVERITY_WARNING</code>) will be reported using the + * <code>DOMErrorHandler</code> object associated with the "error-handler + * " parameter. Note this method might also report fatal errors ( + * <code>DOMError.SEVERITY_FATAL_ERROR</code>) if an implementation + * cannot recover from an error. + * @since DOM Level 3 + */ + public void normalizeDocument(); + + /** + * Rename an existing node of type <code>ELEMENT_NODE</code> or + * <code>ATTRIBUTE_NODE</code>. + * <br>When possible this simply changes the name of the given node, + * otherwise this creates a new node with the specified name and + * replaces the existing node with the new node as described below. + * <br>If simply changing the name of the given node is not possible, the + * following operations are performed: a new node is created, any + * registered event listener is registered on the new node, any user + * data attached to the old node is removed from that node, the old node + * is removed from its parent if it has one, the children are moved to + * the new node, if the renamed node is an <code>Element</code> its + * attributes are moved to the new node, the new node is inserted at the + * position the old node used to have in its parent's child nodes list + * if it has one, the user data that was attached to the old node is + * attached to the new node. + * <br>When the node being renamed is an <code>Element</code> only the + * specified attributes are moved, default attributes originated from + * the DTD are updated according to the new element name. In addition, + * the implementation may update default attributes from other schemas. + * Applications should use <code>Document.normalizeDocument()</code> to + * guarantee these attributes are up-to-date. + * <br>When the node being renamed is an <code>Attr</code> that is + * attached to an <code>Element</code>, the node is first removed from + * the <code>Element</code> attributes map. Then, once renamed, either + * by modifying the existing node or creating a new one as described + * above, it is put back. + * <br>In addition, + * <ul> + * <li> a user data event <code>NODE_RENAMED</code> is fired, + * </li> + * <li> + * when the implementation supports the feature "MutationNameEvents", + * each mutation operation involved in this method fires the appropriate + * event, and in the end the event { + * <code>http://www.w3.org/2001/xml-events</code>, + * <code>DOMElementNameChanged</code>} or { + * <code>http://www.w3.org/2001/xml-events</code>, + * <code>DOMAttributeNameChanged</code>} is fired. + * </li> + * </ul> + * @param n The node to rename. + * @param namespaceURI The new namespace URI. + * @param qualifiedName The new qualified name. + * @return The renamed node. This is either the specified node or the new + * node that was created to replace the specified node. + * @exception DOMException + * NOT_SUPPORTED_ERR: Raised when the type of the specified node is + * neither <code>ELEMENT_NODE</code> nor <code>ATTRIBUTE_NODE</code>, + * or if the implementation does not support the renaming of the + * document element. + * <br>INVALID_CHARACTER_ERR: Raised if the new qualified name is not an + * XML name according to the XML version in use specified in the + * <code>Document.xmlVersion</code> attribute. + * <br>WRONG_DOCUMENT_ERR: Raised when the specified node was created + * from a different document than this document. + * <br>NAMESPACE_ERR: Raised if the <code>qualifiedName</code> is a + * malformed qualified name, if the <code>qualifiedName</code> has a + * prefix and the <code>namespaceURI</code> is <code>null</code>, or + * if the <code>qualifiedName</code> has a prefix that is "xml" and + * the <code>namespaceURI</code> is different from "<a href='http://www.w3.org/XML/1998/namespace'> + * http://www.w3.org/XML/1998/namespace</a>" [<a href='http://www.w3.org/TR/1999/REC-xml-names-19990114/'>XML Namespaces</a>] + * . Also raised, when the node being renamed is an attribute, if the + * <code>qualifiedName</code>, or its prefix, is "xmlns" and the + * <code>namespaceURI</code> is different from "<a href='http://www.w3.org/2000/xmlns/'>http://www.w3.org/2000/xmlns/</a>". + * @since DOM Level 3 + */ + public Node renameNode(Node n, + String namespaceURI, + String qualifiedName) + throws DOMException; + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/DocumentFragment.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/DocumentFragment.java new file mode 100644 index 000000000..68739154e --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/DocumentFragment.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom; + +/** + * <code>DocumentFragment</code> is a "lightweight" or "minimal" + * <code>Document</code> object. It is very common to want to be able to + * extract a portion of a document's tree or to create a new fragment of a + * document. Imagine implementing a user command like cut or rearranging a + * document by moving fragments around. It is desirable to have an object + * which can hold such fragments and it is quite natural to use a Node for + * this purpose. While it is true that a <code>Document</code> object could + * fulfill this role, a <code>Document</code> object can potentially be a + * heavyweight object, depending on the underlying implementation. What is + * really needed for this is a very lightweight object. + * <code>DocumentFragment</code> is such an object. + * <p>Furthermore, various operations -- such as inserting nodes as children + * of another <code>Node</code> -- may take <code>DocumentFragment</code> + * objects as arguments; this results in all the child nodes of the + * <code>DocumentFragment</code> being moved to the child list of this node. + * <p>The children of a <code>DocumentFragment</code> node are zero or more + * nodes representing the tops of any sub-trees defining the structure of + * the document. <code>DocumentFragment</code> nodes do not need to be + * well-formed XML documents (although they do need to follow the rules + * imposed upon well-formed XML parsed entities, which can have multiple top + * nodes). For example, a <code>DocumentFragment</code> might have only one + * child and that child node could be a <code>Text</code> node. Such a + * structure model represents neither an HTML document nor a well-formed XML + * document. + * <p>When a <code>DocumentFragment</code> is inserted into a + * <code>Document</code> (or indeed any other <code>Node</code> that may + * take children) the children of the <code>DocumentFragment</code> and not + * the <code>DocumentFragment</code> itself are inserted into the + * <code>Node</code>. This makes the <code>DocumentFragment</code> very + * useful when the user wishes to create nodes that are siblings; the + * <code>DocumentFragment</code> acts as the parent of these nodes so that + * the user can use the standard methods from the <code>Node</code> + * interface, such as <code>Node.insertBefore</code> and + * <code>Node.appendChild</code>. + * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document Object Model (DOM) Level 3 Core Specification</a>. + */ +public interface DocumentFragment extends Node { +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/DocumentType.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/DocumentType.java new file mode 100644 index 000000000..785578171 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/DocumentType.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom; + +/** + * Each <code>Document</code> has a <code>doctype</code> attribute whose value + * is either <code>null</code> or a <code>DocumentType</code> object. The + * <code>DocumentType</code> interface in the DOM Core provides an interface + * to the list of entities that are defined for the document, and little + * else because the effect of namespaces and the various XML schema efforts + * on DTD representation are not clearly understood as of this writing. + * <p>DOM Level 3 doesn't support editing <code>DocumentType</code> nodes. + * <code>DocumentType</code> nodes are read-only. + * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document Object Model (DOM) Level 3 Core Specification</a>. + */ +public interface DocumentType extends Node { + /** + * The name of DTD; i.e., the name immediately following the + * <code>DOCTYPE</code> keyword. + */ + public String getName(); + + /** + * A <code>NamedNodeMap</code> containing the general entities, both + * external and internal, declared in the DTD. Parameter entities are + * not contained. Duplicates are discarded. For example in: + * <pre><!DOCTYPE + * ex SYSTEM "ex.dtd" [ <!ENTITY foo "foo"> <!ENTITY bar + * "bar"> <!ENTITY bar "bar2"> <!ENTITY % baz "baz"> + * ]> <ex/></pre> + * the interface provides access to <code>foo</code> + * and the first declaration of <code>bar</code> but not the second + * declaration of <code>bar</code> or <code>baz</code>. Every node in + * this map also implements the <code>Entity</code> interface. + * <br>The DOM Level 2 does not support editing entities, therefore + * <code>entities</code> cannot be altered in any way. + */ + public NamedNodeMap getEntities(); + + /** + * A <code>NamedNodeMap</code> containing the notations declared in the + * DTD. Duplicates are discarded. Every node in this map also implements + * the <code>Notation</code> interface. + * <br>The DOM Level 2 does not support editing notations, therefore + * <code>notations</code> cannot be altered in any way. + */ + public NamedNodeMap getNotations(); + + /** + * The public identifier of the external subset. + * @since DOM Level 2 + */ + public String getPublicId(); + + /** + * The system identifier of the external subset. This may be an absolute + * URI or not. + * @since DOM Level 2 + */ + public String getSystemId(); + + /** + * The internal subset as a string, or <code>null</code> if there is none. + * This is does not contain the delimiting square brackets. + * <p ><b>Note:</b> The actual content returned depends on how much + * information is available to the implementation. This may vary + * depending on various parameters, including the XML processor used to + * build the document. + * @since DOM Level 2 + */ + public String getInternalSubset(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/Element.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/Element.java new file mode 100644 index 000000000..beca7fc87 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/Element.java @@ -0,0 +1,439 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom; + +/** + * The <code>Element</code> interface represents an element in an HTML or XML + * document. Elements may have attributes associated with them; since the + * <code>Element</code> interface inherits from <code>Node</code>, the + * generic <code>Node</code> interface attribute <code>attributes</code> may + * be used to retrieve the set of all attributes for an element. There are + * methods on the <code>Element</code> interface to retrieve either an + * <code>Attr</code> object by name or an attribute value by name. In XML, + * where an attribute value may contain entity references, an + * <code>Attr</code> object should be retrieved to examine the possibly + * fairly complex sub-tree representing the attribute value. On the other + * hand, in HTML, where all attributes have simple string values, methods to + * directly access an attribute value can safely be used as a convenience. + * <p ><b>Note:</b> In DOM Level 2, the method <code>normalize</code> is + * inherited from the <code>Node</code> interface where it was moved. + * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document Object Model (DOM) Level 3 Core Specification</a>. + */ +public interface Element extends Node { + /** + * The name of the element. If <code>Node.localName</code> is different + * from <code>null</code>, this attribute is a qualified name. For + * example, in: + * <pre> <elementExample id="demo"> ... + * </elementExample> , </pre> + * <code>tagName</code> has the value + * <code>"elementExample"</code>. Note that this is case-preserving in + * XML, as are all of the operations of the DOM. The HTML DOM returns + * the <code>tagName</code> of an HTML element in the canonical + * uppercase form, regardless of the case in the source HTML document. + */ + public String getTagName(); + + /** + * Retrieves an attribute value by name. + * @param name The name of the attribute to retrieve. + * @return The <code>Attr</code> value as a string, or the empty string + * if that attribute does not have a specified or default value. + */ + public String getAttribute(String name); + + /** + * Adds a new attribute. If an attribute with that name is already present + * in the element, its value is changed to be that of the value + * parameter. This value is a simple string; it is not parsed as it is + * being set. So any markup (such as syntax to be recognized as an + * entity reference) is treated as literal text, and needs to be + * appropriately escaped by the implementation when it is written out. + * In order to assign an attribute value that contains entity + * references, the user must create an <code>Attr</code> node plus any + * <code>Text</code> and <code>EntityReference</code> nodes, build the + * appropriate subtree, and use <code>setAttributeNode</code> to assign + * it as the value of an attribute. + * <br>To set an attribute with a qualified name and namespace URI, use + * the <code>setAttributeNS</code> method. + * @param name The name of the attribute to create or alter. + * @param value Value to set in string form. + * @exception DOMException + * INVALID_CHARACTER_ERR: Raised if the specified name is not an XML + * name according to the XML version in use specified in the + * <code>Document.xmlVersion</code> attribute. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly. + */ + public void setAttribute(String name, + String value) + throws DOMException; + + /** + * Removes an attribute by name. If a default value for the removed + * attribute is defined in the DTD, a new attribute immediately appears + * with the default value as well as the corresponding namespace URI, + * local name, and prefix when applicable. The implementation may handle + * default values from other schemas similarly but applications should + * use <code>Document.normalizeDocument()</code> to guarantee this + * information is up-to-date. + * <br>If no attribute with this name is found, this method has no effect. + * <br>To remove an attribute by local name and namespace URI, use the + * <code>removeAttributeNS</code> method. + * @param name The name of the attribute to remove. + * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly. + */ + public void removeAttribute(String name) + throws DOMException; + + /** + * Retrieves an attribute node by name. + * <br>To retrieve an attribute node by qualified name and namespace URI, + * use the <code>getAttributeNodeNS</code> method. + * @param name The name (<code>nodeName</code>) of the attribute to + * retrieve. + * @return The <code>Attr</code> node with the specified name ( + * <code>nodeName</code>) or <code>null</code> if there is no such + * attribute. + */ + public Attr getAttributeNode(String name); + + /** + * Adds a new attribute node. If an attribute with that name ( + * <code>nodeName</code>) is already present in the element, it is + * replaced by the new one. Replacing an attribute node by itself has no + * effect. + * <br>To add a new attribute node with a qualified name and namespace + * URI, use the <code>setAttributeNodeNS</code> method. + * @param newAttr The <code>Attr</code> node to add to the attribute list. + * @return If the <code>newAttr</code> attribute replaces an existing + * attribute, the replaced <code>Attr</code> node is returned, + * otherwise <code>null</code> is returned. + * @exception DOMException + * WRONG_DOCUMENT_ERR: Raised if <code>newAttr</code> was created from a + * different document than the one that created the element. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly. + * <br>INUSE_ATTRIBUTE_ERR: Raised if <code>newAttr</code> is already an + * attribute of another <code>Element</code> object. The DOM user must + * explicitly clone <code>Attr</code> nodes to re-use them in other + * elements. + */ + public Attr setAttributeNode(Attr newAttr) + throws DOMException; + + /** + * Removes the specified attribute node. If a default value for the + * removed <code>Attr</code> node is defined in the DTD, a new node + * immediately appears with the default value as well as the + * corresponding namespace URI, local name, and prefix when applicable. + * The implementation may handle default values from other schemas + * similarly but applications should use + * <code>Document.normalizeDocument()</code> to guarantee this + * information is up-to-date. + * @param oldAttr The <code>Attr</code> node to remove from the attribute + * list. + * @return The <code>Attr</code> node that was removed. + * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly. + * <br>NOT_FOUND_ERR: Raised if <code>oldAttr</code> is not an attribute + * of the element. + */ + public Attr removeAttributeNode(Attr oldAttr) + throws DOMException; + + /** + * Returns a <code>NodeList</code> of all descendant <code>Elements</code> + * with a given tag name, in document order. + * @param name The name of the tag to match on. The special value "*" + * matches all tags. + * @return A list of matching <code>Element</code> nodes. + */ + public NodeList getElementsByTagName(String name); + + /** + * Retrieves an attribute value by local name and namespace URI. + * <br>Per [<a href='http://www.w3.org/TR/1999/REC-xml-names-19990114/'>XML Namespaces</a>] + * , applications must use the value <code>null</code> as the + * <code>namespaceURI</code> parameter for methods if they wish to have + * no namespace. + * @param namespaceURI The namespace URI of the attribute to retrieve. + * @param localName The local name of the attribute to retrieve. + * @return The <code>Attr</code> value as a string, or the empty string + * if that attribute does not have a specified or default value. + * @exception DOMException + * NOT_SUPPORTED_ERR: May be raised if the implementation does not + * support the feature <code>"XML"</code> and the language exposed + * through the Document does not support XML Namespaces (such as [<a href='http://www.w3.org/TR/1999/REC-html401-19991224/'>HTML 4.01</a>]). + * @since DOM Level 2 + */ + public String getAttributeNS(String namespaceURI, + String localName) + throws DOMException; + + /** + * Adds a new attribute. If an attribute with the same local name and + * namespace URI is already present on the element, its prefix is + * changed to be the prefix part of the <code>qualifiedName</code>, and + * its value is changed to be the <code>value</code> parameter. This + * value is a simple string; it is not parsed as it is being set. So any + * markup (such as syntax to be recognized as an entity reference) is + * treated as literal text, and needs to be appropriately escaped by the + * implementation when it is written out. In order to assign an + * attribute value that contains entity references, the user must create + * an <code>Attr</code> node plus any <code>Text</code> and + * <code>EntityReference</code> nodes, build the appropriate subtree, + * and use <code>setAttributeNodeNS</code> or + * <code>setAttributeNode</code> to assign it as the value of an + * attribute. + * <br>Per [<a href='http://www.w3.org/TR/1999/REC-xml-names-19990114/'>XML Namespaces</a>] + * , applications must use the value <code>null</code> as the + * <code>namespaceURI</code> parameter for methods if they wish to have + * no namespace. + * @param namespaceURI The namespace URI of the attribute to create or + * alter. + * @param qualifiedName The qualified name of the attribute to create or + * alter. + * @param value The value to set in string form. + * @exception DOMException + * INVALID_CHARACTER_ERR: Raised if the specified qualified name is not + * an XML name according to the XML version in use specified in the + * <code>Document.xmlVersion</code> attribute. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly. + * <br>NAMESPACE_ERR: Raised if the <code>qualifiedName</code> is + * malformed per the Namespaces in XML specification, if the + * <code>qualifiedName</code> has a prefix and the + * <code>namespaceURI</code> is <code>null</code>, if the + * <code>qualifiedName</code> has a prefix that is "xml" and the + * <code>namespaceURI</code> is different from "<a href='http://www.w3.org/XML/1998/namespace'> + * http://www.w3.org/XML/1998/namespace</a>", if the <code>qualifiedName</code> or its prefix is "xmlns" and the + * <code>namespaceURI</code> is different from "<a href='http://www.w3.org/2000/xmlns/'>http://www.w3.org/2000/xmlns/</a>", or if the <code>namespaceURI</code> is "<a href='http://www.w3.org/2000/xmlns/'>http://www.w3.org/2000/xmlns/</a>" and neither the <code>qualifiedName</code> nor its prefix is "xmlns". + * <br>NOT_SUPPORTED_ERR: May be raised if the implementation does not + * support the feature <code>"XML"</code> and the language exposed + * through the Document does not support XML Namespaces (such as [<a href='http://www.w3.org/TR/1999/REC-html401-19991224/'>HTML 4.01</a>]). + * @since DOM Level 2 + */ + public void setAttributeNS(String namespaceURI, + String qualifiedName, + String value) + throws DOMException; + + /** + * Removes an attribute by local name and namespace URI. If a default + * value for the removed attribute is defined in the DTD, a new + * attribute immediately appears with the default value as well as the + * corresponding namespace URI, local name, and prefix when applicable. + * The implementation may handle default values from other schemas + * similarly but applications should use + * <code>Document.normalizeDocument()</code> to guarantee this + * information is up-to-date. + * <br>If no attribute with this local name and namespace URI is found, + * this method has no effect. + * <br>Per [<a href='http://www.w3.org/TR/1999/REC-xml-names-19990114/'>XML Namespaces</a>] + * , applications must use the value <code>null</code> as the + * <code>namespaceURI</code> parameter for methods if they wish to have + * no namespace. + * @param namespaceURI The namespace URI of the attribute to remove. + * @param localName The local name of the attribute to remove. + * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly. + * <br>NOT_SUPPORTED_ERR: May be raised if the implementation does not + * support the feature <code>"XML"</code> and the language exposed + * through the Document does not support XML Namespaces (such as [<a href='http://www.w3.org/TR/1999/REC-html401-19991224/'>HTML 4.01</a>]). + * @since DOM Level 2 + */ + public void removeAttributeNS(String namespaceURI, + String localName) + throws DOMException; + + /** + * Retrieves an <code>Attr</code> node by local name and namespace URI. + * <br>Per [<a href='http://www.w3.org/TR/1999/REC-xml-names-19990114/'>XML Namespaces</a>] + * , applications must use the value <code>null</code> as the + * <code>namespaceURI</code> parameter for methods if they wish to have + * no namespace. + * @param namespaceURI The namespace URI of the attribute to retrieve. + * @param localName The local name of the attribute to retrieve. + * @return The <code>Attr</code> node with the specified attribute local + * name and namespace URI or <code>null</code> if there is no such + * attribute. + * @exception DOMException + * NOT_SUPPORTED_ERR: May be raised if the implementation does not + * support the feature <code>"XML"</code> and the language exposed + * through the Document does not support XML Namespaces (such as [<a href='http://www.w3.org/TR/1999/REC-html401-19991224/'>HTML 4.01</a>]). + * @since DOM Level 2 + */ + public Attr getAttributeNodeNS(String namespaceURI, + String localName) + throws DOMException; + + /** + * Adds a new attribute. If an attribute with that local name and that + * namespace URI is already present in the element, it is replaced by + * the new one. Replacing an attribute node by itself has no effect. + * <br>Per [<a href='http://www.w3.org/TR/1999/REC-xml-names-19990114/'>XML Namespaces</a>] + * , applications must use the value <code>null</code> as the + * <code>namespaceURI</code> parameter for methods if they wish to have + * no namespace. + * @param newAttr The <code>Attr</code> node to add to the attribute list. + * @return If the <code>newAttr</code> attribute replaces an existing + * attribute with the same local name and namespace URI, the replaced + * <code>Attr</code> node is returned, otherwise <code>null</code> is + * returned. + * @exception DOMException + * WRONG_DOCUMENT_ERR: Raised if <code>newAttr</code> was created from a + * different document than the one that created the element. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly. + * <br>INUSE_ATTRIBUTE_ERR: Raised if <code>newAttr</code> is already an + * attribute of another <code>Element</code> object. The DOM user must + * explicitly clone <code>Attr</code> nodes to re-use them in other + * elements. + * <br>NOT_SUPPORTED_ERR: May be raised if the implementation does not + * support the feature <code>"XML"</code> and the language exposed + * through the Document does not support XML Namespaces (such as [<a href='http://www.w3.org/TR/1999/REC-html401-19991224/'>HTML 4.01</a>]). + * @since DOM Level 2 + */ + public Attr setAttributeNodeNS(Attr newAttr) + throws DOMException; + + /** + * Returns a <code>NodeList</code> of all the descendant + * <code>Elements</code> with a given local name and namespace URI in + * document order. + * @param namespaceURI The namespace URI of the elements to match on. The + * special value "*" matches all namespaces. + * @param localName The local name of the elements to match on. The + * special value "*" matches all local names. + * @return A new <code>NodeList</code> object containing all the matched + * <code>Elements</code>. + * @exception DOMException + * NOT_SUPPORTED_ERR: May be raised if the implementation does not + * support the feature <code>"XML"</code> and the language exposed + * through the Document does not support XML Namespaces (such as [<a href='http://www.w3.org/TR/1999/REC-html401-19991224/'>HTML 4.01</a>]). + * @since DOM Level 2 + */ + public NodeList getElementsByTagNameNS(String namespaceURI, + String localName) + throws DOMException; + + /** + * Returns <code>true</code> when an attribute with a given name is + * specified on this element or has a default value, <code>false</code> + * otherwise. + * @param name The name of the attribute to look for. + * @return <code>true</code> if an attribute with the given name is + * specified on this element or has a default value, <code>false</code> + * otherwise. + * @since DOM Level 2 + */ + public boolean hasAttribute(String name); + + /** + * Returns <code>true</code> when an attribute with a given local name and + * namespace URI is specified on this element or has a default value, + * <code>false</code> otherwise. + * <br>Per [<a href='http://www.w3.org/TR/1999/REC-xml-names-19990114/'>XML Namespaces</a>] + * , applications must use the value <code>null</code> as the + * <code>namespaceURI</code> parameter for methods if they wish to have + * no namespace. + * @param namespaceURI The namespace URI of the attribute to look for. + * @param localName The local name of the attribute to look for. + * @return <code>true</code> if an attribute with the given local name + * and namespace URI is specified or has a default value on this + * element, <code>false</code> otherwise. + * @exception DOMException + * NOT_SUPPORTED_ERR: May be raised if the implementation does not + * support the feature <code>"XML"</code> and the language exposed + * through the Document does not support XML Namespaces (such as [<a href='http://www.w3.org/TR/1999/REC-html401-19991224/'>HTML 4.01</a>]). + * @since DOM Level 2 + */ + public boolean hasAttributeNS(String namespaceURI, + String localName) + throws DOMException; + + /** + * The type information associated with this element. + * @since DOM Level 3 + */ + public TypeInfo getSchemaTypeInfo(); + + /** + * If the parameter <code>isId</code> is <code>true</code>, this method + * declares the specified attribute to be a user-determined ID attribute + * . This affects the value of <code>Attr.isId</code> and the behavior + * of <code>Document.getElementById</code>, but does not change any + * schema that may be in use, in particular this does not affect the + * <code>Attr.schemaTypeInfo</code> of the specified <code>Attr</code> + * node. Use the value <code>false</code> for the parameter + * <code>isId</code> to undeclare an attribute for being a + * user-determined ID attribute. + * <br> To specify an attribute by local name and namespace URI, use the + * <code>setIdAttributeNS</code> method. + * @param name The name of the attribute. + * @param isId Whether the attribute is a of type ID. + * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly. + * <br>NOT_FOUND_ERR: Raised if the specified node is not an attribute + * of this element. + * @since DOM Level 3 + */ + public void setIdAttribute(String name, + boolean isId) + throws DOMException; + + /** + * If the parameter <code>isId</code> is <code>true</code>, this method + * declares the specified attribute to be a user-determined ID attribute + * . This affects the value of <code>Attr.isId</code> and the behavior + * of <code>Document.getElementById</code>, but does not change any + * schema that may be in use, in particular this does not affect the + * <code>Attr.schemaTypeInfo</code> of the specified <code>Attr</code> + * node. Use the value <code>false</code> for the parameter + * <code>isId</code> to undeclare an attribute for being a + * user-determined ID attribute. + * @param namespaceURI The namespace URI of the attribute. + * @param localName The local name of the attribute. + * @param isId Whether the attribute is a of type ID. + * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly. + * <br>NOT_FOUND_ERR: Raised if the specified node is not an attribute + * of this element. + * @since DOM Level 3 + */ + public void setIdAttributeNS(String namespaceURI, + String localName, + boolean isId) + throws DOMException; + + /** + * If the parameter <code>isId</code> is <code>true</code>, this method + * declares the specified attribute to be a user-determined ID attribute + * . This affects the value of <code>Attr.isId</code> and the behavior + * of <code>Document.getElementById</code>, but does not change any + * schema that may be in use, in particular this does not affect the + * <code>Attr.schemaTypeInfo</code> of the specified <code>Attr</code> + * node. Use the value <code>false</code> for the parameter + * <code>isId</code> to undeclare an attribute for being a + * user-determined ID attribute. + * @param idAttr The attribute node. + * @param isId Whether the attribute is a of type ID. + * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly. + * <br>NOT_FOUND_ERR: Raised if the specified node is not an attribute + * of this element. + * @since DOM Level 3 + */ + public void setIdAttributeNode(Attr idAttr, + boolean isId) + throws DOMException; + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/Entity.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/Entity.java new file mode 100644 index 000000000..fc89248d9 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/Entity.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom; + +/** + * This interface represents a known entity, either parsed or unparsed, in an + * XML document. Note that this models the entity itself <em>not</em> the entity declaration. + * <p>The <code>nodeName</code> attribute that is inherited from + * <code>Node</code> contains the name of the entity. + * <p>An XML processor may choose to completely expand entities before the + * structure model is passed to the DOM; in this case there will be no + * <code>EntityReference</code> nodes in the document tree. + * <p>XML does not mandate that a non-validating XML processor read and + * process entity declarations made in the external subset or declared in + * parameter entities. This means that parsed entities declared in the + * external subset need not be expanded by some classes of applications, and + * that the replacement text of the entity may not be available. When the <a href='http://www.w3.org/TR/2004/REC-xml-20040204#intern-replacement'> + * replacement text</a> is available, the corresponding <code>Entity</code> node's child list + * represents the structure of that replacement value. Otherwise, the child + * list is empty. + * <p>DOM Level 3 does not support editing <code>Entity</code> nodes; if a + * user wants to make changes to the contents of an <code>Entity</code>, + * every related <code>EntityReference</code> node has to be replaced in the + * structure model by a clone of the <code>Entity</code>'s contents, and + * then the desired changes must be made to each of those clones instead. + * <code>Entity</code> nodes and all their descendants are readonly. + * <p>An <code>Entity</code> node does not have any parent. + * <p ><b>Note:</b> If the entity contains an unbound namespace prefix, the + * <code>namespaceURI</code> of the corresponding node in the + * <code>Entity</code> node subtree is <code>null</code>. The same is true + * for <code>EntityReference</code> nodes that refer to this entity, when + * they are created using the <code>createEntityReference</code> method of + * the <code>Document</code> interface. + * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document Object Model (DOM) Level 3 Core Specification</a>. + */ +public interface Entity extends Node { + /** + * The public identifier associated with the entity if specified, and + * <code>null</code> otherwise. + */ + public String getPublicId(); + + /** + * The system identifier associated with the entity if specified, and + * <code>null</code> otherwise. This may be an absolute URI or not. + */ + public String getSystemId(); + + /** + * For unparsed entities, the name of the notation for the entity. For + * parsed entities, this is <code>null</code>. + */ + public String getNotationName(); + + /** + * An attribute specifying the encoding used for this entity at the time + * of parsing, when it is an external parsed entity. This is + * <code>null</code> if it an entity from the internal subset or if it + * is not known. + * @since DOM Level 3 + */ + public String getInputEncoding(); + + /** + * An attribute specifying, as part of the text declaration, the encoding + * of this entity, when it is an external parsed entity. This is + * <code>null</code> otherwise. + * @since DOM Level 3 + */ + public String getXmlEncoding(); + + /** + * An attribute specifying, as part of the text declaration, the version + * number of this entity, when it is an external parsed entity. This is + * <code>null</code> otherwise. + * @since DOM Level 3 + */ + public String getXmlVersion(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/EntityReference.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/EntityReference.java new file mode 100644 index 000000000..66cc66168 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/EntityReference.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom; + +/** + * <code>EntityReference</code> nodes may be used to represent an entity + * reference in the tree. Note that character references and references to + * predefined entities are considered to be expanded by the HTML or XML + * processor so that characters are represented by their Unicode equivalent + * rather than by an entity reference. Moreover, the XML processor may + * completely expand references to entities while building the + * <code>Document</code>, instead of providing <code>EntityReference</code> + * nodes. If it does provide such nodes, then for an + * <code>EntityReference</code> node that represents a reference to a known + * entity an <code>Entity</code> exists, and the subtree of the + * <code>EntityReference</code> node is a copy of the <code>Entity</code> + * node subtree. However, the latter may not be true when an entity contains + * an unbound namespace prefix. In such a case, because the namespace prefix + * resolution depends on where the entity reference is, the descendants of + * the <code>EntityReference</code> node may be bound to different namespace + * URIs. When an <code>EntityReference</code> node represents a reference to + * an unknown entity, the node has no children and its replacement value, + * when used by <code>Attr.value</code> for example, is empty. + * <p>As for <code>Entity</code> nodes, <code>EntityReference</code> nodes and + * all their descendants are readonly. + * <p ><b>Note:</b> <code>EntityReference</code> nodes may cause element + * content and attribute value normalization problems when, such as in XML + * 1.0 and XML Schema, the normalization is performed after entity reference + * are expanded. + * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document Object Model (DOM) Level 3 Core Specification</a>. + */ +public interface EntityReference extends Node { +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/NameList.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/NameList.java new file mode 100644 index 000000000..e94433f98 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/NameList.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom; + +/** + * The <code>NameList</code> interface provides the abstraction of an ordered + * collection of parallel pairs of name and namespace values (which could be + * null values), without defining or constraining how this collection is + * implemented. The items in the <code>NameList</code> are accessible via an + * integral index, starting from 0. + * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document Object Model (DOM) Level 3 Core Specification</a>. + * @since DOM Level 3 + */ +public interface NameList { + /** + * Returns the <code>index</code>th name item in the collection. + * @param index Index into the collection. + * @return The name at the <code>index</code>th position in the + * <code>NameList</code>, or <code>null</code> if there is no name for + * the specified index or if the index is out of range. + */ + public String getName(int index); + + /** + * Returns the <code>index</code>th namespaceURI item in the collection. + * @param index Index into the collection. + * @return The namespace URI at the <code>index</code>th position in the + * <code>NameList</code>, or <code>null</code> if there is no name for + * the specified index or if the index is out of range. + */ + public String getNamespaceURI(int index); + + /** + * The number of pairs (name and namespaceURI) in the list. The range of + * valid child node indices is 0 to <code>length-1</code> inclusive. + */ + public int getLength(); + + /** + * Test if a name is part of this <code>NameList</code>. + * @param str The name to look for. + * @return <code>true</code> if the name has been found, + * <code>false</code> otherwise. + */ + public boolean contains(String str); + + /** + * Test if the pair namespaceURI/name is part of this + * <code>NameList</code>. + * @param namespaceURI The namespace URI to look for. + * @param name The name to look for. + * @return <code>true</code> if the pair namespaceURI/name has been + * found, <code>false</code> otherwise. + */ + public boolean containsNS(String namespaceURI, + String name); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/NamedNodeMap.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/NamedNodeMap.java new file mode 100644 index 000000000..d74ace7a3 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/NamedNodeMap.java @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom; + +/** + * Objects implementing the <code>NamedNodeMap</code> interface are used to + * represent collections of nodes that can be accessed by name. Note that + * <code>NamedNodeMap</code> does not inherit from <code>NodeList</code>; + * <code>NamedNodeMaps</code> are not maintained in any particular order. + * Objects contained in an object implementing <code>NamedNodeMap</code> may + * also be accessed by an ordinal index, but this is simply to allow + * convenient enumeration of the contents of a <code>NamedNodeMap</code>, + * and does not imply that the DOM specifies an order to these Nodes. + * <p><code>NamedNodeMap</code> objects in the DOM are live. + * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document Object Model (DOM) Level 3 Core Specification</a>. + */ +public interface NamedNodeMap { + /** + * Retrieves a node specified by name. + * @param name The <code>nodeName</code> of a node to retrieve. + * @return A <code>Node</code> (of any type) with the specified + * <code>nodeName</code>, or <code>null</code> if it does not identify + * any node in this map. + */ + public Node getNamedItem(String name); + + /** + * Adds a node using its <code>nodeName</code> attribute. If a node with + * that name is already present in this map, it is replaced by the new + * one. Replacing a node by itself has no effect. + * <br>As the <code>nodeName</code> attribute is used to derive the name + * which the node must be stored under, multiple nodes of certain types + * (those that have a "special" string value) cannot be stored as the + * names would clash. This is seen as preferable to allowing nodes to be + * aliased. + * @param arg A node to store in this map. The node will later be + * accessible using the value of its <code>nodeName</code> attribute. + * @return If the new <code>Node</code> replaces an existing node the + * replaced <code>Node</code> is returned, otherwise <code>null</code> + * is returned. + * @exception DOMException + * WRONG_DOCUMENT_ERR: Raised if <code>arg</code> was created from a + * different document than the one that created this map. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this map is readonly. + * <br>INUSE_ATTRIBUTE_ERR: Raised if <code>arg</code> is an + * <code>Attr</code> that is already an attribute of another + * <code>Element</code> object. The DOM user must explicitly clone + * <code>Attr</code> nodes to re-use them in other elements. + * <br>HIERARCHY_REQUEST_ERR: Raised if an attempt is made to add a node + * doesn't belong in this NamedNodeMap. Examples would include trying + * to insert something other than an Attr node into an Element's map + * of attributes, or a non-Entity node into the DocumentType's map of + * Entities. + */ + public Node setNamedItem(Node arg) + throws DOMException; + + /** + * Removes a node specified by name. When this map contains the attributes + * attached to an element, if the removed attribute is known to have a + * default value, an attribute immediately appears containing the + * default value as well as the corresponding namespace URI, local name, + * and prefix when applicable. + * @param name The <code>nodeName</code> of the node to remove. + * @return The node removed from this map if a node with such a name + * exists. + * @exception DOMException + * NOT_FOUND_ERR: Raised if there is no node named <code>name</code> in + * this map. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this map is readonly. + */ + public Node removeNamedItem(String name) + throws DOMException; + + /** + * Returns the <code>index</code>th item in the map. If <code>index</code> + * is greater than or equal to the number of nodes in this map, this + * returns <code>null</code>. + * @param index Index into this map. + * @return The node at the <code>index</code>th position in the map, or + * <code>null</code> if that is not a valid index. + */ + public Node item(int index); + + /** + * The number of nodes in this map. The range of valid child node indices + * is <code>0</code> to <code>length-1</code> inclusive. + */ + public int getLength(); + + /** + * Retrieves a node specified by local name and namespace URI. + * <br>Per [<a href='http://www.w3.org/TR/1999/REC-xml-names-19990114/'>XML Namespaces</a>] + * , applications must use the value null as the namespaceURI parameter + * for methods if they wish to have no namespace. + * @param namespaceURI The namespace URI of the node to retrieve. + * @param localName The local name of the node to retrieve. + * @return A <code>Node</code> (of any type) with the specified local + * name and namespace URI, or <code>null</code> if they do not + * identify any node in this map. + * @exception DOMException + * NOT_SUPPORTED_ERR: May be raised if the implementation does not + * support the feature "XML" and the language exposed through the + * Document does not support XML Namespaces (such as [<a href='http://www.w3.org/TR/1999/REC-html401-19991224/'>HTML 4.01</a>]). + * @since DOM Level 2 + */ + public Node getNamedItemNS(String namespaceURI, + String localName) + throws DOMException; + + /** + * Adds a node using its <code>namespaceURI</code> and + * <code>localName</code>. If a node with that namespace URI and that + * local name is already present in this map, it is replaced by the new + * one. Replacing a node by itself has no effect. + * <br>Per [<a href='http://www.w3.org/TR/1999/REC-xml-names-19990114/'>XML Namespaces</a>] + * , applications must use the value null as the namespaceURI parameter + * for methods if they wish to have no namespace. + * @param arg A node to store in this map. The node will later be + * accessible using the value of its <code>namespaceURI</code> and + * <code>localName</code> attributes. + * @return If the new <code>Node</code> replaces an existing node the + * replaced <code>Node</code> is returned, otherwise <code>null</code> + * is returned. + * @exception DOMException + * WRONG_DOCUMENT_ERR: Raised if <code>arg</code> was created from a + * different document than the one that created this map. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this map is readonly. + * <br>INUSE_ATTRIBUTE_ERR: Raised if <code>arg</code> is an + * <code>Attr</code> that is already an attribute of another + * <code>Element</code> object. The DOM user must explicitly clone + * <code>Attr</code> nodes to re-use them in other elements. + * <br>HIERARCHY_REQUEST_ERR: Raised if an attempt is made to add a node + * doesn't belong in this NamedNodeMap. Examples would include trying + * to insert something other than an Attr node into an Element's map + * of attributes, or a non-Entity node into the DocumentType's map of + * Entities. + * <br>NOT_SUPPORTED_ERR: May be raised if the implementation does not + * support the feature "XML" and the language exposed through the + * Document does not support XML Namespaces (such as [<a href='http://www.w3.org/TR/1999/REC-html401-19991224/'>HTML 4.01</a>]). + * @since DOM Level 2 + */ + public Node setNamedItemNS(Node arg) + throws DOMException; + + /** + * Removes a node specified by local name and namespace URI. A removed + * attribute may be known to have a default value when this map contains + * the attributes attached to an element, as returned by the attributes + * attribute of the <code>Node</code> interface. If so, an attribute + * immediately appears containing the default value as well as the + * corresponding namespace URI, local name, and prefix when applicable. + * <br>Per [<a href='http://www.w3.org/TR/1999/REC-xml-names-19990114/'>XML Namespaces</a>] + * , applications must use the value null as the namespaceURI parameter + * for methods if they wish to have no namespace. + * @param namespaceURI The namespace URI of the node to remove. + * @param localName The local name of the node to remove. + * @return The node removed from this map if a node with such a local + * name and namespace URI exists. + * @exception DOMException + * NOT_FOUND_ERR: Raised if there is no node with the specified + * <code>namespaceURI</code> and <code>localName</code> in this map. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this map is readonly. + * <br>NOT_SUPPORTED_ERR: May be raised if the implementation does not + * support the feature "XML" and the language exposed through the + * Document does not support XML Namespaces (such as [<a href='http://www.w3.org/TR/1999/REC-html401-19991224/'>HTML 4.01</a>]). + * @since DOM Level 2 + */ + public Node removeNamedItemNS(String namespaceURI, + String localName) + throws DOMException; + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/Node.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/Node.java new file mode 100644 index 000000000..c9a6d0098 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/Node.java @@ -0,0 +1,900 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom; + +/** + * The <code>Node</code> interface is the primary datatype for the entire + * Document Object Model. It represents a single node in the document tree. + * While all objects implementing the <code>Node</code> interface expose + * methods for dealing with children, not all objects implementing the + * <code>Node</code> interface may have children. For example, + * <code>Text</code> nodes may not have children, and adding children to + * such nodes results in a <code>DOMException</code> being raised. + * <p>The attributes <code>nodeName</code>, <code>nodeValue</code> and + * <code>attributes</code> are included as a mechanism to get at node + * information without casting down to the specific derived interface. In + * cases where there is no obvious mapping of these attributes for a + * specific <code>nodeType</code> (e.g., <code>nodeValue</code> for an + * <code>Element</code> or <code>attributes</code> for a <code>Comment</code> + * ), this returns <code>null</code>. Note that the specialized interfaces + * may contain additional and more convenient mechanisms to get and set the + * relevant information. + * <p>The values of <code>nodeName</code>, + * <code>nodeValue</code>, and <code>attributes</code> vary according to the + * node type as follows: + * <table border='1' cellpadding='3'> + * <tr> + * <th>Interface</th> + * <th>nodeName</th> + * <th>nodeValue</th> + * <th>attributes</th> + * </tr> + * <tr> + * <td valign='top' rowspan='1' colspan='1'> + * <code>Attr</code></td> + * <td valign='top' rowspan='1' colspan='1'>same as <code>Attr.name</code></td> + * <td valign='top' rowspan='1' colspan='1'>same as + * <code>Attr.value</code></td> + * <td valign='top' rowspan='1' colspan='1'><code>null</code></td> + * </tr> + * <tr> + * <td valign='top' rowspan='1' colspan='1'><code>CDATASection</code></td> + * <td valign='top' rowspan='1' colspan='1'> + * <code>"#cdata-section"</code></td> + * <td valign='top' rowspan='1' colspan='1'>same as <code>CharacterData.data</code>, the + * content of the CDATA Section</td> + * <td valign='top' rowspan='1' colspan='1'><code>null</code></td> + * </tr> + * <tr> + * <td valign='top' rowspan='1' colspan='1'><code>Comment</code></td> + * <td valign='top' rowspan='1' colspan='1'> + * <code>"#comment"</code></td> + * <td valign='top' rowspan='1' colspan='1'>same as <code>CharacterData.data</code>, the + * content of the comment</td> + * <td valign='top' rowspan='1' colspan='1'><code>null</code></td> + * </tr> + * <tr> + * <td valign='top' rowspan='1' colspan='1'><code>Document</code></td> + * <td valign='top' rowspan='1' colspan='1'> + * <code>"#document"</code></td> + * <td valign='top' rowspan='1' colspan='1'><code>null</code></td> + * <td valign='top' rowspan='1' colspan='1'><code>null</code></td> + * </tr> + * <tr> + * <td valign='top' rowspan='1' colspan='1'> + * <code>DocumentFragment</code></td> + * <td valign='top' rowspan='1' colspan='1'><code>"#document-fragment"</code></td> + * <td valign='top' rowspan='1' colspan='1'> + * <code>null</code></td> + * <td valign='top' rowspan='1' colspan='1'><code>null</code></td> + * </tr> + * <tr> + * <td valign='top' rowspan='1' colspan='1'><code>DocumentType</code></td> + * <td valign='top' rowspan='1' colspan='1'>same as + * <code>DocumentType.name</code></td> + * <td valign='top' rowspan='1' colspan='1'><code>null</code></td> + * <td valign='top' rowspan='1' colspan='1'><code>null</code></td> + * </tr> + * <tr> + * <td valign='top' rowspan='1' colspan='1'> + * <code>Element</code></td> + * <td valign='top' rowspan='1' colspan='1'>same as <code>Element.tagName</code></td> + * <td valign='top' rowspan='1' colspan='1'><code>null</code></td> + * <td valign='top' rowspan='1' colspan='1'> + * <code>NamedNodeMap</code></td> + * </tr> + * <tr> + * <td valign='top' rowspan='1' colspan='1'><code>Entity</code></td> + * <td valign='top' rowspan='1' colspan='1'>entity name</td> + * <td valign='top' rowspan='1' colspan='1'><code>null</code></td> + * <td valign='top' rowspan='1' colspan='1'> + * <code>null</code></td> + * </tr> + * <tr> + * <td valign='top' rowspan='1' colspan='1'><code>EntityReference</code></td> + * <td valign='top' rowspan='1' colspan='1'>name of entity referenced</td> + * <td valign='top' rowspan='1' colspan='1'> + * <code>null</code></td> + * <td valign='top' rowspan='1' colspan='1'><code>null</code></td> + * </tr> + * <tr> + * <td valign='top' rowspan='1' colspan='1'><code>Notation</code></td> + * <td valign='top' rowspan='1' colspan='1'>notation name</td> + * <td valign='top' rowspan='1' colspan='1'> + * <code>null</code></td> + * <td valign='top' rowspan='1' colspan='1'><code>null</code></td> + * </tr> + * <tr> + * <td valign='top' rowspan='1' colspan='1'><code>ProcessingInstruction</code></td> + * <td valign='top' rowspan='1' colspan='1'>same + * as <code>ProcessingInstruction.target</code></td> + * <td valign='top' rowspan='1' colspan='1'>same as + * <code>ProcessingInstruction.data</code></td> + * <td valign='top' rowspan='1' colspan='1'><code>null</code></td> + * </tr> + * <tr> + * <td valign='top' rowspan='1' colspan='1'><code>Text</code></td> + * <td valign='top' rowspan='1' colspan='1'> + * <code>"#text"</code></td> + * <td valign='top' rowspan='1' colspan='1'>same as <code>CharacterData.data</code>, the content + * of the text node</td> + * <td valign='top' rowspan='1' colspan='1'><code>null</code></td> + * </tr> + * </table> + * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document Object Model (DOM) Level 3 Core Specification</a>. + */ +public interface Node { + // NodeType + /** + * The node is an <code>Element</code>. + */ + public static final short ELEMENT_NODE = 1; + /** + * The node is an <code>Attr</code>. + */ + public static final short ATTRIBUTE_NODE = 2; + /** + * The node is a <code>Text</code> node. + */ + public static final short TEXT_NODE = 3; + /** + * The node is a <code>CDATASection</code>. + */ + public static final short CDATA_SECTION_NODE = 4; + /** + * The node is an <code>EntityReference</code>. + */ + public static final short ENTITY_REFERENCE_NODE = 5; + /** + * The node is an <code>Entity</code>. + */ + public static final short ENTITY_NODE = 6; + /** + * The node is a <code>ProcessingInstruction</code>. + */ + public static final short PROCESSING_INSTRUCTION_NODE = 7; + /** + * The node is a <code>Comment</code>. + */ + public static final short COMMENT_NODE = 8; + /** + * The node is a <code>Document</code>. + */ + public static final short DOCUMENT_NODE = 9; + /** + * The node is a <code>DocumentType</code>. + */ + public static final short DOCUMENT_TYPE_NODE = 10; + /** + * The node is a <code>DocumentFragment</code>. + */ + public static final short DOCUMENT_FRAGMENT_NODE = 11; + /** + * The node is a <code>Notation</code>. + */ + public static final short NOTATION_NODE = 12; + + /** + * The name of this node, depending on its type; see the table above. + */ + public String getNodeName(); + + /** + * The value of this node, depending on its type; see the table above. + * When it is defined to be <code>null</code>, setting it has no effect, + * including if the node is read-only. + * @exception DOMException + * DOMSTRING_SIZE_ERR: Raised when it would return more characters than + * fit in a <code>DOMString</code> variable on the implementation + * platform. + */ + public String getNodeValue() + throws DOMException; + /** + * The value of this node, depending on its type; see the table above. + * When it is defined to be <code>null</code>, setting it has no effect, + * including if the node is read-only. + * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly and if + * it is not defined to be <code>null</code>. + */ + public void setNodeValue(String nodeValue) + throws DOMException; + + /** + * A code representing the type of the underlying object, as defined above. + */ + public short getNodeType(); + + /** + * The parent of this node. All nodes, except <code>Attr</code>, + * <code>Document</code>, <code>DocumentFragment</code>, + * <code>Entity</code>, and <code>Notation</code> may have a parent. + * However, if a node has just been created and not yet added to the + * tree, or if it has been removed from the tree, this is + * <code>null</code>. + */ + public Node getParentNode(); + + /** + * A <code>NodeList</code> that contains all children of this node. If + * there are no children, this is a <code>NodeList</code> containing no + * nodes. + */ + public NodeList getChildNodes(); + + /** + * The first child of this node. If there is no such node, this returns + * <code>null</code>. + */ + public Node getFirstChild(); + + /** + * The last child of this node. If there is no such node, this returns + * <code>null</code>. + */ + public Node getLastChild(); + + /** + * The node immediately preceding this node. If there is no such node, + * this returns <code>null</code>. + */ + public Node getPreviousSibling(); + + /** + * The node immediately following this node. If there is no such node, + * this returns <code>null</code>. + */ + public Node getNextSibling(); + + /** + * A <code>NamedNodeMap</code> containing the attributes of this node (if + * it is an <code>Element</code>) or <code>null</code> otherwise. + */ + public NamedNodeMap getAttributes(); + + /** + * The <code>Document</code> object associated with this node. This is + * also the <code>Document</code> object used to create new nodes. When + * this node is a <code>Document</code> or a <code>DocumentType</code> + * which is not used with any <code>Document</code> yet, this is + * <code>null</code>. + * @version DOM Level 2 + */ + public Document getOwnerDocument(); + + /** + * Inserts the node <code>newChild</code> before the existing child node + * <code>refChild</code>. If <code>refChild</code> is <code>null</code>, + * insert <code>newChild</code> at the end of the list of children. + * <br>If <code>newChild</code> is a <code>DocumentFragment</code> object, + * all of its children are inserted, in the same order, before + * <code>refChild</code>. If the <code>newChild</code> is already in the + * tree, it is first removed. + * <p ><b>Note:</b> Inserting a node before itself is implementation + * dependent. + * @param newChild The node to insert. + * @param refChild The reference node, i.e., the node before which the + * new node must be inserted. + * @return The node being inserted. + * @exception DOMException + * HIERARCHY_REQUEST_ERR: Raised if this node is of a type that does not + * allow children of the type of the <code>newChild</code> node, or if + * the node to insert is one of this node's ancestors or this node + * itself, or if this node is of type <code>Document</code> and the + * DOM application attempts to insert a second + * <code>DocumentType</code> or <code>Element</code> node. + * <br>WRONG_DOCUMENT_ERR: Raised if <code>newChild</code> was created + * from a different document than the one that created this node. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly or + * if the parent of the node being inserted is readonly. + * <br>NOT_FOUND_ERR: Raised if <code>refChild</code> is not a child of + * this node. + * <br>NOT_SUPPORTED_ERR: if this node is of type <code>Document</code>, + * this exception might be raised if the DOM implementation doesn't + * support the insertion of a <code>DocumentType</code> or + * <code>Element</code> node. + * @version DOM Level 3 + */ + public Node insertBefore(Node newChild, + Node refChild) + throws DOMException; + + /** + * Replaces the child node <code>oldChild</code> with <code>newChild</code> + * in the list of children, and returns the <code>oldChild</code> node. + * <br>If <code>newChild</code> is a <code>DocumentFragment</code> object, + * <code>oldChild</code> is replaced by all of the + * <code>DocumentFragment</code> children, which are inserted in the + * same order. If the <code>newChild</code> is already in the tree, it + * is first removed. + * <p ><b>Note:</b> Replacing a node with itself is implementation + * dependent. + * @param newChild The new node to put in the child list. + * @param oldChild The node being replaced in the list. + * @return The node replaced. + * @exception DOMException + * HIERARCHY_REQUEST_ERR: Raised if this node is of a type that does not + * allow children of the type of the <code>newChild</code> node, or if + * the node to put in is one of this node's ancestors or this node + * itself, or if this node is of type <code>Document</code> and the + * result of the replacement operation would add a second + * <code>DocumentType</code> or <code>Element</code> on the + * <code>Document</code> node. + * <br>WRONG_DOCUMENT_ERR: Raised if <code>newChild</code> was created + * from a different document than the one that created this node. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node or the parent of + * the new node is readonly. + * <br>NOT_FOUND_ERR: Raised if <code>oldChild</code> is not a child of + * this node. + * <br>NOT_SUPPORTED_ERR: if this node is of type <code>Document</code>, + * this exception might be raised if the DOM implementation doesn't + * support the replacement of the <code>DocumentType</code> child or + * <code>Element</code> child. + * @version DOM Level 3 + */ + public Node replaceChild(Node newChild, + Node oldChild) + throws DOMException; + + /** + * Removes the child node indicated by <code>oldChild</code> from the list + * of children, and returns it. + * @param oldChild The node being removed. + * @return The node removed. + * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly. + * <br>NOT_FOUND_ERR: Raised if <code>oldChild</code> is not a child of + * this node. + * <br>NOT_SUPPORTED_ERR: if this node is of type <code>Document</code>, + * this exception might be raised if the DOM implementation doesn't + * support the removal of the <code>DocumentType</code> child or the + * <code>Element</code> child. + * @version DOM Level 3 + */ + public Node removeChild(Node oldChild) + throws DOMException; + + /** + * Adds the node <code>newChild</code> to the end of the list of children + * of this node. If the <code>newChild</code> is already in the tree, it + * is first removed. + * @param newChild The node to add.If it is a + * <code>DocumentFragment</code> object, the entire contents of the + * document fragment are moved into the child list of this node + * @return The node added. + * @exception DOMException + * HIERARCHY_REQUEST_ERR: Raised if this node is of a type that does not + * allow children of the type of the <code>newChild</code> node, or if + * the node to append is one of this node's ancestors or this node + * itself, or if this node is of type <code>Document</code> and the + * DOM application attempts to append a second + * <code>DocumentType</code> or <code>Element</code> node. + * <br>WRONG_DOCUMENT_ERR: Raised if <code>newChild</code> was created + * from a different document than the one that created this node. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly or + * if the previous parent of the node being inserted is readonly. + * <br>NOT_SUPPORTED_ERR: if the <code>newChild</code> node is a child + * of the <code>Document</code> node, this exception might be raised + * if the DOM implementation doesn't support the removal of the + * <code>DocumentType</code> child or <code>Element</code> child. + * @version DOM Level 3 + */ + public Node appendChild(Node newChild) + throws DOMException; + + /** + * Returns whether this node has any children. + * @return Returns <code>true</code> if this node has any children, + * <code>false</code> otherwise. + */ + public boolean hasChildNodes(); + + /** + * Returns a duplicate of this node, i.e., serves as a generic copy + * constructor for nodes. The duplicate node has no parent ( + * <code>parentNode</code> is <code>null</code>) and no user data. User + * data associated to the imported node is not carried over. However, if + * any <code>UserDataHandlers</code> has been specified along with the + * associated data these handlers will be called with the appropriate + * parameters before this method returns. + * <br>Cloning an <code>Element</code> copies all attributes and their + * values, including those generated by the XML processor to represent + * defaulted attributes, but this method does not copy any children it + * contains unless it is a deep clone. This includes text contained in + * an the <code>Element</code> since the text is contained in a child + * <code>Text</code> node. Cloning an <code>Attr</code> directly, as + * opposed to be cloned as part of an <code>Element</code> cloning + * operation, returns a specified attribute (<code>specified</code> is + * <code>true</code>). Cloning an <code>Attr</code> always clones its + * children, since they represent its value, no matter whether this is a + * deep clone or not. Cloning an <code>EntityReference</code> + * automatically constructs its subtree if a corresponding + * <code>Entity</code> is available, no matter whether this is a deep + * clone or not. Cloning any other type of node simply returns a copy of + * this node. + * <br>Note that cloning an immutable subtree results in a mutable copy, + * but the children of an <code>EntityReference</code> clone are readonly + * . In addition, clones of unspecified <code>Attr</code> nodes are + * specified. And, cloning <code>Document</code>, + * <code>DocumentType</code>, <code>Entity</code>, and + * <code>Notation</code> nodes is implementation dependent. + * @param deep If <code>true</code>, recursively clone the subtree under + * the specified node; if <code>false</code>, clone only the node + * itself (and its attributes, if it is an <code>Element</code>). + * @return The duplicate node. + */ + public Node cloneNode(boolean deep); + + /** + * Puts all <code>Text</code> nodes in the full depth of the sub-tree + * underneath this <code>Node</code>, including attribute nodes, into a + * "normal" form where only structure (e.g., elements, comments, + * processing instructions, CDATA sections, and entity references) + * separates <code>Text</code> nodes, i.e., there are neither adjacent + * <code>Text</code> nodes nor empty <code>Text</code> nodes. This can + * be used to ensure that the DOM view of a document is the same as if + * it were saved and re-loaded, and is useful when operations (such as + * XPointer [<a href='http://www.w3.org/TR/2003/REC-xptr-framework-20030325/'>XPointer</a>] + * lookups) that depend on a particular document tree structure are to + * be used. If the parameter "normalize-characters" of the + * <code>DOMConfiguration</code> object attached to the + * <code>Node.ownerDocument</code> is <code>true</code>, this method + * will also fully normalize the characters of the <code>Text</code> + * nodes. + * <p ><b>Note:</b> In cases where the document contains + * <code>CDATASections</code>, the normalize operation alone may not be + * sufficient, since XPointers do not differentiate between + * <code>Text</code> nodes and <code>CDATASection</code> nodes. + * @version DOM Level 3 + */ + public void normalize(); + + /** + * Tests whether the DOM implementation implements a specific feature and + * that feature is supported by this node, as specified in . + * @param feature The name of the feature to test. + * @param version This is the version number of the feature to test. + * @return Returns <code>true</code> if the specified feature is + * supported on this node, <code>false</code> otherwise. + * @since DOM Level 2 + */ + public boolean isSupported(String feature, + String version); + + /** + * The namespace URI of this node, or <code>null</code> if it is + * unspecified (see ). + * <br>This is not a computed value that is the result of a namespace + * lookup based on an examination of the namespace declarations in + * scope. It is merely the namespace URI given at creation time. + * <br>For nodes of any type other than <code>ELEMENT_NODE</code> and + * <code>ATTRIBUTE_NODE</code> and nodes created with a DOM Level 1 + * method, such as <code>Document.createElement()</code>, this is always + * <code>null</code>. + * <p ><b>Note:</b> Per the <em>Namespaces in XML</em> Specification [<a href='http://www.w3.org/TR/1999/REC-xml-names-19990114/'>XML Namespaces</a>] + * an attribute does not inherit its namespace from the element it is + * attached to. If an attribute is not explicitly given a namespace, it + * simply has no namespace. + * @since DOM Level 2 + */ + public String getNamespaceURI(); + + /** + * The namespace prefix of this node, or <code>null</code> if it is + * unspecified. When it is defined to be <code>null</code>, setting it + * has no effect, including if the node is read-only. + * <br>Note that setting this attribute, when permitted, changes the + * <code>nodeName</code> attribute, which holds the qualified name, as + * well as the <code>tagName</code> and <code>name</code> attributes of + * the <code>Element</code> and <code>Attr</code> interfaces, when + * applicable. + * <br>Setting the prefix to <code>null</code> makes it unspecified, + * setting it to an empty string is implementation dependent. + * <br>Note also that changing the prefix of an attribute that is known to + * have a default value, does not make a new attribute with the default + * value and the original prefix appear, since the + * <code>namespaceURI</code> and <code>localName</code> do not change. + * <br>For nodes of any type other than <code>ELEMENT_NODE</code> and + * <code>ATTRIBUTE_NODE</code> and nodes created with a DOM Level 1 + * method, such as <code>createElement</code> from the + * <code>Document</code> interface, this is always <code>null</code>. + * @since DOM Level 2 + */ + public String getPrefix(); + /** + * The namespace prefix of this node, or <code>null</code> if it is + * unspecified. When it is defined to be <code>null</code>, setting it + * has no effect, including if the node is read-only. + * <br>Note that setting this attribute, when permitted, changes the + * <code>nodeName</code> attribute, which holds the qualified name, as + * well as the <code>tagName</code> and <code>name</code> attributes of + * the <code>Element</code> and <code>Attr</code> interfaces, when + * applicable. + * <br>Setting the prefix to <code>null</code> makes it unspecified, + * setting it to an empty string is implementation dependent. + * <br>Note also that changing the prefix of an attribute that is known to + * have a default value, does not make a new attribute with the default + * value and the original prefix appear, since the + * <code>namespaceURI</code> and <code>localName</code> do not change. + * <br>For nodes of any type other than <code>ELEMENT_NODE</code> and + * <code>ATTRIBUTE_NODE</code> and nodes created with a DOM Level 1 + * method, such as <code>createElement</code> from the + * <code>Document</code> interface, this is always <code>null</code>. + * @exception DOMException + * INVALID_CHARACTER_ERR: Raised if the specified prefix contains an + * illegal character according to the XML version in use specified in + * the <code>Document.xmlVersion</code> attribute. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly. + * <br>NAMESPACE_ERR: Raised if the specified <code>prefix</code> is + * malformed per the Namespaces in XML specification, if the + * <code>namespaceURI</code> of this node is <code>null</code>, if the + * specified prefix is "xml" and the <code>namespaceURI</code> of this + * node is different from "<a href='http://www.w3.org/XML/1998/namespace'> + * http://www.w3.org/XML/1998/namespace</a>", if this node is an attribute and the specified prefix is "xmlns" and + * the <code>namespaceURI</code> of this node is different from "<a href='http://www.w3.org/2000/xmlns/'>http://www.w3.org/2000/xmlns/</a>", or if this node is an attribute and the <code>qualifiedName</code> of + * this node is "xmlns" [<a href='http://www.w3.org/TR/1999/REC-xml-names-19990114/'>XML Namespaces</a>] + * . + * @since DOM Level 2 + */ + public void setPrefix(String prefix) + throws DOMException; + + /** + * Returns the local part of the qualified name of this node. + * <br>For nodes of any type other than <code>ELEMENT_NODE</code> and + * <code>ATTRIBUTE_NODE</code> and nodes created with a DOM Level 1 + * method, such as <code>Document.createElement()</code>, this is always + * <code>null</code>. + * @since DOM Level 2 + */ + public String getLocalName(); + + /** + * Returns whether this node (if it is an element) has any attributes. + * @return Returns <code>true</code> if this node has any attributes, + * <code>false</code> otherwise. + * @since DOM Level 2 + */ + public boolean hasAttributes(); + + /** + * The absolute base URI of this node or <code>null</code> if the + * implementation wasn't able to obtain an absolute URI. This value is + * computed as described in . However, when the <code>Document</code> + * supports the feature "HTML" [<a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>DOM Level 2 HTML</a>] + * , the base URI is computed using first the value of the href + * attribute of the HTML BASE element if any, and the value of the + * <code>documentURI</code> attribute from the <code>Document</code> + * interface otherwise. + * @since DOM Level 3 + */ + public String getBaseURI(); + + // DocumentPosition + /** + * The two nodes are disconnected. Order between disconnected nodes is + * always implementation-specific. + */ + public static final short DOCUMENT_POSITION_DISCONNECTED = 0x01; + /** + * The second node precedes the reference node. + */ + public static final short DOCUMENT_POSITION_PRECEDING = 0x02; + /** + * The node follows the reference node. + */ + public static final short DOCUMENT_POSITION_FOLLOWING = 0x04; + /** + * The node contains the reference node. A node which contains is always + * preceding, too. + */ + public static final short DOCUMENT_POSITION_CONTAINS = 0x08; + /** + * The node is contained by the reference node. A node which is contained + * is always following, too. + */ + public static final short DOCUMENT_POSITION_CONTAINED_BY = 0x10; + /** + * The determination of preceding versus following is + * implementation-specific. + */ + public static final short DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20; + + /** + * Compares the reference node, i.e. the node on which this method is + * being called, with a node, i.e. the one passed as a parameter, with + * regard to their position in the document and according to the + * document order. + * @param other The node to compare against the reference node. + * @return Returns how the node is positioned relatively to the reference + * node. + * @exception DOMException + * NOT_SUPPORTED_ERR: when the compared nodes are from different DOM + * implementations that do not coordinate to return consistent + * implementation-specific results. + * @since DOM Level 3 + */ + public short compareDocumentPosition(Node other) + throws DOMException; + + /** + * This attribute returns the text content of this node and its + * descendants. When it is defined to be <code>null</code>, setting it + * has no effect. On setting, any possible children this node may have + * are removed and, if it the new string is not empty or + * <code>null</code>, replaced by a single <code>Text</code> node + * containing the string this attribute is set to. + * <br> On getting, no serialization is performed, the returned string + * does not contain any markup. No whitespace normalization is performed + * and the returned string does not contain the white spaces in element + * content (see the attribute + * <code>Text.isElementContentWhitespace</code>). Similarly, on setting, + * no parsing is performed either, the input string is taken as pure + * textual content. + * <br>The string returned is made of the text content of this node + * depending on its type, as defined below: + * <table border='1' cellpadding='3'> + * <tr> + * <th>Node type</th> + * <th>Content</th> + * </tr> + * <tr> + * <td valign='top' rowspan='1' colspan='1'> + * ELEMENT_NODE, ATTRIBUTE_NODE, ENTITY_NODE, ENTITY_REFERENCE_NODE, + * DOCUMENT_FRAGMENT_NODE</td> + * <td valign='top' rowspan='1' colspan='1'>concatenation of the <code>textContent</code> + * attribute value of every child node, excluding COMMENT_NODE and + * PROCESSING_INSTRUCTION_NODE nodes. This is the empty string if the + * node has no children.</td> + * </tr> + * <tr> + * <td valign='top' rowspan='1' colspan='1'>TEXT_NODE, CDATA_SECTION_NODE, COMMENT_NODE, + * PROCESSING_INSTRUCTION_NODE</td> + * <td valign='top' rowspan='1' colspan='1'><code>nodeValue</code></td> + * </tr> + * <tr> + * <td valign='top' rowspan='1' colspan='1'>DOCUMENT_NODE, + * DOCUMENT_TYPE_NODE, NOTATION_NODE</td> + * <td valign='top' rowspan='1' colspan='1'><em>null</em></td> + * </tr> + * </table> + * @exception DOMException + * DOMSTRING_SIZE_ERR: Raised when it would return more characters than + * fit in a <code>DOMString</code> variable on the implementation + * platform. + * @since DOM Level 3 + */ + public String getTextContent() + throws DOMException; + /** + * This attribute returns the text content of this node and its + * descendants. When it is defined to be <code>null</code>, setting it + * has no effect. On setting, any possible children this node may have + * are removed and, if it the new string is not empty or + * <code>null</code>, replaced by a single <code>Text</code> node + * containing the string this attribute is set to. + * <br> On getting, no serialization is performed, the returned string + * does not contain any markup. No whitespace normalization is performed + * and the returned string does not contain the white spaces in element + * content (see the attribute + * <code>Text.isElementContentWhitespace</code>). Similarly, on setting, + * no parsing is performed either, the input string is taken as pure + * textual content. + * <br>The string returned is made of the text content of this node + * depending on its type, as defined below: + * <table border='1' cellpadding='3'> + * <tr> + * <th>Node type</th> + * <th>Content</th> + * </tr> + * <tr> + * <td valign='top' rowspan='1' colspan='1'> + * ELEMENT_NODE, ATTRIBUTE_NODE, ENTITY_NODE, ENTITY_REFERENCE_NODE, + * DOCUMENT_FRAGMENT_NODE</td> + * <td valign='top' rowspan='1' colspan='1'>concatenation of the <code>textContent</code> + * attribute value of every child node, excluding COMMENT_NODE and + * PROCESSING_INSTRUCTION_NODE nodes. This is the empty string if the + * node has no children.</td> + * </tr> + * <tr> + * <td valign='top' rowspan='1' colspan='1'>TEXT_NODE, CDATA_SECTION_NODE, COMMENT_NODE, + * PROCESSING_INSTRUCTION_NODE</td> + * <td valign='top' rowspan='1' colspan='1'><code>nodeValue</code></td> + * </tr> + * <tr> + * <td valign='top' rowspan='1' colspan='1'>DOCUMENT_NODE, + * DOCUMENT_TYPE_NODE, NOTATION_NODE</td> + * <td valign='top' rowspan='1' colspan='1'><em>null</em></td> + * </tr> + * </table> + * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly. + * @since DOM Level 3 + */ + public void setTextContent(String textContent) + throws DOMException; + + /** + * Returns whether this node is the same node as the given one. + * <br>This method provides a way to determine whether two + * <code>Node</code> references returned by the implementation reference + * the same object. When two <code>Node</code> references are references + * to the same object, even if through a proxy, the references may be + * used completely interchangeably, such that all attributes have the + * same values and calling the same DOM method on either reference + * always has exactly the same effect. + * @param other The node to test against. + * @return Returns <code>true</code> if the nodes are the same, + * <code>false</code> otherwise. + * @since DOM Level 3 + */ + public boolean isSameNode(Node other); + + /** + * Look up the prefix associated to the given namespace URI, starting from + * this node. The default namespace declarations are ignored by this + * method. + * <br>See for details on the algorithm used by this method. + * @param namespaceURI The namespace URI to look for. + * @return Returns an associated namespace prefix if found or + * <code>null</code> if none is found. If more than one prefix are + * associated to the namespace prefix, the returned namespace prefix + * is implementation dependent. + * @since DOM Level 3 + */ + public String lookupPrefix(String namespaceURI); + + /** + * This method checks if the specified <code>namespaceURI</code> is the + * default namespace or not. + * @param namespaceURI The namespace URI to look for. + * @return Returns <code>true</code> if the specified + * <code>namespaceURI</code> is the default namespace, + * <code>false</code> otherwise. + * @since DOM Level 3 + */ + public boolean isDefaultNamespace(String namespaceURI); + + /** + * Look up the namespace URI associated to the given prefix, starting from + * this node. + * <br>See for details on the algorithm used by this method. + * @param prefix The prefix to look for. If this parameter is + * <code>null</code>, the method will return the default namespace URI + * if any. + * @return Returns the associated namespace URI or <code>null</code> if + * none is found. + * @since DOM Level 3 + */ + public String lookupNamespaceURI(String prefix); + + /** + * Tests whether two nodes are equal. + * <br>This method tests for equality of nodes, not sameness (i.e., + * whether the two nodes are references to the same object) which can be + * tested with <code>Node.isSameNode()</code>. All nodes that are the + * same will also be equal, though the reverse may not be true. + * <br>Two nodes are equal if and only if the following conditions are + * satisfied: + * <ul> + * <li>The two nodes are of the same type. + * </li> + * <li>The following string + * attributes are equal: <code>nodeName</code>, <code>localName</code>, + * <code>namespaceURI</code>, <code>prefix</code>, <code>nodeValue</code> + * . This is: they are both <code>null</code>, or they have the same + * length and are character for character identical. + * </li> + * <li>The + * <code>attributes</code> <code>NamedNodeMaps</code> are equal. This + * is: they are both <code>null</code>, or they have the same length and + * for each node that exists in one map there is a node that exists in + * the other map and is equal, although not necessarily at the same + * index. + * </li> + * <li>The <code>childNodes</code> <code>NodeLists</code> are equal. + * This is: they are both <code>null</code>, or they have the same + * length and contain equal nodes at the same index. Note that + * normalization can affect equality; to avoid this, nodes should be + * normalized before being compared. + * </li> + * </ul> + * <br>For two <code>DocumentType</code> nodes to be equal, the following + * conditions must also be satisfied: + * <ul> + * <li>The following string attributes + * are equal: <code>publicId</code>, <code>systemId</code>, + * <code>internalSubset</code>. + * </li> + * <li>The <code>entities</code> + * <code>NamedNodeMaps</code> are equal. + * </li> + * <li>The <code>notations</code> + * <code>NamedNodeMaps</code> are equal. + * </li> + * </ul> + * <br>On the other hand, the following do not affect equality: the + * <code>ownerDocument</code>, <code>baseURI</code>, and + * <code>parentNode</code> attributes, the <code>specified</code> + * attribute for <code>Attr</code> nodes, the <code>schemaTypeInfo</code> + * attribute for <code>Attr</code> and <code>Element</code> nodes, the + * <code>Text.isElementContentWhitespace</code> attribute for + * <code>Text</code> nodes, as well as any user data or event listeners + * registered on the nodes. + * <p ><b>Note:</b> As a general rule, anything not mentioned in the + * description above is not significant in consideration of equality + * checking. Note that future versions of this specification may take + * into account more attributes and implementations conform to this + * specification are expected to be updated accordingly. + * @param arg The node to compare equality with. + * @return Returns <code>true</code> if the nodes are equal, + * <code>false</code> otherwise. + * @since DOM Level 3 + */ + public boolean isEqualNode(Node arg); + + /** + * This method returns a specialized object which implements the + * specialized APIs of the specified feature and version, as specified + * in . The specialized object may also be obtained by using + * binding-specific casting methods but is not necessarily expected to, + * as discussed in . This method also allow the implementation to + * provide specialized objects which do not support the <code>Node</code> + * interface. + * @param feature The name of the feature requested. Note that any plus + * sign "+" prepended to the name of the feature will be ignored since + * it is not significant in the context of this method. + * @param version This is the version number of the feature to test. + * @return Returns an object which implements the specialized APIs of + * the specified feature and version, if any, or <code>null</code> if + * there is no object which implements interfaces associated with that + * feature. If the <code>DOMObject</code> returned by this method + * implements the <code>Node</code> interface, it must delegate to the + * primary core <code>Node</code> and not return results inconsistent + * with the primary core <code>Node</code> such as attributes, + * childNodes, etc. + * @since DOM Level 3 + */ + public Object getFeature(String feature, + String version); + + /** + * Associate an object to a key on this node. The object can later be + * retrieved from this node by calling <code>getUserData</code> with the + * same key. + * @param key The key to associate the object to. + * @param data The object to associate to the given key, or + * <code>null</code> to remove any existing association to that key. + * @param handler The handler to associate to that key, or + * <code>null</code>. + * @return Returns the <code>DOMUserData</code> previously associated to + * the given key on this node, or <code>null</code> if there was none. + * @since DOM Level 3 + */ + public Object setUserData(String key, + Object data, + UserDataHandler handler); + + /** + * Retrieves the object associated to a key on a this node. The object + * must first have been set to this node by calling + * <code>setUserData</code> with the same key. + * @param key The key the object is associated to. + * @return Returns the <code>DOMUserData</code> associated to the given + * key on this node, or <code>null</code> if there was none. + * @since DOM Level 3 + */ + public Object getUserData(String key); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/NodeList.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/NodeList.java new file mode 100644 index 000000000..4a98a9030 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/NodeList.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom; + +/** + * The <code>NodeList</code> interface provides the abstraction of an ordered + * collection of nodes, without defining or constraining how this collection + * is implemented. <code>NodeList</code> objects in the DOM are live. + * <p>The items in the <code>NodeList</code> are accessible via an integral + * index, starting from 0. + * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document Object Model (DOM) Level 3 Core Specification</a>. + */ +public interface NodeList { + /** + * Returns the <code>index</code>th item in the collection. If + * <code>index</code> is greater than or equal to the number of nodes in + * the list, this returns <code>null</code>. + * @param index Index into the collection. + * @return The node at the <code>index</code>th position in the + * <code>NodeList</code>, or <code>null</code> if that is not a valid + * index. + */ + public Node item(int index); + + /** + * The number of nodes in the list. The range of valid child node indices + * is 0 to <code>length-1</code> inclusive. + */ + public int getLength(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/Notation.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/Notation.java new file mode 100644 index 000000000..a7ad40992 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/Notation.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom; + +/** + * This interface represents a notation declared in the DTD. A notation either + * declares, by name, the format of an unparsed entity (see <a href='http://www.w3.org/TR/2004/REC-xml-20040204#Notations'>section 4.7</a> of the XML 1.0 specification [<a href='http://www.w3.org/TR/2004/REC-xml-20040204'>XML 1.0</a>]), or is + * used for formal declaration of processing instruction targets (see <a href='http://www.w3.org/TR/2004/REC-xml-20040204#sec-pi'>section 2.6</a> of the XML 1.0 specification [<a href='http://www.w3.org/TR/2004/REC-xml-20040204'>XML 1.0</a>]). The + * <code>nodeName</code> attribute inherited from <code>Node</code> is set + * to the declared name of the notation. + * <p>The DOM Core does not support editing <code>Notation</code> nodes; they + * are therefore readonly. + * <p>A <code>Notation</code> node does not have any parent. + * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document Object Model (DOM) Level 3 Core Specification</a>. + */ +public interface Notation extends Node { + /** + * The public identifier of this notation. If the public identifier was + * not specified, this is <code>null</code>. + */ + public String getPublicId(); + + /** + * The system identifier of this notation. If the system identifier was + * not specified, this is <code>null</code>. This may be an absolute URI + * or not. + */ + public String getSystemId(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/ProcessingInstruction.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/ProcessingInstruction.java new file mode 100644 index 000000000..61b789231 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/ProcessingInstruction.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom; + +/** + * The <code>ProcessingInstruction</code> interface represents a "processing + * instruction", used in XML as a way to keep processor-specific information + * in the text of the document. + * <p> No lexical check is done on the content of a processing instruction and + * it is therefore possible to have the character sequence + * <code>"?>"</code> in the content, which is illegal a processing + * instruction per section 2.6 of [<a href='http://www.w3.org/TR/2004/REC-xml-20040204'>XML 1.0</a>]. The + * presence of this character sequence must generate a fatal error during + * serialization. + * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document Object Model (DOM) Level 3 Core Specification</a>. + */ +public interface ProcessingInstruction extends Node { + /** + * The target of this processing instruction. XML defines this as being + * the first token following the markup that begins the processing + * instruction. + */ + public String getTarget(); + + /** + * The content of this processing instruction. This is from the first non + * white space character after the target to the character immediately + * preceding the <code>?></code>. + */ + public String getData(); + /** + * The content of this processing instruction. This is from the first non + * white space character after the target to the character immediately + * preceding the <code>?></code>. + * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly. + */ + public void setData(String data) + throws DOMException; + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/Text.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/Text.java new file mode 100644 index 000000000..872c5499d --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/Text.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom; + +/** + * The <code>Text</code> interface inherits from <code>CharacterData</code> + * and represents the textual content (termed <a href='http://www.w3.org/TR/2004/REC-xml-20040204#syntax'>character data</a> in XML) of an <code>Element</code> or <code>Attr</code>. If there is no + * markup inside an element's content, the text is contained in a single + * object implementing the <code>Text</code> interface that is the only + * child of the element. If there is markup, it is parsed into the + * information items (elements, comments, etc.) and <code>Text</code> nodes + * that form the list of children of the element. + * <p>When a document is first made available via the DOM, there is only one + * <code>Text</code> node for each block of text. Users may create adjacent + * <code>Text</code> nodes that represent the contents of a given element + * without any intervening markup, but should be aware that there is no way + * to represent the separations between these nodes in XML or HTML, so they + * will not (in general) persist between DOM editing sessions. The + * <code>Node.normalize()</code> method merges any such adjacent + * <code>Text</code> objects into a single node for each block of text. + * <p> No lexical check is done on the content of a <code>Text</code> node + * and, depending on its position in the document, some characters must be + * escaped during serialization using character references; e.g. the + * characters "<&" if the textual content is part of an element or of + * an attribute, the character sequence "]]>" when part of an element, + * the quotation mark character " or the apostrophe character ' when part of + * an attribute. + * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document Object Model (DOM) Level 3 Core Specification</a>. + */ +public interface Text extends CharacterData { + /** + * Breaks this node into two nodes at the specified <code>offset</code>, + * keeping both in the tree as siblings. After being split, this node + * will contain all the content up to the <code>offset</code> point. A + * new node of the same type, which contains all the content at and + * after the <code>offset</code> point, is returned. If the original + * node had a parent node, the new node is inserted as the next sibling + * of the original node. When the <code>offset</code> is equal to the + * length of this node, the new node has no data. + * @param offset The 16-bit unit offset at which to split, starting from + * <code>0</code>. + * @return The new node, of the same type as this node. + * @exception DOMException + * INDEX_SIZE_ERR: Raised if the specified offset is negative or greater + * than the number of 16-bit units in <code>data</code>. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly. + */ + public Text splitText(int offset) + throws DOMException; + + /** + * Returns whether this text node contains <a href='http://www.w3.org/TR/2004/REC-xml-infoset-20040204#infoitem.character'> + * element content whitespace</a>, often abusively called "ignorable whitespace". The text node is + * determined to contain whitespace in element content during the load + * of the document or if validation occurs while using + * <code>Document.normalizeDocument()</code>. + * @since DOM Level 3 + */ + public boolean isElementContentWhitespace(); + + /** + * Returns all text of <code>Text</code> nodes logically-adjacent text + * nodes to this node, concatenated in document order. + * <br>For instance, in the example below <code>wholeText</code> on the + * <code>Text</code> node that contains "bar" returns "barfoo", while on + * the <code>Text</code> node that contains "foo" it returns "barfoo". + * @since DOM Level 3 + */ + public String getWholeText(); + + /** + * Replaces the text of the current node and all logically-adjacent text + * nodes with the specified text. All logically-adjacent text nodes are + * removed including the current node unless it was the recipient of the + * replacement text. + * <br>This method returns the node which received the replacement text. + * The returned node is: + * <ul> + * <li><code>null</code>, when the replacement text is + * the empty string; + * </li> + * <li>the current node, except when the current node is + * read-only; + * </li> + * <li> a new <code>Text</code> node of the same type ( + * <code>Text</code> or <code>CDATASection</code>) as the current node + * inserted at the location of the replacement. + * </li> + * </ul> + * <br>For instance, in the above example calling + * <code>replaceWholeText</code> on the <code>Text</code> node that + * contains "bar" with "yo" in argument results in the following: + * <br>Where the nodes to be removed are read-only descendants of an + * <code>EntityReference</code>, the <code>EntityReference</code> must + * be removed instead of the read-only nodes. If any + * <code>EntityReference</code> to be removed has descendants that are + * not <code>EntityReference</code>, <code>Text</code>, or + * <code>CDATASection</code> nodes, the <code>replaceWholeText</code> + * method must fail before performing any modification of the document, + * raising a <code>DOMException</code> with the code + * <code>NO_MODIFICATION_ALLOWED_ERR</code>. + * <br>For instance, in the example below calling + * <code>replaceWholeText</code> on the <code>Text</code> node that + * contains "bar" fails, because the <code>EntityReference</code> node + * "ent" contains an <code>Element</code> node which cannot be removed. + * @param content The content of the replacing <code>Text</code> node. + * @return The <code>Text</code> node created with the specified content. + * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised if one of the <code>Text</code> + * nodes being replaced is readonly. + * @since DOM Level 3 + */ + public Text replaceWholeText(String content) + throws DOMException; + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/TypeInfo.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/TypeInfo.java new file mode 100644 index 000000000..d36f3cc37 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/TypeInfo.java @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom; + +/** + * The <code>TypeInfo</code> interface represents a type referenced from + * <code>Element</code> or <code>Attr</code> nodes, specified in the schemas + * associated with the document. The type is a pair of a namespace URI and + * name properties, and depends on the document's schema. + * <p> If the document's schema is an XML DTD [<a href='http://www.w3.org/TR/2004/REC-xml-20040204'>XML 1.0</a>], the values + * are computed as follows: + * <ul> + * <li> If this type is referenced from an + * <code>Attr</code> node, <code>typeNamespace</code> is + * <code>"http://www.w3.org/TR/REC-xml"</code> and <code>typeName</code> + * represents the <b>[attribute type]</b> property in the [<a href='http://www.w3.org/TR/2004/REC-xml-infoset-20040204/'>XML Information Set</a>] + * . If there is no declaration for the attribute, <code>typeNamespace</code> + * and <code>typeName</code> are <code>null</code>. + * </li> + * <li> If this type is + * referenced from an <code>Element</code> node, <code>typeNamespace</code> + * and <code>typeName</code> are <code>null</code>. + * </li> + * </ul> + * <p> If the document's schema is an XML Schema [<a href='http://www.w3.org/TR/2001/REC-xmlschema-1-20010502/'>XML Schema Part 1</a>] + * , the values are computed as follows using the post-schema-validation + * infoset contributions (also called PSVI contributions): + * <ul> + * <li> If the <b>[validity]</b> property exists AND is <em>"invalid"</em> or <em>"notKnown"</em>: the {target namespace} and {name} properties of the declared type if + * available, otherwise <code>null</code>. + * <p ><b>Note:</b> At the time of writing, the XML Schema specification does + * not require exposing the declared type. Thus, DOM implementations might + * choose not to provide type information if validity is not valid. + * </li> + * <li> If the <b>[validity]</b> property exists and is <em>"valid"</em>: + * <ol> + * <li> If <b>[member type definition]</b> exists: + * <ol> + * <li>If {name} is not absent, then expose {name} and {target + * namespace} properties of the <b>[member type definition]</b> property; + * </li> + * <li>Otherwise, expose the namespace and local name of the + * corresponding anonymous type name. + * </li> + * </ol> + * </li> + * <li> If the <b>[type definition]</b> property exists: + * <ol> + * <li>If {name} is not absent, then expose {name} and {target + * namespace} properties of the <b>[type definition]</b> property; + * </li> + * <li>Otherwise, expose the namespace and local name of the + * corresponding anonymous type name. + * </li> + * </ol> + * </li> + * <li> If the <b>[member type definition anonymous]</b> exists: + * <ol> + * <li>If it is false, then expose <b>[member type definition name]</b> and <b>[member type definition namespace]</b> properties; + * </li> + * <li>Otherwise, expose the namespace and local name of the + * corresponding anonymous type name. + * </li> + * </ol> + * </li> + * <li> If the <b>[type definition anonymous]</b> exists: + * <ol> + * <li>If it is false, then expose <b>[type definition name]</b> and <b>[type definition namespace]</b> properties; + * </li> + * <li>Otherwise, expose the namespace and local name of the + * corresponding anonymous type name. + * </li> + * </ol> + * </li> + * </ol> + * </li> + * </ul> + * <p ><b>Note:</b> Other schema languages are outside the scope of the W3C + * and therefore should define how to represent their type systems using + * <code>TypeInfo</code>. + * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document Object Model (DOM) Level 3 Core Specification</a>. + * @since DOM Level 3 + */ +public interface TypeInfo { + /** + * The name of a type declared for the associated element or attribute, + * or <code>null</code> if unknown. + */ + public String getTypeName(); + + /** + * The namespace of the type declared for the associated element or + * attribute or <code>null</code> if the element does not have + * declaration or if no namespace information is available. + */ + public String getTypeNamespace(); + + // DerivationMethods + /** + * If the document's schema is an XML Schema [<a href='http://www.w3.org/TR/2001/REC-xmlschema-1-20010502/'>XML Schema Part 1</a>] + * , this constant represents the derivation by <a href='http://www.w3.org/TR/2001/REC-xmlschema-1-20010502/#key-typeRestriction'> + * restriction</a> if complex types are involved, or a <a href='http://www.w3.org/TR/2001/REC-xmlschema-1-20010502/#element-restriction'> + * restriction</a> if simple types are involved. + * <br> The reference type definition is derived by restriction from the + * other type definition if the other type definition is the same as the + * reference type definition, or if the other type definition can be + * reached recursively following the {base type definition} property + * from the reference type definition, and all the <em>derivation methods</em> involved are restriction. + */ + public static final int DERIVATION_RESTRICTION = 0x00000001; + /** + * If the document's schema is an XML Schema [<a href='http://www.w3.org/TR/2001/REC-xmlschema-1-20010502/'>XML Schema Part 1</a>] + * , this constant represents the derivation by <a href='http://www.w3.org/TR/2001/REC-xmlschema-1-20010502/#key-typeExtension'> + * extension</a>. + * <br> The reference type definition is derived by extension from the + * other type definition if the other type definition can be reached + * recursively following the {base type definition} property from the + * reference type definition, and at least one of the <em>derivation methods</em> involved is an extension. + */ + public static final int DERIVATION_EXTENSION = 0x00000002; + /** + * If the document's schema is an XML Schema [<a href='http://www.w3.org/TR/2001/REC-xmlschema-1-20010502/'>XML Schema Part 1</a>] + * , this constant represents the <a href='http://www.w3.org/TR/2001/REC-xmlschema-1-20010502/#element-union'> + * union</a> if simple types are involved. + * <br> The reference type definition is derived by union from the other + * type definition if there exists two type definitions T1 and T2 such + * as the reference type definition is derived from T1 by + * <code>DERIVATION_RESTRICTION</code> or + * <code>DERIVATION_EXTENSION</code>, T2 is derived from the other type + * definition by <code>DERIVATION_RESTRICTION</code>, T1 has {variety} <em>union</em>, and one of the {member type definitions} is T2. Note that T1 could be + * the same as the reference type definition, and T2 could be the same + * as the other type definition. + */ + public static final int DERIVATION_UNION = 0x00000004; + /** + * If the document's schema is an XML Schema [<a href='http://www.w3.org/TR/2001/REC-xmlschema-1-20010502/'>XML Schema Part 1</a>] + * , this constant represents the <a href='http://www.w3.org/TR/2001/REC-xmlschema-1-20010502/#element-list'>list</a>. + * <br> The reference type definition is derived by list from the other + * type definition if there exists two type definitions T1 and T2 such + * as the reference type definition is derived from T1 by + * <code>DERIVATION_RESTRICTION</code> or + * <code>DERIVATION_EXTENSION</code>, T2 is derived from the other type + * definition by <code>DERIVATION_RESTRICTION</code>, T1 has {variety} <em>list</em>, and T2 is the {item type definition}. Note that T1 could be the same as + * the reference type definition, and T2 could be the same as the other + * type definition. + */ + public static final int DERIVATION_LIST = 0x00000008; + + /** + * This method returns if there is a derivation between the reference + * type definition, i.e. the <code>TypeInfo</code> on which the method + * is being called, and the other type definition, i.e. the one passed + * as parameters. + * @param typeNamespaceArg the namespace of the other type definition. + * @param typeNameArg the name of the other type definition. + * @param derivationMethod the type of derivation and conditions applied + * between two types, as described in the list of constants provided + * in this interface. + * @return If the document's schema is a DTD or no schema is associated + * with the document, this method will always return <code>false</code> + * . If the document's schema is an XML Schema, the method will + * <code>true</code> if the reference type definition is derived from + * the other type definition according to the derivation parameter. If + * the value of the parameter is <code>0</code> (no bit is set to + * <code>1</code> for the <code>derivationMethod</code> parameter), + * the method will return <code>true</code> if the other type + * definition can be reached by recursing any combination of {base + * type definition}, {item type definition}, or {member type + * definitions} from the reference type definition. + */ + public boolean isDerivedFrom(String typeNamespaceArg, + String typeNameArg, + int derivationMethod); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/UserDataHandler.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/UserDataHandler.java new file mode 100644 index 000000000..cf6ee5669 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/UserDataHandler.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom; + +/** + * When associating an object to a key on a node using + * <code>Node.setUserData()</code> the application can provide a handler + * that gets called when the node the object is associated to is being + * cloned, imported, or renamed. This can be used by the application to + * implement various behaviors regarding the data it associates to the DOM + * nodes. This interface defines that handler. + * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document Object Model (DOM) Level 3 Core Specification</a>. + * @since DOM Level 3 + */ +public interface UserDataHandler { + // OperationType + /** + * The node is cloned, using <code>Node.cloneNode()</code>. + */ + public static final short NODE_CLONED = 1; + /** + * The node is imported, using <code>Document.importNode()</code>. + */ + public static final short NODE_IMPORTED = 2; + /** + * The node is deleted. + * <p ><b>Note:</b> This may not be supported or may not be reliable in + * certain environments, such as Java, where the implementation has no + * real control over when objects are actually deleted. + */ + public static final short NODE_DELETED = 3; + /** + * The node is renamed, using <code>Document.renameNode()</code>. + */ + public static final short NODE_RENAMED = 4; + /** + * The node is adopted, using <code>Document.adoptNode()</code>. + */ + public static final short NODE_ADOPTED = 5; + + /** + * This method is called whenever the node for which this handler is + * registered is imported or cloned. + * <br> DOM applications must not raise exceptions in a + * <code>UserDataHandler</code>. The effect of throwing exceptions from + * the handler is DOM implementation dependent. + * @param operation Specifies the type of operation that is being + * performed on the node. + * @param key Specifies the key for which this handler is being called. + * @param data Specifies the data for which this handler is being called. + * @param src Specifies the node being cloned, adopted, imported, or + * renamed. This is <code>null</code> when the node is being deleted. + * @param dst Specifies the node newly created if any, or + * <code>null</code>. + */ + public void handle(short operation, + String key, + Object data, + Node src, + Node dst); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/bootstrap/DOMImplementationRegistry.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/bootstrap/DOMImplementationRegistry.java new file mode 100644 index 000000000..5be8c3ab1 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/bootstrap/DOMImplementationRegistry.java @@ -0,0 +1,387 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + + +package org.w3c.dom.bootstrap; + +import java.util.StringTokenizer; +import java.util.Vector; +import org.w3c.dom.DOMImplementationSource; +import org.w3c.dom.DOMImplementationList; +import org.w3c.dom.DOMImplementation; +import java.io.InputStream; +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.security.AccessController; +import java.security.PrivilegedAction; + +/** + * A factory that enables applications to obtain instances of + * <code>DOMImplementation</code>. + * + * <p> + * Example: + * </p> + * + * <pre class='example'> + * // get an instance of the DOMImplementation registry + * DOMImplementationRegistry registry = + * DOMImplementationRegistry.newInstance(); + * // get a DOM implementation the Level 3 XML module + * DOMImplementation domImpl = + * registry.getDOMImplementation("XML 3.0"); + * </pre> + * + * <p> + * This provides an application with an implementation-independent starting + * point. DOM implementations may modify this class to meet new security + * standards or to provide *additional* fallbacks for the list of + * DOMImplementationSources. + * </p> + * + * @see DOMImplementation + * @see DOMImplementationSource + * @since DOM Level 3 + */ +public final class DOMImplementationRegistry { + /** + * The system property to specify the + * DOMImplementationSource class names. + */ + public static final String PROPERTY = + "org.w3c.dom.DOMImplementationSourceList"; + + /** + * Default columns per line. + */ + private static final int DEFAULT_LINE_LENGTH = 80; + + /** + * The list of DOMImplementationSources. + */ + private Vector sources; + + /** + * Private constructor. + * @param srcs Vector List of DOMImplementationSources + */ + private DOMImplementationRegistry(final Vector srcs) { + sources = srcs; + } + + /** + * Obtain a new instance of a <code>DOMImplementationRegistry</code>. + * + + * The <code>DOMImplementationRegistry</code> is initialized by the + * application or the implementation, depending on the context, by + * first checking the value of the Java system property + * <code>org.w3c.dom.DOMImplementationSourceList</code> and + * the the service provider whose contents are at + * "<code>META_INF/services/org.w3c.dom.DOMImplementationSourceList</code>" + * The value of this property is a white-space separated list of + * names of availables classes implementing the + * <code>DOMImplementationSource</code> interface. Each class listed + * in the class name list is instantiated and any exceptions + * encountered are thrown to the application. + * + * @return an initialized instance of DOMImplementationRegistry + * @throws ClassNotFoundException + * If any specified class can not be found + * @throws InstantiationException + * If any specified class is an interface or abstract class + * @throws IllegalAccessException + * If the default constructor of a specified class is not accessible + * @throws ClassCastException + * If any specified class does not implement + * <code>DOMImplementationSource</code> + */ + public static DOMImplementationRegistry newInstance() + throws + ClassNotFoundException, + InstantiationException, + IllegalAccessException, + ClassCastException { + Vector sources = new Vector(); + + ClassLoader classLoader = getClassLoader(); + // fetch system property: + String p = getSystemProperty(PROPERTY); + + // + // if property is not specified then use contents of + // META_INF/org.w3c.dom.DOMImplementationSourceList from classpath + if (p == null) { + p = getServiceValue(classLoader); + } + if (p == null) { + // + // DOM Implementations can modify here to add *additional* fallback + // mechanisms to access a list of default DOMImplementationSources. + p = "gnu.xml.dom.ImplementationSource"; + } + if (p != null) { + StringTokenizer st = new StringTokenizer(p); + while (st.hasMoreTokens()) { + String sourceName = st.nextToken(); + // Use context class loader, falling back to Class.forName + // if and only if this fails... + Class sourceClass = null; + if (classLoader != null) { + sourceClass = classLoader.loadClass(sourceName); + } else { + sourceClass = Class.forName(sourceName); + } + DOMImplementationSource source = + (DOMImplementationSource) sourceClass.newInstance(); + sources.addElement(source); + } + } + return new DOMImplementationRegistry(sources); + } + + /** + * Return the first implementation that has the desired + * features, or <code>null</code> if none is found. + * + * @param features + * A string that specifies which features are required. This is + * a space separated list in which each feature is specified by + * its name optionally followed by a space and a version number. + * This is something like: "XML 1.0 Traversal +Events 2.0" + * @return An implementation that has the desired features, + * or <code>null</code> if none found. + */ + public DOMImplementation getDOMImplementation(final String features) { + int size = sources.size(); + String name = null; + for (int i = 0; i < size; i++) { + DOMImplementationSource source = + (DOMImplementationSource) sources.elementAt(i); + DOMImplementation impl = source.getDOMImplementation(features); + if (impl != null) { + return impl; + } + } + return null; + } + + /** + * Return a list of implementations that support the + * desired features. + * + * @param features + * A string that specifies which features are required. This is + * a space separated list in which each feature is specified by + * its name optionally followed by a space and a version number. + * This is something like: "XML 1.0 Traversal +Events 2.0" + * @return A list of DOMImplementations that support the desired features. + */ + public DOMImplementationList getDOMImplementationList(final String features) { + final Vector implementations = new Vector(); + int size = sources.size(); + for (int i = 0; i < size; i++) { + DOMImplementationSource source = + (DOMImplementationSource) sources.elementAt(i); + DOMImplementationList impls = + source.getDOMImplementationList(features); + for (int j = 0; j < impls.getLength(); j++) { + DOMImplementation impl = impls.item(j); + implementations.addElement(impl); + } + } + return new DOMImplementationList() { + public DOMImplementation item(final int index) { + if (index >= 0 && index < implementations.size()) { + try { + return (DOMImplementation) + implementations.elementAt(index); + } catch (ArrayIndexOutOfBoundsException e) { + return null; + } + } + return null; + } + + public int getLength() { + return implementations.size(); + } + }; + } + + /** + * Register an implementation. + * + * @param s The source to be registered, may not be <code>null</code> + */ + public void addSource(final DOMImplementationSource s) { + if (s == null) { + throw new NullPointerException(); + } + if (!sources.contains(s)) { + sources.addElement(s); + } + } + + /** + * + * Gets a class loader. + * + * @return A class loader, possibly <code>null</code> + */ + private static ClassLoader getClassLoader() { + try { + ClassLoader contextClassLoader = getContextClassLoader(); + + if (contextClassLoader != null) { + return contextClassLoader; + } + } catch (Exception e) { + // Assume that the DOM application is in a JRE 1.1, use the + // current ClassLoader + return DOMImplementationRegistry.class.getClassLoader(); + } + return DOMImplementationRegistry.class.getClassLoader(); + } + + /** + * This method attempts to return the first line of the resource + * META_INF/services/org.w3c.dom.DOMImplementationSourceList + * from the provided ClassLoader. + * + * @param classLoader classLoader, may not be <code>null</code>. + * @return first line of resource, or <code>null</code> + */ + private static String getServiceValue(final ClassLoader classLoader) { + String serviceId = "META-INF/services/" + PROPERTY; + // try to find services in CLASSPATH + try { + InputStream is = getResourceAsStream(classLoader, serviceId); + + if (is != null) { + BufferedReader rd; + try { + rd = + new BufferedReader(new InputStreamReader(is, "UTF-8"), + DEFAULT_LINE_LENGTH); + } catch (java.io.UnsupportedEncodingException e) { + rd = + new BufferedReader(new InputStreamReader(is), + DEFAULT_LINE_LENGTH); + } + String serviceValue = rd.readLine(); + rd.close(); + if (serviceValue != null && serviceValue.length() > 0) { + return serviceValue; + } + } + } catch (Exception ex) { + return null; + } + return null; + } + + /** + * A simple JRE (Java Runtime Environment) 1.1 test + * + * @return <code>true</code> if JRE 1.1 + */ + private static boolean isJRE11() { + try { + Class c = Class.forName("java.security.AccessController"); + // java.security.AccessController existed since 1.2 so, if no + // exception was thrown, the DOM application is running in a JRE + // 1.2 or higher + return false; + } catch (Exception ex) { + // ignore + } + return true; + } + + /** + * This method returns the ContextClassLoader or <code>null</code> if + * running in a JRE 1.1 + * + * @return The Context Classloader + */ + private static ClassLoader getContextClassLoader() { + return isJRE11() + ? null + : (ClassLoader) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + ClassLoader classLoader = null; + try { + classLoader = + Thread.currentThread().getContextClassLoader(); + } catch (SecurityException ex) { + } + return classLoader; + } + }); + } + + /** + * This method returns the system property indicated by the specified name + * after checking access control privileges. For a JRE 1.1, this check is + * not done. + * + * @param name the name of the system property + * @return the system property + */ + private static String getSystemProperty(final String name) { + return isJRE11() + ? (String) System.getProperty(name) + : (String) AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + return System.getProperty(name); + } + }); + } + + /** + * This method returns an Inputstream for the reading resource + * META_INF/services/org.w3c.dom.DOMImplementationSourceList after checking + * access control privileges. For a JRE 1.1, this check is not done. + * + * @param classLoader classLoader + * @param name the resource + * @return an Inputstream for the resource specified + */ + private static InputStream getResourceAsStream(final ClassLoader classLoader, + final String name) { + if (isJRE11()) { + InputStream ris; + if (classLoader == null) { + ris = ClassLoader.getSystemResourceAsStream(name); + } else { + ris = classLoader.getResourceAsStream(name); + } + return ris; + } else { + return (InputStream) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + InputStream ris; + if (classLoader == null) { + ris = + ClassLoader.getSystemResourceAsStream(name); + } else { + ris = classLoader.getResourceAsStream(name); + } + return ris; + } + }); + } + } +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSS2Properties.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSS2Properties.java new file mode 100644 index 000000000..238eea342 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSS2Properties.java @@ -0,0 +1,1777 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.css; + +import org.w3c.dom.DOMException; + +/** + * The <code>CSS2Properties</code> interface represents a convenience + * mechanism for retrieving and setting properties within a + * <code>CSSStyleDeclaration</code>. The attributes of this interface + * correspond to all the properties specified in CSS2. Getting an attribute + * of this interface is equivalent to calling the + * <code>getPropertyValue</code> method of the + * <code>CSSStyleDeclaration</code> interface. Setting an attribute of this + * interface is equivalent to calling the <code>setProperty</code> method of + * the <code>CSSStyleDeclaration</code> interface. + * <p> A conformant implementation of the CSS module is not required to + * implement the <code>CSS2Properties</code> interface. If an implementation + * does implement this interface, the expectation is that language-specific + * methods can be used to cast from an instance of the + * <code>CSSStyleDeclaration</code> interface to the + * <code>CSS2Properties</code> interface. + * <p> If an implementation does implement this interface, it is expected to + * understand the specific syntax of the shorthand properties, and apply + * their semantics; when the <code>margin</code> property is set, for + * example, the <code>marginTop</code>, <code>marginRight</code>, + * <code>marginBottom</code> and <code>marginLeft</code> properties are + * actually being set by the underlying implementation. + * <p> When dealing with CSS "shorthand" properties, the shorthand properties + * should be decomposed into their component longhand properties as + * appropriate, and when querying for their value, the form returned should + * be the shortest form exactly equivalent to the declarations made in the + * ruleset. However, if there is no shorthand declaration that could be + * added to the ruleset without changing in any way the rules already + * declared in the ruleset (i.e., by adding longhand rules that were + * previously not declared in the ruleset), then the empty string should be + * returned for the shorthand property. + * <p> For example, querying for the <code>font</code> property should not + * return "normal normal normal 14pt/normal Arial, sans-serif", when "14pt + * Arial, sans-serif" suffices. (The normals are initial values, and are + * implied by use of the longhand property.) + * <p> If the values for all the longhand properties that compose a particular + * string are the initial values, then a string consisting of all the + * initial values should be returned (e.g. a <code>border-width</code> value + * of "medium" should be returned as such, not as ""). + * <p> For some shorthand properties that take missing values from other + * sides, such as the <code>margin</code>, <code>padding</code>, and + * <code>border-[width|style|color]</code> properties, the minimum number of + * sides possible should be used; i.e., "0px 10px" will be returned instead + * of "0px 10px 0px 10px". + * <p> If the value of a shorthand property can not be decomposed into its + * component longhand properties, as is the case for the <code>font</code> + * property with a value of "menu", querying for the values of the component + * longhand properties should return the empty string. + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113'>Document Object Model (DOM) Level 2 Style Specification</a>. + * @since DOM Level 2 + */ +public interface CSS2Properties { + /** + * See the azimuth property definition in CSS2. + */ + public String getAzimuth(); + /** + * See the azimuth property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setAzimuth(String azimuth) + throws DOMException; + + /** + * See the background property definition in CSS2. + */ + public String getBackground(); + /** + * See the background property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setBackground(String background) + throws DOMException; + + /** + * See the background-attachment property definition in CSS2. + */ + public String getBackgroundAttachment(); + /** + * See the background-attachment property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setBackgroundAttachment(String backgroundAttachment) + throws DOMException; + + /** + * See the background-color property definition in CSS2. + */ + public String getBackgroundColor(); + /** + * See the background-color property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setBackgroundColor(String backgroundColor) + throws DOMException; + + /** + * See the background-image property definition in CSS2. + */ + public String getBackgroundImage(); + /** + * See the background-image property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setBackgroundImage(String backgroundImage) + throws DOMException; + + /** + * See the background-position property definition in CSS2. + */ + public String getBackgroundPosition(); + /** + * See the background-position property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setBackgroundPosition(String backgroundPosition) + throws DOMException; + + /** + * See the background-repeat property definition in CSS2. + */ + public String getBackgroundRepeat(); + /** + * See the background-repeat property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setBackgroundRepeat(String backgroundRepeat) + throws DOMException; + + /** + * See the border property definition in CSS2. + */ + public String getBorder(); + /** + * See the border property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setBorder(String border) + throws DOMException; + + /** + * See the border-collapse property definition in CSS2. + */ + public String getBorderCollapse(); + /** + * See the border-collapse property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setBorderCollapse(String borderCollapse) + throws DOMException; + + /** + * See the border-color property definition in CSS2. + */ + public String getBorderColor(); + /** + * See the border-color property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setBorderColor(String borderColor) + throws DOMException; + + /** + * See the border-spacing property definition in CSS2. + */ + public String getBorderSpacing(); + /** + * See the border-spacing property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setBorderSpacing(String borderSpacing) + throws DOMException; + + /** + * See the border-style property definition in CSS2. + */ + public String getBorderStyle(); + /** + * See the border-style property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setBorderStyle(String borderStyle) + throws DOMException; + + /** + * See the border-top property definition in CSS2. + */ + public String getBorderTop(); + /** + * See the border-top property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setBorderTop(String borderTop) + throws DOMException; + + /** + * See the border-right property definition in CSS2. + */ + public String getBorderRight(); + /** + * See the border-right property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setBorderRight(String borderRight) + throws DOMException; + + /** + * See the border-bottom property definition in CSS2. + */ + public String getBorderBottom(); + /** + * See the border-bottom property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setBorderBottom(String borderBottom) + throws DOMException; + + /** + * See the border-left property definition in CSS2. + */ + public String getBorderLeft(); + /** + * See the border-left property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setBorderLeft(String borderLeft) + throws DOMException; + + /** + * See the border-top-color property definition in CSS2. + */ + public String getBorderTopColor(); + /** + * See the border-top-color property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setBorderTopColor(String borderTopColor) + throws DOMException; + + /** + * See the border-right-color property definition in CSS2. + */ + public String getBorderRightColor(); + /** + * See the border-right-color property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setBorderRightColor(String borderRightColor) + throws DOMException; + + /** + * See the border-bottom-color property definition in CSS2. + */ + public String getBorderBottomColor(); + /** + * See the border-bottom-color property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setBorderBottomColor(String borderBottomColor) + throws DOMException; + + /** + * See the border-left-color property definition in CSS2. + */ + public String getBorderLeftColor(); + /** + * See the border-left-color property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setBorderLeftColor(String borderLeftColor) + throws DOMException; + + /** + * See the border-top-style property definition in CSS2. + */ + public String getBorderTopStyle(); + /** + * See the border-top-style property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setBorderTopStyle(String borderTopStyle) + throws DOMException; + + /** + * See the border-right-style property definition in CSS2. + */ + public String getBorderRightStyle(); + /** + * See the border-right-style property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setBorderRightStyle(String borderRightStyle) + throws DOMException; + + /** + * See the border-bottom-style property definition in CSS2. + */ + public String getBorderBottomStyle(); + /** + * See the border-bottom-style property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setBorderBottomStyle(String borderBottomStyle) + throws DOMException; + + /** + * See the border-left-style property definition in CSS2. + */ + public String getBorderLeftStyle(); + /** + * See the border-left-style property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setBorderLeftStyle(String borderLeftStyle) + throws DOMException; + + /** + * See the border-top-width property definition in CSS2. + */ + public String getBorderTopWidth(); + /** + * See the border-top-width property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setBorderTopWidth(String borderTopWidth) + throws DOMException; + + /** + * See the border-right-width property definition in CSS2. + */ + public String getBorderRightWidth(); + /** + * See the border-right-width property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setBorderRightWidth(String borderRightWidth) + throws DOMException; + + /** + * See the border-bottom-width property definition in CSS2. + */ + public String getBorderBottomWidth(); + /** + * See the border-bottom-width property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setBorderBottomWidth(String borderBottomWidth) + throws DOMException; + + /** + * See the border-left-width property definition in CSS2. + */ + public String getBorderLeftWidth(); + /** + * See the border-left-width property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setBorderLeftWidth(String borderLeftWidth) + throws DOMException; + + /** + * See the border-width property definition in CSS2. + */ + public String getBorderWidth(); + /** + * See the border-width property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setBorderWidth(String borderWidth) + throws DOMException; + + /** + * See the bottom property definition in CSS2. + */ + public String getBottom(); + /** + * See the bottom property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setBottom(String bottom) + throws DOMException; + + /** + * See the caption-side property definition in CSS2. + */ + public String getCaptionSide(); + /** + * See the caption-side property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setCaptionSide(String captionSide) + throws DOMException; + + /** + * See the clear property definition in CSS2. + */ + public String getClear(); + /** + * See the clear property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setClear(String clear) + throws DOMException; + + /** + * See the clip property definition in CSS2. + */ + public String getClip(); + /** + * See the clip property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setClip(String clip) + throws DOMException; + + /** + * See the color property definition in CSS2. + */ + public String getColor(); + /** + * See the color property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setColor(String color) + throws DOMException; + + /** + * See the content property definition in CSS2. + */ + public String getContent(); + /** + * See the content property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setContent(String content) + throws DOMException; + + /** + * See the counter-increment property definition in CSS2. + */ + public String getCounterIncrement(); + /** + * See the counter-increment property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setCounterIncrement(String counterIncrement) + throws DOMException; + + /** + * See the counter-reset property definition in CSS2. + */ + public String getCounterReset(); + /** + * See the counter-reset property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setCounterReset(String counterReset) + throws DOMException; + + /** + * See the cue property definition in CSS2. + */ + public String getCue(); + /** + * See the cue property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setCue(String cue) + throws DOMException; + + /** + * See the cue-after property definition in CSS2. + */ + public String getCueAfter(); + /** + * See the cue-after property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setCueAfter(String cueAfter) + throws DOMException; + + /** + * See the cue-before property definition in CSS2. + */ + public String getCueBefore(); + /** + * See the cue-before property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setCueBefore(String cueBefore) + throws DOMException; + + /** + * See the cursor property definition in CSS2. + */ + public String getCursor(); + /** + * See the cursor property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setCursor(String cursor) + throws DOMException; + + /** + * See the direction property definition in CSS2. + */ + public String getDirection(); + /** + * See the direction property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setDirection(String direction) + throws DOMException; + + /** + * See the display property definition in CSS2. + */ + public String getDisplay(); + /** + * See the display property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setDisplay(String display) + throws DOMException; + + /** + * See the elevation property definition in CSS2. + */ + public String getElevation(); + /** + * See the elevation property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setElevation(String elevation) + throws DOMException; + + /** + * See the empty-cells property definition in CSS2. + */ + public String getEmptyCells(); + /** + * See the empty-cells property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setEmptyCells(String emptyCells) + throws DOMException; + + /** + * See the float property definition in CSS2. + */ + public String getCssFloat(); + /** + * See the float property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setCssFloat(String cssFloat) + throws DOMException; + + /** + * See the font property definition in CSS2. + */ + public String getFont(); + /** + * See the font property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setFont(String font) + throws DOMException; + + /** + * See the font-family property definition in CSS2. + */ + public String getFontFamily(); + /** + * See the font-family property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setFontFamily(String fontFamily) + throws DOMException; + + /** + * See the font-size property definition in CSS2. + */ + public String getFontSize(); + /** + * See the font-size property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setFontSize(String fontSize) + throws DOMException; + + /** + * See the font-size-adjust property definition in CSS2. + */ + public String getFontSizeAdjust(); + /** + * See the font-size-adjust property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setFontSizeAdjust(String fontSizeAdjust) + throws DOMException; + + /** + * See the font-stretch property definition in CSS2. + */ + public String getFontStretch(); + /** + * See the font-stretch property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setFontStretch(String fontStretch) + throws DOMException; + + /** + * See the font-style property definition in CSS2. + */ + public String getFontStyle(); + /** + * See the font-style property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setFontStyle(String fontStyle) + throws DOMException; + + /** + * See the font-variant property definition in CSS2. + */ + public String getFontVariant(); + /** + * See the font-variant property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setFontVariant(String fontVariant) + throws DOMException; + + /** + * See the font-weight property definition in CSS2. + */ + public String getFontWeight(); + /** + * See the font-weight property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setFontWeight(String fontWeight) + throws DOMException; + + /** + * See the height property definition in CSS2. + */ + public String getHeight(); + /** + * See the height property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setHeight(String height) + throws DOMException; + + /** + * See the left property definition in CSS2. + */ + public String getLeft(); + /** + * See the left property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setLeft(String left) + throws DOMException; + + /** + * See the letter-spacing property definition in CSS2. + */ + public String getLetterSpacing(); + /** + * See the letter-spacing property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setLetterSpacing(String letterSpacing) + throws DOMException; + + /** + * See the line-height property definition in CSS2. + */ + public String getLineHeight(); + /** + * See the line-height property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setLineHeight(String lineHeight) + throws DOMException; + + /** + * See the list-style property definition in CSS2. + */ + public String getListStyle(); + /** + * See the list-style property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setListStyle(String listStyle) + throws DOMException; + + /** + * See the list-style-image property definition in CSS2. + */ + public String getListStyleImage(); + /** + * See the list-style-image property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setListStyleImage(String listStyleImage) + throws DOMException; + + /** + * See the list-style-position property definition in CSS2. + */ + public String getListStylePosition(); + /** + * See the list-style-position property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setListStylePosition(String listStylePosition) + throws DOMException; + + /** + * See the list-style-type property definition in CSS2. + */ + public String getListStyleType(); + /** + * See the list-style-type property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setListStyleType(String listStyleType) + throws DOMException; + + /** + * See the margin property definition in CSS2. + */ + public String getMargin(); + /** + * See the margin property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setMargin(String margin) + throws DOMException; + + /** + * See the margin-top property definition in CSS2. + */ + public String getMarginTop(); + /** + * See the margin-top property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setMarginTop(String marginTop) + throws DOMException; + + /** + * See the margin-right property definition in CSS2. + */ + public String getMarginRight(); + /** + * See the margin-right property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setMarginRight(String marginRight) + throws DOMException; + + /** + * See the margin-bottom property definition in CSS2. + */ + public String getMarginBottom(); + /** + * See the margin-bottom property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setMarginBottom(String marginBottom) + throws DOMException; + + /** + * See the margin-left property definition in CSS2. + */ + public String getMarginLeft(); + /** + * See the margin-left property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setMarginLeft(String marginLeft) + throws DOMException; + + /** + * See the marker-offset property definition in CSS2. + */ + public String getMarkerOffset(); + /** + * See the marker-offset property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setMarkerOffset(String markerOffset) + throws DOMException; + + /** + * See the marks property definition in CSS2. + */ + public String getMarks(); + /** + * See the marks property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setMarks(String marks) + throws DOMException; + + /** + * See the max-height property definition in CSS2. + */ + public String getMaxHeight(); + /** + * See the max-height property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setMaxHeight(String maxHeight) + throws DOMException; + + /** + * See the max-width property definition in CSS2. + */ + public String getMaxWidth(); + /** + * See the max-width property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setMaxWidth(String maxWidth) + throws DOMException; + + /** + * See the min-height property definition in CSS2. + */ + public String getMinHeight(); + /** + * See the min-height property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setMinHeight(String minHeight) + throws DOMException; + + /** + * See the min-width property definition in CSS2. + */ + public String getMinWidth(); + /** + * See the min-width property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setMinWidth(String minWidth) + throws DOMException; + + /** + * See the orphans property definition in CSS2. + */ + public String getOrphans(); + /** + * See the orphans property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setOrphans(String orphans) + throws DOMException; + + /** + * See the outline property definition in CSS2. + */ + public String getOutline(); + /** + * See the outline property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setOutline(String outline) + throws DOMException; + + /** + * See the outline-color property definition in CSS2. + */ + public String getOutlineColor(); + /** + * See the outline-color property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setOutlineColor(String outlineColor) + throws DOMException; + + /** + * See the outline-style property definition in CSS2. + */ + public String getOutlineStyle(); + /** + * See the outline-style property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setOutlineStyle(String outlineStyle) + throws DOMException; + + /** + * See the outline-width property definition in CSS2. + */ + public String getOutlineWidth(); + /** + * See the outline-width property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setOutlineWidth(String outlineWidth) + throws DOMException; + + /** + * See the overflow property definition in CSS2. + */ + public String getOverflow(); + /** + * See the overflow property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setOverflow(String overflow) + throws DOMException; + + /** + * See the padding property definition in CSS2. + */ + public String getPadding(); + /** + * See the padding property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setPadding(String padding) + throws DOMException; + + /** + * See the padding-top property definition in CSS2. + */ + public String getPaddingTop(); + /** + * See the padding-top property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setPaddingTop(String paddingTop) + throws DOMException; + + /** + * See the padding-right property definition in CSS2. + */ + public String getPaddingRight(); + /** + * See the padding-right property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setPaddingRight(String paddingRight) + throws DOMException; + + /** + * See the padding-bottom property definition in CSS2. + */ + public String getPaddingBottom(); + /** + * See the padding-bottom property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setPaddingBottom(String paddingBottom) + throws DOMException; + + /** + * See the padding-left property definition in CSS2. + */ + public String getPaddingLeft(); + /** + * See the padding-left property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setPaddingLeft(String paddingLeft) + throws DOMException; + + /** + * See the page property definition in CSS2. + */ + public String getPage(); + /** + * See the page property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setPage(String page) + throws DOMException; + + /** + * See the page-break-after property definition in CSS2. + */ + public String getPageBreakAfter(); + /** + * See the page-break-after property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setPageBreakAfter(String pageBreakAfter) + throws DOMException; + + /** + * See the page-break-before property definition in CSS2. + */ + public String getPageBreakBefore(); + /** + * See the page-break-before property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setPageBreakBefore(String pageBreakBefore) + throws DOMException; + + /** + * See the page-break-inside property definition in CSS2. + */ + public String getPageBreakInside(); + /** + * See the page-break-inside property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setPageBreakInside(String pageBreakInside) + throws DOMException; + + /** + * See the pause property definition in CSS2. + */ + public String getPause(); + /** + * See the pause property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setPause(String pause) + throws DOMException; + + /** + * See the pause-after property definition in CSS2. + */ + public String getPauseAfter(); + /** + * See the pause-after property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setPauseAfter(String pauseAfter) + throws DOMException; + + /** + * See the pause-before property definition in CSS2. + */ + public String getPauseBefore(); + /** + * See the pause-before property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setPauseBefore(String pauseBefore) + throws DOMException; + + /** + * See the pitch property definition in CSS2. + */ + public String getPitch(); + /** + * See the pitch property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setPitch(String pitch) + throws DOMException; + + /** + * See the pitch-range property definition in CSS2. + */ + public String getPitchRange(); + /** + * See the pitch-range property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setPitchRange(String pitchRange) + throws DOMException; + + /** + * See the play-during property definition in CSS2. + */ + public String getPlayDuring(); + /** + * See the play-during property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setPlayDuring(String playDuring) + throws DOMException; + + /** + * See the position property definition in CSS2. + */ + public String getPosition(); + /** + * See the position property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setPosition(String position) + throws DOMException; + + /** + * See the quotes property definition in CSS2. + */ + public String getQuotes(); + /** + * See the quotes property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setQuotes(String quotes) + throws DOMException; + + /** + * See the richness property definition in CSS2. + */ + public String getRichness(); + /** + * See the richness property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setRichness(String richness) + throws DOMException; + + /** + * See the right property definition in CSS2. + */ + public String getRight(); + /** + * See the right property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setRight(String right) + throws DOMException; + + /** + * See the size property definition in CSS2. + */ + public String getSize(); + /** + * See the size property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setSize(String size) + throws DOMException; + + /** + * See the speak property definition in CSS2. + */ + public String getSpeak(); + /** + * See the speak property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setSpeak(String speak) + throws DOMException; + + /** + * See the speak-header property definition in CSS2. + */ + public String getSpeakHeader(); + /** + * See the speak-header property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setSpeakHeader(String speakHeader) + throws DOMException; + + /** + * See the speak-numeral property definition in CSS2. + */ + public String getSpeakNumeral(); + /** + * See the speak-numeral property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setSpeakNumeral(String speakNumeral) + throws DOMException; + + /** + * See the speak-punctuation property definition in CSS2. + */ + public String getSpeakPunctuation(); + /** + * See the speak-punctuation property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setSpeakPunctuation(String speakPunctuation) + throws DOMException; + + /** + * See the speech-rate property definition in CSS2. + */ + public String getSpeechRate(); + /** + * See the speech-rate property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setSpeechRate(String speechRate) + throws DOMException; + + /** + * See the stress property definition in CSS2. + */ + public String getStress(); + /** + * See the stress property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setStress(String stress) + throws DOMException; + + /** + * See the table-layout property definition in CSS2. + */ + public String getTableLayout(); + /** + * See the table-layout property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setTableLayout(String tableLayout) + throws DOMException; + + /** + * See the text-align property definition in CSS2. + */ + public String getTextAlign(); + /** + * See the text-align property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setTextAlign(String textAlign) + throws DOMException; + + /** + * See the text-decoration property definition in CSS2. + */ + public String getTextDecoration(); + /** + * See the text-decoration property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setTextDecoration(String textDecoration) + throws DOMException; + + /** + * See the text-indent property definition in CSS2. + */ + public String getTextIndent(); + /** + * See the text-indent property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setTextIndent(String textIndent) + throws DOMException; + + /** + * See the text-shadow property definition in CSS2. + */ + public String getTextShadow(); + /** + * See the text-shadow property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setTextShadow(String textShadow) + throws DOMException; + + /** + * See the text-transform property definition in CSS2. + */ + public String getTextTransform(); + /** + * See the text-transform property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setTextTransform(String textTransform) + throws DOMException; + + /** + * See the top property definition in CSS2. + */ + public String getTop(); + /** + * See the top property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setTop(String top) + throws DOMException; + + /** + * See the unicode-bidi property definition in CSS2. + */ + public String getUnicodeBidi(); + /** + * See the unicode-bidi property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setUnicodeBidi(String unicodeBidi) + throws DOMException; + + /** + * See the vertical-align property definition in CSS2. + */ + public String getVerticalAlign(); + /** + * See the vertical-align property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setVerticalAlign(String verticalAlign) + throws DOMException; + + /** + * See the visibility property definition in CSS2. + */ + public String getVisibility(); + /** + * See the visibility property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setVisibility(String visibility) + throws DOMException; + + /** + * See the voice-family property definition in CSS2. + */ + public String getVoiceFamily(); + /** + * See the voice-family property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setVoiceFamily(String voiceFamily) + throws DOMException; + + /** + * See the volume property definition in CSS2. + */ + public String getVolume(); + /** + * See the volume property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setVolume(String volume) + throws DOMException; + + /** + * See the white-space property definition in CSS2. + */ + public String getWhiteSpace(); + /** + * See the white-space property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setWhiteSpace(String whiteSpace) + throws DOMException; + + /** + * See the widows property definition in CSS2. + */ + public String getWidows(); + /** + * See the widows property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setWidows(String widows) + throws DOMException; + + /** + * See the width property definition in CSS2. + */ + public String getWidth(); + /** + * See the width property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setWidth(String width) + throws DOMException; + + /** + * See the word-spacing property definition in CSS2. + */ + public String getWordSpacing(); + /** + * See the word-spacing property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setWordSpacing(String wordSpacing) + throws DOMException; + + /** + * See the z-index property definition in CSS2. + */ + public String getZIndex(); + /** + * See the z-index property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setZIndex(String zIndex) + throws DOMException; + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSSCharsetRule.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSSCharsetRule.java new file mode 100644 index 000000000..55dc6f8cc --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSSCharsetRule.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.css; + +import org.w3c.dom.DOMException; + +/** + * The <code>CSSCharsetRule</code> interface represents a @charset rule in a + * CSS style sheet. The value of the <code>encoding</code> attribute does + * not affect the encoding of text data in the DOM objects; this encoding is + * always UTF-16. After a stylesheet is loaded, the value of the + * <code>encoding</code> attribute is the value found in the + * <code>@charset</code> rule. If there was no <code>@charset</code> in the + * original document, then no <code>CSSCharsetRule</code> is created. The + * value of the <code>encoding</code> attribute may also be used as a hint + * for the encoding used on serialization of the style sheet. + * <p> The value of the @charset rule (and therefore of the + * <code>CSSCharsetRule</code>) may not correspond to the encoding the + * document actually came in; character encoding information e.g. in an HTTP + * header, has priority (see CSS document representation) but this is not + * reflected in the <code>CSSCharsetRule</code>. + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113'>Document Object Model (DOM) Level 2 Style Specification</a>. + * @since DOM Level 2 + */ +public interface CSSCharsetRule extends CSSRule { + /** + * The encoding information used in this <code>@charset</code> rule. + */ + public String getEncoding(); + /** + * The encoding information used in this <code>@charset</code> rule. + * @exception DOMException + * SYNTAX_ERR: Raised if the specified encoding value has a syntax error + * and is unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this encoding rule is + * readonly. + */ + public void setEncoding(String encoding) + throws DOMException; + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSSFontFaceRule.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSSFontFaceRule.java new file mode 100644 index 000000000..e446ea8c5 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSSFontFaceRule.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.css; + +/** + * The <code>CSSFontFaceRule</code> interface represents a @font-face rule in + * a CSS style sheet. The <code>@font-face</code> rule is used to hold a set + * of font descriptions. + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113'>Document Object Model (DOM) Level 2 Style Specification</a>. + * @since DOM Level 2 + */ +public interface CSSFontFaceRule extends CSSRule { + /** + * The declaration-block of this rule. + */ + public CSSStyleDeclaration getStyle(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSSImportRule.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSSImportRule.java new file mode 100644 index 000000000..3dee5d80b --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSSImportRule.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.css; + +import org.w3c.dom.stylesheets.MediaList; + +/** + * The <code>CSSImportRule</code> interface represents a @import rule within + * a CSS style sheet. The <code>@import</code> rule is used to import style + * rules from other style sheets. + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113'>Document Object Model (DOM) Level 2 Style Specification</a>. + * @since DOM Level 2 + */ +public interface CSSImportRule extends CSSRule { + /** + * The location of the style sheet to be imported. The attribute will not + * contain the <code>"url(...)"</code> specifier around the URI. + */ + public String getHref(); + + /** + * A list of media types for which this style sheet may be used. + */ + public MediaList getMedia(); + + /** + * The style sheet referred to by this rule, if it has been loaded. The + * value of this attribute is <code>null</code> if the style sheet has + * not yet been loaded or if it will not be loaded (e.g. if the style + * sheet is for a media type not supported by the user agent). + */ + public CSSStyleSheet getStyleSheet(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSSMediaRule.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSSMediaRule.java new file mode 100644 index 000000000..6e977923d --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSSMediaRule.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.css; + +import org.w3c.dom.DOMException; +import org.w3c.dom.stylesheets.MediaList; + +/** + * The <code>CSSMediaRule</code> interface represents a @media rule in a CSS + * style sheet. A <code>@media</code> rule can be used to delimit style + * rules for specific media types. + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113'>Document Object Model (DOM) Level 2 Style Specification</a>. + * @since DOM Level 2 + */ +public interface CSSMediaRule extends CSSRule { + /** + * A list of media types for this rule. + */ + public MediaList getMedia(); + + /** + * A list of all CSS rules contained within the media block. + */ + public CSSRuleList getCssRules(); + + /** + * Used to insert a new rule into the media block. + * @param rule The parsable text representing the rule. For rule sets + * this contains both the selector and the style declaration. For + * at-rules, this specifies both the at-identifier and the rule + * content. + * @param index The index within the media block's rule collection of + * the rule before which to insert the specified rule. If the + * specified index is equal to the length of the media blocks's rule + * collection, the rule will be added to the end of the media block. + * @return The index within the media block's rule collection of the + * newly inserted rule. + * @exception DOMException + * HIERARCHY_REQUEST_ERR: Raised if the rule cannot be inserted at the + * specified index, e.g., if an <code>@import</code> rule is inserted + * after a standard rule set or other at-rule. + * <br>INDEX_SIZE_ERR: Raised if the specified index is not a valid + * insertion point. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this media rule is + * readonly. + * <br>SYNTAX_ERR: Raised if the specified rule has a syntax error and + * is unparsable. + */ + public int insertRule(String rule, + int index) + throws DOMException; + + /** + * Used to delete a rule from the media block. + * @param index The index within the media block's rule collection of + * the rule to remove. + * @exception DOMException + * INDEX_SIZE_ERR: Raised if the specified index does not correspond to + * a rule in the media rule list. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this media rule is + * readonly. + */ + public void deleteRule(int index) + throws DOMException; + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSSPageRule.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSSPageRule.java new file mode 100644 index 000000000..eb8f783f5 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSSPageRule.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.css; + +import org.w3c.dom.DOMException; + +/** + * The <code>CSSPageRule</code> interface represents a @page rule within a + * CSS style sheet. The <code>@page</code> rule is used to specify the + * dimensions, orientation, margins, etc. of a page box for paged media. + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113'>Document Object Model (DOM) Level 2 Style Specification</a>. + * @since DOM Level 2 + */ +public interface CSSPageRule extends CSSRule { + /** + * The parsable textual representation of the page selector for the rule. + */ + public String getSelectorText(); + /** + * The parsable textual representation of the page selector for the rule. + * @exception DOMException + * SYNTAX_ERR: Raised if the specified CSS string value has a syntax + * error and is unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this rule is readonly. + */ + public void setSelectorText(String selectorText) + throws DOMException; + + /** + * The declaration-block of this rule. + */ + public CSSStyleDeclaration getStyle(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSSPrimitiveValue.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSSPrimitiveValue.java new file mode 100644 index 000000000..25f906a70 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSSPrimitiveValue.java @@ -0,0 +1,296 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.css; + +import org.w3c.dom.DOMException; + +/** + * The <code>CSSPrimitiveValue</code> interface represents a single CSS value + * . This interface may be used to determine the value of a specific style + * property currently set in a block or to set a specific style property + * explicitly within the block. An instance of this interface might be + * obtained from the <code>getPropertyCSSValue</code> method of the + * <code>CSSStyleDeclaration</code> interface. A + * <code>CSSPrimitiveValue</code> object only occurs in a context of a CSS + * property. + * <p> Conversions are allowed between absolute values (from millimeters to + * centimeters, from degrees to radians, and so on) but not between relative + * values. (For example, a pixel value cannot be converted to a centimeter + * value.) Percentage values can't be converted since they are relative to + * the parent value (or another property value). There is one exception for + * color percentage values: since a color percentage value is relative to + * the range 0-255, a color percentage value can be converted to a number; + * (see also the <code>RGBColor</code> interface). + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113'>Document Object Model (DOM) Level 2 Style Specification</a>. + * @since DOM Level 2 + */ +public interface CSSPrimitiveValue extends CSSValue { + // UnitTypes + /** + * The value is not a recognized CSS2 value. The value can only be + * obtained by using the <code>cssText</code> attribute. + */ + public static final short CSS_UNKNOWN = 0; + /** + * The value is a simple number. The value can be obtained by using the + * <code>getFloatValue</code> method. + */ + public static final short CSS_NUMBER = 1; + /** + * The value is a percentage. The value can be obtained by using the + * <code>getFloatValue</code> method. + */ + public static final short CSS_PERCENTAGE = 2; + /** + * The value is a length (ems). The value can be obtained by using the + * <code>getFloatValue</code> method. + */ + public static final short CSS_EMS = 3; + /** + * The value is a length (exs). The value can be obtained by using the + * <code>getFloatValue</code> method. + */ + public static final short CSS_EXS = 4; + /** + * The value is a length (px). The value can be obtained by using the + * <code>getFloatValue</code> method. + */ + public static final short CSS_PX = 5; + /** + * The value is a length (cm). The value can be obtained by using the + * <code>getFloatValue</code> method. + */ + public static final short CSS_CM = 6; + /** + * The value is a length (mm). The value can be obtained by using the + * <code>getFloatValue</code> method. + */ + public static final short CSS_MM = 7; + /** + * The value is a length (in). The value can be obtained by using the + * <code>getFloatValue</code> method. + */ + public static final short CSS_IN = 8; + /** + * The value is a length (pt). The value can be obtained by using the + * <code>getFloatValue</code> method. + */ + public static final short CSS_PT = 9; + /** + * The value is a length (pc). The value can be obtained by using the + * <code>getFloatValue</code> method. + */ + public static final short CSS_PC = 10; + /** + * The value is an angle (deg). The value can be obtained by using the + * <code>getFloatValue</code> method. + */ + public static final short CSS_DEG = 11; + /** + * The value is an angle (rad). The value can be obtained by using the + * <code>getFloatValue</code> method. + */ + public static final short CSS_RAD = 12; + /** + * The value is an angle (grad). The value can be obtained by using the + * <code>getFloatValue</code> method. + */ + public static final short CSS_GRAD = 13; + /** + * The value is a time (ms). The value can be obtained by using the + * <code>getFloatValue</code> method. + */ + public static final short CSS_MS = 14; + /** + * The value is a time (s). The value can be obtained by using the + * <code>getFloatValue</code> method. + */ + public static final short CSS_S = 15; + /** + * The value is a frequency (Hz). The value can be obtained by using the + * <code>getFloatValue</code> method. + */ + public static final short CSS_HZ = 16; + /** + * The value is a frequency (kHz). The value can be obtained by using the + * <code>getFloatValue</code> method. + */ + public static final short CSS_KHZ = 17; + /** + * The value is a number with an unknown dimension. The value can be + * obtained by using the <code>getFloatValue</code> method. + */ + public static final short CSS_DIMENSION = 18; + /** + * The value is a STRING. The value can be obtained by using the + * <code>getStringValue</code> method. + */ + public static final short CSS_STRING = 19; + /** + * The value is a URI. The value can be obtained by using the + * <code>getStringValue</code> method. + */ + public static final short CSS_URI = 20; + /** + * The value is an identifier. The value can be obtained by using the + * <code>getStringValue</code> method. + */ + public static final short CSS_IDENT = 21; + /** + * The value is a attribute function. The value can be obtained by using + * the <code>getStringValue</code> method. + */ + public static final short CSS_ATTR = 22; + /** + * The value is a counter or counters function. The value can be obtained + * by using the <code>getCounterValue</code> method. + */ + public static final short CSS_COUNTER = 23; + /** + * The value is a rect function. The value can be obtained by using the + * <code>getRectValue</code> method. + */ + public static final short CSS_RECT = 24; + /** + * The value is a RGB color. The value can be obtained by using the + * <code>getRGBColorValue</code> method. + */ + public static final short CSS_RGBCOLOR = 25; + + /** + * The type of the value as defined by the constants specified above. + */ + public short getPrimitiveType(); + + /** + * A method to set the float value with a specified unit. If the property + * attached with this value can not accept the specified unit or the + * float value, the value will be unchanged and a + * <code>DOMException</code> will be raised. + * @param unitType A unit code as defined above. The unit code can only + * be a float unit type (i.e. <code>CSS_NUMBER</code>, + * <code>CSS_PERCENTAGE</code>, <code>CSS_EMS</code>, + * <code>CSS_EXS</code>, <code>CSS_PX</code>, <code>CSS_CM</code>, + * <code>CSS_MM</code>, <code>CSS_IN</code>, <code>CSS_PT</code>, + * <code>CSS_PC</code>, <code>CSS_DEG</code>, <code>CSS_RAD</code>, + * <code>CSS_GRAD</code>, <code>CSS_MS</code>, <code>CSS_S</code>, + * <code>CSS_HZ</code>, <code>CSS_KHZ</code>, + * <code>CSS_DIMENSION</code>). + * @param floatValue The new float value. + * @exception DOMException + * INVALID_ACCESS_ERR: Raised if the attached property doesn't support + * the float value or the unit type. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setFloatValue(short unitType, + float floatValue) + throws DOMException; + + /** + * This method is used to get a float value in a specified unit. If this + * CSS value doesn't contain a float value or can't be converted into + * the specified unit, a <code>DOMException</code> is raised. + * @param unitType A unit code to get the float value. The unit code can + * only be a float unit type (i.e. <code>CSS_NUMBER</code>, + * <code>CSS_PERCENTAGE</code>, <code>CSS_EMS</code>, + * <code>CSS_EXS</code>, <code>CSS_PX</code>, <code>CSS_CM</code>, + * <code>CSS_MM</code>, <code>CSS_IN</code>, <code>CSS_PT</code>, + * <code>CSS_PC</code>, <code>CSS_DEG</code>, <code>CSS_RAD</code>, + * <code>CSS_GRAD</code>, <code>CSS_MS</code>, <code>CSS_S</code>, + * <code>CSS_HZ</code>, <code>CSS_KHZ</code>, + * <code>CSS_DIMENSION</code>). + * @return The float value in the specified unit. + * @exception DOMException + * INVALID_ACCESS_ERR: Raised if the CSS value doesn't contain a float + * value or if the float value can't be converted into the specified + * unit. + */ + public float getFloatValue(short unitType) + throws DOMException; + + /** + * A method to set the string value with the specified unit. If the + * property attached to this value can't accept the specified unit or + * the string value, the value will be unchanged and a + * <code>DOMException</code> will be raised. + * @param stringType A string code as defined above. The string code can + * only be a string unit type (i.e. <code>CSS_STRING</code>, + * <code>CSS_URI</code>, <code>CSS_IDENT</code>, and + * <code>CSS_ATTR</code>). + * @param stringValue The new string value. + * @exception DOMException + * INVALID_ACCESS_ERR: Raised if the CSS value doesn't contain a string + * value or if the string value can't be converted into the specified + * unit. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly. + */ + public void setStringValue(short stringType, + String stringValue) + throws DOMException; + + /** + * This method is used to get the string value. If the CSS value doesn't + * contain a string value, a <code>DOMException</code> is raised. Some + * properties (like 'font-family' or 'voice-family') convert a + * whitespace separated list of idents to a string. + * @return The string value in the current unit. The current + * <code>primitiveType</code> can only be a string unit type (i.e. + * <code>CSS_STRING</code>, <code>CSS_URI</code>, + * <code>CSS_IDENT</code> and <code>CSS_ATTR</code>). + * @exception DOMException + * INVALID_ACCESS_ERR: Raised if the CSS value doesn't contain a string + * value. + */ + public String getStringValue() + throws DOMException; + + /** + * This method is used to get the Counter value. If this CSS value + * doesn't contain a counter value, a <code>DOMException</code> is + * raised. Modification to the corresponding style property can be + * achieved using the <code>Counter</code> interface. + * @return The Counter value. + * @exception DOMException + * INVALID_ACCESS_ERR: Raised if the CSS value doesn't contain a + * Counter value (e.g. this is not <code>CSS_COUNTER</code>). + */ + public Counter getCounterValue() + throws DOMException; + + /** + * This method is used to get the Rect value. If this CSS value doesn't + * contain a rect value, a <code>DOMException</code> is raised. + * Modification to the corresponding style property can be achieved + * using the <code>Rect</code> interface. + * @return The Rect value. + * @exception DOMException + * INVALID_ACCESS_ERR: Raised if the CSS value doesn't contain a Rect + * value. (e.g. this is not <code>CSS_RECT</code>). + */ + public Rect getRectValue() + throws DOMException; + + /** + * This method is used to get the RGB color. If this CSS value doesn't + * contain a RGB color value, a <code>DOMException</code> is raised. + * Modification to the corresponding style property can be achieved + * using the <code>RGBColor</code> interface. + * @return the RGB color value. + * @exception DOMException + * INVALID_ACCESS_ERR: Raised if the attached property can't return a + * RGB color value (e.g. this is not <code>CSS_RGBCOLOR</code>). + */ + public RGBColor getRGBColorValue() + throws DOMException; + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSSRule.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSSRule.java new file mode 100644 index 000000000..dfd98aed9 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSSRule.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.css; + +import org.w3c.dom.DOMException; + +/** + * The <code>CSSRule</code> interface is the abstract base interface for any + * type of CSS statement. This includes both rule sets and at-rules. An + * implementation is expected to preserve all rules specified in a CSS style + * sheet, even if the rule is not recognized by the parser. Unrecognized + * rules are represented using the <code>CSSUnknownRule</code> interface. + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113'>Document Object Model (DOM) Level 2 Style Specification</a>. + * @since DOM Level 2 + */ +public interface CSSRule { + // RuleType + /** + * The rule is a <code>CSSUnknownRule</code>. + */ + public static final short UNKNOWN_RULE = 0; + /** + * The rule is a <code>CSSStyleRule</code>. + */ + public static final short STYLE_RULE = 1; + /** + * The rule is a <code>CSSCharsetRule</code>. + */ + public static final short CHARSET_RULE = 2; + /** + * The rule is a <code>CSSImportRule</code>. + */ + public static final short IMPORT_RULE = 3; + /** + * The rule is a <code>CSSMediaRule</code>. + */ + public static final short MEDIA_RULE = 4; + /** + * The rule is a <code>CSSFontFaceRule</code>. + */ + public static final short FONT_FACE_RULE = 5; + /** + * The rule is a <code>CSSPageRule</code>. + */ + public static final short PAGE_RULE = 6; + + /** + * The type of the rule, as defined above. The expectation is that + * binding-specific casting methods can be used to cast down from an + * instance of the <code>CSSRule</code> interface to the specific + * derived interface implied by the <code>type</code>. + */ + public short getType(); + + /** + * The parsable textual representation of the rule. This reflects the + * current state of the rule and not its initial value. + */ + public String getCssText(); + /** + * The parsable textual representation of the rule. This reflects the + * current state of the rule and not its initial value. + * @exception DOMException + * SYNTAX_ERR: Raised if the specified CSS string value has a syntax + * error and is unparsable. + * <br>INVALID_MODIFICATION_ERR: Raised if the specified CSS string + * value represents a different type of rule than the current one. + * <br>HIERARCHY_REQUEST_ERR: Raised if the rule cannot be inserted at + * this point in the style sheet. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if the rule is readonly. + */ + public void setCssText(String cssText) + throws DOMException; + + /** + * The style sheet that contains this rule. + */ + public CSSStyleSheet getParentStyleSheet(); + + /** + * If this rule is contained inside another rule (e.g. a style rule + * inside an @media block), this is the containing rule. If this rule is + * not nested inside any other rules, this returns <code>null</code>. + */ + public CSSRule getParentRule(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSSRuleList.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSSRuleList.java new file mode 100644 index 000000000..b875210cc --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSSRuleList.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.css; + +/** + * The <code>CSSRuleList</code> interface provides the abstraction of an + * ordered collection of CSS rules. + * <p> The items in the <code>CSSRuleList</code> are accessible via an + * integral index, starting from 0. + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113'>Document Object Model (DOM) Level 2 Style Specification</a>. + * @since DOM Level 2 + */ +public interface CSSRuleList { + /** + * The number of <code>CSSRules</code> in the list. The range of valid + * child rule indices is <code>0</code> to <code>length-1</code> + * inclusive. + */ + public int getLength(); + + /** + * Used to retrieve a CSS rule by ordinal index. The order in this + * collection represents the order of the rules in the CSS style sheet. + * If index is greater than or equal to the number of rules in the list, + * this returns <code>null</code>. + * @param index Index into the collection + * @return The style rule at the <code>index</code> position in the + * <code>CSSRuleList</code>, or <code>null</code> if that is not a + * valid index. + */ + public CSSRule item(int index); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSSStyleDeclaration.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSSStyleDeclaration.java new file mode 100644 index 000000000..91b9d9adf --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSSStyleDeclaration.java @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.css; + +import org.w3c.dom.DOMException; + +/** + * The <code>CSSStyleDeclaration</code> interface represents a single CSS + * declaration block. This interface may be used to determine the style + * properties currently set in a block or to set style properties explicitly + * within the block. + * <p> While an implementation may not recognize all CSS properties within a + * CSS declaration block, it is expected to provide access to all specified + * properties in the style sheet through the <code>CSSStyleDeclaration</code> + * interface. Furthermore, implementations that support a specific level of + * CSS should correctly handle CSS shorthand properties for that level. For + * a further discussion of shorthand properties, see the + * <code>CSS2Properties</code> interface. + * <p> This interface is also used to provide a read-only access to the + * computed values of an element. See also the <code>ViewCSS</code> + * interface. The CSS Object Model doesn't provide an access to the + * specified or actual values of the CSS cascade. + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113'>Document Object Model (DOM) Level 2 Style Specification</a>. + * @since DOM Level 2 + */ +public interface CSSStyleDeclaration { + /** + * The parsable textual representation of the declaration block + * (excluding the surrounding curly braces). Setting this attribute will + * result in the parsing of the new value and resetting of all the + * properties in the declaration block including the removal or addition + * of properties. + */ + public String getCssText(); + /** + * The parsable textual representation of the declaration block + * (excluding the surrounding curly braces). Setting this attribute will + * result in the parsing of the new value and resetting of all the + * properties in the declaration block including the removal or addition + * of properties. + * @exception DOMException + * SYNTAX_ERR: Raised if the specified CSS string value has a syntax + * error and is unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this declaration is + * readonly or a property is readonly. + */ + public void setCssText(String cssText) + throws DOMException; + + /** + * Used to retrieve the value of a CSS property if it has been explicitly + * set within this declaration block. + * @param propertyName The name of the CSS property. See the CSS + * property index. + * @return Returns the value of the property if it has been explicitly + * set for this declaration block. Returns the empty string if the + * property has not been set. + */ + public String getPropertyValue(String propertyName); + + /** + * Used to retrieve the object representation of the value of a CSS + * property if it has been explicitly set within this declaration block. + * This method returns <code>null</code> if the property is a shorthand + * property. Shorthand property values can only be accessed and modified + * as strings, using the <code>getPropertyValue</code> and + * <code>setProperty</code> methods. + * @param propertyName The name of the CSS property. See the CSS + * property index. + * @return Returns the value of the property if it has been explicitly + * set for this declaration block. Returns <code>null</code> if the + * property has not been set. + */ + public CSSValue getPropertyCSSValue(String propertyName); + + /** + * Used to remove a CSS property if it has been explicitly set within + * this declaration block. + * @param propertyName The name of the CSS property. See the CSS + * property index. + * @return Returns the value of the property if it has been explicitly + * set for this declaration block. Returns the empty string if the + * property has not been set or the property name does not correspond + * to a known CSS property. + * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised if this declaration is readonly + * or the property is readonly. + */ + public String removeProperty(String propertyName) + throws DOMException; + + /** + * Used to retrieve the priority of a CSS property (e.g. the + * <code>"important"</code> qualifier) if the priority has been + * explicitly set in this declaration block. + * @param propertyName The name of the CSS property. See the CSS + * property index. + * @return A string representing the priority (e.g. + * <code>"important"</code>) if the property has been explicitly set + * in this declaration block and has a priority specified. The empty + * string otherwise. + */ + public String getPropertyPriority(String propertyName); + + /** + * Used to set a property value and priority within this declaration + * block. <code>setProperty</code> permits to modify a property or add a + * new one in the declaration block. Any call to this method may modify + * the order of properties in the <code>item</code> method. + * @param propertyName The name of the CSS property. See the CSS + * property index. + * @param value The new value of the property. + * @param priority The new priority of the property (e.g. + * <code>"important"</code>) or the empty string if none. + * @exception DOMException + * SYNTAX_ERR: Raised if the specified value has a syntax error and is + * unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this declaration is + * readonly or the property is readonly. + */ + public void setProperty(String propertyName, + String value, + String priority) + throws DOMException; + + /** + * The number of properties that have been explicitly set in this + * declaration block. The range of valid indices is 0 to length-1 + * inclusive. + */ + public int getLength(); + + /** + * Used to retrieve the properties that have been explicitly set in this + * declaration block. The order of the properties retrieved using this + * method does not have to be the order in which they were set. This + * method can be used to iterate over all properties in this declaration + * block. + * @param index Index of the property name to retrieve. + * @return The name of the property at this ordinal position. The empty + * string if no property exists at this position. + */ + public String item(int index); + + /** + * The CSS rule that contains this declaration block or <code>null</code> + * if this <code>CSSStyleDeclaration</code> is not attached to a + * <code>CSSRule</code>. + */ + public CSSRule getParentRule(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSSStyleRule.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSSStyleRule.java new file mode 100644 index 000000000..e7377dcbe --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSSStyleRule.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.css; + +import org.w3c.dom.DOMException; + +/** + * The <code>CSSStyleRule</code> interface represents a single rule set in a + * CSS style sheet. + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113'>Document Object Model (DOM) Level 2 Style Specification</a>. + * @since DOM Level 2 + */ +public interface CSSStyleRule extends CSSRule { + /** + * The textual representation of the selector for the rule set. The + * implementation may have stripped out insignificant whitespace while + * parsing the selector. + */ + public String getSelectorText(); + /** + * The textual representation of the selector for the rule set. The + * implementation may have stripped out insignificant whitespace while + * parsing the selector. + * @exception DOMException + * SYNTAX_ERR: Raised if the specified CSS string value has a syntax + * error and is unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this rule is readonly. + */ + public void setSelectorText(String selectorText) + throws DOMException; + + /** + * The declaration-block of this rule set. + */ + public CSSStyleDeclaration getStyle(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSSStyleSheet.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSSStyleSheet.java new file mode 100644 index 000000000..c9538e436 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSSStyleSheet.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.css; + +import org.w3c.dom.DOMException; +import org.w3c.dom.stylesheets.StyleSheet; + +/** + * The <code>CSSStyleSheet</code> interface is a concrete interface used to + * represent a CSS style sheet i.e., a style sheet whose content type is + * "text/css". + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113'>Document Object Model (DOM) Level 2 Style Specification</a>. + * @since DOM Level 2 + */ +public interface CSSStyleSheet extends StyleSheet { + /** + * If this style sheet comes from an <code>@import</code> rule, the + * <code>ownerRule</code> attribute will contain the + * <code>CSSImportRule</code>. In that case, the <code>ownerNode</code> + * attribute in the <code>StyleSheet</code> interface will be + * <code>null</code>. If the style sheet comes from an element or a + * processing instruction, the <code>ownerRule</code> attribute will be + * <code>null</code> and the <code>ownerNode</code> attribute will + * contain the <code>Node</code>. + */ + public CSSRule getOwnerRule(); + + /** + * The list of all CSS rules contained within the style sheet. This + * includes both rule sets and at-rules. + */ + public CSSRuleList getCssRules(); + + /** + * Used to insert a new rule into the style sheet. The new rule now + * becomes part of the cascade. + * @param rule The parsable text representing the rule. For rule sets + * this contains both the selector and the style declaration. For + * at-rules, this specifies both the at-identifier and the rule + * content. + * @param index The index within the style sheet's rule list of the rule + * before which to insert the specified rule. If the specified index + * is equal to the length of the style sheet's rule collection, the + * rule will be added to the end of the style sheet. + * @return The index within the style sheet's rule collection of the + * newly inserted rule. + * @exception DOMException + * HIERARCHY_REQUEST_ERR: Raised if the rule cannot be inserted at the + * specified index e.g. if an <code>@import</code> rule is inserted + * after a standard rule set or other at-rule. + * <br>INDEX_SIZE_ERR: Raised if the specified index is not a valid + * insertion point. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this style sheet is + * readonly. + * <br>SYNTAX_ERR: Raised if the specified rule has a syntax error and + * is unparsable. + */ + public int insertRule(String rule, + int index) + throws DOMException; + + /** + * Used to delete a rule from the style sheet. + * @param index The index within the style sheet's rule list of the rule + * to remove. + * @exception DOMException + * INDEX_SIZE_ERR: Raised if the specified index does not correspond to + * a rule in the style sheet's rule list. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this style sheet is + * readonly. + */ + public void deleteRule(int index) + throws DOMException; + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSSUnknownRule.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSSUnknownRule.java new file mode 100644 index 000000000..d01c1ac27 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSSUnknownRule.java @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.css; + +/** + * The <code>CSSUnknownRule</code> interface represents an at-rule not + * supported by this user agent. + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113'>Document Object Model (DOM) Level 2 Style Specification</a>. + * @since DOM Level 2 + */ +public interface CSSUnknownRule extends CSSRule { +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSSValue.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSSValue.java new file mode 100644 index 000000000..3a43a17f1 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSSValue.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.css; + +import org.w3c.dom.DOMException; + +/** + * The <code>CSSValue</code> interface represents a simple or a complex + * value. A <code>CSSValue</code> object only occurs in a context of a CSS + * property. + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113'>Document Object Model (DOM) Level 2 Style Specification</a>. + * @since DOM Level 2 + */ +public interface CSSValue { + // UnitTypes + /** + * The value is inherited and the <code>cssText</code> contains "inherit". + */ + public static final short CSS_INHERIT = 0; + /** + * The value is a primitive value and an instance of the + * <code>CSSPrimitiveValue</code> interface can be obtained by using + * binding-specific casting methods on this instance of the + * <code>CSSValue</code> interface. + */ + public static final short CSS_PRIMITIVE_VALUE = 1; + /** + * The value is a <code>CSSValue</code> list and an instance of the + * <code>CSSValueList</code> interface can be obtained by using + * binding-specific casting methods on this instance of the + * <code>CSSValue</code> interface. + */ + public static final short CSS_VALUE_LIST = 2; + /** + * The value is a custom value. + */ + public static final short CSS_CUSTOM = 3; + + /** + * A string representation of the current value. + */ + public String getCssText(); + /** + * A string representation of the current value. + * @exception DOMException + * SYNTAX_ERR: Raised if the specified CSS string value has a syntax + * error (according to the attached property) or is unparsable. + * <br>INVALID_MODIFICATION_ERR: Raised if the specified CSS string + * value represents a different type of values than the values allowed + * by the CSS property. + * <br> NO_MODIFICATION_ALLOWED_ERR: Raised if this value is readonly. + */ + public void setCssText(String cssText) + throws DOMException; + + /** + * A code defining the type of the value as defined above. + */ + public short getCssValueType(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSSValueList.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSSValueList.java new file mode 100644 index 000000000..4e29bfa3f --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/CSSValueList.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.css; + +/** + * The <code>CSSValueList</code> interface provides the abstraction of an + * ordered collection of CSS values. + * <p> Some properties allow an empty list into their syntax. In that case, + * these properties take the <code>none</code> identifier. So, an empty list + * means that the property has the value <code>none</code>. + * <p> The items in the <code>CSSValueList</code> are accessible via an + * integral index, starting from 0. + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113'>Document Object Model (DOM) Level 2 Style Specification</a>. + * @since DOM Level 2 + */ +public interface CSSValueList extends CSSValue { + /** + * The number of <code>CSSValues</code> in the list. The range of valid + * values of the indices is <code>0</code> to <code>length-1</code> + * inclusive. + */ + public int getLength(); + + /** + * Used to retrieve a <code>CSSValue</code> by ordinal index. The order in + * this collection represents the order of the values in the CSS style + * property. If index is greater than or equal to the number of values + * in the list, this returns <code>null</code>. + * @param index Index into the collection. + * @return The <code>CSSValue</code> at the <code>index</code> position + * in the <code>CSSValueList</code>, or <code>null</code> if that is + * not a valid index. + */ + public CSSValue item(int index); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/css/Counter.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/Counter.java new file mode 100644 index 000000000..7bfcc79f8 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/Counter.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.css; + +/** + * The <code>Counter</code> interface is used to represent any counter or + * counters function value. This interface reflects the values in the + * underlying style property. + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113'>Document Object Model (DOM) Level 2 Style Specification</a>. + * @since DOM Level 2 + */ +public interface Counter { + /** + * This attribute is used for the identifier of the counter. + */ + public String getIdentifier(); + + /** + * This attribute is used for the style of the list. + */ + public String getListStyle(); + + /** + * This attribute is used for the separator of the nested counters. + */ + public String getSeparator(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/css/DOMImplementationCSS.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/DOMImplementationCSS.java new file mode 100644 index 000000000..90c6c135d --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/DOMImplementationCSS.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.css; + +import org.w3c.dom.DOMImplementation; +import org.w3c.dom.DOMException; + +/** + * This interface allows the DOM user to create a <code>CSSStyleSheet</code> + * outside the context of a document. There is no way to associate the new + * <code>CSSStyleSheet</code> with a document in DOM Level 2. + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113'>Document Object Model (DOM) Level 2 Style Specification</a>. + * @since DOM Level 2 + */ +public interface DOMImplementationCSS extends DOMImplementation { + /** + * Creates a new <code>CSSStyleSheet</code>. + * @param title The advisory title. See also the section. + * @param media The comma-separated list of media associated with the + * new style sheet. See also the section. + * @return A new CSS style sheet. + * @exception DOMException + * SYNTAX_ERR: Raised if the specified media string value has a syntax + * error and is unparsable. + */ + public CSSStyleSheet createCSSStyleSheet(String title, + String media) + throws DOMException; + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/css/DocumentCSS.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/DocumentCSS.java new file mode 100644 index 000000000..68a910754 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/DocumentCSS.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.css; + +import org.w3c.dom.Element; +import org.w3c.dom.stylesheets.DocumentStyle; + +/** + * This interface represents a document with a CSS view. + * <p> The <code>getOverrideStyle</code> method provides a mechanism through + * which a DOM author could effect immediate change to the style of an + * element without modifying the explicitly linked style sheets of a + * document or the inline style of elements in the style sheets. This style + * sheet comes after the author style sheet in the cascade algorithm and is + * called override style sheet. The override style sheet takes precedence + * over author style sheets. An "!important" declaration still takes + * precedence over a normal declaration. Override, author, and user style + * sheets all may contain "!important" declarations. User "!important" rules + * take precedence over both override and author "!important" rules, and + * override "!important" rules take precedence over author "!important" + * rules. + * <p> The expectation is that an instance of the <code>DocumentCSS</code> + * interface can be obtained by using binding-specific casting methods on an + * instance of the <code>Document</code> interface. + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113'>Document Object Model (DOM) Level 2 Style Specification</a>. + * @since DOM Level 2 + */ +public interface DocumentCSS extends DocumentStyle { + /** + * This method is used to retrieve the override style declaration for a + * specified element and a specified pseudo-element. + * @param elt The element whose style is to be modified. This parameter + * cannot be null. + * @param pseudoElt The pseudo-element or <code>null</code> if none. + * @return The override style declaration. + */ + public CSSStyleDeclaration getOverrideStyle(Element elt, + String pseudoElt); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/css/ElementCSSInlineStyle.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/ElementCSSInlineStyle.java new file mode 100644 index 000000000..e1f25060c --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/ElementCSSInlineStyle.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.css; + +/** + * Inline style information attached to elements is exposed through the + * <code>style</code> attribute. This represents the contents of the STYLE + * attribute for HTML elements (or elements in other schemas or DTDs which + * use the STYLE attribute in the same way). The expectation is that an + * instance of the ElementCSSInlineStyle interface can be obtained by using + * binding-specific casting methods on an instance of the Element interface + * when the element supports inline CSS style informations. + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113'>Document Object Model (DOM) Level 2 Style Specification</a>. + * @since DOM Level 2 + */ +public interface ElementCSSInlineStyle { + /** + * The style attribute. + */ + public CSSStyleDeclaration getStyle(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/css/RGBColor.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/RGBColor.java new file mode 100644 index 000000000..215e291da --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/RGBColor.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.css; + +/** + * The <code>RGBColor</code> interface is used to represent any RGB color + * value. This interface reflects the values in the underlying style + * property. Hence, modifications made to the <code>CSSPrimitiveValue</code> + * objects modify the style property. + * <p> A specified RGB color is not clipped (even if the number is outside the + * range 0-255 or 0%-100%). A computed RGB color is clipped depending on the + * device. + * <p> Even if a style sheet can only contain an integer for a color value, + * the internal storage of this integer is a float, and this can be used as + * a float in the specified or the computed style. + * <p> A color percentage value can always be converted to a number and vice + * versa. + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113'>Document Object Model (DOM) Level 2 Style Specification</a>. + * @since DOM Level 2 + */ +public interface RGBColor { + /** + * This attribute is used for the red value of the RGB color. + */ + public CSSPrimitiveValue getRed(); + + /** + * This attribute is used for the green value of the RGB color. + */ + public CSSPrimitiveValue getGreen(); + + /** + * This attribute is used for the blue value of the RGB color. + */ + public CSSPrimitiveValue getBlue(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/css/Rect.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/Rect.java new file mode 100644 index 000000000..ffbf96547 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/Rect.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.css; + +/** + * The <code>Rect</code> interface is used to represent any rect value. This + * interface reflects the values in the underlying style property. Hence, + * modifications made to the <code>CSSPrimitiveValue</code> objects modify + * the style property. + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113'>Document Object Model (DOM) Level 2 Style Specification</a>. + * @since DOM Level 2 + */ +public interface Rect { + /** + * This attribute is used for the top of the rect. + */ + public CSSPrimitiveValue getTop(); + + /** + * This attribute is used for the right of the rect. + */ + public CSSPrimitiveValue getRight(); + + /** + * This attribute is used for the bottom of the rect. + */ + public CSSPrimitiveValue getBottom(); + + /** + * This attribute is used for the left of the rect. + */ + public CSSPrimitiveValue getLeft(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/css/ViewCSS.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/ViewCSS.java new file mode 100644 index 000000000..1db9ac44c --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/css/ViewCSS.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.css; + +import org.w3c.dom.Element; +import org.w3c.dom.views.AbstractView; + +/** + * This interface represents a CSS view. The <code>getComputedStyle</code> + * method provides a read only access to the computed values of an element. + * <p> The expectation is that an instance of the <code>ViewCSS</code> + * interface can be obtained by using binding-specific casting methods on an + * instance of the <code>AbstractView</code> interface. + * <p> Since a computed style is related to an <code>Element</code> node, if + * this element is removed from the document, the associated + * <code>CSSStyleDeclaration</code> and <code>CSSValue</code> related to + * this declaration are no longer valid. + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113'>Document Object Model (DOM) Level 2 Style Specification</a>. + * @since DOM Level 2 + */ +public interface ViewCSS extends AbstractView { + /** + * This method is used to get the computed style as it is defined in [<a href='http://www.w3.org/TR/1998/REC-CSS2-19980512'>CSS2</a>]. + * @param elt The element whose style is to be computed. This parameter + * cannot be null. + * @param pseudoElt The pseudo-element or <code>null</code> if none. + * @return The computed style. The <code>CSSStyleDeclaration</code> is + * read-only and contains only absolute values. + */ + public CSSStyleDeclaration getComputedStyle(Element elt, + String pseudoElt); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/events/DocumentEvent.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/events/DocumentEvent.java new file mode 100644 index 000000000..55c838603 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/events/DocumentEvent.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.events; + +import org.w3c.dom.DOMException; + +/** + * The <code>DocumentEvent</code> interface provides a mechanism by which the + * user can create an Event of a type supported by the implementation. It is + * expected that the <code>DocumentEvent</code> interface will be + * implemented on the same object which implements the <code>Document</code> + * interface in an implementation which supports the Event model. + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113'>Document Object Model (DOM) Level 2 Events Specification</a>. + * @since DOM Level 2 + */ +public interface DocumentEvent { + /** + * + * @param eventType The <code>eventType</code> parameter specifies the + * type of <code>Event</code> interface to be created. If the + * <code>Event</code> interface specified is supported by the + * implementation this method will return a new <code>Event</code> of + * the interface type requested. If the <code>Event</code> is to be + * dispatched via the <code>dispatchEvent</code> method the + * appropriate event init method must be called after creation in + * order to initialize the <code>Event</code>'s values. As an example, + * a user wishing to synthesize some kind of <code>UIEvent</code> + * would call <code>createEvent</code> with the parameter "UIEvents". + * The <code>initUIEvent</code> method could then be called on the + * newly created <code>UIEvent</code> to set the specific type of + * UIEvent to be dispatched and set its context information.The + * <code>createEvent</code> method is used in creating + * <code>Event</code>s when it is either inconvenient or unnecessary + * for the user to create an <code>Event</code> themselves. In cases + * where the implementation provided <code>Event</code> is + * insufficient, users may supply their own <code>Event</code> + * implementations for use with the <code>dispatchEvent</code> method. + * @return The newly created <code>Event</code> + * @exception DOMException + * NOT_SUPPORTED_ERR: Raised if the implementation does not support the + * type of <code>Event</code> interface requested + */ + public Event createEvent(String eventType) + throws DOMException; + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/events/Event.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/events/Event.java new file mode 100644 index 000000000..29a96c50a --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/events/Event.java @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.events; + +/** + * The <code>Event</code> interface is used to provide contextual information + * about an event to the handler processing the event. An object which + * implements the <code>Event</code> interface is generally passed as the + * first parameter to an event handler. More specific context information is + * passed to event handlers by deriving additional interfaces from + * <code>Event</code> which contain information directly relating to the + * type of event they accompany. These derived interfaces are also + * implemented by the object passed to the event listener. + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113'>Document Object Model (DOM) Level 2 Events Specification</a>. + * @since DOM Level 2 + */ +public interface Event { + // PhaseType + /** + * The current event phase is the capturing phase. + */ + public static final short CAPTURING_PHASE = 1; + /** + * The event is currently being evaluated at the target + * <code>EventTarget</code>. + */ + public static final short AT_TARGET = 2; + /** + * The current event phase is the bubbling phase. + */ + public static final short BUBBLING_PHASE = 3; + + /** + * The name of the event (case-insensitive). The name must be an XML name. + */ + public String getType(); + + /** + * Used to indicate the <code>EventTarget</code> to which the event was + * originally dispatched. + */ + public EventTarget getTarget(); + + /** + * Used to indicate the <code>EventTarget</code> whose + * <code>EventListeners</code> are currently being processed. This is + * particularly useful during capturing and bubbling. + */ + public EventTarget getCurrentTarget(); + + /** + * Used to indicate which phase of event flow is currently being + * evaluated. + */ + public short getEventPhase(); + + /** + * Used to indicate whether or not an event is a bubbling event. If the + * event can bubble the value is true, else the value is false. + */ + public boolean getBubbles(); + + /** + * Used to indicate whether or not an event can have its default action + * prevented. If the default action can be prevented the value is true, + * else the value is false. + */ + public boolean getCancelable(); + + /** + * Used to specify the time (in milliseconds relative to the epoch) at + * which the event was created. Due to the fact that some systems may + * not provide this information the value of <code>timeStamp</code> may + * be not available for all events. When not available, a value of 0 + * will be returned. Examples of epoch time are the time of the system + * start or 0:0:0 UTC 1st January 1970. + */ + public long getTimeStamp(); + + /** + * The <code>stopPropagation</code> method is used prevent further + * propagation of an event during event flow. If this method is called + * by any <code>EventListener</code> the event will cease propagating + * through the tree. The event will complete dispatch to all listeners + * on the current <code>EventTarget</code> before event flow stops. This + * method may be used during any stage of event flow. + */ + public void stopPropagation(); + + /** + * If an event is cancelable, the <code>preventDefault</code> method is + * used to signify that the event is to be canceled, meaning any default + * action normally taken by the implementation as a result of the event + * will not occur. If, during any stage of event flow, the + * <code>preventDefault</code> method is called the event is canceled. + * Any default action associated with the event will not occur. Calling + * this method for a non-cancelable event has no effect. Once + * <code>preventDefault</code> has been called it will remain in effect + * throughout the remainder of the event's propagation. This method may + * be used during any stage of event flow. + */ + public void preventDefault(); + + /** + * The <code>initEvent</code> method is used to initialize the value of an + * <code>Event</code> created through the <code>DocumentEvent</code> + * interface. This method may only be called before the + * <code>Event</code> has been dispatched via the + * <code>dispatchEvent</code> method, though it may be called multiple + * times during that phase if necessary. If called multiple times the + * final invocation takes precedence. If called from a subclass of + * <code>Event</code> interface only the values specified in the + * <code>initEvent</code> method are modified, all other attributes are + * left unchanged. + * @param eventTypeArg Specifies the event type. This type may be any + * event type currently defined in this specification or a new event + * type.. The string must be an XML name. Any new event type must not + * begin with any upper, lower, or mixed case version of the string + * "DOM". This prefix is reserved for future DOM event sets. It is + * also strongly recommended that third parties adding their own + * events use their own prefix to avoid confusion and lessen the + * probability of conflicts with other new events. + * @param canBubbleArg Specifies whether or not the event can bubble. + * @param cancelableArg Specifies whether or not the event's default + * action can be prevented. + */ + public void initEvent(String eventTypeArg, + boolean canBubbleArg, + boolean cancelableArg); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/events/EventException.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/events/EventException.java new file mode 100644 index 000000000..9a62f1fc5 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/events/EventException.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.events; + +/** + * Event operations may throw an <code>EventException</code> as specified in + * their method descriptions. + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113'>Document Object Model (DOM) Level 2 Events Specification</a>. + * @since DOM Level 2 + */ +public class EventException extends RuntimeException { + public EventException(short code, String message) { + super(message); + this.code = code; + } + public short code; + // EventExceptionCode + /** + * If the <code>Event</code>'s type was not specified by initializing the + * event before the method was called. Specification of the Event's type + * as <code>null</code> or an empty string will also trigger this + * exception. + */ + public static final short UNSPECIFIED_EVENT_TYPE_ERR = 0; + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/events/EventListener.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/events/EventListener.java new file mode 100644 index 000000000..1be3523fb --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/events/EventListener.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.events; + +/** + * The <code>EventListener</code> interface is the primary method for + * handling events. Users implement the <code>EventListener</code> interface + * and register their listener on an <code>EventTarget</code> using the + * <code>AddEventListener</code> method. The users should also remove their + * <code>EventListener</code> from its <code>EventTarget</code> after they + * have completed using the listener. + * <p> When a <code>Node</code> is copied using the <code>cloneNode</code> + * method the <code>EventListener</code>s attached to the source + * <code>Node</code> are not attached to the copied <code>Node</code>. If + * the user wishes the same <code>EventListener</code>s to be added to the + * newly created copy the user must add them manually. + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113'>Document Object Model (DOM) Level 2 Events Specification</a>. + * @since DOM Level 2 + */ +public interface EventListener { + /** + * This method is called whenever an event occurs of the type for which + * the <code> EventListener</code> interface was registered. + * @param evt The <code>Event</code> contains contextual information + * about the event. It also contains the <code>stopPropagation</code> + * and <code>preventDefault</code> methods which are used in + * determining the event's flow and default action. + */ + public void handleEvent(Event evt); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/events/EventTarget.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/events/EventTarget.java new file mode 100644 index 000000000..3b66a8deb --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/events/EventTarget.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.events; + +/** + * The <code>EventTarget</code> interface is implemented by all + * <code>Nodes</code> in an implementation which supports the DOM Event + * Model. Therefore, this interface can be obtained by using + * binding-specific casting methods on an instance of the <code>Node</code> + * interface. The interface allows registration and removal of + * <code>EventListeners</code> on an <code>EventTarget</code> and dispatch + * of events to that <code>EventTarget</code>. + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113'>Document Object Model (DOM) Level 2 Events Specification</a>. + * @since DOM Level 2 + */ +public interface EventTarget { + /** + * This method allows the registration of event listeners on the event + * target. If an <code>EventListener</code> is added to an + * <code>EventTarget</code> while it is processing an event, it will not + * be triggered by the current actions but may be triggered during a + * later stage of event flow, such as the bubbling phase. + * <br> If multiple identical <code>EventListener</code>s are registered + * on the same <code>EventTarget</code> with the same parameters the + * duplicate instances are discarded. They do not cause the + * <code>EventListener</code> to be called twice and since they are + * discarded they do not need to be removed with the + * <code>removeEventListener</code> method. + * @param type The event type for which the user is registering + * @param listener The <code>listener</code> parameter takes an interface + * implemented by the user which contains the methods to be called + * when the event occurs. + * @param useCapture If true, <code>useCapture</code> indicates that the + * user wishes to initiate capture. After initiating capture, all + * events of the specified type will be dispatched to the registered + * <code>EventListener</code> before being dispatched to any + * <code>EventTargets</code> beneath them in the tree. Events which + * are bubbling upward through the tree will not trigger an + * <code>EventListener</code> designated to use capture. + */ + public void addEventListener(String type, + EventListener listener, + boolean useCapture); + + /** + * This method allows the removal of event listeners from the event + * target. If an <code>EventListener</code> is removed from an + * <code>EventTarget</code> while it is processing an event, it will not + * be triggered by the current actions. <code>EventListener</code>s can + * never be invoked after being removed. + * <br>Calling <code>removeEventListener</code> with arguments which do + * not identify any currently registered <code>EventListener</code> on + * the <code>EventTarget</code> has no effect. + * @param type Specifies the event type of the <code>EventListener</code> + * being removed. + * @param listener The <code>EventListener</code> parameter indicates the + * <code>EventListener </code> to be removed. + * @param useCapture Specifies whether the <code>EventListener</code> + * being removed was registered as a capturing listener or not. If a + * listener was registered twice, one with capture and one without, + * each must be removed separately. Removal of a capturing listener + * does not affect a non-capturing version of the same listener, and + * vice versa. + */ + public void removeEventListener(String type, + EventListener listener, + boolean useCapture); + + /** + * This method allows the dispatch of events into the implementations + * event model. Events dispatched in this manner will have the same + * capturing and bubbling behavior as events dispatched directly by the + * implementation. The target of the event is the + * <code> EventTarget</code> on which <code>dispatchEvent</code> is + * called. + * @param evt Specifies the event type, behavior, and contextual + * information to be used in processing the event. + * @return The return value of <code>dispatchEvent</code> indicates + * whether any of the listeners which handled the event called + * <code>preventDefault</code>. If <code>preventDefault</code> was + * called the value is false, else the value is true. + * @exception EventException + * UNSPECIFIED_EVENT_TYPE_ERR: Raised if the <code>Event</code>'s type + * was not specified by initializing the event before + * <code>dispatchEvent</code> was called. Specification of the + * <code>Event</code>'s type as <code>null</code> or an empty string + * will also trigger this exception. + */ + public boolean dispatchEvent(Event evt) + throws EventException; + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/events/MouseEvent.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/events/MouseEvent.java new file mode 100644 index 000000000..67e20572f --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/events/MouseEvent.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.events; + +import org.w3c.dom.views.AbstractView; + +/** + * The <code>MouseEvent</code> interface provides specific contextual + * information associated with Mouse events. + * <p>The <code>detail</code> attribute inherited from <code>UIEvent</code> + * indicates the number of times a mouse button has been pressed and + * released over the same screen location during a user action. The + * attribute value is 1 when the user begins this action and increments by 1 + * for each full sequence of pressing and releasing. If the user moves the + * mouse between the mousedown and mouseup the value will be set to 0, + * indicating that no click is occurring. + * <p>In the case of nested elements mouse events are always targeted at the + * most deeply nested element. Ancestors of the targeted element may use + * bubbling to obtain notification of mouse events which occur within its + * descendent elements. + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113'>Document Object Model (DOM) Level 2 Events Specification</a>. + * @since DOM Level 2 + */ +public interface MouseEvent extends UIEvent { + /** + * The horizontal coordinate at which the event occurred relative to the + * origin of the screen coordinate system. + */ + public int getScreenX(); + + /** + * The vertical coordinate at which the event occurred relative to the + * origin of the screen coordinate system. + */ + public int getScreenY(); + + /** + * The horizontal coordinate at which the event occurred relative to the + * DOM implementation's client area. + */ + public int getClientX(); + + /** + * The vertical coordinate at which the event occurred relative to the DOM + * implementation's client area. + */ + public int getClientY(); + + /** + * Used to indicate whether the 'ctrl' key was depressed during the firing + * of the event. + */ + public boolean getCtrlKey(); + + /** + * Used to indicate whether the 'shift' key was depressed during the + * firing of the event. + */ + public boolean getShiftKey(); + + /** + * Used to indicate whether the 'alt' key was depressed during the firing + * of the event. On some platforms this key may map to an alternative + * key name. + */ + public boolean getAltKey(); + + /** + * Used to indicate whether the 'meta' key was depressed during the firing + * of the event. On some platforms this key may map to an alternative + * key name. + */ + public boolean getMetaKey(); + + /** + * During mouse events caused by the depression or release of a mouse + * button, <code>button</code> is used to indicate which mouse button + * changed state. The values for <code>button</code> range from zero to + * indicate the left button of the mouse, one to indicate the middle + * button if present, and two to indicate the right button. For mice + * configured for left handed use in which the button actions are + * reversed the values are instead read from right to left. + */ + public short getButton(); + + /** + * Used to identify a secondary <code>EventTarget</code> related to a UI + * event. Currently this attribute is used with the mouseover event to + * indicate the <code>EventTarget</code> which the pointing device + * exited and with the mouseout event to indicate the + * <code>EventTarget</code> which the pointing device entered. + */ + public EventTarget getRelatedTarget(); + + /** + * The <code>initMouseEvent</code> method is used to initialize the value + * of a <code>MouseEvent</code> created through the + * <code>DocumentEvent</code> interface. This method may only be called + * before the <code>MouseEvent</code> has been dispatched via the + * <code>dispatchEvent</code> method, though it may be called multiple + * times during that phase if necessary. If called multiple times, the + * final invocation takes precedence. + * @param typeArg Specifies the event type. + * @param canBubbleArg Specifies whether or not the event can bubble. + * @param cancelableArg Specifies whether or not the event's default + * action can be prevented. + * @param viewArg Specifies the <code>Event</code>'s + * <code>AbstractView</code>. + * @param detailArg Specifies the <code>Event</code>'s mouse click count. + * @param screenXArg Specifies the <code>Event</code>'s screen x + * coordinate + * @param screenYArg Specifies the <code>Event</code>'s screen y + * coordinate + * @param clientXArg Specifies the <code>Event</code>'s client x + * coordinate + * @param clientYArg Specifies the <code>Event</code>'s client y + * coordinate + * @param ctrlKeyArg Specifies whether or not control key was depressed + * during the <code>Event</code>. + * @param altKeyArg Specifies whether or not alt key was depressed during + * the <code>Event</code>. + * @param shiftKeyArg Specifies whether or not shift key was depressed + * during the <code>Event</code>. + * @param metaKeyArg Specifies whether or not meta key was depressed + * during the <code>Event</code>. + * @param buttonArg Specifies the <code>Event</code>'s mouse button. + * @param relatedTargetArg Specifies the <code>Event</code>'s related + * <code>EventTarget</code>. + */ + public void initMouseEvent(String typeArg, + boolean canBubbleArg, + boolean cancelableArg, + AbstractView viewArg, + int detailArg, + int screenXArg, + int screenYArg, + int clientXArg, + int clientYArg, + boolean ctrlKeyArg, + boolean altKeyArg, + boolean shiftKeyArg, + boolean metaKeyArg, + short buttonArg, + EventTarget relatedTargetArg); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/events/MutationEvent.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/events/MutationEvent.java new file mode 100644 index 000000000..2cbedb768 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/events/MutationEvent.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.events; + +import org.w3c.dom.Node; + +/** + * The <code>MutationEvent</code> interface provides specific contextual + * information associated with Mutation events. + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113'>Document Object Model (DOM) Level 2 Events Specification</a>. + * @since DOM Level 2 + */ +public interface MutationEvent extends Event { + // attrChangeType + /** + * The <code>Attr</code> was modified in place. + */ + public static final short MODIFICATION = 1; + /** + * The <code>Attr</code> was just added. + */ + public static final short ADDITION = 2; + /** + * The <code>Attr</code> was just removed. + */ + public static final short REMOVAL = 3; + + /** + * <code>relatedNode</code> is used to identify a secondary node related + * to a mutation event. For example, if a mutation event is dispatched + * to a node indicating that its parent has changed, the + * <code>relatedNode</code> is the changed parent. If an event is + * instead dispatched to a subtree indicating a node was changed within + * it, the <code>relatedNode</code> is the changed node. In the case of + * the DOMAttrModified event it indicates the <code>Attr</code> node + * which was modified, added, or removed. + */ + public Node getRelatedNode(); + + /** + * <code>prevValue</code> indicates the previous value of the + * <code>Attr</code> node in DOMAttrModified events, and of the + * <code>CharacterData</code> node in DOMCharacterDataModified events. + */ + public String getPrevValue(); + + /** + * <code>newValue</code> indicates the new value of the <code>Attr</code> + * node in DOMAttrModified events, and of the <code>CharacterData</code> + * node in DOMCharacterDataModified events. + */ + public String getNewValue(); + + /** + * <code>attrName</code> indicates the name of the changed + * <code>Attr</code> node in a DOMAttrModified event. + */ + public String getAttrName(); + + /** + * <code>attrChange</code> indicates the type of change which triggered + * the DOMAttrModified event. The values can be <code>MODIFICATION</code> + * , <code>ADDITION</code>, or <code>REMOVAL</code>. + */ + public short getAttrChange(); + + /** + * The <code>initMutationEvent</code> method is used to initialize the + * value of a <code>MutationEvent</code> created through the + * <code>DocumentEvent</code> interface. This method may only be called + * before the <code>MutationEvent</code> has been dispatched via the + * <code>dispatchEvent</code> method, though it may be called multiple + * times during that phase if necessary. If called multiple times, the + * final invocation takes precedence. + * @param typeArg Specifies the event type. + * @param canBubbleArg Specifies whether or not the event can bubble. + * @param cancelableArg Specifies whether or not the event's default + * action can be prevented. + * @param relatedNodeArg Specifies the <code>Event</code>'s related Node. + * @param prevValueArg Specifies the <code>Event</code>'s + * <code>prevValue</code> attribute. This value may be null. + * @param newValueArg Specifies the <code>Event</code>'s + * <code>newValue</code> attribute. This value may be null. + * @param attrNameArg Specifies the <code>Event</code>'s + * <code>attrName</code> attribute. This value may be null. + * @param attrChangeArg Specifies the <code>Event</code>'s + * <code>attrChange</code> attribute + */ + public void initMutationEvent(String typeArg, + boolean canBubbleArg, + boolean cancelableArg, + Node relatedNodeArg, + String prevValueArg, + String newValueArg, + String attrNameArg, + short attrChangeArg); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/events/UIEvent.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/events/UIEvent.java new file mode 100644 index 000000000..e3617c026 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/events/UIEvent.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.events; + +import org.w3c.dom.views.AbstractView; + +/** + * The <code>UIEvent</code> interface provides specific contextual information + * associated with User Interface events. + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113'>Document Object Model (DOM) Level 2 Events Specification</a>. + * @since DOM Level 2 + */ +public interface UIEvent extends Event { + /** + * The <code>view</code> attribute identifies the <code>AbstractView</code> + * from which the event was generated. + */ + public AbstractView getView(); + + /** + * Specifies some detail information about the <code>Event</code>, + * depending on the type of event. + */ + public int getDetail(); + + /** + * The <code>initUIEvent</code> method is used to initialize the value of + * a <code>UIEvent</code> created through the <code>DocumentEvent</code> + * interface. This method may only be called before the + * <code>UIEvent</code> has been dispatched via the + * <code>dispatchEvent</code> method, though it may be called multiple + * times during that phase if necessary. If called multiple times, the + * final invocation takes precedence. + * @param typeArg Specifies the event type. + * @param canBubbleArg Specifies whether or not the event can bubble. + * @param cancelableArg Specifies whether or not the event's default + * action can be prevented. + * @param viewArg Specifies the <code>Event</code>'s + * <code>AbstractView</code>. + * @param detailArg Specifies the <code>Event</code>'s detail. + */ + public void initUIEvent(String typeArg, + boolean canBubbleArg, + boolean cancelableArg, + AbstractView viewArg, + int detailArg); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLAnchorElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLAnchorElement.java new file mode 100644 index 000000000..a3ec0b504 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLAnchorElement.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * The anchor element. See the A element definition in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLAnchorElement extends HTMLElement { + /** + * A single character access key to give access to the form control. See + * the accesskey attribute definition in HTML 4.01. + */ + public String getAccessKey(); + /** + * A single character access key to give access to the form control. See + * the accesskey attribute definition in HTML 4.01. + */ + public void setAccessKey(String accessKey); + + /** + * The character encoding of the linked resource. See the charset + * attribute definition in HTML 4.01. + */ + public String getCharset(); + /** + * The character encoding of the linked resource. See the charset + * attribute definition in HTML 4.01. + */ + public void setCharset(String charset); + + /** + * Comma-separated list of lengths, defining an active region geometry. + * See also <code>shape</code> for the shape of the region. See the + * coords attribute definition in HTML 4.01. + */ + public String getCoords(); + /** + * Comma-separated list of lengths, defining an active region geometry. + * See also <code>shape</code> for the shape of the region. See the + * coords attribute definition in HTML 4.01. + */ + public void setCoords(String coords); + + /** + * The absolute URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>] of the linked resource. See the href attribute + * definition in HTML 4.01. + */ + public String getHref(); + /** + * The absolute URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>] of the linked resource. See the href attribute + * definition in HTML 4.01. + */ + public void setHref(String href); + + /** + * Language code of the linked resource. See the hreflang attribute + * definition in HTML 4.01. + */ + public String getHreflang(); + /** + * Language code of the linked resource. See the hreflang attribute + * definition in HTML 4.01. + */ + public void setHreflang(String hreflang); + + /** + * Anchor name. See the name attribute definition in HTML 4.01. + */ + public String getName(); + /** + * Anchor name. See the name attribute definition in HTML 4.01. + */ + public void setName(String name); + + /** + * Forward link type. See the rel attribute definition in HTML 4.01. + */ + public String getRel(); + /** + * Forward link type. See the rel attribute definition in HTML 4.01. + */ + public void setRel(String rel); + + /** + * Reverse link type. See the rev attribute definition in HTML 4.01. + */ + public String getRev(); + /** + * Reverse link type. See the rev attribute definition in HTML 4.01. + */ + public void setRev(String rev); + + /** + * The shape of the active area. The coordinates are given by + * <code>coords</code>. See the shape attribute definition in HTML 4.01. + */ + public String getShape(); + /** + * The shape of the active area. The coordinates are given by + * <code>coords</code>. See the shape attribute definition in HTML 4.01. + */ + public void setShape(String shape); + + /** + * Index that represents the element's position in the tabbing order. See + * the tabindex attribute definition in HTML 4.01. + */ + public int getTabIndex(); + /** + * Index that represents the element's position in the tabbing order. See + * the tabindex attribute definition in HTML 4.01. + */ + public void setTabIndex(int tabIndex); + + /** + * Frame to render the resource in. See the target attribute definition in + * HTML 4.01. + */ + public String getTarget(); + /** + * Frame to render the resource in. See the target attribute definition in + * HTML 4.01. + */ + public void setTarget(String target); + + /** + * Advisory content type. See the type attribute definition in HTML 4.01. + */ + public String getType(); + /** + * Advisory content type. See the type attribute definition in HTML 4.01. + */ + public void setType(String type); + + /** + * Removes keyboard focus from this element. + */ + public void blur(); + + /** + * Gives keyboard focus to this element. + */ + public void focus(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLAppletElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLAppletElement.java new file mode 100644 index 000000000..2e0fc153c --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLAppletElement.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * An embedded Java applet. See the APPLET element definition in HTML 4.01. + * This element is deprecated in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLAppletElement extends HTMLElement { + /** + * Aligns this object (vertically or horizontally) with respect to its + * surrounding text. See the align attribute definition in HTML 4.01. + * This attribute is deprecated in HTML 4.01. + */ + public String getAlign(); + /** + * Aligns this object (vertically or horizontally) with respect to its + * surrounding text. See the align attribute definition in HTML 4.01. + * This attribute is deprecated in HTML 4.01. + */ + public void setAlign(String align); + + /** + * Alternate text for user agents not rendering the normal content of this + * element. See the alt attribute definition in HTML 4.01. This + * attribute is deprecated in HTML 4.01. + */ + public String getAlt(); + /** + * Alternate text for user agents not rendering the normal content of this + * element. See the alt attribute definition in HTML 4.01. This + * attribute is deprecated in HTML 4.01. + */ + public void setAlt(String alt); + + /** + * Comma-separated archive list. See the archive attribute definition in + * HTML 4.01. This attribute is deprecated in HTML 4.01. + */ + public String getArchive(); + /** + * Comma-separated archive list. See the archive attribute definition in + * HTML 4.01. This attribute is deprecated in HTML 4.01. + */ + public void setArchive(String archive); + + /** + * Applet class file. See the code attribute definition in HTML 4.01. This + * attribute is deprecated in HTML 4.01. + */ + public String getCode(); + /** + * Applet class file. See the code attribute definition in HTML 4.01. This + * attribute is deprecated in HTML 4.01. + */ + public void setCode(String code); + + /** + * Optional base URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>] for applet. See the codebase attribute definition in + * HTML 4.01. This attribute is deprecated in HTML 4.01. + */ + public String getCodeBase(); + /** + * Optional base URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>] for applet. See the codebase attribute definition in + * HTML 4.01. This attribute is deprecated in HTML 4.01. + */ + public void setCodeBase(String codeBase); + + /** + * Override height. See the height attribute definition in HTML 4.01. This + * attribute is deprecated in HTML 4.01. + */ + public String getHeight(); + /** + * Override height. See the height attribute definition in HTML 4.01. This + * attribute is deprecated in HTML 4.01. + */ + public void setHeight(String height); + + /** + * Horizontal space, in pixels, to the left and right of this image, + * applet, or object. See the hspace attribute definition in HTML 4.01. + * This attribute is deprecated in HTML 4.01. + * @version DOM Level 2 + */ + public int getHspace(); + /** + * Horizontal space, in pixels, to the left and right of this image, + * applet, or object. See the hspace attribute definition in HTML 4.01. + * This attribute is deprecated in HTML 4.01. + * @version DOM Level 2 + */ + public void setHspace(int hspace); + + /** + * The name of the applet. See the name attribute definition in HTML 4.01. + * This attribute is deprecated in HTML 4.01. + */ + public String getName(); + /** + * The name of the applet. See the name attribute definition in HTML 4.01. + * This attribute is deprecated in HTML 4.01. + */ + public void setName(String name); + + /** + * The value of the "object" attribute. See the object attribute definition + * in HTML 4.01. This attribute is deprecated in HTML 4.01. + * @version DOM Level 2 + */ + public String getObject(); + /** + * The value of the "object" attribute. See the object attribute definition + * in HTML 4.01. This attribute is deprecated in HTML 4.01. + * @version DOM Level 2 + */ + public void setObject(String object); + + /** + * Vertical space, in pixels, above and below this image, applet, or + * object. See the vspace attribute definition in HTML 4.01. This + * attribute is deprecated in HTML 4.01. + * @version DOM Level 2 + */ + public int getVspace(); + /** + * Vertical space, in pixels, above and below this image, applet, or + * object. See the vspace attribute definition in HTML 4.01. This + * attribute is deprecated in HTML 4.01. + * @version DOM Level 2 + */ + public void setVspace(int vspace); + + /** + * Override width. See the width attribute definition in HTML 4.01. This + * attribute is deprecated in HTML 4.01. + */ + public String getWidth(); + /** + * Override width. See the width attribute definition in HTML 4.01. This + * attribute is deprecated in HTML 4.01. + */ + public void setWidth(String width); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLAreaElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLAreaElement.java new file mode 100644 index 000000000..403b94d50 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLAreaElement.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * Client-side image map area definition. See the AREA element definition in + * HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLAreaElement extends HTMLElement { + /** + * A single character access key to give access to the form control. See + * the accesskey attribute definition in HTML 4.01. + */ + public String getAccessKey(); + /** + * A single character access key to give access to the form control. See + * the accesskey attribute definition in HTML 4.01. + */ + public void setAccessKey(String accessKey); + + /** + * Alternate text for user agents not rendering the normal content of this + * element. See the alt attribute definition in HTML 4.01. + */ + public String getAlt(); + /** + * Alternate text for user agents not rendering the normal content of this + * element. See the alt attribute definition in HTML 4.01. + */ + public void setAlt(String alt); + + /** + * Comma-separated list of lengths, defining an active region geometry. + * See also <code>shape</code> for the shape of the region. See the + * coords attribute definition in HTML 4.01. + */ + public String getCoords(); + /** + * Comma-separated list of lengths, defining an active region geometry. + * See also <code>shape</code> for the shape of the region. See the + * coords attribute definition in HTML 4.01. + */ + public void setCoords(String coords); + + /** + * The URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>] of the linked resource. See the href attribute definition in + * HTML 4.01. + */ + public String getHref(); + /** + * The URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>] of the linked resource. See the href attribute definition in + * HTML 4.01. + */ + public void setHref(String href); + + /** + * Specifies that this area is inactive, i.e., has no associated action. + * See the nohref attribute definition in HTML 4.01. + */ + public boolean getNoHref(); + /** + * Specifies that this area is inactive, i.e., has no associated action. + * See the nohref attribute definition in HTML 4.01. + */ + public void setNoHref(boolean noHref); + + /** + * The shape of the active area. The coordinates are given by + * <code>coords</code>. See the shape attribute definition in HTML 4.01. + */ + public String getShape(); + /** + * The shape of the active area. The coordinates are given by + * <code>coords</code>. See the shape attribute definition in HTML 4.01. + */ + public void setShape(String shape); + + /** + * Index that represents the element's position in the tabbing order. See + * the tabindex attribute definition in HTML 4.01. + */ + public int getTabIndex(); + /** + * Index that represents the element's position in the tabbing order. See + * the tabindex attribute definition in HTML 4.01. + */ + public void setTabIndex(int tabIndex); + + /** + * Frame to render the resource in. See the target attribute definition in + * HTML 4.01. + */ + public String getTarget(); + /** + * Frame to render the resource in. See the target attribute definition in + * HTML 4.01. + */ + public void setTarget(String target); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLBRElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLBRElement.java new file mode 100644 index 000000000..74dbe1f3f --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLBRElement.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * Force a line break. See the BR element definition in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLBRElement extends HTMLElement { + /** + * Control flow of text around floats. See the clear attribute definition + * in HTML 4.01. This attribute is deprecated in HTML 4.01. + */ + public String getClear(); + /** + * Control flow of text around floats. See the clear attribute definition + * in HTML 4.01. This attribute is deprecated in HTML 4.01. + */ + public void setClear(String clear); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLBaseElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLBaseElement.java new file mode 100644 index 000000000..9dde9b3da --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLBaseElement.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * Document base URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>]. See the BASE element definition in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLBaseElement extends HTMLElement { + /** + * The base URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>]. See the href attribute definition in HTML 4.01. + */ + public String getHref(); + /** + * The base URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>]. See the href attribute definition in HTML 4.01. + */ + public void setHref(String href); + + /** + * The default target frame. See the target attribute definition in HTML + * 4.01. + */ + public String getTarget(); + /** + * The default target frame. See the target attribute definition in HTML + * 4.01. + */ + public void setTarget(String target); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLBaseFontElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLBaseFontElement.java new file mode 100644 index 000000000..1ae8834d7 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLBaseFontElement.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * Base font. See the BASEFONT element definition in HTML 4.01. This element + * is deprecated in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLBaseFontElement extends HTMLElement { + /** + * Font color. See the color attribute definition in HTML 4.01. This + * attribute is deprecated in HTML 4.01. + */ + public String getColor(); + /** + * Font color. See the color attribute definition in HTML 4.01. This + * attribute is deprecated in HTML 4.01. + */ + public void setColor(String color); + + /** + * Font face identifier. See the face attribute definition in HTML 4.01. + * This attribute is deprecated in HTML 4.01. + */ + public String getFace(); + /** + * Font face identifier. See the face attribute definition in HTML 4.01. + * This attribute is deprecated in HTML 4.01. + */ + public void setFace(String face); + + /** + * Computed font size. See the size attribute definition in HTML 4.01. + * This attribute is deprecated in HTML 4.01. + * @version DOM Level 2 + */ + public int getSize(); + /** + * Computed font size. See the size attribute definition in HTML 4.01. + * This attribute is deprecated in HTML 4.01. + * @version DOM Level 2 + */ + public void setSize(int size); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLBodyElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLBodyElement.java new file mode 100644 index 000000000..7e1aabe1f --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLBodyElement.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * The HTML document body. This element is always present in the DOM API, even + * if the tags are not present in the source document. See the BODY element + * definition in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLBodyElement extends HTMLElement { + /** + * Color of active links (after mouse-button down, but before mouse-button + * up). See the alink attribute definition in HTML 4.01. This attribute + * is deprecated in HTML 4.01. + */ + public String getALink(); + /** + * Color of active links (after mouse-button down, but before mouse-button + * up). See the alink attribute definition in HTML 4.01. This attribute + * is deprecated in HTML 4.01. + */ + public void setALink(String aLink); + + /** + * URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>] of the background texture tile image. See the background attribute + * definition in HTML 4.01. This attribute is deprecated in HTML 4.01. + */ + public String getBackground(); + /** + * URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>] of the background texture tile image. See the background attribute + * definition in HTML 4.01. This attribute is deprecated in HTML 4.01. + */ + public void setBackground(String background); + + /** + * Document background color. See the bgcolor attribute definition in HTML + * 4.01. This attribute is deprecated in HTML 4.01. + */ + public String getBgColor(); + /** + * Document background color. See the bgcolor attribute definition in HTML + * 4.01. This attribute is deprecated in HTML 4.01. + */ + public void setBgColor(String bgColor); + + /** + * Color of links that are not active and unvisited. See the link + * attribute definition in HTML 4.01. This attribute is deprecated in + * HTML 4.01. + */ + public String getLink(); + /** + * Color of links that are not active and unvisited. See the link + * attribute definition in HTML 4.01. This attribute is deprecated in + * HTML 4.01. + */ + public void setLink(String link); + + /** + * Document text color. See the text attribute definition in HTML 4.01. + * This attribute is deprecated in HTML 4.01. + */ + public String getText(); + /** + * Document text color. See the text attribute definition in HTML 4.01. + * This attribute is deprecated in HTML 4.01. + */ + public void setText(String text); + + /** + * Color of links that have been visited by the user. See the vlink + * attribute definition in HTML 4.01. This attribute is deprecated in + * HTML 4.01. + */ + public String getVLink(); + /** + * Color of links that have been visited by the user. See the vlink + * attribute definition in HTML 4.01. This attribute is deprecated in + * HTML 4.01. + */ + public void setVLink(String vLink); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLButtonElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLButtonElement.java new file mode 100644 index 000000000..8e31b103c --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLButtonElement.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * Push button. See the BUTTON element definition in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLButtonElement extends HTMLElement { + /** + * Returns the <code>FORM</code> element containing this control. Returns + * <code>null</code> if this control is not within the context of a + * form. + */ + public HTMLFormElement getForm(); + + /** + * A single character access key to give access to the form control. See + * the accesskey attribute definition in HTML 4.01. + */ + public String getAccessKey(); + /** + * A single character access key to give access to the form control. See + * the accesskey attribute definition in HTML 4.01. + */ + public void setAccessKey(String accessKey); + + /** + * The control is unavailable in this context. See the disabled attribute + * definition in HTML 4.01. + */ + public boolean getDisabled(); + /** + * The control is unavailable in this context. See the disabled attribute + * definition in HTML 4.01. + */ + public void setDisabled(boolean disabled); + + /** + * Form control or object name when submitted with a form. See the name + * attribute definition in HTML 4.01. + */ + public String getName(); + /** + * Form control or object name when submitted with a form. See the name + * attribute definition in HTML 4.01. + */ + public void setName(String name); + + /** + * Index that represents the element's position in the tabbing order. See + * the tabindex attribute definition in HTML 4.01. + */ + public int getTabIndex(); + /** + * Index that represents the element's position in the tabbing order. See + * the tabindex attribute definition in HTML 4.01. + */ + public void setTabIndex(int tabIndex); + + /** + * The type of button (all lower case). See the type attribute definition + * in HTML 4.01. + */ + public String getType(); + + /** + * The current form control value. See the value attribute definition in + * HTML 4.01. + */ + public String getValue(); + /** + * The current form control value. See the value attribute definition in + * HTML 4.01. + */ + public void setValue(String value); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLCollection.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLCollection.java new file mode 100644 index 000000000..d6ec5473f --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLCollection.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +import org.w3c.dom.Node; + +/** + * An <code>HTMLCollection</code> is a list of nodes. An individual node may + * be accessed by either ordinal index or the node's <code>name</code> or + * <code>id</code> attributes. Collections in the HTML DOM are assumed to be + * live meaning that they are automatically updated when the underlying + * document is changed. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLCollection { + /** + * This attribute specifies the length or size of the list. + */ + public int getLength(); + + /** + * This method retrieves a node specified by ordinal index. Nodes are + * numbered in tree order (depth-first traversal order). + * @param index The index of the node to be fetched. The index origin is + * <code>0</code>. + * @return The <code>Node</code> at the corresponding position upon + * success. A value of <code>null</code> is returned if the index is + * out of range. + */ + public Node item(int index); + + /** + * This method retrieves a <code>Node</code> using a name. With [<a href='http://www.w3.org/TR/1999/REC-html401-19991224'>HTML 4.01</a>] + * documents, it first searches for a <code>Node</code> with a matching + * <code>id</code> attribute. If it doesn't find one, it then searches + * for a <code>Node</code> with a matching <code>name</code> attribute, + * but only on those elements that are allowed a name attribute. With [<a href='http://www.w3.org/TR/2002/REC-xhtml1-20020801'>XHTML 1.0</a>] + * documents, this method only searches for <code>Nodes</code> with a + * matching <code>id</code> attribute. This method is case insensitive + * in HTML documents and case sensitive in XHTML documents. + * @param name The name of the <code>Node</code> to be fetched. + * @return The <code>Node</code> with a <code>name</code> or + * <code>id</code> attribute whose value corresponds to the specified + * string. Upon failure (e.g., no node with this name exists), returns + * <code>null</code>. + */ + public Node namedItem(String name); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLDListElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLDListElement.java new file mode 100644 index 000000000..e6f17b6ad --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLDListElement.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * Definition list. See the DL element definition in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLDListElement extends HTMLElement { + /** + * Reduce spacing between list items. See the compact attribute definition + * in HTML 4.01. This attribute is deprecated in HTML 4.01. + */ + public boolean getCompact(); + /** + * Reduce spacing between list items. See the compact attribute definition + * in HTML 4.01. This attribute is deprecated in HTML 4.01. + */ + public void setCompact(boolean compact); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLDirectoryElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLDirectoryElement.java new file mode 100644 index 000000000..b66de037c --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLDirectoryElement.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * Directory list. See the DIR element definition in HTML 4.01. This element + * is deprecated in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLDirectoryElement extends HTMLElement { + /** + * Reduce spacing between list items. See the compact attribute definition + * in HTML 4.01. This attribute is deprecated in HTML 4.01. + */ + public boolean getCompact(); + /** + * Reduce spacing between list items. See the compact attribute definition + * in HTML 4.01. This attribute is deprecated in HTML 4.01. + */ + public void setCompact(boolean compact); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLDivElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLDivElement.java new file mode 100644 index 000000000..5f5c0dc88 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLDivElement.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * Generic block container. See the DIV element definition in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLDivElement extends HTMLElement { + /** + * Horizontal text alignment. See the align attribute definition in HTML + * 4.01. This attribute is deprecated in HTML 4.01. + */ + public String getAlign(); + /** + * Horizontal text alignment. See the align attribute definition in HTML + * 4.01. This attribute is deprecated in HTML 4.01. + */ + public void setAlign(String align); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLDocument.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLDocument.java new file mode 100644 index 000000000..b038783f6 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLDocument.java @@ -0,0 +1,237 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +import org.w3c.dom.Document; +import org.w3c.dom.NodeList; +import org.w3c.dom.DOMException; + +/** + * An <code>HTMLDocument</code> is the root of the HTML hierarchy and holds + * the entire content. Besides providing access to the hierarchy, it also + * provides some convenience methods for accessing certain sets of + * information from the document. + * <p>The following properties have been deprecated in favor of the + * corresponding ones for the <code>BODY</code> element:alinkColorbackground + * bgColorfgColorlinkColorvlinkColorIn DOM Level 2, the method + * <code>getElementById</code> is inherited from the <code>Document</code> + * interface where it was moved to. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLDocument extends Document { + /** + * The title of a document as specified by the <code>TITLE</code> element + * in the head of the document. + */ + public String getTitle(); + /** + * The title of a document as specified by the <code>TITLE</code> element + * in the head of the document. + */ + public void setTitle(String title); + + /** + * Returns the URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>] of the page that linked to this page. The value is an + * empty string if the user navigated to the page directly (not through + * a link, but, for example, via a bookmark). + */ + public String getReferrer(); + + /** + * The domain name of the server that served the document, or + * <code>null</code> if the server cannot be identified by a domain + * name. + */ + public String getDomain(); + + /** + * The absolute URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>] of the document. + */ + public String getURL(); + + /** + * The element that contains the content for the document. In documents + * with <code>BODY</code> contents, returns the <code>BODY</code> + * element. In frameset documents, this returns the outermost + * <code>FRAMESET</code> element. + */ + public HTMLElement getBody(); + /** + * The element that contains the content for the document. In documents + * with <code>BODY</code> contents, returns the <code>BODY</code> + * element. In frameset documents, this returns the outermost + * <code>FRAMESET</code> element. + */ + public void setBody(HTMLElement body); + + /** + * A collection of all the <code>IMG</code> elements in a document. The + * behavior is limited to <code>IMG</code> elements for backwards + * compatibility. As suggested by [<a href='http://www.w3.org/TR/1999/REC-html401-19991224'>HTML 4.01</a>], to include images, authors may use + * the <code>OBJECT</code> element or the <code>IMG</code> element. + * Therefore, it is recommended not to use this attribute to find the + * images in the document but <code>getElementsByTagName</code> with + * HTML 4.01 or <code>getElementsByTagNameNS</code> with XHTML 1.0. + */ + public HTMLCollection getImages(); + + /** + * A collection of all the <code>OBJECT</code> elements that include + * applets and <code>APPLET</code> (deprecated) elements in a document. + */ + public HTMLCollection getApplets(); + + /** + * A collection of all <code>AREA</code> elements and anchor ( + * <code>A</code>) elements in a document with a value for the + * <code>href</code> attribute. + */ + public HTMLCollection getLinks(); + + /** + * A collection of all the forms of a document. + */ + public HTMLCollection getForms(); + + /** + * A collection of all the anchor (<code>A</code>) elements in a document + * with a value for the <code>name</code> attribute. For reasons of + * backward compatibility, the returned set of anchors only contains + * those anchors created with the <code>name</code> attribute, not those + * created with the <code>id</code> attribute. Note that in [<a href='http://www.w3.org/TR/2002/REC-xhtml1-20020801'>XHTML 1.0</a>], the + * <code>name</code> attribute (see section 4.10) has no semantics and + * is only present for legacy user agents: the <code>id</code> attribute + * is used instead. Users should prefer the iterator mechanisms provided + * by [<a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Traversal-Range-20001113'>DOM Level 2 Traversal</a>] instead. + */ + public HTMLCollection getAnchors(); + + /** + * This mutable string attribute denotes persistent state information + * that (1) is associated with the current frame or document and (2) is + * composed of information described by the <code>cookies</code> + * non-terminal of [<a href='http://www.ietf.org/rfc/rfc2965.txt'>IETF RFC 2965</a>], Section 4.2.2. + * <br> If no persistent state information is available for the current + * frame or document document, then this property's value is an empty + * string. + * <br> When this attribute is read, all cookies are returned as a single + * string, with each cookie's name-value pair concatenated into a list + * of name-value pairs, each list item being separated by a ';' + * (semicolon). + * <br> When this attribute is set, the value it is set to should be a + * string that adheres to the <code>cookie</code> non-terminal of [<a href='http://www.ietf.org/rfc/rfc2965.txt'>IETF RFC 2965</a>]; that + * is, it should be a single name-value pair followed by zero or more + * cookie attribute values. If no domain attribute is specified, then + * the domain attribute for the new value defaults to the host portion + * of an absolute URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>] of the current frame or document. If no path + * attribute is specified, then the path attribute for the new value + * defaults to the absolute path portion of the URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>] of the current + * frame or document. If no max-age attribute is specified, then the + * max-age attribute for the new value defaults to a user agent defined + * value. If a cookie with the specified name is already associated with + * the current frame or document, then the new value as well as the new + * attributes replace the old value and attributes. If a max-age + * attribute of 0 is specified for the new value, then any existing + * cookies of the specified name are removed from the cookie storage. + * See [<a href='http://www.ietf.org/rfc/rfc2965.txt'>IETF RFC 2965</a>] for the semantics of persistent state item attribute value + * pairs. The precise nature of a user agent session is not defined by + * this specification. + */ + public String getCookie(); + /** + * This mutable string attribute denotes persistent state information + * that (1) is associated with the current frame or document and (2) is + * composed of information described by the <code>cookies</code> + * non-terminal of [<a href='http://www.ietf.org/rfc/rfc2965.txt'>IETF RFC 2965</a>], Section 4.2.2. + * <br> If no persistent state information is available for the current + * frame or document document, then this property's value is an empty + * string. + * <br> When this attribute is read, all cookies are returned as a single + * string, with each cookie's name-value pair concatenated into a list + * of name-value pairs, each list item being separated by a ';' + * (semicolon). + * <br> When this attribute is set, the value it is set to should be a + * string that adheres to the <code>cookie</code> non-terminal of [<a href='http://www.ietf.org/rfc/rfc2965.txt'>IETF RFC 2965</a>]; that + * is, it should be a single name-value pair followed by zero or more + * cookie attribute values. If no domain attribute is specified, then + * the domain attribute for the new value defaults to the host portion + * of an absolute URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>] of the current frame or document. If no path + * attribute is specified, then the path attribute for the new value + * defaults to the absolute path portion of the URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>] of the current + * frame or document. If no max-age attribute is specified, then the + * max-age attribute for the new value defaults to a user agent defined + * value. If a cookie with the specified name is already associated with + * the current frame or document, then the new value as well as the new + * attributes replace the old value and attributes. If a max-age + * attribute of 0 is specified for the new value, then any existing + * cookies of the specified name are removed from the cookie storage. + * See [<a href='http://www.ietf.org/rfc/rfc2965.txt'>IETF RFC 2965</a>] for the semantics of persistent state item attribute value + * pairs. The precise nature of a user agent session is not defined by + * this specification. + * @exception DOMException + * SYNTAX_ERR: If the new value does not adhere to the cookie syntax + * specified by [<a href='http://www.ietf.org/rfc/rfc2965.txt'>IETF RFC 2965</a>]. + */ + public void setCookie(String cookie) + throws DOMException; + + /** + * Open a document stream for writing. If a document exists in the target, + * this method clears it. This method and the ones following allow a + * user to add to or replace the structure model of a document using + * strings of unparsed HTML. At the time of writing alternate methods + * for providing similar functionality for both HTML and XML documents + * were being considered (see [<a href='http://www.w3.org/TR/2002/WD-DOM-Level-3-LS-20020725'>DOM Level 3 Load and Save</a>]). + */ + public void open(); + + /** + * Closes a document stream opened by <code>open()</code> and forces + * rendering. + */ + public void close(); + + /** + * Write a string of text to a document stream opened by + * <code>open()</code>. Note that the function will produce a document + * which is not necessarily driven by a DTD and therefore might be + * produce an invalid result in the context of the document. + * @param text The string to be parsed into some structure in the + * document structure model. + */ + public void write(String text); + + /** + * Write a string of text followed by a newline character to a document + * stream opened by <code>open()</code>. Note that the function will + * produce a document which is not necessarily driven by a DTD and + * therefore might be produce an invalid result in the context of the + * document + * @param text The string to be parsed into some structure in the + * document structure model. + */ + public void writeln(String text); + + /** + * With [<a href='http://www.w3.org/TR/1999/REC-html401-19991224'>HTML 4.01</a>] documents, this method returns the (possibly empty) collection + * of elements whose <code>name</code> value is given by + * <code>elementName</code>. In [<a href='http://www.w3.org/TR/2002/REC-xhtml1-20020801'>XHTML 1.0</a>] documents, this methods only return the + * (possibly empty) collection of form controls with matching name. This + * method is case sensitive. + * @param elementName The <code>name</code> attribute value for an + * element. + * @return The matching elements. + */ + public NodeList getElementsByName(String elementName); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLElement.java new file mode 100644 index 000000000..c6450301b --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLElement.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +import org.w3c.dom.Element; + +/** + * All HTML element interfaces derive from this class. Elements that only + * expose the HTML core attributes are represented by the base + * <code>HTMLElement</code> interface. These elements are as follows: + * special: SUB, SUP, SPAN, BDOfont: TT, I, B, U, S, STRIKE, BIG, SMALL + * phrase: EM, STRONG, DFN, CODE, SAMP, KBD, VAR, CITE, ACRONYM, ABBRlist: + * DD, DTNOFRAMES, NOSCRIPTADDRESS, CENTERThe <code>style</code> attribute + * of an HTML element is accessible through the + * <code>ElementCSSInlineStyle</code> interface which is defined in the CSS + * module [<a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113'>DOM Level 2 Style Sheets and CSS</a>]. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLElement extends Element { + /** + * The element's identifier. See the id attribute definition in HTML 4.01. + */ + public String getId(); + /** + * The element's identifier. See the id attribute definition in HTML 4.01. + */ + public void setId(String id); + + /** + * The element's advisory title. See the title attribute definition in + * HTML 4.01. + */ + public String getTitle(); + /** + * The element's advisory title. See the title attribute definition in + * HTML 4.01. + */ + public void setTitle(String title); + + /** + * Language code defined in RFC 1766. See the lang attribute definition in + * HTML 4.01. + */ + public String getLang(); + /** + * Language code defined in RFC 1766. See the lang attribute definition in + * HTML 4.01. + */ + public void setLang(String lang); + + /** + * Specifies the base direction of directionally neutral text and the + * directionality of tables. See the dir attribute definition in HTML + * 4.01. + */ + public String getDir(); + /** + * Specifies the base direction of directionally neutral text and the + * directionality of tables. See the dir attribute definition in HTML + * 4.01. + */ + public void setDir(String dir); + + /** + * The class attribute of the element. This attribute has been renamed due + * to conflicts with the "class" keyword exposed by many languages. See + * the class attribute definition in HTML 4.01. + */ + public String getClassName(); + /** + * The class attribute of the element. This attribute has been renamed due + * to conflicts with the "class" keyword exposed by many languages. See + * the class attribute definition in HTML 4.01. + */ + public void setClassName(String className); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLFieldSetElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLFieldSetElement.java new file mode 100644 index 000000000..f3bcb7df7 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLFieldSetElement.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * Organizes form controls into logical groups. See the FIELDSET element + * definition in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLFieldSetElement extends HTMLElement { + /** + * Returns the <code>FORM</code> element containing this control. Returns + * <code>null</code> if this control is not within the context of a + * form. + */ + public HTMLFormElement getForm(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLFontElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLFontElement.java new file mode 100644 index 000000000..aa6a2847b --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLFontElement.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * Local change to font. See the FONT element definition in HTML 4.01. This + * element is deprecated in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLFontElement extends HTMLElement { + /** + * Font color. See the color attribute definition in HTML 4.01. This + * attribute is deprecated in HTML 4.01. + */ + public String getColor(); + /** + * Font color. See the color attribute definition in HTML 4.01. This + * attribute is deprecated in HTML 4.01. + */ + public void setColor(String color); + + /** + * Font face identifier. See the face attribute definition in HTML 4.01. + * This attribute is deprecated in HTML 4.01. + */ + public String getFace(); + /** + * Font face identifier. See the face attribute definition in HTML 4.01. + * This attribute is deprecated in HTML 4.01. + */ + public void setFace(String face); + + /** + * Font size. See the size attribute definition in HTML 4.01. This + * attribute is deprecated in HTML 4.01. + */ + public String getSize(); + /** + * Font size. See the size attribute definition in HTML 4.01. This + * attribute is deprecated in HTML 4.01. + */ + public void setSize(String size); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLFormElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLFormElement.java new file mode 100644 index 000000000..60ec7736f --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLFormElement.java @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * The <code>FORM</code> element encompasses behavior similar to a collection + * and an element. It provides direct access to the contained form controls + * as well as the attributes of the form element. See the FORM element + * definition in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLFormElement extends HTMLElement { + /** + * Returns a collection of all form control elements in the form. + */ + public HTMLCollection getElements(); + + /** + * The number of form controls in the form. + */ + public int getLength(); + + /** + * Names the form. + */ + public String getName(); + /** + * Names the form. + */ + public void setName(String name); + + /** + * List of character sets supported by the server. See the accept-charset + * attribute definition in HTML 4.01. + */ + public String getAcceptCharset(); + /** + * List of character sets supported by the server. See the accept-charset + * attribute definition in HTML 4.01. + */ + public void setAcceptCharset(String acceptCharset); + + /** + * Server-side form handler. See the action attribute definition in HTML + * 4.01. + */ + public String getAction(); + /** + * Server-side form handler. See the action attribute definition in HTML + * 4.01. + */ + public void setAction(String action); + + /** + * The content type of the submitted form, generally + * "application/x-www-form-urlencoded". See the enctype attribute + * definition in HTML 4.01. The onsubmit even handler is not guaranteed + * to be triggered when invoking this method. The behavior is + * inconsistent for historical reasons and authors should not rely on a + * particular one. + */ + public String getEnctype(); + /** + * The content type of the submitted form, generally + * "application/x-www-form-urlencoded". See the enctype attribute + * definition in HTML 4.01. The onsubmit even handler is not guaranteed + * to be triggered when invoking this method. The behavior is + * inconsistent for historical reasons and authors should not rely on a + * particular one. + */ + public void setEnctype(String enctype); + + /** + * HTTP method [<a href='http://www.ietf.org/rfc/rfc2616.txt'>IETF RFC 2616</a>] used to submit form. See the method attribute definition + * in HTML 4.01. + */ + public String getMethod(); + /** + * HTTP method [<a href='http://www.ietf.org/rfc/rfc2616.txt'>IETF RFC 2616</a>] used to submit form. See the method attribute definition + * in HTML 4.01. + */ + public void setMethod(String method); + + /** + * Frame to render the resource in. See the target attribute definition in + * HTML 4.01. + */ + public String getTarget(); + /** + * Frame to render the resource in. See the target attribute definition in + * HTML 4.01. + */ + public void setTarget(String target); + + /** + * Submits the form. It performs the same action as a submit button. + */ + public void submit(); + + /** + * Restores a form element's default values. It performs the same action + * as a reset button. + */ + public void reset(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLFrameElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLFrameElement.java new file mode 100644 index 000000000..dfe877f15 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLFrameElement.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +import org.w3c.dom.Document; + +/** + * Create a frame. See the FRAME element definition in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLFrameElement extends HTMLElement { + /** + * Request frame borders. See the frameborder attribute definition in HTML + * 4.01. + */ + public String getFrameBorder(); + /** + * Request frame borders. See the frameborder attribute definition in HTML + * 4.01. + */ + public void setFrameBorder(String frameBorder); + + /** + * URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>] designating a long description of this image or frame. See the + * longdesc attribute definition in HTML 4.01. + */ + public String getLongDesc(); + /** + * URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>] designating a long description of this image or frame. See the + * longdesc attribute definition in HTML 4.01. + */ + public void setLongDesc(String longDesc); + + /** + * Frame margin height, in pixels. See the marginheight attribute + * definition in HTML 4.01. + */ + public String getMarginHeight(); + /** + * Frame margin height, in pixels. See the marginheight attribute + * definition in HTML 4.01. + */ + public void setMarginHeight(String marginHeight); + + /** + * Frame margin width, in pixels. See the marginwidth attribute definition + * in HTML 4.01. + */ + public String getMarginWidth(); + /** + * Frame margin width, in pixels. See the marginwidth attribute definition + * in HTML 4.01. + */ + public void setMarginWidth(String marginWidth); + + /** + * The frame name (object of the <code>target</code> attribute). See the + * name attribute definition in HTML 4.01. + */ + public String getName(); + /** + * The frame name (object of the <code>target</code> attribute). See the + * name attribute definition in HTML 4.01. + */ + public void setName(String name); + + /** + * When true, forbid user from resizing frame. See the noresize attribute + * definition in HTML 4.01. + */ + public boolean getNoResize(); + /** + * When true, forbid user from resizing frame. See the noresize attribute + * definition in HTML 4.01. + */ + public void setNoResize(boolean noResize); + + /** + * Specify whether or not the frame should have scrollbars. See the + * scrolling attribute definition in HTML 4.01. + */ + public String getScrolling(); + /** + * Specify whether or not the frame should have scrollbars. See the + * scrolling attribute definition in HTML 4.01. + */ + public void setScrolling(String scrolling); + + /** + * A URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>] designating the initial frame contents. See the src attribute + * definition in HTML 4.01. + */ + public String getSrc(); + /** + * A URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>] designating the initial frame contents. See the src attribute + * definition in HTML 4.01. + */ + public void setSrc(String src); + + /** + * The document this frame contains, if there is any and it is available, + * or <code>null</code> otherwise. + * @since DOM Level 2 + */ + public Document getContentDocument(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLFrameSetElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLFrameSetElement.java new file mode 100644 index 000000000..d2b9c34e9 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLFrameSetElement.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * Create a grid of frames. See the FRAMESET element definition in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLFrameSetElement extends HTMLElement { + /** + * The number of columns of frames in the frameset. See the cols attribute + * definition in HTML 4.01. + */ + public String getCols(); + /** + * The number of columns of frames in the frameset. See the cols attribute + * definition in HTML 4.01. + */ + public void setCols(String cols); + + /** + * The number of rows of frames in the frameset. See the rows attribute + * definition in HTML 4.01. + */ + public String getRows(); + /** + * The number of rows of frames in the frameset. See the rows attribute + * definition in HTML 4.01. + */ + public void setRows(String rows); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLHRElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLHRElement.java new file mode 100644 index 000000000..d832bc3f0 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLHRElement.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * Create a horizontal rule. See the HR element definition in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLHRElement extends HTMLElement { + /** + * Align the rule on the page. See the align attribute definition in HTML + * 4.01. This attribute is deprecated in HTML 4.01. + */ + public String getAlign(); + /** + * Align the rule on the page. See the align attribute definition in HTML + * 4.01. This attribute is deprecated in HTML 4.01. + */ + public void setAlign(String align); + + /** + * Indicates to the user agent that there should be no shading in the + * rendering of this element. See the noshade attribute definition in + * HTML 4.01. This attribute is deprecated in HTML 4.01. + */ + public boolean getNoShade(); + /** + * Indicates to the user agent that there should be no shading in the + * rendering of this element. See the noshade attribute definition in + * HTML 4.01. This attribute is deprecated in HTML 4.01. + */ + public void setNoShade(boolean noShade); + + /** + * The height of the rule. See the size attribute definition in HTML 4.01. + * This attribute is deprecated in HTML 4.01. + */ + public String getSize(); + /** + * The height of the rule. See the size attribute definition in HTML 4.01. + * This attribute is deprecated in HTML 4.01. + */ + public void setSize(String size); + + /** + * The width of the rule. See the width attribute definition in HTML 4.01. + * This attribute is deprecated in HTML 4.01. + */ + public String getWidth(); + /** + * The width of the rule. See the width attribute definition in HTML 4.01. + * This attribute is deprecated in HTML 4.01. + */ + public void setWidth(String width); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLHeadElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLHeadElement.java new file mode 100644 index 000000000..85617a7ee --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLHeadElement.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * Document head information. See the HEAD element definition in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLHeadElement extends HTMLElement { + /** + * URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>] designating a metadata profile. See the profile attribute + * definition in HTML 4.01. + */ + public String getProfile(); + /** + * URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>] designating a metadata profile. See the profile attribute + * definition in HTML 4.01. + */ + public void setProfile(String profile); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLHeadingElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLHeadingElement.java new file mode 100644 index 000000000..291f5d87a --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLHeadingElement.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * For the <code>H1</code> to <code>H6</code> elements. See the H1 element + * definition in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLHeadingElement extends HTMLElement { + /** + * Horizontal text alignment. See the align attribute definition in HTML + * 4.01. This attribute is deprecated in HTML 4.01. + */ + public String getAlign(); + /** + * Horizontal text alignment. See the align attribute definition in HTML + * 4.01. This attribute is deprecated in HTML 4.01. + */ + public void setAlign(String align); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLHtmlElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLHtmlElement.java new file mode 100644 index 000000000..3601d7eb3 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLHtmlElement.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * Root of an HTML document. See the HTML element definition in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLHtmlElement extends HTMLElement { + /** + * Version information about the document's DTD. See the version attribute + * definition in HTML 4.01. This attribute is deprecated in HTML 4.01. + */ + public String getVersion(); + /** + * Version information about the document's DTD. See the version attribute + * definition in HTML 4.01. This attribute is deprecated in HTML 4.01. + */ + public void setVersion(String version); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLIFrameElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLIFrameElement.java new file mode 100644 index 000000000..6106e62a2 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLIFrameElement.java @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +import org.w3c.dom.Document; + +/** + * Inline subwindows. See the IFRAME element definition in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLIFrameElement extends HTMLElement { + /** + * Aligns this object (vertically or horizontally) with respect to its + * surrounding text. See the align attribute definition in HTML 4.01. + * This attribute is deprecated in HTML 4.01. + */ + public String getAlign(); + /** + * Aligns this object (vertically or horizontally) with respect to its + * surrounding text. See the align attribute definition in HTML 4.01. + * This attribute is deprecated in HTML 4.01. + */ + public void setAlign(String align); + + /** + * Request frame borders. See the frameborder attribute definition in HTML + * 4.01. + */ + public String getFrameBorder(); + /** + * Request frame borders. See the frameborder attribute definition in HTML + * 4.01. + */ + public void setFrameBorder(String frameBorder); + + /** + * Frame height. See the height attribute definition in HTML 4.01. + */ + public String getHeight(); + /** + * Frame height. See the height attribute definition in HTML 4.01. + */ + public void setHeight(String height); + + /** + * URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>] designating a long description of this image or frame. See the + * longdesc attribute definition in HTML 4.01. + */ + public String getLongDesc(); + /** + * URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>] designating a long description of this image or frame. See the + * longdesc attribute definition in HTML 4.01. + */ + public void setLongDesc(String longDesc); + + /** + * Frame margin height, in pixels. See the marginheight attribute + * definition in HTML 4.01. + */ + public String getMarginHeight(); + /** + * Frame margin height, in pixels. See the marginheight attribute + * definition in HTML 4.01. + */ + public void setMarginHeight(String marginHeight); + + /** + * Frame margin width, in pixels. See the marginwidth attribute definition + * in HTML 4.01. + */ + public String getMarginWidth(); + /** + * Frame margin width, in pixels. See the marginwidth attribute definition + * in HTML 4.01. + */ + public void setMarginWidth(String marginWidth); + + /** + * The frame name (object of the <code>target</code> attribute). See the + * name attribute definition in HTML 4.01. + */ + public String getName(); + /** + * The frame name (object of the <code>target</code> attribute). See the + * name attribute definition in HTML 4.01. + */ + public void setName(String name); + + /** + * Specify whether or not the frame should have scrollbars. See the + * scrolling attribute definition in HTML 4.01. + */ + public String getScrolling(); + /** + * Specify whether or not the frame should have scrollbars. See the + * scrolling attribute definition in HTML 4.01. + */ + public void setScrolling(String scrolling); + + /** + * A URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>] designating the initial frame contents. See the src attribute + * definition in HTML 4.01. + */ + public String getSrc(); + /** + * A URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>] designating the initial frame contents. See the src attribute + * definition in HTML 4.01. + */ + public void setSrc(String src); + + /** + * Frame width. See the width attribute definition in HTML 4.01. + */ + public String getWidth(); + /** + * Frame width. See the width attribute definition in HTML 4.01. + */ + public void setWidth(String width); + + /** + * The document this frame contains, if there is any and it is available, + * or <code>null</code> otherwise. + * @since DOM Level 2 + */ + public Document getContentDocument(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLImageElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLImageElement.java new file mode 100644 index 000000000..0a1d4b722 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLImageElement.java @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * Embedded image. See the IMG element definition in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLImageElement extends HTMLElement { + /** + * The name of the element (for backwards compatibility). + */ + public String getName(); + /** + * The name of the element (for backwards compatibility). + */ + public void setName(String name); + + /** + * Aligns this object (vertically or horizontally) with respect to its + * surrounding text. See the align attribute definition in HTML 4.01. + * This attribute is deprecated in HTML 4.01. + */ + public String getAlign(); + /** + * Aligns this object (vertically or horizontally) with respect to its + * surrounding text. See the align attribute definition in HTML 4.01. + * This attribute is deprecated in HTML 4.01. + */ + public void setAlign(String align); + + /** + * Alternate text for user agents not rendering the normal content of this + * element. See the alt attribute definition in HTML 4.01. + */ + public String getAlt(); + /** + * Alternate text for user agents not rendering the normal content of this + * element. See the alt attribute definition in HTML 4.01. + */ + public void setAlt(String alt); + + /** + * Width of border around image. See the border attribute definition in + * HTML 4.01. This attribute is deprecated in HTML 4.01. Note that the + * type of this attribute was <code>DOMString</code> in DOM Level 1 HTML [<a href='http://www.w3.org/TR/1998/REC-DOM-Level-1-19981001'>DOM Level 1</a>] + * . + */ + public String getBorder(); + /** + * Width of border around image. See the border attribute definition in + * HTML 4.01. This attribute is deprecated in HTML 4.01. Note that the + * type of this attribute was <code>DOMString</code> in DOM Level 1 HTML [<a href='http://www.w3.org/TR/1998/REC-DOM-Level-1-19981001'>DOM Level 1</a>] + * . + */ + public void setBorder(String border); + + /** + * Height of the image in pixels. See the height attribute definition in + * HTML 4.01. Note that the type of this attribute was + * <code>DOMString</code> in DOM Level 1 HTML [<a href='http://www.w3.org/TR/1998/REC-DOM-Level-1-19981001'>DOM Level 1</a>]. + * @version DOM Level 2 + */ + public int getHeight(); + /** + * Height of the image in pixels. See the height attribute definition in + * HTML 4.01. Note that the type of this attribute was + * <code>DOMString</code> in DOM Level 1 HTML [<a href='http://www.w3.org/TR/1998/REC-DOM-Level-1-19981001'>DOM Level 1</a>]. + * @version DOM Level 2 + */ + public void setHeight(int height); + + /** + * Horizontal space to the left and right of this image in pixels. See the + * hspace attribute definition in HTML 4.01. This attribute is + * deprecated in HTML 4.01. Note that the type of this attribute was + * <code>DOMString</code> in DOM Level 1 HTML [<a href='http://www.w3.org/TR/1998/REC-DOM-Level-1-19981001'>DOM Level 1</a>]. + * @version DOM Level 2 + */ + public int getHspace(); + /** + * Horizontal space to the left and right of this image in pixels. See the + * hspace attribute definition in HTML 4.01. This attribute is + * deprecated in HTML 4.01. Note that the type of this attribute was + * <code>DOMString</code> in DOM Level 1 HTML [<a href='http://www.w3.org/TR/1998/REC-DOM-Level-1-19981001'>DOM Level 1</a>]. + * @version DOM Level 2 + */ + public void setHspace(int hspace); + + /** + * Use server-side image map. See the ismap attribute definition in HTML + * 4.01. + */ + public boolean getIsMap(); + /** + * Use server-side image map. See the ismap attribute definition in HTML + * 4.01. + */ + public void setIsMap(boolean isMap); + + /** + * URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>] designating a long description of this image or frame. See the + * longdesc attribute definition in HTML 4.01. + */ + public String getLongDesc(); + /** + * URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>] designating a long description of this image or frame. See the + * longdesc attribute definition in HTML 4.01. + */ + public void setLongDesc(String longDesc); + + /** + * URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>] designating the source of this image. See the src attribute + * definition in HTML 4.01. + */ + public String getSrc(); + /** + * URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>] designating the source of this image. See the src attribute + * definition in HTML 4.01. + */ + public void setSrc(String src); + + /** + * Use client-side image map. See the usemap attribute definition in HTML + * 4.01. + */ + public String getUseMap(); + /** + * Use client-side image map. See the usemap attribute definition in HTML + * 4.01. + */ + public void setUseMap(String useMap); + + /** + * Vertical space above and below this image in pixels. See the vspace + * attribute definition in HTML 4.01. This attribute is deprecated in + * HTML 4.01. Note that the type of this attribute was "DOMString" in + * DOM Level 1 HTML [<a href='http://www.w3.org/TR/1998/REC-DOM-Level-1-19981001'>DOM Level 1</a>]. + * @version DOM Level 2 + */ + public int getVspace(); + /** + * Vertical space above and below this image in pixels. See the vspace + * attribute definition in HTML 4.01. This attribute is deprecated in + * HTML 4.01. Note that the type of this attribute was "DOMString" in + * DOM Level 1 HTML [<a href='http://www.w3.org/TR/1998/REC-DOM-Level-1-19981001'>DOM Level 1</a>]. + * @version DOM Level 2 + */ + public void setVspace(int vspace); + + /** + * The width of the image in pixels. See the width attribute definition in + * HTML 4.01. Note that the type of this attribute was + * <code>DOMString</code> in DOM Level 1 HTML [<a href='http://www.w3.org/TR/1998/REC-DOM-Level-1-19981001'>DOM Level 1</a>]. + * @version DOM Level 2 + */ + public int getWidth(); + /** + * The width of the image in pixels. See the width attribute definition in + * HTML 4.01. Note that the type of this attribute was + * <code>DOMString</code> in DOM Level 1 HTML [<a href='http://www.w3.org/TR/1998/REC-DOM-Level-1-19981001'>DOM Level 1</a>]. + * @version DOM Level 2 + */ + public void setWidth(int width); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLInputElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLInputElement.java new file mode 100644 index 000000000..c557e0bce --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLInputElement.java @@ -0,0 +1,303 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * Form control.Depending upon the environment in which the page is being + * viewed, the value property may be read-only for the file upload input + * type. For the "password" input type, the actual value returned may be + * masked to prevent unauthorized use. See the INPUT element definition in [<a href='http://www.w3.org/TR/1999/REC-html401-19991224'>HTML 4.01</a>]. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLInputElement extends HTMLElement { + /** + * When the <code>type</code> attribute of the element has the value + * "text", "file" or "password", this represents the HTML value + * attribute of the element. The value of this attribute does not change + * if the contents of the corresponding form control, in an interactive + * user agent, changes. See the value attribute definition in HTML 4.01. + */ + public String getDefaultValue(); + /** + * When the <code>type</code> attribute of the element has the value + * "text", "file" or "password", this represents the HTML value + * attribute of the element. The value of this attribute does not change + * if the contents of the corresponding form control, in an interactive + * user agent, changes. See the value attribute definition in HTML 4.01. + */ + public void setDefaultValue(String defaultValue); + + /** + * When <code>type</code> has the value "radio" or "checkbox", this + * represents the HTML checked attribute of the element. The value of + * this attribute does not change if the state of the corresponding form + * control, in an interactive user agent, changes. See the checked + * attribute definition in HTML 4.01. + */ + public boolean getDefaultChecked(); + /** + * When <code>type</code> has the value "radio" or "checkbox", this + * represents the HTML checked attribute of the element. The value of + * this attribute does not change if the state of the corresponding form + * control, in an interactive user agent, changes. See the checked + * attribute definition in HTML 4.01. + */ + public void setDefaultChecked(boolean defaultChecked); + + /** + * Returns the <code>FORM</code> element containing this control. Returns + * <code>null</code> if this control is not within the context of a + * form. + */ + public HTMLFormElement getForm(); + + /** + * A comma-separated list of content types that a server processing this + * form will handle correctly. See the accept attribute definition in + * HTML 4.01. + */ + public String getAccept(); + /** + * A comma-separated list of content types that a server processing this + * form will handle correctly. See the accept attribute definition in + * HTML 4.01. + */ + public void setAccept(String accept); + + /** + * A single character access key to give access to the form control. See + * the accesskey attribute definition in HTML 4.01. + */ + public String getAccessKey(); + /** + * A single character access key to give access to the form control. See + * the accesskey attribute definition in HTML 4.01. + */ + public void setAccessKey(String accessKey); + + /** + * Aligns this object (vertically or horizontally) with respect to its + * surrounding text. See the align attribute definition in HTML 4.01. + * This attribute is deprecated in HTML 4.01. + */ + public String getAlign(); + /** + * Aligns this object (vertically or horizontally) with respect to its + * surrounding text. See the align attribute definition in HTML 4.01. + * This attribute is deprecated in HTML 4.01. + */ + public void setAlign(String align); + + /** + * Alternate text for user agents not rendering the normal content of this + * element. See the alt attribute definition in HTML 4.01. + */ + public String getAlt(); + /** + * Alternate text for user agents not rendering the normal content of this + * element. See the alt attribute definition in HTML 4.01. + */ + public void setAlt(String alt); + + /** + * When the <code>type</code> attribute of the element has the value + * "radio" or "checkbox", this represents the current state of the form + * control, in an interactive user agent. Changes to this attribute + * change the state of the form control, but do not change the value of + * the HTML checked attribute of the INPUT element.During the handling + * of a click event on an input element with a type attribute that has + * the value "radio" or "checkbox", some implementations may change the + * value of this property before the event is being dispatched in the + * document. If the default action of the event is canceled, the value + * of the property may be changed back to its original value. This means + * that the value of this property during the handling of click events + * is implementation dependent. + */ + public boolean getChecked(); + /** + * When the <code>type</code> attribute of the element has the value + * "radio" or "checkbox", this represents the current state of the form + * control, in an interactive user agent. Changes to this attribute + * change the state of the form control, but do not change the value of + * the HTML checked attribute of the INPUT element.During the handling + * of a click event on an input element with a type attribute that has + * the value "radio" or "checkbox", some implementations may change the + * value of this property before the event is being dispatched in the + * document. If the default action of the event is canceled, the value + * of the property may be changed back to its original value. This means + * that the value of this property during the handling of click events + * is implementation dependent. + */ + public void setChecked(boolean checked); + + /** + * The control is unavailable in this context. See the disabled attribute + * definition in HTML 4.01. + */ + public boolean getDisabled(); + /** + * The control is unavailable in this context. See the disabled attribute + * definition in HTML 4.01. + */ + public void setDisabled(boolean disabled); + + /** + * Maximum number of characters for text fields, when <code>type</code> + * has the value "text" or "password". See the maxlength attribute + * definition in HTML 4.01. + */ + public int getMaxLength(); + /** + * Maximum number of characters for text fields, when <code>type</code> + * has the value "text" or "password". See the maxlength attribute + * definition in HTML 4.01. + */ + public void setMaxLength(int maxLength); + + /** + * Form control or object name when submitted with a form. See the name + * attribute definition in HTML 4.01. + */ + public String getName(); + /** + * Form control or object name when submitted with a form. See the name + * attribute definition in HTML 4.01. + */ + public void setName(String name); + + /** + * This control is read-only. Relevant only when <code>type</code> has the + * value "text" or "password". See the readonly attribute definition in + * HTML 4.01. + */ + public boolean getReadOnly(); + /** + * This control is read-only. Relevant only when <code>type</code> has the + * value "text" or "password". See the readonly attribute definition in + * HTML 4.01. + */ + public void setReadOnly(boolean readOnly); + + /** + * Size information. The precise meaning is specific to each type of + * field. See the size attribute definition in HTML 4.01. + * @version DOM Level 2 + */ + public int getSize(); + /** + * Size information. The precise meaning is specific to each type of + * field. See the size attribute definition in HTML 4.01. + * @version DOM Level 2 + */ + public void setSize(int size); + + /** + * When the <code>type</code> attribute has the value "image", this + * attribute specifies the location of the image to be used to decorate + * the graphical submit button. See the src attribute definition in HTML + * 4.01. + */ + public String getSrc(); + /** + * When the <code>type</code> attribute has the value "image", this + * attribute specifies the location of the image to be used to decorate + * the graphical submit button. See the src attribute definition in HTML + * 4.01. + */ + public void setSrc(String src); + + /** + * Index that represents the element's position in the tabbing order. See + * the tabindex attribute definition in HTML 4.01. + */ + public int getTabIndex(); + /** + * Index that represents the element's position in the tabbing order. See + * the tabindex attribute definition in HTML 4.01. + */ + public void setTabIndex(int tabIndex); + + /** + * The type of control created (all lower case). See the type attribute + * definition in HTML 4.01. + * @version DOM Level 2 + */ + public String getType(); + /** + * The type of control created (all lower case). See the type attribute + * definition in HTML 4.01. + * @version DOM Level 2 + */ + public void setType(String type); + + /** + * Use client-side image map. See the usemap attribute definition in HTML + * 4.01. + */ + public String getUseMap(); + /** + * Use client-side image map. See the usemap attribute definition in HTML + * 4.01. + */ + public void setUseMap(String useMap); + + /** + * When the <code>type</code> attribute of the element has the value + * "text", "file" or "password", this represents the current contents of + * the corresponding form control, in an interactive user agent. + * Changing this attribute changes the contents of the form control, but + * does not change the value of the HTML value attribute of the element. + * When the <code>type</code> attribute of the element has the value + * "button", "hidden", "submit", "reset", "image", "checkbox" or + * "radio", this represents the HTML value attribute of the element. See + * the value attribute definition in HTML 4.01. + */ + public String getValue(); + /** + * When the <code>type</code> attribute of the element has the value + * "text", "file" or "password", this represents the current contents of + * the corresponding form control, in an interactive user agent. + * Changing this attribute changes the contents of the form control, but + * does not change the value of the HTML value attribute of the element. + * When the <code>type</code> attribute of the element has the value + * "button", "hidden", "submit", "reset", "image", "checkbox" or + * "radio", this represents the HTML value attribute of the element. See + * the value attribute definition in HTML 4.01. + */ + public void setValue(String value); + + /** + * Removes keyboard focus from this element. + */ + public void blur(); + + /** + * Gives keyboard focus to this element. + */ + public void focus(); + + /** + * Select the contents of the text area. For <code>INPUT</code> elements + * whose <code>type</code> attribute has one of the following values: + * "text", "file", or "password". + */ + public void select(); + + /** + * Simulate a mouse-click. For <code>INPUT</code> elements whose + * <code>type</code> attribute has one of the following values: + * "button", "checkbox", "radio", "reset", or "submit". + */ + public void click(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLIsIndexElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLIsIndexElement.java new file mode 100644 index 000000000..f1b4b7478 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLIsIndexElement.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * This element is used for single-line text input. See the ISINDEX element + * definition in HTML 4.01. This element is deprecated in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLIsIndexElement extends HTMLElement { + /** + * Returns the <code>FORM</code> element containing this control. Returns + * <code>null</code> if this control is not within the context of a + * form. + */ + public HTMLFormElement getForm(); + + /** + * The prompt message. See the prompt attribute definition in HTML 4.01. + * This attribute is deprecated in HTML 4.01. + */ + public String getPrompt(); + /** + * The prompt message. See the prompt attribute definition in HTML 4.01. + * This attribute is deprecated in HTML 4.01. + */ + public void setPrompt(String prompt); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLLIElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLLIElement.java new file mode 100644 index 000000000..3a69f5e9e --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLLIElement.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * List item. See the LI element definition in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLLIElement extends HTMLElement { + /** + * List item bullet style. See the type attribute definition in HTML 4.01. + * This attribute is deprecated in HTML 4.01. + */ + public String getType(); + /** + * List item bullet style. See the type attribute definition in HTML 4.01. + * This attribute is deprecated in HTML 4.01. + */ + public void setType(String type); + + /** + * Reset sequence number when used in <code>OL</code>. See the value + * attribute definition in HTML 4.01. This attribute is deprecated in + * HTML 4.01. + */ + public int getValue(); + /** + * Reset sequence number when used in <code>OL</code>. See the value + * attribute definition in HTML 4.01. This attribute is deprecated in + * HTML 4.01. + */ + public void setValue(int value); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLLabelElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLLabelElement.java new file mode 100644 index 000000000..ef1a10aea --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLLabelElement.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * Form field label text. See the LABEL element definition in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLLabelElement extends HTMLElement { + /** + * Returns the <code>FORM</code> element containing this control. Returns + * <code>null</code> if this control is not within the context of a + * form. + */ + public HTMLFormElement getForm(); + + /** + * A single character access key to give access to the form control. See + * the accesskey attribute definition in HTML 4.01. + */ + public String getAccessKey(); + /** + * A single character access key to give access to the form control. See + * the accesskey attribute definition in HTML 4.01. + */ + public void setAccessKey(String accessKey); + + /** + * This attribute links this label with another form control by + * <code>id</code> attribute. See the for attribute definition in HTML + * 4.01. + */ + public String getHtmlFor(); + /** + * This attribute links this label with another form control by + * <code>id</code> attribute. See the for attribute definition in HTML + * 4.01. + */ + public void setHtmlFor(String htmlFor); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLLegendElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLLegendElement.java new file mode 100644 index 000000000..774a11640 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLLegendElement.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * Provides a caption for a <code>FIELDSET</code> grouping. See the LEGEND + * element definition in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLLegendElement extends HTMLElement { + /** + * Returns the <code>FORM</code> element containing this control. Returns + * <code>null</code> if this control is not within the context of a + * form. + */ + public HTMLFormElement getForm(); + + /** + * A single character access key to give access to the form control. See + * the accesskey attribute definition in HTML 4.01. + */ + public String getAccessKey(); + /** + * A single character access key to give access to the form control. See + * the accesskey attribute definition in HTML 4.01. + */ + public void setAccessKey(String accessKey); + + /** + * Text alignment relative to <code>FIELDSET</code>. See the align + * attribute definition in HTML 4.01. This attribute is deprecated in + * HTML 4.01. + */ + public String getAlign(); + /** + * Text alignment relative to <code>FIELDSET</code>. See the align + * attribute definition in HTML 4.01. This attribute is deprecated in + * HTML 4.01. + */ + public void setAlign(String align); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLLinkElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLLinkElement.java new file mode 100644 index 000000000..8210a4a35 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLLinkElement.java @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * The <code>LINK</code> element specifies a link to an external resource, and + * defines this document's relationship to that resource (or vice versa). + * See the LINK element definition in HTML 4.01 (see also the + * <code>LinkStyle</code> interface in the StyleSheet module [<a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113'>DOM Level 2 Style Sheets and CSS</a>]). + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLLinkElement extends HTMLElement { + /** + * Enables/disables the link. This is currently only used for style sheet + * links, and may be used to activate or deactivate style sheets. + */ + public boolean getDisabled(); + /** + * Enables/disables the link. This is currently only used for style sheet + * links, and may be used to activate or deactivate style sheets. + */ + public void setDisabled(boolean disabled); + + /** + * The character encoding of the resource being linked to. See the charset + * attribute definition in HTML 4.01. + */ + public String getCharset(); + /** + * The character encoding of the resource being linked to. See the charset + * attribute definition in HTML 4.01. + */ + public void setCharset(String charset); + + /** + * The URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>] of the linked resource. See the href attribute definition in + * HTML 4.01. + */ + public String getHref(); + /** + * The URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>] of the linked resource. See the href attribute definition in + * HTML 4.01. + */ + public void setHref(String href); + + /** + * Language code of the linked resource. See the hreflang attribute + * definition in HTML 4.01. + */ + public String getHreflang(); + /** + * Language code of the linked resource. See the hreflang attribute + * definition in HTML 4.01. + */ + public void setHreflang(String hreflang); + + /** + * Designed for use with one or more target media. See the media attribute + * definition in HTML 4.01. + */ + public String getMedia(); + /** + * Designed for use with one or more target media. See the media attribute + * definition in HTML 4.01. + */ + public void setMedia(String media); + + /** + * Forward link type. See the rel attribute definition in HTML 4.01. + */ + public String getRel(); + /** + * Forward link type. See the rel attribute definition in HTML 4.01. + */ + public void setRel(String rel); + + /** + * Reverse link type. See the rev attribute definition in HTML 4.01. + */ + public String getRev(); + /** + * Reverse link type. See the rev attribute definition in HTML 4.01. + */ + public void setRev(String rev); + + /** + * Frame to render the resource in. See the target attribute definition in + * HTML 4.01. + */ + public String getTarget(); + /** + * Frame to render the resource in. See the target attribute definition in + * HTML 4.01. + */ + public void setTarget(String target); + + /** + * Advisory content type. See the type attribute definition in HTML 4.01. + */ + public String getType(); + /** + * Advisory content type. See the type attribute definition in HTML 4.01. + */ + public void setType(String type); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLMapElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLMapElement.java new file mode 100644 index 000000000..b1f78682a --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLMapElement.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * Client-side image map. See the MAP element definition in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLMapElement extends HTMLElement { + /** + * The list of areas defined for the image map. + */ + public HTMLCollection getAreas(); + + /** + * Names the map (for use with <code>usemap</code>). See the name + * attribute definition in HTML 4.01. + */ + public String getName(); + /** + * Names the map (for use with <code>usemap</code>). See the name + * attribute definition in HTML 4.01. + */ + public void setName(String name); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLMenuElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLMenuElement.java new file mode 100644 index 000000000..17e81c597 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLMenuElement.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * Menu list. See the MENU element definition in HTML 4.01. This element is + * deprecated in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLMenuElement extends HTMLElement { + /** + * Reduce spacing between list items. See the compact attribute definition + * in HTML 4.01. This attribute is deprecated in HTML 4.01. + */ + public boolean getCompact(); + /** + * Reduce spacing between list items. See the compact attribute definition + * in HTML 4.01. This attribute is deprecated in HTML 4.01. + */ + public void setCompact(boolean compact); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLMetaElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLMetaElement.java new file mode 100644 index 000000000..a56fed5fc --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLMetaElement.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * This contains generic meta-information about the document. See the META + * element definition in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLMetaElement extends HTMLElement { + /** + * Associated information. See the content attribute definition in HTML + * 4.01. + */ + public String getContent(); + /** + * Associated information. See the content attribute definition in HTML + * 4.01. + */ + public void setContent(String content); + + /** + * HTTP response header name [<a href='http://www.ietf.org/rfc/rfc2616.txt'>IETF RFC 2616</a>]. See the http-equiv attribute definition in + * HTML 4.01. + */ + public String getHttpEquiv(); + /** + * HTTP response header name [<a href='http://www.ietf.org/rfc/rfc2616.txt'>IETF RFC 2616</a>]. See the http-equiv attribute definition in + * HTML 4.01. + */ + public void setHttpEquiv(String httpEquiv); + + /** + * Meta information name. See the name attribute definition in HTML 4.01. + */ + public String getName(); + /** + * Meta information name. See the name attribute definition in HTML 4.01. + */ + public void setName(String name); + + /** + * Select form of content. See the scheme attribute definition in HTML + * 4.01. + */ + public String getScheme(); + /** + * Select form of content. See the scheme attribute definition in HTML + * 4.01. + */ + public void setScheme(String scheme); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLModElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLModElement.java new file mode 100644 index 000000000..f7659f092 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLModElement.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * Notice of modification to part of a document. See the INS and DEL element + * definitions in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLModElement extends HTMLElement { + /** + * A URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>] designating a document that describes the reason for the change. + * See the cite attribute definition in HTML 4.01. + */ + public String getCite(); + /** + * A URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>] designating a document that describes the reason for the change. + * See the cite attribute definition in HTML 4.01. + */ + public void setCite(String cite); + + /** + * The date and time of the change. See the datetime attribute definition + * in HTML 4.01. + */ + public String getDateTime(); + /** + * The date and time of the change. See the datetime attribute definition + * in HTML 4.01. + */ + public void setDateTime(String dateTime); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLOListElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLOListElement.java new file mode 100644 index 000000000..298d47439 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLOListElement.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * Ordered list. See the OL element definition in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLOListElement extends HTMLElement { + /** + * Reduce spacing between list items. See the compact attribute definition + * in HTML 4.01. This attribute is deprecated in HTML 4.01. + */ + public boolean getCompact(); + /** + * Reduce spacing between list items. See the compact attribute definition + * in HTML 4.01. This attribute is deprecated in HTML 4.01. + */ + public void setCompact(boolean compact); + + /** + * Starting sequence number. See the start attribute definition in HTML + * 4.01. This attribute is deprecated in HTML 4.01. + */ + public int getStart(); + /** + * Starting sequence number. See the start attribute definition in HTML + * 4.01. This attribute is deprecated in HTML 4.01. + */ + public void setStart(int start); + + /** + * Numbering style. See the type attribute definition in HTML 4.01. This + * attribute is deprecated in HTML 4.01. + */ + public String getType(); + /** + * Numbering style. See the type attribute definition in HTML 4.01. This + * attribute is deprecated in HTML 4.01. + */ + public void setType(String type); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLObjectElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLObjectElement.java new file mode 100644 index 000000000..e49af5f03 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLObjectElement.java @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +import org.w3c.dom.Document; + +/** + * Generic embedded object.In principle, all properties on the object element + * are read-write but in some environments some properties may be read-only + * once the underlying object is instantiated. See the OBJECT element + * definition in [<a href='http://www.w3.org/TR/1999/REC-html401-19991224'>HTML 4.01</a>]. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLObjectElement extends HTMLElement { + /** + * Returns the <code>FORM</code> element containing this control. Returns + * <code>null</code> if this control is not within the context of a + * form. + */ + public HTMLFormElement getForm(); + + /** + * Applet class file. See the <code>code</code> attribute for + * HTMLAppletElement. + */ + public String getCode(); + /** + * Applet class file. See the <code>code</code> attribute for + * HTMLAppletElement. + */ + public void setCode(String code); + + /** + * Aligns this object (vertically or horizontally) with respect to its + * surrounding text. See the align attribute definition in HTML 4.01. + * This attribute is deprecated in HTML 4.01. + */ + public String getAlign(); + /** + * Aligns this object (vertically or horizontally) with respect to its + * surrounding text. See the align attribute definition in HTML 4.01. + * This attribute is deprecated in HTML 4.01. + */ + public void setAlign(String align); + + /** + * Space-separated list of archives. See the archive attribute definition + * in HTML 4.01. + */ + public String getArchive(); + /** + * Space-separated list of archives. See the archive attribute definition + * in HTML 4.01. + */ + public void setArchive(String archive); + + /** + * Width of border around the object. See the border attribute definition + * in HTML 4.01. This attribute is deprecated in HTML 4.01. + */ + public String getBorder(); + /** + * Width of border around the object. See the border attribute definition + * in HTML 4.01. This attribute is deprecated in HTML 4.01. + */ + public void setBorder(String border); + + /** + * Base URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>] for <code>classid</code>, <code>data</code>, and + * <code>archive</code> attributes. See the codebase attribute definition + * in HTML 4.01. + */ + public String getCodeBase(); + /** + * Base URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>] for <code>classid</code>, <code>data</code>, and + * <code>archive</code> attributes. See the codebase attribute definition + * in HTML 4.01. + */ + public void setCodeBase(String codeBase); + + /** + * Content type for data downloaded via <code>classid</code> attribute. + * See the codetype attribute definition in HTML 4.01. + */ + public String getCodeType(); + /** + * Content type for data downloaded via <code>classid</code> attribute. + * See the codetype attribute definition in HTML 4.01. + */ + public void setCodeType(String codeType); + + /** + * A URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>] specifying the location of the object's data. See the data + * attribute definition in HTML 4.01. + */ + public String getData(); + /** + * A URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>] specifying the location of the object's data. See the data + * attribute definition in HTML 4.01. + */ + public void setData(String data); + + /** + * Declare (for future reference), but do not instantiate, this object. + * See the declare attribute definition in HTML 4.01. + */ + public boolean getDeclare(); + /** + * Declare (for future reference), but do not instantiate, this object. + * See the declare attribute definition in HTML 4.01. + */ + public void setDeclare(boolean declare); + + /** + * Override height. See the height attribute definition in HTML 4.01. + */ + public String getHeight(); + /** + * Override height. See the height attribute definition in HTML 4.01. + */ + public void setHeight(String height); + + /** + * Horizontal space, in pixels, to the left and right of this image, + * applet, or object. See the hspace attribute definition in HTML 4.01. + * This attribute is deprecated in HTML 4.01. + */ + public int getHspace(); + /** + * Horizontal space, in pixels, to the left and right of this image, + * applet, or object. See the hspace attribute definition in HTML 4.01. + * This attribute is deprecated in HTML 4.01. + */ + public void setHspace(int hspace); + + /** + * Form control or object name when submitted with a form. See the name + * attribute definition in HTML 4.01. + */ + public String getName(); + /** + * Form control or object name when submitted with a form. See the name + * attribute definition in HTML 4.01. + */ + public void setName(String name); + + /** + * Message to render while loading the object. See the standby attribute + * definition in HTML 4.01. + */ + public String getStandby(); + /** + * Message to render while loading the object. See the standby attribute + * definition in HTML 4.01. + */ + public void setStandby(String standby); + + /** + * Index that represents the element's position in the tabbing order. See + * the tabindex attribute definition in HTML 4.01. + */ + public int getTabIndex(); + /** + * Index that represents the element's position in the tabbing order. See + * the tabindex attribute definition in HTML 4.01. + */ + public void setTabIndex(int tabIndex); + + /** + * Content type for data downloaded via <code>data</code> attribute. See + * the type attribute definition in HTML 4.01. + */ + public String getType(); + /** + * Content type for data downloaded via <code>data</code> attribute. See + * the type attribute definition in HTML 4.01. + */ + public void setType(String type); + + /** + * Use client-side image map. See the usemap attribute definition in HTML + * 4.01. + */ + public String getUseMap(); + /** + * Use client-side image map. See the usemap attribute definition in HTML + * 4.01. + */ + public void setUseMap(String useMap); + + /** + * Vertical space, in pixels, above and below this image, applet, or + * object. See the vspace attribute definition in HTML 4.01. This + * attribute is deprecated in HTML 4.01. + */ + public int getVspace(); + /** + * Vertical space, in pixels, above and below this image, applet, or + * object. See the vspace attribute definition in HTML 4.01. This + * attribute is deprecated in HTML 4.01. + */ + public void setVspace(int vspace); + + /** + * Override width. See the width attribute definition in HTML 4.01. + */ + public String getWidth(); + /** + * Override width. See the width attribute definition in HTML 4.01. + */ + public void setWidth(String width); + + /** + * The document this object contains, if there is any and it is available, + * or <code>null</code> otherwise. + * @since DOM Level 2 + */ + public Document getContentDocument(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLOptGroupElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLOptGroupElement.java new file mode 100644 index 000000000..8e680a23c --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLOptGroupElement.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * Group options together in logical subdivisions. See the OPTGROUP element + * definition in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLOptGroupElement extends HTMLElement { + /** + * The control is unavailable in this context. See the disabled attribute + * definition in HTML 4.01. + */ + public boolean getDisabled(); + /** + * The control is unavailable in this context. See the disabled attribute + * definition in HTML 4.01. + */ + public void setDisabled(boolean disabled); + + /** + * Assigns a label to this option group. See the label attribute definition + * in HTML 4.01. + */ + public String getLabel(); + /** + * Assigns a label to this option group. See the label attribute definition + * in HTML 4.01. + */ + public void setLabel(String label); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLOptionElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLOptionElement.java new file mode 100644 index 000000000..fe932ca87 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLOptionElement.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * A selectable choice. See the OPTION element definition in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLOptionElement extends HTMLElement { + /** + * Returns the <code>FORM</code> element containing this control. Returns + * <code>null</code> if this control is not within the context of a + * form. + */ + public HTMLFormElement getForm(); + + /** + * Represents the value of the HTML selected attribute. The value of this + * attribute does not change if the state of the corresponding form + * control, in an interactive user agent, changes. See the selected + * attribute definition in HTML 4.01. + * @version DOM Level 2 + */ + public boolean getDefaultSelected(); + /** + * Represents the value of the HTML selected attribute. The value of this + * attribute does not change if the state of the corresponding form + * control, in an interactive user agent, changes. See the selected + * attribute definition in HTML 4.01. + * @version DOM Level 2 + */ + public void setDefaultSelected(boolean defaultSelected); + + /** + * The text contained within the option element. + */ + public String getText(); + + /** + * The index of this <code>OPTION</code> in its parent <code>SELECT</code> + * , starting from 0. + * @version DOM Level 2 + */ + public int getIndex(); + + /** + * The control is unavailable in this context. See the disabled attribute + * definition in HTML 4.01. + */ + public boolean getDisabled(); + /** + * The control is unavailable in this context. See the disabled attribute + * definition in HTML 4.01. + */ + public void setDisabled(boolean disabled); + + /** + * Option label for use in hierarchical menus. See the label attribute + * definition in HTML 4.01. + */ + public String getLabel(); + /** + * Option label for use in hierarchical menus. See the label attribute + * definition in HTML 4.01. + */ + public void setLabel(String label); + + /** + * Represents the current state of the corresponding form control, in an + * interactive user agent. Changing this attribute changes the state of + * the form control, but does not change the value of the HTML selected + * attribute of the element. + */ + public boolean getSelected(); + /** + * Represents the current state of the corresponding form control, in an + * interactive user agent. Changing this attribute changes the state of + * the form control, but does not change the value of the HTML selected + * attribute of the element. + */ + public void setSelected(boolean selected); + + /** + * The current form control value. See the value attribute definition in + * HTML 4.01. + */ + public String getValue(); + /** + * The current form control value. See the value attribute definition in + * HTML 4.01. + */ + public void setValue(String value); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLOptionsCollection.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLOptionsCollection.java new file mode 100644 index 000000000..a28c5ac27 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLOptionsCollection.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +import org.w3c.dom.Node; +import org.w3c.dom.DOMException; + +/** + * An <code>HTMLOptionsCollection</code> is a list of nodes representing HTML + * option element. An individual node may be accessed by either ordinal + * index or the node's <code>name</code> or <code>id</code> attributes. + * Collections in the HTML DOM are assumed to be live meaning that they are + * automatically updated when the underlying document is changed. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + * @since DOM Level 2 + */ +public interface HTMLOptionsCollection { + /** + * This attribute specifies the length or size of the list. + */ + public int getLength(); + /** + * This attribute specifies the length or size of the list. + * @exception DOMException + * NOT_SUPPORTED_ERR: if setting the length is not allowed by the + * implementation. + */ + public void setLength(int length) + throws DOMException; + + /** + * This method retrieves a node specified by ordinal index. Nodes are + * numbered in tree order (depth-first traversal order). + * @param index The index of the node to be fetched. The index origin is + * 0. + * @return The <code>Node</code> at the corresponding position upon + * success. A value of <code>null</code> is returned if the index is + * out of range. + */ + public Node item(int index); + + /** + * This method retrieves a <code>Node</code> using a name. It first + * searches for a <code>Node</code> with a matching <code>id</code> + * attribute. If it doesn't find one, it then searches for a + * <code>Node</code> with a matching <code>name</code> attribute, but + * only on those elements that are allowed a name attribute. This method + * is case insensitive in HTML documents and case sensitive in XHTML + * documents. + * @param name The name of the <code>Node</code> to be fetched. + * @return The <code>Node</code> with a <code>name</code> or + * <code>id</code> attribute whose value corresponds to the specified + * string. Upon failure (e.g., no node with this name exists), returns + * <code>null</code>. + */ + public Node namedItem(String name); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLParagraphElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLParagraphElement.java new file mode 100644 index 000000000..b59f505f9 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLParagraphElement.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * Paragraphs. See the P element definition in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLParagraphElement extends HTMLElement { + /** + * Horizontal text alignment. See the align attribute definition in HTML + * 4.01. This attribute is deprecated in HTML 4.01. + */ + public String getAlign(); + /** + * Horizontal text alignment. See the align attribute definition in HTML + * 4.01. This attribute is deprecated in HTML 4.01. + */ + public void setAlign(String align); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLParamElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLParamElement.java new file mode 100644 index 000000000..33f5f7788 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLParamElement.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * Parameters fed to the <code>OBJECT</code> element. See the PARAM element + * definition in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLParamElement extends HTMLElement { + /** + * The name of a run-time parameter. See the name attribute definition in + * HTML 4.01. + */ + public String getName(); + /** + * The name of a run-time parameter. See the name attribute definition in + * HTML 4.01. + */ + public void setName(String name); + + /** + * Content type for the <code>value</code> attribute when + * <code>valuetype</code> has the value "ref". See the type attribute + * definition in HTML 4.01. + */ + public String getType(); + /** + * Content type for the <code>value</code> attribute when + * <code>valuetype</code> has the value "ref". See the type attribute + * definition in HTML 4.01. + */ + public void setType(String type); + + /** + * The value of a run-time parameter. See the value attribute definition + * in HTML 4.01. + */ + public String getValue(); + /** + * The value of a run-time parameter. See the value attribute definition + * in HTML 4.01. + */ + public void setValue(String value); + + /** + * Information about the meaning of the <code>value</code> attribute + * value. See the valuetype attribute definition in HTML 4.01. + */ + public String getValueType(); + /** + * Information about the meaning of the <code>value</code> attribute + * value. See the valuetype attribute definition in HTML 4.01. + */ + public void setValueType(String valueType); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLPreElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLPreElement.java new file mode 100644 index 000000000..2d39837ed --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLPreElement.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * Preformatted text. See the PRE element definition in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLPreElement extends HTMLElement { + /** + * Fixed width for content. See the width attribute definition in HTML + * 4.01. This attribute is deprecated in HTML 4.01. + */ + public int getWidth(); + /** + * Fixed width for content. See the width attribute definition in HTML + * 4.01. This attribute is deprecated in HTML 4.01. + */ + public void setWidth(int width); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLQuoteElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLQuoteElement.java new file mode 100644 index 000000000..aba49746e --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLQuoteElement.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * For the <code>Q</code> and <code>BLOCKQUOTE</code> elements. See the Q + * element definition in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLQuoteElement extends HTMLElement { + /** + * A URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>] designating a source document or message. See the cite attribute + * definition in HTML 4.01. + */ + public String getCite(); + /** + * A URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>] designating a source document or message. See the cite attribute + * definition in HTML 4.01. + */ + public void setCite(String cite); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLScriptElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLScriptElement.java new file mode 100644 index 000000000..226b394a9 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLScriptElement.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * Script statements. See the SCRIPT element definition in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLScriptElement extends HTMLElement { + /** + * The script content of the element. + */ + public String getText(); + /** + * The script content of the element. + */ + public void setText(String text); + + /** + * Reserved for future use. + */ + public String getHtmlFor(); + /** + * Reserved for future use. + */ + public void setHtmlFor(String htmlFor); + + /** + * Reserved for future use. + */ + public String getEvent(); + /** + * Reserved for future use. + */ + public void setEvent(String event); + + /** + * The character encoding of the linked resource. See the charset + * attribute definition in HTML 4.01. + */ + public String getCharset(); + /** + * The character encoding of the linked resource. See the charset + * attribute definition in HTML 4.01. + */ + public void setCharset(String charset); + + /** + * Indicates that the user agent can defer processing of the script. See + * the defer attribute definition in HTML 4.01. + */ + public boolean getDefer(); + /** + * Indicates that the user agent can defer processing of the script. See + * the defer attribute definition in HTML 4.01. + */ + public void setDefer(boolean defer); + + /** + * URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>] designating an external script. See the src attribute definition + * in HTML 4.01. + */ + public String getSrc(); + /** + * URI [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>] designating an external script. See the src attribute definition + * in HTML 4.01. + */ + public void setSrc(String src); + + /** + * The content type of the script language. See the type attribute + * definition in HTML 4.01. + */ + public String getType(); + /** + * The content type of the script language. See the type attribute + * definition in HTML 4.01. + */ + public void setType(String type); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLSelectElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLSelectElement.java new file mode 100644 index 000000000..98dbc836d --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLSelectElement.java @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +import org.w3c.dom.DOMException; + +/** + * The select element allows the selection of an option. The contained options + * can be directly accessed through the select element as a collection. See + * the SELECT element definition in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLSelectElement extends HTMLElement { + /** + * The type of this form control. This is the string "select-multiple" + * when the multiple attribute is <code>true</code> and the string + * "select-one" when <code>false</code>. + */ + public String getType(); + + /** + * The ordinal index of the selected option, starting from 0. The value -1 + * is returned if no element is selected. If multiple options are + * selected, the index of the first selected option is returned. + */ + public int getSelectedIndex(); + /** + * The ordinal index of the selected option, starting from 0. The value -1 + * is returned if no element is selected. If multiple options are + * selected, the index of the first selected option is returned. + */ + public void setSelectedIndex(int selectedIndex); + + /** + * The current form control value (i.e. the value of the currently + * selected option), if multiple options are selected this is the value + * of the first selected option. + */ + public String getValue(); + /** + * The current form control value (i.e. the value of the currently + * selected option), if multiple options are selected this is the value + * of the first selected option. + */ + public void setValue(String value); + + /** + * The number of options in this <code>SELECT</code>. + * @version DOM Level 2 + */ + public int getLength(); + /** + * The number of options in this <code>SELECT</code>. + * @exception DOMException + * NOT_SUPPORTED_ERR: if setting the length is not allowed by the + * implementation. + * @version DOM Level 2 + */ + public void setLength(int length) + throws DOMException; + + /** + * Returns the <code>FORM</code> element containing this control. Returns + * <code>null</code> if this control is not within the context of a + * form. + */ + public HTMLFormElement getForm(); + + /** + * The collection of <code>OPTION</code> elements contained by this + * element. + * @version DOM Level 2 + */ + public HTMLOptionsCollection getOptions(); + + /** + * The control is unavailable in this context. See the disabled attribute + * definition in HTML 4.01. + */ + public boolean getDisabled(); + /** + * The control is unavailable in this context. See the disabled attribute + * definition in HTML 4.01. + */ + public void setDisabled(boolean disabled); + + /** + * If true, multiple <code>OPTION</code> elements may be selected in this + * <code>SELECT</code>. See the multiple attribute definition in HTML + * 4.01. + */ + public boolean getMultiple(); + /** + * If true, multiple <code>OPTION</code> elements may be selected in this + * <code>SELECT</code>. See the multiple attribute definition in HTML + * 4.01. + */ + public void setMultiple(boolean multiple); + + /** + * Form control or object name when submitted with a form. See the name + * attribute definition in HTML 4.01. + */ + public String getName(); + /** + * Form control or object name when submitted with a form. See the name + * attribute definition in HTML 4.01. + */ + public void setName(String name); + + /** + * Number of visible rows. See the size attribute definition in HTML 4.01. + */ + public int getSize(); + /** + * Number of visible rows. See the size attribute definition in HTML 4.01. + */ + public void setSize(int size); + + /** + * Index that represents the element's position in the tabbing order. See + * the tabindex attribute definition in HTML 4.01. + */ + public int getTabIndex(); + /** + * Index that represents the element's position in the tabbing order. See + * the tabindex attribute definition in HTML 4.01. + */ + public void setTabIndex(int tabIndex); + + /** + * Add a new element to the collection of <code>OPTION</code> elements for + * this <code>SELECT</code>. This method is the equivalent of the + * <code>appendChild</code> method of the <code>Node</code> interface if + * the <code>before</code> parameter is <code>null</code>. It is + * equivalent to the <code>insertBefore</code> method on the parent of + * <code>before</code> in all other cases. This method may have no + * effect if the new element is not an <code>OPTION</code> or an + * <code>OPTGROUP</code>. + * @param element The element to add. + * @param before The element to insert before, or <code>null</code> for + * the tail of the list. + * @exception DOMException + * NOT_FOUND_ERR: Raised if <code>before</code> is not a descendant of + * the <code>SELECT</code> element. + */ + public void add(HTMLElement element, + HTMLElement before) + throws DOMException; + + /** + * Remove an element from the collection of <code>OPTION</code> elements + * for this <code>SELECT</code>. Does nothing if no element has the + * given index. + * @param index The index of the item to remove, starting from 0. + */ + public void remove(int index); + + /** + * Removes keyboard focus from this element. + */ + public void blur(); + + /** + * Gives keyboard focus to this element. + */ + public void focus(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLStyleElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLStyleElement.java new file mode 100644 index 000000000..2512d63a6 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLStyleElement.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * Style information. See the STYLE element definition in HTML 4.01, the CSS + * module [<a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113'>DOM Level 2 Style Sheets and CSS</a>] and the <code>LinkStyle</code> interface in the StyleSheets + * module [<a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113'>DOM Level 2 Style Sheets and CSS</a>]. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLStyleElement extends HTMLElement { + /** + * Enables/disables the style sheet. + */ + public boolean getDisabled(); + /** + * Enables/disables the style sheet. + */ + public void setDisabled(boolean disabled); + + /** + * Designed for use with one or more target media. See the media attribute + * definition in HTML 4.01. + */ + public String getMedia(); + /** + * Designed for use with one or more target media. See the media attribute + * definition in HTML 4.01. + */ + public void setMedia(String media); + + /** + * The content type of the style sheet language. See the type attribute + * definition in HTML 4.01. + */ + public String getType(); + /** + * The content type of the style sheet language. See the type attribute + * definition in HTML 4.01. + */ + public void setType(String type); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLTableCaptionElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLTableCaptionElement.java new file mode 100644 index 000000000..47466e9e9 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLTableCaptionElement.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * Table caption See the CAPTION element definition in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLTableCaptionElement extends HTMLElement { + /** + * Caption alignment with respect to the table. See the align attribute + * definition in HTML 4.01. This attribute is deprecated in HTML 4.01. + */ + public String getAlign(); + /** + * Caption alignment with respect to the table. See the align attribute + * definition in HTML 4.01. This attribute is deprecated in HTML 4.01. + */ + public void setAlign(String align); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLTableCellElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLTableCellElement.java new file mode 100644 index 000000000..2e4db7095 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLTableCellElement.java @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * The object used to represent the <code>TH</code> and <code>TD</code> + * elements. See the TD element definition in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLTableCellElement extends HTMLElement { + /** + * The index of this cell in the row, starting from 0. This index is in + * document tree order and not display order. + */ + public int getCellIndex(); + + /** + * Abbreviation for header cells. See the abbr attribute definition in + * HTML 4.01. + */ + public String getAbbr(); + /** + * Abbreviation for header cells. See the abbr attribute definition in + * HTML 4.01. + */ + public void setAbbr(String abbr); + + /** + * Horizontal alignment of data in cell. See the align attribute definition + * in HTML 4.01. + */ + public String getAlign(); + /** + * Horizontal alignment of data in cell. See the align attribute definition + * in HTML 4.01. + */ + public void setAlign(String align); + + /** + * Names group of related headers. See the axis attribute definition in + * HTML 4.01. + */ + public String getAxis(); + /** + * Names group of related headers. See the axis attribute definition in + * HTML 4.01. + */ + public void setAxis(String axis); + + /** + * Cell background color. See the bgcolor attribute definition in HTML + * 4.01. This attribute is deprecated in HTML 4.01. + */ + public String getBgColor(); + /** + * Cell background color. See the bgcolor attribute definition in HTML + * 4.01. This attribute is deprecated in HTML 4.01. + */ + public void setBgColor(String bgColor); + + /** + * Alignment character for cells in a column. See the char attribute + * definition in HTML 4.01. + */ + public String getCh(); + /** + * Alignment character for cells in a column. See the char attribute + * definition in HTML 4.01. + */ + public void setCh(String ch); + + /** + * Offset of alignment character. See the charoff attribute definition in + * HTML 4.01. + */ + public String getChOff(); + /** + * Offset of alignment character. See the charoff attribute definition in + * HTML 4.01. + */ + public void setChOff(String chOff); + + /** + * Number of columns spanned by cell. See the colspan attribute definition + * in HTML 4.01. + */ + public int getColSpan(); + /** + * Number of columns spanned by cell. See the colspan attribute definition + * in HTML 4.01. + */ + public void setColSpan(int colSpan); + + /** + * List of <code>id</code> attribute values for header cells. See the + * headers attribute definition in HTML 4.01. + */ + public String getHeaders(); + /** + * List of <code>id</code> attribute values for header cells. See the + * headers attribute definition in HTML 4.01. + */ + public void setHeaders(String headers); + + /** + * Cell height. See the height attribute definition in HTML 4.01. This + * attribute is deprecated in HTML 4.01. + */ + public String getHeight(); + /** + * Cell height. See the height attribute definition in HTML 4.01. This + * attribute is deprecated in HTML 4.01. + */ + public void setHeight(String height); + + /** + * Suppress word wrapping. See the nowrap attribute definition in HTML + * 4.01. This attribute is deprecated in HTML 4.01. + */ + public boolean getNoWrap(); + /** + * Suppress word wrapping. See the nowrap attribute definition in HTML + * 4.01. This attribute is deprecated in HTML 4.01. + */ + public void setNoWrap(boolean noWrap); + + /** + * Number of rows spanned by cell. See the rowspan attribute definition in + * HTML 4.01. + */ + public int getRowSpan(); + /** + * Number of rows spanned by cell. See the rowspan attribute definition in + * HTML 4.01. + */ + public void setRowSpan(int rowSpan); + + /** + * Scope covered by header cells. See the scope attribute definition in + * HTML 4.01. + */ + public String getScope(); + /** + * Scope covered by header cells. See the scope attribute definition in + * HTML 4.01. + */ + public void setScope(String scope); + + /** + * Vertical alignment of data in cell. See the valign attribute definition + * in HTML 4.01. + */ + public String getVAlign(); + /** + * Vertical alignment of data in cell. See the valign attribute definition + * in HTML 4.01. + */ + public void setVAlign(String vAlign); + + /** + * Cell width. See the width attribute definition in HTML 4.01. This + * attribute is deprecated in HTML 4.01. + */ + public String getWidth(); + /** + * Cell width. See the width attribute definition in HTML 4.01. This + * attribute is deprecated in HTML 4.01. + */ + public void setWidth(String width); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLTableColElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLTableColElement.java new file mode 100644 index 000000000..57bb35cfc --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLTableColElement.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * Regroups the <code>COL</code> and <code>COLGROUP</code> elements. See the + * COL element definition in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLTableColElement extends HTMLElement { + /** + * Horizontal alignment of cell data in column. See the align attribute + * definition in HTML 4.01. + */ + public String getAlign(); + /** + * Horizontal alignment of cell data in column. See the align attribute + * definition in HTML 4.01. + */ + public void setAlign(String align); + + /** + * Alignment character for cells in a column. See the char attribute + * definition in HTML 4.01. + */ + public String getCh(); + /** + * Alignment character for cells in a column. See the char attribute + * definition in HTML 4.01. + */ + public void setCh(String ch); + + /** + * Offset of alignment character. See the charoff attribute definition in + * HTML 4.01. + */ + public String getChOff(); + /** + * Offset of alignment character. See the charoff attribute definition in + * HTML 4.01. + */ + public void setChOff(String chOff); + + /** + * Indicates the number of columns in a group or affected by a grouping. + * See the span attribute definition in HTML 4.01. + */ + public int getSpan(); + /** + * Indicates the number of columns in a group or affected by a grouping. + * See the span attribute definition in HTML 4.01. + */ + public void setSpan(int span); + + /** + * Vertical alignment of cell data in column. See the valign attribute + * definition in HTML 4.01. + */ + public String getVAlign(); + /** + * Vertical alignment of cell data in column. See the valign attribute + * definition in HTML 4.01. + */ + public void setVAlign(String vAlign); + + /** + * Default column width. See the width attribute definition in HTML 4.01. + */ + public String getWidth(); + /** + * Default column width. See the width attribute definition in HTML 4.01. + */ + public void setWidth(String width); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLTableElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLTableElement.java new file mode 100644 index 000000000..ae15deb77 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLTableElement.java @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +import org.w3c.dom.DOMException; + +/** + * The create* and delete* methods on the table allow authors to construct and + * modify tables. [<a href='http://www.w3.org/TR/1999/REC-html401-19991224'>HTML 4.01</a>] specifies that only one of each of the + * <code>CAPTION</code>, <code>THEAD</code>, and <code>TFOOT</code> elements + * may exist in a table. Therefore, if one exists, and the createTHead() or + * createTFoot() method is called, the method returns the existing THead or + * TFoot element. See the TABLE element definition in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLTableElement extends HTMLElement { + /** + * Returns the table's <code>CAPTION</code>, or void if none exists. + * @version DOM Level 2 + */ + public HTMLTableCaptionElement getCaption(); + /** + * Returns the table's <code>CAPTION</code>, or void if none exists. + * @exception DOMException + * HIERARCHY_REQUEST_ERR: if the element is not a <code>CAPTION</code>. + * @version DOM Level 2 + */ + public void setCaption(HTMLTableCaptionElement caption) + throws DOMException; + + /** + * Returns the table's <code>THEAD</code>, or <code>null</code> if none + * exists. + * @version DOM Level 2 + */ + public HTMLTableSectionElement getTHead(); + /** + * Returns the table's <code>THEAD</code>, or <code>null</code> if none + * exists. + * @exception DOMException + * HIERARCHY_REQUEST_ERR: if the element is not a <code>THEAD</code>. + * @version DOM Level 2 + */ + public void setTHead(HTMLTableSectionElement tHead) + throws DOMException; + + /** + * Returns the table's <code>TFOOT</code>, or <code>null</code> if none + * exists. + * @version DOM Level 2 + */ + public HTMLTableSectionElement getTFoot(); + /** + * Returns the table's <code>TFOOT</code>, or <code>null</code> if none + * exists. + * @exception DOMException + * HIERARCHY_REQUEST_ERR: if the element is not a <code>TFOOT</code>. + * @version DOM Level 2 + */ + public void setTFoot(HTMLTableSectionElement tFoot) + throws DOMException; + + /** + * Returns a collection of all the rows in the table, including all in + * <code>THEAD</code>, <code>TFOOT</code>, all <code>TBODY</code> + * elements. + */ + public HTMLCollection getRows(); + + /** + * Returns a collection of the table bodies (including implicit ones). + */ + public HTMLCollection getTBodies(); + + /** + * Specifies the table's position with respect to the rest of the + * document. See the align attribute definition in HTML 4.01. This + * attribute is deprecated in HTML 4.01. + */ + public String getAlign(); + /** + * Specifies the table's position with respect to the rest of the + * document. See the align attribute definition in HTML 4.01. This + * attribute is deprecated in HTML 4.01. + */ + public void setAlign(String align); + + /** + * Cell background color. See the bgcolor attribute definition in HTML + * 4.01. This attribute is deprecated in HTML 4.01. + */ + public String getBgColor(); + /** + * Cell background color. See the bgcolor attribute definition in HTML + * 4.01. This attribute is deprecated in HTML 4.01. + */ + public void setBgColor(String bgColor); + + /** + * The width of the border around the table. See the border attribute + * definition in HTML 4.01. + */ + public String getBorder(); + /** + * The width of the border around the table. See the border attribute + * definition in HTML 4.01. + */ + public void setBorder(String border); + + /** + * Specifies the horizontal and vertical space between cell content and + * cell borders. See the cellpadding attribute definition in HTML 4.01. + */ + public String getCellPadding(); + /** + * Specifies the horizontal and vertical space between cell content and + * cell borders. See the cellpadding attribute definition in HTML 4.01. + */ + public void setCellPadding(String cellPadding); + + /** + * Specifies the horizontal and vertical separation between cells. See the + * cellspacing attribute definition in HTML 4.01. + */ + public String getCellSpacing(); + /** + * Specifies the horizontal and vertical separation between cells. See the + * cellspacing attribute definition in HTML 4.01. + */ + public void setCellSpacing(String cellSpacing); + + /** + * Specifies which external table borders to render. See the frame + * attribute definition in HTML 4.01. + */ + public String getFrame(); + /** + * Specifies which external table borders to render. See the frame + * attribute definition in HTML 4.01. + */ + public void setFrame(String frame); + + /** + * Specifies which internal table borders to render. See the rules + * attribute definition in HTML 4.01. + */ + public String getRules(); + /** + * Specifies which internal table borders to render. See the rules + * attribute definition in HTML 4.01. + */ + public void setRules(String rules); + + /** + * Description about the purpose or structure of a table. See the summary + * attribute definition in HTML 4.01. + */ + public String getSummary(); + /** + * Description about the purpose or structure of a table. See the summary + * attribute definition in HTML 4.01. + */ + public void setSummary(String summary); + + /** + * Specifies the desired table width. See the width attribute definition + * in HTML 4.01. + */ + public String getWidth(); + /** + * Specifies the desired table width. See the width attribute definition + * in HTML 4.01. + */ + public void setWidth(String width); + + /** + * Create a table header row or return an existing one. + * @return A new table header element (<code>THEAD</code>). + */ + public HTMLElement createTHead(); + + /** + * Delete the header from the table, if one exists. + */ + public void deleteTHead(); + + /** + * Create a table footer row or return an existing one. + * @return A footer element (<code>TFOOT</code>). + */ + public HTMLElement createTFoot(); + + /** + * Delete the footer from the table, if one exists. + */ + public void deleteTFoot(); + + /** + * Create a new table caption object or return an existing one. + * @return A <code>CAPTION</code> element. + */ + public HTMLElement createCaption(); + + /** + * Delete the table caption, if one exists. + */ + public void deleteCaption(); + + /** + * Insert a new empty row in the table. The new row is inserted + * immediately before and in the same section as the current + * <code>index</code>th row in the table. If <code>index</code> is -1 or + * equal to the number of rows, the new row is appended. In addition, + * when the table is empty the row is inserted into a <code>TBODY</code> + * which is created and inserted into the table.A table row cannot be + * empty according to [<a href='http://www.w3.org/TR/1999/REC-html401-19991224'>HTML 4.01</a>]. + * @param index The row number where to insert a new row. This index + * starts from 0 and is relative to the logical order (not document + * order) of all the rows contained inside the table. + * @return The newly created row. + * @exception DOMException + * INDEX_SIZE_ERR: Raised if the specified index is greater than the + * number of rows or if the index is a negative number other than -1. + * @version DOM Level 2 + */ + public HTMLElement insertRow(int index) + throws DOMException; + + /** + * Delete a table row. + * @param index The index of the row to be deleted. This index starts + * from 0 and is relative to the logical order (not document order) of + * all the rows contained inside the table. If the index is -1 the + * last row in the table is deleted. + * @exception DOMException + * INDEX_SIZE_ERR: Raised if the specified index is greater than or + * equal to the number of rows or if the index is a negative number + * other than -1. + * @version DOM Level 2 + */ + public void deleteRow(int index) + throws DOMException; + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLTableRowElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLTableRowElement.java new file mode 100644 index 000000000..8c3618f39 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLTableRowElement.java @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +import org.w3c.dom.DOMException; + +/** + * A row in a table. See the TR element definition in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLTableRowElement extends HTMLElement { + /** + * This is in logical order and not in document order. The + * <code>rowIndex</code> does take into account sections ( + * <code>THEAD</code>, <code>TFOOT</code>, or <code>TBODY</code>) within + * the table, placing <code>THEAD</code> rows first in the index, + * followed by <code>TBODY</code> rows, followed by <code>TFOOT</code> + * rows. + * @version DOM Level 2 + */ + public int getRowIndex(); + + /** + * The index of this row, relative to the current section ( + * <code>THEAD</code>, <code>TFOOT</code>, or <code>TBODY</code>), + * starting from 0. + * @version DOM Level 2 + */ + public int getSectionRowIndex(); + + /** + * The collection of cells in this row. + * @version DOM Level 2 + */ + public HTMLCollection getCells(); + + /** + * Horizontal alignment of data within cells of this row. See the align + * attribute definition in HTML 4.01. + */ + public String getAlign(); + /** + * Horizontal alignment of data within cells of this row. See the align + * attribute definition in HTML 4.01. + */ + public void setAlign(String align); + + /** + * Background color for rows. See the bgcolor attribute definition in HTML + * 4.01. This attribute is deprecated in HTML 4.01. + */ + public String getBgColor(); + /** + * Background color for rows. See the bgcolor attribute definition in HTML + * 4.01. This attribute is deprecated in HTML 4.01. + */ + public void setBgColor(String bgColor); + + /** + * Alignment character for cells in a column. See the char attribute + * definition in HTML 4.01. + */ + public String getCh(); + /** + * Alignment character for cells in a column. See the char attribute + * definition in HTML 4.01. + */ + public void setCh(String ch); + + /** + * Offset of alignment character. See the charoff attribute definition in + * HTML 4.01. + */ + public String getChOff(); + /** + * Offset of alignment character. See the charoff attribute definition in + * HTML 4.01. + */ + public void setChOff(String chOff); + + /** + * Vertical alignment of data within cells of this row. See the valign + * attribute definition in HTML 4.01. + */ + public String getVAlign(); + /** + * Vertical alignment of data within cells of this row. See the valign + * attribute definition in HTML 4.01. + */ + public void setVAlign(String vAlign); + + /** + * Insert an empty <code>TD</code> cell into this row. If + * <code>index</code> is -1 or equal to the number of cells, the new + * cell is appended. + * @param index The place to insert the cell, starting from 0. + * @return The newly created cell. + * @exception DOMException + * INDEX_SIZE_ERR: Raised if the specified <code>index</code> is greater + * than the number of cells or if the index is a negative number other + * than -1. + * @version DOM Level 2 + */ + public HTMLElement insertCell(int index) + throws DOMException; + + /** + * Delete a cell from the current row. + * @param index The index of the cell to delete, starting from 0. If the + * index is -1 the last cell in the row is deleted. + * @exception DOMException + * INDEX_SIZE_ERR: Raised if the specified <code>index</code> is greater + * than or equal to the number of cells or if the index is a negative + * number other than -1. + * @version DOM Level 2 + */ + public void deleteCell(int index) + throws DOMException; + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLTableSectionElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLTableSectionElement.java new file mode 100644 index 000000000..5e3d6e53f --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLTableSectionElement.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +import org.w3c.dom.DOMException; + +/** + * The <code>THEAD</code>, <code>TFOOT</code>, and <code>TBODY</code> + * elements. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLTableSectionElement extends HTMLElement { + /** + * Horizontal alignment of data in cells. See the <code>align</code> + * attribute for HTMLTheadElement for details. + */ + public String getAlign(); + /** + * Horizontal alignment of data in cells. See the <code>align</code> + * attribute for HTMLTheadElement for details. + */ + public void setAlign(String align); + + /** + * Alignment character for cells in a column. See the char attribute + * definition in HTML 4.01. + */ + public String getCh(); + /** + * Alignment character for cells in a column. See the char attribute + * definition in HTML 4.01. + */ + public void setCh(String ch); + + /** + * Offset of alignment character. See the charoff attribute definition in + * HTML 4.01. + */ + public String getChOff(); + /** + * Offset of alignment character. See the charoff attribute definition in + * HTML 4.01. + */ + public void setChOff(String chOff); + + /** + * Vertical alignment of data in cells. See the <code>valign</code> + * attribute for HTMLTheadElement for details. + */ + public String getVAlign(); + /** + * Vertical alignment of data in cells. See the <code>valign</code> + * attribute for HTMLTheadElement for details. + */ + public void setVAlign(String vAlign); + + /** + * The collection of rows in this table section. + */ + public HTMLCollection getRows(); + + /** + * Insert a row into this section. The new row is inserted immediately + * before the current <code>index</code>th row in this section. If + * <code>index</code> is -1 or equal to the number of rows in this + * section, the new row is appended. + * @param index The row number where to insert a new row. This index + * starts from 0 and is relative only to the rows contained inside + * this section, not all the rows in the table. + * @return The newly created row. + * @exception DOMException + * INDEX_SIZE_ERR: Raised if the specified index is greater than the + * number of rows of if the index is a negative number other than -1. + * @version DOM Level 2 + */ + public HTMLElement insertRow(int index) + throws DOMException; + + /** + * Delete a row from this section. + * @param index The index of the row to be deleted, or -1 to delete the + * last row. This index starts from 0 and is relative only to the rows + * contained inside this section, not all the rows in the table. + * @exception DOMException + * INDEX_SIZE_ERR: Raised if the specified index is greater than or + * equal to the number of rows or if the index is a negative number + * other than -1. + * @version DOM Level 2 + */ + public void deleteRow(int index) + throws DOMException; + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLTextAreaElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLTextAreaElement.java new file mode 100644 index 000000000..caabe4a19 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLTextAreaElement.java @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * Multi-line text field. See the TEXTAREA element definition in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLTextAreaElement extends HTMLElement { + /** + * Represents the contents of the element. The value of this attribute + * does not change if the contents of the corresponding form control, in + * an interactive user agent, changes. + * @version DOM Level 2 + */ + public String getDefaultValue(); + /** + * Represents the contents of the element. The value of this attribute + * does not change if the contents of the corresponding form control, in + * an interactive user agent, changes. + * @version DOM Level 2 + */ + public void setDefaultValue(String defaultValue); + + /** + * Returns the <code>FORM</code> element containing this control. Returns + * <code>null</code> if this control is not within the context of a + * form. + */ + public HTMLFormElement getForm(); + + /** + * A single character access key to give access to the form control. See + * the accesskey attribute definition in HTML 4.01. + */ + public String getAccessKey(); + /** + * A single character access key to give access to the form control. See + * the accesskey attribute definition in HTML 4.01. + */ + public void setAccessKey(String accessKey); + + /** + * Width of control (in characters). See the cols attribute definition in + * HTML 4.01. + */ + public int getCols(); + /** + * Width of control (in characters). See the cols attribute definition in + * HTML 4.01. + */ + public void setCols(int cols); + + /** + * The control is unavailable in this context. See the disabled attribute + * definition in HTML 4.01. + */ + public boolean getDisabled(); + /** + * The control is unavailable in this context. See the disabled attribute + * definition in HTML 4.01. + */ + public void setDisabled(boolean disabled); + + /** + * Form control or object name when submitted with a form. See the name + * attribute definition in HTML 4.01. + */ + public String getName(); + /** + * Form control or object name when submitted with a form. See the name + * attribute definition in HTML 4.01. + */ + public void setName(String name); + + /** + * This control is read-only. See the readonly attribute definition in + * HTML 4.01. + */ + public boolean getReadOnly(); + /** + * This control is read-only. See the readonly attribute definition in + * HTML 4.01. + */ + public void setReadOnly(boolean readOnly); + + /** + * Number of text rows. See the rows attribute definition in HTML 4.01. + */ + public int getRows(); + /** + * Number of text rows. See the rows attribute definition in HTML 4.01. + */ + public void setRows(int rows); + + /** + * Index that represents the element's position in the tabbing order. See + * the tabindex attribute definition in HTML 4.01. + */ + public int getTabIndex(); + /** + * Index that represents the element's position in the tabbing order. See + * the tabindex attribute definition in HTML 4.01. + */ + public void setTabIndex(int tabIndex); + + /** + * The type of this form control. This the string "textarea". + */ + public String getType(); + + /** + * Represents the current contents of the corresponding form control, in + * an interactive user agent. Changing this attribute changes the + * contents of the form control, but does not change the contents of the + * element. If the entirety of the data can not fit into a single + * <code>DOMString</code>, the implementation may truncate the data. + */ + public String getValue(); + /** + * Represents the current contents of the corresponding form control, in + * an interactive user agent. Changing this attribute changes the + * contents of the form control, but does not change the contents of the + * element. If the entirety of the data can not fit into a single + * <code>DOMString</code>, the implementation may truncate the data. + */ + public void setValue(String value); + + /** + * Removes keyboard focus from this element. + */ + public void blur(); + + /** + * Gives keyboard focus to this element. + */ + public void focus(); + + /** + * Select the contents of the <code>TEXTAREA</code>. + */ + public void select(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLTitleElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLTitleElement.java new file mode 100644 index 000000000..a86b3a926 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLTitleElement.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * The document title. See the TITLE element definition in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLTitleElement extends HTMLElement { + /** + * The specified title as a string. + */ + public String getText(); + /** + * The specified title as a string. + */ + public void setText(String text); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLUListElement.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLUListElement.java new file mode 100644 index 000000000..e5828fd39 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/html2/HTMLUListElement.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.html2; + +/** + * Unordered list. See the UL element definition in HTML 4.01. + * <p>See also the <a href='http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109'>Document Object Model (DOM) Level 2 HTML Specification</a>. + */ +public interface HTMLUListElement extends HTMLElement { + /** + * Reduce spacing between list items. See the compact attribute definition + * in HTML 4.01. This attribute is deprecated in HTML 4.01. + */ + public boolean getCompact(); + /** + * Reduce spacing between list items. See the compact attribute definition + * in HTML 4.01. This attribute is deprecated in HTML 4.01. + */ + public void setCompact(boolean compact); + + /** + * Bullet style. See the type attribute definition in HTML 4.01. This + * attribute is deprecated in HTML 4.01. + */ + public String getType(); + /** + * Bullet style. See the type attribute definition in HTML 4.01. This + * attribute is deprecated in HTML 4.01. + */ + public void setType(String type); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/ls/DOMImplementationLS.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/ls/DOMImplementationLS.java new file mode 100644 index 000000000..4d1b0971d --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/ls/DOMImplementationLS.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom.ls; + +import org.w3c.dom.DOMException; + +/** + * <code>DOMImplementationLS</code> contains the factory methods for creating + * Load and Save objects. + * <p> The expectation is that an instance of the + * <code>DOMImplementationLS</code> interface can be obtained by using + * binding-specific casting methods on an instance of the + * <code>DOMImplementation</code> interface or, if the <code>Document</code> + * supports the feature <code>"Core"</code> version <code>"3.0"</code> + * defined in [<a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>DOM Level 3 Core</a>] + * , by using the method <code>DOMImplementation.getFeature</code> with + * parameter values <code>"LS"</code> (or <code>"LS-Async"</code>) and + * <code>"3.0"</code> (respectively). + * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-LS-20040407'>Document Object Model (DOM) Level 3 Load +and Save Specification</a>. + */ +public interface DOMImplementationLS { + // DOMImplementationLSMode + /** + * Create a synchronous <code>LSParser</code>. + */ + public static final short MODE_SYNCHRONOUS = 1; + /** + * Create an asynchronous <code>LSParser</code>. + */ + public static final short MODE_ASYNCHRONOUS = 2; + + /** + * Create a new <code>LSParser</code>. The newly constructed parser may + * then be configured by means of its <code>DOMConfiguration</code> + * object, and used to parse documents by means of its <code>parse</code> + * method. + * @param mode The <code>mode</code> argument is either + * <code>MODE_SYNCHRONOUS</code> or <code>MODE_ASYNCHRONOUS</code>, if + * <code>mode</code> is <code>MODE_SYNCHRONOUS</code> then the + * <code>LSParser</code> that is created will operate in synchronous + * mode, if it's <code>MODE_ASYNCHRONOUS</code> then the + * <code>LSParser</code> that is created will operate in asynchronous + * mode. + * @param schemaType An absolute URI representing the type of the schema + * language used during the load of a <code>Document</code> using the + * newly created <code>LSParser</code>. Note that no lexical checking + * is done on the absolute URI. In order to create a + * <code>LSParser</code> for any kind of schema types (i.e. the + * LSParser will be free to use any schema found), use the value + * <code>null</code>. + * <p ><b>Note:</b> For W3C XML Schema [<a href='http://www.w3.org/TR/2001/REC-xmlschema-1-20010502/'>XML Schema Part 1</a>] + * , applications must use the value + * <code>"http://www.w3.org/2001/XMLSchema"</code>. For XML DTD [<a href='http://www.w3.org/TR/2004/REC-xml-20040204'>XML 1.0</a>], + * applications must use the value + * <code>"http://www.w3.org/TR/REC-xml"</code>. Other Schema languages + * are outside the scope of the W3C and therefore should recommend an + * absolute URI in order to use this method. + * @return The newly created <code>LSParser</code> object. This + * <code>LSParser</code> is either synchronous or asynchronous + * depending on the value of the <code>mode</code> argument. + * <p ><b>Note:</b> By default, the newly created <code>LSParser</code> + * does not contain a <code>DOMErrorHandler</code>, i.e. the value of + * the "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-error-handler'> + * error-handler</a>" configuration parameter is <code>null</code>. However, implementations + * may provide a default error handler at creation time. In that case, + * the initial value of the <code>"error-handler"</code> configuration + * parameter on the new <code>LSParser</code> object contains a + * reference to the default error handler. + * @exception DOMException + * NOT_SUPPORTED_ERR: Raised if the requested mode or schema type is + * not supported. + */ + public LSParser createLSParser(short mode, + String schemaType) + throws DOMException; + + /** + * Create a new <code>LSSerializer</code> object. + * @return The newly created <code>LSSerializer</code> object. + * <p ><b>Note:</b> By default, the newly created + * <code>LSSerializer</code> has no <code>DOMErrorHandler</code>, i.e. + * the value of the <code>"error-handler"</code> configuration + * parameter is <code>null</code>. However, implementations may + * provide a default error handler at creation time. In that case, the + * initial value of the <code>"error-handler"</code> configuration + * parameter on the new <code>LSSerializer</code> object contains a + * reference to the default error handler. + */ + public LSSerializer createLSSerializer(); + + /** + * Create a new empty input source object where + * <code>LSInput.characterStream</code>, <code>LSInput.byteStream</code> + * , <code>LSInput.stringData</code> <code>LSInput.systemId</code>, + * <code>LSInput.publicId</code>, <code>LSInput.baseURI</code>, and + * <code>LSInput.encoding</code> are null, and + * <code>LSInput.certifiedText</code> is false. + * @return The newly created input object. + */ + public LSInput createLSInput(); + + /** + * Create a new empty output destination object where + * <code>LSOutput.characterStream</code>, + * <code>LSOutput.byteStream</code>, <code>LSOutput.systemId</code>, + * <code>LSOutput.encoding</code> are null. + * @return The newly created output object. + */ + public LSOutput createLSOutput(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/ls/LSException.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/ls/LSException.java new file mode 100644 index 000000000..677ad385c --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/ls/LSException.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom.ls; + +/** + * Parser or write operations may throw an <code>LSException</code> if the + * processing is stopped. The processing can be stopped due to a + * <code>DOMError</code> with a severity of + * <code>DOMError.SEVERITY_FATAL_ERROR</code> or a non recovered + * <code>DOMError.SEVERITY_ERROR</code>, or if + * <code>DOMErrorHandler.handleError()</code> returned <code>false</code>. + * <p ><b>Note:</b> As suggested in the definition of the constants in the + * <code>DOMError</code> interface, a DOM implementation may choose to + * continue after a fatal error, but the resulting DOM tree is then + * implementation dependent. + * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-LS-20040407'>Document Object Model (DOM) Level 3 Load +and Save Specification</a>. + */ +public class LSException extends RuntimeException { + public LSException(short code, String message) { + super(message); + this.code = code; + } + public short code; + // LSExceptionCode + /** + * If an attempt was made to load a document, or an XML Fragment, using + * <code>LSParser</code> and the processing has been stopped. + */ + public static final short PARSE_ERR = 81; + /** + * If an attempt was made to serialize a <code>Node</code> using + * <code>LSSerializer</code> and the processing has been stopped. + */ + public static final short SERIALIZE_ERR = 82; + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/ls/LSInput.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/ls/LSInput.java new file mode 100644 index 000000000..bba1792cd --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/ls/LSInput.java @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom.ls; + +/** + * This interface represents an input source for data. + * <p> This interface allows an application to encapsulate information about + * an input source in a single object, which may include a public + * identifier, a system identifier, a byte stream (possibly with a specified + * encoding), a base URI, and/or a character stream. + * <p> The exact definitions of a byte stream and a character stream are + * binding dependent. + * <p> The application is expected to provide objects that implement this + * interface whenever such objects are needed. The application can either + * provide its own objects that implement this interface, or it can use the + * generic factory method <code>DOMImplementationLS.createLSInput()</code> + * to create objects that implement this interface. + * <p> The <code>LSParser</code> will use the <code>LSInput</code> object to + * determine how to read data. The <code>LSParser</code> will look at the + * different inputs specified in the <code>LSInput</code> in the following + * order to know which one to read from, the first one that is not null and + * not an empty string will be used: + * <ol> + * <li> <code>LSInput.characterStream</code> + * </li> + * <li> + * <code>LSInput.byteStream</code> + * </li> + * <li> <code>LSInput.stringData</code> + * </li> + * <li> + * <code>LSInput.systemId</code> + * </li> + * <li> <code>LSInput.publicId</code> + * </li> + * </ol> + * <p> If all inputs are null, the <code>LSParser</code> will report a + * <code>DOMError</code> with its <code>DOMError.type</code> set to + * <code>"no-input-specified"</code> and its <code>DOMError.severity</code> + * set to <code>DOMError.SEVERITY_FATAL_ERROR</code>. + * <p> <code>LSInput</code> objects belong to the application. The DOM + * implementation will never modify them (though it may make copies and + * modify the copies, if necessary). + * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-LS-20040407'>Document Object Model (DOM) Level 3 Load +and Save Specification</a>. + */ +public interface LSInput { + /** + * An attribute of a language and binding dependent type that represents + * a stream of 16-bit units. The application must encode the stream + * using UTF-16 (defined in [Unicode] and in [ISO/IEC 10646]). It is not a requirement to have an XML declaration when + * using character streams. If an XML declaration is present, the value + * of the encoding attribute will be ignored. + */ + public java.io.Reader getCharacterStream(); + /** + * An attribute of a language and binding dependent type that represents + * a stream of 16-bit units. The application must encode the stream + * using UTF-16 (defined in [Unicode] and in [ISO/IEC 10646]). It is not a requirement to have an XML declaration when + * using character streams. If an XML declaration is present, the value + * of the encoding attribute will be ignored. + */ + public void setCharacterStream(java.io.Reader characterStream); + + /** + * An attribute of a language and binding dependent type that represents + * a stream of bytes. + * <br> If the application knows the character encoding of the byte + * stream, it should set the encoding attribute. Setting the encoding in + * this way will override any encoding specified in an XML declaration + * in the data. + */ + public java.io.InputStream getByteStream(); + /** + * An attribute of a language and binding dependent type that represents + * a stream of bytes. + * <br> If the application knows the character encoding of the byte + * stream, it should set the encoding attribute. Setting the encoding in + * this way will override any encoding specified in an XML declaration + * in the data. + */ + public void setByteStream(java.io.InputStream byteStream); + + /** + * String data to parse. If provided, this will always be treated as a + * sequence of 16-bit units (UTF-16 encoded characters). It is not a + * requirement to have an XML declaration when using + * <code>stringData</code>. If an XML declaration is present, the value + * of the encoding attribute will be ignored. + */ + public String getStringData(); + /** + * String data to parse. If provided, this will always be treated as a + * sequence of 16-bit units (UTF-16 encoded characters). It is not a + * requirement to have an XML declaration when using + * <code>stringData</code>. If an XML declaration is present, the value + * of the encoding attribute will be ignored. + */ + public void setStringData(String stringData); + + /** + * The system identifier, a URI reference [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>], for this + * input source. The system identifier is optional if there is a byte + * stream, a character stream, or string data. It is still useful to + * provide one, since the application will use it to resolve any + * relative URIs and can include it in error messages and warnings. (The + * LSParser will only attempt to fetch the resource identified by the + * URI reference if there is no other input available in the input + * source.) + * <br> If the application knows the character encoding of the object + * pointed to by the system identifier, it can set the encoding using + * the <code>encoding</code> attribute. + * <br> If the specified system ID is a relative URI reference (see + * section 5 in [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>]), the DOM + * implementation will attempt to resolve the relative URI with the + * <code>baseURI</code> as the base, if that fails, the behavior is + * implementation dependent. + */ + public String getSystemId(); + /** + * The system identifier, a URI reference [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>], for this + * input source. The system identifier is optional if there is a byte + * stream, a character stream, or string data. It is still useful to + * provide one, since the application will use it to resolve any + * relative URIs and can include it in error messages and warnings. (The + * LSParser will only attempt to fetch the resource identified by the + * URI reference if there is no other input available in the input + * source.) + * <br> If the application knows the character encoding of the object + * pointed to by the system identifier, it can set the encoding using + * the <code>encoding</code> attribute. + * <br> If the specified system ID is a relative URI reference (see + * section 5 in [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>]), the DOM + * implementation will attempt to resolve the relative URI with the + * <code>baseURI</code> as the base, if that fails, the behavior is + * implementation dependent. + */ + public void setSystemId(String systemId); + + /** + * The public identifier for this input source. This may be mapped to an + * input source using an implementation dependent mechanism (such as + * catalogues or other mappings). The public identifier, if specified, + * may also be reported as part of the location information when errors + * are reported. + */ + public String getPublicId(); + /** + * The public identifier for this input source. This may be mapped to an + * input source using an implementation dependent mechanism (such as + * catalogues or other mappings). The public identifier, if specified, + * may also be reported as part of the location information when errors + * are reported. + */ + public void setPublicId(String publicId); + + /** + * The base URI to be used (see section 5.1.4 in [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>]) for + * resolving a relative <code>systemId</code> to an absolute URI. + * <br> If, when used, the base URI is itself a relative URI, an empty + * string, or null, the behavior is implementation dependent. + */ + public String getBaseURI(); + /** + * The base URI to be used (see section 5.1.4 in [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>]) for + * resolving a relative <code>systemId</code> to an absolute URI. + * <br> If, when used, the base URI is itself a relative URI, an empty + * string, or null, the behavior is implementation dependent. + */ + public void setBaseURI(String baseURI); + + /** + * The character encoding, if known. The encoding must be a string + * acceptable for an XML encoding declaration ([<a href='http://www.w3.org/TR/2004/REC-xml-20040204'>XML 1.0</a>] section + * 4.3.3 "Character Encoding in Entities"). + * <br> This attribute has no effect when the application provides a + * character stream or string data. For other sources of input, an + * encoding specified by means of this attribute will override any + * encoding specified in the XML declaration or the Text declaration, or + * an encoding obtained from a higher level protocol, such as HTTP [<a href='http://www.ietf.org/rfc/rfc2616.txt'>IETF RFC 2616</a>]. + */ + public String getEncoding(); + /** + * The character encoding, if known. The encoding must be a string + * acceptable for an XML encoding declaration ([<a href='http://www.w3.org/TR/2004/REC-xml-20040204'>XML 1.0</a>] section + * 4.3.3 "Character Encoding in Entities"). + * <br> This attribute has no effect when the application provides a + * character stream or string data. For other sources of input, an + * encoding specified by means of this attribute will override any + * encoding specified in the XML declaration or the Text declaration, or + * an encoding obtained from a higher level protocol, such as HTTP [<a href='http://www.ietf.org/rfc/rfc2616.txt'>IETF RFC 2616</a>]. + */ + public void setEncoding(String encoding); + + /** + * If set to true, assume that the input is certified (see section 2.13 + * in [<a href='http://www.w3.org/TR/2004/REC-xml11-20040204/'>XML 1.1</a>]) when + * parsing [<a href='http://www.w3.org/TR/2004/REC-xml11-20040204/'>XML 1.1</a>]. + */ + public boolean getCertifiedText(); + /** + * If set to true, assume that the input is certified (see section 2.13 + * in [<a href='http://www.w3.org/TR/2004/REC-xml11-20040204/'>XML 1.1</a>]) when + * parsing [<a href='http://www.w3.org/TR/2004/REC-xml11-20040204/'>XML 1.1</a>]. + */ + public void setCertifiedText(boolean certifiedText); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/ls/LSLoadEvent.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/ls/LSLoadEvent.java new file mode 100644 index 000000000..0140b4123 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/ls/LSLoadEvent.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom.ls; + +import org.w3c.dom.Document; +import org.w3c.dom.events.Event; + +/** + * This interface represents a load event object that signals the completion + * of a document load. + * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-LS-20040407'>Document Object Model (DOM) Level 3 Load +and Save Specification</a>. + */ +public interface LSLoadEvent extends Event { + /** + * The document that finished loading. + */ + public Document getNewDocument(); + + /** + * The input source that was parsed. + */ + public LSInput getInput(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/ls/LSOutput.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/ls/LSOutput.java new file mode 100644 index 000000000..789b95a93 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/ls/LSOutput.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom.ls; + +/** + * This interface represents an output destination for data. + * <p> This interface allows an application to encapsulate information about + * an output destination in a single object, which may include a URI, a byte + * stream (possibly with a specified encoding), a base URI, and/or a + * character stream. + * <p> The exact definitions of a byte stream and a character stream are + * binding dependent. + * <p> The application is expected to provide objects that implement this + * interface whenever such objects are needed. The application can either + * provide its own objects that implement this interface, or it can use the + * generic factory method <code>DOMImplementationLS.createLSOutput()</code> + * to create objects that implement this interface. + * <p> The <code>LSSerializer</code> will use the <code>LSOutput</code> object + * to determine where to serialize the output to. The + * <code>LSSerializer</code> will look at the different outputs specified in + * the <code>LSOutput</code> in the following order to know which one to + * output to, the first one that is not null and not an empty string will be + * used: + * <ol> + * <li> <code>LSOutput.characterStream</code> + * </li> + * <li> + * <code>LSOutput.byteStream</code> + * </li> + * <li> <code>LSOutput.systemId</code> + * </li> + * </ol> + * <p> <code>LSOutput</code> objects belong to the application. The DOM + * implementation will never modify them (though it may make copies and + * modify the copies, if necessary). + * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-LS-20040407'>Document Object Model (DOM) Level 3 Load +and Save Specification</a>. + */ +public interface LSOutput { + /** + * An attribute of a language and binding dependent type that represents + * a writable stream to which 16-bit units can be output. + */ + public java.io.Writer getCharacterStream(); + /** + * An attribute of a language and binding dependent type that represents + * a writable stream to which 16-bit units can be output. + */ + public void setCharacterStream(java.io.Writer characterStream); + + /** + * An attribute of a language and binding dependent type that represents + * a writable stream of bytes. + */ + public java.io.OutputStream getByteStream(); + /** + * An attribute of a language and binding dependent type that represents + * a writable stream of bytes. + */ + public void setByteStream(java.io.OutputStream byteStream); + + /** + * The system identifier, a URI reference [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>], for this + * output destination. + * <br> If the system ID is a relative URI reference (see section 5 in [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>]), the + * behavior is implementation dependent. + */ + public String getSystemId(); + /** + * The system identifier, a URI reference [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>], for this + * output destination. + * <br> If the system ID is a relative URI reference (see section 5 in [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>]), the + * behavior is implementation dependent. + */ + public void setSystemId(String systemId); + + /** + * The character encoding to use for the output. The encoding must be a + * string acceptable for an XML encoding declaration ([<a href='http://www.w3.org/TR/2004/REC-xml-20040204'>XML 1.0</a>] section + * 4.3.3 "Character Encoding in Entities"), it is recommended that + * character encodings registered (as charsets) with the Internet + * Assigned Numbers Authority [<a href='ftp://ftp.isi.edu/in-notes/iana/assignments/character-sets'>IANA-CHARSETS</a>] + * should be referred to using their registered names. + */ + public String getEncoding(); + /** + * The character encoding to use for the output. The encoding must be a + * string acceptable for an XML encoding declaration ([<a href='http://www.w3.org/TR/2004/REC-xml-20040204'>XML 1.0</a>] section + * 4.3.3 "Character Encoding in Entities"), it is recommended that + * character encodings registered (as charsets) with the Internet + * Assigned Numbers Authority [<a href='ftp://ftp.isi.edu/in-notes/iana/assignments/character-sets'>IANA-CHARSETS</a>] + * should be referred to using their registered names. + */ + public void setEncoding(String encoding); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/ls/LSParser.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/ls/LSParser.java new file mode 100644 index 000000000..41781fa33 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/ls/LSParser.java @@ -0,0 +1,466 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom.ls; + +import org.w3c.dom.Document; +import org.w3c.dom.DOMConfiguration; +import org.w3c.dom.Node; +import org.w3c.dom.DOMException; + +/** + * An interface to an object that is able to build, or augment, a DOM tree + * from various input sources. + * <p> <code>LSParser</code> provides an API for parsing XML and building the + * corresponding DOM document structure. A <code>LSParser</code> instance + * can be obtained by invoking the + * <code>DOMImplementationLS.createLSParser()</code> method. + * <p> As specified in [<a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>DOM Level 3 Core</a>] + * , when a document is first made available via the LSParser: + * <ul> + * <li> there will + * never be two adjacent nodes of type NODE_TEXT, and there will never be + * empty text nodes. + * </li> + * <li> it is expected that the <code>value</code> and + * <code>nodeValue</code> attributes of an <code>Attr</code> node initially + * return the <a href='http://www.w3.org/TR/2004/REC-xml-20040204#AVNormalize'>XML 1.0 + * normalized value</a>. However, if the parameters "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-validate-if-schema'> + * validate-if-schema</a>" and "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-datatype-normalization'> + * datatype-normalization</a>" are set to <code>true</code>, depending on the attribute normalization + * used, the attribute values may differ from the ones obtained by the XML + * 1.0 attribute normalization. If the parameters "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-datatype-normalization'> + * datatype-normalization</a>" is set to <code>false</code>, the XML 1.0 attribute normalization is + * guaranteed to occur, and if the attributes list does not contain + * namespace declarations, the <code>attributes</code> attribute on + * <code>Element</code> node represents the property <b>[attributes]</b> defined in [<a href='http://www.w3.org/TR/2004/REC-xml-infoset-20040204/'>XML Information Set</a>] + * . + * </li> + * </ul> + * <p> Asynchronous <code>LSParser</code> objects are expected to also + * implement the <code>events::EventTarget</code> interface so that event + * listeners can be registered on asynchronous <code>LSParser</code> + * objects. + * <p> Events supported by asynchronous <code>LSParser</code> objects are: + * <dl> + * <dt>load</dt> + * <dd> + * The <code>LSParser</code> finishes to load the document. See also the + * definition of the <code>LSLoadEvent</code> interface. </dd> + * <dt>progress</dt> + * <dd> The + * <code>LSParser</code> signals progress as data is parsed. This + * specification does not attempt to define exactly when progress events + * should be dispatched. That is intentionally left as + * implementation-dependent. Here is one example of how an application might + * dispatch progress events: Once the parser starts receiving data, a + * progress event is dispatched to indicate that the parsing starts. From + * there on, a progress event is dispatched for every 4096 bytes of data + * that is received and processed. This is only one example, though, and + * implementations can choose to dispatch progress events at any time while + * parsing, or not dispatch them at all. See also the definition of the + * <code>LSProgressEvent</code> interface. </dd> + * </dl> + * <p ><b>Note:</b> All events defined in this specification use the + * namespace URI <code>"http://www.w3.org/2002/DOMLS"</code>. + * <p> While parsing an input source, errors are reported to the application + * through the error handler (<code>LSParser.domConfig</code>'s "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-error-handler'> + * error-handler</a>" parameter). This specification does in no way try to define all possible + * errors that can occur while parsing XML, or any other markup, but some + * common error cases are defined. The types (<code>DOMError.type</code>) of + * errors and warnings defined by this specification are: + * <dl> + * <dt> + * <code>"check-character-normalization-failure" [error]</code> </dt> + * <dd> Raised if + * the parameter "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-check-character-normalization'> + * check-character-normalization</a>" is set to true and a string is encountered that fails normalization + * checking. </dd> + * <dt><code>"doctype-not-allowed" [fatal]</code></dt> + * <dd> Raised if the + * configuration parameter "disallow-doctype" is set to <code>true</code> + * and a doctype is encountered. </dd> + * <dt><code>"no-input-specified" [fatal]</code></dt> + * <dd> + * Raised when loading a document and no input is specified in the + * <code>LSInput</code> object. </dd> + * <dt> + * <code>"pi-base-uri-not-preserved" [warning]</code></dt> + * <dd> Raised if a processing + * instruction is encountered in a location where the base URI of the + * processing instruction can not be preserved. One example of a case where + * this warning will be raised is if the configuration parameter "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-entities'> + * entities</a>" is set to <code>false</code> and the following XML file is parsed: + * <pre> + * <!DOCTYPE root [ <!ENTITY e SYSTEM 'subdir/myentity.ent' ]> + * <root> &e; </root></pre> + * And <code>subdir/myentity.ent</code> + * contains: + * <pre><one> <two/> </one> <?pi 3.14159?> + * <more/></pre> + * </dd> + * <dt><code>"unbound-prefix-in-entity" [warning]</code></dt> + * <dd> An + * implementation dependent warning that may be raised if the configuration + * parameter "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-namespaces'> + * namespaces</a>" is set to <code>true</code> and an unbound namespace prefix is + * encountered in an entity's replacement text. Raising this warning is not + * enforced since some existing parsers may not recognize unbound namespace + * prefixes in the replacement text of entities. </dd> + * <dt> + * <code>"unknown-character-denormalization" [fatal]</code></dt> + * <dd> Raised if the + * configuration parameter "ignore-unknown-character-denormalizations" is + * set to <code>false</code> and a character is encountered for which the + * processor cannot determine the normalization properties. </dd> + * <dt> + * <code>"unsupported-encoding" [fatal]</code></dt> + * <dd> Raised if an unsupported + * encoding is encountered. </dd> + * <dt><code>"unsupported-media-type" [fatal]</code></dt> + * <dd> + * Raised if the configuration parameter "supported-media-types-only" is set + * to <code>true</code> and an unsupported media type is encountered. </dd> + * </dl> + * <p> In addition to raising the defined errors and warnings, implementations + * are expected to raise implementation specific errors and warnings for any + * other error and warning cases such as IO errors (file not found, + * permission denied,...), XML well-formedness errors, and so on. + * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-LS-20040407'>Document Object Model (DOM) Level 3 Load +and Save Specification</a>. + */ +public interface LSParser { + /** + * The <code>DOMConfiguration</code> object used when parsing an input + * source. This <code>DOMConfiguration</code> is specific to the parse + * operation. No parameter values from this <code>DOMConfiguration</code> + * object are passed automatically to the <code>DOMConfiguration</code> + * object on the <code>Document</code> that is created, or used, by the + * parse operation. The DOM application is responsible for passing any + * needed parameter values from this <code>DOMConfiguration</code> + * object to the <code>DOMConfiguration</code> object referenced by the + * <code>Document</code> object. + * <br> In addition to the parameters recognized in on the <a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#DOMConfiguration'> + * DOMConfiguration</a> interface defined in [<a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>DOM Level 3 Core</a>] + * , the <code>DOMConfiguration</code> objects for <code>LSParser</code> + * add or modify the following parameters: + * <dl> + * <dt> + * <code>"charset-overrides-xml-encoding"</code></dt> + * <dd> + * <dl> + * <dt><code>true</code></dt> + * <dd>[<em>optional</em>] (<em>default</em>) If a higher level protocol such as HTTP [<a href='http://www.ietf.org/rfc/rfc2616.txt'>IETF RFC 2616</a>] provides an + * indication of the character encoding of the input stream being + * processed, that will override any encoding specified in the XML + * declaration or the Text declaration (see also section 4.3.3, + * "Character Encoding in Entities", in [<a href='http://www.w3.org/TR/2004/REC-xml-20040204'>XML 1.0</a>]). + * Explicitly setting an encoding in the <code>LSInput</code> overrides + * any encoding from the protocol. </dd> + * <dt><code>false</code></dt> + * <dd>[<em>required</em>] The parser ignores any character set encoding information from + * higher-level protocols. </dd> + * </dl></dd> + * <dt><code>"disallow-doctype"</code></dt> + * <dd> + * <dl> + * <dt> + * <code>true</code></dt> + * <dd>[<em>optional</em>] Throw a fatal <b>"doctype-not-allowed"</b> error if a doctype node is found while parsing the document. This is + * useful when dealing with things like SOAP envelopes where doctype + * nodes are not allowed. </dd> + * <dt><code>false</code></dt> + * <dd>[<em>required</em>] (<em>default</em>) Allow doctype nodes in the document. </dd> + * </dl></dd> + * <dt> + * <code>"ignore-unknown-character-denormalizations"</code></dt> + * <dd> + * <dl> + * <dt> + * <code>true</code></dt> + * <dd>[<em>required</em>] (<em>default</em>) If, while verifying full normalization when [<a href='http://www.w3.org/TR/2004/REC-xml11-20040204/'>XML 1.1</a>] is + * supported, a processor encounters characters for which it cannot + * determine the normalization properties, then the processor will + * ignore any possible denormalizations caused by these characters. + * This parameter is ignored for [<a href='http://www.w3.org/TR/2004/REC-xml-20040204'>XML 1.0</a>]. </dd> + * <dt> + * <code>false</code></dt> + * <dd>[<em>optional</em>] Report an fatal <b>"unknown-character-denormalization"</b> error if a character is encountered for which the processor cannot + * determine the normalization properties. </dd> + * </dl></dd> + * <dt><code>"infoset"</code></dt> + * <dd> See + * the definition of <code>DOMConfiguration</code> for a description of + * this parameter. Unlike in [<a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>DOM Level 3 Core</a>] + * , this parameter will default to <code>true</code> for + * <code>LSParser</code>. </dd> + * <dt><code>"namespaces"</code></dt> + * <dd> + * <dl> + * <dt><code>true</code></dt> + * <dd>[<em>required</em>] (<em>default</em>) Perform the namespace processing as defined in [<a href='http://www.w3.org/TR/1999/REC-xml-names-19990114/'>XML Namespaces</a>] + * and [<a href='http://www.w3.org/TR/2004/REC-xml-names11-20040204/'>XML Namespaces 1.1</a>] + * . </dd> + * <dt><code>false</code></dt> + * <dd>[<em>optional</em>] Do not perform the namespace processing. </dd> + * </dl></dd> + * <dt> + * <code>"resource-resolver"</code></dt> + * <dd>[<em>required</em>] A reference to a <code>LSResourceResolver</code> object, or null. If + * the value of this parameter is not null when an external resource + * (such as an external XML entity or an XML schema location) is + * encountered, the implementation will request that the + * <code>LSResourceResolver</code> referenced in this parameter resolves + * the resource. </dd> + * <dt><code>"supported-media-types-only"</code></dt> + * <dd> + * <dl> + * <dt> + * <code>true</code></dt> + * <dd>[<em>optional</em>] Check that the media type of the parsed resource is a supported media + * type. If an unsupported media type is encountered, a fatal error of + * type <b>"unsupported-media-type"</b> will be raised. The media types defined in [<a href='http://www.ietf.org/rfc/rfc3023.txt'>IETF RFC 3023</a>] must always + * be accepted. </dd> + * <dt><code>false</code></dt> + * <dd>[<em>required</em>] (<em>default</em>) Accept any media type. </dd> + * </dl></dd> + * <dt><code>"validate"</code></dt> + * <dd> See the definition of + * <code>DOMConfiguration</code> for a description of this parameter. + * Unlike in [<a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>DOM Level 3 Core</a>] + * , the processing of the internal subset is always accomplished, even + * if this parameter is set to <code>false</code>. </dd> + * <dt> + * <code>"validate-if-schema"</code></dt> + * <dd> See the definition of + * <code>DOMConfiguration</code> for a description of this parameter. + * Unlike in [<a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>DOM Level 3 Core</a>] + * , the processing of the internal subset is always accomplished, even + * if this parameter is set to <code>false</code>. </dd> + * <dt> + * <code>"well-formed"</code></dt> + * <dd> See the definition of + * <code>DOMConfiguration</code> for a description of this parameter. + * Unlike in [<a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>DOM Level 3 Core</a>] + * , this parameter cannot be set to <code>false</code>. </dd> + * </dl> + */ + public DOMConfiguration getDomConfig(); + + /** + * When a filter is provided, the implementation will call out to the + * filter as it is constructing the DOM tree structure. The filter can + * choose to remove elements from the document being constructed, or to + * terminate the parsing early. + * <br> The filter is invoked after the operations requested by the + * <code>DOMConfiguration</code> parameters have been applied. For + * example, if "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-validate'> + * validate</a>" is set to <code>true</code>, the validation is done before invoking the + * filter. + */ + public LSParserFilter getFilter(); + /** + * When a filter is provided, the implementation will call out to the + * filter as it is constructing the DOM tree structure. The filter can + * choose to remove elements from the document being constructed, or to + * terminate the parsing early. + * <br> The filter is invoked after the operations requested by the + * <code>DOMConfiguration</code> parameters have been applied. For + * example, if "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-validate'> + * validate</a>" is set to <code>true</code>, the validation is done before invoking the + * filter. + */ + public void setFilter(LSParserFilter filter); + + /** + * <code>true</code> if the <code>LSParser</code> is asynchronous, + * <code>false</code> if it is synchronous. + */ + public boolean getAsync(); + + /** + * <code>true</code> if the <code>LSParser</code> is currently busy + * loading a document, otherwise <code>false</code>. + */ + public boolean getBusy(); + + /** + * Parse an XML document from a resource identified by a + * <code>LSInput</code>. + * @param input The <code>LSInput</code> from which the source of the + * document is to be read. + * @return If the <code>LSParser</code> is a synchronous + * <code>LSParser</code>, the newly created and populated + * <code>Document</code> is returned. If the <code>LSParser</code> is + * asynchronous, <code>null</code> is returned since the document + * object may not yet be constructed when this method returns. + * @exception DOMException + * INVALID_STATE_ERR: Raised if the <code>LSParser</code>'s + * <code>LSParser.busy</code> attribute is <code>true</code>. + * @exception LSException + * PARSE_ERR: Raised if the <code>LSParser</code> was unable to load + * the XML document. DOM applications should attach a + * <code>DOMErrorHandler</code> using the parameter "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-error-handler'> + * error-handler</a>" if they wish to get details on the error. + */ + public Document parse(LSInput input) + throws DOMException, LSException; + + /** + * Parse an XML document from a location identified by a URI reference [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>]. If the URI + * contains a fragment identifier (see section 4.1 in [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>]), the + * behavior is not defined by this specification, future versions of + * this specification may define the behavior. + * @param uri The location of the XML document to be read. + * @return If the <code>LSParser</code> is a synchronous + * <code>LSParser</code>, the newly created and populated + * <code>Document</code> is returned, or <code>null</code> if an error + * occured. If the <code>LSParser</code> is asynchronous, + * <code>null</code> is returned since the document object may not yet + * be constructed when this method returns. + * @exception DOMException + * INVALID_STATE_ERR: Raised if the <code>LSParser.busy</code> + * attribute is <code>true</code>. + * @exception LSException + * PARSE_ERR: Raised if the <code>LSParser</code> was unable to load + * the XML document. DOM applications should attach a + * <code>DOMErrorHandler</code> using the parameter "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-error-handler'> + * error-handler</a>" if they wish to get details on the error. + */ + public Document parseURI(String uri) + throws DOMException, LSException; + + // ACTION_TYPES + /** + * Append the result of the parse operation as children of the context + * node. For this action to work, the context node must be an + * <code>Element</code> or a <code>DocumentFragment</code>. + */ + public static final short ACTION_APPEND_AS_CHILDREN = 1; + /** + * Replace all the children of the context node with the result of the + * parse operation. For this action to work, the context node must be an + * <code>Element</code>, a <code>Document</code>, or a + * <code>DocumentFragment</code>. + */ + public static final short ACTION_REPLACE_CHILDREN = 2; + /** + * Insert the result of the parse operation as the immediately preceding + * sibling of the context node. For this action to work the context + * node's parent must be an <code>Element</code> or a + * <code>DocumentFragment</code>. + */ + public static final short ACTION_INSERT_BEFORE = 3; + /** + * Insert the result of the parse operation as the immediately following + * sibling of the context node. For this action to work the context + * node's parent must be an <code>Element</code> or a + * <code>DocumentFragment</code>. + */ + public static final short ACTION_INSERT_AFTER = 4; + /** + * Replace the context node with the result of the parse operation. For + * this action to work, the context node must have a parent, and the + * parent must be an <code>Element</code> or a + * <code>DocumentFragment</code>. + */ + public static final short ACTION_REPLACE = 5; + + /** + * Parse an XML fragment from a resource identified by a + * <code>LSInput</code> and insert the content into an existing document + * at the position specified with the <code>context</code> and + * <code>action</code> arguments. When parsing the input stream, the + * context node (or its parent, depending on where the result will be + * inserted) is used for resolving unbound namespace prefixes. The + * context node's <code>ownerDocument</code> node (or the node itself if + * the node of type <code>DOCUMENT_NODE</code>) is used to resolve + * default attributes and entity references. + * <br> As the new data is inserted into the document, at least one + * mutation event is fired per new immediate child or sibling of the + * context node. + * <br> If the context node is a <code>Document</code> node and the action + * is <code>ACTION_REPLACE_CHILDREN</code>, then the document that is + * passed as the context node will be changed such that its + * <code>xmlEncoding</code>, <code>documentURI</code>, + * <code>xmlVersion</code>, <code>inputEncoding</code>, + * <code>xmlStandalone</code>, and all other such attributes are set to + * what they would be set to if the input source was parsed using + * <code>LSParser.parse()</code>. + * <br> This method is always synchronous, even if the + * <code>LSParser</code> is asynchronous (<code>LSParser.async</code> is + * <code>true</code>). + * <br> If an error occurs while parsing, the caller is notified through + * the <code>ErrorHandler</code> instance associated with the "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-error-handler'> + * error-handler</a>" parameter of the <code>DOMConfiguration</code>. + * <br> When calling <code>parseWithContext</code>, the values of the + * following configuration parameters will be ignored and their default + * values will always be used instead: "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-validate'> + * validate</a>", "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-validate-if-schema'> + * validate-if-schema</a>", and "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-element-content-whitespace'> + * element-content-whitespace</a>". Other parameters will be treated normally, and the parser is expected + * to call the <code>LSParserFilter</code> just as if a whole document + * was parsed. + * @param input The <code>LSInput</code> from which the source document + * is to be read. The source document must be an XML fragment, i.e. + * anything except a complete XML document (except in the case where + * the context node of type <code>DOCUMENT_NODE</code>, and the action + * is <code>ACTION_REPLACE_CHILDREN</code>), a DOCTYPE (internal + * subset), entity declaration(s), notation declaration(s), or XML or + * text declaration(s). + * @param contextArg The node that is used as the context for the data + * that is being parsed. This node must be a <code>Document</code> + * node, a <code>DocumentFragment</code> node, or a node of a type + * that is allowed as a child of an <code>Element</code> node, e.g. it + * cannot be an <code>Attribute</code> node. + * @param action This parameter describes which action should be taken + * between the new set of nodes being inserted and the existing + * children of the context node. The set of possible actions is + * defined in <code>ACTION_TYPES</code> above. + * @return Return the node that is the result of the parse operation. If + * the result is more than one top-level node, the first one is + * returned. + * @exception DOMException + * HIERARCHY_REQUEST_ERR: Raised if the content cannot replace, be + * inserted before, after, or as a child of the context node (see also + * <code>Node.insertBefore</code> or <code>Node.replaceChild</code> in [<a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>DOM Level 3 Core</a>] + * ). + * <br> NOT_SUPPORTED_ERR: Raised if the <code>LSParser</code> doesn't + * support this method, or if the context node is of type + * <code>Document</code> and the DOM implementation doesn't support + * the replacement of the <code>DocumentType</code> child or + * <code>Element</code> child. + * <br> NO_MODIFICATION_ALLOWED_ERR: Raised if the context node is a + * read only node and the content is being appended to its child list, + * or if the parent node of the context node is read only node and the + * content is being inserted in its child list. + * <br> INVALID_STATE_ERR: Raised if the <code>LSParser.busy</code> + * attribute is <code>true</code>. + * @exception LSException + * PARSE_ERR: Raised if the <code>LSParser</code> was unable to load + * the XML fragment. DOM applications should attach a + * <code>DOMErrorHandler</code> using the parameter "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-error-handler'> + * error-handler</a>" if they wish to get details on the error. + */ + public Node parseWithContext(LSInput input, + Node contextArg, + short action) + throws DOMException, LSException; + + /** + * Abort the loading of the document that is currently being loaded by + * the <code>LSParser</code>. If the <code>LSParser</code> is currently + * not busy, a call to this method does nothing. + */ + public void abort(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/ls/LSParserFilter.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/ls/LSParserFilter.java new file mode 100644 index 000000000..00db4d3c2 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/ls/LSParserFilter.java @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom.ls; + +import org.w3c.dom.Node; +import org.w3c.dom.Element; + +/** + * <code>LSParserFilter</code>s provide applications the ability to examine + * nodes as they are being constructed while parsing. As each node is + * examined, it may be modified or removed, or the entire parse may be + * terminated early. + * <p> At the time any of the filter methods are called by the parser, the + * owner Document and DOMImplementation objects exist and are accessible. + * The document element is never passed to the <code>LSParserFilter</code> + * methods, i.e. it is not possible to filter out the document element. + * <code>Document</code>, <code>DocumentType</code>, <code>Notation</code>, + * <code>Entity</code>, and <code>Attr</code> nodes are never passed to the + * <code>acceptNode</code> method on the filter. The child nodes of an + * <code>EntityReference</code> node are passed to the filter if the + * parameter "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-entities'> + * entities</a>" is set to <code>false</code>. Note that, as described by the parameter "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-entities'> + * entities</a>", unexpanded entity reference nodes are never discarded and are always + * passed to the filter. + * <p> All validity checking while parsing a document occurs on the source + * document as it appears on the input stream, not on the DOM document as it + * is built in memory. With filters, the document in memory may be a subset + * of the document on the stream, and its validity may have been affected by + * the filtering. + * <p> All default attributes must be present on elements when the elements + * are passed to the filter methods. All other default content must be + * passed to the filter methods. + * <p> DOM applications must not raise exceptions in a filter. The effect of + * throwing exceptions from a filter is DOM implementation dependent. + * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-LS-20040407'>Document Object Model (DOM) Level 3 Load +and Save Specification</a>. + */ +public interface LSParserFilter { + // Constants returned by startElement and acceptNode + /** + * Accept the node. + */ + public static final short FILTER_ACCEPT = 1; + /** + * Reject the node and its children. + */ + public static final short FILTER_REJECT = 2; + /** + * Skip this single node. The children of this node will still be + * considered. + */ + public static final short FILTER_SKIP = 3; + /** + * Interrupt the normal processing of the document. + */ + public static final short FILTER_INTERRUPT = 4; + + /** + * The parser will call this method after each <code>Element</code> start + * tag has been scanned, but before the remainder of the + * <code>Element</code> is processed. The intent is to allow the + * element, including any children, to be efficiently skipped. Note that + * only element nodes are passed to the <code>startElement</code> + * function. + * <br>The element node passed to <code>startElement</code> for filtering + * will include all of the Element's attributes, but none of the + * children nodes. The Element may not yet be in place in the document + * being constructed (it may not have a parent node.) + * <br>A <code>startElement</code> filter function may access or change + * the attributes for the Element. Changing Namespace declarations will + * have no effect on namespace resolution by the parser. + * <br>For efficiency, the Element node passed to the filter may not be + * the same one as is actually placed in the tree if the node is + * accepted. And the actual node (node object identity) may be reused + * during the process of reading in and filtering a document. + * @param elementArg The newly encountered element. At the time this + * method is called, the element is incomplete - it will have its + * attributes, but no children. + * @return + * <ul> + * <li> <code>FILTER_ACCEPT</code> if the <code>Element</code> should + * be included in the DOM document being built. + * </li> + * <li> + * <code>FILTER_REJECT</code> if the <code>Element</code> and all of + * its children should be rejected. + * </li> + * <li> <code>FILTER_SKIP</code> if the + * <code>Element</code> should be skipped. All of its children are + * inserted in place of the skipped <code>Element</code> node. + * </li> + * <li> + * <code>FILTER_INTERRUPT</code> if the filter wants to stop the + * processing of the document. Interrupting the processing of the + * document does no longer guarantee that the resulting DOM tree is + * XML well-formed. The <code>Element</code> is rejected. + * </li> + * </ul> Returning + * any other values will result in unspecified behavior. + */ + public short startElement(Element elementArg); + + /** + * This method will be called by the parser at the completion of the + * parsing of each node. The node and all of its descendants will exist + * and be complete. The parent node will also exist, although it may be + * incomplete, i.e. it may have additional children that have not yet + * been parsed. Attribute nodes are never passed to this function. + * <br>From within this method, the new node may be freely modified - + * children may be added or removed, text nodes modified, etc. The state + * of the rest of the document outside this node is not defined, and the + * affect of any attempt to navigate to, or to modify any other part of + * the document is undefined. + * <br>For validating parsers, the checks are made on the original + * document, before any modification by the filter. No validity checks + * are made on any document modifications made by the filter. + * <br>If this new node is rejected, the parser might reuse the new node + * and any of its descendants. + * @param nodeArg The newly constructed element. At the time this method + * is called, the element is complete - it has all of its children + * (and their children, recursively) and attributes, and is attached + * as a child to its parent. + * @return + * <ul> + * <li> <code>FILTER_ACCEPT</code> if this <code>Node</code> should + * be included in the DOM document being built. + * </li> + * <li> + * <code>FILTER_REJECT</code> if the <code>Node</code> and all of its + * children should be rejected. + * </li> + * <li> <code>FILTER_SKIP</code> if the + * <code>Node</code> should be skipped and the <code>Node</code> + * should be replaced by all the children of the <code>Node</code>. + * </li> + * <li> + * <code>FILTER_INTERRUPT</code> if the filter wants to stop the + * processing of the document. Interrupting the processing of the + * document does no longer guarantee that the resulting DOM tree is + * XML well-formed. The <code>Node</code> is accepted and will be the + * last completely parsed node. + * </li> + * </ul> + */ + public short acceptNode(Node nodeArg); + + /** + * Tells the <code>LSParser</code> what types of nodes to show to the + * method <code>LSParserFilter.acceptNode</code>. If a node is not shown + * to the filter using this attribute, it is automatically included in + * the DOM document being built. See <code>NodeFilter</code> for + * definition of the constants. The constants <code>SHOW_ATTRIBUTE</code> + * , <code>SHOW_DOCUMENT</code>, <code>SHOW_DOCUMENT_TYPE</code>, + * <code>SHOW_NOTATION</code>, <code>SHOW_ENTITY</code>, and + * <code>SHOW_DOCUMENT_FRAGMENT</code> are meaningless here. Those nodes + * will never be passed to <code>LSParserFilter.acceptNode</code>. + * <br> The constants used here are defined in [<a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Traversal-Range-20001113'>DOM Level 2 Traversal and Range</a>] + * . + */ + public int getWhatToShow(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/ls/LSProgressEvent.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/ls/LSProgressEvent.java new file mode 100644 index 000000000..adf7b098c --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/ls/LSProgressEvent.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom.ls; + +import org.w3c.dom.events.Event; + +/** + * This interface represents a progress event object that notifies the + * application about progress as a document is parsed. It extends the + * <code>Event</code> interface defined in [<a href='http://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107'>DOM Level 3 Events</a>] + * . + * <p> The units used for the attributes <code>position</code> and + * <code>totalSize</code> are not specified and can be implementation and + * input dependent. + * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-LS-20040407'>Document Object Model (DOM) Level 3 Load +and Save Specification</a>. + */ +public interface LSProgressEvent extends Event { + /** + * The input source that is being parsed. + */ + public LSInput getInput(); + + /** + * The current position in the input source, including all external + * entities and other resources that have been read. + */ + public int getPosition(); + + /** + * The total size of the document including all external resources, this + * number might change as a document is being parsed if references to + * more external resources are seen. A value of <code>0</code> is + * returned if the total size cannot be determined or estimated. + */ + public int getTotalSize(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/ls/LSResourceResolver.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/ls/LSResourceResolver.java new file mode 100644 index 000000000..5301beb8f --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/ls/LSResourceResolver.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom.ls; + +/** + * <code>LSResourceResolver</code> provides a way for applications to + * redirect references to external resources. + * <p> Applications needing to implement custom handling for external + * resources can implement this interface and register their implementation + * by setting the "resource-resolver" parameter of + * <code>DOMConfiguration</code> objects attached to <code>LSParser</code> + * and <code>LSSerializer</code>. It can also be register on + * <code>DOMConfiguration</code> objects attached to <code>Document</code> + * if the "LS" feature is supported. + * <p> The <code>LSParser</code> will then allow the application to intercept + * any external entities, including the external DTD subset and external + * parameter entities, before including them. The top-level document entity + * is never passed to the <code>resolveResource</code> method. + * <p> Many DOM applications will not need to implement this interface, but it + * will be especially useful for applications that build XML documents from + * databases or other specialized input sources, or for applications that + * use URNs. + * <p ><b>Note:</b> <code>LSResourceResolver</code> is based on the SAX2 [<a href='http://www.saxproject.org/'>SAX</a>] <code>EntityResolver</code> + * interface. + * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-LS-20040407'>Document Object Model (DOM) Level 3 Load +and Save Specification</a>. + */ +public interface LSResourceResolver { + /** + * Allow the application to resolve external resources. + * <br> The <code>LSParser</code> will call this method before opening any + * external resource, including the external DTD subset, external + * entities referenced within the DTD, and external entities referenced + * within the document element (however, the top-level document entity + * is not passed to this method). The application may then request that + * the <code>LSParser</code> resolve the external resource itself, that + * it use an alternative URI, or that it use an entirely different input + * source. + * <br> Application writers can use this method to redirect external + * system identifiers to secure and/or local URI, to look up public + * identifiers in a catalogue, or to read an entity from a database or + * other input source (including, for example, a dialog box). + * @param type The type of the resource being resolved. For XML [<a href='http://www.w3.org/TR/2004/REC-xml-20040204'>XML 1.0</a>] resources + * (i.e. entities), applications must use the value + * <code>"http://www.w3.org/TR/REC-xml"</code>. For XML Schema [<a href='http://www.w3.org/TR/2001/REC-xmlschema-1-20010502/'>XML Schema Part 1</a>] + * , applications must use the value + * <code>"http://www.w3.org/2001/XMLSchema"</code>. Other types of + * resources are outside the scope of this specification and therefore + * should recommend an absolute URI in order to use this method. + * @param namespaceURI The namespace of the resource being resolved, + * e.g. the target namespace of the XML Schema [<a href='http://www.w3.org/TR/2001/REC-xmlschema-1-20010502/'>XML Schema Part 1</a>] + * when resolving XML Schema resources. + * @param publicId The public identifier of the external entity being + * referenced, or <code>null</code> if no public identifier was + * supplied or if the resource is not an entity. + * @param systemId The system identifier, a URI reference [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>], of the + * external resource being referenced, or <code>null</code> if no + * system identifier was supplied. + * @param baseURI The absolute base URI of the resource being parsed, or + * <code>null</code> if there is no base URI. + * @return A <code>LSInput</code> object describing the new input + * source, or <code>null</code> to request that the parser open a + * regular URI connection to the resource. + */ + public LSInput resolveResource(String type, + String namespaceURI, + String publicId, + String systemId, + String baseURI); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/ls/LSSerializer.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/ls/LSSerializer.java new file mode 100644 index 000000000..2a6fb6ff4 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/ls/LSSerializer.java @@ -0,0 +1,436 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom.ls; + +import org.w3c.dom.DOMConfiguration; +import org.w3c.dom.Node; +import org.w3c.dom.DOMException; + +/** + * A <code>LSSerializer</code> provides an API for serializing (writing) a + * DOM document out into XML. The XML data is written to a string or an + * output stream. Any changes or fixups made during the serialization affect + * only the serialized data. The <code>Document</code> object and its + * children are never altered by the serialization operation. + * <p> During serialization of XML data, namespace fixup is done as defined in [<a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>DOM Level 3 Core</a>] + * , Appendix B. [<a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113'>DOM Level 2 Core</a>] + * allows empty strings as a real namespace URI. If the + * <code>namespaceURI</code> of a <code>Node</code> is empty string, the + * serialization will treat them as <code>null</code>, ignoring the prefix + * if any. + * <p> <code>LSSerializer</code> accepts any node type for serialization. For + * nodes of type <code>Document</code> or <code>Entity</code>, well-formed + * XML will be created when possible (well-formedness is guaranteed if the + * document or entity comes from a parse operation and is unchanged since it + * was created). The serialized output for these node types is either as a + * XML document or an External XML Entity, respectively, and is acceptable + * input for an XML parser. For all other types of nodes the serialized form + * is implementation dependent. + * <p>Within a <code>Document</code>, <code>DocumentFragment</code>, or + * <code>Entity</code> being serialized, <code>Nodes</code> are processed as + * follows + * <ul> + * <li> <code>Document</code> nodes are written, including the XML + * declaration (unless the parameter "xml-declaration" is set to + * <code>false</code>) and a DTD subset, if one exists in the DOM. Writing a + * <code>Document</code> node serializes the entire document. + * </li> + * <li> + * <code>Entity</code> nodes, when written directly by + * <code>LSSerializer.write</code>, outputs the entity expansion but no + * namespace fixup is done. The resulting output will be valid as an + * external entity. + * </li> + * <li> If the parameter "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-entities'> + * entities</a>" is set to <code>true</code>, <code>EntityReference</code> nodes are + * serialized as an entity reference of the form " + * <code>&entityName;</code>" in the output. Child nodes (the expansion) + * of the entity reference are ignored. If the parameter "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-entities'> + * entities</a>" is set to <code>false</code>, only the children of the entity reference + * are serialized. <code>EntityReference</code> nodes with no children (no + * corresponding <code>Entity</code> node or the corresponding + * <code>Entity</code> nodes have no children) are always serialized. + * </li> + * <li> + * <code>CDATAsections</code> containing content characters that cannot be + * represented in the specified output encoding are handled according to the + * "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-split-cdata-sections'> + * split-cdata-sections</a>" parameter. If the parameter is set to <code>true</code>, + * <code>CDATAsections</code> are split, and the unrepresentable characters + * are serialized as numeric character references in ordinary content. The + * exact position and number of splits is not specified. If the parameter + * is set to <code>false</code>, unrepresentable characters in a + * <code>CDATAsection</code> are reported as + * <code>"wf-invalid-character"</code> errors if the parameter "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-well-formed'> + * well-formed</a>" is set to <code>true</code>. The error is not recoverable - there is no + * mechanism for supplying alternative characters and continuing with the + * serialization. + * </li> + * <li> <code>DocumentFragment</code> nodes are serialized by + * serializing the children of the document fragment in the order they + * appear in the document fragment. + * </li> + * <li> All other node types (Element, Text, + * etc.) are serialized to their corresponding XML source form. + * </li> + * </ul> + * <p ><b>Note:</b> The serialization of a <code>Node</code> does not always + * generate a well-formed XML document, i.e. a <code>LSParser</code> might + * throw fatal errors when parsing the resulting serialization. + * <p> Within the character data of a document (outside of markup), any + * characters that cannot be represented directly are replaced with + * character references. Occurrences of '<' and '&' are replaced by + * the predefined entities &lt; and &amp;. The other predefined + * entities (&gt;, &apos;, and &quot;) might not be used, except + * where needed (e.g. using &gt; in cases such as ']]>'). Any + * characters that cannot be represented directly in the output character + * encoding are serialized as numeric character references (and since + * character encoding standards commonly use hexadecimal representations of + * characters, using the hexadecimal representation when serializing + * character references is encouraged). + * <p> To allow attribute values to contain both single and double quotes, the + * apostrophe or single-quote character (') may be represented as + * "&apos;", and the double-quote character (") as "&quot;". New + * line characters and other characters that cannot be represented directly + * in attribute values in the output character encoding are serialized as a + * numeric character reference. + * <p> Within markup, but outside of attributes, any occurrence of a character + * that cannot be represented in the output character encoding is reported + * as a <code>DOMError</code> fatal error. An example would be serializing + * the element <LaCa\u00f1ada/> with <code>encoding="us-ascii"</code>. + * This will result with a generation of a <code>DOMError</code> + * "wf-invalid-character-in-node-name" (as proposed in "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-well-formed'> + * well-formed</a>"). + * <p> When requested by setting the parameter "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-normalize-characters'> + * normalize-characters</a>" on <code>LSSerializer</code> to true, character normalization is + * performed according to the definition of <a href='http://www.w3.org/TR/2004/REC-xml11-20040204/#dt-fullnorm'>fully + * normalized</a> characters included in appendix E of [<a href='http://www.w3.org/TR/2004/REC-xml11-20040204/'>XML 1.1</a>] on all + * data to be serialized, both markup and character data. The character + * normalization process affects only the data as it is being written; it + * does not alter the DOM's view of the document after serialization has + * completed. + * <p> Implementations are required to support the encodings "UTF-8", + * "UTF-16", "UTF-16BE", and "UTF-16LE" to guarantee that data is + * serializable in all encodings that are required to be supported by all + * XML parsers. When the encoding is UTF-8, whether or not a byte order mark + * is serialized, or if the output is big-endian or little-endian, is + * implementation dependent. When the encoding is UTF-16, whether or not the + * output is big-endian or little-endian is implementation dependent, but a + * Byte Order Mark must be generated for non-character outputs, such as + * <code>LSOutput.byteStream</code> or <code>LSOutput.systemId</code>. If + * the Byte Order Mark is not generated, a "byte-order-mark-needed" warning + * is reported. When the encoding is UTF-16LE or UTF-16BE, the output is + * big-endian (UTF-16BE) or little-endian (UTF-16LE) and the Byte Order Mark + * is not be generated. In all cases, the encoding declaration, if + * generated, will correspond to the encoding used during the serialization + * (e.g. <code>encoding="UTF-16"</code> will appear if UTF-16 was + * requested). + * <p> Namespaces are fixed up during serialization, the serialization process + * will verify that namespace declarations, namespace prefixes and the + * namespace URI associated with elements and attributes are consistent. If + * inconsistencies are found, the serialized form of the document will be + * altered to remove them. The method used for doing the namespace fixup + * while serializing a document is the algorithm defined in Appendix B.1, + * "Namespace normalization", of [<a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>DOM Level 3 Core</a>] + * . + * <p> While serializing a document, the parameter "discard-default-content" + * controls whether or not non-specified data is serialized. + * <p> While serializing, errors and warnings are reported to the application + * through the error handler (<code>LSSerializer.domConfig</code>'s "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-error-handler'> + * error-handler</a>" parameter). This specification does in no way try to define all possible + * errors and warnings that can occur while serializing a DOM node, but some + * common error and warning cases are defined. The types ( + * <code>DOMError.type</code>) of errors and warnings defined by this + * specification are: + * <dl> + * <dt><code>"no-output-specified" [fatal]</code></dt> + * <dd> Raised when + * writing to a <code>LSOutput</code> if no output is specified in the + * <code>LSOutput</code>. </dd> + * <dt> + * <code>"unbound-prefix-in-entity-reference" [fatal]</code> </dt> + * <dd> Raised if the + * configuration parameter "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-namespaces'> + * namespaces</a>" is set to <code>true</code> and an entity whose replacement text + * contains unbound namespace prefixes is referenced in a location where + * there are no bindings for the namespace prefixes. </dd> + * <dt> + * <code>"unsupported-encoding" [fatal]</code></dt> + * <dd> Raised if an unsupported + * encoding is encountered. </dd> + * </dl> + * <p> In addition to raising the defined errors and warnings, implementations + * are expected to raise implementation specific errors and warnings for any + * other error and warning cases such as IO errors (file not found, + * permission denied,...) and so on. + * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-LS-20040407'>Document Object Model (DOM) Level 3 Load +and Save Specification</a>. + */ +public interface LSSerializer { + /** + * The <code>DOMConfiguration</code> object used by the + * <code>LSSerializer</code> when serializing a DOM node. + * <br> In addition to the parameters recognized by the <a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#DOMConfiguration'> + * DOMConfiguration</a> interface defined in [<a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>DOM Level 3 Core</a>] + * , the <code>DOMConfiguration</code> objects for + * <code>LSSerializer</code> adds, or modifies, the following + * parameters: + * <dl> + * <dt><code>"canonical-form"</code></dt> + * <dd> + * <dl> + * <dt><code>true</code></dt> + * <dd>[<em>optional</em>] Writes the document according to the rules specified in [<a href='http://www.w3.org/TR/2001/REC-xml-c14n-20010315'>Canonical XML</a>]. + * In addition to the behavior described in "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-canonical-form'> + * canonical-form</a>" [<a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>DOM Level 3 Core</a>] + * , setting this parameter to <code>true</code> will set the parameters + * "format-pretty-print", "discard-default-content", and "xml-declaration + * ", to <code>false</code>. Setting one of those parameters to + * <code>true</code> will set this parameter to <code>false</code>. + * Serializing an XML 1.1 document when "canonical-form" is + * <code>true</code> will generate a fatal error. </dd> + * <dt><code>false</code></dt> + * <dd>[<em>required</em>] (<em>default</em>) Do not canonicalize the output. </dd> + * </dl></dd> + * <dt><code>"discard-default-content"</code></dt> + * <dd> + * <dl> + * <dt> + * <code>true</code></dt> + * <dd>[<em>required</em>] (<em>default</em>) Use the <code>Attr.specified</code> attribute to decide what attributes + * should be discarded. Note that some implementations might use + * whatever information available to the implementation (i.e. XML + * schema, DTD, the <code>Attr.specified</code> attribute, and so on) to + * determine what attributes and content to discard if this parameter is + * set to <code>true</code>. </dd> + * <dt><code>false</code></dt> + * <dd>[<em>required</em>]Keep all attributes and all content.</dd> + * </dl></dd> + * <dt><code>"format-pretty-print"</code></dt> + * <dd> + * <dl> + * <dt> + * <code>true</code></dt> + * <dd>[<em>optional</em>] Formatting the output by adding whitespace to produce a pretty-printed, + * indented, human-readable form. The exact form of the transformations + * is not specified by this specification. Pretty-printing changes the + * content of the document and may affect the validity of the document, + * validating implementations should preserve validity. </dd> + * <dt> + * <code>false</code></dt> + * <dd>[<em>required</em>] (<em>default</em>) Don't pretty-print the result. </dd> + * </dl></dd> + * <dt> + * <code>"ignore-unknown-character-denormalizations"</code> </dt> + * <dd> + * <dl> + * <dt> + * <code>true</code></dt> + * <dd>[<em>required</em>] (<em>default</em>) If, while verifying full normalization when [<a href='http://www.w3.org/TR/2004/REC-xml11-20040204/'>XML 1.1</a>] is + * supported, a character is encountered for which the normalization + * properties cannot be determined, then raise a + * <code>"unknown-character-denormalization"</code> warning (instead of + * raising an error, if this parameter is not set) and ignore any + * possible denormalizations caused by these characters. </dd> + * <dt> + * <code>false</code></dt> + * <dd>[<em>optional</em>] Report a fatal error if a character is encountered for which the + * processor cannot determine the normalization properties. </dd> + * </dl></dd> + * <dt> + * <code>"normalize-characters"</code></dt> + * <dd> This parameter is equivalent to + * the one defined by <code>DOMConfiguration</code> in [<a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>DOM Level 3 Core</a>] + * . Unlike in the Core, the default value for this parameter is + * <code>true</code>. While DOM implementations are not required to + * support <a href='http://www.w3.org/TR/2004/REC-xml11-20040204/#dt-fullnorm'>fully + * normalizing</a> the characters in the document according to appendix E of [<a href='http://www.w3.org/TR/2004/REC-xml11-20040204/'>XML 1.1</a>], this + * parameter must be activated by default if supported. </dd> + * <dt> + * <code>"xml-declaration"</code></dt> + * <dd> + * <dl> + * <dt><code>true</code></dt> + * <dd>[<em>required</em>] (<em>default</em>) If a <code>Document</code>, <code>Element</code>, or <code>Entity</code> + * node is serialized, the XML declaration, or text declaration, should + * be included. The version (<code>Document.xmlVersion</code> if the + * document is a Level 3 document and the version is non-null, otherwise + * use the value "1.0"), and the output encoding (see + * <code>LSSerializer.write</code> for details on how to find the output + * encoding) are specified in the serialized XML declaration. </dd> + * <dt> + * <code>false</code></dt> + * <dd>[<em>required</em>] Do not serialize the XML and text declarations. Report a + * <code>"xml-declaration-needed"</code> warning if this will cause + * problems (i.e. the serialized data is of an XML version other than [<a href='http://www.w3.org/TR/2004/REC-xml-20040204'>XML 1.0</a>], or an + * encoding would be needed to be able to re-parse the serialized data). </dd> + * </dl></dd> + * </dl> + */ + public DOMConfiguration getDomConfig(); + + /** + * The end-of-line sequence of characters to be used in the XML being + * written out. Any string is supported, but XML treats only a certain + * set of characters sequence as end-of-line (See section 2.11, + * "End-of-Line Handling" in [<a href='http://www.w3.org/TR/2004/REC-xml-20040204'>XML 1.0</a>], if the + * serialized content is XML 1.0 or section 2.11, "End-of-Line Handling" + * in [<a href='http://www.w3.org/TR/2004/REC-xml11-20040204/'>XML 1.1</a>], if the + * serialized content is XML 1.1). Using other character sequences than + * the recommended ones can result in a document that is either not + * serializable or not well-formed). + * <br> On retrieval, the default value of this attribute is the + * implementation specific default end-of-line sequence. DOM + * implementations should choose the default to match the usual + * convention for text files in the environment being used. + * Implementations must choose a default sequence that matches one of + * those allowed by XML 1.0 or XML 1.1, depending on the serialized + * content. Setting this attribute to <code>null</code> will reset its + * value to the default value. + * <br> + */ + public String getNewLine(); + /** + * The end-of-line sequence of characters to be used in the XML being + * written out. Any string is supported, but XML treats only a certain + * set of characters sequence as end-of-line (See section 2.11, + * "End-of-Line Handling" in [<a href='http://www.w3.org/TR/2004/REC-xml-20040204'>XML 1.0</a>], if the + * serialized content is XML 1.0 or section 2.11, "End-of-Line Handling" + * in [<a href='http://www.w3.org/TR/2004/REC-xml11-20040204/'>XML 1.1</a>], if the + * serialized content is XML 1.1). Using other character sequences than + * the recommended ones can result in a document that is either not + * serializable or not well-formed). + * <br> On retrieval, the default value of this attribute is the + * implementation specific default end-of-line sequence. DOM + * implementations should choose the default to match the usual + * convention for text files in the environment being used. + * Implementations must choose a default sequence that matches one of + * those allowed by XML 1.0 or XML 1.1, depending on the serialized + * content. Setting this attribute to <code>null</code> will reset its + * value to the default value. + * <br> + */ + public void setNewLine(String newLine); + + /** + * When the application provides a filter, the serializer will call out + * to the filter before serializing each Node. The filter implementation + * can choose to remove the node from the stream or to terminate the + * serialization early. + * <br> The filter is invoked after the operations requested by the + * <code>DOMConfiguration</code> parameters have been applied. For + * example, CDATA sections won't be passed to the filter if "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-cdata-sections'> + * cdata-sections</a>" is set to <code>false</code>. + */ + public LSSerializerFilter getFilter(); + /** + * When the application provides a filter, the serializer will call out + * to the filter before serializing each Node. The filter implementation + * can choose to remove the node from the stream or to terminate the + * serialization early. + * <br> The filter is invoked after the operations requested by the + * <code>DOMConfiguration</code> parameters have been applied. For + * example, CDATA sections won't be passed to the filter if "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-cdata-sections'> + * cdata-sections</a>" is set to <code>false</code>. + */ + public void setFilter(LSSerializerFilter filter); + + /** + * Serialize the specified node as described above in the general + * description of the <code>LSSerializer</code> interface. The output is + * written to the supplied <code>LSOutput</code>. + * <br> When writing to a <code>LSOutput</code>, the encoding is found by + * looking at the encoding information that is reachable through the + * <code>LSOutput</code> and the item to be written (or its owner + * document) in this order: + * <ol> + * <li> <code>LSOutput.encoding</code>, + * </li> + * <li> + * <code>Document.inputEncoding</code>, + * </li> + * <li> + * <code>Document.xmlEncoding</code>. + * </li> + * </ol> + * <br> If no encoding is reachable through the above properties, a + * default encoding of "UTF-8" will be used. If the specified encoding + * is not supported an "unsupported-encoding" fatal error is raised. + * <br> If no output is specified in the <code>LSOutput</code>, a + * "no-output-specified" fatal error is raised. + * <br> The implementation is responsible of associating the appropriate + * media type with the serialized data. + * <br> When writing to a HTTP URI, a HTTP PUT is performed. When writing + * to other types of URIs, the mechanism for writing the data to the URI + * is implementation dependent. + * @param nodeArg The node to serialize. + * @param destination The destination for the serialized DOM. + * @return Returns <code>true</code> if <code>node</code> was + * successfully serialized. Return <code>false</code> in case the + * normal processing stopped but the implementation kept serializing + * the document; the result of the serialization being implementation + * dependent then. + * @exception LSException + * SERIALIZE_ERR: Raised if the <code>LSSerializer</code> was unable to + * serialize the node. DOM applications should attach a + * <code>DOMErrorHandler</code> using the parameter "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-error-handler'> + * error-handler</a>" if they wish to get details on the error. + */ + public boolean write(Node nodeArg, + LSOutput destination) + throws LSException; + + /** + * A convenience method that acts as if <code>LSSerializer.write</code> + * was called with a <code>LSOutput</code> with no encoding specified + * and <code>LSOutput.systemId</code> set to the <code>uri</code> + * argument. + * @param nodeArg The node to serialize. + * @param uri The URI to write to. + * @return Returns <code>true</code> if <code>node</code> was + * successfully serialized. Return <code>false</code> in case the + * normal processing stopped but the implementation kept serializing + * the document; the result of the serialization being implementation + * dependent then. + * @exception LSException + * SERIALIZE_ERR: Raised if the <code>LSSerializer</code> was unable to + * serialize the node. DOM applications should attach a + * <code>DOMErrorHandler</code> using the parameter "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-error-handler'> + * error-handler</a>" if they wish to get details on the error. + */ + public boolean writeToURI(Node nodeArg, + String uri) + throws LSException; + + /** + * Serialize the specified node as described above in the general + * description of the <code>LSSerializer</code> interface. The output is + * written to a <code>DOMString</code> that is returned to the caller. + * The encoding used is the encoding of the <code>DOMString</code> type, + * i.e. UTF-16. Note that no Byte Order Mark is generated in a + * <code>DOMString</code> object. + * @param nodeArg The node to serialize. + * @return Returns the serialized data. + * @exception DOMException + * DOMSTRING_SIZE_ERR: Raised if the resulting string is too long to + * fit in a <code>DOMString</code>. + * @exception LSException + * SERIALIZE_ERR: Raised if the <code>LSSerializer</code> was unable to + * serialize the node. DOM applications should attach a + * <code>DOMErrorHandler</code> using the parameter "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-error-handler'> + * error-handler</a>" if they wish to get details on the error. + */ + public String writeToString(Node nodeArg) + throws DOMException, LSException; + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/ls/LSSerializerFilter.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/ls/LSSerializerFilter.java new file mode 100644 index 000000000..b04655677 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/ls/LSSerializerFilter.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom.ls; + +import org.w3c.dom.traversal.NodeFilter; + +/** + * <code>LSSerializerFilter</code>s provide applications the ability to + * examine nodes as they are being serialized and decide what nodes should + * be serialized or not. The <code>LSSerializerFilter</code> interface is + * based on the <code>NodeFilter</code> interface defined in [<a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Traversal-Range-20001113'>DOM Level 2 Traversal and Range</a>] + * . + * <p> <code>Document</code>, <code>DocumentType</code>, + * <code>DocumentFragment</code>, <code>Notation</code>, <code>Entity</code> + * , and children of <code>Attr</code> nodes are not passed to the filter. + * The child nodes of an <code>EntityReference</code> node are only passed + * to the filter if the <code>EntityReference</code> node is skipped by the + * method <code>LSParserFilter.acceptNode()</code>. + * <p> When serializing an <code>Element</code>, the element is passed to the + * filter before any of its attributes are passed to the filter. Namespace + * declaration attributes, and default attributes (except in the case when " + * discard-default-content" is set to <code>false</code>), are never passed + * to the filter. + * <p> The result of any attempt to modify a node passed to a + * <code>LSSerializerFilter</code> is implementation dependent. + * <p> DOM applications must not raise exceptions in a filter. The effect of + * throwing exceptions from a filter is DOM implementation dependent. + * <p> For efficiency, a node passed to the filter may not be the same as the + * one that is actually in the tree. And the actual node (node object + * identity) may be reused during the process of filtering and serializing a + * document. + * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-LS-20040407'>Document Object Model (DOM) Level 3 Load +and Save Specification</a>. + */ +public interface LSSerializerFilter extends NodeFilter { + /** + * Tells the <code>LSSerializer</code> what types of nodes to show to the + * filter. If a node is not shown to the filter using this attribute, it + * is automatically serialized. See <code>NodeFilter</code> for + * definition of the constants. The constants <code>SHOW_DOCUMENT</code> + * , <code>SHOW_DOCUMENT_TYPE</code>, <code>SHOW_DOCUMENT_FRAGMENT</code> + * , <code>SHOW_NOTATION</code>, and <code>SHOW_ENTITY</code> are + * meaningless here, such nodes will never be passed to a + * <code>LSSerializerFilter</code>. + * <br> Unlike [<a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Traversal-Range-20001113'>DOM Level 2 Traversal and Range</a>] + * , the <code>SHOW_ATTRIBUTE</code> constant indicates that the + * <code>Attr</code> nodes are shown and passed to the filter. + * <br> The constants used here are defined in [<a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Traversal-Range-20001113'>DOM Level 2 Traversal and Range</a>] + * . + */ + public int getWhatToShow(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/ranges/DocumentRange.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/ranges/DocumentRange.java new file mode 100644 index 000000000..de56e07d6 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/ranges/DocumentRange.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.ranges; + +/** + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Traversal-Range-20001113'>Document Object Model (DOM) Level 2 Traversal and Range Specification</a>. + * @since DOM Level 2 + */ +public interface DocumentRange { + /** + * This interface can be obtained from the object implementing the + * <code>Document</code> interface using binding-specific casting + * methods. + * @return The initial state of the Range returned from this method is + * such that both of its boundary-points are positioned at the + * beginning of the corresponding Document, before any content. The + * Range returned can only be used to select content associated with + * this Document, or with DocumentFragments and Attrs for which this + * Document is the <code>ownerDocument</code>. + */ + public Range createRange(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/ranges/Range.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/ranges/Range.java new file mode 100644 index 000000000..9e1957883 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/ranges/Range.java @@ -0,0 +1,416 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.ranges; + +import org.w3c.dom.Node; +import org.w3c.dom.DOMException; +import org.w3c.dom.DocumentFragment; + +/** + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Traversal-Range-20001113'>Document Object Model (DOM) Level 2 Traversal and Range Specification</a>. + * @since DOM Level 2 + */ +public interface Range { + /** + * Node within which the Range begins + * @exception DOMException + * INVALID_STATE_ERR: Raised if <code>detach()</code> has already been + * invoked on this object. + */ + public Node getStartContainer() + throws DOMException; + + /** + * Offset within the starting node of the Range. + * @exception DOMException + * INVALID_STATE_ERR: Raised if <code>detach()</code> has already been + * invoked on this object. + */ + public int getStartOffset() + throws DOMException; + + /** + * Node within which the Range ends + * @exception DOMException + * INVALID_STATE_ERR: Raised if <code>detach()</code> has already been + * invoked on this object. + */ + public Node getEndContainer() + throws DOMException; + + /** + * Offset within the ending node of the Range. + * @exception DOMException + * INVALID_STATE_ERR: Raised if <code>detach()</code> has already been + * invoked on this object. + */ + public int getEndOffset() + throws DOMException; + + /** + * TRUE if the Range is collapsed + * @exception DOMException + * INVALID_STATE_ERR: Raised if <code>detach()</code> has already been + * invoked on this object. + */ + public boolean getCollapsed() + throws DOMException; + + /** + * The deepest common ancestor container of the Range's two + * boundary-points. + * @exception DOMException + * INVALID_STATE_ERR: Raised if <code>detach()</code> has already been + * invoked on this object. + */ + public Node getCommonAncestorContainer() + throws DOMException; + + /** + * Sets the attributes describing the start of the Range. + * @param refNode The <code>refNode</code> value. This parameter must be + * different from <code>null</code>. + * @param offset The <code>startOffset</code> value. + * @exception RangeException + * INVALID_NODE_TYPE_ERR: Raised if <code>refNode</code> or an ancestor + * of <code>refNode</code> is an Entity, Notation, or DocumentType + * node. + * @exception DOMException + * INDEX_SIZE_ERR: Raised if <code>offset</code> is negative or greater + * than the number of child units in <code>refNode</code>. Child units + * are 16-bit units if <code>refNode</code> is a type of CharacterData + * node (e.g., a Text or Comment node) or a ProcessingInstruction + * node. Child units are Nodes in all other cases. + * <br>INVALID_STATE_ERR: Raised if <code>detach()</code> has already + * been invoked on this object. + * <br>WRONG_DOCUMENT_ERR: Raised if <code>refNode</code> was created + * from a different document than the one that created this range. + */ + public void setStart(Node refNode, + int offset) + throws RangeException, DOMException; + + /** + * Sets the attributes describing the end of a Range. + * @param refNode The <code>refNode</code> value. This parameter must be + * different from <code>null</code>. + * @param offset The <code>endOffset</code> value. + * @exception RangeException + * INVALID_NODE_TYPE_ERR: Raised if <code>refNode</code> or an ancestor + * of <code>refNode</code> is an Entity, Notation, or DocumentType + * node. + * @exception DOMException + * INDEX_SIZE_ERR: Raised if <code>offset</code> is negative or greater + * than the number of child units in <code>refNode</code>. Child units + * are 16-bit units if <code>refNode</code> is a type of CharacterData + * node (e.g., a Text or Comment node) or a ProcessingInstruction + * node. Child units are Nodes in all other cases. + * <br>INVALID_STATE_ERR: Raised if <code>detach()</code> has already + * been invoked on this object. + * <br>WRONG_DOCUMENT_ERR: Raised if <code>refNode</code> was created + * from a different document than the one that created this range. + */ + public void setEnd(Node refNode, + int offset) + throws RangeException, DOMException; + + /** + * Sets the start position to be before a node + * @param refNode Range starts before <code>refNode</code> + * @exception RangeException + * INVALID_NODE_TYPE_ERR: Raised if the root container of + * <code>refNode</code> is not an Attr, Document, or DocumentFragment + * node or if <code>refNode</code> is a Document, DocumentFragment, + * Attr, Entity, or Notation node. + * @exception DOMException + * INVALID_STATE_ERR: Raised if <code>detach()</code> has already been + * invoked on this object. + * <br>WRONG_DOCUMENT_ERR: Raised if <code>refNode</code> was created + * from a different document than the one that created this range. + */ + public void setStartBefore(Node refNode) + throws RangeException, DOMException; + + /** + * Sets the start position to be after a node + * @param refNode Range starts after <code>refNode</code> + * @exception RangeException + * INVALID_NODE_TYPE_ERR: Raised if the root container of + * <code>refNode</code> is not an Attr, Document, or DocumentFragment + * node or if <code>refNode</code> is a Document, DocumentFragment, + * Attr, Entity, or Notation node. + * @exception DOMException + * INVALID_STATE_ERR: Raised if <code>detach()</code> has already been + * invoked on this object. + * <br>WRONG_DOCUMENT_ERR: Raised if <code>refNode</code> was created + * from a different document than the one that created this range. + */ + public void setStartAfter(Node refNode) + throws RangeException, DOMException; + + /** + * Sets the end position to be before a node. + * @param refNode Range ends before <code>refNode</code> + * @exception RangeException + * INVALID_NODE_TYPE_ERR: Raised if the root container of + * <code>refNode</code> is not an Attr, Document, or DocumentFragment + * node or if <code>refNode</code> is a Document, DocumentFragment, + * Attr, Entity, or Notation node. + * @exception DOMException + * INVALID_STATE_ERR: Raised if <code>detach()</code> has already been + * invoked on this object. + * <br>WRONG_DOCUMENT_ERR: Raised if <code>refNode</code> was created + * from a different document than the one that created this range. + */ + public void setEndBefore(Node refNode) + throws RangeException, DOMException; + + /** + * Sets the end of a Range to be after a node + * @param refNode Range ends after <code>refNode</code>. + * @exception RangeException + * INVALID_NODE_TYPE_ERR: Raised if the root container of + * <code>refNode</code> is not an Attr, Document or DocumentFragment + * node or if <code>refNode</code> is a Document, DocumentFragment, + * Attr, Entity, or Notation node. + * @exception DOMException + * INVALID_STATE_ERR: Raised if <code>detach()</code> has already been + * invoked on this object. + * <br>WRONG_DOCUMENT_ERR: Raised if <code>refNode</code> was created + * from a different document than the one that created this range. + */ + public void setEndAfter(Node refNode) + throws RangeException, DOMException; + + /** + * Collapse a Range onto one of its boundary-points + * @param toStart If TRUE, collapses the Range onto its start; if FALSE, + * collapses it onto its end. + * @exception DOMException + * INVALID_STATE_ERR: Raised if <code>detach()</code> has already been + * invoked on this object. + */ + public void collapse(boolean toStart) + throws DOMException; + + /** + * Select a node and its contents + * @param refNode The node to select. + * @exception RangeException + * INVALID_NODE_TYPE_ERR: Raised if an ancestor of <code>refNode</code> + * is an Entity, Notation or DocumentType node or if + * <code>refNode</code> is a Document, DocumentFragment, Attr, Entity, + * or Notation node. + * @exception DOMException + * INVALID_STATE_ERR: Raised if <code>detach()</code> has already been + * invoked on this object. + * <br>WRONG_DOCUMENT_ERR: Raised if <code>refNode</code> was created + * from a different document than the one that created this range. + */ + public void selectNode(Node refNode) + throws RangeException, DOMException; + + /** + * Select the contents within a node + * @param refNode Node to select from + * @exception RangeException + * INVALID_NODE_TYPE_ERR: Raised if <code>refNode</code> or an ancestor + * of <code>refNode</code> is an Entity, Notation or DocumentType node. + * @exception DOMException + * INVALID_STATE_ERR: Raised if <code>detach()</code> has already been + * invoked on this object. + * <br>WRONG_DOCUMENT_ERR: Raised if <code>refNode</code> was created + * from a different document than the one that created this range. + */ + public void selectNodeContents(Node refNode) + throws RangeException, DOMException; + + // CompareHow + /** + * Compare start boundary-point of <code>sourceRange</code> to start + * boundary-point of Range on which <code>compareBoundaryPoints</code> + * is invoked. + */ + public static final short START_TO_START = 0; + /** + * Compare start boundary-point of <code>sourceRange</code> to end + * boundary-point of Range on which <code>compareBoundaryPoints</code> + * is invoked. + */ + public static final short START_TO_END = 1; + /** + * Compare end boundary-point of <code>sourceRange</code> to end + * boundary-point of Range on which <code>compareBoundaryPoints</code> + * is invoked. + */ + public static final short END_TO_END = 2; + /** + * Compare end boundary-point of <code>sourceRange</code> to start + * boundary-point of Range on which <code>compareBoundaryPoints</code> + * is invoked. + */ + public static final short END_TO_START = 3; + + /** + * Compare the boundary-points of two Ranges in a document. + * @param how A code representing the type of comparison, as defined + * above. + * @param sourceRange The <code>Range</code> on which this current + * <code>Range</code> is compared to. + * @return -1, 0 or 1 depending on whether the corresponding + * boundary-point of the Range is respectively before, equal to, or + * after the corresponding boundary-point of <code>sourceRange</code>. + * @exception DOMException + * WRONG_DOCUMENT_ERR: Raised if the two Ranges are not in the same + * Document or DocumentFragment. + * <br>INVALID_STATE_ERR: Raised if <code>detach()</code> has already + * been invoked on this object. + */ + public short compareBoundaryPoints(short how, + Range sourceRange) + throws DOMException; + + /** + * Removes the contents of a Range from the containing document or + * document fragment without returning a reference to the removed + * content. + * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised if any portion of the content of + * the Range is read-only or any of the nodes that contain any of the + * content of the Range are read-only. + * <br>INVALID_STATE_ERR: Raised if <code>detach()</code> has already + * been invoked on this object. + */ + public void deleteContents() + throws DOMException; + + /** + * Moves the contents of a Range from the containing document or document + * fragment to a new DocumentFragment. + * @return A DocumentFragment containing the extracted contents. + * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised if any portion of the content of + * the Range is read-only or any of the nodes which contain any of the + * content of the Range are read-only. + * <br>HIERARCHY_REQUEST_ERR: Raised if a DocumentType node would be + * extracted into the new DocumentFragment. + * <br>INVALID_STATE_ERR: Raised if <code>detach()</code> has already + * been invoked on this object. + */ + public DocumentFragment extractContents() + throws DOMException; + + /** + * Duplicates the contents of a Range + * @return A DocumentFragment that contains content equivalent to this + * Range. + * @exception DOMException + * HIERARCHY_REQUEST_ERR: Raised if a DocumentType node would be + * extracted into the new DocumentFragment. + * <br>INVALID_STATE_ERR: Raised if <code>detach()</code> has already + * been invoked on this object. + */ + public DocumentFragment cloneContents() + throws DOMException; + + /** + * Inserts a node into the Document or DocumentFragment at the start of + * the Range. If the container is a Text node, this will be split at the + * start of the Range (as if the Text node's splitText method was + * performed at the insertion point) and the insertion will occur + * between the two resulting Text nodes. Adjacent Text nodes will not be + * automatically merged. If the node to be inserted is a + * DocumentFragment node, the children will be inserted rather than the + * DocumentFragment node itself. + * @param newNode The node to insert at the start of the Range + * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised if an ancestor container of the + * start of the Range is read-only. + * <br>WRONG_DOCUMENT_ERR: Raised if <code>newNode</code> and the + * container of the start of the Range were not created from the same + * document. + * <br>HIERARCHY_REQUEST_ERR: Raised if the container of the start of + * the Range is of a type that does not allow children of the type of + * <code>newNode</code> or if <code>newNode</code> is an ancestor of + * the container. + * <br>INVALID_STATE_ERR: Raised if <code>detach()</code> has already + * been invoked on this object. + * @exception RangeException + * INVALID_NODE_TYPE_ERR: Raised if <code>newNode</code> is an Attr, + * Entity, Notation, or Document node. + */ + public void insertNode(Node newNode) + throws DOMException, RangeException; + + /** + * Reparents the contents of the Range to the given node and inserts the + * node at the position of the start of the Range. + * @param newParent The node to surround the contents with. + * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised if an ancestor container of + * either boundary-point of the Range is read-only. + * <br>WRONG_DOCUMENT_ERR: Raised if <code> newParent</code> and the + * container of the start of the Range were not created from the same + * document. + * <br>HIERARCHY_REQUEST_ERR: Raised if the container of the start of + * the Range is of a type that does not allow children of the type of + * <code>newParent</code> or if <code>newParent</code> is an ancestor + * of the container or if <code>node</code> would end up with a child + * node of a type not allowed by the type of <code>node</code>. + * <br>INVALID_STATE_ERR: Raised if <code>detach()</code> has already + * been invoked on this object. + * @exception RangeException + * BAD_BOUNDARYPOINTS_ERR: Raised if the Range partially selects a + * non-text node. + * <br>INVALID_NODE_TYPE_ERR: Raised if <code> node</code> is an Attr, + * Entity, DocumentType, Notation, Document, or DocumentFragment node. + */ + public void surroundContents(Node newParent) + throws DOMException, RangeException; + + /** + * Produces a new Range whose boundary-points are equal to the + * boundary-points of the Range. + * @return The duplicated Range. + * @exception DOMException + * INVALID_STATE_ERR: Raised if <code>detach()</code> has already been + * invoked on this object. + */ + public Range cloneRange() + throws DOMException; + + /** + * Returns the contents of a Range as a string. This string contains only + * the data characters, not any markup. + * @return The contents of the Range. + * @exception DOMException + * INVALID_STATE_ERR: Raised if <code>detach()</code> has already been + * invoked on this object. + */ + public String toString() + throws DOMException; + + /** + * Called to indicate that the Range is no longer in use and that the + * implementation may relinquish any resources associated with this + * Range. Subsequent calls to any methods or attribute getters on this + * Range will result in a <code>DOMException</code> being thrown with an + * error code of <code>INVALID_STATE_ERR</code>. + * @exception DOMException + * INVALID_STATE_ERR: Raised if <code>detach()</code> has already been + * invoked on this object. + */ + public void detach() + throws DOMException; + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/ranges/RangeException.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/ranges/RangeException.java new file mode 100644 index 000000000..2dee8195b --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/ranges/RangeException.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.ranges; + +/** + * Range operations may throw a <code>RangeException</code> as specified in + * their method descriptions. + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Traversal-Range-20001113'>Document Object Model (DOM) Level 2 Traversal and Range Specification</a>. + * @since DOM Level 2 + */ +public class RangeException extends RuntimeException { + public RangeException(short code, String message) { + super(message); + this.code = code; + } + public short code; + // RangeExceptionCode + /** + * If the boundary-points of a Range do not meet specific requirements. + */ + public static final short BAD_BOUNDARYPOINTS_ERR = 1; + /** + * If the container of an boundary-point of a Range is being set to either + * a node of an invalid type or a node with an ancestor of an invalid + * type. + */ + public static final short INVALID_NODE_TYPE_ERR = 2; + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/stylesheets/DocumentStyle.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/stylesheets/DocumentStyle.java new file mode 100644 index 000000000..ecfba994c --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/stylesheets/DocumentStyle.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.stylesheets; + +/** + * The <code>DocumentStyle</code> interface provides a mechanism by which the + * style sheets embedded in a document can be retrieved. The expectation is + * that an instance of the <code>DocumentStyle</code> interface can be + * obtained by using binding-specific casting methods on an instance of the + * <code>Document</code> interface. + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113'>Document Object Model (DOM) Level 2 Style Specification</a>. + * @since DOM Level 2 + */ +public interface DocumentStyle { + /** + * A list containing all the style sheets explicitly linked into or + * embedded in a document. For HTML documents, this includes external + * style sheets, included via the HTML LINK element, and inline STYLE + * elements. In XML, this includes external style sheets, included via + * style sheet processing instructions (see [XML StyleSheet]). + */ + public StyleSheetList getStyleSheets(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/stylesheets/LinkStyle.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/stylesheets/LinkStyle.java new file mode 100644 index 000000000..c7560d647 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/stylesheets/LinkStyle.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.stylesheets; + +/** + * The <code>LinkStyle</code> interface provides a mechanism by which a style + * sheet can be retrieved from the node responsible for linking it into a + * document. An instance of the <code>LinkStyle</code> interface can be + * obtained using binding-specific casting methods on an instance of a + * linking node (<code>HTMLLinkElement</code>, <code>HTMLStyleElement</code> + * or <code>ProcessingInstruction</code> in DOM Level 2). + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113'>Document Object Model (DOM) Level 2 Style Specification</a>. + * @since DOM Level 2 + */ +public interface LinkStyle { + /** + * The style sheet. + */ + public StyleSheet getSheet(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/stylesheets/MediaList.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/stylesheets/MediaList.java new file mode 100644 index 000000000..000c90c43 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/stylesheets/MediaList.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.stylesheets; + +import org.w3c.dom.DOMException; + +/** + * The <code>MediaList</code> interface provides the abstraction of an + * ordered collection of media, without defining or constraining how this + * collection is implemented. An empty list is the same as a list that + * contains the medium <code>"all"</code>. + * <p> The items in the <code>MediaList</code> are accessible via an integral + * index, starting from 0. + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113'>Document Object Model (DOM) Level 2 Style Specification</a>. + * @since DOM Level 2 + */ +public interface MediaList { + /** + * The parsable textual representation of the media list. This is a + * comma-separated list of media. + */ + public String getMediaText(); + /** + * The parsable textual representation of the media list. This is a + * comma-separated list of media. + * @exception DOMException + * SYNTAX_ERR: Raised if the specified string value has a syntax error + * and is unparsable. + * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this media list is + * readonly. + */ + public void setMediaText(String mediaText) + throws DOMException; + + /** + * The number of media in the list. The range of valid media is + * <code>0</code> to <code>length-1</code> inclusive. + */ + public int getLength(); + + /** + * Returns the <code>index</code>th in the list. If <code>index</code> is + * greater than or equal to the number of media in the list, this + * returns <code>null</code>. + * @param index Index into the collection. + * @return The medium at the <code>index</code>th position in the + * <code>MediaList</code>, or <code>null</code> if that is not a valid + * index. + */ + public String item(int index); + + /** + * Deletes the medium indicated by <code>oldMedium</code> from the list. + * @param oldMedium The medium to delete in the media list. + * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised if this list is readonly. + * <br> NOT_FOUND_ERR: Raised if <code>oldMedium</code> is not in the + * list. + */ + public void deleteMedium(String oldMedium) + throws DOMException; + + /** + * Adds the medium <code>newMedium</code> to the end of the list. If the + * <code>newMedium</code> is already used, it is first removed. + * @param newMedium The new medium to add. + * @exception DOMException + * INVALID_CHARACTER_ERR: If the medium contains characters that are + * invalid in the underlying style language. + * <br> NO_MODIFICATION_ALLOWED_ERR: Raised if this list is readonly. + */ + public void appendMedium(String newMedium) + throws DOMException; + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/stylesheets/StyleSheet.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/stylesheets/StyleSheet.java new file mode 100644 index 000000000..828902817 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/stylesheets/StyleSheet.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.stylesheets; + +import org.w3c.dom.Node; + +/** + * The <code>StyleSheet</code> interface is the abstract base interface for + * any type of style sheet. It represents a single style sheet associated + * with a structured document. In HTML, the StyleSheet interface represents + * either an external style sheet, included via the HTML LINK element, or + * an inline STYLE element. In XML, this interface represents an external + * style sheet, included via a style sheet processing instruction. + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113'>Document Object Model (DOM) Level 2 Style Specification</a>. + * @since DOM Level 2 + */ +public interface StyleSheet { + /** + * This specifies the style sheet language for this style sheet. The + * style sheet language is specified as a content type (e.g. + * "text/css"). The content type is often specified in the + * <code>ownerNode</code>. Also see the type attribute definition for + * the <code>LINK</code> element in HTML 4.0, and the type + * pseudo-attribute for the XML style sheet processing instruction. + */ + public String getType(); + + /** + * <code>false</code> if the style sheet is applied to the document. + * <code>true</code> if it is not. Modifying this attribute may cause a + * new resolution of style for the document. A stylesheet only applies + * if both an appropriate medium definition is present and the disabled + * attribute is false. So, if the media doesn't apply to the current + * user agent, the <code>disabled</code> attribute is ignored. + */ + public boolean getDisabled(); + /** + * <code>false</code> if the style sheet is applied to the document. + * <code>true</code> if it is not. Modifying this attribute may cause a + * new resolution of style for the document. A stylesheet only applies + * if both an appropriate medium definition is present and the disabled + * attribute is false. So, if the media doesn't apply to the current + * user agent, the <code>disabled</code> attribute is ignored. + */ + public void setDisabled(boolean disabled); + + /** + * The node that associates this style sheet with the document. For HTML, + * this may be the corresponding <code>LINK</code> or <code>STYLE</code> + * element. For XML, it may be the linking processing instruction. For + * style sheets that are included by other style sheets, the value of + * this attribute is <code>null</code>. + */ + public Node getOwnerNode(); + + /** + * For style sheet languages that support the concept of style sheet + * inclusion, this attribute represents the including style sheet, if + * one exists. If the style sheet is a top-level style sheet, or the + * style sheet language does not support inclusion, the value of this + * attribute is <code>null</code>. + */ + public StyleSheet getParentStyleSheet(); + + /** + * If the style sheet is a linked style sheet, the value of its attribute + * is its location. For inline style sheets, the value of this attribute + * is <code>null</code>. See the href attribute definition for the + * <code>LINK</code> element in HTML 4.0, and the href pseudo-attribute + * for the XML style sheet processing instruction. + */ + public String getHref(); + + /** + * The advisory title. The title is often specified in the + * <code>ownerNode</code>. See the title attribute definition for the + * <code>LINK</code> element in HTML 4.0, and the title pseudo-attribute + * for the XML style sheet processing instruction. + */ + public String getTitle(); + + /** + * The intended destination media for style information. The media is + * often specified in the <code>ownerNode</code>. If no media has been + * specified, the <code>MediaList</code> will be empty. See the media + * attribute definition for the <code>LINK</code> element in HTML 4.0, + * and the media pseudo-attribute for the XML style sheet processing + * instruction . Modifying the media list may cause a change to the + * attribute <code>disabled</code>. + */ + public MediaList getMedia(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/stylesheets/StyleSheetList.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/stylesheets/StyleSheetList.java new file mode 100644 index 000000000..6bb085fca --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/stylesheets/StyleSheetList.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.stylesheets; + +/** + * The <code>StyleSheetList</code> interface provides the abstraction of an + * ordered collection of style sheets. + * <p> The items in the <code>StyleSheetList</code> are accessible via an + * integral index, starting from 0. + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113'>Document Object Model (DOM) Level 2 Style Specification</a>. + * @since DOM Level 2 + */ +public interface StyleSheetList { + /** + * The number of <code>StyleSheets</code> in the list. The range of valid + * child stylesheet indices is <code>0</code> to <code>length-1</code> + * inclusive. + */ + public int getLength(); + + /** + * Used to retrieve a style sheet by ordinal index. If index is greater + * than or equal to the number of style sheets in the list, this returns + * <code>null</code>. + * @param index Index into the collection + * @return The style sheet at the <code>index</code> position in the + * <code>StyleSheetList</code>, or <code>null</code> if that is not a + * valid index. + */ + public StyleSheet item(int index); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/traversal/DocumentTraversal.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/traversal/DocumentTraversal.java new file mode 100644 index 000000000..e68d656f2 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/traversal/DocumentTraversal.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.traversal; + +import org.w3c.dom.Node; +import org.w3c.dom.DOMException; + +/** + * <code>DocumentTraversal</code> contains methods that create + * <code>NodeIterators</code> and <code>TreeWalkers</code> to traverse a + * node and its children in document order (depth first, pre-order + * traversal, which is equivalent to the order in which the start tags occur + * in the text representation of the document). In DOMs which support the + * Traversal feature, <code>DocumentTraversal</code> will be implemented by + * the same objects that implement the Document interface. + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Traversal-Range-20001113'>Document Object Model (DOM) Level 2 Traversal and Range Specification</a>. + * @since DOM Level 2 + */ +public interface DocumentTraversal { + /** + * Create a new <code>NodeIterator</code> over the subtree rooted at the + * specified node. + * @param root The node which will be iterated together with its + * children. The <code>NodeIterator</code> is initially positioned + * just before this node. The <code>whatToShow</code> flags and the + * filter, if any, are not considered when setting this position. The + * root must not be <code>null</code>. + * @param whatToShow This flag specifies which node types may appear in + * the logical view of the tree presented by the + * <code>NodeIterator</code>. See the description of + * <code>NodeFilter</code> for the set of possible <code>SHOW_</code> + * values.These flags can be combined using <code>OR</code>. + * @param filter The <code>NodeFilter</code> to be used with this + * <code>NodeIterator</code>, or <code>null</code> to indicate no + * filter. + * @param entityReferenceExpansion The value of this flag determines + * whether entity reference nodes are expanded. + * @return The newly created <code>NodeIterator</code>. + * @exception DOMException + * NOT_SUPPORTED_ERR: Raised if the specified <code>root</code> is + * <code>null</code>. + */ + public NodeIterator createNodeIterator(Node root, + int whatToShow, + NodeFilter filter, + boolean entityReferenceExpansion) + throws DOMException; + + /** + * Create a new <code>TreeWalker</code> over the subtree rooted at the + * specified node. + * @param root The node which will serve as the <code>root</code> for the + * <code>TreeWalker</code>. The <code>whatToShow</code> flags and the + * <code>NodeFilter</code> are not considered when setting this value; + * any node type will be accepted as the <code>root</code>. The + * <code>currentNode</code> of the <code>TreeWalker</code> is + * initialized to this node, whether or not it is visible. The + * <code>root</code> functions as a stopping point for traversal + * methods that look upward in the document structure, such as + * <code>parentNode</code> and nextNode. The <code>root</code> must + * not be <code>null</code>. + * @param whatToShow This flag specifies which node types may appear in + * the logical view of the tree presented by the + * <code>TreeWalker</code>. See the description of + * <code>NodeFilter</code> for the set of possible <code>SHOW_</code> + * values.These flags can be combined using <code>OR</code>. + * @param filter The <code>NodeFilter</code> to be used with this + * <code>TreeWalker</code>, or <code>null</code> to indicate no filter. + * @param entityReferenceExpansion If this flag is false, the contents of + * <code>EntityReference</code> nodes are not presented in the logical + * view. + * @return The newly created <code>TreeWalker</code>. + * @exception DOMException + * NOT_SUPPORTED_ERR: Raised if the specified <code>root</code> is + * <code>null</code>. + */ + public TreeWalker createTreeWalker(Node root, + int whatToShow, + NodeFilter filter, + boolean entityReferenceExpansion) + throws DOMException; + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/traversal/NodeFilter.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/traversal/NodeFilter.java new file mode 100644 index 000000000..554775078 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/traversal/NodeFilter.java @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.traversal; + +import org.w3c.dom.Node; + +/** + * Filters are objects that know how to "filter out" nodes. If a + * <code>NodeIterator</code> or <code>TreeWalker</code> is given a + * <code>NodeFilter</code>, it applies the filter before it returns the next + * node. If the filter says to accept the node, the traversal logic returns + * it; otherwise, traversal looks for the next node and pretends that the + * node that was rejected was not there. + * <p>The DOM does not provide any filters. <code>NodeFilter</code> is just an + * interface that users can implement to provide their own filters. + * <p><code>NodeFilters</code> do not need to know how to traverse from node + * to node, nor do they need to know anything about the data structure that + * is being traversed. This makes it very easy to write filters, since the + * only thing they have to know how to do is evaluate a single node. One + * filter may be used with a number of different kinds of traversals, + * encouraging code reuse. + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Traversal-Range-20001113'>Document Object Model (DOM) Level 2 Traversal and Range Specification</a>. + * @since DOM Level 2 + */ +public interface NodeFilter { + // Constants returned by acceptNode + /** + * Accept the node. Navigation methods defined for + * <code>NodeIterator</code> or <code>TreeWalker</code> will return this + * node. + */ + public static final short FILTER_ACCEPT = 1; + /** + * Reject the node. Navigation methods defined for + * <code>NodeIterator</code> or <code>TreeWalker</code> will not return + * this node. For <code>TreeWalker</code>, the children of this node + * will also be rejected. <code>NodeIterators</code> treat this as a + * synonym for <code>FILTER_SKIP</code>. + */ + public static final short FILTER_REJECT = 2; + /** + * Skip this single node. Navigation methods defined for + * <code>NodeIterator</code> or <code>TreeWalker</code> will not return + * this node. For both <code>NodeIterator</code> and + * <code>TreeWalker</code>, the children of this node will still be + * considered. + */ + public static final short FILTER_SKIP = 3; + + // Constants for whatToShow + /** + * Show all <code>Nodes</code>. + */ + public static final int SHOW_ALL = 0xFFFFFFFF; + /** + * Show <code>Element</code> nodes. + */ + public static final int SHOW_ELEMENT = 0x00000001; + /** + * Show <code>Attr</code> nodes. This is meaningful only when creating an + * <code>NodeIterator</code> or <code>TreeWalker</code> with an + * attribute node as its <code>root</code>; in this case, it means that + * the attribute node will appear in the first position of the iteration + * or traversal. Since attributes are never children of other nodes, + * they do not appear when traversing over the document tree. + */ + public static final int SHOW_ATTRIBUTE = 0x00000002; + /** + * Show <code>Text</code> nodes. + */ + public static final int SHOW_TEXT = 0x00000004; + /** + * Show <code>CDATASection</code> nodes. + */ + public static final int SHOW_CDATA_SECTION = 0x00000008; + /** + * Show <code>EntityReference</code> nodes. + */ + public static final int SHOW_ENTITY_REFERENCE = 0x00000010; + /** + * Show <code>Entity</code> nodes. This is meaningful only when creating + * an <code>NodeIterator</code> or <code>TreeWalker</code> with an + * <code>Entity</code> node as its <code>root</code>; in this case, it + * means that the <code>Entity</code> node will appear in the first + * position of the traversal. Since entities are not part of the + * document tree, they do not appear when traversing over the document + * tree. + */ + public static final int SHOW_ENTITY = 0x00000020; + /** + * Show <code>ProcessingInstruction</code> nodes. + */ + public static final int SHOW_PROCESSING_INSTRUCTION = 0x00000040; + /** + * Show <code>Comment</code> nodes. + */ + public static final int SHOW_COMMENT = 0x00000080; + /** + * Show <code>Document</code> nodes. + */ + public static final int SHOW_DOCUMENT = 0x00000100; + /** + * Show <code>DocumentType</code> nodes. + */ + public static final int SHOW_DOCUMENT_TYPE = 0x00000200; + /** + * Show <code>DocumentFragment</code> nodes. + */ + public static final int SHOW_DOCUMENT_FRAGMENT = 0x00000400; + /** + * Show <code>Notation</code> nodes. This is meaningful only when creating + * an <code>NodeIterator</code> or <code>TreeWalker</code> with a + * <code>Notation</code> node as its <code>root</code>; in this case, it + * means that the <code>Notation</code> node will appear in the first + * position of the traversal. Since notations are not part of the + * document tree, they do not appear when traversing over the document + * tree. + */ + public static final int SHOW_NOTATION = 0x00000800; + + /** + * Test whether a specified node is visible in the logical view of a + * <code>TreeWalker</code> or <code>NodeIterator</code>. This function + * will be called by the implementation of <code>TreeWalker</code> and + * <code>NodeIterator</code>; it is not normally called directly from + * user code. (Though you could do so if you wanted to use the same + * filter to guide your own application logic.) + * @param n The node to check to see if it passes the filter or not. + * @return A constant to determine whether the node is accepted, + * rejected, or skipped, as defined above. + */ + public short acceptNode(Node n); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/traversal/NodeIterator.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/traversal/NodeIterator.java new file mode 100644 index 000000000..40deef2f3 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/traversal/NodeIterator.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.traversal; + +import org.w3c.dom.Node; +import org.w3c.dom.DOMException; + +/** + * <code>NodeIterators</code> are used to step through a set of nodes, e.g. + * the set of nodes in a <code>NodeList</code>, the document subtree + * governed by a particular <code>Node</code>, the results of a query, or + * any other set of nodes. The set of nodes to be iterated is determined by + * the implementation of the <code>NodeIterator</code>. DOM Level 2 + * specifies a single <code>NodeIterator</code> implementation for + * document-order traversal of a document subtree. Instances of these + * <code>NodeIterators</code> are created by calling + * <code>DocumentTraversal</code><code>.createNodeIterator()</code>. + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Traversal-Range-20001113'>Document Object Model (DOM) Level 2 Traversal and Range Specification</a>. + * @since DOM Level 2 + */ +public interface NodeIterator { + /** + * The root node of the <code>NodeIterator</code>, as specified when it + * was created. + */ + public Node getRoot(); + + /** + * This attribute determines which node types are presented via the + * <code>NodeIterator</code>. The available set of constants is defined + * in the <code>NodeFilter</code> interface. Nodes not accepted by + * <code>whatToShow</code> will be skipped, but their children may still + * be considered. Note that this skip takes precedence over the filter, + * if any. + */ + public int getWhatToShow(); + + /** + * The <code>NodeFilter</code> used to screen nodes. + */ + public NodeFilter getFilter(); + + /** + * The value of this flag determines whether the children of entity + * reference nodes are visible to the <code>NodeIterator</code>. If + * false, these children and their descendants will be rejected. Note + * that this rejection takes precedence over <code>whatToShow</code> and + * the filter. Also note that this is currently the only situation where + * <code>NodeIterators</code> may reject a complete subtree rather than + * skipping individual nodes. + * <br> + * <br> To produce a view of the document that has entity references + * expanded and does not expose the entity reference node itself, use + * the <code>whatToShow</code> flags to hide the entity reference node + * and set <code>expandEntityReferences</code> to true when creating the + * <code>NodeIterator</code>. To produce a view of the document that has + * entity reference nodes but no entity expansion, use the + * <code>whatToShow</code> flags to show the entity reference node and + * set <code>expandEntityReferences</code> to false. + */ + public boolean getExpandEntityReferences(); + + /** + * Returns the next node in the set and advances the position of the + * <code>NodeIterator</code> in the set. After a + * <code>NodeIterator</code> is created, the first call to + * <code>nextNode()</code> returns the first node in the set. + * @return The next <code>Node</code> in the set being iterated over, or + * <code>null</code> if there are no more members in that set. + * @exception DOMException + * INVALID_STATE_ERR: Raised if this method is called after the + * <code>detach</code> method was invoked. + */ + public Node nextNode() + throws DOMException; + + /** + * Returns the previous node in the set and moves the position of the + * <code>NodeIterator</code> backwards in the set. + * @return The previous <code>Node</code> in the set being iterated over, + * or <code>null</code> if there are no more members in that set. + * @exception DOMException + * INVALID_STATE_ERR: Raised if this method is called after the + * <code>detach</code> method was invoked. + */ + public Node previousNode() + throws DOMException; + + /** + * Detaches the <code>NodeIterator</code> from the set which it iterated + * over, releasing any computational resources and placing the + * <code>NodeIterator</code> in the INVALID state. After + * <code>detach</code> has been invoked, calls to <code>nextNode</code> + * or <code>previousNode</code> will raise the exception + * INVALID_STATE_ERR. + */ + public void detach(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/traversal/TreeWalker.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/traversal/TreeWalker.java new file mode 100644 index 000000000..74527f30d --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/traversal/TreeWalker.java @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.traversal; + +import org.w3c.dom.Node; +import org.w3c.dom.DOMException; + +/** + * <code>TreeWalker</code> objects are used to navigate a document tree or + * subtree using the view of the document defined by their + * <code>whatToShow</code> flags and filter (if any). Any function which + * performs navigation using a <code>TreeWalker</code> will automatically + * support any view defined by a <code>TreeWalker</code>. + * <p>Omitting nodes from the logical view of a subtree can result in a + * structure that is substantially different from the same subtree in the + * complete, unfiltered document. Nodes that are siblings in the + * <code>TreeWalker</code> view may be children of different, widely + * separated nodes in the original view. For instance, consider a + * <code>NodeFilter</code> that skips all nodes except for Text nodes and + * the root node of a document. In the logical view that results, all text + * nodes will be siblings and appear as direct children of the root node, no + * matter how deeply nested the structure of the original document. + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Traversal-Range-20001113'>Document Object Model (DOM) Level 2 Traversal and Range Specification</a>. + * @since DOM Level 2 + */ +public interface TreeWalker { + /** + * The <code>root</code> node of the <code>TreeWalker</code>, as specified + * when it was created. + */ + public Node getRoot(); + + /** + * This attribute determines which node types are presented via the + * <code>TreeWalker</code>. The available set of constants is defined in + * the <code>NodeFilter</code> interface. Nodes not accepted by + * <code>whatToShow</code> will be skipped, but their children may still + * be considered. Note that this skip takes precedence over the filter, + * if any. + */ + public int getWhatToShow(); + + /** + * The filter used to screen nodes. + */ + public NodeFilter getFilter(); + + /** + * The value of this flag determines whether the children of entity + * reference nodes are visible to the <code>TreeWalker</code>. If false, + * these children and their descendants will be rejected. Note that + * this rejection takes precedence over <code>whatToShow</code> and the + * filter, if any. + * <br> To produce a view of the document that has entity references + * expanded and does not expose the entity reference node itself, use + * the <code>whatToShow</code> flags to hide the entity reference node + * and set <code>expandEntityReferences</code> to true when creating the + * <code>TreeWalker</code>. To produce a view of the document that has + * entity reference nodes but no entity expansion, use the + * <code>whatToShow</code> flags to show the entity reference node and + * set <code>expandEntityReferences</code> to false. + */ + public boolean getExpandEntityReferences(); + + /** + * The node at which the <code>TreeWalker</code> is currently positioned. + * <br>Alterations to the DOM tree may cause the current node to no longer + * be accepted by the <code>TreeWalker</code>'s associated filter. + * <code>currentNode</code> may also be explicitly set to any node, + * whether or not it is within the subtree specified by the + * <code>root</code> node or would be accepted by the filter and + * <code>whatToShow</code> flags. Further traversal occurs relative to + * <code>currentNode</code> even if it is not part of the current view, + * by applying the filters in the requested direction; if no traversal + * is possible, <code>currentNode</code> is not changed. + */ + public Node getCurrentNode(); + /** + * The node at which the <code>TreeWalker</code> is currently positioned. + * <br>Alterations to the DOM tree may cause the current node to no longer + * be accepted by the <code>TreeWalker</code>'s associated filter. + * <code>currentNode</code> may also be explicitly set to any node, + * whether or not it is within the subtree specified by the + * <code>root</code> node or would be accepted by the filter and + * <code>whatToShow</code> flags. Further traversal occurs relative to + * <code>currentNode</code> even if it is not part of the current view, + * by applying the filters in the requested direction; if no traversal + * is possible, <code>currentNode</code> is not changed. + * @exception DOMException + * NOT_SUPPORTED_ERR: Raised if an attempt is made to set + * <code>currentNode</code> to <code>null</code>. + */ + public void setCurrentNode(Node currentNode) + throws DOMException; + + /** + * Moves to and returns the closest visible ancestor node of the current + * node. If the search for <code>parentNode</code> attempts to step + * upward from the <code>TreeWalker</code>'s <code>root</code> node, or + * if it fails to find a visible ancestor node, this method retains the + * current position and returns <code>null</code>. + * @return The new parent node, or <code>null</code> if the current node + * has no parent in the <code>TreeWalker</code>'s logical view. + */ + public Node parentNode(); + + /** + * Moves the <code>TreeWalker</code> to the first visible child of the + * current node, and returns the new node. If the current node has no + * visible children, returns <code>null</code>, and retains the current + * node. + * @return The new node, or <code>null</code> if the current node has no + * visible children in the <code>TreeWalker</code>'s logical view. + */ + public Node firstChild(); + + /** + * Moves the <code>TreeWalker</code> to the last visible child of the + * current node, and returns the new node. If the current node has no + * visible children, returns <code>null</code>, and retains the current + * node. + * @return The new node, or <code>null</code> if the current node has no + * children in the <code>TreeWalker</code>'s logical view. + */ + public Node lastChild(); + + /** + * Moves the <code>TreeWalker</code> to the previous sibling of the + * current node, and returns the new node. If the current node has no + * visible previous sibling, returns <code>null</code>, and retains the + * current node. + * @return The new node, or <code>null</code> if the current node has no + * previous sibling. in the <code>TreeWalker</code>'s logical view. + */ + public Node previousSibling(); + + /** + * Moves the <code>TreeWalker</code> to the next sibling of the current + * node, and returns the new node. If the current node has no visible + * next sibling, returns <code>null</code>, and retains the current node. + * @return The new node, or <code>null</code> if the current node has no + * next sibling. in the <code>TreeWalker</code>'s logical view. + */ + public Node nextSibling(); + + /** + * Moves the <code>TreeWalker</code> to the previous visible node in + * document order relative to the current node, and returns the new + * node. If the current node has no previous node, or if the search for + * <code>previousNode</code> attempts to step upward from the + * <code>TreeWalker</code>'s <code>root</code> node, returns + * <code>null</code>, and retains the current node. + * @return The new node, or <code>null</code> if the current node has no + * previous node in the <code>TreeWalker</code>'s logical view. + */ + public Node previousNode(); + + /** + * Moves the <code>TreeWalker</code> to the next visible node in document + * order relative to the current node, and returns the new node. If the + * current node has no next node, or if the search for nextNode attempts + * to step upward from the <code>TreeWalker</code>'s <code>root</code> + * node, returns <code>null</code>, and retains the current node. + * @return The new node, or <code>null</code> if the current node has no + * next node in the <code>TreeWalker</code>'s logical view. + */ + public Node nextNode(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/views/AbstractView.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/views/AbstractView.java new file mode 100644 index 000000000..b024cc780 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/views/AbstractView.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.views; + +/** + * A base interface that all views shall derive from. + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Views-20001113'>Document Object Model (DOM) Level 2 Views Specification</a>. + * @since DOM Level 2 + */ +public interface AbstractView { + /** + * The source <code>DocumentView</code> of which this is an + * <code>AbstractView</code>. + */ + public DocumentView getDocument(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/views/DocumentView.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/views/DocumentView.java new file mode 100644 index 000000000..37dfbe1a3 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/views/DocumentView.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom.views; + +/** + * The <code>DocumentView</code> interface is implemented by + * <code>Document</code> objects in DOM implementations supporting DOM + * Views. It provides an attribute to retrieve the default view of a + * document. + * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Views-20001113'>Document Object Model (DOM) Level 2 Views Specification</a>. + * @since DOM Level 2 + */ +public interface DocumentView { + /** + * The default <code>AbstractView</code> for this <code>Document</code>, + * or <code>null</code> if none available. + */ + public AbstractView getDefaultView(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/xpath/XPathEvaluator.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/xpath/XPathEvaluator.java new file mode 100644 index 000000000..848c67329 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/xpath/XPathEvaluator.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom.xpath; + +import org.w3c.dom.Node; +import org.w3c.dom.DOMException; + +/** + * The evaluation of XPath expressions is provided by + * <code>XPathEvaluator</code>. In a DOM implementation which supports the + * XPath 3.0 feature, as described above, the <code>XPathEvaluator</code> + * interface will be implemented on the same object which implements the + * <code>Document</code> interface permitting it to be obtained by the usual + * binding-specific method such as casting or by using the DOM Level 3 + * getInterface method. In this case the implementation obtained from the + * Document supports the XPath DOM module and is compatible with the XPath + * 1.0 specification. + * <p>Evaluation of expressions with specialized extension functions or + * variables may not work in all implementations and is, therefore, not + * portable. <code>XPathEvaluator</code> implementations may be available + * from other sources that could provide specific support for specialized + * extension functions or variables as would be defined by other + * specifications. + * <p>See also the <a href='http://www.w3.org/TR/2004/NOTE-DOM-Level-3-XPath-20040226'>Document Object Model (DOM) Level 3 XPath Specification</a>. + */ +public interface XPathEvaluator { + /** + * Creates a parsed XPath expression with resolved namespaces. This is + * useful when an expression will be reused in an application since it + * makes it possible to compile the expression string into a more + * efficient internal form and preresolve all namespace prefixes which + * occur within the expression. + * @param expression The XPath expression string to be parsed. + * @param resolver The <code>resolver</code> permits translation of all + * prefixes, including the <code>xml</code> namespace prefix, within + * the XPath expression into appropriate namespace URIs. If this is + * specified as <code>null</code>, any namespace prefix within the + * expression will result in <code>DOMException</code> being thrown + * with the code <code>NAMESPACE_ERR</code>. + * @return The compiled form of the XPath expression. + * @exception XPathException + * INVALID_EXPRESSION_ERR: Raised if the expression is not legal + * according to the rules of the <code>XPathEvaluator</code>. + * @exception DOMException + * NAMESPACE_ERR: Raised if the expression contains namespace prefixes + * which cannot be resolved by the specified + * <code>XPathNSResolver</code>. + */ + public XPathExpression createExpression(String expression, + XPathNSResolver resolver) + throws XPathException, DOMException; + + /** + * Adapts any DOM node to resolve namespaces so that an XPath expression + * can be easily evaluated relative to the context of the node where it + * appeared within the document. This adapter works like the DOM Level 3 + * method <code>lookupNamespaceURI</code> on nodes in resolving the + * namespaceURI from a given prefix using the current information + * available in the node's hierarchy at the time lookupNamespaceURI is + * called. also correctly resolving the implicit xml prefix. + * @param nodeResolver The node to be used as a context for namespace + * resolution. + * @return <code>XPathNSResolver</code> which resolves namespaces with + * respect to the definitions in scope for a specified node. + */ + public XPathNSResolver createNSResolver(Node nodeResolver); + + /** + * Evaluates an XPath expression string and returns a result of the + * specified type if possible. + * @param expression The XPath expression string to be parsed and + * evaluated. + * @param contextNode The <code>context</code> is context node for the + * evaluation of this XPath expression. If the XPathEvaluator was + * obtained by casting the <code>Document</code> then this must be + * owned by the same document and must be a <code>Document</code>, + * <code>Element</code>, <code>Attribute</code>, <code>Text</code>, + * <code>CDATASection</code>, <code>Comment</code>, + * <code>ProcessingInstruction</code>, or <code>XPathNamespace</code> + * node. If the context node is a <code>Text</code> or a + * <code>CDATASection</code>, then the context is interpreted as the + * whole logical text node as seen by XPath, unless the node is empty + * in which case it may not serve as the XPath context. + * @param resolver The <code>resolver</code> permits translation of all + * prefixes, including the <code>xml</code> namespace prefix, within + * the XPath expression into appropriate namespace URIs. If this is + * specified as <code>null</code>, any namespace prefix within the + * expression will result in <code>DOMException</code> being thrown + * with the code <code>NAMESPACE_ERR</code>. + * @param type If a specific <code>type</code> is specified, then the + * result will be returned as the corresponding type.For XPath 1.0 + * results, this must be one of the codes of the + * <code>XPathResult</code> interface. + * @param result The <code>result</code> specifies a specific result + * object which may be reused and returned by this method. If this is + * specified as <code>null</code>or the implementation does not reuse + * the specified result, a new result object will be constructed and + * returned.For XPath 1.0 results, this object will be of type + * <code>XPathResult</code>. + * @return The result of the evaluation of the XPath expression.For XPath + * 1.0 results, this object will be of type <code>XPathResult</code>. + * @exception XPathException + * INVALID_EXPRESSION_ERR: Raised if the expression is not legal + * according to the rules of the <code>XPathEvaluator</code>i + * <br>TYPE_ERR: Raised if the result cannot be converted to return the + * specified type. + * @exception DOMException + * NAMESPACE_ERR: Raised if the expression contains namespace prefixes + * which cannot be resolved by the specified + * <code>XPathNSResolver</code>. + * <br>WRONG_DOCUMENT_ERR: The Node is from a document that is not + * supported by this <code>XPathEvaluator</code>. + * <br>NOT_SUPPORTED_ERR: The Node is not a type permitted as an XPath + * context node or the request type is not permitted by this + * <code>XPathEvaluator</code>. + */ + public Object evaluate(String expression, + Node contextNode, + XPathNSResolver resolver, + short type, + Object result) + throws XPathException, DOMException; + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/xpath/XPathException.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/xpath/XPathException.java new file mode 100644 index 000000000..6b13cdf00 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/xpath/XPathException.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom.xpath; + +/** + * A new exception has been created for exceptions specific to these XPath + * interfaces. + * <p>See also the <a href='http://www.w3.org/TR/2004/NOTE-DOM-Level-3-XPath-20040226'>Document Object Model (DOM) Level 3 XPath Specification</a>. + */ +public class XPathException extends RuntimeException { + public XPathException(short code, String message) { + super(message); + this.code = code; + } + public short code; + // XPathExceptionCode + /** + * If the expression has a syntax error or otherwise is not a legal + * expression according to the rules of the specific + * <code>XPathEvaluator</code> or contains specialized extension + * functions or variables not supported by this implementation. + */ + public static final short INVALID_EXPRESSION_ERR = 51; + /** + * If the expression cannot be converted to return the specified type. + */ + public static final short TYPE_ERR = 52; + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/xpath/XPathExpression.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/xpath/XPathExpression.java new file mode 100644 index 000000000..ab5d28c43 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/xpath/XPathExpression.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom.xpath; + +import org.w3c.dom.Node; +import org.w3c.dom.DOMException; + +/** + * The <code>XPathExpression</code> interface represents a parsed and resolved + * XPath expression. + * <p>See also the <a href='http://www.w3.org/TR/2004/NOTE-DOM-Level-3-XPath-20040226'>Document Object Model (DOM) Level 3 XPath Specification</a>. + */ +public interface XPathExpression { + /** + * Evaluates this XPath expression and returns a result. + * @param contextNode The <code>context</code> is context node for the + * evaluation of this XPath expression.If the XPathEvaluator was + * obtained by casting the <code>Document</code> then this must be + * owned by the same document and must be a <code>Document</code>, + * <code>Element</code>, <code>Attribute</code>, <code>Text</code>, + * <code>CDATASection</code>, <code>Comment</code>, + * <code>ProcessingInstruction</code>, or <code>XPathNamespace</code> + * node.If the context node is a <code>Text</code> or a + * <code>CDATASection</code>, then the context is interpreted as the + * whole logical text node as seen by XPath, unless the node is empty + * in which case it may not serve as the XPath context. + * @param type If a specific <code>type</code> is specified, then the + * result will be coerced to return the specified type relying on + * XPath conversions and fail if the desired coercion is not possible. + * This must be one of the type codes of <code>XPathResult</code>. + * @param result The <code>result</code> specifies a specific result + * object which may be reused and returned by this method. If this is + * specified as <code>null</code>or the implementation does not reuse + * the specified result, a new result object will be constructed and + * returned.For XPath 1.0 results, this object will be of type + * <code>XPathResult</code>. + * @return The result of the evaluation of the XPath expression.For XPath + * 1.0 results, this object will be of type <code>XPathResult</code>. + * @exception XPathException + * TYPE_ERR: Raised if the result cannot be converted to return the + * specified type. + * @exception DOMException + * WRONG_DOCUMENT_ERR: The Node is from a document that is not supported + * by the XPathEvaluator that created this <code>XPathExpression</code> + * . + * <br>NOT_SUPPORTED_ERR: The Node is not a type permitted as an XPath + * context node or the request type is not permitted by this + * <code>XPathExpression</code>. + */ + public Object evaluate(Node contextNode, + short type, + Object result) + throws XPathException, DOMException; + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/xpath/XPathNSResolver.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/xpath/XPathNSResolver.java new file mode 100644 index 000000000..5ce068de9 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/xpath/XPathNSResolver.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom.xpath; + +/** + * The <code>XPathNSResolver</code> interface permit <code>prefix</code> + * strings in the expression to be properly bound to + * <code>namespaceURI</code> strings. <code>XPathEvaluator</code> can + * construct an implementation of <code>XPathNSResolver</code> from a node, + * or the interface may be implemented by any application. + * <p>See also the <a href='http://www.w3.org/TR/2004/NOTE-DOM-Level-3-XPath-20040226'>Document Object Model (DOM) Level 3 XPath Specification</a>. + */ +public interface XPathNSResolver { + /** + * Look up the namespace URI associated to the given namespace prefix. The + * XPath evaluator must never call this with a <code>null</code> or + * empty argument, because the result of doing this is undefined. + * @param prefix The prefix to look for. + * @return Returns the associated namespace URI or <code>null</code> if + * none is found. + */ + public String lookupNamespaceURI(String prefix); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/xpath/XPathNamespace.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/xpath/XPathNamespace.java new file mode 100644 index 000000000..d644051f2 --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/xpath/XPathNamespace.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom.xpath; + +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +/** + * The <code>XPathNamespace</code> interface is returned by + * <code>XPathResult</code> interfaces to represent the XPath namespace node + * type that DOM lacks. There is no public constructor for this node type. + * Attempts to place it into a hierarchy or a NamedNodeMap result in a + * <code>DOMException</code> with the code <code>HIERARCHY_REQUEST_ERR</code> + * . This node is read only, so methods or setting of attributes that would + * mutate the node result in a DOMException with the code + * <code>NO_MODIFICATION_ALLOWED_ERR</code>. + * <p>The core specification describes attributes of the <code>Node</code> + * interface that are different for different node types but does not + * describe <code>XPATH_NAMESPACE_NODE</code>, so here is a description of + * those attributes for this node type. All attributes of <code>Node</code> + * not described in this section have a <code>null</code> or + * <code>false</code> value. + * <p><code>ownerDocument</code> matches the <code>ownerDocument</code> of the + * <code>ownerElement</code> even if the element is later adopted. + * <p><code>nodeName</code> is always the string "<code>#namespace</code>". + * <p><code>prefix</code> is the prefix of the namespace represented by the + * node. + * <p><code>localName</code> is the same as <code>prefix</code>. + * <p><code>nodeType</code> is equal to <code>XPATH_NAMESPACE_NODE</code>. + * <p><code>namespaceURI</code> is the namespace URI of the namespace + * represented by the node. + * <p><code>nodeValue</code> is the same as <code>namespaceURI</code>. + * <p><code>adoptNode</code>, <code>cloneNode</code>, and + * <code>importNode</code> fail on this node type by raising a + * <code>DOMException</code> with the code <code>NOT_SUPPORTED_ERR</code>. + * <p ><b>Note:</b> In future versions of the XPath specification, the + * definition of a namespace node may be changed incomatibly, in which case + * incompatible changes to field values may be required to implement + * versions beyond XPath 1.0. + * <p>See also the <a href='http://www.w3.org/TR/2004/NOTE-DOM-Level-3-XPath-20040226'>Document Object Model (DOM) Level 3 XPath Specification</a>. + */ +public interface XPathNamespace extends Node { + // XPathNodeType + /** + * The node is a <code>Namespace</code>. + */ + public static final short XPATH_NAMESPACE_NODE = 13; + + /** + * The <code>Element</code> on which the namespace was in scope when it + * was requested. This does not change on a returned namespace node even + * if the document changes such that the namespace goes out of scope on + * that element and this node is no longer found there by XPath. + */ + public Element getOwnerElement(); + +} diff --git a/libjava/classpath/external/w3c_dom/org/w3c/dom/xpath/XPathResult.java b/libjava/classpath/external/w3c_dom/org/w3c/dom/xpath/XPathResult.java new file mode 100644 index 000000000..06fd29dac --- /dev/null +++ b/libjava/classpath/external/w3c_dom/org/w3c/dom/xpath/XPathResult.java @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] 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. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +package org.w3c.dom.xpath; + +import org.w3c.dom.Node; +import org.w3c.dom.DOMException; + +/** + * The <code>XPathResult</code> interface represents the result of the + * evaluation of an XPath 1.0 expression within the context of a particular + * node. Since evaluation of an XPath expression can result in various + * result types, this object makes it possible to discover and manipulate + * the type and value of the result. + * <p>See also the <a href='http://www.w3.org/TR/2004/NOTE-DOM-Level-3-XPath-20040226'>Document Object Model (DOM) Level 3 XPath Specification</a>. + */ +public interface XPathResult { + // XPathResultType + /** + * This code does not represent a specific type. An evaluation of an XPath + * expression will never produce this type. If this type is requested, + * then the evaluation returns whatever type naturally results from + * evaluation of the expression. + * <br>If the natural result is a node set when <code>ANY_TYPE</code> was + * requested, then <code>UNORDERED_NODE_ITERATOR_TYPE</code> is always + * the resulting type. Any other representation of a node set must be + * explicitly requested. + */ + public static final short ANY_TYPE = 0; + /** + * The result is a <a href='http://www.w3.org/TR/1999/REC-xpath-19991116#numbers'>number</a> as defined by [<a href='http://www.w3.org/TR/1999/REC-xpath-19991116'>XPath 1.0</a>]. + * Document modification does not invalidate the number, but may mean + * that reevaluation would not yield the same number. + */ + public static final short NUMBER_TYPE = 1; + /** + * The result is a <a href='http://www.w3.org/TR/1999/REC-xpath-19991116#strings'>string</a> as defined by [<a href='http://www.w3.org/TR/1999/REC-xpath-19991116'>XPath 1.0</a>]. + * Document modification does not invalidate the string, but may mean + * that the string no longer corresponds to the current document. + */ + public static final short STRING_TYPE = 2; + /** + * The result is a <a href='http://www.w3.org/TR/1999/REC-xpath-19991116#booleans'>boolean</a> as defined by [<a href='http://www.w3.org/TR/1999/REC-xpath-19991116'>XPath 1.0</a>]. + * Document modification does not invalidate the boolean, but may mean + * that reevaluation would not yield the same boolean. + */ + public static final short BOOLEAN_TYPE = 3; + /** + * The result is a <a href='http://www.w3.org/TR/1999/REC-xpath-19991116#node-sets'>node set</a> as defined by [<a href='http://www.w3.org/TR/1999/REC-xpath-19991116'>XPath 1.0</a>] that + * will be accessed iteratively, which may not produce nodes in a + * particular order. Document modification invalidates the iteration. + * <br>This is the default type returned if the result is a node set and + * <code>ANY_TYPE</code> is requested. + */ + public static final short UNORDERED_NODE_ITERATOR_TYPE = 4; + /** + * The result is a node set as defined by [<a href='http://www.w3.org/TR/1999/REC-xpath-19991116'>XPath 1.0</a>] that + * will be accessed iteratively, which will produce document-ordered + * nodes. Document modification invalidates the iteration. + */ + public static final short ORDERED_NODE_ITERATOR_TYPE = 5; + /** + * The result is a <a href='http://www.w3.org/TR/1999/REC-xpath-19991116#node-sets'>node set</a> as defined by [<a href='http://www.w3.org/TR/1999/REC-xpath-19991116'>XPath 1.0</a>] that + * will be accessed as a snapshot list of nodes that may not be in a + * particular order. Document modification does not invalidate the + * snapshot but may mean that reevaluation would not yield the same + * snapshot and nodes in the snapshot may have been altered, moved, or + * removed from the document. + */ + public static final short UNORDERED_NODE_SNAPSHOT_TYPE = 6; + /** + * The result is a <a href='http://www.w3.org/TR/1999/REC-xpath-19991116#node-sets'>node set</a> as defined by [<a href='http://www.w3.org/TR/1999/REC-xpath-19991116'>XPath 1.0</a>] that + * will be accessed as a snapshot list of nodes that will be in original + * document order. Document modification does not invalidate the + * snapshot but may mean that reevaluation would not yield the same + * snapshot and nodes in the snapshot may have been altered, moved, or + * removed from the document. + */ + public static final short ORDERED_NODE_SNAPSHOT_TYPE = 7; + /** + * The result is a <a href='http://www.w3.org/TR/1999/REC-xpath-19991116#node-sets'>node set</a> as defined by [<a href='http://www.w3.org/TR/1999/REC-xpath-19991116'>XPath 1.0</a>] and + * will be accessed as a single node, which may be <code>null</code>if + * the node set is empty. Document modification does not invalidate the + * node, but may mean that the result node no longer corresponds to the + * current document. This is a convenience that permits optimization + * since the implementation can stop once any node in the resulting set + * has been found. + * <br>If there is more than one node in the actual result, the single + * node returned might not be the first in document order. + */ + public static final short ANY_UNORDERED_NODE_TYPE = 8; + /** + * The result is a <a href='http://www.w3.org/TR/1999/REC-xpath-19991116#node-sets'>node set</a> as defined by [<a href='http://www.w3.org/TR/1999/REC-xpath-19991116'>XPath 1.0</a>] and + * will be accessed as a single node, which may be <code>null</code> if + * the node set is empty. Document modification does not invalidate the + * node, but may mean that the result node no longer corresponds to the + * current document. This is a convenience that permits optimization + * since the implementation can stop once the first node in document + * order of the resulting set has been found. + * <br>If there are more than one node in the actual result, the single + * node returned will be the first in document order. + */ + public static final short FIRST_ORDERED_NODE_TYPE = 9; + + /** + * A code representing the type of this result, as defined by the type + * constants. + */ + public short getResultType(); + + /** + * The value of this number result. If the native double type of the DOM + * binding does not directly support the exact IEEE 754 result of the + * XPath expression, then it is up to the definition of the binding to + * specify how the XPath number is converted to the native binding + * number. + * @exception XPathException + * TYPE_ERR: raised if <code>resultType</code> is not + * <code>NUMBER_TYPE</code>. + */ + public double getNumberValue() + throws XPathException; + + /** + * The value of this string result. + * @exception XPathException + * TYPE_ERR: raised if <code>resultType</code> is not + * <code>STRING_TYPE</code>. + */ + public String getStringValue() + throws XPathException; + + /** + * The value of this boolean result. + * @exception XPathException + * TYPE_ERR: raised if <code>resultType</code> is not + * <code>BOOLEAN_TYPE</code>. + */ + public boolean getBooleanValue() + throws XPathException; + + /** + * The value of this single node result, which may be <code>null</code>. + * @exception XPathException + * TYPE_ERR: raised if <code>resultType</code> is not + * <code>ANY_UNORDERED_NODE_TYPE</code> or + * <code>FIRST_ORDERED_NODE_TYPE</code>. + */ + public Node getSingleNodeValue() + throws XPathException; + + /** + * Signifies that the iterator has become invalid. True if + * <code>resultType</code> is <code>UNORDERED_NODE_ITERATOR_TYPE</code> + * or <code>ORDERED_NODE_ITERATOR_TYPE</code> and the document has been + * modified since this result was returned. + */ + public boolean getInvalidIteratorState(); + + /** + * The number of nodes in the result snapshot. Valid values for + * snapshotItem indices are <code>0</code> to + * <code>snapshotLength-1</code> inclusive. + * @exception XPathException + * TYPE_ERR: raised if <code>resultType</code> is not + * <code>UNORDERED_NODE_SNAPSHOT_TYPE</code> or + * <code>ORDERED_NODE_SNAPSHOT_TYPE</code>. + */ + public int getSnapshotLength() + throws XPathException; + + /** + * Iterates and returns the next node from the node set or + * <code>null</code>if there are no more nodes. + * @return Returns the next node. + * @exception XPathException + * TYPE_ERR: raised if <code>resultType</code> is not + * <code>UNORDERED_NODE_ITERATOR_TYPE</code> or + * <code>ORDERED_NODE_ITERATOR_TYPE</code>. + * @exception DOMException + * INVALID_STATE_ERR: The document has been mutated since the result was + * returned. + */ + public Node iterateNext() + throws XPathException, DOMException; + + /** + * Returns the <code>index</code>th item in the snapshot collection. If + * <code>index</code> is greater than or equal to the number of nodes in + * the list, this method returns <code>null</code>. Unlike the iterator + * result, the snapshot does not become invalid, but may not correspond + * to the current document if it is mutated. + * @param index Index into the snapshot collection. + * @return The node at the <code>index</code>th position in the + * <code>NodeList</code>, or <code>null</code> if that is not a valid + * index. + * @exception XPathException + * TYPE_ERR: raised if <code>resultType</code> is not + * <code>UNORDERED_NODE_SNAPSHOT_TYPE</code> or + * <code>ORDERED_NODE_SNAPSHOT_TYPE</code>. + */ + public Node snapshotItem(int index) + throws XPathException; + +} |