This commit is contained in:
Alejandro Murillo 2013-01-30 10:18:33 -08:00
commit 294ab2b404
646 changed files with 123056 additions and 3300 deletions

View File

@ -237,6 +237,9 @@ SUBDIRS = tools java javax sun com jdk
ifeq ($(PLATFORM), macosx)
SUBDIRS += apple
endif
ifeq ($(PLATFORM), windows)
SUBDIRS += bridge
endif
SUBDIRS_tools = launchers
SUBDIRS_misc = org jpda

View File

@ -0,0 +1,93 @@
#
# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Oracle designates this
# particular file as subject to the "Classpath" exception as provided
# by Oracle in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
#
# Makefile for building AccessBridge
#
BUILDDIR = ../..
PRODUCT = java
PACKAGE = com.sun.java.accessibility
include $(BUILDDIR)/common/Defs.gmk
JARFILE = $(EXTDIR)/access-bridge$(ABSUFFIX).jar
ifeq ($(ARCH_DATA_MODEL), 64)
ABPLATFORM = 64bit
ABSUFFIX = -64
else
ifeq ($(ARCH_DATA_MODEL), 32)
ifdef ABLEGACY
ABSUFFIX =
ABPLATFORM = legacy
else
ABPLATFORM = 32bit
ABSUFFIX = -32
endif
endif
endif
#
# Java files to compile.
#
FILES_java = com/sun/java/accessibility/AccessBridge.java
#
# Location for the newly built classfiles.
#
CLASSDESTDIR = $(TEMPDIR)/classes
#
# Rules
#
CLASSDESTDIR = $(TEMPDIR)/classes
FILES_class = $(FILES_java:%.java=$(CLASSDESTDIR)/%.class)
build: prebuild
prebuild:
$(CP) $(CLOSED_PLATFORM_SRC)/classes/com/sun/java/accessibility/$(ABPLATFORM)/AccessBridge.java \
$(CLOSED_PLATFORM_SRC)/classes/com/sun/java/accessibility
all : build $(JARFILE)
#
# JAR file
#
$(JARFILE): \
$(FILES_class)
$(BOOT_JAR_CMD) -cf $(JARFILE) \
-C $(CLASSDESTDIR) com \
$(BOOT_JAR_JFLAGS)
@$(java-vm-cleanup)
#
# Rules
#
include $(BUILDDIR)/common/Classes.gmk
clean clobber::
$(RM) -r $(CLASSDESTDIR) \
$(EXTDIR)/$(JARFILE)

View File

@ -0,0 +1,29 @@
#
# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Oracle designates this
# particular file as subject to the "Classpath" exception as provided
# by Oracle in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
#
# Native files to compile.
FILES_cpp = \
JAWTAccessBridge.cpp

View File

@ -0,0 +1,69 @@
#
# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Oracle designates this
# particular file as subject to the "Classpath" exception as provided
# by Oracle in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
#
# Makefile for building JAWTAccessBridge
#
BUILDDIR = ../..
LIBRARY = JAWTAccessBridge$(ABSUFFIX)
include $(BUILDDIR)/common/Defs.gmk
# Indicate we want the C++ compiler to do the linking.
CPLUSPLUSLIBRARY=true
ifeq ($(ARCH_DATA_MODEL), 64)
ABSUFFIX = -64
ACCESSBRIDGE_ARCH = ACCESSBRIDGE_ARCH_64
ABRIDGE_MACHINE=X64
else
ifeq ($(ARCH_DATA_MODEL), 32)
ABRIDGE_MACHINE=I386
ifdef ABLEGACY
ABSUFFIX =
ACCESSBRIDGE_ARCH = ACCESSBRIDGE_ARCH_LEGACY
else
ABSUFFIX = -32
ACCESSBRIDGE_ARCH = ACCESSBRIDGE_ARCH_32
endif
endif
endif
include FILES_cpp.gmk
VERSIONINFO_RESOURCE = $(CLOSED_PLATFORM_SRC)/native/sun/bridge/AccessBridgeStatusWindow.rc
OTHER_CPPFLAGS += -D$(ACCESSBRIDGE_ARCH) -I "$(INCLUDEDIR)" -I "$(PLATFORM_INCLUDE)"
LDLIBS += kernel32.lib user32.lib gdi32.lib winspool.lib jawt.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib \
uuid.lib odbc32.lib odbccp32.lib /subsystem:windows /dll /incremental:no /machine:$(ABRIDGE_MACHINE) \
/def:$(CLOSED_PLATFORM_SRC)/native/sun/bridge/JAWTAccessBridge.DEF /libpath:"$(LIBDIR)"
#
# Rules
#
include $(BUILDDIR)/common/Library.gmk
vpath %.cpp $(CLOSED_PLATFORM_SRC)/native/sun/bridge
vpath %.RC $(CLOSED_PLATFORM_SRC)/native/sun/bridge

View File

@ -0,0 +1,63 @@
#
# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Oracle designates this
# particular file as subject to the "Classpath" exception as provided
# by Oracle in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
#
# Makefile for building jabswitch.exe
#
BUILDDIR = ../..
PROGRAM = jabswitch
include $(BUILDDIR)/common/Defs.gmk
# Indicate we want the C++ compiler to do the linking.
CPLUSPLUSLIBRARY=true
VERSIONINFO_RESOURCE = $(CLOSED_PLATFORM_SRC)/native/sun/bridge/AccessBridgeStatusWindow.rc
VERSIONRES = $(TEMPDIR)/AccessBridgeStatusWindow.res
JAB_EXE= $(TEMPDIR)/jabswitch.exe
JAB_SRC = $(CLOSED_PLATFORM_SRC)/native/sun/bridge/jabswitch.cpp
JAB_MANIFEST_INP = $(CLOSED_PLATFORM_SRC)/native/sun/bridge/jabswitch.manifest
JAB_MANIFEST_OUT = $(TEMPDIR)/jabswitch.exe.intermediate.manifest
RC_FLAGS += /fo "$(VERSIONRES)"
OTHER_CPPFLAGS += /MD /Fo"$(TEMPDIR)/" /Fd"$(TEMPDIR)/" /analyze- /Od /Gd /nologo /D "WIN32" /D "_WINDOWS" /D "_UNICODE" /D "UNICODE" /RTC1 /W3 /ZI /Zc:wchar_t /EHsc
LDDFLAGS += Advapi32.lib Version.lib User32.lib
all: buildexe copyfilejab
buildexe :
$(CD) $(TEMPDIR)
$(RC) $(RC_FLAGS) $(VERSIONINFO_RESOURCE)
$(CC) $(CPPFLAGS) $(JAB_SRC) $(LDDFLAGS) $(VERSIONRES) -o $(JAB_EXE)
$(MT) /nologo /verbose /manifest $(JAB_MANIFEST_INP) /outputresource:$(JAB_EXE)
copyfilejab :
$(CP) $(JAB_EXE) $(BINDIR)
vpath %.cpp $(CLOSED_PLATFORM_SRC)/native/sun/bridge
vpath %.rc $(CLOSED_PLATFORM_SRC)/native/sun/bridge

View File

@ -0,0 +1,85 @@
#
# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Oracle designates this
# particular file as subject to the "Classpath" exception as provided
# by Oracle in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
#
# Makefile for building jaccess
#
BUILDDIR = ../..
PRODUCT = java
PACKAGE = com.sun.java.accessibility.jaccess
include $(BUILDDIR)/common/Defs.gmk
JARFILE = $(EXTDIR)/jaccess.jar
#
# Java files to compile.
#
#AUTO_FILES_JAVA_DIRS = $(CLOSED_PLATFORM_SRC)/bridge
FILES_java = \
com/sun/java/accessibility/util/AccessibilityEventMonitor.java \
com/sun/java/accessibility/util/AccessibilityListenerList.java \
com/sun/java/accessibility/util/AWTEventMonitor.java \
com/sun/java/accessibility/util/EventID.java \
com/sun/java/accessibility/util/EventQueueMonitor.java \
com/sun/java/accessibility/util/GUIInitializedListener.java \
com/sun/java/accessibility/util/GUIInitializedMulticaster.java \
com/sun/java/accessibility/util/SwingEventMonitor.java \
com/sun/java/accessibility/util/TopLevelWindowListener.java \
com/sun/java/accessibility/util/TopLevelWindowMulticaster.java \
com/sun/java/accessibility/util/Translator.java \
com/sun/java/accessibility/util/java/awt/ButtonTranslator.java \
com/sun/java/accessibility/util/java/awt/CheckboxTranslator.java \
com/sun/java/accessibility/util/java/awt/LabelTranslator.java \
com/sun/java/accessibility/util/java/awt/ListTranslator.java \
com/sun/java/accessibility/util/java/awt/TextComponentTranslator.java
#
# Rules
#
CLASSDESTDIR = $(TEMPDIR)/classes
FILES_class = $(FILES_java:%.java=$(CLASSDESTDIR)/%.class)
all : build $(JARFILE)
#
# JAR file
#
$(JARFILE): \
$(FILES_class)
$(BOOT_JAR_CMD) -cf $(JARFILE) \
-C $(CLASSDESTDIR) com \
$(BOOT_JAR_JFLAGS)
@$(java-vm-cleanup)
#
# Rules
#
include $(BUILDDIR)/common/Classes.gmk
clean clobber::
$(RM) -r $(CLASSDESTDIR) \
$(EXTDIR)/$(JARFILE)

View File

@ -0,0 +1,33 @@
#
# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Oracle designates this
# particular file as subject to the "Classpath" exception as provided
# by Oracle in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
#
# Native files to compile.
FILES_cpp = \
AccessBridgeATInstance.cpp \
AccessBridgeDebug.cpp \
AccessBridgeJavaEntryPoints.cpp \
AccessBridgeMessages.cpp \
JavaAccessBridge.cpp

View File

@ -0,0 +1,90 @@
#
# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Oracle designates this
# particular file as subject to the "Classpath" exception as provided
# by Oracle in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
#
# Makefile for building JavaAccessBridge.DLL
#
BUILDDIR = ../..
LIBRARY = JavaAccessBridge$(ABSUFFIX)
include $(BUILDDIR)/common/Defs.gmk
# Indicate we want the C++ compiler to do the linking.
CPLUSPLUSLIBRARY=true
ifeq ($(ARCH_DATA_MODEL), 64)
ABSUFFIX = -64
ACCESSBRIDGE_ARCH = ACCESSBRIDGE_ARCH_64
ABRIDGE_MACHINE=X64
else
ifeq ($(ARCH_DATA_MODEL), 32)
ABRIDGE_MACHINE=I386
ifdef ABLEGACY
ABSUFFIX =
ACCESSBRIDGE_ARCH = ACCESSBRIDGE_ARCH_LEGACY
else
ABSUFFIX = -32
ACCESSBRIDGE_ARCH = ACCESSBRIDGE_ARCH_32
endif
endif
endif
include FILES_cpp.gmk
PLATFORM_INCLUDE_BRIDGE = $(PLATFORM_INCLUDE)/bridge
VERSIONINFO_RESOURCE = $(CLOSED_PLATFORM_SRC)/native/sun/bridge/AccessBridgeStatusWindow.rc
OTHER_CPPFLAGS += -D$(ACCESSBRIDGE_ARCH) -I "$(INCLUDEDIR)" -I "$(PLATFORM_INCLUDE)"
LDLIBS += kernel32.lib user32.lib gdi32.lib winspool.lib jawt.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib \
odbc32.lib odbccp32.lib /subsystem:windows /dll /incremental:no /machine:$(ABRIDGE_MACHINE) \
/def:$(CLOSED_PLATFORM_SRC)/native/sun/bridge/JavaAccessBridge.DEF /libpath:"$(LIBDIR)"
all : build postbuild
postbuild :
$(MKDIR) -p $(PLATFORM_INCLUDE_BRIDGE)
$(CP) $(CLOSED_PLATFORM_SRC)/native/sun/bridge/accessibility.properties $(LIBDIR)
$(CP) $(CLOSED_PLATFORM_SRC)/native/sun/bridge/AccessBridgeCallbacks.h $(PLATFORM_INCLUDE_BRIDGE)
$(CP) $(CLOSED_PLATFORM_SRC)/native/sun/bridge/AccessBridgeCalls.h $(PLATFORM_INCLUDE_BRIDGE)
$(CP) $(CLOSED_PLATFORM_SRC)/native/sun/bridge/AccessBridgePackages.h $(PLATFORM_INCLUDE_BRIDGE)
$(CP) $(CLOSED_PLATFORM_SRC)/native/sun/bridge/AccessBridgeCalls.c $(PLATFORM_INCLUDE_BRIDGE)
#
# Rules
#
include $(BUILDDIR)/common/Library.gmk
vpath %.cpp $(CLOSED_PLATFORM_SRC)/native/sun/bridge
vpath %.DEF $(CLOSED_PLATFORM_SRC)/native/sun/bridge
vpath %.rc $(CLOSED_PLATFORM_SRC)/native/sun/bridge
vpath %.c $(CLOSED_PLATFORM_SRC)/native/sun/bridge
vpath %.h $(CLOSED_PLATFORM_SRC)/native/sun/bridge
#
# Extra clean rule.
#
clean clobber::
$(RM) $(FILES_h)

65
jdk/make/bridge/Makefile Normal file
View File

@ -0,0 +1,65 @@
#
# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Oracle designates this
# particular file as subject to the "Classpath" exception as provided
# by Oracle in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
#
# Makefile for building Java Access Bridge
#
BUILDDIR = ..
include $(BUILDDIR)/common/Defs.gmk
#
#
ifndef OPENJDK
ifeq ($(PLATFORM), windows)
include $(BUILDDIR)/common/Subdirs.gmk
#
# build for 32 and 64 bit (new api)
#
SUBDIRS = Jaccess JavaAccessBridge WindowsAccessBridge JAWTAccessBridge AccessBridgeJava Jabswitch
#
# build for legacy
#
ifeq ($(ARCH_DATA_MODEL), 32)
OTHERSUBDIRS_MAKEFLAGS += ABLEGACY=true
OTHERSUBDIRS = JavaAccessBridge WindowsAccessBridge JAWTAccessBridge AccessBridgeJava
endif
ifeq ($(ARCH_DATA_MODEL), 32)
all build clean clobber ::
$(SUBDIRS-loop)
$(OTHERSUBDIRS-loop)
else
all build clean clobber ::
$(SUBDIRS-loop)
endif
clean::
$(RM) -r $(CLASSBINDIR) $(CLASSBINDIR)
endif # PLATFORM
endif #OPENJDK

View File

@ -0,0 +1,35 @@
#
# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Oracle designates this
# particular file as subject to the "Classpath" exception as provided
# by Oracle in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
#
# Native files to compile.
FILES_cpp = \
AccessBridgeJavaVMInstance.cpp \
AccessBridgeMessageQueue.cpp \
AccessBridgeMessages.cpp \
AccessBridgeWindowsEntryPoints.cpp \
WinAccessBridge.cpp \
AccessBridgeDebug.cpp \
AccessBridgeEventHandler.cpp

View File

@ -0,0 +1,71 @@
#
# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Oracle designates this
# particular file as subject to the "Classpath" exception as provided
# by Oracle in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
#
# Makefile for building WindowsAccessBridge.dll
#
BUILDDIR = ../..
LIBRARY = WindowsAccessBridge$(ABSUFFIX)
include $(BUILDDIR)/common/Defs.gmk
# Indicate we want the C++ compiler to do the linking.
CPLUSPLUSLIBRARY=true
ifeq ($(ARCH_DATA_MODEL), 64)
ABSUFFIX = -64
ACCESSBRIDGE_ARCH = ACCESSBRIDGE_ARCH_64
ABRIDGE_MACHINE=X64
else
ifeq ($(ARCH_DATA_MODEL), 32)
ABRIDGE_MACHINE=I386
ifdef ABLEGACY
ABSUFFIX =
ACCESSBRIDGE_ARCH = ACCESSBRIDGE_ARCH_LEGACY
else
ABSUFFIX = -32
ACCESSBRIDGE_ARCH = ACCESSBRIDGE_ARCH_32
endif
endif
endif
include FILES_cpp.gmk
VERSIONINFO_RESOURCE = $(CLOSED_PLATFORM_SRC)/native/sun/bridge/AccessBridgeStatusWindow.rc
OTHER_CPPFLAGS += -MT -D$(ACCESSBRIDGE_ARCH) -I "$(INCLUDEDIR)" -I "$(PLATFORM_INCLUDE)"
LDLIBS += kernel32.lib user32.lib gdi32.lib winspool.lib jawt.lib comdlg32.lib advapi32.lib shell32.lib \
ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /subsystem:windows /dll /incremental:no /machine:$(ABRIDGE_MACHINE) \
/def:$(CLOSED_PLATFORM_SRC)/native/sun/bridge/WinAccessBridge.DEF /libpath:"$(LIBDIR)"
#
# Rules
#
include $(BUILDDIR)/common/Library.gmk
vpath %.cpp $(CLOSED_PLATFORM_SRC)/native/sun/bridge
vpath %.DEF $(CLOSED_PLATFORM_SRC)/native/sun/bridge
vpath %.rc $(CLOSED_PLATFORM_SRC)/native/sun/bridge

View File

@ -127,6 +127,11 @@ CORE_PKGS = \
java.sql \
java.text \
java.text.spi \
java.time \
java.time.temporal \
java.time.calendar \
java.time.format \
java.time.zone \
java.util \
java.util.concurrent \
java.util.concurrent.atomic \

View File

@ -207,6 +207,7 @@ COMMON_JAVADOCFLAGS = \
-quiet \
-use \
-keywords \
-Xdoclint:none \
$(ADDITIONAL_JAVADOCFLAGS)
ifdef OPENJDK

View File

@ -39,7 +39,7 @@ SUBDIRS += version jvm redist verify fdlibm java sun_nio jli main zip
# Others
# Note: java_crw_demo java_hprof_demo are demos but must be delivered built in sdk
SUBDIRS += security math util text net nio jar
SUBDIRS += security math util text net nio jar time
SUBDIRS_desktop = awt applet beans
SUBDIRS_management = management

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@ -57,6 +57,7 @@ FILES_export = \
java/lang/reflect/Constructor.java \
java/lang/reflect/InvocationTargetException.java \
java/lang/reflect/Array.java \
java/lang/reflect/Executable.java \
java/lang/reflect/Proxy.java \
java/security/AccessController.java \
java/util/Date.java \
@ -129,6 +130,7 @@ FILES_export = \
java/lang/reflect/Constructor.java \
java/lang/reflect/InvocationTargetException.java \
java/lang/reflect/Array.java \
java/lang/reflect/Executable.java \
java/lang/reflect/Proxy.java \
java/lang/ref/Reference.java \
java/lang/ref/Finalizer.java \

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@ -32,6 +32,7 @@ FILES_c = \
Compiler.c \
Console_md.c \
Double.c \
Executable.c \
FileDescriptor_md.c \
FileInputStream.c \
FileInputStream_md.c \

View File

@ -137,6 +137,7 @@ JAVA_JAVA_java = \
java/lang/Appendable.java \
java/lang/Comparable.java \
java/lang/Readable.java \
java/lang/FunctionalInterface.java \
java/lang/Override.java \
java/lang/SafeVarargs.java \
java/lang/SuppressWarnings.java \
@ -227,6 +228,7 @@ JAVA_JAVA_java = \
sun/util/locale/provider/LocaleResources.java \
sun/util/locale/provider/NumberFormatProviderImpl.java \
sun/util/locale/provider/RuleBasedBreakIterator.java \
sun/util/locale/provider/ResourceBundleBasedAdapter.java \
sun/util/locale/provider/SPILocaleProviderAdapter.java \
sun/util/locale/provider/TimeZoneNameProviderImpl.java \
sun/util/locale/provider/TimeZoneNameUtility.java \
@ -372,6 +374,11 @@ JAVA_JAVA_java = \
java/util/concurrent/atomic/AtomicReferenceArray.java \
java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java \
java/util/concurrent/atomic/AtomicStampedReference.java \
java/util/concurrent/atomic/DoubleAccumulator.java \
java/util/concurrent/atomic/DoubleAdder.java \
java/util/concurrent/atomic/LongAccumulator.java \
java/util/concurrent/atomic/LongAdder.java \
java/util/concurrent/atomic/Striped64.java \
java/util/concurrent/locks/AbstractOwnableSynchronizer.java \
java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java \
java/util/concurrent/locks/AbstractQueuedSynchronizer.java \

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@ -189,6 +189,7 @@ SUNWprivate_1.1 {
Java_java_lang_reflect_Array_setInt;
Java_java_lang_reflect_Array_setLong;
Java_java_lang_reflect_Array_setShort;
Java_java_lang_reflect_Executable_getParameters0;
Java_java_lang_Runtime_freeMemory;
Java_java_lang_Runtime_maxMemory;
Java_java_lang_Runtime_gc;

View File

@ -0,0 +1,42 @@
#
# Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Oracle designates this
# particular file as subject to the "Classpath" exception as provided
# by Oracle in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
#
# Makefile for building jar utility.
#
BUILDDIR = ../../
PACKAGE = java.time
include $(BUILDDIR)/common/Defs.gmk
#
# Files
#
AUTO_FILES_JAVA_DIRS = java/time
#
# Rules
#
include $(BUILDDIR)/common/Classes.gmk

View File

@ -87,6 +87,7 @@ jprt.make.rule.core.test.targets= \
${jprt.my.test.target.set:TESTNAME=jdk_text}, \
${jprt.my.test.target.set:TESTNAME=jdk_tools}, \
${jprt.my.test.target.set:TESTNAME=jdk_jfr}, \
${jprt.my.test.target.set:TESTNAME=jdk_time}, \
${jprt.my.test.target.set:TESTNAME=jdk_other}
# All vm test targets (testset=all)

View File

@ -70,7 +70,7 @@ else
endif
# nio need to be compiled before awt to have all charsets ready
SUBDIRS = jar security javazic misc net nio text util launcher cldr
SUBDIRS = jar security javazic misc net nio text util launcher cldr tzdb
ifdef BUILD_HEADLESS_ONLY
DISPLAY_LIBS = awt $(HEADLESS_SUBDIR)

View File

@ -0,0 +1,68 @@
#
# Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Oracle designates this
# particular file as subject to the "Classpath" exception as provided
# by Oracle in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
#
# Makefile for building tzdb compiler utility.
#
BUILDDIR = ../..
PACKAGE = sun.tzdb
PRODUCT = sun
include $(BUILDDIR)/common/Defs.gmk
# This program must contain a manifest that defines the execution level
# needed to follow standard Vista User Access Control Guidelines
# This must be set before Program.gmk is included
#
BUILD_MANIFEST=true
#
# Time zone data file creation
#
TZDATA_DIR := ../javazic/tzdata
TZDATA_VER := $(subst tzdata,,$(shell $(GREP) '^tzdata' $(TZDATA_DIR)/VERSION))
TZFILE := africa antarctica asia australasia europe northamerica southamerica backward etcetera
TZFILES := $(addprefix $(TZDATA_DIR)/,$(TZFILE))
TZDB_JAR = tzdb.jar
#
# Rules
#
include $(BUILDDIR)/common/Classes.gmk
#
# Add to the build rule
#
build: $(LIBDIR)/$(TZDB_JAR)
$(LIBDIR)/$(TZDB_JAR): $(TZFILES)
$(prep-target)
echo build tzdb from version $(TZDATA_VER)
$(BOOT_JAVA_CMD) -jar $(BUILDTOOLJARDIR)/tzdb.jar -verbose \
-version $(TZDATA_VER) -srcdir $(TZDATA_DIR) -dstdir $(LIBDIR) $(TZFILE)
clean clobber::
$(RM) $(LIBDIR)/$(TZDB_JAR)

View File

@ -53,6 +53,7 @@ SUBDIRS = \
makeclasslist \
strip_properties \
spp \
tzdb \
CharsetMapping
ifndef DISABLE_NIMBUS

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -274,7 +274,7 @@ class Bundle {
handleDateTimeFormatPatterns(DATETIME_PATTERN_KEYS, myMap, parentsMap, calendarType, "DateTimePatterns");
}
// if myMap has any empty timezone or metazone names, weed out them.
// First, weed out any empty timezone or metazone names from myMap.
// Fill in any missing abbreviations if locale is "en".
for (Iterator<String> it = myMap.keySet().iterator(); it.hasNext();) {
String key = it.next();
@ -426,7 +426,7 @@ class Bundle {
/*
* Adjusts String[] for era names because JRE's Calendars use different
* ERA value indexes in the Buddhist and Japanese Imperial calendars.
* ERA value indexes in the Buddhist, Japanese Imperial, and Islamic calendars.
*/
private void adjustEraNames(Map<String, Object> map, CalendarType type) {
String[][] eraNames = new String[ERA_KEYS.length][];
@ -458,6 +458,11 @@ class Bundle {
// Replace the value
value = new String[] {"BC", value[0]};
break;
case ISLAMIC:
// Replace the value
value = new String[] {"", value[0]};
break;
}
if (!key.equals(realKey)) {
map.put(realKey, value);
@ -479,6 +484,7 @@ class Bundle {
for (String k : patternKeys) {
if (myMap.containsKey(calendarPrefix + k)) {
int len = patternKeys.length;
List<String> rawPatterns = new ArrayList<>();
List<String> patterns = new ArrayList<>();
for (int i = 0; i < len; i++) {
String key = calendarPrefix + patternKeys[i];
@ -487,6 +493,7 @@ class Bundle {
pattern = (String) parentsMap.remove(key);
}
if (pattern != null) {
rawPatterns.add(i, pattern);
patterns.add(i, translateDateFormatLetters(calendarType, pattern));
}
}
@ -494,6 +501,9 @@ class Bundle {
return;
}
String key = calendarPrefix + name;
if (!rawPatterns.equals(patterns)) {
myMap.put("cldr." + key, rawPatterns.toArray(new String[len]));
}
myMap.put(key, patterns.toArray(new String[len]));
break;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -58,6 +58,7 @@ public class CLDRConverter {
static final String LOCALE_NAME_PREFIX = "locale.displayname.";
static final String CURRENCY_SYMBOL_PREFIX = "currency.symbol.";
static final String CURRENCY_NAME_PREFIX = "currency.displayname.";
static final String CALENDAR_NAME_PREFIX = "calendarname.";
static final String TIMEZONE_ID_PREFIX = "timezone.id.";
static final String ZONE_NAME_PREFIX = "timezone.displayname.";
static final String METAZONE_ID_PREFIX = "metazone.id.";
@ -519,35 +520,70 @@ public class CLDRConverter {
return calendarData;
}
static final String[] FORMAT_DATA_ELEMENTS = {
"MonthNames",
"standalone.MonthNames",
"MonthAbbreviations",
"standalone.MonthAbbreviations",
"MonthNarrow",
"standalone.MonthNarrows",
"DayNames",
"standalone.DayNames",
"DayAbbreviations",
"standalone.DayAbbreviations",
"DayNarrows",
"standalone.DayNarrows",
"AmPmMarkers",
"narrow.AmPmMarkers",
"long.Eras",
"Eras",
"narrow.Eras",
"field.era",
"field.year",
"field.month",
"field.week",
"field.weekday",
"field.dayperiod",
"field.hour",
"field.minute",
"field.second",
"field.zone",
"TimePatterns",
"DatePatterns",
"DateTimePatterns",
"DateTimePatternChars"
};
private static Map<String, Object> extractFormatData(Map<String, Object> map, String id) {
Map<String, Object> formatData = new LinkedHashMap<>();
for (CalendarType calendarType : CalendarType.values()) {
String prefix = calendarType.keyElementName();
copyIfPresent(map, prefix + "MonthNames", formatData); // default FORMAT since JDK8
copyIfPresent(map, prefix + "standalone.MonthNames", formatData);
copyIfPresent(map, prefix + "MonthAbbreviations", formatData);
copyIfPresent(map, prefix + "standalone.MonthAbbreviations", formatData);
copyIfPresent(map, prefix + "MonthNarrow", formatData);
copyIfPresent(map, prefix + "standalone.MonthNarrows", formatData);
copyIfPresent(map, prefix + "DayNames", formatData);
copyIfPresent(map, prefix + "standalone.DayNames", formatData);
copyIfPresent(map, prefix + "DayAbbreviations", formatData);
copyIfPresent(map, prefix + "standalone.DayAbbreviations", formatData);
copyIfPresent(map, prefix + "DayNarrows", formatData);
copyIfPresent(map, prefix + "standalone.DayNarrows", formatData);
copyIfPresent(map, prefix + "AmPmMarkers", formatData);
copyIfPresent(map, prefix + "narrow.AmPmMarkers", formatData);
copyIfPresent(map, prefix + "long.Eras", formatData);
copyIfPresent(map, prefix + "Eras", formatData);
copyIfPresent(map, prefix + "narrow.Eras", formatData);
copyIfPresent(map, prefix + "TimePatterns", formatData);
copyIfPresent(map, prefix + "DatePatterns", formatData);
copyIfPresent(map, prefix + "DateTimePatterns", formatData);
copyIfPresent(map, prefix + "DateTimePatternChars", formatData);
for (String element : FORMAT_DATA_ELEMENTS) {
String key = prefix + element;
copyIfPresent(map, "cldr." + key, formatData);
copyIfPresent(map, key, formatData);
}
}
// Copy available calendar names
for (String key : map.keySet()) {
if (key.startsWith(CLDRConverter.CALENDAR_NAME_PREFIX)) {
String type = key.substring(CLDRConverter.CALENDAR_NAME_PREFIX.length());
for (CalendarType calendarType : CalendarType.values()) {
if (type.equals(calendarType.lname())) {
Object value = map.get(key);
formatData.put(key, value);
String ukey = CLDRConverter.CALENDAR_NAME_PREFIX + calendarType.uname();
if (!key.equals(ukey)) {
formatData.put(ukey, value);
}
}
}
}
}
copyIfPresent(map, "DefaultNumberingSystem", formatData);
String defaultScript = (String) map.get("DefaultNumberingSystem");
@SuppressWarnings("unchecked")
List<String> numberingScripts = (List<String>) map.remove("numberingScripts");
if (numberingScripts != null) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -31,26 +31,42 @@ import java.util.Locale;
* Constants for the Calendars supported by JRE.
*/
enum CalendarType {
GREGORIAN, BUDDHIST, JAPANESE;
GREGORIAN("gregory"), BUDDHIST, JAPANESE, ROC, ISLAMIC, ISLAMIC_CIVIL("islamicc");
private static final int[][] ERA_DATA = {
// start index, array length
{0, 2}, // gregorian
{0, 1}, // buddhist
{232, 4}, // japanese (eras from Meiji)
{0, 2}, // roc (Minguo)
{0, 1}, // islamic (Hijrah)
{0, 1}, // islamicc (same as islamic)
};
private final String lname; // lowercase name
private final String uname; // unicode key name (e.g., "gregory" for GREGORIAN)
private CalendarType() {
lname = name().toLowerCase(Locale.ROOT);
this(null);
}
private CalendarType(String uname) {
String lname = name().toLowerCase(Locale.ROOT);
if (lname.equals("islamic_civil")) {
lname = "islamic-civil";
}
this.lname = lname;
this.uname = (uname != null) ? uname : lname;
}
String lname() {
return lname;
}
String uname() {
return uname;
}
String keyElementName() {
return (this == GREGORIAN) ? "" : lname + ".";
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -71,6 +71,13 @@ class LDMLParseHandler extends AbstractLDMLHandler<Object> {
// ignore this element - it has language and territory elements that aren't locale data
pushIgnoredContainer(qName);
break;
case "type":
if ("calendar".equals(attributes.getValue("key"))) {
pushStringEntry(qName, attributes, CLDRConverter.CALENDAR_NAME_PREFIX + attributes.getValue("type"));
} else {
pushIgnoredContainer(qName);
}
break;
case "language":
// for LocaleNames
// copy string
@ -98,19 +105,30 @@ class LDMLParseHandler extends AbstractLDMLHandler<Object> {
case "symbol":
// for CurrencyNames
// need to get the key from the containing <currency> element
pushStringEntry(qName, attributes, CLDRConverter.CURRENCY_SYMBOL_PREFIX + getContainerKey());
pushStringEntry(qName, attributes, CLDRConverter.CURRENCY_SYMBOL_PREFIX
+ getContainerKey());
break;
// Calendar or currency
case "displayName":
// for CurrencyNames
// need to get the key from the containing <currency> element
// ignore if is has "count" attribute
String containerKey = getContainerKey();
if (containerKey != null && attributes.getValue("count") == null) {
pushStringEntry(qName, attributes,
CLDRConverter.CURRENCY_NAME_PREFIX + containerKey.toLowerCase(Locale.ROOT),
attributes.getValue("type"));
} else {
pushIgnoredContainer(qName);
{
if (currentCalendarType != null) {
pushStringEntry(qName, attributes,
currentCalendarType.keyElementName() + "field." + getContainerKey());
} else {
// for CurrencyNames
// need to get the key from the containing <currency> element
// ignore if is has "count" attribute
String containerKey = getContainerKey();
if (containerKey != null && attributes.getValue("count") == null) {
pushStringEntry(qName, attributes,
CLDRConverter.CURRENCY_NAME_PREFIX
+ containerKey.toLowerCase(Locale.ROOT),
attributes.getValue("type"));
} else {
pushIgnoredContainer(qName);
}
}
}
break;
@ -130,6 +148,35 @@ class LDMLParseHandler extends AbstractLDMLHandler<Object> {
}
}
break;
case "fields":
if (currentCalendarType != null) {
pushContainer(qName, attributes);
} else {
pushIgnoredContainer(qName);
}
break;
case "field":
{
String type = attributes.getValue("type");
switch (type) {
case "era":
case "year":
case "month":
case "week":
case "weekday":
case "dayperiod":
case "hour":
case "minute":
case "second":
case "zone":
pushKeyContainer(qName, attributes, type);
break;
default:
pushIgnoredContainer(qName);
break;
}
}
break;
case "monthContext":
{
// for FormatData

View File

@ -0,0 +1,180 @@
/*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* Copyright (c) 2012, Stephen Colebourne & Michael Nascimento Santos
*
* 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 JSR-310 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 COPYRIGHT OWNER 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 build.tools.tzdb;
/**
* A standard set of date/time fields.
*
* @since 1.8
*/
enum ChronoField {
/**
* The second-of-minute.
* <p>
* This counts the second within the minute, from 0 to 59.
* This field has the same meaning for all calendar systems.
*/
SECOND_OF_MINUTE("SecondOfMinute", 0, 59),
/**
* The second-of-day.
* <p>
* This counts the second within the day, from 0 to (24 * 60 * 60) - 1.
* This field has the same meaning for all calendar systems.
*/
SECOND_OF_DAY("SecondOfDay", 0, 86400 - 1),
/**
* The minute-of-hour.
* <p>
* This counts the minute within the hour, from 0 to 59.
* This field has the same meaning for all calendar systems.
*/
MINUTE_OF_HOUR("MinuteOfHour", 0, 59),
/**
* The hour-of-day.
* <p>
* This counts the hour within the day, from 0 to 23.
* This is the hour that would be observed on a standard 24-hour digital clock.
* This field has the same meaning for all calendar systems.
*/
HOUR_OF_DAY("HourOfDay", 0, 23),
/**
* The day-of-month.
* <p>
* This represents the concept of the day within the month.
* In the default ISO calendar system, this has values from 1 to 31 in most months.
* April, June, September, November have days from 1 to 30, while February has days
* from 1 to 28, or 29 in a leap year.
* <p>
* Non-ISO calendar systems should implement this field using the most recognized
* day-of-month values for users of the calendar system.
* Normally, this is a count of days from 1 to the length of the month.
*/
DAY_OF_MONTH("DayOfMonth", 1, 31),
/**
* The month-of-year, such as March.
* <p>
* This represents the concept of the month within the year.
* In the default ISO calendar system, this has values from January (1) to December (12).
* <p>
* Non-ISO calendar systems should implement this field using the most recognized
* month-of-year values for users of the calendar system.
* Normally, this is a count of months starting from 1.
*/
MONTH_OF_YEAR("MonthOfYear", 1, 12),
/**
* The proleptic year, such as 2012.
* <p>
* This represents the concept of the year, counting sequentially and using negative numbers.
* The proleptic year is not interpreted in terms of the era.
* See {@link #YEAR_OF_ERA} for an example showing the mapping from proleptic year to year-of-era.
* <p>
* The standard mental model for a date is based on three concepts - year, month and day.
* These map onto the {@code YEAR}, {@code MONTH_OF_YEAR} and {@code DAY_OF_MONTH} fields.
* Note that there is no reference to eras.
* The full model for a date requires four concepts - era, year, month and day. These map onto
* the {@code ERA}, {@code YEAR_OF_ERA}, {@code MONTH_OF_YEAR} and {@code DAY_OF_MONTH} fields.
* Whether this field or {@code YEAR_OF_ERA} is used depends on which mental model is being used.
* See {@link ChronoLocalDate} for more discussion on this topic.
* <p>
* Non-ISO calendar systems should implement this field as follows.
* If the calendar system has only two eras, before and after a fixed date, then the
* proleptic-year value must be the same as the year-of-era value for the later era,
* and increasingly negative for the earlier era.
* If the calendar system has more than two eras, then the proleptic-year value may be
* defined with any appropriate value, although defining it to be the same as ISO may be
* the best option.
*/
YEAR("Year", -999_999_999, 999_999_999);
private final String name;
private final int min;
private final int max;
private ChronoField(String name, int min, int max) {
this.name = name;
this.min= min;
this.max= max;
}
/**
* Checks that the specified value is valid for this field.
* <p>
*
* @param value the value to check
* @return the value that was passed in
*/
public int checkValidValue(int value) {
if (value >= min && value <= max) {
return value;
}
throw new DateTimeException("Invalid value for " + name + " value: " + value);
}
public String toString() {
return name;
}
}

View File

@ -0,0 +1,98 @@
/*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos
*
* 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 JSR-310 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 COPYRIGHT OWNER 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 build.tools.tzdb;
/**
* Exception used to indicate a problem while calculating a date-time.
* <p>
* This exception is used to indicate problems with creating, querying
* and manipulating date-time objects.
*
* @since 1.8
*/
class DateTimeException extends RuntimeException {
/**
* Serialization version.
*/
private static final long serialVersionUID = -1632418723876261839L;
/**
* Constructs a new date-time exception with the specified message.
*
* @param message the message to use for this exception, may be null
*/
public DateTimeException(String message) {
super(message);
}
/**
* Constructs a new date-time exception with the specified message and cause.
*
* @param message the message to use for this exception, may be null
* @param cause the cause of the exception, may be null
*/
public DateTimeException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@ -0,0 +1,363 @@
/*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* Copyright (c) 2007-2012, Stephen Colebourne & Michael Nascimento Santos
*
* 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 JSR-310 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 COPYRIGHT OWNER 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 build.tools.tzdb;
import static build.tools.tzdb.Utils.*;
import static build.tools.tzdb.LocalTime.SECONDS_PER_DAY;
import static build.tools.tzdb.ChronoField.DAY_OF_MONTH;
import static build.tools.tzdb.ChronoField.MONTH_OF_YEAR;
import static build.tools.tzdb.ChronoField.YEAR;
import java.util.Objects;
/**
* A date without a time-zone in the ISO-8601 calendar system,
* such as {@code 2007-12-03}.
*
* @since 1.8
*/
final class LocalDate {
/**
* The minimum supported {@code LocalDate}, '-999999999-01-01'.
* This could be used by an application as a "far past" date.
*/
public static final LocalDate MIN = new LocalDate(YEAR_MIN_VALUE, 1, 1);
/**
* The maximum supported {@code LocalDate}, '+999999999-12-31'.
* This could be used by an application as a "far future" date.
*/
public static final LocalDate MAX = new LocalDate(YEAR_MAX_VALUE, 12, 31);
/**
* The number of days in a 400 year cycle.
*/
private static final int DAYS_PER_CYCLE = 146097;
/**
* The number of days from year zero to year 1970.
* There are five 400 year cycles from year zero to 2000.
* There are 7 leap years from 1970 to 2000.
*/
static final long DAYS_0000_TO_1970 = (DAYS_PER_CYCLE * 5L) - (30L * 365L + 7L);
/**
* The year.
*/
private final int year;
/**
* The month-of-year.
*/
private final short month;
/**
* The day-of-month.
*/
private final short day;
/**
* Obtains an instance of {@code LocalDate} from a year, month and day.
* <p>
* The day must be valid for the year and month, otherwise an exception will be thrown.
*
* @param year the year to represent, from MIN_YEAR to MAX_YEAR
* @param month the month-of-year to represent, from 1 (January) to 12 (December)
* @param dayOfMonth the day-of-month to represent, from 1 to 31
* @return the local date, not null
* @throws DateTimeException if the value of any field is out of range
* @throws DateTimeException if the day-of-month is invalid for the month-year
*/
public static LocalDate of(int year, int month, int dayOfMonth) {
YEAR.checkValidValue(year);
MONTH_OF_YEAR.checkValidValue(month);
DAY_OF_MONTH.checkValidValue(dayOfMonth);
if (dayOfMonth > 28 && dayOfMonth > lengthOfMonth(month, isLeapYear(year))) {
if (dayOfMonth == 29) {
throw new DateTimeException("Invalid date 'February 29' as '" + year + "' is not a leap year");
} else {
throw new DateTimeException("Invalid date '" + month + " " + dayOfMonth + "'");
}
}
return new LocalDate(year, month, dayOfMonth);
}
/**
* Constructor, previously validated.
*
* @param year the year to represent, from MIN_YEAR to MAX_YEAR
* @param month the month-of-year to represent, not null
* @param dayOfMonth the day-of-month to represent, valid for year-month, from 1 to 31
*/
private LocalDate(int year, int month, int dayOfMonth) {
this.year = year;
this.month = (short) month;
this.day = (short) dayOfMonth;
}
/**
* Gets the year field.
* <p>
* This method returns the primitive {@code int} value for the year.
* <p>
* The year returned by this method is proleptic as per {@code get(YEAR)}.
* To obtain the year-of-era, use {@code get(YEAR_OF_ERA}.
*
* @return the year, from MIN_YEAR to MAX_YEAR
*/
public int getYear() {
return year;
}
/**
* Gets the month-of-year field as an int from 1 to 12.
*
* @return the month-of-year
*/
public int getMonth() {
return month;
}
/**
* Gets the day-of-month field.
* <p>
* This method returns the primitive {@code int} value for the day-of-month.
*
* @return the day-of-month, from 1 to 31
*/
public int getDayOfMonth() {
return day;
}
/**
* Gets the day-of-week field, which is an int from 1 to 7.
*
* @return the day-of-week
*/
public int getDayOfWeek() {
return (int)floorMod(toEpochDay() + 3, 7) + 1;
}
/**
* Returns a copy of this {@code LocalDate} with the specified number of days added.
* <p>
* This method adds the specified amount to the days field incrementing the
* month and year fields as necessary to ensure the result remains valid.
* The result is only invalid if the maximum/minimum year is exceeded.
* <p>
* For example, 2008-12-31 plus one day would result in 2009-01-01.
* <p>
* This instance is immutable and unaffected by this method call.
*
* @param daysToAdd the days to add, may be negative
* @return a {@code LocalDate} based on this date with the days added, not null
* @throws DateTimeException if the result exceeds the supported date range
*/
public LocalDate plusDays(long daysToAdd) {
if (daysToAdd == 0) {
return this;
}
long mjDay = addExact(toEpochDay(), daysToAdd);
return LocalDate.ofEpochDay(mjDay);
}
/**
* Returns a copy of this {@code LocalDate} with the specified number of days subtracted.
* <p>
* This method subtracts the specified amount from the days field decrementing the
* month and year fields as necessary to ensure the result remains valid.
* The result is only invalid if the maximum/minimum year is exceeded.
* <p>
* For example, 2009-01-01 minus one day would result in 2008-12-31.
* <p>
* This instance is immutable and unaffected by this method call.
*
* @param daysToSubtract the days to subtract, may be negative
* @return a {@code LocalDate} based on this date with the days subtracted, not null
* @throws DateTimeException if the result exceeds the supported date range
*/
public LocalDate minusDays(long daysToSubtract) {
return (daysToSubtract == Long.MIN_VALUE ? plusDays(Long.MAX_VALUE).plusDays(1) : plusDays(-daysToSubtract));
}
/**
* Obtains an instance of {@code LocalDate} from the epoch day count.
* <p>
* The Epoch Day count is a simple incrementing count of days
* where day 0 is 1970-01-01. Negative numbers represent earlier days.
*
* @param epochDay the Epoch Day to convert, based on the epoch 1970-01-01
* @return the local date, not null
* @throws DateTimeException if the epoch days exceeds the supported date range
*/
public static LocalDate ofEpochDay(long epochDay) {
long zeroDay = epochDay + DAYS_0000_TO_1970;
// find the march-based year
zeroDay -= 60; // adjust to 0000-03-01 so leap day is at end of four year cycle
long adjust = 0;
if (zeroDay < 0) {
// adjust negative years to positive for calculation
long adjustCycles = (zeroDay + 1) / DAYS_PER_CYCLE - 1;
adjust = adjustCycles * 400;
zeroDay += -adjustCycles * DAYS_PER_CYCLE;
}
long yearEst = (400 * zeroDay + 591) / DAYS_PER_CYCLE;
long doyEst = zeroDay - (365 * yearEst + yearEst / 4 - yearEst / 100 + yearEst / 400);
if (doyEst < 0) {
// fix estimate
yearEst--;
doyEst = zeroDay - (365 * yearEst + yearEst / 4 - yearEst / 100 + yearEst / 400);
}
yearEst += adjust; // reset any negative year
int marchDoy0 = (int) doyEst;
// convert march-based values back to january-based
int marchMonth0 = (marchDoy0 * 5 + 2) / 153;
int month = (marchMonth0 + 2) % 12 + 1;
int dom = marchDoy0 - (marchMonth0 * 306 + 5) / 10 + 1;
yearEst += marchMonth0 / 10;
// check year now we are certain it is correct
int year = YEAR.checkValidValue((int)yearEst);
return new LocalDate(year, month, dom);
}
public long toEpochDay() {
long y = year;
long m = month;
long total = 0;
total += 365 * y;
if (y >= 0) {
total += (y + 3) / 4 - (y + 99) / 100 + (y + 399) / 400;
} else {
total -= y / -4 - y / -100 + y / -400;
}
total += ((367 * m - 362) / 12);
total += day - 1;
if (m > 2) {
total--;
if (isLeapYear(year) == false) {
total--;
}
}
return total - DAYS_0000_TO_1970;
}
/**
* Compares this date to another date.
* <p>
* The comparison is primarily based on the date, from earliest to latest.
* It is "consistent with equals", as defined by {@link Comparable}.
* <p>
* If all the dates being compared are instances of {@code LocalDate},
* then the comparison will be entirely based on the date.
* If some dates being compared are in different chronologies, then the
* chronology is also considered, see {@link java.time.temporal.ChronoLocalDate#compareTo}.
*
* @param other the other date to compare to, not null
* @return the comparator value, negative if less, positive if greater
*/
public int compareTo(LocalDate otherDate) {
int cmp = (year - otherDate.year);
if (cmp == 0) {
cmp = (month - otherDate.month);
if (cmp == 0) {
cmp = (day - otherDate.day);
}
}
return cmp;
}
/**
* Checks if this date is equal to another date.
* <p>
* Compares this {@code LocalDate} with another ensuring that the date is the same.
* <p>
* Only objects of type {@code LocalDate} are compared, other types return false.
* To compare the dates of two {@code TemporalAccessor} instances, including dates
* in two different chronologies, use {@link ChronoField#EPOCH_DAY} as a comparator.
*
* @param obj the object to check, null returns false
* @return true if this is equal to the other date
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof LocalDate) {
return compareTo((LocalDate) obj) == 0;
}
return false;
}
/**
* A hash code for this date.
*
* @return a suitable hash code
*/
@Override
public int hashCode() {
int yearValue = year;
int monthValue = month;
int dayValue = day;
return (yearValue & 0xFFFFF800) ^ ((yearValue << 11) + (monthValue << 6) + (dayValue));
}
}

View File

@ -0,0 +1,427 @@
/*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* Copyright (c) 2007-2012, Stephen Colebourne & Michael Nascimento Santos
*
* 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 JSR-310 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 COPYRIGHT OWNER 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 build.tools.tzdb;
import static build.tools.tzdb.Utils.*;
import static build.tools.tzdb.LocalTime.HOURS_PER_DAY;
import static build.tools.tzdb.LocalTime.MICROS_PER_DAY;
import static build.tools.tzdb.LocalTime.MILLIS_PER_DAY;
import static build.tools.tzdb.LocalTime.MINUTES_PER_DAY;
import static build.tools.tzdb.LocalTime.SECONDS_PER_DAY;
import static build.tools.tzdb.LocalTime.SECONDS_PER_MINUTE;
import static build.tools.tzdb.LocalTime.SECONDS_PER_HOUR;
import java.util.Objects;
/**
* A date-time without a time-zone in the ISO-8601 calendar system,
* such as {@code 2007-12-03T10:15:30}.
*
* @since 1.8
*/
final class LocalDateTime {
/**
* The minimum supported {@code LocalDateTime}, '-999999999-01-01T00:00:00'.
* This is the local date-time of midnight at the start of the minimum date.
* This combines {@link LocalDate#MIN} and {@link LocalTime#MIN}.
* This could be used by an application as a "far past" date-time.
*/
public static final LocalDateTime MIN = LocalDateTime.of(LocalDate.MIN, LocalTime.MIN);
/**
* The maximum supported {@code LocalDateTime}, '+999999999-12-31T23:59:59.999999999'.
* This is the local date-time just before midnight at the end of the maximum date.
* This combines {@link LocalDate#MAX} and {@link LocalTime#MAX}.
* This could be used by an application as a "far future" date-time.
*/
public static final LocalDateTime MAX = LocalDateTime.of(LocalDate.MAX, LocalTime.MAX);
/**
* The date part.
*/
private final LocalDate date;
/**
* The time part.
*/
private final LocalTime time;
/**
* Obtains an instance of {@code LocalDateTime} from year, month,
* day, hour and minute, setting the second and nanosecond to zero.
* <p>
* The day must be valid for the year and month, otherwise an exception will be thrown.
* The second and nanosecond fields will be set to zero.
*
* @param year the year to represent, from MIN_YEAR to MAX_YEAR
* @param month the month-of-year to represent, from 1 (January) to 12 (December)
* @param dayOfMonth the day-of-month to represent, from 1 to 31
* @param hour the hour-of-day to represent, from 0 to 23
* @param minute the minute-of-hour to represent, from 0 to 59
* @return the local date-time, not null
* @throws DateTimeException if the value of any field is out of range
* @throws DateTimeException if the day-of-month is invalid for the month-year
*/
public static LocalDateTime of(int year, int month, int dayOfMonth, int hour, int minute) {
LocalDate date = LocalDate.of(year, month, dayOfMonth);
LocalTime time = LocalTime.of(hour, minute);
return new LocalDateTime(date, time);
}
/**
* Obtains an instance of {@code LocalDateTime} from a date and time.
*
* @param date the local date, not null
* @param time the local time, not null
* @return the local date-time, not null
*/
public static LocalDateTime of(LocalDate date, LocalTime time) {
Objects.requireNonNull(date, "date");
Objects.requireNonNull(time, "time");
return new LocalDateTime(date, time);
}
/**
* Obtains an instance of {@code LocalDateTime} using seconds from the
* epoch of 1970-01-01T00:00:00Z.
* <p>
* This allows the {@link ChronoField#INSTANT_SECONDS epoch-second} field
* to be converted to a local date-time. This is primarily intended for
* low-level conversions rather than general application usage.
*
* @param epochSecond the number of seconds from the epoch of 1970-01-01T00:00:00Z
* @param nanoOfSecond the nanosecond within the second, from 0 to 999,999,999
* @param offset the zone offset, not null
* @return the local date-time, not null
* @throws DateTimeException if the result exceeds the supported range
*/
public static LocalDateTime ofEpochSecond(long epochSecond, int nanoOfSecond, ZoneOffset offset) {
Objects.requireNonNull(offset, "offset");
long localSecond = epochSecond + offset.getTotalSeconds(); // overflow caught later
long localEpochDay = floorDiv(localSecond, SECONDS_PER_DAY);
int secsOfDay = (int)floorMod(localSecond, SECONDS_PER_DAY);
LocalDate date = LocalDate.ofEpochDay(localEpochDay);
LocalTime time = LocalTime.ofSecondOfDay(secsOfDay); // ignore nano
return new LocalDateTime(date, time);
}
/**
* Constructor.
*
* @param date the date part of the date-time, validated not null
* @param time the time part of the date-time, validated not null
*/
private LocalDateTime(LocalDate date, LocalTime time) {
this.date = date;
this.time = time;
}
/**
* Returns a copy of this date-time with the new date and time, checking
* to see if a new object is in fact required.
*
* @param newDate the date of the new date-time, not null
* @param newTime the time of the new date-time, not null
* @return the date-time, not null
*/
private LocalDateTime with(LocalDate newDate, LocalTime newTime) {
if (date == newDate && time == newTime) {
return this;
}
return new LocalDateTime(newDate, newTime);
}
/**
* Gets the {@code LocalDate} part of this date-time.
* <p>
* This returns a {@code LocalDate} with the same year, month and day
* as this date-time.
*
* @return the date part of this date-time, not null
*/
public LocalDate getDate() {
return date;
}
/**
* Gets the year field.
* <p>
* This method returns the primitive {@code int} value for the year.
* <p>
* The year returned by this method is proleptic as per {@code get(YEAR)}.
* To obtain the year-of-era, use {@code get(YEAR_OF_ERA}.
*
* @return the year, from MIN_YEAR to MAX_YEAR
*/
public int getYear() {
return date.getYear();
}
/**
* Gets the month-of-year field as an int from 1 to 12.
*
* @return the month-of-year
*/
public int getMonth() {
return date.getMonth();
}
/**
* Gets the day-of-month field.
* <p>
* This method returns the primitive {@code int} value for the day-of-month.
*
* @return the day-of-month, from 1 to 31
*/
public int getDayOfMonth() {
return date.getDayOfMonth();
}
/**
* Gets the day-of-week field, which is an integer from 1 to 7.
*
* @return the day-of-week, from 1 to 7
*/
public int getDayOfWeek() {
return date.getDayOfWeek();
}
/**
* Gets the {@code LocalTime} part of this date-time.
* <p>
* This returns a {@code LocalTime} with the same hour, minute, second and
* nanosecond as this date-time.
*
* @return the time part of this date-time, not null
*/
public LocalTime getTime() {
return time;
}
/**
* Gets the hour-of-day field.
*
* @return the hour-of-day, from 0 to 23
*/
public int getHour() {
return time.getHour();
}
/**
* Gets the minute-of-hour field.
*
* @return the minute-of-hour, from 0 to 59
*/
public int getMinute() {
return time.getMinute();
}
/**
* Gets the second-of-minute field.
*
* @return the second-of-minute, from 0 to 59
*/
public int getSecond() {
return time.getSecond();
}
/**
* Converts this date-time to the number of seconds from the epoch
* of 1970-01-01T00:00:00Z.
* <p>
* This combines this local date-time and the specified offset to calculate the
* epoch-second value, which is the number of elapsed seconds from 1970-01-01T00:00:00Z.
* Instants on the time-line after the epoch are positive, earlier are negative.
* <p>
* This default implementation calculates from the epoch-day of the date and the
* second-of-day of the time.
*
* @param offset the offset to use for the conversion, not null
* @return the number of seconds from the epoch of 1970-01-01T00:00:00Z
*/
public long toEpochSecond(ZoneOffset offset) {
Objects.requireNonNull(offset, "offset");
long epochDay = getDate().toEpochDay();
long secs = epochDay * 86400 + getTime().toSecondOfDay();
secs -= offset.getTotalSeconds();
return secs;
}
/**
* Returns a copy of this {@code LocalDateTime} with the specified period in days added.
* <p>
* This method adds the specified amount to the days field incrementing the
* month and year fields as necessary to ensure the result remains valid.
* The result is only invalid if the maximum/minimum year is exceeded.
* <p>
* For example, 2008-12-31 plus one day would result in 2009-01-01.
* <p>
* This instance is immutable and unaffected by this method call.
*
* @param days the days to add, may be negative
* @return a {@code LocalDateTime} based on this date-time with the days added, not null
* @throws DateTimeException if the result exceeds the supported date range
*/
public LocalDateTime plusDays(long days) {
LocalDate newDate = date.plusDays(days);
return with(newDate, time);
}
/**
* Returns a copy of this {@code LocalDateTime} with the specified period in seconds added.
* <p>
* This instance is immutable and unaffected by this method call.
*
* @param seconds the seconds to add, may be negative
* @return a {@code LocalDateTime} based on this date-time with the seconds added, not null
* @throws DateTimeException if the result exceeds the supported date range
*/
public LocalDateTime plusSeconds(long seconds) {
return plusWithOverflow(date, 0, 0, seconds, 1);
}
/**
* Returns a copy of this {@code LocalDateTime} with the specified period added.
* <p>
* This instance is immutable and unaffected by this method call.
*
* @param newDate the new date to base the calculation on, not null
* @param hours the hours to add, may be negative
* @param minutes the minutes to add, may be negative
* @param seconds the seconds to add, may be negative
* @param nanos the nanos to add, may be negative
* @param sign the sign to determine add or subtract
* @return the combined result, not null
*/
private LocalDateTime plusWithOverflow(LocalDate newDate, long hours, long minutes, long seconds, int sign) {
if ((hours | minutes | seconds) == 0) {
return with(newDate, time);
}
long totDays = seconds / SECONDS_PER_DAY + // max/24*60*60
minutes / MINUTES_PER_DAY + // max/24*60
hours / HOURS_PER_DAY; // max/24
totDays *= sign; // total max*0.4237...
long totSecs = (seconds % SECONDS_PER_DAY) +
(minutes % MINUTES_PER_DAY) * SECONDS_PER_MINUTE +
(hours % HOURS_PER_DAY) * SECONDS_PER_HOUR;
long curSoD = time.toSecondOfDay();
totSecs = totSecs * sign + curSoD; // total 432000000000000
totDays += floorDiv(totSecs, SECONDS_PER_DAY);
int newSoD = (int)floorMod(totSecs, SECONDS_PER_DAY);
LocalTime newTime = (newSoD == curSoD ? time : LocalTime.ofSecondOfDay(newSoD));
return with(newDate.plusDays(totDays), newTime);
}
/**
* Compares this date-time to another date-time.
* <p>
* The comparison is primarily based on the date-time, from earliest to latest.
* It is "consistent with equals", as defined by {@link Comparable}.
* <p>
* If all the date-times being compared are instances of {@code LocalDateTime},
* then the comparison will be entirely based on the date-time.
* If some dates being compared are in different chronologies, then the
* chronology is also considered, see {@link ChronoLocalDateTime#compareTo}.
*
* @param other the other date-time to compare to, not null
* @return the comparator value, negative if less, positive if greater
*/
public int compareTo(LocalDateTime other) {
int cmp = date.compareTo(other.getDate());
if (cmp == 0) {
cmp = time.compareTo(other.getTime());
}
return cmp;
}
/**
* Checks if this date-time is equal to another date-time.
* <p>
* Compares this {@code LocalDateTime} with another ensuring that the date-time is the same.
* Only objects of type {@code LocalDateTime} are compared, other types return false.
*
* @param obj the object to check, null returns false
* @return true if this is equal to the other date-time
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof LocalDateTime) {
LocalDateTime other = (LocalDateTime) obj;
return date.equals(other.date) && time.equals(other.time);
}
return false;
}
/**
* A hash code for this date-time.
*
* @return a suitable hash code
*/
@Override
public int hashCode() {
return date.hashCode() ^ time.hashCode();
}
}

View File

@ -0,0 +1,388 @@
/*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* Copyright (c) 2007-2012, Stephen Colebourne & Michael Nascimento Santos
*
* 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 JSR-310 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 COPYRIGHT OWNER 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 build.tools.tzdb;
import static build.tools.tzdb.ChronoField.HOUR_OF_DAY;
import static build.tools.tzdb.ChronoField.MINUTE_OF_HOUR;
import static build.tools.tzdb.ChronoField.SECOND_OF_MINUTE;
import static build.tools.tzdb.ChronoField.SECOND_OF_DAY;
import java.util.Objects;
/**
* A time without time-zone in the ISO-8601 calendar system,
* such as {@code 10:15:30}.
*
*/
final class LocalTime {
/**
* The minimum supported {@code LocalTime}, '00:00'.
* This is the time of midnight at the start of the day.
*/
public static final LocalTime MIN;
/**
* The minimum supported {@code LocalTime}, '23:59:59.999999999'.
* This is the time just before midnight at the end of the day.
*/
public static final LocalTime MAX;
/**
* The time of midnight at the start of the day, '00:00'.
*/
public static final LocalTime MIDNIGHT;
/**
* The time of noon in the middle of the day, '12:00'.
*/
public static final LocalTime NOON;
/**
* Constants for the local time of each hour.
*/
private static final LocalTime[] HOURS = new LocalTime[24];
static {
for (int i = 0; i < HOURS.length; i++) {
HOURS[i] = new LocalTime(i, 0, 0);
}
MIDNIGHT = HOURS[0];
NOON = HOURS[12];
MIN = HOURS[0];
MAX = new LocalTime(23, 59, 59);
}
/**
* Hours per day.
*/
static final int HOURS_PER_DAY = 24;
/**
* Minutes per hour.
*/
static final int MINUTES_PER_HOUR = 60;
/**
* Minutes per day.
*/
static final int MINUTES_PER_DAY = MINUTES_PER_HOUR * HOURS_PER_DAY;
/**
* Seconds per minute.
*/
static final int SECONDS_PER_MINUTE = 60;
/**
* Seconds per hour.
*/
static final int SECONDS_PER_HOUR = SECONDS_PER_MINUTE * MINUTES_PER_HOUR;
/**
* Seconds per day.
*/
static final int SECONDS_PER_DAY = SECONDS_PER_HOUR * HOURS_PER_DAY;
/**
* Milliseconds per day.
*/
static final long MILLIS_PER_DAY = SECONDS_PER_DAY * 1000L;
/**
* Microseconds per day.
*/
static final long MICROS_PER_DAY = SECONDS_PER_DAY * 1000_000L;
/**
* The hour.
*/
private final byte hour;
/**
* The minute.
*/
private final byte minute;
/**
* The second.
*/
private final byte second;
/**
* Obtains an instance of {@code LocalTime} from an hour and minute.
* <p>
* The second and nanosecond fields will be set to zero by this factory method.
* <p>
* This factory may return a cached value, but applications must not rely on this.
*
* @param hour the hour-of-day to represent, from 0 to 23
* @param minute the minute-of-hour to represent, from 0 to 59
* @return the local time, not null
* @throws DateTimeException if the value of any field is out of range
*/
public static LocalTime of(int hour, int minute) {
HOUR_OF_DAY.checkValidValue(hour);
if (minute == 0) {
return HOURS[hour]; // for performance
}
MINUTE_OF_HOUR.checkValidValue(minute);
return new LocalTime(hour, minute, 0);
}
/**
* Obtains an instance of {@code LocalTime} from an hour, minute and second.
* <p>
* The nanosecond field will be set to zero by this factory method.
* <p>
* This factory may return a cached value, but applications must not rely on this.
*
* @param hour the hour-of-day to represent, from 0 to 23
* @param minute the minute-of-hour to represent, from 0 to 59
* @param second the second-of-minute to represent, from 0 to 59
* @return the local time, not null
* @throws DateTimeException if the value of any field is out of range
*/
public static LocalTime of(int hour, int minute, int second) {
HOUR_OF_DAY.checkValidValue(hour);
if ((minute | second) == 0) {
return HOURS[hour]; // for performance
}
MINUTE_OF_HOUR.checkValidValue(minute);
SECOND_OF_MINUTE.checkValidValue(second);
return new LocalTime(hour, minute, second);
}
/**
* Obtains an instance of {@code LocalTime} from a second-of-day value.
* <p>
* This factory may return a cached value, but applications must not rely on this.
*
* @param secondOfDay the second-of-day, from {@code 0} to {@code 24 * 60 * 60 - 1}
* @return the local time, not null
* @throws DateTimeException if the second-of-day value is invalid
*/
public static LocalTime ofSecondOfDay(int secondOfDay) {
SECOND_OF_DAY.checkValidValue(secondOfDay);
int hours = secondOfDay / SECONDS_PER_HOUR;
secondOfDay -= hours * SECONDS_PER_HOUR;
int minutes = secondOfDay / SECONDS_PER_MINUTE;
secondOfDay -= minutes * SECONDS_PER_MINUTE;
return create(hours, minutes, secondOfDay);
}
/**
* Creates a local time from the hour, minute, second and nanosecond fields.
* <p>
* This factory may return a cached value, but applications must not rely on this.
*
* @param hour the hour-of-day to represent, validated from 0 to 23
* @param minute the minute-of-hour to represent, validated from 0 to 59
* @param second the second-of-minute to represent, validated from 0 to 59
* @return the local time, not null
*/
private static LocalTime create(int hour, int minute, int second) {
if ((minute | second) == 0) {
return HOURS[hour];
}
return new LocalTime(hour, minute, second);
}
/**
* Constructor, previously validated.
*
* @param hour the hour-of-day to represent, validated from 0 to 23
* @param minute the minute-of-hour to represent, validated from 0 to 59
* @param second the second-of-minute to represent, validated from 0 to 59
*/
private LocalTime(int hour, int minute, int second) {
this.hour = (byte) hour;
this.minute = (byte) minute;
this.second = (byte) second;
}
/**
* Gets the hour-of-day field.
*
* @return the hour-of-day, from 0 to 23
*/
public int getHour() {
return hour;
}
/**
* Gets the minute-of-hour field.
*
* @return the minute-of-hour, from 0 to 59
*/
public int getMinute() {
return minute;
}
/**
* Gets the second-of-minute field.
*
* @return the second-of-minute, from 0 to 59
*/
public int getSecond() {
return second;
}
/**
* Returns a copy of this {@code LocalTime} with the specified period in seconds added.
* <p>
* This adds the specified number of seconds to this time, returning a new time.
* The calculation wraps around midnight.
* <p>
* This instance is immutable and unaffected by this method call.
*
* @param secondstoAdd the seconds to add, may be negative
* @return a {@code LocalTime} based on this time with the seconds added, not null
*/
public LocalTime plusSeconds(long secondstoAdd) {
if (secondstoAdd == 0) {
return this;
}
int sofd = hour * SECONDS_PER_HOUR +
minute * SECONDS_PER_MINUTE + second;
int newSofd = ((int) (secondstoAdd % SECONDS_PER_DAY) + sofd + SECONDS_PER_DAY) % SECONDS_PER_DAY;
if (sofd == newSofd) {
return this;
}
int newHour = newSofd / SECONDS_PER_HOUR;
int newMinute = (newSofd / SECONDS_PER_MINUTE) % MINUTES_PER_HOUR;
int newSecond = newSofd % SECONDS_PER_MINUTE;
return create(newHour, newMinute, newSecond);
}
/**
* Returns a copy of this {@code LocalTime} with the specified period in seconds subtracted.
* <p>
* This subtracts the specified number of seconds from this time, returning a new time.
* The calculation wraps around midnight.
* <p>
* This instance is immutable and unaffected by this method call.
*
* @param secondsToSubtract the seconds to subtract, may be negative
* @return a {@code LocalTime} based on this time with the seconds subtracted, not null
*/
public LocalTime minusSeconds(long secondsToSubtract) {
return plusSeconds(-(secondsToSubtract % SECONDS_PER_DAY));
}
/**
* Extracts the time as seconds of day,
* from {@code 0} to {@code 24 * 60 * 60 - 1}.
*
* @return the second-of-day equivalent to this time
*/
public int toSecondOfDay() {
int total = hour * SECONDS_PER_HOUR;
total += minute * SECONDS_PER_MINUTE;
total += second;
return total;
}
/**
* Compares this {@code LocalTime} to another time.
* <p>
* The comparison is based on the time-line position of the local times within a day.
* It is "consistent with equals", as defined by {@link Comparable}.
*
* @param other the other time to compare to, not null
* @return the comparator value, negative if less, positive if greater
* @throws NullPointerException if {@code other} is null
*/
public int compareTo(LocalTime other) {
int cmp = Integer.compare(hour, other.hour);
if (cmp == 0) {
cmp = Integer.compare(minute, other.minute);
if (cmp == 0) {
cmp = Integer.compare(second, other.second);
}
}
return cmp;
}
/**
* Checks if this time is equal to another time.
* <p>
* The comparison is based on the time-line position of the time within a day.
* <p>
* Only objects of type {@code LocalTime} are compared, other types return false.
* To compare the date of two {@code TemporalAccessor} instances, use
* {@link ChronoField#NANO_OF_DAY} as a comparator.
*
* @param obj the object to check, null returns false
* @return true if this is equal to the other time
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof LocalTime) {
LocalTime other = (LocalTime) obj;
return hour == other.hour && minute == other.minute &&
second == other.second;
}
return false;
}
/**
* A hash code for this time.
*
* @return a suitable hash code
*/
@Override
public int hashCode() {
long sod = toSecondOfDay();
return (int) (sod ^ (sod >>> 32));
}
}

View File

@ -0,0 +1,117 @@
/*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* Copyright (c) 2009-2012, Stephen Colebourne & Michael Nascimento Santos
*
* 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 JSR-310 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 COPYRIGHT OWNER 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 build.tools.tzdb;
import java.util.Objects;
/**
* A definition of the way a local time can be converted to the actual
* transition date-time.
* <p>
* Time zone rules are expressed in one of three ways:
* <p><ul>
* <li>Relative to UTC</li>
* <li>Relative to the standard offset in force</li>
* <li>Relative to the wall offset (what you would see on a clock on the wall)</li>
* </ul><p>
*/
public enum TimeDefinition {
/** The local date-time is expressed in terms of the UTC offset. */
UTC,
/** The local date-time is expressed in terms of the wall offset. */
WALL,
/** The local date-time is expressed in terms of the standard offset. */
STANDARD;
/**
* Converts the specified local date-time to the local date-time actually
* seen on a wall clock.
* <p>
* This method converts using the type of this enum.
* The output is defined relative to the 'before' offset of the transition.
* <p>
* The UTC type uses the UTC offset.
* The STANDARD type uses the standard offset.
* The WALL type returns the input date-time.
* The result is intended for use with the wall-offset.
*
* @param dateTime the local date-time, not null
* @param standardOffset the standard offset, not null
* @param wallOffset the wall offset, not null
* @return the date-time relative to the wall/before offset, not null
*/
public LocalDateTime createDateTime(LocalDateTime dateTime, ZoneOffset standardOffset, ZoneOffset wallOffset) {
switch (this) {
case UTC: {
int difference = wallOffset.getTotalSeconds() - ZoneOffset.UTC.getTotalSeconds();
return dateTime.plusSeconds(difference);
}
case STANDARD: {
int difference = wallOffset.getTotalSeconds() - standardOffset.getTotalSeconds();
return dateTime.plusSeconds(difference);
}
default: // WALL
return dateTime;
}
}
}

View File

@ -0,0 +1,876 @@
/*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* Copyright (c) 2009-2012, Stephen Colebourne & Michael Nascimento Santos
*
* 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 JSR-310 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 COPYRIGHT OWNER 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 build.tools.tzdb;
import static build.tools.tzdb.Utils.*;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.text.ParsePosition;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.jar.JarOutputStream;
import java.util.zip.ZipEntry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* A builder that can read the TZDB time-zone files and build {@code ZoneRules} instances.
*
* @since 1.8
*/
public final class TzdbZoneRulesCompiler {
private static final Matcher YEAR = Pattern.compile("(?i)(?<min>min)|(?<max>max)|(?<only>only)|(?<year>[0-9]+)").matcher("");
private static final Matcher MONTH = Pattern.compile("(?i)(jan)|(feb)|(mar)|(apr)|(may)|(jun)|(jul)|(aug)|(sep)|(oct)|(nov)|(dec)").matcher("");
private static final Matcher DOW = Pattern.compile("(?i)(mon)|(tue)|(wed)|(thu)|(fri)|(sat)|(sun)").matcher("");
private static final Matcher TIME = Pattern.compile("(?<neg>-)?+(?<hour>[0-9]{1,2})(:(?<minute>[0-5][0-9]))?+(:(?<second>[0-5][0-9]))?+").matcher("");
/**
* Constant for MJD 1972-01-01.
*/
private static final long MJD_1972_01_01 = 41317L;
/**
* Reads a set of TZDB files and builds a single combined data file.
*
* @param args the arguments
*/
public static void main(String[] args) {
if (args.length < 2) {
outputHelp();
return;
}
// parse args
String version = null;
File baseSrcDir = null;
File dstDir = null;
boolean verbose = false;
// parse options
int i;
for (i = 0; i < args.length; i++) {
String arg = args[i];
if (arg.startsWith("-") == false) {
break;
}
if ("-srcdir".equals(arg)) {
if (baseSrcDir == null && ++i < args.length) {
baseSrcDir = new File(args[i]);
continue;
}
} else if ("-dstdir".equals(arg)) {
if (dstDir == null && ++i < args.length) {
dstDir = new File(args[i]);
continue;
}
} else if ("-version".equals(arg)) {
if (version == null && ++i < args.length) {
version = args[i];
continue;
}
} else if ("-verbose".equals(arg)) {
if (verbose == false) {
verbose = true;
continue;
}
} else if ("-help".equals(arg) == false) {
System.out.println("Unrecognised option: " + arg);
}
outputHelp();
return;
}
// check source directory
if (baseSrcDir == null) {
System.out.println("Source directory must be specified using -srcdir: " + baseSrcDir);
return;
}
if (baseSrcDir.isDirectory() == false) {
System.out.println("Source does not exist or is not a directory: " + baseSrcDir);
return;
}
dstDir = (dstDir != null ? dstDir : baseSrcDir);
// parse source file names
List<String> srcFileNames = Arrays.asList(Arrays.copyOfRange(args, i, args.length));
if (srcFileNames.isEmpty()) {
System.out.println("Source filenames not specified, using default set");
System.out.println("(africa antarctica asia australasia backward etcetera europe northamerica southamerica)");
srcFileNames = Arrays.asList("africa", "antarctica", "asia", "australasia", "backward",
"etcetera", "europe", "northamerica", "southamerica");
}
// find source directories to process
List<File> srcDirs = new ArrayList<>();
if (version != null) {
// if the "version" specified, as in jdk repo, the "baseSrcDir" is
// the "srcDir" that contains the tzdb data.
srcDirs.add(baseSrcDir);
} else {
File[] dirs = baseSrcDir.listFiles();
for (File dir : dirs) {
if (dir.isDirectory() && dir.getName().matches("[12][0-9]{3}[A-Za-z0-9._-]+")) {
srcDirs.add(dir);
}
}
}
if (srcDirs.isEmpty()) {
System.out.println("Source directory contains no valid source folders: " + baseSrcDir);
return;
}
// check destination directory
if (dstDir.exists() == false && dstDir.mkdirs() == false) {
System.out.println("Destination directory could not be created: " + dstDir);
return;
}
if (dstDir.isDirectory() == false) {
System.out.println("Destination is not a directory: " + dstDir);
return;
}
process(srcDirs, srcFileNames, dstDir, version, verbose);
System.exit(0);
}
/**
* Output usage text for the command line.
*/
private static void outputHelp() {
System.out.println("Usage: TzdbZoneRulesCompiler <options> <tzdb source filenames>");
System.out.println("where options include:");
System.out.println(" -srcdir <directory> Where to find source directories (required)");
System.out.println(" -dstdir <directory> Where to output generated files (default srcdir)");
System.out.println(" -version <version> Specify the version, such as 2009a (optional)");
System.out.println(" -help Print this usage message");
System.out.println(" -verbose Output verbose information during compilation");
System.out.println(" There must be one directory for each version in srcdir");
System.out.println(" Each directory must have the name of the version, such as 2009a");
System.out.println(" Each directory must contain the unpacked tzdb files, such as asia or europe");
System.out.println(" Directories must match the regex [12][0-9][0-9][0-9][A-Za-z0-9._-]+");
System.out.println(" There will be one jar file for each version and one combined jar in dstdir");
System.out.println(" If the version is specified, only that version is processed");
}
/**
* Process to create the jar files.
*/
private static void process(List<File> srcDirs, List<String> srcFileNames, File dstDir, String version, boolean verbose) {
// build actual jar files
Map<String, SortedMap<String, ZoneRules>> allBuiltZones = new TreeMap<>();
Set<String> allRegionIds = new TreeSet<String>();
Set<ZoneRules> allRules = new HashSet<ZoneRules>();
for (File srcDir : srcDirs) {
// source files in this directory
List<File> srcFiles = new ArrayList<>();
for (String srcFileName : srcFileNames) {
File file = new File(srcDir, srcFileName);
if (file.exists()) {
srcFiles.add(file);
}
}
if (srcFiles.isEmpty()) {
continue; // nothing to process
}
// compile
String loopVersion = srcDir.getName();
TzdbZoneRulesCompiler compiler = new TzdbZoneRulesCompiler(loopVersion, srcFiles, verbose);
try {
// compile
compiler.compile();
SortedMap<String, ZoneRules> builtZones = compiler.getZones();
// output version-specific file
File dstFile = version == null ? new File(dstDir, "tzdb" + loopVersion + ".jar")
: new File(dstDir, "tzdb.jar");
if (verbose) {
System.out.println("Outputting file: " + dstFile);
}
outputFile(dstFile, loopVersion, builtZones);
// create totals
allBuiltZones.put(loopVersion, builtZones);
allRegionIds.addAll(builtZones.keySet());
allRules.addAll(builtZones.values());
} catch (Exception ex) {
System.out.println("Failed: " + ex.toString());
ex.printStackTrace();
System.exit(1);
}
}
// output merged file
if (version == null) {
File dstFile = new File(dstDir, "tzdb-all.jar");
if (verbose) {
System.out.println("Outputting combined file: " + dstFile);
}
outputFile(dstFile, allBuiltZones, allRegionIds, allRules);
}
}
/**
* Outputs the file.
*/
private static void outputFile(File dstFile,
String version,
SortedMap<String, ZoneRules> builtZones) {
Map<String, SortedMap<String, ZoneRules>> loopAllBuiltZones = new TreeMap<>();
loopAllBuiltZones.put(version, builtZones);
Set<String> loopAllRegionIds = new TreeSet<String>(builtZones.keySet());
Set<ZoneRules> loopAllRules = new HashSet<ZoneRules>(builtZones.values());
outputFile(dstFile, loopAllBuiltZones, loopAllRegionIds, loopAllRules);
}
/**
* Outputs the file.
*/
private static void outputFile(File dstFile,
Map<String, SortedMap<String, ZoneRules>> allBuiltZones,
Set<String> allRegionIds,
Set<ZoneRules> allRules)
{
try (JarOutputStream jos = new JarOutputStream(new FileOutputStream(dstFile))) {
outputTZEntry(jos, allBuiltZones, allRegionIds, allRules);
} catch (Exception ex) {
System.out.println("Failed: " + ex.toString());
ex.printStackTrace();
System.exit(1);
}
}
/**
* Outputs the timezone entry in the JAR file.
*/
private static void outputTZEntry(JarOutputStream jos,
Map<String, SortedMap<String, ZoneRules>> allBuiltZones,
Set<String> allRegionIds,
Set<ZoneRules> allRules) {
// this format is not publicly specified
try {
jos.putNextEntry(new ZipEntry("TZDB.dat"));
DataOutputStream out = new DataOutputStream(jos);
// file version
out.writeByte(1);
// group
out.writeUTF("TZDB");
// versions
String[] versionArray = allBuiltZones.keySet().toArray(new String[allBuiltZones.size()]);
out.writeShort(versionArray.length);
for (String version : versionArray) {
out.writeUTF(version);
}
// regions
String[] regionArray = allRegionIds.toArray(new String[allRegionIds.size()]);
out.writeShort(regionArray.length);
for (String regionId : regionArray) {
out.writeUTF(regionId);
}
// rules
List<ZoneRules> rulesList = new ArrayList<>(allRules);
out.writeShort(rulesList.size());
ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
for (ZoneRules rules : rulesList) {
baos.reset();
DataOutputStream dataos = new DataOutputStream(baos);
rules.writeExternal(dataos);
dataos.close();
byte[] bytes = baos.toByteArray();
out.writeShort(bytes.length);
out.write(bytes);
}
// link version-region-rules
for (String version : allBuiltZones.keySet()) {
out.writeShort(allBuiltZones.get(version).size());
for (Map.Entry<String, ZoneRules> entry : allBuiltZones.get(version).entrySet()) {
int regionIndex = Arrays.binarySearch(regionArray, entry.getKey());
int rulesIndex = rulesList.indexOf(entry.getValue());
out.writeShort(regionIndex);
out.writeShort(rulesIndex);
}
}
out.flush();
jos.closeEntry();
} catch (Exception ex) {
System.out.println("Failed: " + ex.toString());
ex.printStackTrace();
System.exit(1);
}
}
//-----------------------------------------------------------------------
/** The TZDB rules. */
private final Map<String, List<TZDBRule>> rules = new HashMap<>();
/** The TZDB zones. */
private final Map<String, List<TZDBZone>> zones = new HashMap<>();
/** The TZDB links. */
private final Map<String, String> links = new HashMap<>();
/** The built zones. */
private final SortedMap<String, ZoneRules> builtZones = new TreeMap<>();
/** The version to produce. */
private final String version;
/** The source files. */
private final List<File> sourceFiles;
/** The version to produce. */
private final boolean verbose;
/**
* Creates an instance if you want to invoke the compiler manually.
*
* @param version the version, such as 2009a, not null
* @param sourceFiles the list of source files, not empty, not null
* @param verbose whether to output verbose messages
*/
public TzdbZoneRulesCompiler(String version, List<File> sourceFiles, boolean verbose) {
this.version = version;
this.sourceFiles = sourceFiles;
this.verbose = verbose;
}
/**
* Compile the rules file.
* <p>
* Use {@link #getZones()} to retrieve the parsed data.
*
* @throws Exception if an error occurs
*/
public void compile() throws Exception {
printVerbose("Compiling TZDB version " + version);
parseFiles();
buildZoneRules();
printVerbose("Compiled TZDB version " + version);
}
/**
* Gets the parsed zone rules.
*
* @return the parsed zone rules, not null
*/
public SortedMap<String, ZoneRules> getZones() {
return builtZones;
}
/**
* Parses the source files.
*
* @throws Exception if an error occurs
*/
private void parseFiles() throws Exception {
for (File file : sourceFiles) {
printVerbose("Parsing file: " + file);
parseFile(file);
}
}
/**
* Parses a source file.
*
* @param file the file being read, not null
* @throws Exception if an error occurs
*/
private void parseFile(File file) throws Exception {
int lineNumber = 1;
String line = null;
BufferedReader in = null;
try {
in = new BufferedReader(new FileReader(file));
List<TZDBZone> openZone = null;
for ( ; (line = in.readLine()) != null; lineNumber++) {
int index = line.indexOf('#'); // remove comments (doesn't handle # in quotes)
if (index >= 0) {
line = line.substring(0, index);
}
if (line.trim().length() == 0) { // ignore blank lines
continue;
}
StringTokenizer st = new StringTokenizer(line, " \t");
if (openZone != null && Character.isWhitespace(line.charAt(0)) && st.hasMoreTokens()) {
if (parseZoneLine(st, openZone)) {
openZone = null;
}
} else {
if (st.hasMoreTokens()) {
String first = st.nextToken();
if (first.equals("Zone")) {
if (st.countTokens() < 3) {
printVerbose("Invalid Zone line in file: " + file + ", line: " + line);
throw new IllegalArgumentException("Invalid Zone line");
}
openZone = new ArrayList<>();
zones.put(st.nextToken(), openZone);
if (parseZoneLine(st, openZone)) {
openZone = null;
}
} else {
openZone = null;
if (first.equals("Rule")) {
if (st.countTokens() < 9) {
printVerbose("Invalid Rule line in file: " + file + ", line: " + line);
throw new IllegalArgumentException("Invalid Rule line");
}
parseRuleLine(st);
} else if (first.equals("Link")) {
if (st.countTokens() < 2) {
printVerbose("Invalid Link line in file: " + file + ", line: " + line);
throw new IllegalArgumentException("Invalid Link line");
}
String realId = st.nextToken();
String aliasId = st.nextToken();
links.put(aliasId, realId);
} else {
throw new IllegalArgumentException("Unknown line");
}
}
}
}
}
} catch (Exception ex) {
throw new Exception("Failed while processing file '" + file + "' on line " + lineNumber + " '" + line + "'", ex);
} finally {
try {
if (in != null) {
in.close();
}
} catch (Exception ex) {
// ignore NPE and IOE
}
}
}
/**
* Parses a Rule line.
*
* @param st the tokenizer, not null
*/
private void parseRuleLine(StringTokenizer st) {
TZDBRule rule = new TZDBRule();
String name = st.nextToken();
if (rules.containsKey(name) == false) {
rules.put(name, new ArrayList<TZDBRule>());
}
rules.get(name).add(rule);
rule.startYear = parseYear(st.nextToken(), 0);
rule.endYear = parseYear(st.nextToken(), rule.startYear);
if (rule.startYear > rule.endYear) {
throw new IllegalArgumentException("Year order invalid: " + rule.startYear + " > " + rule.endYear);
}
parseOptional(st.nextToken()); // type is unused
parseMonthDayTime(st, rule);
rule.savingsAmount = parsePeriod(st.nextToken());
rule.text = parseOptional(st.nextToken());
}
/**
* Parses a Zone line.
*
* @param st the tokenizer, not null
* @return true if the zone is complete
*/
private boolean parseZoneLine(StringTokenizer st, List<TZDBZone> zoneList) {
TZDBZone zone = new TZDBZone();
zoneList.add(zone);
zone.standardOffset = parseOffset(st.nextToken());
String savingsRule = parseOptional(st.nextToken());
if (savingsRule == null) {
zone.fixedSavingsSecs = 0;
zone.savingsRule = null;
} else {
try {
zone.fixedSavingsSecs = parsePeriod(savingsRule);
zone.savingsRule = null;
} catch (Exception ex) {
zone.fixedSavingsSecs = null;
zone.savingsRule = savingsRule;
}
}
zone.text = st.nextToken();
if (st.hasMoreTokens()) {
zone.year = Integer.parseInt(st.nextToken());
if (st.hasMoreTokens()) {
parseMonthDayTime(st, zone);
}
return false;
} else {
return true;
}
}
/**
* Parses a Rule line.
*
* @param st the tokenizer, not null
* @param mdt the object to parse into, not null
*/
private void parseMonthDayTime(StringTokenizer st, TZDBMonthDayTime mdt) {
mdt.month = parseMonth(st.nextToken());
if (st.hasMoreTokens()) {
String dayRule = st.nextToken();
if (dayRule.startsWith("last")) {
mdt.dayOfMonth = -1;
mdt.dayOfWeek = parseDayOfWeek(dayRule.substring(4));
mdt.adjustForwards = false;
} else {
int index = dayRule.indexOf(">=");
if (index > 0) {
mdt.dayOfWeek = parseDayOfWeek(dayRule.substring(0, index));
dayRule = dayRule.substring(index + 2);
} else {
index = dayRule.indexOf("<=");
if (index > 0) {
mdt.dayOfWeek = parseDayOfWeek(dayRule.substring(0, index));
mdt.adjustForwards = false;
dayRule = dayRule.substring(index + 2);
}
}
mdt.dayOfMonth = Integer.parseInt(dayRule);
}
if (st.hasMoreTokens()) {
String timeStr = st.nextToken();
int secsOfDay = parseSecs(timeStr);
if (secsOfDay == 86400) {
mdt.endOfDay = true;
secsOfDay = 0;
}
LocalTime time = LocalTime.ofSecondOfDay(secsOfDay);
mdt.time = time;
mdt.timeDefinition = parseTimeDefinition(timeStr.charAt(timeStr.length() - 1));
}
}
}
private int parseYear(String str, int defaultYear) {
if (YEAR.reset(str).matches()) {
if (YEAR.group("min") != null) {
return YEAR_MIN_VALUE;
} else if (YEAR.group("max") != null) {
return YEAR_MAX_VALUE;
} else if (YEAR.group("only") != null) {
return defaultYear;
}
return Integer.parseInt(YEAR.group("year"));
}
throw new IllegalArgumentException("Unknown year: " + str);
}
private int parseMonth(String str) {
if (MONTH.reset(str).matches()) {
for (int moy = 1; moy < 13; moy++) {
if (MONTH.group(moy) != null) {
return moy;
}
}
}
throw new IllegalArgumentException("Unknown month: " + str);
}
private int parseDayOfWeek(String str) {
if (DOW.reset(str).matches()) {
for (int dow = 1; dow < 8; dow++) {
if (DOW.group(dow) != null) {
return dow;
}
}
}
throw new IllegalArgumentException("Unknown day-of-week: " + str);
}
private String parseOptional(String str) {
return str.equals("-") ? null : str;
}
private int parseSecs(String str) {
if (str.equals("-")) {
return 0;
}
try {
if (TIME.reset(str).find()) {
int secs = Integer.parseInt(TIME.group("hour")) * 60 * 60;
if (TIME.group("minute") != null) {
secs += Integer.parseInt(TIME.group("minute")) * 60;
}
if (TIME.group("second") != null) {
secs += Integer.parseInt(TIME.group("second"));
}
if (TIME.group("neg") != null) {
secs = -secs;
}
return secs;
}
} catch (NumberFormatException x) {}
throw new IllegalArgumentException(str);
}
private ZoneOffset parseOffset(String str) {
int secs = parseSecs(str);
return ZoneOffset.ofTotalSeconds(secs);
}
private int parsePeriod(String str) {
return parseSecs(str);
}
private TimeDefinition parseTimeDefinition(char c) {
switch (c) {
case 's':
case 'S':
// standard time
return TimeDefinition.STANDARD;
case 'u':
case 'U':
case 'g':
case 'G':
case 'z':
case 'Z':
// UTC
return TimeDefinition.UTC;
case 'w':
case 'W':
default:
// wall time
return TimeDefinition.WALL;
}
}
//-----------------------------------------------------------------------
/**
* Build the rules, zones and links into real zones.
*
* @throws Exception if an error occurs
*/
private void buildZoneRules() throws Exception {
// build zones
for (String zoneId : zones.keySet()) {
printVerbose("Building zone " + zoneId);
List<TZDBZone> tzdbZones = zones.get(zoneId);
ZoneRulesBuilder bld = new ZoneRulesBuilder();
for (TZDBZone tzdbZone : tzdbZones) {
bld = tzdbZone.addToBuilder(bld, rules);
}
ZoneRules buildRules = bld.toRules(zoneId);
builtZones.put(zoneId, buildRules);
}
// build aliases
for (String aliasId : links.keySet()) {
String realId = links.get(aliasId);
printVerbose("Linking alias " + aliasId + " to " + realId);
ZoneRules realRules = builtZones.get(realId);
if (realRules == null) {
realId = links.get(realId); // try again (handle alias liked to alias)
printVerbose("Relinking alias " + aliasId + " to " + realId);
realRules = builtZones.get(realId);
if (realRules == null) {
throw new IllegalArgumentException("Alias '" + aliasId + "' links to invalid zone '" + realId + "' for '" + version + "'");
}
}
builtZones.put(aliasId, realRules);
}
// remove UTC and GMT
builtZones.remove("UTC");
builtZones.remove("GMT");
builtZones.remove("GMT0");
builtZones.remove("GMT+0");
builtZones.remove("GMT-0");
}
//-----------------------------------------------------------------------
/**
* Prints a verbose message.
*
* @param message the message, not null
*/
private void printVerbose(String message) {
if (verbose) {
System.out.println(message);
}
}
//-----------------------------------------------------------------------
/**
* Class representing a month-day-time in the TZDB file.
*/
abstract class TZDBMonthDayTime {
/** The month of the cutover. */
int month = 1;
/** The day-of-month of the cutover. */
int dayOfMonth = 1;
/** Whether to adjust forwards. */
boolean adjustForwards = true;
/** The day-of-week of the cutover. */
int dayOfWeek = -1;
/** The time of the cutover. */
LocalTime time = LocalTime.MIDNIGHT;
/** Whether this is midnight end of day. */
boolean endOfDay;
/** The time of the cutover. */
TimeDefinition timeDefinition = TimeDefinition.WALL;
void adjustToFowards(int year) {
if (adjustForwards == false && dayOfMonth > 0) {
LocalDate adjustedDate = LocalDate.of(year, month, dayOfMonth).minusDays(6);
dayOfMonth = adjustedDate.getDayOfMonth();
month = adjustedDate.getMonth();
adjustForwards = true;
}
}
}
/**
* Class representing a rule line in the TZDB file.
*/
final class TZDBRule extends TZDBMonthDayTime {
/** The start year. */
int startYear;
/** The end year. */
int endYear;
/** The amount of savings. */
int savingsAmount;
/** The text name of the zone. */
String text;
void addToBuilder(ZoneRulesBuilder bld) {
adjustToFowards(2004); // irrelevant, treat as leap year
bld.addRuleToWindow(startYear, endYear, month, dayOfMonth, dayOfWeek, time, endOfDay, timeDefinition, savingsAmount);
}
}
/**
* Class representing a linked set of zone lines in the TZDB file.
*/
final class TZDBZone extends TZDBMonthDayTime {
/** The standard offset. */
ZoneOffset standardOffset;
/** The fixed savings amount. */
Integer fixedSavingsSecs;
/** The savings rule. */
String savingsRule;
/** The text name of the zone. */
String text;
/** The year of the cutover. */
int year = YEAR_MAX_VALUE;
ZoneRulesBuilder addToBuilder(ZoneRulesBuilder bld, Map<String, List<TZDBRule>> rules) {
if (year != YEAR_MAX_VALUE) {
bld.addWindow(standardOffset, toDateTime(year), timeDefinition);
} else {
bld.addWindowForever(standardOffset);
}
if (fixedSavingsSecs != null) {
bld.setFixedSavingsToWindow(fixedSavingsSecs);
} else {
List<TZDBRule> tzdbRules = rules.get(savingsRule);
if (tzdbRules == null) {
throw new IllegalArgumentException("Rule not found: " + savingsRule);
}
for (TZDBRule tzdbRule : tzdbRules) {
tzdbRule.addToBuilder(bld);
}
}
return bld;
}
private LocalDateTime toDateTime(int year) {
adjustToFowards(year);
LocalDate date;
if (dayOfMonth == -1) {
dayOfMonth = lengthOfMonth(month, isLeapYear(year));
date = LocalDate.of(year, month, dayOfMonth);
if (dayOfWeek != -1) {
date = previousOrSame(date, dayOfWeek);
}
} else {
date = LocalDate.of(year, month, dayOfMonth);
if (dayOfWeek != -1) {
date = nextOrSame(date, dayOfWeek);
}
}
LocalDateTime ldt = LocalDateTime.of(date, time);
if (endOfDay) {
ldt = ldt.plusDays(1);
}
return ldt;
}
}
}

View File

@ -0,0 +1,176 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* Copyright (c) 2009-2012, Stephen Colebourne & Michael Nascimento Santos
*
* 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 JSR-310 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 COPYRIGHT OWNER 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 build.tools.tzdb;
import java.util.Objects;
class Utils {
// Returns the largest (closest to positive infinity)
public static long floorDiv(long x, long y) {
long r = x / y;
// if the signs are different and modulo not zero, round down
if ((x ^ y) < 0 && (r * y != x)) {
r--;
}
return r;
}
// Returns the floor modulus of the {@code long} arguments.
public static long floorMod(long x, long y) {
return x - floorDiv(x, y) * y;
}
// Returns the sum of its arguments,
public static long addExact(long x, long y) {
long r = x + y;
// HD 2-12 Overflow iff both arguments have the opposite sign of the result
if (((x ^ r) & (y ^ r)) < 0) {
throw new ArithmeticException("long overflow");
}
return r;
}
// Year
// Returns true if the specified year is a leap year.
public static boolean isLeapYear(int year) {
return ((year & 3) == 0) && ((year % 100) != 0 || (year % 400) == 0);
}
// The minimum supported year, '-999,999,999'.
public static final int YEAR_MIN_VALUE = -999_999_999;
// The maximum supported year, '+999,999,999'.
public static final int YEAR_MAX_VALUE = 999_999_999;
// Gets the length of the specified month in days.
public static int lengthOfMonth(int month, boolean leapYear) {
switch (month) {
case 2: //FEBRUARY:
return (leapYear ? 29 : 28);
case 4: //APRIL:
case 6: //JUNE:
case 9: //SEPTEMBER:
case 11: //NOVEMBER:
return 30;
default:
return 31;
}
}
// Gets the maximum length of the specified month in days.
public static int maxLengthOfMonth(int month) {
switch (month) {
case 2: //FEBRUARY:
return 29;
case 4: //APRIL:
case 6: //JUNE:
case 9: //SEPTEMBER:
case 11: //NOVEMBER:
return 30;
default:
return 31;
}
}
// DayOfWeek
// Returns the day-of-week that is the specified number of days after
// this one, from 1 to 7 for Monday to Sunday.
public static int plusDayOfWeek(int dow, long days) {
int amount = (int) (days % 7);
return (dow - 1 + (amount + 7)) % 7 + 1;
}
// Returns the day-of-week that is the specified number of days before
// this one, from 1 to 7 for Monday to Sunday.
public static int minusDayOfWeek(int dow, long days) {
return plusDayOfWeek(dow, -(days % 7));
}
// Adjusts the date to the first occurrence of the specified day-of-week
// before the date being adjusted unless it is already on that day in
// which case the same object is returned.
public static LocalDate previousOrSame(LocalDate date, int dayOfWeek) {
return adjust(date, dayOfWeek, 1);
}
// Adjusts the date to the first occurrence of the specified day-of-week
// after the date being adjusted unless it is already on that day in
// which case the same object is returned.
public static LocalDate nextOrSame(LocalDate date, int dayOfWeek) {
return adjust(date, dayOfWeek, 0);
}
// Implementation of next, previous or current day-of-week.
// @param relative whether the current date is a valid answer
private static final LocalDate adjust(LocalDate date, int dow, int relative) {
int calDow = date.getDayOfWeek();
if (relative < 2 && calDow == dow) {
return date;
}
if ((relative & 1) == 0) {
int daysDiff = calDow - dow;
return date.plusDays(daysDiff >= 0 ? 7 - daysDiff : -daysDiff);
} else {
int daysDiff = dow - calDow;
return date.minusDays(daysDiff >= 0 ? 7 - daysDiff : -daysDiff);
}
}
}

View File

@ -0,0 +1,474 @@
/*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* Copyright (c) 2007-2012, Stephen Colebourne & Michael Nascimento Santos
*
* 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 JSR-310 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 COPYRIGHT OWNER 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 build.tools.tzdb;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
* A time-zone offset from Greenwich/UTC, such as {@code +02:00}.
* <p>
* A time-zone offset is the period of time that a time-zone differs from Greenwich/UTC.
* This is usually a fixed number of hours and minutes.
*
* @since 1.8
*/
final class ZoneOffset implements Comparable<ZoneOffset> {
/** Cache of time-zone offset by offset in seconds. */
private static final ConcurrentMap<Integer, ZoneOffset> SECONDS_CACHE = new ConcurrentHashMap<>(16, 0.75f, 4);
/** Cache of time-zone offset by ID. */
private static final ConcurrentMap<String, ZoneOffset> ID_CACHE = new ConcurrentHashMap<>(16, 0.75f, 4);
/**
* The number of seconds per hour.
*/
private static final int SECONDS_PER_HOUR = 60 * 60;
/**
* The number of seconds per minute.
*/
private static final int SECONDS_PER_MINUTE = 60;
/**
* The number of minutes per hour.
*/
private static final int MINUTES_PER_HOUR = 60;
/**
* The abs maximum seconds.
*/
private static final int MAX_SECONDS = 18 * SECONDS_PER_HOUR;
/**
* Serialization version.
*/
private static final long serialVersionUID = 2357656521762053153L;
/**
* The time-zone offset for UTC, with an ID of 'Z'.
*/
public static final ZoneOffset UTC = ZoneOffset.ofTotalSeconds(0);
/**
* Constant for the maximum supported offset.
*/
public static final ZoneOffset MIN = ZoneOffset.ofTotalSeconds(-MAX_SECONDS);
/**
* Constant for the maximum supported offset.
*/
public static final ZoneOffset MAX = ZoneOffset.ofTotalSeconds(MAX_SECONDS);
/**
* The total offset in seconds.
*/
private final int totalSeconds;
/**
* The string form of the time-zone offset.
*/
private final transient String id;
//-----------------------------------------------------------------------
/**
* Obtains an instance of {@code ZoneOffset} using the ID.
* <p>
* This method parses the string ID of a {@code ZoneOffset} to
* return an instance. The parsing accepts all the formats generated by
* {@link #getId()}, plus some additional formats:
* <p><ul>
* <li>{@code Z} - for UTC
* <li>{@code +h}
* <li>{@code +hh}
* <li>{@code +hh:mm}
* <li>{@code -hh:mm}
* <li>{@code +hhmm}
* <li>{@code -hhmm}
* <li>{@code +hh:mm:ss}
* <li>{@code -hh:mm:ss}
* <li>{@code +hhmmss}
* <li>{@code -hhmmss}
* </ul><p>
* Note that &plusmn; means either the plus or minus symbol.
* <p>
* The ID of the returned offset will be normalized to one of the formats
* described by {@link #getId()}.
* <p>
* The maximum supported range is from +18:00 to -18:00 inclusive.
*
* @param offsetId the offset ID, not null
* @return the zone-offset, not null
* @throws DateTimeException if the offset ID is invalid
*/
@SuppressWarnings("fallthrough")
public static ZoneOffset of(String offsetId) {
Objects.requireNonNull(offsetId, "offsetId");
// "Z" is always in the cache
ZoneOffset offset = ID_CACHE.get(offsetId);
if (offset != null) {
return offset;
}
// parse - +h, +hh, +hhmm, +hh:mm, +hhmmss, +hh:mm:ss
final int hours, minutes, seconds;
switch (offsetId.length()) {
case 2:
offsetId = offsetId.charAt(0) + "0" + offsetId.charAt(1); // fallthru
case 3:
hours = parseNumber(offsetId, 1, false);
minutes = 0;
seconds = 0;
break;
case 5:
hours = parseNumber(offsetId, 1, false);
minutes = parseNumber(offsetId, 3, false);
seconds = 0;
break;
case 6:
hours = parseNumber(offsetId, 1, false);
minutes = parseNumber(offsetId, 4, true);
seconds = 0;
break;
case 7:
hours = parseNumber(offsetId, 1, false);
minutes = parseNumber(offsetId, 3, false);
seconds = parseNumber(offsetId, 5, false);
break;
case 9:
hours = parseNumber(offsetId, 1, false);
minutes = parseNumber(offsetId, 4, true);
seconds = parseNumber(offsetId, 7, true);
break;
default:
throw new DateTimeException("Zone offset ID '" + offsetId + "' is invalid");
}
char first = offsetId.charAt(0);
if (first != '+' && first != '-') {
throw new DateTimeException("Zone offset ID '" + offsetId + "' is invalid: Plus/minus not found when expected");
}
if (first == '-') {
return ofHoursMinutesSeconds(-hours, -minutes, -seconds);
} else {
return ofHoursMinutesSeconds(hours, minutes, seconds);
}
}
/**
* Parse a two digit zero-prefixed number.
*
* @param offsetId the offset ID, not null
* @param pos the position to parse, valid
* @param precededByColon should this number be prefixed by a precededByColon
* @return the parsed number, from 0 to 99
*/
private static int parseNumber(CharSequence offsetId, int pos, boolean precededByColon) {
if (precededByColon && offsetId.charAt(pos - 1) != ':') {
throw new DateTimeException("Zone offset ID '" + offsetId + "' is invalid: Colon not found when expected");
}
char ch1 = offsetId.charAt(pos);
char ch2 = offsetId.charAt(pos + 1);
if (ch1 < '0' || ch1 > '9' || ch2 < '0' || ch2 > '9') {
throw new DateTimeException("Zone offset ID '" + offsetId + "' is invalid: Non numeric characters found");
}
return (ch1 - 48) * 10 + (ch2 - 48);
}
//-----------------------------------------------------------------------
/**
* Obtains an instance of {@code ZoneOffset} using an offset in hours.
*
* @param hours the time-zone offset in hours, from -18 to +18
* @return the zone-offset, not null
* @throws DateTimeException if the offset is not in the required range
*/
public static ZoneOffset ofHours(int hours) {
return ofHoursMinutesSeconds(hours, 0, 0);
}
/**
* Obtains an instance of {@code ZoneOffset} using an offset in
* hours and minutes.
* <p>
* The sign of the hours and minutes components must match.
* Thus, if the hours is negative, the minutes must be negative or zero.
* If the hours is zero, the minutes may be positive, negative or zero.
*
* @param hours the time-zone offset in hours, from -18 to +18
* @param minutes the time-zone offset in minutes, from 0 to &plusmn;59, sign matches hours
* @return the zone-offset, not null
* @throws DateTimeException if the offset is not in the required range
*/
public static ZoneOffset ofHoursMinutes(int hours, int minutes) {
return ofHoursMinutesSeconds(hours, minutes, 0);
}
/**
* Obtains an instance of {@code ZoneOffset} using an offset in
* hours, minutes and seconds.
* <p>
* The sign of the hours, minutes and seconds components must match.
* Thus, if the hours is negative, the minutes and seconds must be negative or zero.
*
* @param hours the time-zone offset in hours, from -18 to +18
* @param minutes the time-zone offset in minutes, from 0 to &plusmn;59, sign matches hours and seconds
* @param seconds the time-zone offset in seconds, from 0 to &plusmn;59, sign matches hours and minutes
* @return the zone-offset, not null
* @throws DateTimeException if the offset is not in the required range
*/
public static ZoneOffset ofHoursMinutesSeconds(int hours, int minutes, int seconds) {
validate(hours, minutes, seconds);
int totalSeconds = totalSeconds(hours, minutes, seconds);
return ofTotalSeconds(totalSeconds);
}
/**
* Validates the offset fields.
*
* @param hours the time-zone offset in hours, from -18 to +18
* @param minutes the time-zone offset in minutes, from 0 to &plusmn;59
* @param seconds the time-zone offset in seconds, from 0 to &plusmn;59
* @throws DateTimeException if the offset is not in the required range
*/
private static void validate(int hours, int minutes, int seconds) {
if (hours < -18 || hours > 18) {
throw new DateTimeException("Zone offset hours not in valid range: value " + hours +
" is not in the range -18 to 18");
}
if (hours > 0) {
if (minutes < 0 || seconds < 0) {
throw new DateTimeException("Zone offset minutes and seconds must be positive because hours is positive");
}
} else if (hours < 0) {
if (minutes > 0 || seconds > 0) {
throw new DateTimeException("Zone offset minutes and seconds must be negative because hours is negative");
}
} else if ((minutes > 0 && seconds < 0) || (minutes < 0 && seconds > 0)) {
throw new DateTimeException("Zone offset minutes and seconds must have the same sign");
}
if (Math.abs(minutes) > 59) {
throw new DateTimeException("Zone offset minutes not in valid range: abs(value) " +
Math.abs(minutes) + " is not in the range 0 to 59");
}
if (Math.abs(seconds) > 59) {
throw new DateTimeException("Zone offset seconds not in valid range: abs(value) " +
Math.abs(seconds) + " is not in the range 0 to 59");
}
if (Math.abs(hours) == 18 && (Math.abs(minutes) > 0 || Math.abs(seconds) > 0)) {
throw new DateTimeException("Zone offset not in valid range: -18:00 to +18:00");
}
}
/**
* Calculates the total offset in seconds.
*
* @param hours the time-zone offset in hours, from -18 to +18
* @param minutes the time-zone offset in minutes, from 0 to &plusmn;59, sign matches hours and seconds
* @param seconds the time-zone offset in seconds, from 0 to &plusmn;59, sign matches hours and minutes
* @return the total in seconds
*/
private static int totalSeconds(int hours, int minutes, int seconds) {
return hours * SECONDS_PER_HOUR + minutes * SECONDS_PER_MINUTE + seconds;
}
//-----------------------------------------------------------------------
/**
* Obtains an instance of {@code ZoneOffset} specifying the total offset in seconds
* <p>
* The offset must be in the range {@code -18:00} to {@code +18:00}, which corresponds to -64800 to +64800.
*
* @param totalSeconds the total time-zone offset in seconds, from -64800 to +64800
* @return the ZoneOffset, not null
* @throws DateTimeException if the offset is not in the required range
*/
public static ZoneOffset ofTotalSeconds(int totalSeconds) {
if (Math.abs(totalSeconds) > MAX_SECONDS) {
throw new DateTimeException("Zone offset not in valid range: -18:00 to +18:00");
}
if (totalSeconds % (15 * SECONDS_PER_MINUTE) == 0) {
Integer totalSecs = totalSeconds;
ZoneOffset result = SECONDS_CACHE.get(totalSecs);
if (result == null) {
result = new ZoneOffset(totalSeconds);
SECONDS_CACHE.putIfAbsent(totalSecs, result);
result = SECONDS_CACHE.get(totalSecs);
ID_CACHE.putIfAbsent(result.getId(), result);
}
return result;
} else {
return new ZoneOffset(totalSeconds);
}
}
/**
* Constructor.
*
* @param totalSeconds the total time-zone offset in seconds, from -64800 to +64800
*/
private ZoneOffset(int totalSeconds) {
super();
this.totalSeconds = totalSeconds;
id = buildId(totalSeconds);
}
private static String buildId(int totalSeconds) {
if (totalSeconds == 0) {
return "Z";
} else {
int absTotalSeconds = Math.abs(totalSeconds);
StringBuilder buf = new StringBuilder();
int absHours = absTotalSeconds / SECONDS_PER_HOUR;
int absMinutes = (absTotalSeconds / SECONDS_PER_MINUTE) % MINUTES_PER_HOUR;
buf.append(totalSeconds < 0 ? "-" : "+")
.append(absHours < 10 ? "0" : "").append(absHours)
.append(absMinutes < 10 ? ":0" : ":").append(absMinutes);
int absSeconds = absTotalSeconds % SECONDS_PER_MINUTE;
if (absSeconds != 0) {
buf.append(absSeconds < 10 ? ":0" : ":").append(absSeconds);
}
return buf.toString();
}
}
/**
* Gets the total zone offset in seconds.
* <p>
* This is the primary way to access the offset amount.
* It returns the total of the hours, minutes and seconds fields as a
* single offset that can be added to a time.
*
* @return the total zone offset amount in seconds
*/
public int getTotalSeconds() {
return totalSeconds;
}
/**
* Gets the normalized zone offset ID.
* <p>
* The ID is minor variation to the standard ISO-8601 formatted string
* for the offset. There are three formats:
* <p><ul>
* <li>{@code Z} - for UTC (ISO-8601)
* <li>{@code +hh:mm} or {@code -hh:mm} - if the seconds are zero (ISO-8601)
* <li>{@code +hh:mm:ss} or {@code -hh:mm:ss} - if the seconds are non-zero (not ISO-8601)
* </ul><p>
*
* @return the zone offset ID, not null
*/
public String getId() {
return id;
}
/**
* Compares this offset to another offset in descending order.
* <p>
* The offsets are compared in the order that they occur for the same time
* of day around the world. Thus, an offset of {@code +10:00} comes before an
* offset of {@code +09:00} and so on down to {@code -18:00}.
* <p>
* The comparison is "consistent with equals", as defined by {@link Comparable}.
*
* @param other the other date to compare to, not null
* @return the comparator value, negative if less, postive if greater
* @throws NullPointerException if {@code other} is null
*/
@Override
public int compareTo(ZoneOffset other) {
return other.totalSeconds - totalSeconds;
}
/**
* Checks if this offset is equal to another offset.
* <p>
* The comparison is based on the amount of the offset in seconds.
* This is equivalent to a comparison by ID.
*
* @param obj the object to check, null returns false
* @return true if this is equal to the other offset
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof ZoneOffset) {
return totalSeconds == ((ZoneOffset) obj).totalSeconds;
}
return false;
}
/**
* A hash code for this offset.
*
* @return a suitable hash code
*/
@Override
public int hashCode() {
return totalSeconds;
}
/**
* Outputs this offset as a {@code String}, using the normalized ID.
*
* @return a string representation of this offset, not null
*/
@Override
public String toString() {
return id;
}
}

View File

@ -0,0 +1,290 @@
/*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* Copyright (c) 2009-2012, Stephen Colebourne & Michael Nascimento Santos
*
* 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 JSR-310 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 COPYRIGHT OWNER 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 build.tools.tzdb;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
/**
* A transition between two offsets caused by a discontinuity in the local time-line.
*
* @since 1.8
*/
final class ZoneOffsetTransition implements Comparable<ZoneOffsetTransition> {
/**
* The local transition date-time at the transition.
*/
private final LocalDateTime transition;
/**
* The offset before transition.
*/
private final ZoneOffset offsetBefore;
/**
* The offset after transition.
*/
private final ZoneOffset offsetAfter;
/**
* Creates an instance defining a transition between two offsets.
*
* @param transition the transition date-time with the offset before the transition, not null
* @param offsetBefore the offset before the transition, not null
* @param offsetAfter the offset at and after the transition, not null
*/
ZoneOffsetTransition(LocalDateTime transition, ZoneOffset offsetBefore, ZoneOffset offsetAfter) {
Objects.requireNonNull(transition, "transition");
Objects.requireNonNull(offsetBefore, "offsetBefore");
Objects.requireNonNull(offsetAfter, "offsetAfter");
if (offsetBefore.equals(offsetAfter)) {
throw new IllegalArgumentException("Offsets must not be equal");
}
this.transition = transition;
this.offsetBefore = offsetBefore;
this.offsetAfter = offsetAfter;
}
/**
* Creates an instance from epoch-second and offsets.
*
* @param epochSecond the transition epoch-second
* @param offsetBefore the offset before the transition, not null
* @param offsetAfter the offset at and after the transition, not null
*/
ZoneOffsetTransition(long epochSecond, ZoneOffset offsetBefore, ZoneOffset offsetAfter) {
this.transition = LocalDateTime.ofEpochSecond(epochSecond, 0, offsetBefore);
this.offsetBefore = offsetBefore;
this.offsetAfter = offsetAfter;
}
/**
* Gets the transition instant as an epoch second.
*
* @return the transition epoch second
*/
public long toEpochSecond() {
return transition.toEpochSecond(offsetBefore);
}
/**
* Gets the local transition date-time, as would be expressed with the 'before' offset.
* <p>
* This is the date-time where the discontinuity begins expressed with the 'before' offset.
* At this instant, the 'after' offset is actually used, therefore the combination of this
* date-time and the 'before' offset will never occur.
* <p>
* The combination of the 'before' date-time and offset represents the same instant
* as the 'after' date-time and offset.
*
* @return the transition date-time expressed with the before offset, not null
*/
public LocalDateTime getDateTimeBefore() {
return transition;
}
/**
* Gets the local transition date-time, as would be expressed with the 'after' offset.
* <p>
* This is the first date-time after the discontinuity, when the new offset applies.
* <p>
* The combination of the 'before' date-time and offset represents the same instant
* as the 'after' date-time and offset.
*
* @return the transition date-time expressed with the after offset, not null
*/
public LocalDateTime getDateTimeAfter() {
return transition.plusSeconds(getDurationSeconds());
}
/**
* Gets the offset before the transition.
* <p>
* This is the offset in use before the instant of the transition.
*
* @return the offset before the transition, not null
*/
public ZoneOffset getOffsetBefore() {
return offsetBefore;
}
/**
* Gets the offset after the transition.
* <p>
* This is the offset in use on and after the instant of the transition.
*
* @return the offset after the transition, not null
*/
public ZoneOffset getOffsetAfter() {
return offsetAfter;
}
/**
* Gets the duration of the transition in seconds.
*
* @return the duration in seconds
*/
private int getDurationSeconds() {
return getOffsetAfter().getTotalSeconds() - getOffsetBefore().getTotalSeconds();
}
/**
* Does this transition represent a gap in the local time-line.
* <p>
* Gaps occur where there are local date-times that simply do not not exist.
* An example would be when the offset changes from {@code +01:00} to {@code +02:00}.
* This might be described as 'the clocks will move forward one hour tonight at 1am'.
*
* @return true if this transition is a gap, false if it is an overlap
*/
public boolean isGap() {
return getOffsetAfter().getTotalSeconds() > getOffsetBefore().getTotalSeconds();
}
/**
* Does this transition represent a gap in the local time-line.
* <p>
* Overlaps occur where there are local date-times that exist twice.
* An example would be when the offset changes from {@code +02:00} to {@code +01:00}.
* This might be described as 'the clocks will move back one hour tonight at 2am'.
*
* @return true if this transition is an overlap, false if it is a gap
*/
public boolean isOverlap() {
return getOffsetAfter().getTotalSeconds() < getOffsetBefore().getTotalSeconds();
}
/**
* Checks if the specified offset is valid during this transition.
* <p>
* This checks to see if the given offset will be valid at some point in the transition.
* A gap will always return false.
* An overlap will return true if the offset is either the before or after offset.
*
* @param offset the offset to check, null returns false
* @return true if the offset is valid during the transition
*/
public boolean isValidOffset(ZoneOffset offset) {
return isGap() ? false : (getOffsetBefore().equals(offset) || getOffsetAfter().equals(offset));
}
/**
* Gets the valid offsets during this transition.
* <p>
* A gap will return an empty list, while an overlap will return both offsets.
*
* @return the list of valid offsets
*/
List<ZoneOffset> getValidOffsets() {
if (isGap()) {
return Collections.emptyList();
}
return Arrays.asList(getOffsetBefore(), getOffsetAfter());
}
/**
* Compares this transition to another based on the transition instant.
* <p>
* This compares the instants of each transition.
* The offsets are ignored, making this order inconsistent with equals.
*
* @param transition the transition to compare to, not null
* @return the comparator value, negative if less, positive if greater
*/
@Override
public int compareTo(ZoneOffsetTransition transition) {
return Long.compare(this.toEpochSecond(), transition.toEpochSecond());
}
/**
* Checks if this object equals another.
* <p>
* The entire state of the object is compared.
*
* @param other the other object to compare to, null returns false
* @return true if equal
*/
@Override
public boolean equals(Object other) {
if (other == this) {
return true;
}
if (other instanceof ZoneOffsetTransition) {
ZoneOffsetTransition d = (ZoneOffsetTransition) other;
return transition.equals(d.transition) &&
offsetBefore.equals(d.offsetBefore) && offsetAfter.equals(d.offsetAfter);
}
return false;
}
/**
* Returns a suitable hash code.
*
* @return the hash code
*/
@Override
public int hashCode() {
return transition.hashCode() ^ offsetBefore.hashCode() ^ Integer.rotateLeft(offsetAfter.hashCode(), 16);
}
}

View File

@ -0,0 +1,223 @@
/*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* Copyright (c) 2009-2012, Stephen Colebourne & Michael Nascimento Santos
*
* 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 JSR-310 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 COPYRIGHT OWNER 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 build.tools.tzdb;
import static build.tools.tzdb.Utils.*;
import java.util.Objects;
/**
* A rule expressing how to create a transition.
* <p>
* This class allows rules for identifying future transitions to be expressed.
* A rule might be written in many forms:
* <p><ul>
* <li>the 16th March
* <li>the Sunday on or after the 16th March
* <li>the Sunday on or before the 16th March
* <li>the last Sunday in February
* </ul><p>
* These different rule types can be expressed and queried.
*
* <h3>Specification for implementors</h3>
* This class is immutable and thread-safe.
*
* @since 1.8
*/
final class ZoneOffsetTransitionRule {
/**
* The month of the month-day of the first day of the cutover week.
* The actual date will be adjusted by the dowChange field.
*/
final int month;
/**
* The day-of-month of the month-day of the cutover week.
* If positive, it is the start of the week where the cutover can occur.
* If negative, it represents the end of the week where cutover can occur.
* The value is the number of days from the end of the month, such that
* {@code -1} is the last day of the month, {@code -2} is the second
* to last day, and so on.
*/
final byte dom;
/**
* The cutover day-of-week, -1 to retain the day-of-month.
*/
final int dow;
/**
* The cutover time in the 'before' offset.
*/
final LocalTime time;
/**
* Whether the cutover time is midnight at the end of day.
*/
final boolean timeEndOfDay;
/**
* The definition of how the local time should be interpreted.
*/
final TimeDefinition timeDefinition;
/**
* The standard offset at the cutover.
*/
final ZoneOffset standardOffset;
/**
* The offset before the cutover.
*/
final ZoneOffset offsetBefore;
/**
* The offset after the cutover.
*/
final ZoneOffset offsetAfter;
/**
* Creates an instance defining the yearly rule to create transitions between two offsets.
*
* @param month the month of the month-day of the first day of the cutover week, from 1 to 12
* @param dayOfMonthIndicator the day of the month-day of the cutover week, positive if the week is that
* day or later, negative if the week is that day or earlier, counting from the last day of the month,
* from -28 to 31 excluding 0
* @param dayOfWeek the required day-of-week, -1 if the month-day should not be changed
* @param time the cutover time in the 'before' offset, not null
* @param timeEndOfDay whether the time is midnight at the end of day
* @param timeDefnition how to interpret the cutover
* @param standardOffset the standard offset in force at the cutover, not null
* @param offsetBefore the offset before the cutover, not null
* @param offsetAfter the offset after the cutover, not null
* @throws IllegalArgumentException if the day of month indicator is invalid
* @throws IllegalArgumentException if the end of day flag is true when the time is not midnight
*/
ZoneOffsetTransitionRule(
int month,
int dayOfMonthIndicator,
int dayOfWeek,
LocalTime time,
boolean timeEndOfDay,
TimeDefinition timeDefnition,
ZoneOffset standardOffset,
ZoneOffset offsetBefore,
ZoneOffset offsetAfter) {
Objects.requireNonNull(time, "time");
Objects.requireNonNull(timeDefnition, "timeDefnition");
Objects.requireNonNull(standardOffset, "standardOffset");
Objects.requireNonNull(offsetBefore, "offsetBefore");
Objects.requireNonNull(offsetAfter, "offsetAfter");
if (month < 1 || month > 12) {
throw new IllegalArgumentException("month must be between 1 and 12");
}
if (dayOfMonthIndicator < -28 || dayOfMonthIndicator > 31 || dayOfMonthIndicator == 0) {
throw new IllegalArgumentException("Day of month indicator must be between -28 and 31 inclusive excluding zero");
}
if (timeEndOfDay && time.equals(LocalTime.MIDNIGHT) == false) {
throw new IllegalArgumentException("Time must be midnight when end of day flag is true");
}
this.month = month;
this.dom = (byte) dayOfMonthIndicator;
this.dow = dayOfWeek;
this.time = time;
this.timeEndOfDay = timeEndOfDay;
this.timeDefinition = timeDefnition;
this.standardOffset = standardOffset;
this.offsetBefore = offsetBefore;
this.offsetAfter = offsetAfter;
}
//-----------------------------------------------------------------------
/**
* Checks if this object equals another.
* <p>
* The entire state of the object is compared.
*
* @param otherRule the other object to compare to, null returns false
* @return true if equal
*/
@Override
public boolean equals(Object otherRule) {
if (otherRule == this) {
return true;
}
if (otherRule instanceof ZoneOffsetTransitionRule) {
ZoneOffsetTransitionRule other = (ZoneOffsetTransitionRule) otherRule;
return month == other.month && dom == other.dom && dow == other.dow &&
timeDefinition == other.timeDefinition &&
time.equals(other.time) &&
timeEndOfDay == other.timeEndOfDay &&
standardOffset.equals(other.standardOffset) &&
offsetBefore.equals(other.offsetBefore) &&
offsetAfter.equals(other.offsetAfter);
}
return false;
}
/**
* Returns a suitable hash code.
*
* @return the hash code
*/
@Override
public int hashCode() {
int hash = ((time.toSecondOfDay() + (timeEndOfDay ? 1 : 0)) << 15) +
(month << 11) + ((dom + 32) << 5) +
((dow == -1 ? 8 : dow) << 2) + (timeDefinition.ordinal());
return hash ^ standardOffset.hashCode() ^
offsetBefore.hashCode() ^ offsetAfter.hashCode();
}
}

View File

@ -0,0 +1,311 @@
/*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* Copyright (c) 2011-2012, Stephen Colebourne & Michael Nascimento Santos
*
* 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 JSR-310 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 COPYRIGHT OWNER 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 build.tools.tzdb;
import java.io.DataOutput;
import java.io.IOException;
import java.io.ObjectOutput;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;
/**
* Duplicated code of javax.time.zone.ZoneRules, ZoneOffsetTransitionRule
* and Ser to generate the serialization form output of ZoneRules for
* tzdb.jar.
*
* Implementation here is the copy/paste of ZoneRules, ZoneOffsetTransitionRule
* and Ser in javax.time.zone package. Make sure the code here is synchrionozed
* with the serialization implementation there.
*
* @since 1.8
*/
final class ZoneRules {
/**
* The transitions between standard offsets (epoch seconds), sorted.
*/
private final long[] standardTransitions;
/**
* The standard offsets.
*/
private final ZoneOffset[] standardOffsets;
/**
* The transitions between instants (epoch seconds), sorted.
*/
private final long[] savingsInstantTransitions;
/**
* The wall offsets.
*/
private final ZoneOffset[] wallOffsets;
/**
* The last rule.
*/
private final ZoneOffsetTransitionRule[] lastRules;
/**
* Creates an instance.
*
* @param baseStandardOffset the standard offset to use before legal rules were set, not null
* @param baseWallOffset the wall offset to use before legal rules were set, not null
* @param standardOffsetTransitionList the list of changes to the standard offset, not null
* @param transitionList the list of transitions, not null
* @param lastRules the recurring last rules, size 16 or less, not null
*/
ZoneRules(ZoneOffset baseStandardOffset,
ZoneOffset baseWallOffset,
List<ZoneOffsetTransition> standardOffsetTransitionList,
List<ZoneOffsetTransition> transitionList,
List<ZoneOffsetTransitionRule> lastRules) {
this.standardTransitions = new long[standardOffsetTransitionList.size()];
this.standardOffsets = new ZoneOffset[standardOffsetTransitionList.size() + 1];
this.standardOffsets[0] = baseStandardOffset;
for (int i = 0; i < standardOffsetTransitionList.size(); i++) {
this.standardTransitions[i] = standardOffsetTransitionList.get(i).toEpochSecond();
this.standardOffsets[i + 1] = standardOffsetTransitionList.get(i).getOffsetAfter();
}
// convert savings transitions to locals
List<ZoneOffset> localTransitionOffsetList = new ArrayList<>();
localTransitionOffsetList.add(baseWallOffset);
for (ZoneOffsetTransition trans : transitionList) {
localTransitionOffsetList.add(trans.getOffsetAfter());
}
this.wallOffsets = localTransitionOffsetList.toArray(new ZoneOffset[localTransitionOffsetList.size()]);
// convert savings transitions to instants
this.savingsInstantTransitions = new long[transitionList.size()];
for (int i = 0; i < transitionList.size(); i++) {
this.savingsInstantTransitions[i] = transitionList.get(i).toEpochSecond();
}
// last rules
if (lastRules.size() > 16) {
throw new IllegalArgumentException("Too many transition rules");
}
this.lastRules = lastRules.toArray(new ZoneOffsetTransitionRule[lastRules.size()]);
}
/** Type for ZoneRules. */
static final byte ZRULES = 1;
/**
* Writes the state to the stream.
*
* @param out the output stream, not null
* @throws IOException if an error occurs
*/
void writeExternal(DataOutput out) throws IOException {
out.writeByte(ZRULES);
out.writeInt(standardTransitions.length);
for (long trans : standardTransitions) {
writeEpochSec(trans, out);
}
for (ZoneOffset offset : standardOffsets) {
writeOffset(offset, out);
}
out.writeInt(savingsInstantTransitions.length);
for (long trans : savingsInstantTransitions) {
writeEpochSec(trans, out);
}
for (ZoneOffset offset : wallOffsets) {
writeOffset(offset, out);
}
out.writeByte(lastRules.length);
for (ZoneOffsetTransitionRule rule : lastRules) {
writeRule(rule, out);
}
}
/**
* Writes the state the ZoneOffset to the stream.
*
* @param offset the offset, not null
* @param out the output stream, not null
* @throws IOException if an error occurs
*/
static void writeOffset(ZoneOffset offset, DataOutput out) throws IOException {
final int offsetSecs = offset.getTotalSeconds();
int offsetByte = offsetSecs % 900 == 0 ? offsetSecs / 900 : 127; // compress to -72 to +72
out.writeByte(offsetByte);
if (offsetByte == 127) {
out.writeInt(offsetSecs);
}
}
/**
* Writes the epoch seconds to the stream.
*
* @param epochSec the epoch seconds, not null
* @param out the output stream, not null
* @throws IOException if an error occurs
*/
static void writeEpochSec(long epochSec, DataOutput out) throws IOException {
if (epochSec >= -4575744000L && epochSec < 10413792000L && epochSec % 900 == 0) { // quarter hours between 1825 and 2300
int store = (int) ((epochSec + 4575744000L) / 900);
out.writeByte((store >>> 16) & 255);
out.writeByte((store >>> 8) & 255);
out.writeByte(store & 255);
} else {
out.writeByte(255);
out.writeLong(epochSec);
}
}
/**
* Writes the state of the transition rule to the stream.
*
* @param rule the transition rule, not null
* @param out the output stream, not null
* @throws IOException if an error occurs
*/
static void writeRule(ZoneOffsetTransitionRule rule, DataOutput out) throws IOException {
int month = rule.month;
byte dom = rule.dom;
int dow = rule.dow;
LocalTime time = rule.time;
boolean timeEndOfDay = rule.timeEndOfDay;
TimeDefinition timeDefinition = rule.timeDefinition;
ZoneOffset standardOffset = rule.standardOffset;
ZoneOffset offsetBefore = rule.offsetBefore;
ZoneOffset offsetAfter = rule.offsetAfter;
int timeSecs = (timeEndOfDay ? 86400 : time.toSecondOfDay());
int stdOffset = standardOffset.getTotalSeconds();
int beforeDiff = offsetBefore.getTotalSeconds() - stdOffset;
int afterDiff = offsetAfter.getTotalSeconds() - stdOffset;
int timeByte = (timeSecs % 3600 == 0 ? (timeEndOfDay ? 24 : time.getHour()) : 31);
int stdOffsetByte = (stdOffset % 900 == 0 ? stdOffset / 900 + 128 : 255);
int beforeByte = (beforeDiff == 0 || beforeDiff == 1800 || beforeDiff == 3600 ? beforeDiff / 1800 : 3);
int afterByte = (afterDiff == 0 || afterDiff == 1800 || afterDiff == 3600 ? afterDiff / 1800 : 3);
int dowByte = (dow == -1 ? 0 : dow);
int b = (month << 28) + // 4 bytes
((dom + 32) << 22) + // 6 bytes
(dowByte << 19) + // 3 bytes
(timeByte << 14) + // 5 bytes
(timeDefinition.ordinal() << 12) + // 2 bytes
(stdOffsetByte << 4) + // 8 bytes
(beforeByte << 2) + // 2 bytes
afterByte; // 2 bytes
out.writeInt(b);
if (timeByte == 31) {
out.writeInt(timeSecs);
}
if (stdOffsetByte == 255) {
out.writeInt(stdOffset);
}
if (beforeByte == 3) {
out.writeInt(offsetBefore.getTotalSeconds());
}
if (afterByte == 3) {
out.writeInt(offsetAfter.getTotalSeconds());
}
}
/**
* Checks if this set of rules equals another.
* <p>
* Two rule sets are equal if they will always result in the same output
* for any given input instant or local date-time.
* Rules from two different groups may return false even if they are in fact the same.
* <p>
* This definition should result in implementations comparing their entire state.
*
* @param otherRules the other rules, null returns false
* @return true if this rules is the same as that specified
*/
@Override
public boolean equals(Object otherRules) {
if (this == otherRules) {
return true;
}
if (otherRules instanceof ZoneRules) {
ZoneRules other = (ZoneRules) otherRules;
return Arrays.equals(standardTransitions, other.standardTransitions) &&
Arrays.equals(standardOffsets, other.standardOffsets) &&
Arrays.equals(savingsInstantTransitions, other.savingsInstantTransitions) &&
Arrays.equals(wallOffsets, other.wallOffsets) &&
Arrays.equals(lastRules, other.lastRules);
}
return false;
}
/**
* Returns a suitable hash code given the definition of {@code #equals}.
*
* @return the hash code
*/
@Override
public int hashCode() {
return Arrays.hashCode(standardTransitions) ^
Arrays.hashCode(standardOffsets) ^
Arrays.hashCode(savingsInstantTransitions) ^
Arrays.hashCode(wallOffsets) ^
Arrays.hashCode(lastRules);
}
}

View File

@ -0,0 +1,743 @@
/*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* Copyright (c) 2009-2012, Stephen Colebourne & Michael Nascimento Santos
*
* 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 JSR-310 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 COPYRIGHT OWNER 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 build.tools.tzdb;
import static build.tools.tzdb.Utils.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
* A mutable builder used to create all the rules for a historic time-zone.
* <p>
* The rules of a time-zone describe how the offset changes over time.
* The rules are created by building windows on the time-line within which
* the different rules apply. The rules may be one of two kinds:
* <p><ul>
* <li>Fixed savings - A single fixed amount of savings from the standard offset will apply.</li>
* <li>Rules - A set of one or more rules describe how daylight savings changes during the window.</li>
* </ul><p>
*
* <h4>Implementation notes</h4>
* This class is a mutable builder used to create zone instances.
* It must only be used from a single thread.
* The created instances are immutable and thread-safe.
*
* @since 1.8
*/
public class ZoneRulesBuilder {
/**
* The list of windows.
*/
private List<TZWindow> windowList = new ArrayList<>();
//-----------------------------------------------------------------------
/**
* Constructs an instance of the builder that can be used to create zone rules.
* <p>
* The builder is used by adding one or more windows representing portions
* of the time-line. The standard offset from UTC/Greenwich will be constant
* within a window, although two adjacent windows can have the same standard offset.
* <p>
* Within each window, there can either be a
* {@link #setFixedSavingsToWindow fixed savings amount} or a
* {@link #addRuleToWindow list of rules}.
*/
public ZoneRulesBuilder() {
}
//-----------------------------------------------------------------------
/**
* Adds a window to the builder that can be used to filter a set of rules.
* <p>
* This method defines and adds a window to the zone where the standard offset is specified.
* The window limits the effect of subsequent additions of transition rules
* or fixed savings. If neither rules or fixed savings are added to the window
* then the window will default to no savings.
* <p>
* Each window must be added sequentially, as the start instant of the window
* is derived from the until instant of the previous window.
*
* @param standardOffset the standard offset, not null
* @param until the date-time that the offset applies until, not null
* @param untilDefinition the time type for the until date-time, not null
* @return this, for chaining
* @throws IllegalStateException if the window order is invalid
*/
public ZoneRulesBuilder addWindow(
ZoneOffset standardOffset,
LocalDateTime until,
TimeDefinition untilDefinition) {
Objects.requireNonNull(standardOffset, "standardOffset");
Objects.requireNonNull(until, "until");
Objects.requireNonNull(untilDefinition, "untilDefinition");
TZWindow window = new TZWindow(standardOffset, until, untilDefinition);
if (windowList.size() > 0) {
TZWindow previous = windowList.get(windowList.size() - 1);
window.validateWindowOrder(previous);
}
windowList.add(window);
return this;
}
/**
* Adds a window that applies until the end of time to the builder that can be
* used to filter a set of rules.
* <p>
* This method defines and adds a window to the zone where the standard offset is specified.
* The window limits the effect of subsequent additions of transition rules
* or fixed savings. If neither rules or fixed savings are added to the window
* then the window will default to no savings.
* <p>
* This must be added after all other windows.
* No more windows can be added after this one.
*
* @param standardOffset the standard offset, not null
* @return this, for chaining
* @throws IllegalStateException if a forever window has already been added
*/
public ZoneRulesBuilder addWindowForever(ZoneOffset standardOffset) {
return addWindow(standardOffset, LocalDateTime.MAX, TimeDefinition.WALL);
}
//-----------------------------------------------------------------------
/**
* Sets the previously added window to have fixed savings.
* <p>
* Setting a window to have fixed savings simply means that a single daylight
* savings amount applies throughout the window. The window could be small,
* such as a single summer, or large, such as a multi-year daylight savings.
* <p>
* A window can either have fixed savings or rules but not both.
*
* @param fixedSavingAmountSecs the amount of saving to use for the whole window, not null
* @return this, for chaining
* @throws IllegalStateException if no window has yet been added
* @throws IllegalStateException if the window already has rules
*/
public ZoneRulesBuilder setFixedSavingsToWindow(int fixedSavingAmountSecs) {
if (windowList.isEmpty()) {
throw new IllegalStateException("Must add a window before setting the fixed savings");
}
TZWindow window = windowList.get(windowList.size() - 1);
window.setFixedSavings(fixedSavingAmountSecs);
return this;
}
//-----------------------------------------------------------------------
/**
* Adds a single transition rule to the current window.
* <p>
* This adds a rule such that the offset, expressed as a daylight savings amount,
* changes at the specified date-time.
*
* @param transitionDateTime the date-time that the transition occurs as defined by timeDefintion, not null
* @param timeDefinition the definition of how to convert local to actual time, not null
* @param savingAmountSecs the amount of saving from the standard offset after the transition in seconds
* @return this, for chaining
* @throws IllegalStateException if no window has yet been added
* @throws IllegalStateException if the window already has fixed savings
* @throws IllegalStateException if the window has reached the maximum capacity of 2000 rules
*/
public ZoneRulesBuilder addRuleToWindow(
LocalDateTime transitionDateTime,
TimeDefinition timeDefinition,
int savingAmountSecs) {
Objects.requireNonNull(transitionDateTime, "transitionDateTime");
return addRuleToWindow(
transitionDateTime.getYear(), transitionDateTime.getYear(),
transitionDateTime.getMonth(), transitionDateTime.getDayOfMonth(),
-1, transitionDateTime.getTime(), false, timeDefinition, savingAmountSecs);
}
/**
* Adds a single transition rule to the current window.
* <p>
* This adds a rule such that the offset, expressed as a daylight savings amount,
* changes at the specified date-time.
*
* @param year the year of the transition, from MIN_YEAR to MAX_YEAR
* @param month the month of the transition, not null
* @param dayOfMonthIndicator the day-of-month of the transition, adjusted by dayOfWeek,
* from 1 to 31 adjusted later, or -1 to -28 adjusted earlier from the last day of the month
* @param time the time that the transition occurs as defined by timeDefintion, not null
* @param timeEndOfDay whether midnight is at the end of day
* @param timeDefinition the definition of how to convert local to actual time, not null
* @param savingAmountSecs the amount of saving from the standard offset after the transition in seconds
* @return this, for chaining
* @throws DateTimeException if a date-time field is out of range
* @throws IllegalStateException if no window has yet been added
* @throws IllegalStateException if the window already has fixed savings
* @throws IllegalStateException if the window has reached the maximum capacity of 2000 rules
*/
public ZoneRulesBuilder addRuleToWindow(
int year,
int month,
int dayOfMonthIndicator,
LocalTime time,
boolean timeEndOfDay,
TimeDefinition timeDefinition,
int savingAmountSecs) {
return addRuleToWindow(year, year, month, dayOfMonthIndicator, -1, time, timeEndOfDay, timeDefinition, savingAmountSecs);
}
/**
* Adds a multi-year transition rule to the current window.
* <p>
* This adds a rule such that the offset, expressed as a daylight savings amount,
* changes at the specified date-time for each year in the range.
*
* @param startYear the start year of the rule, from MIN_YEAR to MAX_YEAR
* @param endYear the end year of the rule, from MIN_YEAR to MAX_YEAR
* @param month the month of the transition, from 1 to 12
* @param dayOfMonthIndicator the day-of-month of the transition, adjusted by dayOfWeek,
* from 1 to 31 adjusted later, or -1 to -28 adjusted earlier from the last day of the month
* @param dayOfWeek the day-of-week to adjust to, -1 if day-of-month should not be adjusted
* @param time the time that the transition occurs as defined by timeDefintion, not null
* @param timeEndOfDay whether midnight is at the end of day
* @param timeDefinition the definition of how to convert local to actual time, not null
* @param savingAmountSecs the amount of saving from the standard offset after the transition in seconds
* @return this, for chaining
* @throws DateTimeException if a date-time field is out of range
* @throws IllegalArgumentException if the day of month indicator is invalid
* @throws IllegalArgumentException if the end of day midnight flag does not match the time
* @throws IllegalStateException if no window has yet been added
* @throws IllegalStateException if the window already has fixed savings
* @throws IllegalStateException if the window has reached the maximum capacity of 2000 rules
*/
public ZoneRulesBuilder addRuleToWindow(
int startYear,
int endYear,
int month,
int dayOfMonthIndicator,
int dayOfWeek,
LocalTime time,
boolean timeEndOfDay,
TimeDefinition timeDefinition,
int savingAmountSecs) {
Objects.requireNonNull(time, "time");
Objects.requireNonNull(timeDefinition, "timeDefinition");
if (dayOfMonthIndicator < -28 || dayOfMonthIndicator > 31 || dayOfMonthIndicator == 0) {
throw new IllegalArgumentException("Day of month indicator must be between -28 and 31 inclusive excluding zero");
}
if (timeEndOfDay && time.equals(LocalTime.MIDNIGHT) == false) {
throw new IllegalArgumentException("Time must be midnight when end of day flag is true");
}
if (windowList.isEmpty()) {
throw new IllegalStateException("Must add a window before adding a rule");
}
TZWindow window = windowList.get(windowList.size() - 1);
window.addRule(startYear, endYear, month, dayOfMonthIndicator, dayOfWeek, time, timeEndOfDay, timeDefinition, savingAmountSecs);
return this;
}
//-----------------------------------------------------------------------
/**
* Completes the build converting the builder to a set of time-zone rules.
* <p>
* Calling this method alters the state of the builder.
* Further rules should not be added to this builder once this method is called.
*
* @param zoneId the time-zone ID, not null
* @return the zone rules, not null
* @throws IllegalStateException if no windows have been added
* @throws IllegalStateException if there is only one rule defined as being forever for any given window
*/
public ZoneRules toRules(String zoneId) {
Objects.requireNonNull(zoneId, "zoneId");
if (windowList.isEmpty()) {
throw new IllegalStateException("No windows have been added to the builder");
}
final List<ZoneOffsetTransition> standardTransitionList = new ArrayList<>(4);
final List<ZoneOffsetTransition> transitionList = new ArrayList<>(256);
final List<ZoneOffsetTransitionRule> lastTransitionRuleList = new ArrayList<>(2);
// initialize the standard offset calculation
final TZWindow firstWindow = windowList.get(0);
ZoneOffset loopStandardOffset = firstWindow.standardOffset;
int loopSavings = 0;
if (firstWindow.fixedSavingAmountSecs != null) {
loopSavings = firstWindow.fixedSavingAmountSecs;
}
final ZoneOffset firstWallOffset = ZoneOffset.ofTotalSeconds(loopStandardOffset.getTotalSeconds() + loopSavings);
LocalDateTime loopWindowStart = LocalDateTime.of(YEAR_MIN_VALUE, 1, 1, 0, 0);
ZoneOffset loopWindowOffset = firstWallOffset;
// build the windows and rules to interesting data
for (TZWindow window : windowList) {
// tidy the state
window.tidy(loopWindowStart.getYear());
// calculate effective savings at the start of the window
Integer effectiveSavings = window.fixedSavingAmountSecs;
if (effectiveSavings == null) {
// apply rules from this window together with the standard offset and
// savings from the last window to find the savings amount applicable
// at start of this window
effectiveSavings = 0;
for (TZRule rule : window.ruleList) {
if (rule.toEpochSecond(loopStandardOffset, loopSavings) > loopWindowStart.toEpochSecond(loopWindowOffset)) {
// previous savings amount found, which could be the savings amount at
// the instant that the window starts (hence isAfter)
break;
}
effectiveSavings = rule.savingAmountSecs;
}
}
// check if standard offset changed, and update it
if (loopStandardOffset.equals(window.standardOffset) == false) {
standardTransitionList.add(
new ZoneOffsetTransition(
LocalDateTime.ofEpochSecond(loopWindowStart.toEpochSecond(loopWindowOffset), 0, loopStandardOffset),
loopStandardOffset, window.standardOffset));
loopStandardOffset = window.standardOffset;
}
// check if the start of the window represents a transition
ZoneOffset effectiveWallOffset = ZoneOffset.ofTotalSeconds(loopStandardOffset.getTotalSeconds() + effectiveSavings);
if (loopWindowOffset.equals(effectiveWallOffset) == false) {
transitionList.add(new ZoneOffsetTransition(loopWindowStart, loopWindowOffset, effectiveWallOffset));
}
loopSavings = effectiveSavings;
// apply rules within the window
for (TZRule rule : window.ruleList) {
if (rule.isTransition(loopSavings)) {
ZoneOffsetTransition trans = rule.toTransition(loopStandardOffset, loopSavings);
if (trans.toEpochSecond() < loopWindowStart.toEpochSecond(loopWindowOffset) == false &&
trans.toEpochSecond() < window.createDateTimeEpochSecond(loopSavings)) {
transitionList.add(trans);
loopSavings = rule.savingAmountSecs;
}
}
}
// calculate last rules
for (TZRule lastRule : window.lastRuleList) {
lastTransitionRuleList.add(lastRule.toTransitionRule(loopStandardOffset, loopSavings));
loopSavings = lastRule.savingAmountSecs;
}
// finally we can calculate the true end of the window, passing it to the next window
loopWindowOffset = window.createWallOffset(loopSavings);
loopWindowStart = LocalDateTime.ofEpochSecond(
window.createDateTimeEpochSecond(loopSavings), 0, loopWindowOffset);
}
return new ZoneRules(
firstWindow.standardOffset, firstWallOffset, standardTransitionList,
transitionList, lastTransitionRuleList);
}
//-----------------------------------------------------------------------
/**
* A definition of a window in the time-line.
* The window will have one standard offset and will either have a
* fixed DST savings or a set of rules.
*/
class TZWindow {
/** The standard offset during the window, not null. */
private final ZoneOffset standardOffset;
/** The end local time, not null. */
private final LocalDateTime windowEnd;
/** The type of the end time, not null. */
private final TimeDefinition timeDefinition;
/** The fixed amount of the saving to be applied during this window. */
private Integer fixedSavingAmountSecs;
/** The rules for the current window. */
private List<TZRule> ruleList = new ArrayList<>();
/** The latest year that the last year starts at. */
private int maxLastRuleStartYear = YEAR_MIN_VALUE;
/** The last rules. */
private List<TZRule> lastRuleList = new ArrayList<>();
/**
* Constructor.
*
* @param standardOffset the standard offset applicable during the window, not null
* @param windowEnd the end of the window, relative to the time definition, null if forever
* @param timeDefinition the time definition for calculating the true end, not null
*/
TZWindow(
ZoneOffset standardOffset,
LocalDateTime windowEnd,
TimeDefinition timeDefinition) {
super();
this.windowEnd = windowEnd;
this.timeDefinition = timeDefinition;
this.standardOffset = standardOffset;
}
/**
* Sets the fixed savings amount for the window.
*
* @param fixedSavingAmount the amount of daylight saving to apply throughout the window, may be null
* @throws IllegalStateException if the window already has rules
*/
void setFixedSavings(int fixedSavingAmount) {
if (ruleList.size() > 0 || lastRuleList.size() > 0) {
throw new IllegalStateException("Window has DST rules, so cannot have fixed savings");
}
this.fixedSavingAmountSecs = fixedSavingAmount;
}
/**
* Adds a rule to the current window.
*
* @param startYear the start year of the rule, from MIN_YEAR to MAX_YEAR
* @param endYear the end year of the rule, from MIN_YEAR to MAX_YEAR
* @param month the month of the transition, not null
* @param dayOfMonthIndicator the day-of-month of the transition, adjusted by dayOfWeek,
* from 1 to 31 adjusted later, or -1 to -28 adjusted earlier from the last day of the month
* @param dayOfWeek the day-of-week to adjust to, null if day-of-month should not be adjusted
* @param time the time that the transition occurs as defined by timeDefintion, not null
* @param timeEndOfDay whether midnight is at the end of day
* @param timeDefinition the definition of how to convert local to actual time, not null
* @param savingAmountSecs the amount of saving from the standard offset in seconds
* @throws IllegalStateException if the window already has fixed savings
* @throws IllegalStateException if the window has reached the maximum capacity of 2000 rules
*/
void addRule(
int startYear,
int endYear,
int month,
int dayOfMonthIndicator,
int dayOfWeek,
LocalTime time,
boolean timeEndOfDay,
TimeDefinition timeDefinition,
int savingAmountSecs) {
if (fixedSavingAmountSecs != null) {
throw new IllegalStateException("Window has a fixed DST saving, so cannot have DST rules");
}
if (ruleList.size() >= 2000) {
throw new IllegalStateException("Window has reached the maximum number of allowed rules");
}
boolean lastRule = false;
if (endYear == YEAR_MAX_VALUE) {
lastRule = true;
endYear = startYear;
}
int year = startYear;
while (year <= endYear) {
TZRule rule = new TZRule(year, month, dayOfMonthIndicator, dayOfWeek, time, timeEndOfDay, timeDefinition, savingAmountSecs);
if (lastRule) {
lastRuleList.add(rule);
maxLastRuleStartYear = Math.max(startYear, maxLastRuleStartYear);
} else {
ruleList.add(rule);
}
year++;
}
}
/**
* Validates that this window is after the previous one.
*
* @param previous the previous window, not null
* @throws IllegalStateException if the window order is invalid
*/
void validateWindowOrder(TZWindow previous) {
if (windowEnd.compareTo(previous.windowEnd) < 0) {
throw new IllegalStateException("Windows must be added in date-time order: " +
windowEnd + " < " + previous.windowEnd);
}
}
/**
* Adds rules to make the last rules all start from the same year.
* Also add one more year to avoid weird case where penultimate year has odd offset.
*
* @param windowStartYear the window start year
* @throws IllegalStateException if there is only one rule defined as being forever
*/
void tidy(int windowStartYear) {
if (lastRuleList.size() == 1) {
throw new IllegalStateException("Cannot have only one rule defined as being forever");
}
// handle last rules
if (windowEnd.equals(LocalDateTime.MAX)) {
// setup at least one real rule, which closes off other windows nicely
maxLastRuleStartYear = Math.max(maxLastRuleStartYear, windowStartYear) + 1;
for (TZRule lastRule : lastRuleList) {
addRule(lastRule.year, maxLastRuleStartYear, lastRule.month, lastRule.dayOfMonthIndicator,
lastRule.dayOfWeek, lastRule.time, lastRule.timeEndOfDay, lastRule.timeDefinition, lastRule.savingAmountSecs);
lastRule.year = maxLastRuleStartYear + 1;
}
if (maxLastRuleStartYear == YEAR_MAX_VALUE) {
lastRuleList.clear();
} else {
maxLastRuleStartYear++;
}
} else {
// convert all within the endYear limit
int endYear = windowEnd.getYear();
for (TZRule lastRule : lastRuleList) {
addRule(lastRule.year, endYear + 1, lastRule.month, lastRule.dayOfMonthIndicator,
lastRule.dayOfWeek, lastRule.time, lastRule.timeEndOfDay, lastRule.timeDefinition, lastRule.savingAmountSecs);
}
lastRuleList.clear();
maxLastRuleStartYear = YEAR_MAX_VALUE;
}
// ensure lists are sorted
Collections.sort(ruleList);
Collections.sort(lastRuleList);
// default fixed savings to zero
if (ruleList.size() == 0 && fixedSavingAmountSecs == null) {
fixedSavingAmountSecs = 0;
}
}
/**
* Checks if the window is empty.
*
* @return true if the window is only a standard offset
*/
boolean isSingleWindowStandardOffset() {
return windowEnd.equals(LocalDateTime.MAX) && timeDefinition == TimeDefinition.WALL &&
fixedSavingAmountSecs == null && lastRuleList.isEmpty() && ruleList.isEmpty();
}
/**
* Creates the wall offset for the local date-time at the end of the window.
*
* @param savingsSecs the amount of savings in use in seconds
* @return the created date-time epoch second in the wall offset, not null
*/
ZoneOffset createWallOffset(int savingsSecs) {
return ZoneOffset.ofTotalSeconds(standardOffset.getTotalSeconds() + savingsSecs);
}
/**
* Creates the offset date-time for the local date-time at the end of the window.
*
* @param savingsSecs the amount of savings in use in seconds
* @return the created date-time epoch second in the wall offset, not null
*/
long createDateTimeEpochSecond(int savingsSecs) {
ZoneOffset wallOffset = createWallOffset(savingsSecs);
LocalDateTime ldt = timeDefinition.createDateTime(windowEnd, standardOffset, wallOffset);
return ldt.toEpochSecond(wallOffset);
}
}
//-----------------------------------------------------------------------
/**
* A definition of the way a local time can be converted to an offset time.
*/
class TZRule implements Comparable<TZRule> {
private int year;
private int month;
private int dayOfMonthIndicator;
private int dayOfWeek;
private LocalTime time;
private boolean timeEndOfDay; // Whether the local time is end of day.
private TimeDefinition timeDefinition; // The type of the time.
private int savingAmountSecs; // The amount of the saving to be applied after this point.
/**
* Constructor.
*
* @param year the year
* @param month the month, value from 1 to 12
* @param dayOfMonthIndicator the day-of-month of the transition, adjusted by dayOfWeek,
* from 1 to 31 adjusted later, or -1 to -28 adjusted earlier from the last day of the month
* @param dayOfWeek the day-of-week, -1 if day-of-month is exact
* @param time the time, not null
* @param timeEndOfDay whether midnight is at the end of day
* @param timeDefinition the time definition, not null
* @param savingAfterSecs the savings amount in seconds
*/
TZRule(int year, int month, int dayOfMonthIndicator,
int dayOfWeek, LocalTime time, boolean timeEndOfDay,
TimeDefinition timeDefinition, int savingAfterSecs) {
this.year = year;
this.month = month;
this.dayOfMonthIndicator = dayOfMonthIndicator;
this.dayOfWeek = dayOfWeek;
this.time = time;
this.timeEndOfDay = timeEndOfDay;
this.timeDefinition = timeDefinition;
this.savingAmountSecs = savingAfterSecs;
}
/**
* Converts this to a transition.
*
* @param standardOffset the active standard offset, not null
* @param savingsBeforeSecs the active savings in seconds
* @return the transition, not null
*/
ZoneOffsetTransition toTransition(ZoneOffset standardOffset, int savingsBeforeSecs) {
// copy of code in ZoneOffsetTransitionRule to avoid infinite loop
LocalDate date = toLocalDate();
LocalDateTime ldt = LocalDateTime.of(date, time);
ZoneOffset wallOffset = ZoneOffset.ofTotalSeconds(standardOffset.getTotalSeconds() + savingsBeforeSecs);
LocalDateTime dt = timeDefinition.createDateTime(ldt, standardOffset, wallOffset);
ZoneOffset offsetAfter = ZoneOffset.ofTotalSeconds(standardOffset.getTotalSeconds() + savingAmountSecs);
return new ZoneOffsetTransition(dt, wallOffset, offsetAfter);
}
/**
* Returns the apoch second of this rules with the specified
* active standard offset and active savings
*
* @param standardOffset the active standard offset, not null
* @param savingsBeforeSecs the active savings in seconds
* @return the transition epoch second
*/
long toEpochSecond(ZoneOffset standardOffset, int savingsBeforeSecs) {
LocalDateTime ldt = LocalDateTime.of(toLocalDate(), time);
ZoneOffset wallOffset = ZoneOffset.ofTotalSeconds(standardOffset.getTotalSeconds() + savingsBeforeSecs);
return timeDefinition.createDateTime(ldt, standardOffset, wallOffset)
.toEpochSecond(wallOffset);
}
/**
* Tests if this a real transition with the active savings in seconds
*
* @param savingsBeforeSecs the active savings in seconds
* @return true, if savings in seconds changes
*/
boolean isTransition(int savingsBeforeSecs) {
return savingAmountSecs != savingsBeforeSecs;
}
/**
* Converts this to a transition rule.
*
* @param standardOffset the active standard offset, not null
* @param savingsBeforeSecs the active savings before the transition in seconds
* @return the transition, not null
*/
ZoneOffsetTransitionRule toTransitionRule(ZoneOffset standardOffset, int savingsBeforeSecs) {
// optimize stored format
if (dayOfMonthIndicator < 0) {
if (month != 2) { // not Month.FEBRUARY
dayOfMonthIndicator = maxLengthOfMonth(month) - 6;
}
}
if (timeEndOfDay && dayOfMonthIndicator > 0 &&
(dayOfMonthIndicator == 28 && month == 2) == false) {
LocalDate date = LocalDate.of(2004, month, dayOfMonthIndicator).plusDays(1); // leap-year
month = date.getMonth();
dayOfMonthIndicator = date.getDayOfMonth();
if (dayOfWeek != -1) {
dayOfWeek = plusDayOfWeek(dayOfWeek, 1);
}
timeEndOfDay = false;
}
// build rule
return new ZoneOffsetTransitionRule(
month, dayOfMonthIndicator, dayOfWeek, time, timeEndOfDay, timeDefinition,
standardOffset,
ZoneOffset.ofTotalSeconds(standardOffset.getTotalSeconds() + savingsBeforeSecs),
ZoneOffset.ofTotalSeconds(standardOffset.getTotalSeconds() + savingAmountSecs));
}
public int compareTo(TZRule other) {
int cmp = year - other.year;
cmp = (cmp == 0 ? month - other.month : cmp);
if (cmp == 0) {
// convert to date to handle dow/domIndicator/timeEndOfDay
LocalDate thisDate = toLocalDate();
LocalDate otherDate = other.toLocalDate();
cmp = thisDate.compareTo(otherDate);
}
cmp = (cmp == 0 ? time.compareTo(other.time) : cmp);
return cmp;
}
private LocalDate toLocalDate() {
LocalDate date;
if (dayOfMonthIndicator < 0) {
int monthLen = lengthOfMonth(month, isLeapYear(year));
date = LocalDate.of(year, month, monthLen + 1 + dayOfMonthIndicator);
if (dayOfWeek != -1) {
date = previousOrSame(date, dayOfWeek);
}
} else {
date = LocalDate.of(year, month, dayOfMonthIndicator);
if (dayOfWeek != -1) {
date = nextOrSame(date, dayOfWeek);
}
}
if (timeEndOfDay) {
date = date.plusDays(1);
}
return date;
}
}
}

View File

@ -0,0 +1,43 @@
#
# Copyright (c) 1998, 2005, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Oracle designates this
# particular file as subject to the "Classpath" exception as provided
# by Oracle in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
#
# Makefile for building the tzdb compiler tool
#
BUILDDIR = ../..
PACKAGE = build.tools.tzdb
PRODUCT = tzdb
PROGRAM = tzdb
include $(BUILDDIR)/common/Defs.gmk
BUILDTOOL_SOURCE_ROOT = $(BUILDDIR)/tools/src
BUILDTOOL_MAIN = $(PKGDIR)/TzdbZoneRulesCompiler.java
#
# Build tool jar rules.
#
include $(BUILDDIR)/common/BuildToolJar.gmk

View File

@ -59,6 +59,12 @@ ifndef OPENJDK
# This gets built on unix platforms implicitly in the old build even though
# it's excluded in the closed build.
EXCLUDES+=sun/java2d/pisces
# AccessBridge is compiled separately below.
EXFILES += AccessBridge.java \
com/sun/java/accessibility/util/java/awt/ChoiceTranslator.java
# This seems to never be built
EXCLUDES += com/sun/java/accessibility/extensions
endif
endif
@ -248,10 +254,8 @@ include CopyIntoClasses.gmk
# Now we have COPY_PATTERNS, COPY_FILES and COPY_EXTRA
ifndef OPENJDK
CLOSED_SRC_DIRS:=$(JDK_TOPDIR)/src/closed/share/classes
ifneq ($(OPENJDK_TARGET_OS_API_DIR),windows)
CLOSED_SRC_DIRS += $(JDK_TOPDIR)/src/closed/$(OPENJDK_TARGET_OS_API_DIR)/classes
endif
CLOSED_SRC_DIRS:=$(JDK_TOPDIR)/src/closed/share/classes \
$(JDK_TOPDIR)/src/closed/$(OPENJDK_TARGET_OS_API_DIR)/classes
endif
MACOSX_SRC_DIRS :=
@ -364,8 +368,44 @@ endif
##########################################################################################
# copy with -a to preserve timestamps so dependencies down the line aren't messed up
ifndef OPENJDK
ifeq ($(OPENJDK_TARGET_OS), windows)
ifeq ($(OPENJDK_TARGET_CPU_BITS), 32)
$(eval $(call SetupJavaCompilation,BUILD_ACCESSBRIDGE_32,\
SETUP:=GENERATE_JDKBYTECODE,\
JAVAC_FLAGS:=-cp $(JDK_OUTPUTDIR)/classes,\
SRC:=$(JDK_OUTPUTDIR)/gensrc_ab/32bit,\
BIN:=$(JDK_OUTPUTDIR)/classes_ab/32bit))
$(BUILD_ACCESSBRIDGE_32): $(BUILD_JDK)
$(eval $(call SetupJavaCompilation,BUILD_ACCESSBRIDGE_LEGACY,\
SETUP:=GENERATE_JDKBYTECODE,\
JAVAC_FLAGS:=-cp $(JDK_OUTPUTDIR)/classes,\
SRC:=$(JDK_OUTPUTDIR)/gensrc_ab/legacy,\
BIN:=$(JDK_OUTPUTDIR)/classes_ab/legacy))
$(BUILD_ACCESSBRIDGE_LEGACY): $(BUILD_JDK)
else
$(eval $(call SetupJavaCompilation,BUILD_ACCESSBRIDGE_64,\
SETUP:=GENERATE_JDKBYTECODE,\
JAVAC_FLAGS:=-cp $(JDK_OUTPUTDIR)/classes,\
SRC:=$(JDK_OUTPUTDIR)/gensrc_ab/64bit,\
BIN:=$(JDK_OUTPUTDIR)/classes_ab/64bit))
$(BUILD_ACCESSBRIDGE_64): $(BUILD_JDK)
endif
endif
endif
##########################################################################################
all: $(BUILD_JDK) $(BUILD_ALTCLASSES) $(BUILD_JOBJC) $(BUILD_JOBJC_HEADERS) $(COPY_EXTRA) \
$(JDK_OUTPUTDIR)/classes/META-INF/services/com.sun.tools.xjc.Plugin
$(JDK_OUTPUTDIR)/classes/META-INF/services/com.sun.tools.xjc.Plugin \
$(BUILD_ACCESSBRIDGE_32) $(BUILD_ACCESSBRIDGE_64) \
$(BUILD_ACCESSBRIDGE_LEGACY)
.PHONY: all

View File

@ -590,6 +590,34 @@ else
$(CHMOD) a+x $@
endif
##########################################################################################
# jabswitch
ifndef OPENJDK
ifeq ($(OPENJDK_TARGET_OS),windows)
$(eval $(call SetupNativeCompilation,BUILD_JABSWITCH,\
SRC:=$(JDK_TOPDIR)/src/closed/windows/native/sun/bridge,\
INCLUDE_FILES:=jabswitch.cpp,\
LANG:=C++,\
CFLAGS:=$(filter-out -Zc:wchar_t-,$(CFLAGS_JDKEXE)) -Zc:wchar_t \
-analyze- -Od -Gd -D_WINDOWS \
-D_UNICODE -DUNICODE -RTC1 -EHsc,\
LDFLAGS:=$(LDFLAGS_JDKEXE) \
Advapi32.lib Version.lib User32.lib,\
OBJECT_DIR:=$(JDK_OUTPUTDIR)/objs/jabswitch,\
OUTPUT_DIR:=$(JDK_OUTPUTDIR)/bin,\
PROGRAM:=jabswitch,\
DEBUG_SYMBOLS:=true,\
VERSIONINFO_RESOURCE:=$(JDK_TOPDIR)/src/closed/windows/native/sun/bridge/AccessBridgeStatusWindow.rc,\
RC_FLAGS:=$(RC_FLAGS),\
MANIFEST:=$(JDK_TOPDIR)/src/closed/windows/native/sun/bridge/jabswitch.manifest))
BUILD_LAUNCHERS += $(BUILD_JABSWITCH)
endif
endif
##########################################################################################
$(BUILD_LAUNCHERS) : $(JDK_TOPDIR)/makefiles/CompileLaunchers.gmk

View File

@ -3294,6 +3294,97 @@ BUILD_LIBRARIES += $(INSTALL_LIBRARIES_HERE)/$(LIBRARY_PREFIX)JObjC$(SHARED_LIBR
endif
##########################################################################################
ifndef OPENJDK
ifeq ($(OPENJDK_TARGET_OS), windows)
ACCESSBRIDGE_SRCDIR:=$(JDK_TOPDIR)/src/closed/windows/native/sun/bridge
define SetupAccessBridge
# Parameter 1 Suffix
# Parameter 2 Machine
# Parameter 3 ACCESSBRIDGE_ARCH_ suffix
$(call SetupNativeCompilation,BUILD_JAWTACCESSBRIDGE$1,\
LIBRARY=JAWTAccessBridge$1,\
OUTPUT_DIR:=$(INSTALL_LIBRARIES_HERE),\
SRC:=$(ACCESSBRIDGE_SRCDIR),\
INCLUDE_FILES:=JAWTAccessBridge.cpp,\
LANG:=C++,\
OPTIMIZATION:=LOW,\
CFLAGS:=$(CFLAGS_JDKLIB) \
-DACCESSBRIDGE_ARCH_$3,\
LDFLAGS:=$(LDFLAGS_JDKLIB) kernel32.lib user32.lib gdi32.lib \
winspool.lib jawt.lib comdlg32.lib advapi32.lib shell32.lib \
ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib \
-subsystem:windows -machine:$2 \
-def:$(ACCESSBRIDGE_SRCDIR)/JAWTAccessBridge.DEF,\
VERSIONINFO_RESOURCE:=$(ACCESSBRIDGE_SRCDIR)/AccessBridgeStatusWindow.rc,\
RC_FLAGS:=$(RC_FLAGS),\
OBJECT_DIR:=$(JDK_OUTPUTDIR)/objs/libjawtaccessbridge$1,\
DEBUG_SYMBOLS:=true)
$$(BUILD_JAWTACCESSBRIDGE$1): $(JDK_OUTPUTDIR)/lib/$(LIBRARY_PREFIX)jawt$(STATIC_LIBRARY_SUFFIX)
$(call SetupNativeCompilation,BUILD_JAVAACCESSBRIDGE$1,\
LIBRARY=JavaAccessBridge$1,\
OUTPUT_DIR:=$(INSTALL_LIBRARIES_HERE),\
SRC:=$(ACCESSBRIDGE_SRCDIR),\
INCLUDE_FILES:=AccessBridgeATInstance.cpp AccessBridgeDebug.cpp \
AccessBridgeJavaEntryPoints.cpp \
AccessBridgeMessages.cpp JavaAccessBridge.cpp,\
LANG:=C++,\
OPTIMIZATION:=LOW,\
CFLAGS:=$(CFLAGS_JDKLIB) \
-DACCESSBRIDGE_ARCH_$3,\
LDFLAGS:=$(LDFLAGS_JDKLIB) kernel32.lib user32.lib gdi32.lib \
winspool.lib comdlg32.lib advapi32.lib shell32.lib \
ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib \
-subsystem:windows -machine:$2 \
-def:$(ACCESSBRIDGE_SRCDIR)/JavaAccessBridge.DEF,\
VERSIONINFO_RESOURCE:=$(ACCESSBRIDGE_SRCDIR)/AccessBridgeStatusWindow.rc,\
RC_FLAGS:=$(RC_FLAGS),\
OBJECT_DIR:=$(JDK_OUTPUTDIR)/objs/libjavaaccessbridge$1,\
DEBUG_SYMBOLS:=true)
$(call SetupNativeCompilation,BUILD_WINDOWSACCESSBRIDGE$1,\
LIBRARY=WindowsAccessBridge$1,\
OUTPUT_DIR:=$(INSTALL_LIBRARIES_HERE),\
SRC:=$(ACCESSBRIDGE_SRCDIR),\
INCLUDE_FILES:=AccessBridgeJavaVMInstance.cpp AccessBridgeMessageQueue.cpp \
AccessBridgeMessages.cpp AccessBridgeWindowsEntryPoints.cpp \
WinAccessBridge.cpp AccessBridgeDebug.cpp \
AccessBridgeEventHandler.cpp,\
LANG:=C++,\
OPTIMIZATION:=LOW,\
CFLAGS:=$(filter-out -MD,$(CFLAGS_JDKLIB)) -MT \
-DACCESSBRIDGE_ARCH_$3,\
LDFLAGS:=$(LDFLAGS_JDKLIB) kernel32.lib user32.lib gdi32.lib \
winspool.lib comdlg32.lib advapi32.lib shell32.lib \
ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib \
-subsystem:windows -machine:$2 \
-def:$(ACCESSBRIDGE_SRCDIR)/WinAccessBridge.DEF,\
VERSIONINFO_RESOURCE:=$(ACCESSBRIDGE_SRCDIR)/AccessBridgeStatusWindow.rc,\
RC_FLAGS:=$(RC_FLAGS),\
OBJECT_DIR:=$(JDK_OUTPUTDIR)/objs/libwindowsaccessbridge$1,\
DEBUG_SYMBOLS:=true)
BUILD_LIBRARIES += $$(BUILD_JAWTACCESSBRIDGE$1) $$(BUILD_JAVAACCESSBRIDGE$1) \
$$(BUILD_WINDOWSACCESSBRIDGE$1)
endef
ifeq ($(OPENJDK_TARGET_CPU_BITS),32)
$(eval $(call SetupAccessBridge,-32,I386,32))
$(eval $(call SetupAccessBridge,,I386,LEGACY))
else
$(eval $(call SetupAccessBridge,-64,X64,64))
endif
endif
endif
##########################################################################################
all: $(COPY_FILES) $(BUILD_LIBRARIES)

View File

@ -42,7 +42,7 @@ H_TARGET_FILES =$(INCLUDEDIR)/jdwpTransport.h \
$(INCLUDEDIR)/jvmticmlr.h \
$(INCLUDEDIR)/classfile_constants.h \
$(INCLUDEDIR)/jawt.h \
$(OPENJDK_TARGET_OS_INCLUDE)/jni_md.h \
$(OPENJDK_TARGET_OS_INCLUDE)/jni_md.h \
$(OPENJDK_TARGET_OS_INCLUDE)/jawt_md.h
$(INCLUDEDIR)/%.h: $(JDK_TOPDIR)/src/share/javavm/export/%.h
@ -59,6 +59,27 @@ COPY_FILES = $(H_TARGET_FILES)
##########################################################################################
ifndef OPENJDK
ifeq ($(OPENJDK_TARGET_OS), windows)
COPY_FILES += $(OPENJDK_TARGET_OS_INCLUDE)/bridge/AccessBridgeCallbacks.h \
$(OPENJDK_TARGET_OS_INCLUDE)/bridge/AccessBridgeCalls.h \
$(OPENJDK_TARGET_OS_INCLUDE)/bridge/AccessBridgePackages.h \
$(OPENJDK_TARGET_OS_INCLUDE)/bridge/AccessBridgeCalls.c \
$(JDK_OUTPUTDIR)/lib/accessibility.properties
$(OPENJDK_TARGET_OS_INCLUDE)/bridge/%: \
$(JDK_TOPDIR)/src/closed/windows/native/sun/bridge/%
$(install-file)
$(JDK_OUTPUTDIR)/lib/accessibility.properties: \
$(JDK_TOPDIR)/src/closed/windows/native/sun/bridge/accessibility.properties
$(install-file)
endif
endif
##########################################################################################
LIBDIR = $(JDK_OUTPUTDIR)/lib
SERVICETAG_LIBDIR = $(LIBDIR)/servicetag

View File

@ -72,6 +72,13 @@ JARS+=$(IMAGES_OUTPUTDIR)/lib/ext/dnsns.jar
##########################################################################################
$(IMAGES_OUTPUTDIR)/lib/tzdb.jar: $(JDK_OUTPUTDIR)/lib/tzdb.jar
$(install-file)
JARS += $(IMAGES_OUTPUTDIR)/lib/tzdb.jar
##########################################################################################
LOCALEDATA_INCLUDE_LOCALES := ar be bg ca cs da de el es et fi fr ga hi hr hu in is it \
iw ja ko lt lv mk ms mt nl no pl pt ro ru sk sl sq sr sv \
th tr uk vi zh
@ -134,6 +141,7 @@ RT_JAR_EXCLUDES := \
com/sun/crypto/provider \
com/sun/istack/internal/tools \
com/sun/jarsigner \
com/sun/java/accessibility \
com/sun/javadoc \
com/sun/jdi \
com/sun/net/ssl/internal/ssl \
@ -934,6 +942,47 @@ JARS+=$(IMAGES_OUTPUTDIR)/src.zip
##########################################################################################
ifndef OPENJDK
ifeq ($(OPENJDK_TARGET_OS), windows)
$(eval $(call SetupArchive,BUILD_JACCESS_JAR,,\
SRCS:=$(JDK_OUTPUTDIR)/classes,\
INCLUDES:=com/sun/java/accessibility/util,\
JAR:=$(IMAGES_OUTPUTDIR)/lib/ext/jaccess.jar,\
SKIP_METAINF:=true))
JARS += $(IMAGES_OUTPUTDIR)/lib/ext/jaccess.jar
ifeq ($(OPENJDK_TARGET_CPU_BITS), 32)
$(eval $(call SetupArchive,BUILD_ACCESSBRIDGE_32_JAR,,\
SRCS:=$(JDK_OUTPUTDIR)/classes_ab/32bit $(JDK_OUTPUTDIR)/classes,\
INCLUDES:=com/sun/java/accessibility,\
JAR:=$(IMAGES_OUTPUTDIR)/lib/ext/access-bridge-32.jar,\
SKIP_METAINF:=true))
$(eval $(call SetupArchive,BUILD_ACCESSBRIDGE_LEGACY_JAR,,\
SRCS:=$(JDK_OUTPUTDIR)/classes_ab/legacy $(JDK_OUTPUTDIR)/classes,\
INCLUDES:=com/sun/java/accessibility,\
JAR:=$(IMAGES_OUTPUTDIR)/lib/ext/access-bridge.jar,\
SKIP_METAINF:=true))
JARS += $(IMAGES_OUTPUTDIR)/lib/ext/access-bridge-32.jar \
$(IMAGES_OUTPUTDIR)/lib/ext/access-bridge.jar
else
$(eval $(call SetupArchive,BUILD_ACCESSBRIDGE_64_JAR,,\
SRCS:=$(JDK_OUTPUTDIR)/classes_ab/64bit $(JDK_OUTPUTDIR)/classes,\
INCLUDES:=com/sun/java/accessibility,\
EXCLUDES:=com/sun/java/accessibility/util/java,\
JAR:=$(IMAGES_OUTPUTDIR)/lib/ext/access-bridge-64.jar,\
SKIP_METAINF:=true))
JARS += $(IMAGES_OUTPUTDIR)/lib/ext/access-bridge-64.jar
endif
endif
endif
##########################################################################################
#
# This is an empty jar (only contains manifest) and fits poorly into framework...
# create simple rule instead

View File

@ -0,0 +1,44 @@
#
# Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Oracle designates this
# particular file as subject to the "Classpath" exception as provided
# by Oracle in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
GENDATA_TZDB :=
#
# Time zone data file creation
#
TZDATA_DIR := $(JDK_TOPDIR)/make/sun/javazic/tzdata
TZDATA_VER := $(subst tzdata,,$(shell $(GREP) '^tzdata' $(TZDATA_DIR)/VERSION))
TZDATA_TZFILE := africa antarctica asia australasia europe northamerica southamerica backward etcetera
TZDATA_TZFILES := $(addprefix $(TZDATA_DIR)/,$(TZDATA_TZFILE))
GENDATA_TZDB_DST := $(JDK_OUTPUTDIR)/lib
GENDATA_TZDB_JAR := tzdb.jar
$(GENDATA_TZDB_DST)/$(GENDATA_TZDB_JAR) : $(TZDATA_TZFILES)
$(RM) $(GENDATA_TZDB_DST)/$(GENDATA_TZDB_JAR)
echo building tzdb from version $(TZDATA_VER)
$(TOOL_TZDB) -verbose -version $(TZDATA_VER) -srcdir $(TZDATA_DIR) -dstdir $(GENDATA_TZDB_DST) $(TZDATA_TZFILE)
GENDATA_TZDB += $(GENDATA_TZDB_DST)/$(GENDATA_TZDB_JAR)

View File

@ -47,6 +47,9 @@ GENDATA += $(GENDATA_FONT_CONFIG)
include GendataTimeZone.gmk
GENDATA += $(GENDATA_TIMEZONE)
include GendataTZDB.gmk
GENDATA += $(GENDATA_TZDB)
include GendataHtml32dtd.gmk
GENDATA += $(GENDATA_HTML32DTD)

View File

@ -190,3 +190,36 @@ $(JDK_OUTPUTDIR)/gensrc/sun/nio/fs/SolarisConstants.java : $(BUILD_GENSRC_SOL_EX
endif
##########################################################################################
ifndef OPENJDK
ifeq ($(OPENJDK_TARGET_OS), windows)
AB_GENSRC_DIR := $(JDK_OUTPUTDIR)/gensrc_ab
AB_SRC_DIR := $(JDK_TOPDIR)/src/closed/windows/classes/com/sun/java/accessibility
ifeq ($(OPENJDK_TARGET_CPU_BITS), 32)
$(AB_GENSRC_DIR)/32bit/com/sun/java/accessibility/AccessBridge.java: \
$(AB_SRC_DIR)/32bit/AccessBridge.java
$(install-file)
$(AB_GENSRC_DIR)/legacy/com/sun/java/accessibility/AccessBridge.java: \
$(AB_SRC_DIR)/legacy/AccessBridge.java
$(install-file)
GENSRC_MISC += $(AB_GENSRC_DIR)/32bit/com/sun/java/accessibility/AccessBridge.java \
$(AB_GENSRC_DIR)/legacy/com/sun/java/accessibility/AccessBridge.java
else
$(AB_GENSRC_DIR)/64bit/com/sun/java/accessibility/AccessBridge.java: \
$(AB_SRC_DIR)/64bit/AccessBridge.java
$(install-file)
GENSRC_MISC += $(AB_GENSRC_DIR)/64bit/com/sun/java/accessibility/AccessBridge.java
endif
endif
endif
##########################################################################################

View File

@ -106,6 +106,10 @@ TOOL_JARSPLIT=$(JAVA) -cp $(JDK_OUTPUTDIR)/btclasses \
TOOL_JAVAZIC=$(JAVA) -cp $(JDK_OUTPUTDIR)/btclasses \
build.tools.javazic.Main
TOOL_TZDB=$(JAVA) -cp $(JDK_OUTPUTDIR)/btclasses \
build.tools.tzdb.TzdbZoneRulesCompiler
# TODO: There are references to the jdwpgen.jar in jdk/make/netbeans/jdwpgen/build.xml
# and nbproject/project.properties in the same dir. Needs to be looked at.
TOOL_JDWPGEN=$(JAVA) -cp $(JDK_OUTPUTDIR)/btclasses build.tools.jdwpgen.Main

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@ -189,6 +189,7 @@ SUNWprivate_1.1 {
Java_java_lang_reflect_Array_setInt;
Java_java_lang_reflect_Array_setLong;
Java_java_lang_reflect_Array_setShort;
Java_java_lang_reflect_Executable_getParameters0;
Java_java_lang_Runtime_freeMemory;
Java_java_lang_Runtime_maxMemory;
Java_java_lang_Runtime_gc;

View File

@ -142,6 +142,21 @@ public class AquaKeyBindings {
}));
}
LateBoundInputMap getPasswordFieldInputMap() {
return new LateBoundInputMap(new SimpleBinding(getTextFieldInputMap().getBindings()),
// nullify all the bindings that may discover space characters in the text
new SimpleBinding(new String[] {
"alt LEFT", null,
"alt KP_LEFT", null,
"alt RIGHT", null,
"alt KP_RIGHT", null,
"shift alt LEFT", null,
"shift alt KP_LEFT", null,
"shift alt RIGHT", null,
"shift alt KP_RIGHT", null,
}));
}
LateBoundInputMap getMultiLineTextInputMap() {
return new LateBoundInputMap(new SimpleBinding(commonTextEditorBindings), new SimpleBinding(new String[] {
"ENTER", DefaultEditorKit.insertBreakAction,

View File

@ -697,7 +697,7 @@ public class AquaLookAndFeel extends BasicLookAndFeel {
"Panel.foreground", black,
"Panel.opaque", useOpaqueComponents,
"PasswordField.focusInputMap", aquaKeyBindings.getTextFieldInputMap(),
"PasswordField.focusInputMap", aquaKeyBindings.getPasswordFieldInputMap(),
"PasswordField.font", controlFont,
"PasswordField.background", textBackground,
"PasswordField.foreground", textForeground,

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -37,7 +37,6 @@ import sun.awt.image.*;
import sun.java2d.*;
import sun.print.*;
import apple.laf.*;
import apple.laf.JRSUIConstants.Widget;
import apple.laf.JRSUIUtils.NineSliceMetricsProvider;
abstract class AquaPainter <T extends JRSUIState> {
@ -63,7 +62,7 @@ abstract class AquaPainter <T extends JRSUIState> {
}
static <T extends JRSUIState> AquaPainter<T> create(final T state, final NineSliceMetricsProvider metricsProvider) {
return new AquaNineSlicingImagePainter<T>(state, metricsProvider);
return new AquaNineSlicingImagePainter<>(state, metricsProvider);
}
abstract void paint(final Graphics2D g, final T stateToPaint, final Component c);
@ -71,7 +70,7 @@ abstract class AquaPainter <T extends JRSUIState> {
final Rectangle boundsRect = new Rectangle();
final JRSUIControl control;
T state;
public AquaPainter(final JRSUIControl control, final T state) {
AquaPainter(final JRSUIControl control, final T state) {
this.control = control;
this.state = state;
}
@ -94,14 +93,14 @@ abstract class AquaPainter <T extends JRSUIState> {
protected final HashMap<T, RecyclableJRSUISlicedImageControl> slicedControlImages;
protected final NineSliceMetricsProvider metricsProvider;
public AquaNineSlicingImagePainter(final T state) {
AquaNineSlicingImagePainter(final T state) {
this(state, null);
}
public AquaNineSlicingImagePainter(final T state, final NineSliceMetricsProvider metricsProvider) {
AquaNineSlicingImagePainter(final T state, final NineSliceMetricsProvider metricsProvider) {
super(new JRSUIControl(false), state);
this.metricsProvider = metricsProvider;
slicedControlImages = new HashMap<T, RecyclableJRSUISlicedImageControl>();
slicedControlImages = new HashMap<>();
}
@Override
@ -127,7 +126,7 @@ abstract class AquaPainter <T extends JRSUIState> {
}
static class AquaSingleImagePainter<T extends JRSUIState> extends AquaPainter<T> {
public AquaSingleImagePainter(final T state) {
AquaSingleImagePainter(final T state) {
super(new JRSUIControl(false), state);
}
@ -137,12 +136,12 @@ abstract class AquaPainter <T extends JRSUIState> {
}
static void paintFromSingleCachedImage(final Graphics2D g, final JRSUIControl control, final JRSUIState controlState, final Component c, final Rectangle boundsRect) {
Rectangle clipRect = g.getClipBounds();
Rectangle intersection = boundsRect.intersection(clipRect);
final Rectangle clipRect = g.getClipBounds();
final Rectangle intersection = boundsRect.intersection(clipRect);
if (intersection.width <= 0 || intersection.height <= 0) return;
int imgX1 = intersection.x - boundsRect.x;
int imgY1 = intersection.y - boundsRect.y;
final int imgX1 = intersection.x - boundsRect.x;
final int imgY1 = intersection.y - boundsRect.y;
final GraphicsConfiguration config = g.getDeviceConfiguration();
final ImageCache cache = ImageCache.getInstance();
@ -150,20 +149,15 @@ abstract class AquaPainter <T extends JRSUIState> {
if (image == null) {
image = new BufferedImage(boundsRect.width, boundsRect.height, BufferedImage.TYPE_INT_ARGB_PRE);
cache.setImage(image, config, boundsRect.width, boundsRect.height, controlState);
} else {
g.drawImage(image, intersection.x, intersection.y, intersection.x + intersection.width, intersection.y + intersection.height,
imgX1, imgY1, imgX1 + intersection.width, imgY1 + intersection.height, null);
return;
final WritableRaster raster = image.getRaster();
final DataBufferInt buffer = (DataBufferInt)raster.getDataBuffer();
control.set(controlState);
control.paint(SunWritableRaster.stealData(buffer, 0),
image.getWidth(), image.getHeight(), 0, 0, boundsRect.width, boundsRect.height);
SunWritableRaster.markDirty(buffer);
}
final WritableRaster raster = image.getRaster();
final DataBufferInt buffer = (DataBufferInt)raster.getDataBuffer();
control.set(controlState);
control.paint(SunWritableRaster.stealData(buffer, 0),
image.getWidth(), image.getHeight(), 0, 0, boundsRect.width, boundsRect.height);
SunWritableRaster.markDirty(buffer);
g.drawImage(image, intersection.x, intersection.y, intersection.x + intersection.width, intersection.y + intersection.height,
imgX1, imgY1, imgX1 + intersection.width, imgY1 + intersection.height, null);
}
@ -173,7 +167,7 @@ abstract class AquaPainter <T extends JRSUIState> {
final JRSUIControl control;
final JRSUIState state;
public RecyclableJRSUISlicedImageControl(final JRSUIControl control, final JRSUIState state, final NineSliceMetrics metrics) {
RecyclableJRSUISlicedImageControl(final JRSUIControl control, final JRSUIState state, final NineSliceMetrics metrics) {
super(metrics);
this.control = control;
this.state = state;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -30,6 +30,7 @@ import java.lang.ref.*;
import java.util.*;
import java.util.concurrent.locks.*;
import apple.laf.JRSUIConstants;
import apple.laf.JRSUIState;
import com.apple.laf.AquaUtils.RecyclableSingleton;
@ -38,9 +39,9 @@ import com.apple.laf.AquaUtils.RecyclableSingleton;
* SoftReferences so they will be dropped by the GC if heap memory gets tight. When our size hits max pixel count least
* recently requested images are removed first.
*/
class ImageCache {
final class ImageCache {
// Ordered Map keyed by args hash, ordered by most recent accessed entry.
private final LinkedHashMap<Integer, PixelCountSoftReference> map = new LinkedHashMap<Integer, PixelCountSoftReference>(16, 0.75f, true);
private final LinkedHashMap<Integer, PixelCountSoftReference> map = new LinkedHashMap<>(16, 0.75f, true);
// Maximum number of pixels to cache, this is used if maxCount
private final int maxPixelCount;
@ -50,7 +51,7 @@ class ImageCache {
// Lock for concurrent access to map
private final ReadWriteLock lock = new ReentrantReadWriteLock();
// Reference queue for tracking lost softreferences to images in the cache
private final ReferenceQueue<Image> referenceQueue = new ReferenceQueue<Image>();
private final ReferenceQueue<Image> referenceQueue = new ReferenceQueue<>();
// Singleton Instance
private static final RecyclableSingleton<ImageCache> instance = new RecyclableSingleton<ImageCache>() {
@ -63,11 +64,11 @@ class ImageCache {
return instance.get();
}
public ImageCache(final int maxPixelCount) {
ImageCache(final int maxPixelCount) {
this.maxPixelCount = maxPixelCount;
}
public ImageCache() {
ImageCache() {
this((8 * 1024 * 1024) / 4); // 8Mb of pixels
}
@ -99,10 +100,13 @@ class ImageCache {
* @param config The graphics configuration, needed if cached image is a Volatile Image. Used as part of cache key
* @param w The image width, used as part of cache key
* @param h The image height, used as part of cache key
* @param args Other arguments to use as part of the cache key
* @return true if the image could be cached or false if the image is too big
* @return true if the image could be cached, false otherwise.
*/
public boolean setImage(final Image image, final GraphicsConfiguration config, final int w, final int h, final JRSUIState state) {
if (state.is(JRSUIConstants.Animating.YES)) {
return false;
}
final int hash = hash(config, w, h, state);
lock.writeLock().lock();
@ -167,7 +171,7 @@ class ImageCache {
private final int h;
private final JRSUIState state;
public PixelCountSoftReference(final Image referent, final ReferenceQueue<? super Image> q, final int pixelCount, final int hash, final GraphicsConfiguration config, final int w, final int h, final JRSUIState state) {
PixelCountSoftReference(final Image referent, final ReferenceQueue<? super Image> q, final int pixelCount, final int hash, final GraphicsConfiguration config, final int w, final int h, final JRSUIState state) {
super(referent, q);
this.pixelCount = pixelCount;
this.hash = hash;

View File

@ -30,6 +30,7 @@ import java.awt.GraphicsDevice;
import java.awt.Window;
import java.awt.AWTPermission;
import java.awt.DisplayMode;
import java.util.Objects;
import sun.java2d.opengl.CGLGraphicsConfig;
@ -122,12 +123,12 @@ public final class CGraphicsDevice extends GraphicsDevice {
boolean fsSupported = isFullScreenSupported();
if (fsSupported && old != null) {
// enter windowed mode (and restore original display mode)
exitFullScreenExclusive(old);
// restore original display mode and enter windowed mode.
if (originalMode != null) {
setDisplayMode(originalMode);
originalMode = null;
}
exitFullScreenExclusive(old);
}
super.setFullScreenWindow(w);
@ -186,13 +187,20 @@ public final class CGraphicsDevice extends GraphicsDevice {
}
@Override
public void setDisplayMode(DisplayMode dm) {
public void setDisplayMode(final DisplayMode dm) {
if (dm == null) {
throw new IllegalArgumentException("Invalid display mode");
}
nativeSetDisplayMode(displayID, dm.getWidth(), dm.getHeight(), dm.getBitDepth(), dm.getRefreshRate());
if (isFullScreenSupported() && getFullScreenWindow() != null) {
getFullScreenWindow().setSize(dm.getWidth(), dm.getHeight());
if (!Objects.equals(dm, getDisplayMode())) {
final Window w = getFullScreenWindow();
if (w != null) {
exitFullScreenExclusive(w);
}
nativeSetDisplayMode(displayID, dm.getWidth(), dm.getHeight(),
dm.getBitDepth(), dm.getRefreshRate());
if (isFullScreenSupported() && w != null) {
enterFullScreenExclusive(w);
}
}
}

View File

@ -1226,7 +1226,7 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
sendEventToDelegate(e);
}
private void sendEventToDelegate(final AWTEvent e) {
protected void sendEventToDelegate(final AWTEvent e) {
synchronized (getDelegateLock()) {
if (getDelegate() == null || !isShowing() || !isEnabled()) {
return;

View File

@ -29,6 +29,7 @@ import javax.swing.*;
import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;
import java.awt.*;
import java.awt.event.MouseWheelEvent;
import java.awt.peer.ScrollPanePeer;
import java.util.List;
@ -51,6 +52,21 @@ final class LWScrollPanePeer extends LWContainerPeer<ScrollPane, JScrollPane>
return sp;
}
@Override
public void handleEvent(AWTEvent e) {
if (e instanceof MouseWheelEvent) {
MouseWheelEvent wheelEvent = (MouseWheelEvent) e;
//java.awt.ScrollPane consumes the event
// in case isWheelScrollingEnabled() is true,
// forcibly send the consumed event to the delegate
if (getTarget().isWheelScrollingEnabled() && wheelEvent.isConsumed()) {
sendEventToDelegate(wheelEvent);
}
} else {
super.handleEvent(e);
}
}
@Override
public void stateChanged(final ChangeEvent e) {
SwingUtilities.invokeLater(new Runnable() {

View File

@ -34,7 +34,7 @@ import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.peer.TextFieldPeer;
import javax.swing.JPasswordField;
import javax.swing.*;
import javax.swing.text.JTextComponent;
final class LWTextFieldPeer
@ -48,7 +48,7 @@ final class LWTextFieldPeer
@Override
protected JPasswordField createDelegate() {
return new JTextAreaDelegate();
return new JPasswordFieldDelegate();
}
@Override
@ -69,9 +69,18 @@ final class LWTextFieldPeer
public void setEchoChar(final char echoChar) {
synchronized (getDelegateLock()) {
getDelegate().setEchoChar(echoChar);
getDelegate().putClientProperty("JPasswordField.cutCopyAllowed",
getDelegate().echoCharIsSet()
? Boolean.FALSE : Boolean.TRUE);
final boolean cutCopyAllowed;
final String focusInputMapKey;
if (echoChar != 0) {
cutCopyAllowed = false;
focusInputMapKey = "PasswordField.focusInputMap";
} else {
cutCopyAllowed = true;
focusInputMapKey = "TextField.focusInputMap";
}
getDelegate().putClientProperty("JPasswordField.cutCopyAllowed", cutCopyAllowed);
InputMap inputMap = (InputMap) UIManager.get(focusInputMapKey);
SwingUtilities.replaceUIInputMap(getDelegate(), JComponent.WHEN_FOCUSED, inputMap);
}
}
@ -106,11 +115,11 @@ final class LWTextFieldPeer
super.handleJavaFocusEvent(e);
}
private final class JTextAreaDelegate extends JPasswordField {
private final class JPasswordFieldDelegate extends JPasswordField {
// Empty non private constructor was added because access to this
// class shouldn't be emulated by a synthetic accessor method.
JTextAreaDelegate() {
JPasswordFieldDelegate() {
super();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -539,7 +539,7 @@ public abstract class LWToolkit extends SunToolkit implements Runnable {
@Override
public void ungrab(Window w) {
if (w.getPeer() != null) {
((LWWindowPeer)w.getPeer()).ungrab();
((LWWindowPeer)w.getPeer()).ungrab(false);
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -53,7 +53,7 @@ public class LWWindowPeer
private static final PlatformLogger focusLog = PlatformLogger.getLogger("sun.lwawt.focus.LWWindowPeer");
private PlatformWindow platformWindow;
private final PlatformWindow platformWindow;
// Window bounds reported by the native system (as opposed to
// regular bounds inherited from LWComponentPeer which are
@ -554,12 +554,14 @@ public class LWWindowPeer
/**
* Called by the {@code PlatformWindow} when this window is moved/resized by
* user. There's no notifyReshape() in LWComponentPeer as the only
* components which could be resized by user are top-level windows.
* user or window insets are changed. There's no notifyReshape() in
* LWComponentPeer as the only components which could be resized by user are
* top-level windows.
*/
public final void notifyReshape(int x, int y, int w, int h) {
final boolean moved;
final boolean resized;
final boolean invalid = updateInsets(platformWindow.getInsets());
synchronized (getStateLock()) {
moved = (x != sysX) || (y != sysY);
resized = (w != sysW) || (h != sysH);
@ -570,7 +572,7 @@ public class LWWindowPeer
}
// Check if anything changed
if (!moved && !resized) {
if (!moved && !resized && !invalid) {
return;
}
// First, update peer's bounds
@ -584,10 +586,10 @@ public class LWWindowPeer
}
// Third, COMPONENT_MOVED/COMPONENT_RESIZED/PAINT events
if (moved) {
if (moved || invalid) {
handleMove(x, y, true);
}
if (resized) {
if (resized || invalid) {
handleResize(w, h, true);
repaintPeer();
}
@ -999,27 +1001,21 @@ public class LWWindowPeer
}
}
/*
* Request the window insets from the delegate and compares it
* with the current one. This method is mostly called by the
* delegate, e.g. when the window state is changed and insets
* should be recalculated.
*
/**
* Request the window insets from the delegate and compares it with the
* current one. This method is mostly called by the delegate, e.g. when the
* window state is changed and insets should be recalculated.
* <p/>
* This method may be called on the toolkit thread.
*/
public boolean updateInsets(Insets newInsets) {
boolean changed = false;
public final boolean updateInsets(final Insets newInsets) {
synchronized (getStateLock()) {
changed = (insets.equals(newInsets));
if (insets.equals(newInsets)) {
return false;
}
insets = newInsets;
}
if (changed) {
replaceSurfaceData();
repaintPeer();
}
return changed;
return true;
}
public static LWWindowPeer getWindowUnderCursor() {
@ -1208,13 +1204,19 @@ public class LWWindowPeer
grabbingWindow = this;
}
void ungrab() {
final void ungrab(boolean doPost) {
if (isGrabbing()) {
grabbingWindow = null;
postEvent(new UngrabEvent(getTarget()));
if (doPost) {
postEvent(new UngrabEvent(getTarget()));
}
}
}
void ungrab() {
ungrab(true);
}
private boolean isGrabbing() {
return this == grabbingWindow;
}

View File

@ -273,8 +273,31 @@ public class CDataTransferer extends DataTransferer {
@Override
protected ByteArrayOutputStream convertFileListToBytes(ArrayList<String> fileList) throws IOException {
// TODO Auto-generated method stub
return null;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
for (int i = 0; i < fileList.size(); i++)
{
byte[] bytes = fileList.get(i).getBytes();
bos.write(bytes, 0, bytes.length);
bos.write(0);
}
return bos;
}
@Override
protected boolean isURIListFormat(long format) {
String nat = getNativeForFormat(format);
if (nat == null) {
return false;
}
try {
DataFlavor df = new DataFlavor(nat);
if (df.getPrimaryType().equals("text") && df.getSubType().equals("uri-list")) {
return true;
}
} catch (Exception e) {
// Not a MIME format.
}
return false;
}
}

View File

@ -27,7 +27,6 @@ package sun.lwawt.macosx;
import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.awt.image.VolatileImage;
import sun.awt.CGraphicsConfig;
import sun.awt.CGraphicsEnvironment;
@ -89,29 +88,8 @@ public class CPlatformView extends CFRetainedResource {
return peer;
}
public void enterFullScreenMode(final long nsWindowPtr) {
public void enterFullScreenMode() {
CWrapper.NSView.enterFullScreenMode(ptr);
// REMIND: CGLSurfaceData expects top-level's size
// and therefore we need to account insets before
// recreating the surface data
Insets insets = peer.getInsets();
Rectangle screenBounds;
final long screenPtr = CWrapper.NSWindow.screen(nsWindowPtr);
try {
screenBounds = CWrapper.NSScreen.frame(screenPtr).getBounds();
} finally {
CWrapper.NSObject.release(screenPtr);
}
// the move/size notification from the underlying system comes
// but it contains a bounds smaller than the whole screen
// and therefore we need to create the synthetic notifications
peer.notifyReshape(screenBounds.x - insets.left,
screenBounds.y - insets.bottom,
screenBounds.width + insets.left + insets.right,
screenBounds.height + insets.top + insets.bottom);
}
public void exitFullScreenMode() {

View File

@ -38,7 +38,6 @@ import sun.awt.*;
import sun.java2d.SurfaceData;
import sun.java2d.opengl.CGLSurfaceData;
import sun.lwawt.*;
import sun.lwawt.LWWindowPeer.PeerType;
import sun.util.logging.PlatformLogger;
import com.apple.laf.*;
@ -58,7 +57,6 @@ public final class CPlatformWindow extends CFRetainedResource implements Platfor
private static native void nativeRevalidateNSWindowShadow(long nsWindowPtr);
private static native void nativeSetNSWindowMinimizedIcon(long nsWindowPtr, long nsImage);
private static native void nativeSetNSWindowRepresentedFilename(long nsWindowPtr, String representedFilename);
private static native void nativeSetNSWindowSecurityWarningPositioning(long nsWindowPtr, double x, double y, float biasX, float biasY);
private static native void nativeSetEnabled(long nsWindowPtr, boolean isEnabled);
private static native void nativeSynthesizeMouseEnteredExitedEvents();
private static native void nativeDispose(long nsWindowPtr);
@ -197,7 +195,8 @@ public final class CPlatformWindow extends CFRetainedResource implements Platfor
// 1) setting native bounds via nativeSetBounds() call
// 2) getting notification from the native level via deliverMoveResizeEvent()
private Rectangle nativeBounds = new Rectangle(0, 0, 0, 0);
private volatile boolean isFullScreenMode = false;
private volatile boolean isFullScreenMode;
private boolean isFullScreenAnimationOn;
private Window target;
private LWWindowPeer peer;
@ -415,8 +414,10 @@ public final class CPlatformWindow extends CFRetainedResource implements Platfor
@Override // PlatformWindow
public Insets getInsets() {
final Insets insets = nativeGetNSWindowInsets(getNSWindowPtr());
return insets;
if (!isFullScreenMode) {
return nativeGetNSWindowInsets(getNSWindowPtr());
}
return new Insets(0, 0, 0, 0);
}
@Override // PlatformWindow
@ -728,7 +729,19 @@ public final class CPlatformWindow extends CFRetainedResource implements Platfor
@Override
public void enterFullScreenMode() {
isFullScreenMode = true;
contentView.enterFullScreenMode(getNSWindowPtr());
contentView.enterFullScreenMode();
// the move/size notification from the underlying system comes
// but it contains a bounds smaller than the whole screen
// and therefore we need to create the synthetic notifications
Rectangle screenBounds;
final long screenPtr = CWrapper.NSWindow.screen(getNSWindowPtr());
try {
screenBounds = CWrapper.NSScreen.frame(screenPtr).getBounds();
} finally {
CWrapper.NSObject.release(screenPtr);
}
peer.notifyReshape(screenBounds.x, screenBounds.y, screenBounds.width,
screenBounds.height);
}
@Override
@ -875,11 +888,10 @@ public final class CPlatformWindow extends CFRetainedResource implements Platfor
final Rectangle oldB = nativeBounds;
nativeBounds = new Rectangle(x, y, width, height);
peer.notifyReshape(x, y, width, height);
if (byUser && !oldB.getSize().equals(nativeBounds.getSize())) {
if ((byUser && !oldB.getSize().equals(nativeBounds.getSize()))
|| isFullScreenAnimationOn) {
flushBuffers();
}
//TODO validateSurface already called from notifyReshape
validateSurface();
}
private void deliverWindowClosingEvent() {
@ -924,6 +936,10 @@ public final class CPlatformWindow extends CFRetainedResource implements Platfor
return false;
}
if (blocker instanceof CPrinterDialogPeer) {
return true;
}
CPlatformWindow pWindow = (CPlatformWindow)blocker.getPlatformWindow();
pWindow.orderAboveSiblings();
@ -975,27 +991,19 @@ public final class CPlatformWindow extends CFRetainedResource implements Platfor
orderAboveSiblings();
}
private void updateDisplay() {
EventQueue.invokeLater(new Runnable() {
public void run() {
validateSurface();
}
});
}
private void updateWindowContent() {
ComponentEvent resizeEvent = new ComponentEvent(target, ComponentEvent.COMPONENT_RESIZED);
SunToolkit.postEvent(SunToolkit.targetToAppContext(target), resizeEvent);
}
private void windowWillEnterFullScreen() {
updateWindowContent();
isFullScreenAnimationOn = true;
}
private void windowDidEnterFullScreen() {
updateDisplay();
isFullScreenAnimationOn = false;
}
private void windowWillExitFullScreen() {
updateWindowContent();
isFullScreenAnimationOn = true;
}
private void windowDidExitFullScreen() {
isFullScreenAnimationOn = false;
}
private void windowDidExitFullScreen() {}
}

View File

@ -101,8 +101,7 @@ Java_sun_lwawt_macosx_CPlatformComponent_nativeCreateComponent
JNF_COCOA_ENTER(env);
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
AWT_ASSERT_APPKIT_THREAD;
CALayer *windowLayer = jlong_to_ptr(windowLayerPtr);
surfaceLayers = [[AWTSurfaceLayers alloc] initWithWindowLayer: windowLayer];
CFRetain(surfaceLayers);
@ -127,7 +126,6 @@ JNF_COCOA_ENTER(env);
AWTSurfaceLayers *surfaceLayers = OBJC(surfaceLayersPtr);
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
AWT_ASSERT_APPKIT_THREAD;
CGRect rect = CGRectMake(x, y, width, height);
[surfaceLayers setBounds: rect];

View File

@ -1243,8 +1243,7 @@ JNF_COCOA_ENTER(env);
jobject cPlatformView = (*env)->NewGlobalRef(env, obj);
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
AWT_ASSERT_APPKIT_THREAD;
CALayer *windowLayer = jlong_to_ptr(windowLayerPtr);
AWTView *view = [[AWTView alloc] initWithRect:rect
platformView:cPlatformView
@ -1274,8 +1273,7 @@ JNF_COCOA_ENTER(env);
NSView *view = (NSView *)jlong_to_ptr(viewPtr);
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
AWT_ASSERT_APPKIT_THREAD;
if (toResize) {
[view setAutoresizingMask: NSViewHeightSizable | NSViewWidthSizable];
} else {
@ -1308,8 +1306,7 @@ JNF_COCOA_ENTER(env);
NSWindow *window = [view window];
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
AWT_ASSERT_APPKIT_THREAD;
ret = (jint)[[AWTWindow getNSWindowDisplayID_AppKitThread: window] intValue];
}];
@ -1336,8 +1333,7 @@ JNF_COCOA_ENTER(env);
NSView *view = (NSView *)jlong_to_ptr(viewPtr);
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
AWT_ASSERT_APPKIT_THREAD;
NSRect viewBounds = [view bounds];
NSRect frameInWindow = [view convertRect:viewBounds toView:nil];
rect = [[view window] convertRectToScreen:frameInWindow];
@ -1366,9 +1362,7 @@ JNIEXPORT jboolean JNICALL Java_sun_lwawt_macosx_CPlatformView_nativeIsViewUnder
JNF_COCOA_ENTER(env);
NSView *nsView = OBJC(viewPtr);
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
AWT_ASSERT_APPKIT_THREAD;
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
NSPoint ptWindowCoords = [[nsView window] mouseLocationOutsideOfEventStream];
NSPoint ptViewCoords = [nsView convertPoint:ptWindowCoords fromView:nil];
underMouse = [nsView hitTest:ptViewCoords] != nil;

View File

@ -738,14 +738,12 @@ JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeCreateNSWind
__block AWTWindow *window = nil;
JNF_COCOA_ENTER(env);
AWT_ASSERT_NOT_APPKIT_THREAD;
JNFWeakJObjectWrapper *platformWindow = [JNFWeakJObjectWrapper wrapperWithJObject:obj withEnv:env];
NSView *contentView = OBJC(contentViewPtr);
NSRect frameRect = NSMakeRect(x, y, w, h);
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
AWT_ASSERT_APPKIT_THREAD;
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
window = [[AWTWindow alloc] initWithPlatformWindow:platformWindow
styleBits:styleBits
@ -770,11 +768,9 @@ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowSt
(JNIEnv *env, jclass clazz, jlong windowPtr, jint mask, jint bits)
{
JNF_COCOA_ENTER(env);
AWT_ASSERT_NOT_APPKIT_THREAD;
NSWindow *nsWindow = OBJC(windowPtr);
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
AWT_ASSERT_APPKIT_THREAD;
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
AWTWindow *window = (AWTWindow*)[nsWindow delegate];
@ -807,12 +803,10 @@ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowMe
(JNIEnv *env, jclass clazz, jlong windowPtr, jlong menuBarPtr)
{
JNF_COCOA_ENTER(env);
AWT_ASSERT_NOT_APPKIT_THREAD;
NSWindow *nsWindow = OBJC(windowPtr);
CMenuBar *menuBar = OBJC(menuBarPtr);
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
AWT_ASSERT_APPKIT_THREAD;
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
AWTWindow *window = (AWTWindow*)[nsWindow delegate];
@ -838,14 +832,12 @@ JNIEXPORT jobject JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeGetNSWindo
jobject ret = NULL;
JNF_COCOA_ENTER(env);
AWT_ASSERT_NOT_APPKIT_THREAD;
NSWindow *nsWindow = OBJC(windowPtr);
__block NSRect contentRect = NSZeroRect;
__block NSRect frame = NSZeroRect;
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
AWT_ASSERT_APPKIT_THREAD;
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
frame = [nsWindow frame];
contentRect = [NSWindow contentRectForFrameRect:frame styleMask:[nsWindow styleMask]];
@ -873,14 +865,12 @@ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowBo
(JNIEnv *env, jclass clazz, jlong windowPtr, jdouble originX, jdouble originY, jdouble width, jdouble height)
{
JNF_COCOA_ENTER(env);
AWT_ASSERT_NOT_APPKIT_THREAD;
NSRect jrect = NSMakeRect(originX, originY, width, height);
// TODO: not sure we need displayIfNeeded message in our view
NSWindow *nsWindow = OBJC(windowPtr);
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
AWT_ASSERT_APPKIT_THREAD;
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
AWTWindow *window = (AWTWindow*)[nsWindow delegate];
@ -913,7 +903,6 @@ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowMi
(JNIEnv *env, jclass clazz, jlong windowPtr, jdouble minW, jdouble minH, jdouble maxW, jdouble maxH)
{
JNF_COCOA_ENTER(env);
AWT_ASSERT_NOT_APPKIT_THREAD;
if (minW < 1) minW = 1;
if (minH < 1) minH = 1;
@ -921,8 +910,7 @@ AWT_ASSERT_NOT_APPKIT_THREAD;
if (maxH < 1) maxH = 1;
NSWindow *nsWindow = OBJC(windowPtr);
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
AWT_ASSERT_APPKIT_THREAD;
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
AWTWindow *window = (AWTWindow*)[nsWindow delegate];
@ -949,12 +937,9 @@ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativePushNSWindowT
(JNIEnv *env, jclass clazz, jlong windowPtr)
{
JNF_COCOA_ENTER(env);
AWT_ASSERT_NOT_APPKIT_THREAD;
NSWindow *nsWindow = OBJC(windowPtr);
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
AWT_ASSERT_APPKIT_THREAD;
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
[nsWindow orderBack:nil];
}];
@ -970,11 +955,9 @@ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativePushNSWindowT
(JNIEnv *env, jclass clazz, jlong windowPtr)
{
JNF_COCOA_ENTER(env);
AWT_ASSERT_NOT_APPKIT_THREAD;
NSWindow *nsWindow = OBJC(windowPtr);
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
AWT_ASSERT_APPKIT_THREAD;
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
if (![nsWindow isKeyWindow]) {
[nsWindow makeKeyAndOrderFront:nsWindow];
@ -995,7 +978,6 @@ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowTi
(JNIEnv *env, jclass clazz, jlong windowPtr, jstring jtitle)
{
JNF_COCOA_ENTER(env);
AWT_ASSERT_NOT_APPKIT_THREAD;
NSWindow *nsWindow = OBJC(windowPtr);
[nsWindow performSelectorOnMainThread:@selector(setTitle:)
@ -1016,15 +998,9 @@ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeRevalidateNSW
JNF_COCOA_ENTER(env);
NSWindow *nsWindow = OBJC(windowPtr);
if ([NSThread isMainThread]) {
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
[nsWindow invalidateShadow];
} else {
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
AWT_ASSERT_APPKIT_THREAD;
[nsWindow invalidateShadow];
}];
}
}];
JNF_COCOA_EXIT(env);
}
@ -1060,13 +1036,10 @@ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowMi
(JNIEnv *env, jclass clazz, jlong windowPtr, jlong nsImagePtr)
{
JNF_COCOA_ENTER(env);
AWT_ASSERT_NOT_APPKIT_THREAD;
NSWindow *nsWindow = OBJC(windowPtr);
NSImage *image = OBJC(nsImagePtr);
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
AWT_ASSERT_APPKIT_THREAD;
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
[nsWindow setMiniwindowImage:image];
}];
@ -1082,35 +1055,16 @@ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowRe
(JNIEnv *env, jclass clazz, jlong windowPtr, jstring filename)
{
JNF_COCOA_ENTER(env);
AWT_ASSERT_NOT_APPKIT_THREAD;
NSWindow *nsWindow = OBJC(windowPtr);
NSURL *url = (filename == NULL) ? nil : [NSURL fileURLWithPath:JNFNormalizedNSStringForPath(env, filename)];
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
AWT_ASSERT_APPKIT_THREAD;
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
[nsWindow setRepresentedURL:url];
}];
JNF_COCOA_EXIT(env);
}
/*
* Class: sun_lwawt_macosx_CPlatformWindow
* Method: nativeSetNSWindowSecurityWarningPositioning
* Signature: (JDDFF)V
*/
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowSecurityWarningPositioning
(JNIEnv *env, jclass clazz, jlong windowPtr, jdouble x, jdouble y, jfloat biasX, jfloat biasY)
{
JNF_COCOA_ENTER(env);
AWT_ASSERT_NOT_APPKIT_THREAD;
[JNFException raise:env as:kRuntimeException reason:"unimplemented"];
JNF_COCOA_EXIT(env);
}
/*
* Class: sun_lwawt_macosx_CPlatformWindow
* Method: nativeGetTopmostPlatformWindowUnderMouse
@ -1144,10 +1098,8 @@ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSynthesizeMou
(JNIEnv *env, jclass clazz)
{
JNF_COCOA_ENTER(env);
AWT_ASSERT_NOT_APPKIT_THREAD;
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
AWT_ASSERT_APPKIT_THREAD;
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
[AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows];
}];
@ -1168,7 +1120,7 @@ JNF_COCOA_ENTER(env);
SEL toggleFullScreenSelector = @selector(toggleFullScreen:);
if (![nsWindow respondsToSelector:toggleFullScreenSelector]) return;
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
[nsWindow performSelector:toggleFullScreenSelector withObject:nil];
}];
@ -1181,7 +1133,7 @@ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetEnabled
JNF_COCOA_ENTER(env);
NSWindow *nsWindow = OBJC(windowPtr);
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
AWTWindow *window = (AWTWindow*)[nsWindow delegate];
[window setEnabled: isEnabled];
@ -1196,7 +1148,7 @@ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeDispose
JNF_COCOA_ENTER(env);
NSWindow *nsWindow = OBJC(windowPtr);
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
AWTWindow *window = (AWTWindow*)[nsWindow delegate];
if ([AWTWindow lastKeyWindow] == window) {

View File

@ -515,10 +515,9 @@ AWT_ASSERT_APPKIT_THREAD;
JNIEXPORT void JNICALL Java_com_apple_eawt_Application_nativeInitializeApplicationDelegate
(JNIEnv *env, jclass clz)
{
AWT_ASSERT_NOT_APPKIT_THREAD;
JNF_COCOA_ENTER(env);
// Force initialization to happen on AppKit thread!
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
[ApplicationDelegate sharedDelegate];
}];
JNF_COCOA_EXIT(env);
@ -532,10 +531,9 @@ JNF_COCOA_EXIT(env);
JNIEXPORT void JNICALL Java_com_apple_eawt__1AppEventHandler_nativeOpenCocoaAboutWindow
(JNIEnv *env, jclass clz)
{
AWT_ASSERT_NOT_APPKIT_THREAD;
JNF_COCOA_ENTER(env);
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
[NSApp orderFrontStandardAboutPanel:nil];
}];
@ -550,10 +548,9 @@ JNF_COCOA_EXIT(env);
JNIEXPORT void JNICALL Java_com_apple_eawt__1AppEventHandler_nativeReplyToAppShouldTerminate
(JNIEnv *env, jclass clz, jboolean doTerminate)
{
AWT_ASSERT_NOT_APPKIT_THREAD;
JNF_COCOA_ENTER(env);
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
[NSApp replyToApplicationShouldTerminate:doTerminate];
}];
@ -568,7 +565,6 @@ JNF_COCOA_EXIT(env);
JNIEXPORT void JNICALL Java_com_apple_eawt__1AppEventHandler_nativeRegisterForNotification
(JNIEnv *env, jclass clz, jint notificationType)
{
AWT_ASSERT_NOT_APPKIT_THREAD;
JNF_COCOA_ENTER(env);
[ThreadUtilities performOnMainThread:@selector(_registerForNotification:)
onObject:[ApplicationDelegate class]
@ -586,13 +582,10 @@ JNF_COCOA_EXIT(env);
JNIEXPORT void JNICALL Java_com_apple_eawt__1AppDockIconHandler_nativeSetDockMenu
(JNIEnv *env, jclass clz, jlong nsMenuPtr)
{
AWT_ASSERT_NOT_APPKIT_THREAD;
JNF_COCOA_ENTER(env);
NSMenu *menu = (NSMenu *)jlong_to_ptr(nsMenuPtr);
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
AWT_ASSERT_APPKIT_THREAD;
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
[ApplicationDelegate sharedDelegate].fDockMenu = menu;
}];
@ -607,14 +600,13 @@ JNF_COCOA_EXIT(env);
JNIEXPORT void JNICALL Java_com_apple_eawt__1AppDockIconHandler_nativeSetDockIconImage
(JNIEnv *env, jclass clz, jlong nsImagePtr)
{
AWT_ASSERT_NOT_APPKIT_THREAD;
JNF_COCOA_ENTER(env);
NSImage *_image = (NSImage *)jlong_to_ptr(nsImagePtr);
[JNFRunLoop performOnMainThread:@selector(_setDockIconImage:)
on:[ApplicationDelegate class]
withObject:_image
waitUntilDone:NO];
[ThreadUtilities performOnMainThread:@selector(_setDockIconImage:)
on:[ApplicationDelegate class]
withObject:_image
waitUntilDone:NO];
JNF_COCOA_EXIT(env);
}
@ -629,12 +621,9 @@ JNIEXPORT jlong JNICALL Java_com_apple_eawt__1AppDockIconHandler_nativeGetDockIc
{
__block NSImage *image = nil;
AWT_ASSERT_NOT_APPKIT_THREAD;
JNF_COCOA_ENTER(env);
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
AWT_ASSERT_APPKIT_THREAD;
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
image = [ApplicationDelegate _dockIconImage];
CFRetain(image);
}];
@ -652,13 +641,10 @@ JNF_COCOA_EXIT(env);
JNIEXPORT void JNICALL Java_com_apple_eawt__1AppDockIconHandler_nativeSetDockIconBadge
(JNIEnv *env, jclass clz, jstring badge)
{
AWT_ASSERT_NOT_APPKIT_THREAD;
JNF_COCOA_ENTER(env);
NSString *badgeString = JNFJavaToNSString(env, badge);
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
AWT_ASSERT_APPKIT_THREAD;
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
NSDockTile *dockTile = [NSApp dockTile];
[dockTile setBadgeLabel:badgeString];
[dockTile display];
@ -675,12 +661,9 @@ JNF_COCOA_EXIT(env);
JNIEXPORT void JNICALL Java_com_apple_eawt__1AppMiscHandlers_nativeRequestActivation
(JNIEnv *env, jclass clz, jboolean allWindows)
{
AWT_ASSERT_NOT_APPKIT_THREAD;
JNF_COCOA_ENTER(env);
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
AWT_ASSERT_APPKIT_THREAD;
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
NSApplicationActivationOptions options = allWindows ? NSApplicationActivateAllWindows : 0;
options |= NSApplicationActivateIgnoringOtherApps; // without this, nothing happens!
[[NSRunningApplication currentApplication] activateWithOptions:options];
@ -697,12 +680,9 @@ JNF_COCOA_EXIT(env);
JNIEXPORT void JNICALL Java_com_apple_eawt__1AppMiscHandlers_nativeRequestUserAttention
(JNIEnv *env, jclass clz, jboolean critical)
{
AWT_ASSERT_NOT_APPKIT_THREAD;
JNF_COCOA_ENTER(env);
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
AWT_ASSERT_APPKIT_THREAD;
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
[NSApp requestUserAttention:critical ? NSCriticalRequest : NSInformationalRequest];
}];
@ -717,13 +697,12 @@ JNF_COCOA_EXIT(env);
JNIEXPORT void JNICALL Java_com_apple_eawt__1AppMiscHandlers_nativeOpenHelpViewer
(JNIEnv *env, jclass clz)
{
AWT_ASSERT_NOT_APPKIT_THREAD;
JNF_COCOA_ENTER(env);
[JNFRunLoop performOnMainThread:@selector(showHelp:)
on:NSApp
withObject:nil
waitUntilDone:NO];
[ThreadUtilities performOnMainThread:@selector(showHelp:)
on:NSApp
withObject:nil
waitUntilDone:NO];
JNF_COCOA_EXIT(env);
}
@ -736,7 +715,6 @@ JNF_COCOA_EXIT(env);
JNIEXPORT void JNICALL Java_com_apple_eawt__1AppMiscHandlers_nativeEnableSuddenTermination
(JNIEnv *env, jclass clz)
{
AWT_ASSERT_NOT_APPKIT_THREAD;
JNF_COCOA_ENTER(env);
[[NSProcessInfo processInfo] enableSuddenTermination]; // Foundation thread-safe
@ -752,7 +730,6 @@ JNF_COCOA_EXIT(env);
JNIEXPORT void JNICALL Java_com_apple_eawt__1AppMiscHandlers_nativeDisableSuddenTermination
(JNIEnv *env, jclass clz)
{
AWT_ASSERT_NOT_APPKIT_THREAD;
JNF_COCOA_ENTER(env);
[[NSProcessInfo processInfo] disableSuddenTermination]; // Foundation thread-safe
@ -768,12 +745,9 @@ JNF_COCOA_EXIT(env);
JNIEXPORT void JNICALL Java_com_apple_eawt__1AppMenuBarHandler_nativeSetMenuState
(JNIEnv *env, jclass clz, jint menuID, jboolean visible, jboolean enabled)
{
AWT_ASSERT_NOT_APPKIT_THREAD;
JNF_COCOA_ENTER(env);
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
AWT_ASSERT_APPKIT_THREAD;
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
ApplicationDelegate *delegate = [ApplicationDelegate sharedDelegate];
switch (menuID) {
case com_apple_eawt__AppMenuBarHandler_MENU_ABOUT:
@ -796,12 +770,10 @@ JNF_COCOA_EXIT(env);
JNIEXPORT void JNICALL Java_com_apple_eawt__1AppMenuBarHandler_nativeSetDefaultMenuBar
(JNIEnv *env, jclass clz, jlong cMenuBarPtr)
{
AWT_ASSERT_NOT_APPKIT_THREAD;
JNF_COCOA_ENTER(env);
CMenuBar *menu = (CMenuBar *)jlong_to_ptr(cMenuBarPtr);
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
AWT_ASSERT_APPKIT_THREAD;
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
[ApplicationDelegate sharedDelegate].fDefaultMenuBar = menu;
}];

View File

@ -109,7 +109,6 @@ static CClipboard *sClipboard = nil;
}
- (void) javaDeclareTypes:(NSArray *)inTypes withOwner:(jobject)inClipboard jniEnv:(JNIEnv *)inEnv {
AWT_ASSERT_NOT_APPKIT_THREAD;
//NSLog(@"CClipboard javaDeclareTypes %@ withOwner", inTypes);
@ -134,7 +133,6 @@ static CClipboard *sClipboard = nil;
- (NSArray *) javaGetTypes {
AWT_ASSERT_NOT_APPKIT_THREAD;
NSMutableArray *args = [NSMutableArray arrayWithCapacity:1];
[ThreadUtilities performOnMainThread:@selector(_nativeGetTypes:) onObject:self withObject:args waitUntilDone:YES awtMode:YES];
@ -152,7 +150,6 @@ static CClipboard *sClipboard = nil;
}
- (void) javaSetData:(NSData *)inData forType:(NSString *) inFormat {
AWT_ASSERT_NOT_APPKIT_THREAD;
CClipboardUpdate *newUpdate = [[CClipboardUpdate alloc] initWithData:inData withFormat:inFormat];
[ThreadUtilities performOnMainThread:@selector(_nativeSetData:) onObject:self withObject:newUpdate waitUntilDone:YES awtMode:YES];
@ -171,7 +168,6 @@ static CClipboard *sClipboard = nil;
}
- (NSData *) javaGetDataForType:(NSString *) inFormat {
AWT_ASSERT_NOT_APPKIT_THREAD;
NSMutableArray *args = [NSMutableArray arrayWithObject:inFormat];
[ThreadUtilities performOnMainThread:@selector(_nativeGetDataForType:) onObject:self withObject:args waitUntilDone:YES awtMode:YES];

View File

@ -74,7 +74,6 @@ Java_sun_lwawt_macosx_CCursorManager_nativeSetBuiltInCursor
(JNIEnv *env, jclass class, jint type, jstring name)
{
JNF_COCOA_ENTER(env);
AWT_ASSERT_NOT_APPKIT_THREAD;
NSString *cursorName = JNFJavaToNSString(env, name);
SEL cursorSelector = (type == sun_lwawt_macosx_CCursorManager_NAMED_CURSOR) ? lookupCursorSelectorForName(cursorName) : lookupCursorSelectorForType(type);
@ -87,9 +86,7 @@ AWT_ASSERT_NOT_APPKIT_THREAD;
[JNFException raise:env as:kNoSuchMethodException reason:"missing NSCursor selector"];
}
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
AWT_ASSERT_APPKIT_THREAD;
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
setCursorOnAppKitThread([[NSCursor class] performSelector:cursorSelector]);
}];
@ -101,12 +98,9 @@ Java_sun_lwawt_macosx_CCursorManager_nativeSetCustomCursor
(JNIEnv *env, jclass class, jlong imgPtr, jdouble x, jdouble y)
{
JNF_COCOA_ENTER(env);
AWT_ASSERT_NOT_APPKIT_THREAD;
NSImage *image = (NSImage *)jlong_to_ptr(imgPtr);
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
AWT_ASSERT_APPKIT_THREAD;
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
NSCursor *cursor = [[NSCursor alloc] initWithImage:image
hotSpot:(NSPoint){ x, y }];
setCursorOnAppKitThread(cursor);
@ -127,8 +121,6 @@ JNF_COCOA_ENTER(env);
__block NSPoint pt = NSZeroPoint;
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
AWT_ASSERT_APPKIT_THREAD;
pt = ConvertNSScreenPoint(env, [NSEvent mouseLocation]);
}];
@ -144,13 +136,11 @@ JNIEXPORT void JNICALL
Java_sun_lwawt_macosx_CCursorManager_nativeSetAllowsCursorSetInBackground
(JNIEnv *env, jclass class, jboolean allows)
{
JNF_COCOA_ENTER(env);
AWT_ASSERT_NOT_APPKIT_THREAD;
SEL allowsSetInBackground_SEL = @selector(javaSetAllowsCursorSetInBackground:);
if ([[NSCursor class] respondsToSelector:allowsSetInBackground_SEL]) {
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
NSMethodSignature *allowsSetInBackground_sig =
[[NSCursor class] methodSignatureForSelector:allowsSetInBackground_SEL];
NSInvocation *invocation =

View File

@ -36,8 +36,6 @@
JNIEXPORT jint JNICALL Java_sun_lwawt_macosx_CDesktopPeer__1lsOpenURI
(JNIEnv *env, jclass clz, jstring uri)
{
// AWT_ASSERT_ANY_THREAD
OSStatus status = noErr;
JNF_COCOA_ENTER(env);
@ -63,8 +61,6 @@ JNF_COCOA_EXIT(env);
JNIEXPORT jint JNICALL Java_sun_lwawt_macosx_CDesktopPeer__1lsOpenFile
(JNIEnv *env, jclass clz, jstring jpath, jboolean print)
{
// AWT_ASSERT_ANY_THREAD
OSStatus status = noErr;
JNF_COCOA_ENTER(env);

View File

@ -46,7 +46,7 @@ JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CDragSourceContextPeer_createNativ
__block CDragSource* dragSource = nil;
JNF_COCOA_ENTER(env);
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
dragSource = [[CDragSource alloc] init:jthis component:jcomponent peer:jpeer control:controlObj
transferable:jtransferable triggerEvent:jtrigger dragPosX:jdragposx
dragPosY:jdragposy modifiers:jextmodifiers clickCount:jclickcount timeStamp:jtimestamp
@ -103,7 +103,7 @@ JNF_COCOA_EXIT(env);
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CDragSourceContextPeer_setNativeCursor
(JNIEnv *env, jobject jthis, jlong nativeDragSourceVal, jobject jcursor, jint jcursortype)
{
AWT_ASSERT_NOT_APPKIT_THREAD;
//AWT_ASSERT_NOT_APPKIT_THREAD;
//JNF_COCOA_ENTER(env);
// jobject gCursor = JNFNewGlobalRef(env, jcursor);

View File

@ -108,7 +108,6 @@ JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CImage_nativeCreateNSImageFromArra
jlong result = 0L;
JNF_COCOA_ENTER(env);
AWT_ASSERT_ANY_THREAD;
NSBitmapImageRep* imageRep = CImage_CreateImageRep(env, buffer, width, height);
if (imageRep) {
@ -139,7 +138,6 @@ JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CImage_nativeCreateNSImageFromArra
jlong result = 0L;
JNF_COCOA_ENTER(env);
AWT_ASSERT_ANY_THREAD;
jsize num = (*env)->GetArrayLength(env, buffers);
NSMutableArray * reps = [NSMutableArray arrayWithCapacity: num];
@ -187,7 +185,6 @@ JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CImage_nativeCreateNSImageFromIcon
NSImage *image = nil;
JNF_COCOA_ENTER(env);
AWT_ASSERT_ANY_THREAD;
IconRef iconRef;
if (noErr == GetIconRef(kOnSystemDisk, kSystemIconsCreator, selector, &iconRef)) {
@ -212,7 +209,6 @@ JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CImage_nativeCreateNSImageFromFile
NSImage *image = nil;
JNF_COCOA_ENTER(env);
AWT_ASSERT_ANY_THREAD;
NSString *path = JNFNormalizedNSStringForPath(env, file);
image = [[NSImage alloc] initByReferencingFile:path];
@ -234,10 +230,9 @@ JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CImage_nativeCreateNSImageOfFileFr
__block NSImage *image = nil;
JNF_COCOA_ENTER(env);
AWT_ASSERT_ANY_THREAD;
NSString *path = JNFNormalizedNSStringForPath(env, file);
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
image = [[NSWorkspace sharedWorkspace] iconForFile:path];
[image setScalesWhenResized:TRUE];
if (image) CFRetain(image); // GC
@ -259,7 +254,6 @@ JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CImage_nativeCreateNSImageFromImag
NSImage *image = nil;
JNF_COCOA_ENTER(env);
AWT_ASSERT_ANY_THREAD;
image = [NSImage imageNamed:JNFJavaToNSString(env, name)];
if (image) CFRetain(image); // GC
@ -278,7 +272,6 @@ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CImage_nativeCopyNSImageIntoArray
(JNIEnv *env, jclass klass, jlong nsImgPtr, jintArray buffer, jint w, jint h)
{
JNF_COCOA_ENTER(env);
AWT_ASSERT_ANY_THREAD;
NSImage *img = (NSImage *)jlong_to_ptr(nsImgPtr);
jint *dst = (*env)->GetPrimitiveArrayCritical(env, buffer, NULL);
@ -301,7 +294,6 @@ JNIEXPORT jobject JNICALL Java_sun_lwawt_macosx_CImage_nativeGetNSImageSize
jobject size = NULL;
JNF_COCOA_ENTER(env);
AWT_ASSERT_ANY_THREAD;
size = NSToJavaSize(env, [(NSImage *)jlong_to_ptr(nsImgPtr) size]);

View File

@ -153,7 +153,7 @@ JNIEXPORT jobject JNICALL Java_sun_lwawt_macosx_CInputMethod_nativeGetCurrentInp
__block NSString *keyboardInfo = NULL;
JNF_COCOA_ENTER(env);
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
keyboardInfo = [inputMethodController performSelector:@selector(currentInputMethodName)];
[keyboardInfo retain];
}];
@ -177,7 +177,7 @@ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CInputMethod_nativeNotifyPeer
JNF_COCOA_ENTER(env);
AWTView *view = (AWTView *)jlong_to_ptr(nativePeer);
JNFJObjectWrapper *inputMethodWrapper = [[JNFJObjectWrapper alloc] initWithJObject:inputMethod withEnv:env];
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
[CInputMethod _nativeNotifyPeerWithView:view inputMethod:inputMethodWrapper];
}];
@ -196,7 +196,7 @@ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CInputMethod_nativeEndComposition
JNF_COCOA_ENTER(env);
AWTView *view = (AWTView *)jlong_to_ptr(nativePeer);
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
[CInputMethod _nativeEndComposition:view];
}];
@ -216,7 +216,7 @@ JNIEXPORT jobject JNICALL Java_sun_lwawt_macosx_CInputMethod_getNativeLocale
__block NSString *isoAbbreviation;
JNF_COCOA_ENTER(env);
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
isoAbbreviation = (NSString *) [inputMethodController performSelector:@selector(currentInputMethodLocale)];
[isoAbbreviation retain];
}];
@ -259,7 +259,7 @@ JNF_COCOA_ENTER(env);
NSString *localeStr = JNFJavaToNSString(env, locale);
[localeStr retain];
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
[CInputMethod setKeyboardLayout:localeStr];
}];
@ -293,7 +293,7 @@ JNIEXPORT jobject JNICALL Java_sun_lwawt_macosx_CInputMethodDescriptor_nativeGet
__block NSArray *selectableArray = nil;
JNF_COCOA_ENTER(env);
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
selectableArray = (NSArray *)[inputMethodController performSelector:@selector(availableInputMethodLocales)];
[selectableArray retain];
}];

View File

@ -55,12 +55,10 @@ AWT_ASSERT_APPKIT_THREAD;
//- (void)finalize { [super finalize]; }
- (void)addJavaSubmenu:(CMenu *)submenu {
AWT_ASSERT_NOT_APPKIT_THREAD;
[ThreadUtilities performOnMainThread:@selector(addNativeItem_OnAppKitThread:) onObject:self withObject:submenu waitUntilDone:YES awtMode:YES];
}
- (void)addJavaMenuItem:(CMenuItem *)theMenuItem {
AWT_ASSERT_NOT_APPKIT_THREAD;
[ThreadUtilities performOnMainThread:@selector(addNativeItem_OnAppKitThread:) onObject:self withObject:theMenuItem waitUntilDone:YES awtMode:YES];
}
@ -70,7 +68,6 @@ AWT_ASSERT_APPKIT_THREAD;
}
- (void)setJavaMenuTitle:(NSString *)title {
AWT_ASSERT_NOT_APPKIT_THREAD;
if (title) {
[ThreadUtilities performOnMainThread:@selector(setNativeMenuTitle_OnAppKitThread:) onObject:self withObject:title waitUntilDone:YES awtMode:YES];
@ -95,7 +92,6 @@ AWT_ASSERT_APPKIT_THREAD;
}
- (void)deleteJavaItem:(jint)index {
AWT_ASSERT_NOT_APPKIT_THREAD;
[ThreadUtilities performOnMainThread:@selector(deleteNativeJavaItem_OnAppKitThread:) onObject:self withObject:[NSNumber numberWithInt:index] waitUntilDone:YES awtMode:YES];
}

View File

@ -80,10 +80,10 @@ Java_sun_lwawt_macosx_CMenuComponent_nativeDispose
{
JNF_COCOA_ENTER(env);
[JNFRunLoop performOnMainThread:@selector(disposer)
on:((id)jlong_to_ptr(menuItemObj))
withObject:nil
waitUntilDone:NO];
[ThreadUtilities performOnMainThread:@selector(disposer)
on:((id)jlong_to_ptr(menuItemObj))
withObject:nil
waitUntilDone:NO];
JNF_COCOA_EXIT(env);
}

View File

@ -104,7 +104,6 @@ JNF_COCOA_EXIT(env);
}
- (void) setJavaLabel:(NSString *)theLabel shortcut:(NSString *)theKeyEquivalent modifierMask:(jint)modifiers {
AWT_ASSERT_NOT_APPKIT_THREAD;
NSUInteger modifierMask = 0;
@ -126,8 +125,7 @@ AWT_ASSERT_NOT_APPKIT_THREAD;
modifierMask = JavaModifiersToNsKeyModifiers(modifiers, NO);
}
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
AWT_ASSERT_APPKIT_THREAD;
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
[fMenuItem setKeyEquivalent:theKeyEquivalent];
[fMenuItem setKeyEquivalentModifierMask:modifierMask];
[fMenuItem setTitle:theLabel];
@ -135,32 +133,23 @@ AWT_ASSERT_NOT_APPKIT_THREAD;
}
- (void) setJavaImage:(NSImage *)theImage {
AWT_ASSERT_NOT_APPKIT_THREAD;
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
AWT_ASSERT_APPKIT_THREAD;
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
[fMenuItem setImage:theImage];
}];
}
- (void) setJavaToolTipText:(NSString *)theText {
AWT_ASSERT_NOT_APPKIT_THREAD;
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
AWT_ASSERT_APPKIT_THREAD;
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
[fMenuItem setToolTip:theText];
}];
}
- (void)setJavaEnabled:(BOOL) enabled {
AWT_ASSERT_NOT_APPKIT_THREAD;
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
AWT_ASSERT_APPKIT_THREAD;
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
@synchronized(self) {
fIsEnabled = enabled;
@ -173,7 +162,6 @@ AWT_ASSERT_NOT_APPKIT_THREAD;
}
- (BOOL)isEnabled {
// AWT_ASSERT_ANY_THREAD;
BOOL enabled = NO;
@synchronized(self) {
@ -184,11 +172,8 @@ AWT_ASSERT_NOT_APPKIT_THREAD;
- (void)setJavaState:(BOOL)newState {
AWT_ASSERT_NOT_APPKIT_THREAD;
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
AWT_ASSERT_APPKIT_THREAD;
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
[fMenuItem setState:(newState ? NSOnState : NSOffState)];
}];
}

View File

@ -64,7 +64,7 @@ JNF_COCOA_ENTER(env);
jobject cPeerObjGlobal = JNFNewGlobalRef(env, peer);
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
aCPopupMenu = [[CPopupMenu alloc] initWithPeer:cPeerObjGlobal];
CFRetain(aCPopupMenu);
[aCPopupMenu release];
@ -82,7 +82,7 @@ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPopupMenu_nativeShowPopupMenu
CPopupMenu* cPopupMenu = (CPopupMenu*)jlong_to_ptr(menuPtr);
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
NSPoint loc = ConvertNSScreenPoint(env, NSMakePoint(x, y));
[[cPopupMenu menu] popUpMenuPositioningItem: nil

View File

@ -303,10 +303,9 @@ JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CTrayIcon_nativeCreate
__block AWTTrayIcon *trayIcon = nil;
JNF_COCOA_ENTER(env);
AWT_ASSERT_NOT_APPKIT_THREAD;
jobject thePeer = JNFNewGlobalRef(env, peer);
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
trayIcon = [[AWTTrayIcon alloc] initWithPeer:thePeer];
}];
@ -334,11 +333,10 @@ JNIEXPORT void JNICALL Java_java_awt_TrayIcon_initIDs
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CTrayIcon_nativeSetToolTip
(JNIEnv *env, jobject self, jlong model, jstring jtooltip) {
JNF_COCOA_ENTER(env);
AWT_ASSERT_NOT_APPKIT_THREAD;
AWTTrayIcon *icon = jlong_to_ptr(model);
NSString *tooltip = JNFJavaToNSString(env, jtooltip);
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
[icon setTooltip:tooltip];
}];
@ -353,10 +351,9 @@ JNF_COCOA_EXIT(env);
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CTrayIcon_setNativeImage
(JNIEnv *env, jobject self, jlong model, jlong imagePtr, jboolean autosize) {
JNF_COCOA_ENTER(env);
AWT_ASSERT_NOT_APPKIT_THREAD;
AWTTrayIcon *icon = jlong_to_ptr(model);
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
[icon setImage:jlong_to_ptr(imagePtr) sizing:autosize];
}];
@ -369,13 +366,10 @@ Java_sun_lwawt_macosx_CTrayIcon_nativeGetIconLocation
jobject jpt = NULL;
JNF_COCOA_ENTER(env);
AWT_ASSERT_NOT_APPKIT_THREAD;
__block NSPoint pt = NSZeroPoint;
AWTTrayIcon *icon = jlong_to_ptr(model);
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
AWT_ASSERT_APPKIT_THREAD;
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
NSPoint loc = [icon getLocationOnScreen];
pt = ConvertNSScreenPoint(env, loc);
}];

View File

@ -46,7 +46,7 @@ Java_sun_lwawt_macosx_CWrapper_00024NSObject_release
JNF_COCOA_ENTER(env);
id obj = (id)jlong_to_ptr(objectPtr);
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
CFRelease(obj);
}];
@ -66,10 +66,10 @@ Java_sun_lwawt_macosx_CWrapper_00024NSWindow_makeKeyAndOrderFront
JNF_COCOA_ENTER(env);
NSWindow *window = (NSWindow *)jlong_to_ptr(windowPtr);
[JNFRunLoop performOnMainThread:@selector(makeKeyAndOrderFront:)
on:window
withObject:nil
waitUntilDone:NO];
[ThreadUtilities performOnMainThread:@selector(makeKeyAndOrderFront:)
on:window
withObject:nil
waitUntilDone:NO];
JNF_COCOA_EXIT(env);
}
@ -86,10 +86,10 @@ Java_sun_lwawt_macosx_CWrapper_00024NSWindow_makeKeyWindow
JNF_COCOA_ENTER(env);
NSWindow *window = (NSWindow *)jlong_to_ptr(windowPtr);
[JNFRunLoop performOnMainThread:@selector(makeKeyWindow)
on:window
withObject:nil
waitUntilDone:NO];
[ThreadUtilities performOnMainThread:@selector(makeKeyWindow)
on:window
withObject:nil
waitUntilDone:NO];
JNF_COCOA_EXIT(env);
}
@ -106,10 +106,10 @@ Java_sun_lwawt_macosx_CWrapper_00024NSWindow_makeMainWindow
JNF_COCOA_ENTER(env);
NSWindow *window = (NSWindow *)jlong_to_ptr(windowPtr);
[JNFRunLoop performOnMainThread:@selector(makeMainWindow)
on:window
withObject:nil
waitUntilDone:NO];
[ThreadUtilities performOnMainThread:@selector(makeMainWindow)
on:window
withObject:nil
waitUntilDone:NO];
JNF_COCOA_EXIT(env);
}
@ -128,7 +128,7 @@ Java_sun_lwawt_macosx_CWrapper_00024NSWindow_canBecomeMainWindow
JNF_COCOA_ENTER(env);
NSWindow *window = (NSWindow *)jlong_to_ptr(windowPtr);
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
canBecomeMainWindow = [window canBecomeMainWindow];
}];
@ -151,7 +151,7 @@ Java_sun_lwawt_macosx_CWrapper_00024NSWindow_isKeyWindow
JNF_COCOA_ENTER(env);
NSWindow *window = (NSWindow *)jlong_to_ptr(windowPtr);
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
isKeyWindow = [window isKeyWindow];
}];
@ -172,10 +172,10 @@ Java_sun_lwawt_macosx_CWrapper_00024NSWindow_orderFront
JNF_COCOA_ENTER(env);
NSWindow *window = (NSWindow *)jlong_to_ptr(windowPtr);
[JNFRunLoop performOnMainThread:@selector(orderFront:)
on:window
withObject:window
waitUntilDone:NO];
[ThreadUtilities performOnMainThread:@selector(orderFront:)
on:window
withObject:window
waitUntilDone:NO];
JNF_COCOA_EXIT(env);
}
@ -192,10 +192,10 @@ Java_sun_lwawt_macosx_CWrapper_00024NSWindow_orderOut
JNF_COCOA_ENTER(env);
NSWindow *window = (NSWindow *)jlong_to_ptr(windowPtr);
[JNFRunLoop performOnMainThread:@selector(orderOut:)
on:window
withObject:window
waitUntilDone:NO];
[ThreadUtilities performOnMainThread:@selector(orderOut:)
on:window
withObject:window
waitUntilDone:NO];
JNF_COCOA_EXIT(env);
}
@ -212,10 +212,10 @@ Java_sun_lwawt_macosx_CWrapper_00024NSWindow_orderFrontRegardless
JNF_COCOA_ENTER(env);
NSWindow *window = (NSWindow *)jlong_to_ptr(windowPtr);
[JNFRunLoop performOnMainThread:@selector(orderFrontRegardless)
on:window
withObject:nil
waitUntilDone:NO];
[ThreadUtilities performOnMainThread:@selector(orderFrontRegardless)
on:window
withObject:nil
waitUntilDone:NO];
JNF_COCOA_EXIT(env);
}
@ -233,7 +233,7 @@ JNF_COCOA_ENTER(env);
NSWindow *window = (NSWindow *)jlong_to_ptr(windowPtr);
NSWindow *relativeTo = (NSWindow *)jlong_to_ptr(relativeToPtr);
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
[window orderWindow:(NSWindowOrderingMode)order relativeTo:[relativeTo windowNumber]];
}];
@ -267,7 +267,7 @@ JNF_COCOA_ENTER(env);
initLevels();
NSWindow *window = (NSWindow *)jlong_to_ptr(windowPtr);
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
[window setLevel: LEVELS[level]];
}];
} else {
@ -290,7 +290,7 @@ JNF_COCOA_ENTER(env);
NSWindow *parent = (NSWindow *)jlong_to_ptr(parentPtr);
NSWindow *child = (NSWindow *)jlong_to_ptr(childPtr);
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
[parent addChildWindow:child ordered:order];
}];
@ -310,10 +310,10 @@ JNF_COCOA_ENTER(env);
AWTWindow *parent = (AWTWindow *)jlong_to_ptr(parentPtr);
AWTWindow *child = (AWTWindow *)jlong_to_ptr(childPtr);
[JNFRunLoop performOnMainThread:@selector(removeChildWindow:)
on:parent
withObject:child
waitUntilDone:NO];
[ThreadUtilities performOnMainThread:@selector(removeChildWindow:)
on:parent
withObject:child
waitUntilDone:NO];
JNF_COCOA_EXIT(env);
}
@ -331,7 +331,7 @@ JNF_COCOA_ENTER(env);
AWTWindow *window = (AWTWindow *)jlong_to_ptr(windowPtr);
NSRect frame = NSMakeRect(x, y, w, h);
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
[window setFrame:frame display:display];
}];
@ -350,7 +350,7 @@ Java_sun_lwawt_macosx_CWrapper_00024NSWindow_setAlphaValue
JNF_COCOA_ENTER(env);
AWTWindow *window = (AWTWindow *)jlong_to_ptr(windowPtr);
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
[window setAlphaValue:(CGFloat)alpha];
}];
@ -369,7 +369,7 @@ Java_sun_lwawt_macosx_CWrapper_00024NSWindow_setOpaque
JNF_COCOA_ENTER(env);
AWTWindow *window = (AWTWindow *)jlong_to_ptr(windowPtr);
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
[window setOpaque:(BOOL)opaque];
}];
@ -389,7 +389,7 @@ JNF_COCOA_ENTER(env);
AWTWindow *window = (AWTWindow *)jlong_to_ptr(windowPtr);
NSColor *color = (NSColor *)jlong_to_ptr(colorPtr);
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
[window setBackgroundColor:color];
}];
@ -410,7 +410,7 @@ Java_sun_lwawt_macosx_CWrapper_00024NSWindow_screen
JNF_COCOA_ENTER(env);
AWTWindow *window = (AWTWindow *)jlong_to_ptr(windowPtr);
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
const NSScreen *screen = [window screen];
CFRetain(screen); // GC
screenPtr = ptr_to_jlong(screen);
@ -432,10 +432,10 @@ Java_sun_lwawt_macosx_CWrapper_00024NSWindow_miniaturize
JNF_COCOA_ENTER(env);
NSWindow *window = (NSWindow *)jlong_to_ptr(windowPtr);
[JNFRunLoop performOnMainThread:@selector(miniaturize:)
on:window
withObject:nil
waitUntilDone:NO];
[ThreadUtilities performOnMainThread:@selector(miniaturize:)
on:window
withObject:nil
waitUntilDone:NO];
JNF_COCOA_EXIT(env);
}
@ -452,10 +452,10 @@ Java_sun_lwawt_macosx_CWrapper_00024NSWindow_deminiaturize
JNF_COCOA_ENTER(env);
NSWindow *window = (NSWindow *)jlong_to_ptr(windowPtr);
[JNFRunLoop performOnMainThread:@selector(deminiaturize:)
on:window
withObject:nil
waitUntilDone:NO];
[ThreadUtilities performOnMainThread:@selector(deminiaturize:)
on:window
withObject:nil
waitUntilDone:NO];
JNF_COCOA_EXIT(env);
}
@ -472,10 +472,10 @@ Java_sun_lwawt_macosx_CWrapper_00024NSWindow_zoom
JNF_COCOA_ENTER(env);
NSWindow *window = (NSWindow *)jlong_to_ptr(windowPtr);
[JNFRunLoop performOnMainThread:@selector(zoom:)
on:window
withObject:nil
waitUntilDone:NO];
[ThreadUtilities performOnMainThread:@selector(zoom:)
on:window
withObject:nil
waitUntilDone:NO];
JNF_COCOA_EXIT(env);
}
@ -493,10 +493,10 @@ JNF_COCOA_ENTER(env);
NSWindow *window = (NSWindow *)jlong_to_ptr(windowPtr);
NSResponder *responder = (NSResponder *)jlong_to_ptr(responderPtr);
[JNFRunLoop performOnMainThread:@selector(makeFirstResponder:)
on:window
withObject:responder
waitUntilDone:NO];
[ThreadUtilities performOnMainThread:@selector(makeFirstResponder:)
on:window
withObject:responder
waitUntilDone:NO];
JNF_COCOA_EXIT(env);
}
@ -514,7 +514,7 @@ JNF_COCOA_ENTER(env);
NSView *view = (NSView *)jlong_to_ptr(viewPtr);
NSView *subview = (NSView *)jlong_to_ptr(subviewPtr);
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
[view addSubview:subview];
}];
@ -533,10 +533,10 @@ Java_sun_lwawt_macosx_CWrapper_00024NSView_removeFromSuperview
JNF_COCOA_ENTER(env);
NSView *view = (NSView *)jlong_to_ptr(viewPtr);
[JNFRunLoop performOnMainThread:@selector(removeFromSuperview)
on:view
withObject:nil
waitUntilDone:NO];
[ThreadUtilities performOnMainThread:@selector(removeFromSuperview)
on:view
withObject:nil
waitUntilDone:NO];
JNF_COCOA_EXIT(env);
}
@ -553,7 +553,7 @@ Java_sun_lwawt_macosx_CWrapper_00024NSView_setFrame
JNF_COCOA_ENTER(env);
NSView *view = (NSView *)jlong_to_ptr(viewPtr);
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
[view setFrame:NSMakeRect(x, y, w, h)];
}];
@ -576,7 +576,7 @@ JNF_COCOA_ENTER(env);
__block NSRect rect = NSZeroRect;
NSView *view = (NSView *)jlong_to_ptr(viewPtr);
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
rect = [view frame];
}];
@ -599,7 +599,7 @@ Java_sun_lwawt_macosx_CWrapper_00024NSView_enterFullScreenMode
JNF_COCOA_ENTER(env);
NSView *view = (NSView *)jlong_to_ptr(viewPtr);
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
NSScreen *screen = [[view window] screen];
NSDictionary *opts = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:NO], NSFullScreenModeAllScreens, nil];
[view enterFullScreenMode:screen withOptions:opts];
@ -620,7 +620,7 @@ Java_sun_lwawt_macosx_CWrapper_00024NSView_exitFullScreenMode
JNF_COCOA_ENTER(env);
NSView *view = (NSView *)jlong_to_ptr(viewPtr);
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
[view exitFullScreenModeWithOptions:nil];
}];
@ -641,7 +641,7 @@ Java_sun_lwawt_macosx_CWrapper_00024NSView_window
JNF_COCOA_ENTER(env);
NSView *view = (NSView *)jlong_to_ptr(viewPtr);
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
windowPtr = ptr_to_jlong([view window]);
}];
@ -655,14 +655,14 @@ JNF_COCOA_EXIT(env);
* Method: setHidden
* Signature: (JZ)V
*/
JNIEXPORT jlong JNICALL
JNIEXPORT void JNICALL
Java_sun_lwawt_macosx_CWrapper_00024NSView_setHidden
(JNIEnv *env, jclass cls, jlong viewPtr, jboolean toHide)
{
JNF_COCOA_ENTER(env);
NSView *view = (NSView *)jlong_to_ptr(viewPtr);
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
[view setHidden:(BOOL)toHide];
}];
@ -686,7 +686,7 @@ JNF_COCOA_ENTER(env);
__block NSRect rect = NSZeroRect;
NSScreen *screen = (NSScreen *)jlong_to_ptr(screenPtr);
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
rect = [screen frame];
}];
@ -713,7 +713,7 @@ JNF_COCOA_ENTER(env);
__block NSRect rect = NSZeroRect;
NSScreen *screen = (NSScreen *)jlong_to_ptr(screenPtr);
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
rect = [screen visibleFrame];
}];
@ -737,7 +737,7 @@ Java_sun_lwawt_macosx_CWrapper_00024NSScreen_screenByDisplayId
JNF_COCOA_ENTER(env);
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
NSArray *screens = [NSScreen screens];
for (NSScreen *screen in screens) {
NSDictionary *screenInfo = [screen deviceDescription];
@ -768,7 +768,7 @@ Java_sun_lwawt_macosx_CWrapper_00024NSColor_clearColor
JNF_COCOA_ENTER(env);
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
clearColorPtr = ptr_to_jlong([NSColor clearColor]);
}];

View File

@ -1147,7 +1147,6 @@ static NSObject *sAttributeNamesLOCK = nil;
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessibility_focusChanged
(JNIEnv *env, jobject jthis)
{
AWT_ASSERT_NOT_APPKIT_THREAD;
JNF_COCOA_ENTER(env);
[ThreadUtilities performOnMainThread:@selector(postFocusChanged:) onObject:[JavaComponentAccessibility class] withObject:nil waitUntilDone:NO awtMode:NO];
@ -1164,7 +1163,6 @@ JNF_COCOA_EXIT(env);
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_valueChanged
(JNIEnv *env, jclass jklass, jlong element)
{
AWT_ASSERT_NOT_APPKIT_THREAD;
JNF_COCOA_ENTER(env);
[ThreadUtilities performOnMainThread:@selector(postValueChanged) onObject:(JavaComponentAccessibility *)jlong_to_ptr(element) withObject:nil waitUntilDone:NO awtMode:NO];
JNF_COCOA_EXIT(env);
@ -1178,7 +1176,6 @@ JNF_COCOA_EXIT(env);
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_selectionChanged
(JNIEnv *env, jclass jklass, jlong element)
{
AWT_ASSERT_NOT_APPKIT_THREAD;
JNF_COCOA_ENTER(env);
[ThreadUtilities performOnMainThread:@selector(postSelectionChanged) onObject:(JavaComponentAccessibility *)jlong_to_ptr(element) withObject:nil waitUntilDone:NO awtMode:NO];
JNF_COCOA_EXIT(env);
@ -1193,7 +1190,6 @@ JNF_COCOA_EXIT(env);
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_unregisterFromCocoaAXSystem
(JNIEnv *env, jclass jklass, jlong element)
{
AWT_ASSERT_NOT_APPKIT_THREAD;
JNF_COCOA_ENTER(env);
[ThreadUtilities performOnMainThread:@selector(unregisterFromCocoaAXSystem) onObject:(JavaComponentAccessibility *)jlong_to_ptr(element) withObject:nil waitUntilDone:NO awtMode:NO];
JNF_COCOA_EXIT(env);

View File

@ -415,13 +415,9 @@ JNIEXPORT jboolean JNICALL Java_sun_lwawt_macosx_LWCToolkit_isApplicationActive
JNF_COCOA_ENTER(env);
if ([NSThread isMainThread]) {
[ThreadUtilities performOnMainThreadWaiting:YES block:^() {
active = (jboolean)[NSRunningApplication currentApplication].active;
} else {
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^() {
active = (jboolean)[NSRunningApplication currentApplication].active;
}];
}
}];
JNF_COCOA_EXIT(env);

View File

@ -42,6 +42,15 @@
// The symbol is defined in libosxapp.dylib (ThreadUtilities.m)
extern JavaVM *jvm;
// Indicates if AWT is running embedded (in SWT, FX, elsewhere)
static BOOL isEmbedded = NO;
// Indicates that the app has been started with -XstartOnFirstThread
// (directly or via WebStart settings), and AWT should not run its
// own event loop in this mode. Even if a loop isn't running yet,
// we expect an embedder (e.g. SWT) to start it some time later.
static BOOL forceEmbeddedMode = NO;
static bool ShouldPrintVerboseDebugging() {
static int debug = -1;
if (debug == -1) {
@ -63,31 +72,29 @@ static void AWT_NSUncaughtExceptionHandler(NSException *exception);
static CFRunLoopObserverRef busyObserver = NULL;
static CFRunLoopObserverRef notBusyObserver = NULL;
static void setUpAWTAppKit(BOOL swt_mode, BOOL headless) {
AWT_ASSERT_APPKIT_THREAD;
static void setUpAWTAppKit()
{
BOOL verbose = ShouldPrintVerboseDebugging();
if (verbose) AWT_DEBUG_LOG(@"setting up busy observers");
JNIEnv *env = [ThreadUtilities getJNIEnv];
// Add CFRunLoopObservers to call into AWT so that AWT knows that the
// AWT thread (which is the AppKit main thread) is alive. This way AWT
// will not automatically shutdown.
busyObserver = CFRunLoopObserverCreate(
NULL, // CFAllocator
kCFRunLoopAfterWaiting, // CFOptionFlags
true, // repeats
NSIntegerMax, // order
&BusyObserver, // CFRunLoopObserverCallBack
NULL); // CFRunLoopObserverContext
NULL, // CFAllocator
kCFRunLoopAfterWaiting, // CFOptionFlags
true, // repeats
NSIntegerMax, // order
&BusyObserver, // CFRunLoopObserverCallBack
NULL); // CFRunLoopObserverContext
notBusyObserver = CFRunLoopObserverCreate(
NULL, // CFAllocator
kCFRunLoopBeforeWaiting, // CFOptionFlags
true, // repeats
NSIntegerMin, // order
&NotBusyObserver, // CFRunLoopObserverCallBack
NULL); // CFRunLoopObserverContext
NULL, // CFAllocator
kCFRunLoopBeforeWaiting, // CFOptionFlags
true, // repeats
NSIntegerMin, // order
&NotBusyObserver, // CFRunLoopObserverCallBack
NULL); // CFRunLoopObserverContext
CFRunLoopRef runLoop = [[NSRunLoop currentRunLoop] getCFRunLoop];
CFRunLoopAddObserver(runLoop, busyObserver, kCFRunLoopDefaultMode);
@ -95,29 +102,33 @@ AWT_ASSERT_APPKIT_THREAD;
CFRelease(busyObserver);
CFRelease(notBusyObserver);
if (!headless) setBusy(YES);
setBusy(YES);
}
static void setUpAppKitThreadName()
{
BOOL verbose = ShouldPrintVerboseDebugging();
JNIEnv *env = [ThreadUtilities getJNIEnv];
// Set the java name of the AppKit main thread appropriately.
jclass threadClass = NULL;
jstring name = NULL;
jobject curThread = NULL;
if (!swt_mode) {
threadClass = (*env)->FindClass(env, "java/lang/Thread");
if (threadClass == NULL || (*env)->ExceptionCheck(env)) goto cleanup;
jmethodID currentThreadID = (*env)->GetStaticMethodID(env, threadClass, "currentThread", "()Ljava/lang/Thread;");
if (currentThreadID == NULL || (*env)->ExceptionCheck(env)) goto cleanup;
jmethodID setName = (*env)->GetMethodID(env, threadClass, "setName", "(Ljava/lang/String;)V");
if (setName == NULL || (*env)->ExceptionCheck(env)) goto cleanup;
threadClass = (*env)->FindClass(env, "java/lang/Thread");
if (threadClass == NULL || (*env)->ExceptionCheck(env)) goto cleanup;
jmethodID currentThreadID = (*env)->GetStaticMethodID(env, threadClass, "currentThread", "()Ljava/lang/Thread;");
if (currentThreadID == NULL || (*env)->ExceptionCheck(env)) goto cleanup;
jmethodID setName = (*env)->GetMethodID(env, threadClass, "setName", "(Ljava/lang/String;)V");
if (setName == NULL || (*env)->ExceptionCheck(env)) goto cleanup;
curThread = (*env)->CallStaticObjectMethod(env, threadClass, currentThreadID); // AWT_THREADING Safe (known object)
if (curThread == NULL || (*env)->ExceptionCheck(env)) goto cleanup;
name = (*env)->NewStringUTF(env, "AWT-AppKit");
if (name == NULL || (*env)->ExceptionCheck(env)) goto cleanup;
(*env)->CallVoidMethod(env, curThread, setName, name); // AWT_THREADING Safe (known object)
if ((*env)->ExceptionCheck(env)) goto cleanup;
}
curThread = (*env)->CallStaticObjectMethod(env, threadClass, currentThreadID); // AWT_THREADING Safe (known object)
if (curThread == NULL || (*env)->ExceptionCheck(env)) goto cleanup;
name = (*env)->NewStringUTF(env, "AWT-AppKit");
if (name == NULL || (*env)->ExceptionCheck(env)) goto cleanup;
(*env)->CallVoidMethod(env, curThread, setName, name); // AWT_THREADING Safe (known object)
if ((*env)->ExceptionCheck(env)) goto cleanup;
cleanup:
if (threadClass != NULL) {
@ -134,14 +145,10 @@ cleanup:
(*env)->ExceptionClear(env);
}
// Add the exception handler of last resort
NSSetUncaughtExceptionHandler(AWT_NSUncaughtExceptionHandler);
if (verbose) AWT_DEBUG_LOG(@"finished setting thread name");
}
// Returns true if java believes it is running headless
BOOL isHeadless(JNIEnv *env) {
// Just access the property directly, instead of using GraphicsEnvironment.isHeadless.
@ -200,7 +207,7 @@ static void AWT_NSUncaughtExceptionHandler(NSException *exception) {
// This is an empty Obj-C object just so that -peformSelectorOnMainThread can be used.
@interface AWTStarter : NSObject { }
+ (void)start:(BOOL)headless swtMode:(BOOL)swtMode swtModeForWebStart:(BOOL)swtModeForWebStart;
+ (void)start:(BOOL)headless;
- (void)starter:(NSArray*)args;
+ (void)appKitIsRunning:(id)arg;
@end
@ -242,7 +249,7 @@ AWT_ASSERT_APPKIT_THREAD;
if (verbose) AWT_DEBUG_LOG(@"finished messaging AppKit started");
}
+ (void)start:(BOOL)headless swtMode:(BOOL)swtMode swtModeForWebStart:(BOOL)swtModeForWebStart
+ (void)start:(BOOL)headless
{
BOOL verbose = ShouldPrintVerboseDebugging();
@ -258,7 +265,7 @@ AWT_ASSERT_APPKIT_THREAD;
BOOL onMainThread = (pthread_main_np() != 0);
if (verbose) {
NSString *msg = [NSString stringWithFormat:@"+[AWTStarter start headless:%d swtMode:%d swtModeForWebStart:%d] { onMainThread:%d }", headless, swtMode, swtModeForWebStart, onMainThread];
NSString *msg = [NSString stringWithFormat:@"+[AWTStarter start headless:%d] { onMainThread:%d }", headless, onMainThread];
AWT_DEBUG_LOG(msg);
}
@ -280,9 +287,7 @@ AWT_ASSERT_APPKIT_THREAD;
NSArray * args = [NSArray arrayWithObjects:
[NSNumber numberWithBool: onMainThread],
[NSNumber numberWithBool: swtMode],
[NSNumber numberWithBool: headless],
[NSNumber numberWithBool: swtModeForWebStart],
[NSNumber numberWithBool: verbose],
nil];
@ -310,39 +315,38 @@ AWT_ASSERT_APPKIT_THREAD;
// Don't set the delegate until the NSApplication has been created and
// its finishLaunching has initialized it.
// ApplicationDelegate is the support code for com.apple.eawt.
void (^setDelegateBlock)() = ^(){
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
OSXAPP_SetApplicationDelegate([ApplicationDelegate sharedDelegate]);
};
if (onMainThread) {
setDelegateBlock();
} else {
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:setDelegateBlock];
}
}];
}
- (void)starter:(NSArray*)args {
NSAutoreleasePool *pool = [NSAutoreleasePool new];
BOOL onMainThread = [[args objectAtIndex:0] boolValue];
BOOL swtMode = [[args objectAtIndex:1] boolValue];
BOOL headless = [[args objectAtIndex:2] boolValue];
BOOL swtModeForWebStart = [[args objectAtIndex:3] boolValue];
BOOL verbose = [[args objectAtIndex:4] boolValue];
BOOL headless = [[args objectAtIndex:1] boolValue];
BOOL verbose = [[args objectAtIndex:2] boolValue];
BOOL wasOnMainThread = onMainThread;
setUpAWTAppKit(swtMode, headless);
// Add the exception handler of last resort
NSSetUncaughtExceptionHandler(AWT_NSUncaughtExceptionHandler);
// Headless mode trumps either ordinary AWT or SWT-in-AWT mode. Declare us a daemon and return.
if (headless) {
BOOL didBecomeDaemon = [AWTStarter markAppAsDaemon];
if (!forceEmbeddedMode) {
setUpAppKitThreadName();
}
[AWTStarter markAppAsDaemon];
return;
}
if (swtMode || swtModeForWebStart) {
if (forceEmbeddedMode) {
if (verbose) NSLog(@"in SWT or SWT/WebStart mode");
// The SWT should call NSApplicationLoad, but they don't know a priori that they will be using the AWT, so they don't.
// Init a default NSApplication instance instead of the NSApplicationAWT.
// Note that [NSApp isRunning] will return YES after that, though
// this behavior isn't specified anywhere. We rely on that.
NSApplicationLoad();
}
@ -351,6 +355,13 @@ AWT_ASSERT_APPKIT_THREAD;
// and -[NSApplication isRunning] returns YES, AWT is embedded inside another
// AppKit Application.
NSApplication *app = [NSApplicationAWT sharedApplication];
isEmbedded = ![NSApp isKindOfClass:[NSApplicationAWT class]];
if (!isEmbedded) {
// Install run loop observers and set the AppKit Java thread name
setUpAWTAppKit();
setUpAppKitThreadName();
}
// AWT gets to this point BEFORE NSApplicationDidFinishLaunchingNotification is sent.
if (![app isRunning]) {
@ -360,17 +371,11 @@ AWT_ASSERT_APPKIT_THREAD;
[NSApplicationAWT runAWTLoopWithApp: app];
} else {
// We're either embedded, or showing a splash screen
if (![NSApp isKindOfClass:[NSApplicationAWT class]]) {
if (isEmbedded) {
if (verbose) AWT_DEBUG_LOG(@"running embedded");
// Since we're embedded, no need to be swamping the runloop with the observers.
CFRunLoopRef runLoop = [[NSRunLoop currentRunLoop] getCFRunLoop];
CFRunLoopRemoveObserver(runLoop, busyObserver, kCFRunLoopDefaultMode);
CFRunLoopRemoveObserver(runLoop, notBusyObserver, kCFRunLoopDefaultMode);
// We don't track if the runloop is busy, so set it free to let AWT finish when it needs
setBusy(NO);
busyObserver = NULL;
notBusyObserver = NULL;
} else {
if (verbose) AWT_DEBUG_LOG(@"running after showing a splash screen");
}
@ -408,49 +413,28 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
return JNI_VERSION_1_4;
}
// The following is true when AWT is attempting to connect to the window server
// when it isn't set up properly to do so.
// BOOL AWTLoadFailure = YES; For now we are skipping this check so i'm commenting out this variable as unused
JNF_COCOA_ENTER(env);
// If -XstartOnFirstThread was used at invocation time, an environment variable will be set.
// (See java_md.c for the matching setenv call.) When that happens, we assume the SWT will be in use.
BOOL swt_compatible_mode = NO;
// Launcher sets this env variable if -XstartOnFirstThread is specified
char envVar[80];
snprintf(envVar, sizeof(envVar), "JAVA_STARTED_ON_FIRST_THREAD_%d", getpid());
if (getenv(envVar) != NULL) {
swt_compatible_mode = YES;
forceEmbeddedMode = YES;
unsetenv(envVar);
}
BOOL swt_in_webstart = isSWTInWebStart(env);
BOOL headless = isHeadless(env);
// Make sure we're on the right thread. If not, we still need the JNIEnv to throw an exception.
if (pthread_main_np() != 0 && !swt_compatible_mode && !headless) {
AWT_DEBUG_LOG(@"Apple AWT Java VM was loaded on first thread -- can't start AWT.");
[JNFException raise:env as:kInternalError reason:"Can't start the AWT because Java was started on the first thread. Make sure StartOnFirstThread is "
"not specified in your application's Info.plist or on the command line"];
return JNI_VERSION_1_4;
if (isSWTInWebStart(env)) {
forceEmbeddedMode = YES;
}
BOOL headless = isHeadless(env);
// We need to let Foundation know that this is a multithreaded application, if it isn't already.
if (![NSThread isMultiThreaded]) {
[NSThread detachNewThreadSelector:nil toTarget:nil withObject:nil];
}
// if (swt_compatible_mode || headless || [AWTStarter isConnectedToWindowServer] || [AWTStarter isRemoteSession]) {
// No need in this check - we will try to launch AWTStarter anyways - to be able to run GUI application remotely
// AWTLoadFailure = NO;
[AWTStarter start:headless swtMode:swt_compatible_mode swtModeForWebStart:swt_in_webstart];
// }
/* if (AWTLoadFailure) { // We will not reach this code anyways
[JNFException raise:env as:kInternalError reason:"Can't connect to window server - not enough permissions."];
} */
[AWTStarter start:headless];
JNF_COCOA_EXIT(env);

View File

@ -98,8 +98,6 @@ do { \
} \
} while (0)
#define AWT_ASSERT_ANY_THREAD
#endif /* AWT_THREAD_ASSERTS_MESSAGES */
#ifdef AWT_THREAD_ASSERTS_WAIT
@ -114,15 +112,12 @@ do { \
while (pthread_main_np() != 0) {} \
} while (0)
#define AWT_ASSERT_ANY_THREAD
#endif /* AWT_THREAD_ASSERTS_WAIT */
#else /* AWT_THREAD_ASSERTS */
#define AWT_ASSERT_APPKIT_THREAD do {} while (0)
#define AWT_ASSERT_NOT_APPKIT_THREAD do {} while (0)
#define AWT_ASSERT_ANY_THREAD
#endif /* AWT_THREAD_ASSERTS */
// --------------------------------------------------------------------------
@ -139,7 +134,10 @@ __attribute__((visibility("default")))
+ (JNIEnv*)getJNIEnvUncached;
+ (void)performOnMainThread:(SEL)aSelector onObject:(id)target withObject:(id)arg waitUntilDone:(BOOL)wait awtMode:(BOOL)inAWT;
//Wrappers for the corresponding JNFRunLoop methods with a check for main thread
+ (void)performOnMainThreadWaiting:(BOOL)wait block:(void (^)())block;
+ (void)performOnMainThread:(SEL)aSelector on:(id)target withObject:(id)arg waitUntilDone:(BOOL)wait;
@end
void OSXAPP_SetJavaVM(JavaVM *vm);

View File

@ -37,27 +37,13 @@ static JNIEnv *appKitEnv = NULL;
static NSArray *sPerformModes = nil;
static NSArray *sAWTPerformModes = nil;
static BOOL sCocoaComponentCompatibility = NO;
static NSTimeInterval sCocoaComponentCompatibilityTimeout = 0.5;
static BOOL sLoggingEnabled = YES;
#ifdef AWT_THREAD_ASSERTS_ENV_ASSERT
int sAWTThreadAsserts = 0;
#endif /* AWT_THREAD_ASSERTS_ENV_ASSERT */
// This is for backward compatibility for those people using CocoaComponent
// Since we've flipped the AWT threading model for Tiger (10.4), all the rules
// for CocoaComponent are wrong.
// So for existing CocoaComponent users, we can't be synchronous.
// Making things totally asynchronous breaks a _lot_, so we try to be
// synchronous and time out after a little bit.
#define NOT_READY 0
#define READY 1
#define IN_PROGRESS 2
BOOL sInPerformFromJava = NO;
NSUInteger sPerformCount = 0;
// This class is used so that performSelectorOnMainThread can be
// controlled a little more easily by us. It has 2 roles.
@ -73,8 +59,6 @@ NSUInteger sPerformCount = 0;
- (id) initWithTarget:(id)target selector:(SEL)selector arg:(id)arg wait:(BOOL)wait;
- (void) perform;
- (void) performCompatible;
- (void) _performCompatible:(NSConditionLock *)resultLock;
@end
@ -113,8 +97,6 @@ NSUInteger sPerformCount = 0;
sInPerformFromJava = YES;
}
sPerformCount++;
// Actually do the work (cheat to avoid a method call)
@try {
objc_msgSend(fTarget, fSelector, fArg);
@ -128,69 +110,6 @@ NSUInteger sPerformCount = 0;
}
}
}
- (void) performCompatible {
// We check if we are on the AppKit thread because frequently, apps
// using CocoaComponent are doing things on the wrong thread!
if (pthread_main_np()) {
[fTarget performSelector:fSelector withObject:fArg];
} else {
// Setup the lock
NSConditionLock *resultLock =
[[NSConditionLock alloc] initWithCondition:NOT_READY];
// Make sure that if we return early, nothing gets released out
// from under us
[resultLock retain];
[fTarget retain];
[fArg retain];
[self retain];
// Do an asynchronous perform to the main thread.
[self performSelectorOnMainThread:@selector(_performCompatible:)
withObject:resultLock waitUntilDone:NO modes:sAWTPerformModes];
// Wait for a little bit for it to finish
[resultLock lockWhenCondition:READY beforeDate:[NSDate dateWithTimeIntervalSinceNow:sCocoaComponentCompatibilityTimeout]];
// If the _performCompatible is actually in progress,
// we should let it finish
if ([resultLock condition] == IN_PROGRESS) {
[resultLock lockWhenCondition:READY];
}
if ([resultLock condition] == NOT_READY && sLoggingEnabled) {
NSLog(@"[Java CocoaComponent compatibility mode]: Operation timed out due to possible deadlock: selector '%@' on target '%@' with args '%@'", NSStringFromSelector(fSelector), fTarget, fArg);
}
[resultLock unlock];
[resultLock autorelease];
}
}
- (void) _performCompatible:(NSConditionLock *)resultLock {
// notify that the perform is in progress!
[resultLock lock];
[resultLock unlockWithCondition:IN_PROGRESS];
sPerformCount++;
// Actually do the work.
@try {
[fTarget performSelector:fSelector withObject:fArg];
} @catch (NSException *e) {
NSLog(@"*** CPerformer: ignoring exception '%@' raised during performCompatible of selector '%@' on target '%@' with args '%@'", e, NSStringFromSelector(fSelector), fTarget, fArg);
} @finally {
// notify done!
[resultLock lock];
[resultLock unlockWithCondition:READY];
// Clean up after ourselves
[resultLock autorelease];
[fTarget autorelease];
[fArg autorelease];
[self autorelease];
}
}
@end
@ -236,13 +155,8 @@ AWT_ASSERT_APPKIT_THREAD;
// java event thread without deadlocking. See CToolkit.invokeAndWait.
+ (void)performOnMainThread:(SEL)aSelector onObject:(id)target withObject:(id)arg waitUntilDone:(BOOL)wait awtMode:(BOOL)inAWT {
CPerformer *performer = [[CPerformer alloc] initWithTarget:target selector:aSelector arg:arg wait:wait];
if (sCocoaComponentCompatibility && wait && inAWT) {
[performer performCompatible];
[performer autorelease];
} else {
[performer performSelectorOnMainThread:@selector(perform) withObject:nil waitUntilDone:wait modes:((inAWT) ? sAWTPerformModes : sPerformModes)]; // AWT_THREADING Safe (cover method)
[performer release];
}
[performer performSelectorOnMainThread:@selector(perform) withObject:nil waitUntilDone:wait modes:((inAWT) ? sAWTPerformModes : sPerformModes)]; // AWT_THREADING Safe (cover method)
[performer release];
}
+ (void)performOnMainThreadWaiting:(BOOL)wait block:(void (^)())block {
@ -253,6 +167,14 @@ AWT_ASSERT_APPKIT_THREAD;
}
}
+ (void)performOnMainThread:(SEL)aSelector on:(id)target withObject:(id)arg waitUntilDone:(BOOL)wait {
if ([NSThread isMainThread] && wait == YES) {
[target performSelector:aSelector withObject:arg];
} else {
[JNFRunLoop performOnMainThread:aSelector on:target withObject:arg waitUntilDone:wait];
}
}
@end

View File

@ -787,7 +787,6 @@ public class GTKLookAndFeel extends SynthLookAndFeel {
"List.font", new FontLazyValue(Region.LIST),
"List.rendererUseUIBorder", Boolean.FALSE,
"Menu.shortcutKeys", new int[] {KeyEvent.ALT_MASK},
"Menu.arrowIcon", new GTKStyle.GTKLazyValue(
"com.sun.java.swing.plaf.gtk.GTKIconFactory",
"getMenuArrowIcon"),

View File

@ -630,8 +630,10 @@ public class MotifLookAndFeel extends BasicLookAndFeel
"Menu.menuPopupOffsetY", new Integer(0),
"Menu.submenuPopupOffsetX", new Integer(-2),
"Menu.submenuPopupOffsetY", new Integer(3),
"Menu.shortcutKeys", new int[] {KeyEvent.ALT_MASK,
KeyEvent.META_MASK},
"Menu.shortcutKeys", new int[]{
SwingUtilities2.getSystemMnemonicKeyMask(),
KeyEvent.META_MASK
},
"Menu.cancelMode", "hideMenuTree",
"MenuBar.border", menuBarBorder,

View File

@ -2619,13 +2619,15 @@ public class WindowsLookAndFeel extends BasicLookAndFeel
private static class FocusColorProperty extends DesktopProperty {
public FocusColorProperty () {
// Fallback value is never used bacause of the configureValue method doesn't return null
// Fallback value is never used because of the configureValue method doesn't return null
super("win.3d.backgroundColor", Color.BLACK);
}
@Override
protected Object configureValue(Object value) {
if (! ((Boolean)Toolkit.getDefaultToolkit().getDesktopProperty("win.highContrast.on")).booleanValue()){
Object highContrastOn = Toolkit.getDefaultToolkit().
getDesktopProperty("win.highContrast.on");
if (highContrastOn == null || !((Boolean) highContrastOn).booleanValue()) {
return Color.BLACK;
}
return Color.BLACK.equals(value) ? Color.WHITE : Color.BLACK;

View File

@ -93,6 +93,11 @@ public class WindowsTreeUI extends BasicTreeUI {
counter = endRow;
}
}
if (testRect == null) {
return;
}
tree.scrollRectToVisible(new Rectangle(visRect.x, beginY, 1,
testRect.y + testRect.height-
beginY));

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -177,6 +177,7 @@ class Attribute implements Comparable<Attribute> {
define(sd, ATTR_CONTEXT_METHOD, "Synthetic", "");
define(sd, ATTR_CONTEXT_METHOD, "Deprecated", "");
define(sd, ATTR_CONTEXT_METHOD, "Exceptions", "NH[RCH]");
define(sd, ATTR_CONTEXT_METHOD, "MethodParameters", "NB[RUNHI]");
//define(sd, ATTR_CONTEXT_METHOD, "Code", "HHNI[B]NH[PHPOHPOHRCNH]NH[RUHNI[B]]");
define(sd, ATTR_CONTEXT_CODE, "StackMapTable",

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -1502,6 +1502,10 @@ class BandStructure {
CPRefBand method_Exceptions_RC = method_attr_bands.newCPRefBand("method_Exceptions_RC", CONSTANT_Class);
CPRefBand method_Signature_RS = method_attr_bands.newCPRefBand("method_Signature_RS", CONSTANT_Signature);
MultiBand method_metadata_bands = method_attr_bands.newMultiBand("(method_metadata_bands)", UNSIGNED5);
// band for predefine method parameters
IntBand method_MethodParameters_NB = method_attr_bands.newIntBand("method_MethodParameters_NB", BYTE1);
CPRefBand method_MethodParameters_name_RUN = method_attr_bands.newCPRefBand("method_MethodParameters_name_RUN", UNSIGNED5, CONSTANT_Utf8, NULL_IS_OK);
IntBand method_MethodParameters_flag_I = method_attr_bands.newIntBand("method_MethodParameters_flag_I");
MultiBand class_attr_bands = class_bands.newMultiBand("(class_attr_bands)", UNSIGNED5);
IntBand class_flags_hi = class_attr_bands.newIntBand("class_flags_hi");
@ -1768,6 +1772,13 @@ class BandStructure {
method_Exceptions_RC
},
"Exceptions", "NH[RCH]");
predefineAttribute(METHOD_ATTR_MethodParameters, ATTR_CONTEXT_METHOD,
new Band[]{
method_MethodParameters_NB,
method_MethodParameters_name_RUN,
method_MethodParameters_flag_I
},
"MethodParameters", "NB[RUNHI]");
assert(attrCodeEmpty == Package.attrCodeEmpty);
predefineAttribute(X_ATTR_Signature, ATTR_CONTEXT_METHOD,
new Band[] { method_Signature_RS },

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -73,6 +73,9 @@ class Constants {
public final static Package.Version JAVA7_PACKAGE_VERSION =
Package.Version.of(170, 1);
public final static Package.Version JAVA8_PACKAGE_VERSION =
Package.Version.of(171, 0);
// upper limit, should point to the latest class version
public final static Package.Version JAVA_MAX_CLASS_VERSION =
JAVA8_MAX_CLASS_VERSION;
@ -158,6 +161,7 @@ class Constants {
METHOD_ATTR_RuntimeInvisibleParameterAnnotations = 24,
CLASS_ATTR_ClassFile_version = 24,
METHOD_ATTR_AnnotationDefault = 25,
METHOD_ATTR_MethodParameters = 26,
CODE_ATTR_StackMapTable = 0, // new in Java 6
CODE_ATTR_LineNumberTable = 1,
CODE_ATTR_LocalVariableTable = 2,

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -242,6 +242,7 @@ class PackageReader extends BandStructure {
void checkArchiveVersion() throws IOException {
Package.Version versionFound = null;
for (Package.Version v : new Package.Version[] {
JAVA8_PACKAGE_VERSION,
JAVA7_PACKAGE_VERSION,
JAVA6_PACKAGE_VERSION,
JAVA5_PACKAGE_VERSION
@ -252,7 +253,9 @@ class PackageReader extends BandStructure {
}
}
if (versionFound == null) {
String expVer = JAVA7_PACKAGE_VERSION.toString()
String expVer = JAVA8_PACKAGE_VERSION.toString()
+ "OR"
+ JAVA7_PACKAGE_VERSION.toString()
+ " OR "
+ JAVA6_PACKAGE_VERSION.toString()
+ " OR "
@ -1516,6 +1519,9 @@ class PackageReader extends BandStructure {
// method_metadata_bands
// *method_Exceptions_N :UNSIGNED5
// *method_Exceptions_RC :UNSIGNED5 (cp_Class)
// *method_MethodParameters_NB: BYTE1
// *method_MethodParameters_RUN: UNSIGNED5 (cp_Utf8)
// *method_MethodParameters_I: UNSIGNED5 (flag)
//
// code_attr_bands:
// *code_flags :UNSIGNED5

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -142,12 +142,14 @@ class PackageWriter extends BandStructure {
} else if (highV.equals(JAVA6_MAX_CLASS_VERSION) ||
(highV.equals(JAVA7_MAX_CLASS_VERSION) && !pkg.cp.haveExtraTags())) {
// force down the package version if we have jdk7 classes without
// any Indy references, this is because jdk7 class file (52.0) without
// Indy is identical to jdk6 class file (51.0).
// any Indy references, this is because jdk7 class file (51.0) without
// Indy is identical to jdk6 class file (50.0).
packageVersion = JAVA6_PACKAGE_VERSION;
} else if (highV.equals(JAVA7_MAX_CLASS_VERSION)) {
packageVersion = JAVA7_PACKAGE_VERSION;
} else {
// Normal case. Use the newest archive format, when available
packageVersion = JAVA7_PACKAGE_VERSION;
packageVersion = JAVA8_PACKAGE_VERSION;
}
if (verbose > 0) {

View File

@ -25,6 +25,8 @@
package com.sun.net.httpserver;
import java.util.Base64;
/**
* BasicAuthenticator provides an implementation of HTTP Basic
* authentication. It is an abstract class and must be extended
@ -68,7 +70,7 @@ public abstract class BasicAuthenticator extends Authenticator {
if (sp == -1 || !auth.substring(0, sp).equals ("Basic")) {
return new Authenticator.Failure (401);
}
byte[] b = Base64.base64ToByteArray (auth.substring(sp+1));
byte[] b = Base64.getDecoder().decode(auth.substring(sp+1));
String userpass = new String (b);
int colon = userpass.indexOf (':');
String uname = userpass.substring (0, colon);
@ -102,208 +104,3 @@ public abstract class BasicAuthenticator extends Authenticator {
public abstract boolean checkCredentials (String username, String password);
}
class Base64 {
/**
* Translates the specified byte array into a Base64 string as per
* Preferences.put(byte[]).
*/
static String byteArrayToBase64(byte[] a) {
return byteArrayToBase64(a, false);
}
/**
* Translates the specified byte array into an "aternate representation"
* Base64 string. This non-standard variant uses an alphabet that does
* not contain the uppercase alphabetic characters, which makes it
* suitable for use in situations where case-folding occurs.
*/
static String byteArrayToAltBase64(byte[] a) {
return byteArrayToBase64(a, true);
}
private static String byteArrayToBase64(byte[] a, boolean alternate) {
int aLen = a.length;
int numFullGroups = aLen/3;
int numBytesInPartialGroup = aLen - 3*numFullGroups;
int resultLen = 4*((aLen + 2)/3);
StringBuffer result = new StringBuffer(resultLen);
char[] intToAlpha = (alternate ? intToAltBase64 : intToBase64);
// Translate all full groups from byte array elements to Base64
int inCursor = 0;
for (int i=0; i<numFullGroups; i++) {
int byte0 = a[inCursor++] & 0xff;
int byte1 = a[inCursor++] & 0xff;
int byte2 = a[inCursor++] & 0xff;
result.append(intToAlpha[byte0 >> 2]);
result.append(intToAlpha[(byte0 << 4)&0x3f | (byte1 >> 4)]);
result.append(intToAlpha[(byte1 << 2)&0x3f | (byte2 >> 6)]);
result.append(intToAlpha[byte2 & 0x3f]);
}
// Translate partial group if present
if (numBytesInPartialGroup != 0) {
int byte0 = a[inCursor++] & 0xff;
result.append(intToAlpha[byte0 >> 2]);
if (numBytesInPartialGroup == 1) {
result.append(intToAlpha[(byte0 << 4) & 0x3f]);
result.append("==");
} else {
// assert numBytesInPartialGroup == 2;
int byte1 = a[inCursor++] & 0xff;
result.append(intToAlpha[(byte0 << 4)&0x3f | (byte1 >> 4)]);
result.append(intToAlpha[(byte1 << 2)&0x3f]);
result.append('=');
}
}
// assert inCursor == a.length;
// assert result.length() == resultLen;
return result.toString();
}
/**
* This array is a lookup table that translates 6-bit positive integer
* index values into their "Base64 Alphabet" equivalents as specified
* in Table 1 of RFC 2045.
*/
private static final char intToBase64[] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
};
/**
* This array is a lookup table that translates 6-bit positive integer
* index values into their "Alternate Base64 Alphabet" equivalents.
* This is NOT the real Base64 Alphabet as per in Table 1 of RFC 2045.
* This alternate alphabet does not use the capital letters. It is
* designed for use in environments where "case folding" occurs.
*/
private static final char intToAltBase64[] = {
'!', '"', '#', '$', '%', '&', '\'', '(', ')', ',', '-', '.', ':',
';', '<', '>', '@', '[', ']', '^', '`', '_', '{', '|', '}', '~',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '?'
};
/**
* Translates the specified Base64 string (as per Preferences.get(byte[]))
* into a byte array.
*
* @throw IllegalArgumentException if <tt>s</tt> is not a valid Base64
* string.
*/
static byte[] base64ToByteArray(String s) {
return base64ToByteArray(s, false);
}
/**
* Translates the specified "aternate representation" Base64 string
* into a byte array.
*
* @throw IllegalArgumentException or ArrayOutOfBoundsException
* if <tt>s</tt> is not a valid alternate representation
* Base64 string.
*/
static byte[] altBase64ToByteArray(String s) {
return base64ToByteArray(s, true);
}
private static byte[] base64ToByteArray(String s, boolean alternate) {
byte[] alphaToInt = (alternate ? altBase64ToInt : base64ToInt);
int sLen = s.length();
int numGroups = sLen/4;
if (4*numGroups != sLen)
throw new IllegalArgumentException(
"String length must be a multiple of four.");
int missingBytesInLastGroup = 0;
int numFullGroups = numGroups;
if (sLen != 0) {
if (s.charAt(sLen-1) == '=') {
missingBytesInLastGroup++;
numFullGroups--;
}
if (s.charAt(sLen-2) == '=')
missingBytesInLastGroup++;
}
byte[] result = new byte[3*numGroups - missingBytesInLastGroup];
// Translate all full groups from base64 to byte array elements
int inCursor = 0, outCursor = 0;
for (int i=0; i<numFullGroups; i++) {
int ch0 = base64toInt(s.charAt(inCursor++), alphaToInt);
int ch1 = base64toInt(s.charAt(inCursor++), alphaToInt);
int ch2 = base64toInt(s.charAt(inCursor++), alphaToInt);
int ch3 = base64toInt(s.charAt(inCursor++), alphaToInt);
result[outCursor++] = (byte) ((ch0 << 2) | (ch1 >> 4));
result[outCursor++] = (byte) ((ch1 << 4) | (ch2 >> 2));
result[outCursor++] = (byte) ((ch2 << 6) | ch3);
}
// Translate partial group, if present
if (missingBytesInLastGroup != 0) {
int ch0 = base64toInt(s.charAt(inCursor++), alphaToInt);
int ch1 = base64toInt(s.charAt(inCursor++), alphaToInt);
result[outCursor++] = (byte) ((ch0 << 2) | (ch1 >> 4));
if (missingBytesInLastGroup == 1) {
int ch2 = base64toInt(s.charAt(inCursor++), alphaToInt);
result[outCursor++] = (byte) ((ch1 << 4) | (ch2 >> 2));
}
}
// assert inCursor == s.length()-missingBytesInLastGroup;
// assert outCursor == result.length;
return result;
}
/**
* Translates the specified character, which is assumed to be in the
* "Base 64 Alphabet" into its equivalent 6-bit positive integer.
*
* @throw IllegalArgumentException or ArrayOutOfBoundsException if
* c is not in the Base64 Alphabet.
*/
private static int base64toInt(char c, byte[] alphaToInt) {
int result = alphaToInt[c];
if (result < 0)
throw new IllegalArgumentException("Illegal character " + c);
return result;
}
/**
* This array is a lookup table that translates unicode characters
* drawn from the "Base64 Alphabet" (as specified in Table 1 of RFC 2045)
* into their 6-bit positive integer equivalents. Characters that
* are not in the Base64 alphabet but fall within the bounds of the
* array are translated to -1.
*/
private static final byte base64ToInt[] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54,
55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4,
5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34,
35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
};
/**
* This array is the analogue of base64ToInt, but for the nonstandard
* variant that avoids the use of uppercase alphabetic characters.
*/
private static final byte altBase64ToInt[] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1,
2, 3, 4, 5, 6, 7, 8, -1, 62, 9, 10, 11, -1 , 52, 53, 54, 55, 56, 57,
58, 59, 60, 61, 12, 13, 14, -1, 15, 63, 16, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, 17, -1, 18, 19, 21, 20, 26, 27, 28, 29, 30, 31, 32, 33,
34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
51, 22, 23, 24, 25
};
}

View File

@ -300,7 +300,7 @@ public class Button extends Component implements Accessible {
* @since 1.4
*/
public synchronized ActionListener[] getActionListeners() {
return (ActionListener[]) (getListeners(ActionListener.class));
return getListeners(ActionListener.class);
}
/**

View File

@ -470,7 +470,7 @@ public class Checkbox extends Component implements ItemSelectable, Accessible {
* @since 1.4
*/
public synchronized ItemListener[] getItemListeners() {
return (ItemListener[]) (getListeners(ItemListener.class));
return getListeners(ItemListener.class);
}
/**

View File

@ -85,7 +85,7 @@ public class Choice extends Component implements ItemSelectable, Accessible {
* @see #insert(String, int)
* @see #remove(String)
*/
Vector pItems;
Vector<String> pItems;
/**
* The index of the current choice for this <code>Choice</code>
@ -129,7 +129,7 @@ public class Choice extends Component implements ItemSelectable, Accessible {
*/
public Choice() throws HeadlessException {
GraphicsEnvironment.checkHeadless();
pItems = new Vector();
pItems = new Vector<>();
}
/**
@ -191,7 +191,7 @@ public class Choice extends Component implements ItemSelectable, Accessible {
* be called on the toolkit thread.
*/
final String getItemImpl(int index) {
return (String)pItems.elementAt(index);
return pItems.elementAt(index);
}
/**
@ -524,7 +524,7 @@ public class Choice extends Component implements ItemSelectable, Accessible {
* @since 1.4
*/
public synchronized ItemListener[] getItemListeners() {
return (ItemListener[])(getListeners(ItemListener.class));
return getListeners(ItemListener.class);
}
/**

View File

@ -7287,6 +7287,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
}
final Set<AWTKeyStroke> getFocusTraversalKeys_NoIDCheck(int id) {
// Okay to return Set directly because it is an unmodifiable view
@SuppressWarnings("unchecked")
Set<AWTKeyStroke> keystrokes = (focusTraversalKeys != null)
? focusTraversalKeys[id]
: null;

View File

@ -161,7 +161,7 @@ public class Container extends Component {
private boolean focusTraversalPolicyProvider;
// keeps track of the threads that are printing this component
private transient Set printingThreads;
private transient Set<Thread> printingThreads;
// True if there is at least one thread that's printing this component
private transient boolean printing = false;
@ -275,7 +275,7 @@ public class Container extends Component {
*/
public Container() {
}
@SuppressWarnings({"unchecked","rawtypes"})
void initializeFocusTraversalKeys() {
focusTraversalKeys = new Set[4];
}
@ -2006,7 +2006,7 @@ public class Container extends Component {
try {
synchronized (getObjectLock()) {
if (printingThreads == null) {
printingThreads = new HashSet();
printingThreads = new HashSet<>();
}
printingThreads.add(t);
printing = true;
@ -2148,7 +2148,7 @@ public class Container extends Component {
* @since 1.4
*/
public synchronized ContainerListener[] getContainerListeners() {
return (ContainerListener[]) (getListeners(ContainerListener.class));
return getListeners(ContainerListener.class);
}
/**
@ -2599,9 +2599,9 @@ public class Container extends Component {
if (GraphicsEnvironment.isHeadless()) {
throw new HeadlessException();
}
PointerInfo pi = (PointerInfo)java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction() {
public Object run() {
PointerInfo pi = java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<PointerInfo>() {
public PointerInfo run() {
return MouseInfo.getPointerInfo();
}
}
@ -2682,7 +2682,7 @@ public class Container extends Component {
y - comp.y,
ignoreEnabled);
} else {
comp = comp.locate(x - comp.x, y - comp.y);
comp = comp.getComponentAt(x - comp.x, y - comp.y);
}
if (comp != null && comp.visible &&
(ignoreEnabled || comp.enabled))
@ -2700,7 +2700,7 @@ public class Container extends Component {
y - comp.y,
ignoreEnabled);
} else {
comp = comp.locate(x - comp.x, y - comp.y);
comp = comp.getComponentAt(x - comp.x, y - comp.y);
}
if (comp != null && comp.visible &&
(ignoreEnabled || comp.enabled))
@ -4637,7 +4637,7 @@ class LightweightDispatcher implements java.io.Serializable, AWTEventListener {
private void startListeningForOtherDrags() {
//System.out.println("Adding AWTEventListener");
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction() {
new java.security.PrivilegedAction<Object>() {
public Object run() {
nativeContainer.getToolkit().addAWTEventListener(
LightweightDispatcher.this,
@ -4652,7 +4652,7 @@ class LightweightDispatcher implements java.io.Serializable, AWTEventListener {
private void stopListeningForOtherDrags() {
//System.out.println("Removing AWTEventListener");
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction() {
new java.security.PrivilegedAction<Object>() {
public Object run() {
nativeContainer.getToolkit().removeAWTEventListener(LightweightDispatcher.this);
return null;

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