mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-12 11:28:35 +00:00
Merge
This commit is contained in:
commit
fee9c1b0cc
@ -373,7 +373,14 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
|
||||
POLICY_SRC_LIST += $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS)/lib/security/java.policy
|
||||
endif
|
||||
ifndef OPENJDK
|
||||
ifneq (, $(filter $(OPENJDK_TARGET_OS), windows solaris))
|
||||
ifeq ($(OPENJDK_TARGET_OS), windows)
|
||||
ifeq ($(OPENJDK_TARGET_CPU_BITS), 32)
|
||||
POLICY_SRC_LIST += $(JDK_TOPDIR)/src/closed/$(OPENJDK_TARGET_OS)/lib/security/java.policy-win32
|
||||
else
|
||||
POLICY_SRC_LIST += $(JDK_TOPDIR)/src/closed/$(OPENJDK_TARGET_OS)/lib/security/java.policy-win64
|
||||
endif
|
||||
endif
|
||||
ifeq ($(OPENJDK_TARGET_OS), solaris)
|
||||
POLICY_SRC_LIST += $(JDK_TOPDIR)/src/closed/$(OPENJDK_TARGET_OS)/lib/security/java.policy
|
||||
endif
|
||||
endif
|
||||
|
||||
@ -27,7 +27,7 @@ DISABLE_WARNINGS := -Xlint:all,-deprecation,-unchecked,-rawtypes,-cast,-serial,-
|
||||
|
||||
# To build with all warnings enabled, do the following:
|
||||
# make JAVAC_WARNINGS="-Xlint:all -Xmaxwarns 10000"
|
||||
JAVAC_WARNINGS := -Xlint:-unchecked,-deprecation,-overrides,auxiliaryclass,cast,classfile,dep-ann,divzero,empty,fallthrough,overloads,serial,static,try,varargs -Werror
|
||||
JAVAC_WARNINGS := -Xlint:-unchecked,-deprecation,-overrides,auxiliaryclass,cast,classfile,dep-ann,divzero,empty,fallthrough,finally,overloads,serial,static,try,varargs -Werror
|
||||
|
||||
# Any java code executed during a JDK build to build other parts of the JDK must be
|
||||
# executed by the bootstrap JDK (probably with -Xbootclasspath/p: ) and for this
|
||||
|
||||
@ -1,180 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,98 +0,0 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,363 +0,0 @@
|
||||
/*
|
||||
* 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));
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,427 +0,0 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,388 +0,0 @@
|
||||
/*
|
||||
* 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));
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,117 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -56,8 +56,6 @@
|
||||
*/
|
||||
package build.tools.tzdb;
|
||||
|
||||
import static build.tools.tzdb.Utils.*;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
@ -179,15 +177,41 @@ public final class TzdbZoneRulesCompiler {
|
||||
System.exit(1);
|
||||
System.err.println("Source directory does not contain file: VERSION");
|
||||
}
|
||||
|
||||
// load source files
|
||||
printVerbose("Compiling TZDB version " + version);
|
||||
// parse source files
|
||||
for (Path file : srcFiles) {
|
||||
printVerbose("Parsing file: " + file);
|
||||
parseFile(file);
|
||||
}
|
||||
TzdbZoneRulesProvider provider = new TzdbZoneRulesProvider(srcFiles);
|
||||
|
||||
// build zone rules
|
||||
printVerbose("Building rules");
|
||||
buildZoneRules();
|
||||
|
||||
// Build the rules, zones and links into real zones.
|
||||
SortedMap<String, ZoneRules> builtZones = new TreeMap<>();
|
||||
|
||||
// build zones
|
||||
for (String zoneId : provider.getZoneIds()) {
|
||||
printVerbose("Building zone " + zoneId);
|
||||
builtZones.put(zoneId, provider.getZoneRules(zoneId));
|
||||
}
|
||||
|
||||
// build aliases
|
||||
Map<String, String> links = provider.getAliasMap();
|
||||
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);
|
||||
}
|
||||
links.put(aliasId, realId);
|
||||
}
|
||||
builtZones.put(aliasId, realRules);
|
||||
}
|
||||
|
||||
// output to file
|
||||
printVerbose("Outputting tzdb file: " + dstFile);
|
||||
outputFile(dstFile, version, builtZones, links);
|
||||
@ -269,361 +293,13 @@ public final class TzdbZoneRulesCompiler {
|
||||
}
|
||||
}
|
||||
|
||||
private static final Pattern YEAR = Pattern.compile("(?i)(?<min>min)|(?<max>max)|(?<only>only)|(?<year>[0-9]+)");
|
||||
private static final Pattern MONTH = Pattern.compile("(?i)(jan)|(feb)|(mar)|(apr)|(may)|(jun)|(jul)|(aug)|(sep)|(oct)|(nov)|(dec)");
|
||||
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("");
|
||||
|
||||
/** 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<>();
|
||||
|
||||
/** Whether to output verbose messages. */
|
||||
private boolean verbose;
|
||||
|
||||
/**
|
||||
* private contructor
|
||||
*/
|
||||
private TzdbZoneRulesCompiler() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a source file.
|
||||
*
|
||||
* @param file the file being read, not null
|
||||
* @throws Exception if an error occurs
|
||||
*/
|
||||
private void parseFile(Path file) throws Exception {
|
||||
int lineNumber = 1;
|
||||
String line = null;
|
||||
try {
|
||||
List<String> lines = Files.readAllLines(file, StandardCharsets.ISO_8859_1);
|
||||
List<TZDBZone> openZone = null;
|
||||
for (; lineNumber < lines.size(); lineNumber++) {
|
||||
line = lines.get(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;
|
||||
}
|
||||
Scanner s = new Scanner(line);
|
||||
if (openZone != null && Character.isWhitespace(line.charAt(0)) && s.hasNext()) {
|
||||
if (parseZoneLine(s, openZone)) {
|
||||
openZone = null;
|
||||
}
|
||||
} else {
|
||||
if (s.hasNext()) {
|
||||
String first = s.next();
|
||||
if (first.equals("Zone")) {
|
||||
openZone = new ArrayList<>();
|
||||
try {
|
||||
zones.put(s.next(), openZone);
|
||||
if (parseZoneLine(s, openZone)) {
|
||||
openZone = null;
|
||||
}
|
||||
} catch (NoSuchElementException x) {
|
||||
printVerbose("Invalid Zone line in file: " + file + ", line: " + line);
|
||||
throw new IllegalArgumentException("Invalid Zone line");
|
||||
}
|
||||
} else {
|
||||
openZone = null;
|
||||
if (first.equals("Rule")) {
|
||||
try {
|
||||
parseRuleLine(s);
|
||||
} catch (NoSuchElementException x) {
|
||||
printVerbose("Invalid Rule line in file: " + file + ", line: " + line);
|
||||
throw new IllegalArgumentException("Invalid Rule line");
|
||||
}
|
||||
} else if (first.equals("Link")) {
|
||||
try {
|
||||
String realId = s.next();
|
||||
String aliasId = s.next();
|
||||
links.put(aliasId, realId);
|
||||
} catch (NoSuchElementException x) {
|
||||
printVerbose("Invalid Link line in file: " + file + ", line: " + line);
|
||||
throw new IllegalArgumentException("Invalid Link line");
|
||||
}
|
||||
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown line");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new Exception("Failed while parsing file '" + file + "' on line " + lineNumber + " '" + line + "'", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a Rule line.
|
||||
*
|
||||
* @param s the line scanner, not null
|
||||
*/
|
||||
private void parseRuleLine(Scanner s) {
|
||||
TZDBRule rule = new TZDBRule();
|
||||
String name = s.next();
|
||||
if (rules.containsKey(name) == false) {
|
||||
rules.put(name, new ArrayList<TZDBRule>());
|
||||
}
|
||||
rules.get(name).add(rule);
|
||||
rule.startYear = parseYear(s, 0);
|
||||
rule.endYear = parseYear(s, rule.startYear);
|
||||
if (rule.startYear > rule.endYear) {
|
||||
throw new IllegalArgumentException("Year order invalid: " + rule.startYear + " > " + rule.endYear);
|
||||
}
|
||||
parseOptional(s.next()); // type is unused
|
||||
parseMonthDayTime(s, rule);
|
||||
rule.savingsAmount = parsePeriod(s.next());
|
||||
rule.text = parseOptional(s.next());
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a Zone line.
|
||||
*
|
||||
* @param s the line scanner, not null
|
||||
* @return true if the zone is complete
|
||||
*/
|
||||
private boolean parseZoneLine(Scanner s, List<TZDBZone> zoneList) {
|
||||
TZDBZone zone = new TZDBZone();
|
||||
zoneList.add(zone);
|
||||
zone.standardOffset = parseOffset(s.next());
|
||||
String savingsRule = parseOptional(s.next());
|
||||
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 = s.next();
|
||||
if (s.hasNext()) {
|
||||
zone.year = Integer.parseInt(s.next());
|
||||
if (s.hasNext()) {
|
||||
parseMonthDayTime(s, zone);
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a Rule line.
|
||||
*
|
||||
* @param s the line scanner, not null
|
||||
* @param mdt the object to parse into, not null
|
||||
*/
|
||||
private void parseMonthDayTime(Scanner s, TZDBMonthDayTime mdt) {
|
||||
mdt.month = parseMonth(s);
|
||||
if (s.hasNext()) {
|
||||
String dayRule = s.next();
|
||||
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 (s.hasNext()) {
|
||||
String timeStr = s.next();
|
||||
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(Scanner s, int defaultYear) {
|
||||
if (s.hasNext(YEAR)) {
|
||||
s.next(YEAR);
|
||||
MatchResult mr = s.match();
|
||||
if (mr.group(1) != null) {
|
||||
return 1900; // systemv has min
|
||||
} else if (mr.group(2) != null) {
|
||||
return YEAR_MAX_VALUE;
|
||||
} else if (mr.group(3) != null) {
|
||||
return defaultYear;
|
||||
}
|
||||
return Integer.parseInt(mr.group(4));
|
||||
/*
|
||||
if (mr.group("min") != null) {
|
||||
//return YEAR_MIN_VALUE;
|
||||
return 1900; // systemv has min
|
||||
} else if (mr.group("max") != null) {
|
||||
return YEAR_MAX_VALUE;
|
||||
} else if (mr.group("only") != null) {
|
||||
return defaultYear;
|
||||
}
|
||||
return Integer.parseInt(mr.group("year"));
|
||||
*/
|
||||
}
|
||||
throw new IllegalArgumentException("Unknown year: " + s.next());
|
||||
}
|
||||
|
||||
private int parseMonth(Scanner s) {
|
||||
if (s.hasNext(MONTH)) {
|
||||
s.next(MONTH);
|
||||
for (int moy = 1; moy < 13; moy++) {
|
||||
if (s.match().group(moy) != null) {
|
||||
return moy;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Unknown month: " + s.next());
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
builtZones.put(zoneId, bld.toRules(zoneId));
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
links.put(aliasId, realId);
|
||||
}
|
||||
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");
|
||||
links.remove("GMT+0");
|
||||
links.remove("GMT-0");
|
||||
// remove ROC, which is not supported in j.u.tz
|
||||
builtZones.remove("ROC");
|
||||
links.remove("ROC");
|
||||
// remove EST, HST and MST. They are supported via
|
||||
// the short-id mapping
|
||||
builtZones.remove("EST");
|
||||
builtZones.remove("HST");
|
||||
builtZones.remove("MST");
|
||||
}
|
||||
private TzdbZoneRulesCompiler() {}
|
||||
|
||||
/**
|
||||
* Prints a verbose message.
|
||||
@ -635,109 +311,4 @@ public final class TzdbZoneRulesCompiler {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
843
jdk/make/src/classes/build/tools/tzdb/TzdbZoneRulesProvider.java
Normal file
843
jdk/make/src/classes/build/tools/tzdb/TzdbZoneRulesProvider.java
Normal file
@ -0,0 +1,843 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
package build.tools.tzdb;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.NavigableMap;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.time.*;
|
||||
import java.time.Year;
|
||||
import java.time.chrono.IsoChronology;
|
||||
import java.time.temporal.TemporalAdjusters;
|
||||
import java.time.zone.ZoneOffsetTransition;
|
||||
import java.time.zone.ZoneOffsetTransitionRule;
|
||||
import java.time.zone.ZoneOffsetTransitionRule.TimeDefinition;
|
||||
import java.time.zone.ZoneRulesException;
|
||||
|
||||
/**
|
||||
* Compile and build time-zone rules from IANA timezone data
|
||||
*
|
||||
* @author Xueming Shen
|
||||
* @author Stephen Colebourne
|
||||
* @author Michael Nascimento Santos
|
||||
*
|
||||
* @since 1.9
|
||||
*/
|
||||
|
||||
class TzdbZoneRulesProvider {
|
||||
|
||||
/**
|
||||
* Creates an instance.
|
||||
*
|
||||
* @throws ZoneRulesException if unable to load
|
||||
*/
|
||||
public TzdbZoneRulesProvider(List<Path> files) {
|
||||
try {
|
||||
load(files);
|
||||
} catch (Exception ex) {
|
||||
throw new ZoneRulesException("Unable to load TZDB time-zone rules", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public Set<String> getZoneIds() {
|
||||
return new TreeSet(regionIds);
|
||||
}
|
||||
|
||||
public Map<String, String> getAliasMap() {
|
||||
return links;
|
||||
}
|
||||
|
||||
public ZoneRules getZoneRules(String zoneId) {
|
||||
Object obj = zones.get(zoneId);
|
||||
if (obj == null) {
|
||||
String zoneId0 = zoneId;
|
||||
if (links.containsKey(zoneId)) {
|
||||
zoneId = links.get(zoneId);
|
||||
obj = zones.get(zoneId);
|
||||
}
|
||||
if (obj == null) {
|
||||
throw new ZoneRulesException("Unknown time-zone ID: " + zoneId0);
|
||||
}
|
||||
}
|
||||
if (obj instanceof ZoneRules) {
|
||||
return (ZoneRules)obj;
|
||||
}
|
||||
try {
|
||||
ZoneRules zrules = buildRules(zoneId, (List<ZoneLine>)obj);
|
||||
zones.put(zoneId, zrules);
|
||||
return zrules;
|
||||
} catch (Exception ex) {
|
||||
throw new ZoneRulesException(
|
||||
"Invalid binary time-zone data: TZDB:" + zoneId, ex);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* All the regions that are available.
|
||||
*/
|
||||
private List<String> regionIds = new ArrayList<>(600);
|
||||
|
||||
/**
|
||||
* Zone region to rules mapping
|
||||
*/
|
||||
private final Map<String, Object> zones = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* compatibility list
|
||||
*/
|
||||
private static HashSet<String> excludedZones;
|
||||
static {
|
||||
// (1) exclude EST, HST and MST. They are supported
|
||||
// via the short-id mapping
|
||||
// (2) remove UTC and GMT
|
||||
// (3) remove ROC, which is not supported in j.u.tz
|
||||
excludedZones = new HashSet<>(10);
|
||||
excludedZones.add("EST");
|
||||
excludedZones.add("HST");
|
||||
excludedZones.add("MST");
|
||||
excludedZones.add("GMT+0");
|
||||
excludedZones.add("GMT-0");
|
||||
excludedZones.add("ROC");
|
||||
}
|
||||
|
||||
private Map<String, String> links = new HashMap<>(150);
|
||||
private Map<String, List<RuleLine>> rules = new HashMap<>(500);
|
||||
|
||||
private void load(List<Path> files) throws IOException {
|
||||
|
||||
for (Path file : files) {
|
||||
List<ZoneLine> openZone = null;
|
||||
try {
|
||||
for (String line : Files.readAllLines(file, StandardCharsets.ISO_8859_1)) {
|
||||
if (line.length() == 0 || line.charAt(0) == '#') {
|
||||
continue;
|
||||
}
|
||||
//StringIterator itr = new StringIterator(line);
|
||||
String[] tokens = split(line);
|
||||
if (openZone != null && // continuing zone line
|
||||
Character.isWhitespace(line.charAt(0)) &&
|
||||
tokens.length > 0) {
|
||||
ZoneLine zLine = new ZoneLine();
|
||||
openZone.add(zLine);
|
||||
if (zLine.parse(tokens, 0)) {
|
||||
openZone = null;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (line.startsWith("Zone")) { // parse Zone line
|
||||
String name = tokens[1];
|
||||
if (excludedZones.contains(name)){
|
||||
continue;
|
||||
}
|
||||
if (zones.containsKey(name)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Duplicated zone name in file: " + name +
|
||||
", line: [" + line + "]");
|
||||
}
|
||||
openZone = new ArrayList<>(10);
|
||||
zones.put(name, openZone);
|
||||
regionIds.add(name);
|
||||
ZoneLine zLine = new ZoneLine();
|
||||
openZone.add(zLine);
|
||||
if (zLine.parse(tokens, 2)) {
|
||||
openZone = null;
|
||||
}
|
||||
} else if (line.startsWith("Rule")) { // parse Rule line
|
||||
String name = tokens[1];
|
||||
if (!rules.containsKey(name)) {
|
||||
rules.put(name, new ArrayList<RuleLine>(10));
|
||||
}
|
||||
rules.get(name).add(new RuleLine().parse(tokens));
|
||||
} else if (line.startsWith("Link")) { // parse link line
|
||||
if (tokens.length >= 3) {
|
||||
String realId = tokens[1];
|
||||
String aliasId = tokens[2];
|
||||
if (excludedZones.contains(aliasId)){
|
||||
continue;
|
||||
}
|
||||
links.put(aliasId, realId);
|
||||
regionIds.add(aliasId);
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid Link line in file" +
|
||||
file + ", line: [" + line + "]");
|
||||
}
|
||||
} else {
|
||||
// skip unknown line
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException("Failed while processing file [" + file +
|
||||
"]", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String[] split(String str) {
|
||||
int off = 0;
|
||||
int end = str.length();
|
||||
ArrayList<String> list = new ArrayList<>(10);
|
||||
while (off < end) {
|
||||
char c = str.charAt(off);
|
||||
if (c == '\t' || c == ' ') {
|
||||
off++;
|
||||
continue;
|
||||
}
|
||||
if (c == '#') { // comment
|
||||
break;
|
||||
}
|
||||
int start = off;
|
||||
while (off < end) {
|
||||
c = str.charAt(off);
|
||||
if (c == ' ' || c == '\t') {
|
||||
break;
|
||||
}
|
||||
off++;
|
||||
}
|
||||
if (start != off) {
|
||||
list.add(str.substring(start, off));
|
||||
}
|
||||
}
|
||||
return list.toArray(new String[list.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Class representing a month-day-time in the TZDB file.
|
||||
*/
|
||||
private static abstract class MonthDayTime {
|
||||
/** The month of the cutover. */
|
||||
Month month = Month.JANUARY;
|
||||
|
||||
/** The day-of-month of the cutover. */
|
||||
int dayOfMonth = 1;
|
||||
|
||||
/** Whether to adjust forwards. */
|
||||
boolean adjustForwards = true;
|
||||
|
||||
/** The day-of-week of the cutover. */
|
||||
DayOfWeek dayOfWeek;
|
||||
|
||||
/** The time of the cutover, in second of day */
|
||||
int secsOfDay = 0;
|
||||
|
||||
/** Whether this is midnight end of day. */
|
||||
boolean endOfDay;
|
||||
/** The time of the cutover. */
|
||||
|
||||
TimeDefinition timeDefinition = TimeDefinition.WALL;
|
||||
|
||||
void adjustToForwards(int year) {
|
||||
if (adjustForwards == false && dayOfMonth > 0) {
|
||||
// weekDay<=monthDay case, don't have it in tzdb data for now
|
||||
LocalDate adjustedDate = LocalDate.of(year, month, dayOfMonth).minusDays(6);
|
||||
dayOfMonth = adjustedDate.getDayOfMonth();
|
||||
month = adjustedDate.getMonth();
|
||||
adjustForwards = true;
|
||||
}
|
||||
}
|
||||
|
||||
LocalDateTime toDateTime(int year) {
|
||||
LocalDate date;
|
||||
if (dayOfMonth < 0) {
|
||||
int monthLen = month.length(IsoChronology.INSTANCE.isLeapYear(year));
|
||||
date = LocalDate.of(year, month, monthLen + 1 + dayOfMonth);
|
||||
if (dayOfWeek != null) {
|
||||
date = date.with(TemporalAdjusters.previousOrSame(dayOfWeek));
|
||||
}
|
||||
} else {
|
||||
date = LocalDate.of(year, month, dayOfMonth);
|
||||
if (dayOfWeek != null) {
|
||||
date = date.with(TemporalAdjusters.nextOrSame(dayOfWeek));
|
||||
}
|
||||
}
|
||||
if (endOfDay) {
|
||||
date = date.plusDays(1);
|
||||
}
|
||||
return LocalDateTime.of(date, LocalTime.ofSecondOfDay(secsOfDay));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the MonthDaytime segment of a tzdb line.
|
||||
*/
|
||||
private void parse(String[] tokens, int off) {
|
||||
month = parseMonth(tokens[off++]);
|
||||
if (off < tokens.length) {
|
||||
String dayRule = tokens[off++];
|
||||
if (dayRule.startsWith("last")) {
|
||||
dayOfMonth = -1;
|
||||
dayOfWeek = parseDayOfWeek(dayRule.substring(4));
|
||||
adjustForwards = false;
|
||||
} else {
|
||||
int index = dayRule.indexOf(">=");
|
||||
if (index > 0) {
|
||||
dayOfWeek = parseDayOfWeek(dayRule.substring(0, index));
|
||||
dayRule = dayRule.substring(index + 2);
|
||||
} else {
|
||||
index = dayRule.indexOf("<=");
|
||||
if (index > 0) {
|
||||
dayOfWeek = parseDayOfWeek(dayRule.substring(0, index));
|
||||
adjustForwards = false;
|
||||
dayRule = dayRule.substring(index + 2);
|
||||
}
|
||||
}
|
||||
dayOfMonth = Integer.parseInt(dayRule);
|
||||
if (dayOfMonth < -28 || dayOfMonth > 31 || dayOfMonth == 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Day of month indicator must be between -28 and 31 inclusive excluding zero");
|
||||
}
|
||||
}
|
||||
if (off < tokens.length) {
|
||||
String timeStr = tokens[off++];
|
||||
secsOfDay = parseSecs(timeStr);
|
||||
if (secsOfDay == 86400) {
|
||||
// time must be midnight when end of day flag is true
|
||||
endOfDay = true;
|
||||
secsOfDay = 0;
|
||||
}
|
||||
timeDefinition = parseTimeDefinition(timeStr.charAt(timeStr.length() - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int parseYear(String year, int defaultYear) {
|
||||
switch (year.toLowerCase()) {
|
||||
case "min": return 1900;
|
||||
case "max": return Year.MAX_VALUE;
|
||||
case "only": return defaultYear;
|
||||
}
|
||||
return Integer.parseInt(year);
|
||||
}
|
||||
|
||||
Month parseMonth(String mon) {
|
||||
switch (mon) {
|
||||
case "Jan": return Month.JANUARY;
|
||||
case "Feb": return Month.FEBRUARY;
|
||||
case "Mar": return Month.MARCH;
|
||||
case "Apr": return Month.APRIL;
|
||||
case "May": return Month.MAY;
|
||||
case "Jun": return Month.JUNE;
|
||||
case "Jul": return Month.JULY;
|
||||
case "Aug": return Month.AUGUST;
|
||||
case "Sep": return Month.SEPTEMBER;
|
||||
case "Oct": return Month.OCTOBER;
|
||||
case "Nov": return Month.NOVEMBER;
|
||||
case "Dec": return Month.DECEMBER;
|
||||
}
|
||||
throw new IllegalArgumentException("Unknown month: " + mon);
|
||||
}
|
||||
|
||||
DayOfWeek parseDayOfWeek(String dow) {
|
||||
switch (dow) {
|
||||
case "Mon": return DayOfWeek.MONDAY;
|
||||
case "Tue": return DayOfWeek.TUESDAY;
|
||||
case "Wed": return DayOfWeek.WEDNESDAY;
|
||||
case "Thu": return DayOfWeek.THURSDAY;
|
||||
case "Fri": return DayOfWeek.FRIDAY;
|
||||
case "Sat": return DayOfWeek.SATURDAY;
|
||||
case "Sun": return DayOfWeek.SUNDAY;
|
||||
}
|
||||
throw new IllegalArgumentException("Unknown day-of-week: " + dow);
|
||||
}
|
||||
|
||||
String parseOptional(String str) {
|
||||
return str.equals("-") ? null : str;
|
||||
}
|
||||
|
||||
static final boolean isDigit(char c) {
|
||||
return c >= '0' && c <= '9';
|
||||
}
|
||||
|
||||
private int parseSecs(String time) {
|
||||
if (time.equals("-")) {
|
||||
return 0;
|
||||
}
|
||||
// faster hack
|
||||
int secs = 0;
|
||||
int sign = 1;
|
||||
int off = 0;
|
||||
int len = time.length();
|
||||
if (off < len && time.charAt(off) == '-') {
|
||||
sign = -1;
|
||||
off++;
|
||||
}
|
||||
char c0, c1;
|
||||
if (off < len && isDigit(c0 = time.charAt(off++))) {
|
||||
int hour = c0 - '0';
|
||||
if (off < len && isDigit(c1 = time.charAt(off))) {
|
||||
hour = hour * 10 + c1 - '0';
|
||||
off++;
|
||||
}
|
||||
secs = hour * 60 * 60;
|
||||
if (off < len && time.charAt(off++) == ':') {
|
||||
if (off + 1 < len &&
|
||||
isDigit(c0 = time.charAt(off++)) &&
|
||||
isDigit(c1 = time.charAt(off++))) {
|
||||
// minutes
|
||||
secs += ((c0 - '0') * 10 + c1 - '0') * 60;
|
||||
if (off < len && time.charAt(off++) == ':') {
|
||||
if (off + 1 < len &&
|
||||
isDigit(c0 = time.charAt(off++)) &&
|
||||
isDigit(c1 = time.charAt(off++))) {
|
||||
// seconds
|
||||
secs += ((c0 - '0') * 10 + c1 - '0');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return secs * sign;
|
||||
}
|
||||
throw new IllegalArgumentException("[" + time + "]");
|
||||
}
|
||||
|
||||
int parseOffset(String str) {
|
||||
int secs = parseSecs(str);
|
||||
if (Math.abs(secs) > 18 * 60 * 60) {
|
||||
throw new IllegalArgumentException(
|
||||
"Zone offset not in valid range: -18:00 to +18:00");
|
||||
}
|
||||
return secs;
|
||||
}
|
||||
|
||||
int parsePeriod(String str) {
|
||||
return parseSecs(str);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class representing a rule line in the TZDB file.
|
||||
*/
|
||||
private static class RuleLine extends MonthDayTime {
|
||||
/** The start year. */
|
||||
int startYear;
|
||||
|
||||
/** The end year. */
|
||||
int endYear;
|
||||
|
||||
/** The amount of savings, in seconds. */
|
||||
int savingsAmount;
|
||||
|
||||
/** The text name of the zone. */
|
||||
String text;
|
||||
|
||||
/**
|
||||
* 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 stdOffset, int savingsBefore) {
|
||||
// rule shared by different zones, so don't change it
|
||||
Month month = this.month;
|
||||
int dayOfMonth = this.dayOfMonth;
|
||||
DayOfWeek dayOfWeek = this.dayOfWeek;
|
||||
boolean endOfDay = this.endOfDay;
|
||||
|
||||
// optimize stored format
|
||||
if (dayOfMonth < 0) {
|
||||
if (month != Month.FEBRUARY) { // not Month.FEBRUARY
|
||||
dayOfMonth = month.maxLength() - 6;
|
||||
}
|
||||
}
|
||||
if (endOfDay && dayOfMonth > 0 &&
|
||||
(dayOfMonth == 28 && month == Month.FEBRUARY) == false) {
|
||||
LocalDate date = LocalDate.of(2004, month, dayOfMonth).plusDays(1); // leap-year
|
||||
month = date.getMonth();
|
||||
dayOfMonth = date.getDayOfMonth();
|
||||
if (dayOfWeek != null) {
|
||||
dayOfWeek = dayOfWeek.plus(1);
|
||||
}
|
||||
endOfDay = false;
|
||||
}
|
||||
// build rule
|
||||
return ZoneOffsetTransitionRule.of(
|
||||
//month, dayOfMonth, dayOfWeek, time, endOfDay, timeDefinition,
|
||||
month, dayOfMonth, dayOfWeek,
|
||||
LocalTime.ofSecondOfDay(secsOfDay), endOfDay, timeDefinition,
|
||||
stdOffset,
|
||||
ZoneOffset.ofTotalSeconds(stdOffset.getTotalSeconds() + savingsBefore),
|
||||
ZoneOffset.ofTotalSeconds(stdOffset.getTotalSeconds() + savingsAmount));
|
||||
}
|
||||
|
||||
RuleLine parse(String[] tokens) {
|
||||
startYear = parseYear(tokens[2], 0);
|
||||
endYear = parseYear(tokens[3], startYear);
|
||||
if (startYear > endYear) {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid <Rule> line/Year order invalid:" + startYear + " > " + endYear);
|
||||
}
|
||||
//parseOptional(s.next()); // type is unused
|
||||
super.parse(tokens, 5); // monthdaytime parsing
|
||||
savingsAmount = parsePeriod(tokens[8]);
|
||||
//rule.text = parseOptional(s.next());
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class representing a linked set of zone lines in the TZDB file.
|
||||
*/
|
||||
private static class ZoneLine extends MonthDayTime {
|
||||
/** The standard offset. */
|
||||
int stdOffsetSecs;
|
||||
|
||||
/** The fixed savings amount. */
|
||||
int fixedSavingsSecs = 0;
|
||||
|
||||
/** The savings rule. */
|
||||
String savingsRule;
|
||||
|
||||
/** The text name of the zone. */
|
||||
String text;
|
||||
|
||||
/** The cutover year */
|
||||
int year = Year.MAX_VALUE;
|
||||
|
||||
/** The cutover date time */
|
||||
LocalDateTime ldt;
|
||||
|
||||
/** The cutover date/time in epoch seconds/UTC */
|
||||
long ldtSecs = Long.MIN_VALUE;
|
||||
|
||||
LocalDateTime toDateTime() {
|
||||
if (ldt == null) {
|
||||
ldt = toDateTime(year);
|
||||
}
|
||||
return ldt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the date-time epoch second in 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
|
||||
*/
|
||||
long toDateTimeEpochSecond(int savingsSecs) {
|
||||
if (ldtSecs == Long.MIN_VALUE) {
|
||||
ldtSecs = toDateTime().toEpochSecond(ZoneOffset.UTC);
|
||||
}
|
||||
switch(timeDefinition) {
|
||||
case UTC: return ldtSecs;
|
||||
case STANDARD: return ldtSecs - stdOffsetSecs;
|
||||
default: return ldtSecs - (stdOffsetSecs + savingsSecs); // WALL
|
||||
}
|
||||
}
|
||||
|
||||
boolean parse(String[] tokens, int off) {
|
||||
stdOffsetSecs = parseOffset(tokens[off++]);
|
||||
savingsRule = parseOptional(tokens[off++]);
|
||||
if (savingsRule != null && savingsRule.length() > 0 &&
|
||||
(savingsRule.charAt(0) == '-' || isDigit(savingsRule.charAt(0)))) {
|
||||
try {
|
||||
fixedSavingsSecs = parsePeriod(savingsRule);
|
||||
savingsRule = null;
|
||||
} catch (Exception ex) {
|
||||
fixedSavingsSecs = 0;
|
||||
}
|
||||
}
|
||||
text = tokens[off++];
|
||||
if (off < tokens.length) {
|
||||
year = Integer.parseInt(tokens[off++]);
|
||||
if (off < tokens.length) {
|
||||
super.parse(tokens, off); // MonthDayTime
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class representing a rule line in the TZDB file for a particular year.
|
||||
*/
|
||||
private static class TransRule implements Comparable<TransRule>
|
||||
{
|
||||
private int year;
|
||||
private RuleLine rule;
|
||||
|
||||
/** The trans date/time */
|
||||
private LocalDateTime ldt;
|
||||
|
||||
/** The trans date/time in epoch seconds (assume UTC) */
|
||||
long ldtSecs;
|
||||
|
||||
TransRule(int year, RuleLine rule) {
|
||||
this.year = year;
|
||||
this.rule = rule;
|
||||
this.ldt = rule.toDateTime(year);
|
||||
this.ldtSecs = ldt.toEpochSecond(ZoneOffset.UTC);
|
||||
}
|
||||
|
||||
ZoneOffsetTransition toTransition(ZoneOffset standardOffset, int savingsBeforeSecs) {
|
||||
// copy of code in ZoneOffsetTransitionRule to avoid infinite loop
|
||||
ZoneOffset wallOffset = ZoneOffset.ofTotalSeconds(
|
||||
standardOffset.getTotalSeconds() + savingsBeforeSecs);
|
||||
ZoneOffset offsetAfter = ZoneOffset.ofTotalSeconds(
|
||||
standardOffset.getTotalSeconds() + rule.savingsAmount);
|
||||
LocalDateTime dt = rule.timeDefinition
|
||||
.createDateTime(ldt, standardOffset, wallOffset);
|
||||
return ZoneOffsetTransition.of(dt, wallOffset, offsetAfter);
|
||||
}
|
||||
|
||||
long toEpochSecond(ZoneOffset stdOffset, int savingsBeforeSecs) {
|
||||
switch(rule.timeDefinition) {
|
||||
case UTC: return ldtSecs;
|
||||
case STANDARD: return ldtSecs - stdOffset.getTotalSeconds();
|
||||
default: return ldtSecs - (stdOffset.getTotalSeconds() + savingsBeforeSecs); // WALL
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if this a real transition with the active savings in seconds
|
||||
*
|
||||
* @param savingsBefore the active savings in seconds
|
||||
* @return true, if savings changes
|
||||
*/
|
||||
boolean isTransition(int savingsBefore) {
|
||||
return rule.savingsAmount != savingsBefore;
|
||||
}
|
||||
|
||||
public int compareTo(TransRule other) {
|
||||
return (ldtSecs < other.ldtSecs)? -1 : ((ldtSecs == other.ldtSecs) ? 0 : 1);
|
||||
}
|
||||
}
|
||||
|
||||
private ZoneRules buildRules(String zoneId, List<ZoneLine> zones) {
|
||||
if (zones.isEmpty()) {
|
||||
throw new IllegalStateException("No available zone window");
|
||||
}
|
||||
final List<ZoneOffsetTransition> standardTransitionList = new ArrayList<>(4);
|
||||
final List<ZoneOffsetTransition> transitionList = new ArrayList<>(256);
|
||||
final List<ZoneOffsetTransitionRule> lastTransitionRuleList = new ArrayList<>(2);
|
||||
|
||||
final ZoneLine zone0 = zones.get(0);
|
||||
// initialize the standard offset, wallOffset and savings for loop
|
||||
|
||||
//ZoneOffset stdOffset = zone0.standardOffset;
|
||||
ZoneOffset stdOffset = ZoneOffset.ofTotalSeconds(zone0.stdOffsetSecs);
|
||||
|
||||
int savings = zone0.fixedSavingsSecs;
|
||||
ZoneOffset wallOffset = ZoneOffset.ofTotalSeconds(stdOffset.getTotalSeconds() + savings);
|
||||
|
||||
// start ldt of each zone window
|
||||
LocalDateTime zoneStart = LocalDateTime.MIN;
|
||||
|
||||
// first stanard offset
|
||||
ZoneOffset firstStdOffset = stdOffset;
|
||||
// first wall offset
|
||||
ZoneOffset firstWallOffset = wallOffset;
|
||||
|
||||
for (ZoneLine zone : zones) {
|
||||
// check if standard offset changed, update it if yes
|
||||
ZoneOffset stdOffsetPrev = stdOffset; // for effectiveSavings check
|
||||
if (zone.stdOffsetSecs != stdOffset.getTotalSeconds()) {
|
||||
ZoneOffset stdOffsetNew = ZoneOffset.ofTotalSeconds(zone.stdOffsetSecs);
|
||||
standardTransitionList.add(
|
||||
ZoneOffsetTransition.of(
|
||||
LocalDateTime.ofEpochSecond(zoneStart.toEpochSecond(wallOffset),
|
||||
0,
|
||||
stdOffset),
|
||||
stdOffset,
|
||||
stdOffsetNew));
|
||||
stdOffset = stdOffsetNew;
|
||||
}
|
||||
|
||||
LocalDateTime zoneEnd;
|
||||
if (zone.year == Year.MAX_VALUE) {
|
||||
zoneEnd = LocalDateTime.MAX;
|
||||
} else {
|
||||
zoneEnd = zone.toDateTime();
|
||||
}
|
||||
if (zoneEnd.compareTo(zoneStart) < 0) {
|
||||
throw new IllegalStateException("Windows must be in date-time order: " +
|
||||
zoneEnd + " < " + zoneStart);
|
||||
}
|
||||
// calculate effective savings at the start of the window
|
||||
List<TransRule> trules = null;
|
||||
List<TransRule> lastRules = null;
|
||||
|
||||
int effectiveSavings = zone.fixedSavingsSecs;
|
||||
if (zone.savingsRule != null) {
|
||||
List<RuleLine> tzdbRules = rules.get(zone.savingsRule);
|
||||
if (tzdbRules == null) {
|
||||
throw new IllegalArgumentException("<Rule> not found: " +
|
||||
zone.savingsRule);
|
||||
}
|
||||
trules = new ArrayList<>(256);
|
||||
lastRules = new ArrayList<>(2);
|
||||
int lastRulesStartYear = Year.MIN_VALUE;
|
||||
|
||||
// merge the rules to transitions
|
||||
for (RuleLine rule : tzdbRules) {
|
||||
if (rule.startYear > zoneEnd.getYear()) {
|
||||
// rules will not be used for this zone entry
|
||||
continue;
|
||||
}
|
||||
rule.adjustToForwards(2004); // irrelevant, treat as leap year
|
||||
|
||||
int startYear = rule.startYear;
|
||||
int endYear = rule.endYear;
|
||||
if (zoneEnd.equals(LocalDateTime.MAX)) {
|
||||
if (endYear == Year.MAX_VALUE) {
|
||||
endYear = startYear;
|
||||
lastRules.add(new TransRule(endYear, rule));
|
||||
lastRulesStartYear = Math.max(startYear, lastRulesStartYear);
|
||||
}
|
||||
} else {
|
||||
if (endYear == Year.MAX_VALUE) {
|
||||
//endYear = zoneEnd.getYear();
|
||||
endYear = zone.year;
|
||||
}
|
||||
}
|
||||
int year = startYear;
|
||||
while (year <= endYear) {
|
||||
trules.add(new TransRule(year, rule));
|
||||
year++;
|
||||
}
|
||||
}
|
||||
|
||||
// last rules, fill the gap years between different last rules
|
||||
if (zoneEnd.equals(LocalDateTime.MAX)) {
|
||||
lastRulesStartYear = Math.max(lastRulesStartYear, zoneStart.getYear()) + 1;
|
||||
for (TransRule rule : lastRules) {
|
||||
if (rule.year <= lastRulesStartYear) {
|
||||
int year = rule.year;
|
||||
while (year <= lastRulesStartYear) {
|
||||
trules.add(new TransRule(year, rule.rule));
|
||||
year++;
|
||||
}
|
||||
rule.year = lastRulesStartYear;
|
||||
rule.ldt = rule.rule.toDateTime(year);
|
||||
rule.ldtSecs = rule.ldt.toEpochSecond(ZoneOffset.UTC);
|
||||
}
|
||||
}
|
||||
Collections.sort(lastRules);
|
||||
}
|
||||
// sort the merged rules
|
||||
Collections.sort(trules);
|
||||
|
||||
effectiveSavings = 0;
|
||||
for (TransRule rule : trules) {
|
||||
if (rule.toEpochSecond(stdOffsetPrev, savings) >
|
||||
zoneStart.toEpochSecond(wallOffset)) {
|
||||
// previous savings amount found, which could be the
|
||||
// savings amount at the instant that the window starts
|
||||
// (hence isAfter)
|
||||
break;
|
||||
}
|
||||
effectiveSavings = rule.rule.savingsAmount;
|
||||
}
|
||||
}
|
||||
// check if the start of the window represents a transition
|
||||
ZoneOffset effectiveWallOffset =
|
||||
ZoneOffset.ofTotalSeconds(stdOffset.getTotalSeconds() + effectiveSavings);
|
||||
|
||||
if (!wallOffset.equals(effectiveWallOffset)) {
|
||||
transitionList.add(ZoneOffsetTransition.of(zoneStart,
|
||||
wallOffset,
|
||||
effectiveWallOffset));
|
||||
}
|
||||
savings = effectiveSavings;
|
||||
// apply rules within the window
|
||||
if (trules != null) {
|
||||
long zoneStartEpochSecs = zoneStart.toEpochSecond(wallOffset);
|
||||
for (TransRule trule : trules) {
|
||||
if (trule.isTransition(savings)) {
|
||||
long epochSecs = trule.toEpochSecond(stdOffset, savings);
|
||||
if (epochSecs < zoneStartEpochSecs ||
|
||||
epochSecs >= zone.toDateTimeEpochSecond(savings)) {
|
||||
continue;
|
||||
}
|
||||
transitionList.add(trule.toTransition(stdOffset, savings));
|
||||
savings = trule.rule.savingsAmount;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (lastRules != null) {
|
||||
for (TransRule trule : lastRules) {
|
||||
lastTransitionRuleList.add(trule.rule.toTransitionRule(stdOffset, savings));
|
||||
savings = trule.rule.savingsAmount;
|
||||
}
|
||||
}
|
||||
|
||||
// finally we can calculate the true end of the window, passing it to the next window
|
||||
wallOffset = ZoneOffset.ofTotalSeconds(stdOffset.getTotalSeconds() + savings);
|
||||
zoneStart = LocalDateTime.ofEpochSecond(zone.toDateTimeEpochSecond(savings),
|
||||
0,
|
||||
wallOffset);
|
||||
}
|
||||
return new ZoneRules(firstStdOffset,
|
||||
firstWallOffset,
|
||||
standardTransitionList,
|
||||
transitionList,
|
||||
lastTransitionRuleList);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,176 +0,0 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,474 +0,0 @@
|
||||
/*
|
||||
* 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 ± 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 ±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 ±59, sign matches hours and seconds
|
||||
* @param seconds the time-zone offset in seconds, from 0 to ±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 ±59
|
||||
* @param seconds the time-zone offset in seconds, from 0 to ±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 ±59, sign matches hours and seconds
|
||||
* @param seconds the time-zone offset in seconds, from 0 to ±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;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,290 +0,0 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,223 +0,0 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
|
||||
}
|
||||
@ -64,6 +64,12 @@ package build.tools.tzdb;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectOutput;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.zone.ZoneOffsetTransition;
|
||||
import java.time.zone.ZoneOffsetTransitionRule;
|
||||
import java.time.zone.ZoneOffsetTransitionRule.TimeDefinition;
|
||||
import java.util.Arrays;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -224,15 +230,15 @@ final class ZoneRules {
|
||||
* @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 month = rule.getMonth().getValue();
|
||||
byte dom = (byte)rule.getDayOfMonthIndicator();
|
||||
int dow = rule.getDayOfWeek().getValue();
|
||||
LocalTime time = rule.getLocalTime();
|
||||
boolean timeEndOfDay = rule.isMidnightEndOfDay();
|
||||
TimeDefinition timeDefinition = rule.getTimeDefinition();
|
||||
ZoneOffset standardOffset = rule.getStandardOffset();
|
||||
ZoneOffset offsetBefore = rule.getOffsetBefore();
|
||||
ZoneOffset offsetAfter = rule.getOffsetAfter();
|
||||
|
||||
int timeSecs = (timeEndOfDay ? 86400 : time.toSecondOfDay());
|
||||
int stdOffset = standardOffset.getTotalSeconds();
|
||||
|
||||
@ -1,743 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, 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
|
||||
@ -81,6 +81,8 @@ public class AncestorEvent extends AWTEvent {
|
||||
|
||||
/**
|
||||
* Returns the ancestor that the event actually occurred on.
|
||||
*
|
||||
* @return the {@code Container} object specifying the ancestor component
|
||||
*/
|
||||
public Container getAncestor() {
|
||||
return ancestor;
|
||||
@ -90,6 +92,8 @@ public class AncestorEvent extends AWTEvent {
|
||||
* Returns the parent of the ancestor the event actually occurred on.
|
||||
* This is most interesting in an ANCESTOR_REMOVED event, as
|
||||
* the ancestor may no longer be in the component hierarchy.
|
||||
*
|
||||
* @return the {@code Container} object specifying the ancestor's parent
|
||||
*/
|
||||
public Container getAncestorParent() {
|
||||
return ancestorParent;
|
||||
@ -97,6 +101,8 @@ public class AncestorEvent extends AWTEvent {
|
||||
|
||||
/**
|
||||
* Returns the component that the listener was added to.
|
||||
*
|
||||
* @return the {@code JComponent} on which the event occurred
|
||||
*/
|
||||
public JComponent getComponent() {
|
||||
return (JComponent)getSource();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 1998, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, 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
|
||||
@ -48,6 +48,9 @@ public interface AncestorListener extends EventListener {
|
||||
* if the source has actually become visible. For this to be true
|
||||
* all its parents must be visible and it must be in a hierarchy
|
||||
* rooted at a Window
|
||||
*
|
||||
* @param event an {@code AncestorEvent} signifying a change in an
|
||||
* ancestor-component's display-status
|
||||
*/
|
||||
public void ancestorAdded(AncestorEvent event);
|
||||
|
||||
@ -58,11 +61,17 @@ public interface AncestorListener extends EventListener {
|
||||
* if the source has actually become invisible. For this to be true
|
||||
* at least one of its parents must by invisible or it is not in
|
||||
* a hierarchy rooted at a Window
|
||||
*
|
||||
* @param event an {@code AncestorEvent} signifying a change in an
|
||||
* ancestor-component's display-status
|
||||
*/
|
||||
public void ancestorRemoved(AncestorEvent event);
|
||||
|
||||
/**
|
||||
* Called when either the source or one of its ancestors is moved.
|
||||
*
|
||||
* @param event an {@code AncestorEvent} signifying a change in an
|
||||
* ancestor-component's display-status
|
||||
*/
|
||||
public void ancestorMoved(AncestorEvent event);
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 1998, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, 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,9 +37,17 @@ import java.util.EventListener;
|
||||
|
||||
public interface CellEditorListener extends java.util.EventListener {
|
||||
|
||||
/** This tells the listeners the editor has ended editing */
|
||||
/**
|
||||
* This tells the listeners the editor has ended editing
|
||||
*
|
||||
* @param e the {@code ChangeEvent} containing the source of the event
|
||||
*/
|
||||
public void editingStopped(ChangeEvent e);
|
||||
|
||||
/** This tells the listeners the editor has canceled editing */
|
||||
/**
|
||||
* This tells the listeners the editor has canceled editing
|
||||
*
|
||||
* @param e the {@code ChangeEvent} containing the source of the event
|
||||
*/
|
||||
public void editingCanceled(ChangeEvent e);
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, 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
|
||||
@ -120,6 +120,8 @@ public class EventListenerList implements Serializable {
|
||||
* any such manipulation is necessary, it should be done
|
||||
* on a copy of the array returned rather than the array
|
||||
* itself.
|
||||
*
|
||||
* @return array of ListenerType-listener pairs
|
||||
*/
|
||||
public Object[] getListenerList() {
|
||||
return listenerList;
|
||||
@ -127,6 +129,9 @@ public class EventListenerList implements Serializable {
|
||||
|
||||
/**
|
||||
* Return an array of all the listeners of the given type.
|
||||
*
|
||||
* @param <T> the type of {@code EventListener} to search for
|
||||
* @param t the type of {@code EventListener} classes to be returned
|
||||
* @return all of the listeners of the specified type.
|
||||
* @exception ClassCastException if the supplied class
|
||||
* is not assignable to EventListener
|
||||
@ -148,6 +153,8 @@ public class EventListenerList implements Serializable {
|
||||
|
||||
/**
|
||||
* Returns the total number of listeners for this listener list.
|
||||
*
|
||||
* @return an integer count of total number of listeners
|
||||
*/
|
||||
public int getListenerCount() {
|
||||
return listenerList.length/2;
|
||||
@ -156,6 +163,9 @@ public class EventListenerList implements Serializable {
|
||||
/**
|
||||
* Returns the total number of listeners of the supplied type
|
||||
* for this listener list.
|
||||
*
|
||||
* @param t the type of listeners to count
|
||||
* @return the number of listeners of type {@code t}
|
||||
*/
|
||||
public int getListenerCount(Class<?> t) {
|
||||
Object[] lList = listenerList;
|
||||
@ -173,7 +183,9 @@ public class EventListenerList implements Serializable {
|
||||
|
||||
/**
|
||||
* Adds the listener as a listener of the specified type.
|
||||
* @param t the type of the listener to be added
|
||||
*
|
||||
* @param <T> the type of {@code EventListener} to add
|
||||
* @param t the type of the {@code EventListener} class to add
|
||||
* @param l the listener to be added
|
||||
*/
|
||||
public synchronized <T extends EventListener> void add(Class<T> t, T l) {
|
||||
@ -206,6 +218,8 @@ public class EventListenerList implements Serializable {
|
||||
|
||||
/**
|
||||
* Removes the listener as a listener of the specified type.
|
||||
*
|
||||
* @param <T> the type of {@code EventListener}
|
||||
* @param t the type of the listener to be removed
|
||||
* @param l the listener to be removed
|
||||
*/
|
||||
|
||||
@ -142,6 +142,8 @@ public class HyperlinkEvent extends EventObject {
|
||||
* This may be useful if a URL can't be formed
|
||||
* from the description, in which case the associated
|
||||
* URL would be null.
|
||||
*
|
||||
* @return the description of this link as a {@code String}
|
||||
*/
|
||||
public String getDescription() {
|
||||
return desc;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2014, 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
|
||||
@ -42,6 +42,9 @@ import java.util.EventListener;
|
||||
public interface InternalFrameListener extends EventListener {
|
||||
/**
|
||||
* Invoked when a internal frame has been opened.
|
||||
*
|
||||
* @param e an {@code InternalFrameEvent} with information about the
|
||||
* {@code JInteralFrame} that originated the event
|
||||
* @see javax.swing.JInternalFrame#show
|
||||
*/
|
||||
public void internalFrameOpened(InternalFrameEvent e);
|
||||
@ -49,36 +52,54 @@ public interface InternalFrameListener extends EventListener {
|
||||
/**
|
||||
* Invoked when an internal frame is in the process of being closed.
|
||||
* The close operation can be overridden at this point.
|
||||
*
|
||||
* @param e an {@code InternalFrameEvent} with information about the
|
||||
* {@code JInteralFrame} that originated the event
|
||||
* @see javax.swing.JInternalFrame#setDefaultCloseOperation
|
||||
*/
|
||||
public void internalFrameClosing(InternalFrameEvent e);
|
||||
|
||||
/**
|
||||
* Invoked when an internal frame has been closed.
|
||||
*
|
||||
* @param e an {@code InternalFrameEvent} with information about the
|
||||
* {@code JInteralFrame} that originated the event
|
||||
* @see javax.swing.JInternalFrame#setClosed
|
||||
*/
|
||||
public void internalFrameClosed(InternalFrameEvent e);
|
||||
|
||||
/**
|
||||
* Invoked when an internal frame is iconified.
|
||||
*
|
||||
* @param e an {@code InternalFrameEvent} with information about the
|
||||
* {@code JInteralFrame} that originated the event
|
||||
* @see javax.swing.JInternalFrame#setIcon
|
||||
*/
|
||||
public void internalFrameIconified(InternalFrameEvent e);
|
||||
|
||||
/**
|
||||
* Invoked when an internal frame is de-iconified.
|
||||
*
|
||||
* @param e an {@code InternalFrameEvent} with information about the
|
||||
* {@code JInteralFrame} that originated the event
|
||||
* @see javax.swing.JInternalFrame#setIcon
|
||||
*/
|
||||
public void internalFrameDeiconified(InternalFrameEvent e);
|
||||
|
||||
/**
|
||||
* Invoked when an internal frame is activated.
|
||||
*
|
||||
* @param e an {@code InternalFrameEvent} with information about the
|
||||
* {@code JInteralFrame} that originated the event
|
||||
* @see javax.swing.JInternalFrame#setSelected
|
||||
*/
|
||||
public void internalFrameActivated(InternalFrameEvent e);
|
||||
|
||||
/**
|
||||
* Invoked when an internal frame is de-activated.
|
||||
*
|
||||
* @param e an {@code InternalFrameEvent} with information about the
|
||||
* {@code JInteralFrame} that originated the event
|
||||
* @see javax.swing.JInternalFrame#setSelected
|
||||
*/
|
||||
public void internalFrameDeactivated(InternalFrameEvent e);
|
||||
|
||||
@ -63,6 +63,7 @@ public class ListSelectionEvent extends EventObject
|
||||
* {@code lastIndex}. The selection of at least one index within the range will
|
||||
* have changed.
|
||||
*
|
||||
* @param source the {@code Object} on which the event initially occurred
|
||||
* @param firstIndex the first index in the range, <= lastIndex
|
||||
* @param lastIndex the last index in the range, >= firstIndex
|
||||
* @param isAdjusting whether or not this is one in a series of
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2014, 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,16 +37,22 @@ public interface MenuKeyListener extends EventListener {
|
||||
/**
|
||||
* Invoked when a key has been typed.
|
||||
* This event occurs when a key press is followed by a key release.
|
||||
*
|
||||
* @param e a {@code MenuKeyEvent}
|
||||
*/
|
||||
void menuKeyTyped(MenuKeyEvent e);
|
||||
|
||||
/**
|
||||
* Invoked when a key has been pressed.
|
||||
*
|
||||
* @param e a {@code MenuKeyEvent}
|
||||
*/
|
||||
void menuKeyPressed(MenuKeyEvent e);
|
||||
|
||||
/**
|
||||
* Invoked when a key has been released.
|
||||
*
|
||||
* @param e a {@code MenuKeyEvent}
|
||||
*/
|
||||
void menuKeyReleased(MenuKeyEvent e);
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -27,7 +27,7 @@ package javax.swing.event;
|
||||
import java.util.EventObject;
|
||||
|
||||
/**
|
||||
* PopupMenuEvent only contains the source of the event which is the JPoupMenu
|
||||
* PopupMenuEvent only contains the source of the event which is the JPopupMenu
|
||||
* sending the event
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 1998, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, 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
|
||||
@ -35,17 +35,23 @@ public interface PopupMenuListener extends EventListener {
|
||||
|
||||
/**
|
||||
* This method is called before the popup menu becomes visible
|
||||
*
|
||||
* @param e a {@code PopupMenuEvent} containing the source of the event
|
||||
*/
|
||||
void popupMenuWillBecomeVisible(PopupMenuEvent e);
|
||||
|
||||
/**
|
||||
* This method is called before the popup menu becomes invisible
|
||||
* Note that a JPopupMenu can become invisible any time
|
||||
*
|
||||
* @param e a {@code PopupMenuEvent} containing the source of the event
|
||||
*/
|
||||
void popupMenuWillBecomeInvisible(PopupMenuEvent e);
|
||||
|
||||
/**
|
||||
* This method is called when the popup menu is canceled
|
||||
*
|
||||
* @param e a {@code PopupMenuEvent} containing the source of the event
|
||||
*/
|
||||
void popupMenuCanceled(PopupMenuEvent e);
|
||||
}
|
||||
|
||||
@ -83,9 +83,17 @@ public class TableColumnModelEvent extends java.util.EventObject
|
||||
// Querying Methods
|
||||
//
|
||||
|
||||
/** Returns the fromIndex. Valid for removed or moved events */
|
||||
/**
|
||||
* Returns the fromIndex. Valid for removed or moved events
|
||||
*
|
||||
* @return int value for index from which the column was moved or removed
|
||||
*/
|
||||
public int getFromIndex() { return fromIndex; };
|
||||
|
||||
/** Returns the toIndex. Valid for add and moved events */
|
||||
/**
|
||||
* Returns the toIndex. Valid for add and moved events
|
||||
*
|
||||
* @return int value of column's new index
|
||||
*/
|
||||
public int getToIndex() { return toIndex; };
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 1998, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, 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
|
||||
@ -39,21 +39,39 @@ import java.util.EventListener;
|
||||
|
||||
public interface TableColumnModelListener extends java.util.EventListener
|
||||
{
|
||||
/** Tells listeners that a column was added to the model. */
|
||||
/**
|
||||
* Tells listeners that a column was added to the model.
|
||||
*
|
||||
* @param e a {@code TableColumnModelEvent}
|
||||
*/
|
||||
public void columnAdded(TableColumnModelEvent e);
|
||||
|
||||
/** Tells listeners that a column was removed from the model. */
|
||||
/**
|
||||
* Tells listeners that a column was removed from the model.
|
||||
*
|
||||
* @param e a {@code TableColumnModelEvent}
|
||||
*/
|
||||
public void columnRemoved(TableColumnModelEvent e);
|
||||
|
||||
/** Tells listeners that a column was repositioned. */
|
||||
/**
|
||||
* Tells listeners that a column was repositioned.
|
||||
*
|
||||
* @param e a {@code TableColumnModelEvent}
|
||||
*/
|
||||
public void columnMoved(TableColumnModelEvent e);
|
||||
|
||||
/** Tells listeners that a column was moved due to a margin change. */
|
||||
/**
|
||||
* Tells listeners that a column was moved due to a margin change.
|
||||
*
|
||||
* @param e a {@code ChangeEvent}
|
||||
*/
|
||||
public void columnMarginChanged(ChangeEvent e);
|
||||
|
||||
/**
|
||||
* Tells listeners that the selection model of the
|
||||
* TableColumnModel changed.
|
||||
*
|
||||
* @param e a {@code ListSelectionEvent}
|
||||
*/
|
||||
public void columnSelectionChanged(ListSelectionEvent e);
|
||||
}
|
||||
|
||||
@ -95,13 +95,15 @@ public class TableModelEvent extends java.util.EventObject
|
||||
//
|
||||
|
||||
/**
|
||||
* All row data in the table has changed, listeners should discard any state
|
||||
* that was based on the rows and requery the <code>TableModel</code>
|
||||
* to get the new row count and all the appropriate values.
|
||||
* The <code>JTable</code> will repaint the entire visible region on
|
||||
* receiving this event, querying the model for the cell values that are visible.
|
||||
* The structure of the table ie, the column names, types and order
|
||||
* have not changed.
|
||||
* All row data in the table has changed, listeners should discard any state
|
||||
* that was based on the rows and requery the <code>TableModel</code>
|
||||
* to get the new row count and all the appropriate values.
|
||||
* The <code>JTable</code> will repaint the entire visible region on
|
||||
* receiving this event, querying the model for the cell values that are visible.
|
||||
* The structure of the table ie, the column names, types and order
|
||||
* have not changed.
|
||||
*
|
||||
* @param source the {@code TableModel} affected by this event
|
||||
*/
|
||||
public TableModelEvent(TableModel source) {
|
||||
// Use Integer.MAX_VALUE instead of getRowCount() in case rows were deleted.
|
||||
@ -109,21 +111,28 @@ public class TableModelEvent extends java.util.EventObject
|
||||
}
|
||||
|
||||
/**
|
||||
* This row of data has been updated.
|
||||
* To denote the arrival of a completely new table with a different structure
|
||||
* use <code>HEADER_ROW</code> as the value for the <code>row</code>.
|
||||
* When the <code>JTable</code> receives this event and its
|
||||
* <code>autoCreateColumnsFromModel</code>
|
||||
* flag is set it discards any TableColumns that it had and reallocates
|
||||
* default ones in the order they appear in the model. This is the
|
||||
* same as calling <code>setModel(TableModel)</code> on the <code>JTable</code>.
|
||||
* This row of data has been updated.
|
||||
* To denote the arrival of a completely new table with a different structure
|
||||
* use <code>HEADER_ROW</code> as the value for the <code>row</code>.
|
||||
* When the <code>JTable</code> receives this event and its
|
||||
* <code>autoCreateColumnsFromModel</code>
|
||||
* flag is set it discards any TableColumns that it had and reallocates
|
||||
* default ones in the order they appear in the model. This is the
|
||||
* same as calling <code>setModel(TableModel)</code> on the <code>JTable</code>.
|
||||
*
|
||||
* @param source the {@code TableModel} affected by this event
|
||||
* @param row the row which has been updated
|
||||
*/
|
||||
public TableModelEvent(TableModel source, int row) {
|
||||
this(source, row, row, ALL_COLUMNS, UPDATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* The data in rows [<I>firstRow</I>, <I>lastRow</I>] have been updated.
|
||||
* The data in rows [<I>firstRow</I>, <I>lastRow</I>] have been updated.
|
||||
*
|
||||
* @param source the {@code TableModel} affected by this event
|
||||
* @param firstRow the first row affected by this event
|
||||
* @param lastRow the last row affected by this event
|
||||
*/
|
||||
public TableModelEvent(TableModel source, int firstRow, int lastRow) {
|
||||
this(source, firstRow, lastRow, ALL_COLUMNS, UPDATE);
|
||||
@ -132,18 +141,32 @@ public class TableModelEvent extends java.util.EventObject
|
||||
/**
|
||||
* The cells in column <I>column</I> in the range
|
||||
* [<I>firstRow</I>, <I>lastRow</I>] have been updated.
|
||||
*
|
||||
* @param source the {@code TableModel} affected by this event
|
||||
* @param firstRow the first row affected by this event
|
||||
* @param lastRow the last row affected by this event
|
||||
* @param column the column index of cells changed; {@code ALL_COLUMNS}
|
||||
* signifies all cells in the specified range of rows are changed.
|
||||
*/
|
||||
public TableModelEvent(TableModel source, int firstRow, int lastRow, int column) {
|
||||
this(source, firstRow, lastRow, column, UPDATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* The cells from (firstRow, column) to (lastRow, column) have been changed.
|
||||
* The <I>column</I> refers to the column index of the cell in the model's
|
||||
* co-ordinate system. When <I>column</I> is ALL_COLUMNS, all cells in the
|
||||
* specified range of rows are considered changed.
|
||||
* <p>
|
||||
* The <I>type</I> should be one of: INSERT, UPDATE and DELETE.
|
||||
* The cells from (firstRow, column) to (lastRow, column) have been changed.
|
||||
* The <I>column</I> refers to the column index of the cell in the model's
|
||||
* co-ordinate system. When <I>column</I> is ALL_COLUMNS, all cells in the
|
||||
* specified range of rows are considered changed.
|
||||
* <p>
|
||||
* The <I>type</I> should be one of: INSERT, UPDATE and DELETE.
|
||||
*
|
||||
* @param source the {@code TableModel} affected by this event
|
||||
* @param firstRow the first row affected by this event
|
||||
* @param lastRow the last row affected by this event
|
||||
* @param column the column index of cells changed; {@code ALL_COLUMNS}
|
||||
* signifies all cells in the specified range of rows are changed.
|
||||
* @param type the type of change signified by this even, @code INSERT},
|
||||
* {@code DELETE } or {@code UPDATE}
|
||||
*/
|
||||
public TableModelEvent(TableModel source, int firstRow, int lastRow, int column, int type) {
|
||||
super(source);
|
||||
@ -157,23 +180,36 @@ public class TableModelEvent extends java.util.EventObject
|
||||
// Querying Methods
|
||||
//
|
||||
|
||||
/** Returns the first row that changed. HEADER_ROW means the meta data,
|
||||
/**
|
||||
* Returns the first row that changed. HEADER_ROW means the meta data,
|
||||
* ie. names, types and order of the columns.
|
||||
*
|
||||
* @return an integer signifying the first row changed
|
||||
*/
|
||||
public int getFirstRow() { return firstRow; };
|
||||
|
||||
/** Returns the last row that changed. */
|
||||
/**
|
||||
* Returns the last row that changed.
|
||||
*
|
||||
* @return an integer signifying the last row changed
|
||||
*/
|
||||
public int getLastRow() { return lastRow; };
|
||||
|
||||
/**
|
||||
* Returns the column for the event. If the return
|
||||
* value is ALL_COLUMNS; it means every column in the specified
|
||||
* rows changed.
|
||||
*
|
||||
* @return an integer signifying which column is affected by this event
|
||||
*/
|
||||
public int getColumn() { return column; };
|
||||
|
||||
/**
|
||||
* Returns the type of event - one of: INSERT, UPDATE and DELETE.
|
||||
*
|
||||
* @return the type of change to a table model, an {@code INSERT} or
|
||||
* {@code DELETE } of row(s) or column(s) or {@code UPDATE}
|
||||
* to data
|
||||
*/
|
||||
public int getType() { return type; }
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 1998, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, 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
|
||||
@ -40,6 +40,9 @@ public interface TableModelListener extends java.util.EventListener
|
||||
/**
|
||||
* This fine grain notification tells listeners the exact range
|
||||
* of cells, rows, or columns that changed.
|
||||
*
|
||||
* @param e a {@code TableModelEvent} to notify listener that a table model
|
||||
* has changed
|
||||
*/
|
||||
public void tableChanged(TableModelEvent e);
|
||||
}
|
||||
|
||||
@ -54,7 +54,7 @@ public class TreeExpansionEvent extends EventObject
|
||||
/**
|
||||
* Path to the value this event represents.
|
||||
*/
|
||||
protected TreePath path;
|
||||
protected TreePath path;
|
||||
|
||||
/**
|
||||
* Constructs a TreeExpansionEvent object.
|
||||
@ -71,6 +71,8 @@ public class TreeExpansionEvent extends EventObject
|
||||
|
||||
/**
|
||||
* Returns the path to the value that has been expanded/collapsed.
|
||||
*
|
||||
* @return this event's {@code TreePath} object
|
||||
*/
|
||||
public TreePath getPath() { return path; }
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -41,12 +41,18 @@ import java.util.EventListener;
|
||||
public interface TreeExpansionListener extends EventListener
|
||||
{
|
||||
/**
|
||||
* Called whenever an item in the tree has been expanded.
|
||||
*/
|
||||
* Called whenever an item in the tree has been expanded.
|
||||
*
|
||||
* @param event a {@code TreeExpansionEvent} containing a {@code TreePath}
|
||||
* object for the expanded node
|
||||
*/
|
||||
public void treeExpanded(TreeExpansionEvent event);
|
||||
|
||||
/**
|
||||
* Called whenever an item in the tree has been collapsed.
|
||||
*/
|
||||
* Called whenever an item in the tree has been collapsed.
|
||||
*
|
||||
* @param event a {@code TreeExpansionEvent} containing a {@code TreePath}
|
||||
* object for the collapsed node
|
||||
*/
|
||||
public void treeCollapsed(TreeExpansionEvent event);
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, 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
|
||||
@ -46,25 +46,26 @@ public interface TreeModelListener extends EventListener {
|
||||
* altered their children arrays, but other attributes have
|
||||
* changed and may affect presentation. Example: the name of a
|
||||
* file has changed, but it is in the same location in the file
|
||||
* system.</p>
|
||||
* <p>To indicate the root has changed, childIndices and children
|
||||
* will be null. </p>
|
||||
* system.
|
||||
*
|
||||
* <p>Use <code>e.getPath()</code>
|
||||
* to get the parent of the changed node(s).
|
||||
* <code>e.getChildIndices()</code>
|
||||
* returns the index(es) of the changed node(s).</p>
|
||||
* <p>To indicate the root has changed, childIndices and children
|
||||
* will be null.
|
||||
*
|
||||
* <p>Use {@code e.getPath()} to get the parent of the changed node(s).
|
||||
* {@code e.getChildIndices()} returns the index(es) of the changed node(s).
|
||||
*
|
||||
* @param e a {@code TreeModelEvent} describing changes to a tree model
|
||||
*/
|
||||
void treeNodesChanged(TreeModelEvent e);
|
||||
|
||||
/**
|
||||
* <p>Invoked after nodes have been inserted into the tree.</p>
|
||||
*
|
||||
* <p>Use <code>e.getPath()</code>
|
||||
* to get the parent of the new node(s).
|
||||
* <code>e.getChildIndices()</code>
|
||||
* returns the index(es) of the new node(s)
|
||||
* in ascending order.</p>
|
||||
* <p>Use {@code e.getPath()} to get the parent of the new node(s).
|
||||
* {@code e.getChildIndices()} returns the index(es) of the new node(s)
|
||||
* in ascending order.
|
||||
*
|
||||
* @param e a {@code TreeModelEvent} describing changes to a tree model
|
||||
*/
|
||||
void treeNodesInserted(TreeModelEvent e);
|
||||
|
||||
@ -74,11 +75,11 @@ public interface TreeModelListener extends EventListener {
|
||||
* invoked once for the root of the removed subtree, not once for
|
||||
* each individual set of siblings removed.</p>
|
||||
*
|
||||
* <p>Use <code>e.getPath()</code>
|
||||
* to get the former parent of the deleted node(s).
|
||||
* <code>e.getChildIndices()</code>
|
||||
* returns, in ascending order, the index(es)
|
||||
* the node(s) had before being deleted.</p>
|
||||
* <p>Use {@code e.getPath()} to get the former parent of the deleted
|
||||
* node(s). {@code e.getChildIndices()} returns, in ascending order, the
|
||||
* index(es) the node(s) had before being deleted.
|
||||
*
|
||||
* @param e a {@code TreeModelEvent} describing changes to a tree model
|
||||
*/
|
||||
void treeNodesRemoved(TreeModelEvent e);
|
||||
|
||||
@ -88,10 +89,10 @@ public interface TreeModelListener extends EventListener {
|
||||
* one and the first element does not identify the current root node
|
||||
* the first element should become the new root of the tree.
|
||||
*
|
||||
* <p>Use <code>e.getPath()</code>
|
||||
* to get the path to the node.
|
||||
* <code>e.getChildIndices()</code>
|
||||
* returns null.</p>
|
||||
* <p>Use {@code e.getPath()} to get the path to the node.
|
||||
* {@code e.getChildIndices()} returns null.
|
||||
*
|
||||
* @param e a {@code TreeModelEvent} describing changes to a tree model
|
||||
*/
|
||||
void treeStructureChanged(TreeModelEvent e);
|
||||
|
||||
|
||||
@ -62,12 +62,16 @@ public class TreeSelectionEvent extends EventObject
|
||||
protected TreePath newLeadSelectionPath;
|
||||
|
||||
/**
|
||||
* Represents a change in the selection of a TreeSelectionModel.
|
||||
* paths identifies the paths that have been either added or
|
||||
* Represents a change in the selection of a {@code TreeSelectionModel}.
|
||||
* {@code paths} identifies the paths that have been either added or
|
||||
* removed from the selection.
|
||||
*
|
||||
* @param source source of event
|
||||
* @param paths the paths that have changed in the selection
|
||||
* @param areNew a {@code boolean} array indicating whether the paths in
|
||||
* {@code paths} are new to the selection
|
||||
* @param oldLeadSelectionPath the previous lead selection path
|
||||
* @param newLeadSelectionPath the new lead selection path
|
||||
*/
|
||||
public TreeSelectionEvent(Object source, TreePath[] paths,
|
||||
boolean[] areNew, TreePath oldLeadSelectionPath,
|
||||
@ -81,14 +85,16 @@ public class TreeSelectionEvent extends EventObject
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a change in the selection of a TreeSelectionModel.
|
||||
* path identifies the path that have been either added or
|
||||
* Represents a change in the selection of a {@code TreeSelectionModel}.
|
||||
* {@code path} identifies the path that has been either added or
|
||||
* removed from the selection.
|
||||
*
|
||||
* @param source source of event
|
||||
* @param path the path that has changed in the selection
|
||||
* @param isNew whether or not the path is new to the selection, false
|
||||
* means path was removed from the selection.
|
||||
* means path was removed from the selection.
|
||||
* @param oldLeadSelectionPath the previous lead selection path
|
||||
* @param newLeadSelectionPath the new lead selection path
|
||||
*/
|
||||
public TreeSelectionEvent(Object source, TreePath path, boolean isNew,
|
||||
TreePath oldLeadSelectionPath,
|
||||
@ -104,8 +110,9 @@ public class TreeSelectionEvent extends EventObject
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the paths that have been added or removed from the
|
||||
* selection.
|
||||
* Returns the paths that have been added or removed from the selection.
|
||||
*
|
||||
* @return copy of the array of {@code TreePath} obects for this event.
|
||||
*/
|
||||
public TreePath[] getPaths()
|
||||
{
|
||||
@ -120,6 +127,8 @@ public class TreeSelectionEvent extends EventObject
|
||||
|
||||
/**
|
||||
* Returns the first path element.
|
||||
*
|
||||
* @return the first {@code TreePath} element represented by this event
|
||||
*/
|
||||
public TreePath getPath()
|
||||
{
|
||||
@ -187,6 +196,8 @@ public class TreeSelectionEvent extends EventObject
|
||||
|
||||
/**
|
||||
* Returns the path that was previously the lead path.
|
||||
*
|
||||
* @return a {@code TreePath} containing the old lead selection path
|
||||
*/
|
||||
public TreePath getOldLeadSelectionPath() {
|
||||
return oldLeadSelectionPath;
|
||||
@ -194,6 +205,8 @@ public class TreeSelectionEvent extends EventObject
|
||||
|
||||
/**
|
||||
* Returns the current lead path.
|
||||
*
|
||||
* @return a {@code TreePath} containing the new lead selection path
|
||||
*/
|
||||
public TreePath getNewLeadSelectionPath() {
|
||||
return newLeadSelectionPath;
|
||||
@ -201,10 +214,14 @@ public class TreeSelectionEvent extends EventObject
|
||||
|
||||
/**
|
||||
* Returns a copy of the receiver, but with the source being newSource.
|
||||
*
|
||||
* @param newSource source of event
|
||||
* @return an {@code Object} which is a copy of this event with the source
|
||||
* being the {@code newSource} provided
|
||||
*/
|
||||
public Object cloneWithSource(Object newSource) {
|
||||
// Fix for IE bug - crashing
|
||||
return new TreeSelectionEvent(newSource, paths,areNew,
|
||||
return new TreeSelectionEvent(newSource, paths, areNew,
|
||||
oldLeadSelectionPath,
|
||||
newLeadSelectionPath);
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -41,11 +41,19 @@ import javax.swing.tree.ExpandVetoException;
|
||||
public interface TreeWillExpandListener extends EventListener {
|
||||
/**
|
||||
* Invoked whenever a node in the tree is about to be expanded.
|
||||
*
|
||||
* @param event a {@code TreeExpansionEvent} containing a {@code TreePath}
|
||||
* object for the node
|
||||
* @throws ExpandVetoException to signify expansion has been canceled
|
||||
*/
|
||||
public void treeWillExpand(TreeExpansionEvent event) throws ExpandVetoException;
|
||||
|
||||
/**
|
||||
* Invoked whenever a node in the tree is about to be collapsed.
|
||||
*
|
||||
* @param event a {@code TreeExpansionEvent} containing a {@code TreePath}
|
||||
* object for the node
|
||||
* @throws ExpandVetoException to signify collapse has been canceled
|
||||
*/
|
||||
public void treeWillCollapse(TreeExpansionEvent event) throws ExpandVetoException;
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 1998, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, 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
|
||||
@ -38,6 +38,8 @@ public interface UndoableEditListener extends java.util.EventListener {
|
||||
|
||||
/**
|
||||
* An undoable edit happened
|
||||
*
|
||||
* @param e an {@code UndoableEditEvent} object
|
||||
*/
|
||||
void undoableEditHappened(UndoableEditEvent e);
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, 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,8 @@ public class MultiButtonUI extends ButtonUI {
|
||||
* Returns the list of UIs associated with this multiplexing UI. This
|
||||
* allows processing of the UIs by an application aware of multiplexing
|
||||
* UIs on components.
|
||||
*
|
||||
* @return an array of the UI delegates
|
||||
*/
|
||||
public ComponentUI[] getUIs() {
|
||||
return MultiLookAndFeel.uisToArray(uis);
|
||||
@ -98,6 +100,9 @@ public class MultiButtonUI extends ButtonUI {
|
||||
* Returns a multiplexing UI instance if any of the auxiliary
|
||||
* <code>LookAndFeel</code>s supports this UI. Otherwise, just returns the
|
||||
* UI object obtained from the default <code>LookAndFeel</code>.
|
||||
*
|
||||
* @param a the component to create the UI for
|
||||
* @return the UI delegate created
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent a) {
|
||||
ComponentUI mui = new MultiButtonUI();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2014, 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,8 @@ public class MultiColorChooserUI extends ColorChooserUI {
|
||||
* Returns the list of UIs associated with this multiplexing UI. This
|
||||
* allows processing of the UIs by an application aware of multiplexing
|
||||
* UIs on components.
|
||||
*
|
||||
* @return an array of the UI delegates
|
||||
*/
|
||||
public ComponentUI[] getUIs() {
|
||||
return MultiLookAndFeel.uisToArray(uis);
|
||||
@ -98,6 +100,9 @@ public class MultiColorChooserUI extends ColorChooserUI {
|
||||
* Returns a multiplexing UI instance if any of the auxiliary
|
||||
* <code>LookAndFeel</code>s supports this UI. Otherwise, just returns the
|
||||
* UI object obtained from the default <code>LookAndFeel</code>.
|
||||
*
|
||||
* @param a the component to create the UI for
|
||||
* @return the UI delegate created
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent a) {
|
||||
ComponentUI mui = new MultiColorChooserUI();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, 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,8 @@ public class MultiComboBoxUI extends ComboBoxUI {
|
||||
* Returns the list of UIs associated with this multiplexing UI. This
|
||||
* allows processing of the UIs by an application aware of multiplexing
|
||||
* UIs on components.
|
||||
*
|
||||
* @return an array of the UI delegates
|
||||
*/
|
||||
public ComponentUI[] getUIs() {
|
||||
return MultiLookAndFeel.uisToArray(uis);
|
||||
@ -138,6 +140,9 @@ public class MultiComboBoxUI extends ComboBoxUI {
|
||||
* Returns a multiplexing UI instance if any of the auxiliary
|
||||
* <code>LookAndFeel</code>s supports this UI. Otherwise, just returns the
|
||||
* UI object obtained from the default <code>LookAndFeel</code>.
|
||||
*
|
||||
* @param a the component to create the UI for
|
||||
* @return the UI delegate created
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent a) {
|
||||
ComponentUI mui = new MultiComboBoxUI();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, 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,8 @@ public class MultiDesktopIconUI extends DesktopIconUI {
|
||||
* Returns the list of UIs associated with this multiplexing UI. This
|
||||
* allows processing of the UIs by an application aware of multiplexing
|
||||
* UIs on components.
|
||||
*
|
||||
* @return an array of the UI delegates
|
||||
*/
|
||||
public ComponentUI[] getUIs() {
|
||||
return MultiLookAndFeel.uisToArray(uis);
|
||||
@ -98,6 +100,9 @@ public class MultiDesktopIconUI extends DesktopIconUI {
|
||||
* Returns a multiplexing UI instance if any of the auxiliary
|
||||
* <code>LookAndFeel</code>s supports this UI. Otherwise, just returns the
|
||||
* UI object obtained from the default <code>LookAndFeel</code>.
|
||||
*
|
||||
* @param a the component to create the UI for
|
||||
* @return the UI delegate created
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent a) {
|
||||
ComponentUI mui = new MultiDesktopIconUI();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, 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,8 @@ public class MultiDesktopPaneUI extends DesktopPaneUI {
|
||||
* Returns the list of UIs associated with this multiplexing UI. This
|
||||
* allows processing of the UIs by an application aware of multiplexing
|
||||
* UIs on components.
|
||||
*
|
||||
* @return an array of the UI delegates
|
||||
*/
|
||||
public ComponentUI[] getUIs() {
|
||||
return MultiLookAndFeel.uisToArray(uis);
|
||||
@ -98,6 +100,9 @@ public class MultiDesktopPaneUI extends DesktopPaneUI {
|
||||
* Returns a multiplexing UI instance if any of the auxiliary
|
||||
* <code>LookAndFeel</code>s supports this UI. Otherwise, just returns the
|
||||
* UI object obtained from the default <code>LookAndFeel</code>.
|
||||
*
|
||||
* @param a the component to create the UI for
|
||||
* @return the UI delegate created
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent a) {
|
||||
ComponentUI mui = new MultiDesktopPaneUI();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, 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
|
||||
@ -62,6 +62,8 @@ public class MultiFileChooserUI extends FileChooserUI {
|
||||
* Returns the list of UIs associated with this multiplexing UI. This
|
||||
* allows processing of the UIs by an application aware of multiplexing
|
||||
* UIs on components.
|
||||
*
|
||||
* @return an array of the UI delegates
|
||||
*/
|
||||
public ComponentUI[] getUIs() {
|
||||
return MultiLookAndFeel.uisToArray(uis);
|
||||
@ -181,6 +183,9 @@ public class MultiFileChooserUI extends FileChooserUI {
|
||||
* Returns a multiplexing UI instance if any of the auxiliary
|
||||
* <code>LookAndFeel</code>s supports this UI. Otherwise, just returns the
|
||||
* UI object obtained from the default <code>LookAndFeel</code>.
|
||||
*
|
||||
* @param a the component to create the UI for
|
||||
* @return the UI delegate created
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent a) {
|
||||
ComponentUI mui = new MultiFileChooserUI();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, 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,8 @@ public class MultiInternalFrameUI extends InternalFrameUI {
|
||||
* Returns the list of UIs associated with this multiplexing UI. This
|
||||
* allows processing of the UIs by an application aware of multiplexing
|
||||
* UIs on components.
|
||||
*
|
||||
* @return an array of the UI delegates
|
||||
*/
|
||||
public ComponentUI[] getUIs() {
|
||||
return MultiLookAndFeel.uisToArray(uis);
|
||||
@ -98,6 +100,9 @@ public class MultiInternalFrameUI extends InternalFrameUI {
|
||||
* Returns a multiplexing UI instance if any of the auxiliary
|
||||
* <code>LookAndFeel</code>s supports this UI. Otherwise, just returns the
|
||||
* UI object obtained from the default <code>LookAndFeel</code>.
|
||||
*
|
||||
* @param a the component to create the UI for
|
||||
* @return the UI delegate created
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent a) {
|
||||
ComponentUI mui = new MultiInternalFrameUI();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, 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,8 @@ public class MultiLabelUI extends LabelUI {
|
||||
* Returns the list of UIs associated with this multiplexing UI. This
|
||||
* allows processing of the UIs by an application aware of multiplexing
|
||||
* UIs on components.
|
||||
*
|
||||
* @return an array of the UI delegates
|
||||
*/
|
||||
public ComponentUI[] getUIs() {
|
||||
return MultiLookAndFeel.uisToArray(uis);
|
||||
@ -98,6 +100,9 @@ public class MultiLabelUI extends LabelUI {
|
||||
* Returns a multiplexing UI instance if any of the auxiliary
|
||||
* <code>LookAndFeel</code>s supports this UI. Otherwise, just returns the
|
||||
* UI object obtained from the default <code>LookAndFeel</code>.
|
||||
*
|
||||
* @param a the component to create the UI for
|
||||
* @return the UI delegate created
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent a) {
|
||||
ComponentUI mui = new MultiLabelUI();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, 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
|
||||
@ -60,6 +60,8 @@ public class MultiListUI extends ListUI {
|
||||
* Returns the list of UIs associated with this multiplexing UI. This
|
||||
* allows processing of the UIs by an application aware of multiplexing
|
||||
* UIs on components.
|
||||
*
|
||||
* @return an array of the UI delegates
|
||||
*/
|
||||
public ComponentUI[] getUIs() {
|
||||
return MultiLookAndFeel.uisToArray(uis);
|
||||
@ -146,6 +148,9 @@ public class MultiListUI extends ListUI {
|
||||
* Returns a multiplexing UI instance if any of the auxiliary
|
||||
* <code>LookAndFeel</code>s supports this UI. Otherwise, just returns the
|
||||
* UI object obtained from the default <code>LookAndFeel</code>.
|
||||
*
|
||||
* @param a the component to create the UI for
|
||||
* @return the UI delegate created
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent a) {
|
||||
ComponentUI mui = new MultiListUI();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, 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,8 @@ public class MultiMenuBarUI extends MenuBarUI {
|
||||
* Returns the list of UIs associated with this multiplexing UI. This
|
||||
* allows processing of the UIs by an application aware of multiplexing
|
||||
* UIs on components.
|
||||
*
|
||||
* @return an array of the UI delegates
|
||||
*/
|
||||
public ComponentUI[] getUIs() {
|
||||
return MultiLookAndFeel.uisToArray(uis);
|
||||
@ -98,6 +100,9 @@ public class MultiMenuBarUI extends MenuBarUI {
|
||||
* Returns a multiplexing UI instance if any of the auxiliary
|
||||
* <code>LookAndFeel</code>s supports this UI. Otherwise, just returns the
|
||||
* UI object obtained from the default <code>LookAndFeel</code>.
|
||||
*
|
||||
* @param a the component to create the UI for
|
||||
* @return the UI delegate created
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent a) {
|
||||
ComponentUI mui = new MultiMenuBarUI();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, 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,8 @@ public class MultiMenuItemUI extends MenuItemUI {
|
||||
* Returns the list of UIs associated with this multiplexing UI. This
|
||||
* allows processing of the UIs by an application aware of multiplexing
|
||||
* UIs on components.
|
||||
*
|
||||
* @return an array of the UI delegates
|
||||
*/
|
||||
public ComponentUI[] getUIs() {
|
||||
return MultiLookAndFeel.uisToArray(uis);
|
||||
@ -103,6 +105,9 @@ public class MultiMenuItemUI extends MenuItemUI {
|
||||
* Returns a multiplexing UI instance if any of the auxiliary
|
||||
* <code>LookAndFeel</code>s supports this UI. Otherwise, just returns the
|
||||
* UI object obtained from the default <code>LookAndFeel</code>.
|
||||
*
|
||||
* @param a the component to create the UI for
|
||||
* @return the UI delegate created
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent a) {
|
||||
ComponentUI mui = new MultiMenuItemUI();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, 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,8 @@ public class MultiOptionPaneUI extends OptionPaneUI {
|
||||
* Returns the list of UIs associated with this multiplexing UI. This
|
||||
* allows processing of the UIs by an application aware of multiplexing
|
||||
* UIs on components.
|
||||
*
|
||||
* @return an array of the UI delegates
|
||||
*/
|
||||
public ComponentUI[] getUIs() {
|
||||
return MultiLookAndFeel.uisToArray(uis);
|
||||
@ -123,6 +125,9 @@ public class MultiOptionPaneUI extends OptionPaneUI {
|
||||
* Returns a multiplexing UI instance if any of the auxiliary
|
||||
* <code>LookAndFeel</code>s supports this UI. Otherwise, just returns the
|
||||
* UI object obtained from the default <code>LookAndFeel</code>.
|
||||
*
|
||||
* @param a the component to create the UI for
|
||||
* @return the UI delegate created
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent a) {
|
||||
ComponentUI mui = new MultiOptionPaneUI();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2014, 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,8 @@ public class MultiPanelUI extends PanelUI {
|
||||
* Returns the list of UIs associated with this multiplexing UI. This
|
||||
* allows processing of the UIs by an application aware of multiplexing
|
||||
* UIs on components.
|
||||
*
|
||||
* @return an array of the UI delegates
|
||||
*/
|
||||
public ComponentUI[] getUIs() {
|
||||
return MultiLookAndFeel.uisToArray(uis);
|
||||
@ -98,6 +100,9 @@ public class MultiPanelUI extends PanelUI {
|
||||
* Returns a multiplexing UI instance if any of the auxiliary
|
||||
* <code>LookAndFeel</code>s supports this UI. Otherwise, just returns the
|
||||
* UI object obtained from the default <code>LookAndFeel</code>.
|
||||
*
|
||||
* @param a the component to create the UI for
|
||||
* @return the UI delegate created
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent a) {
|
||||
ComponentUI mui = new MultiPanelUI();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, 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
|
||||
@ -60,6 +60,8 @@ public class MultiPopupMenuUI extends PopupMenuUI {
|
||||
* Returns the list of UIs associated with this multiplexing UI. This
|
||||
* allows processing of the UIs by an application aware of multiplexing
|
||||
* UIs on components.
|
||||
*
|
||||
* @return an array of the UI delegates
|
||||
*/
|
||||
public ComponentUI[] getUIs() {
|
||||
return MultiLookAndFeel.uisToArray(uis);
|
||||
@ -133,6 +135,9 @@ public class MultiPopupMenuUI extends PopupMenuUI {
|
||||
* Returns a multiplexing UI instance if any of the auxiliary
|
||||
* <code>LookAndFeel</code>s supports this UI. Otherwise, just returns the
|
||||
* UI object obtained from the default <code>LookAndFeel</code>.
|
||||
*
|
||||
* @param a the component to create the UI for
|
||||
* @return the UI delegate created
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent a) {
|
||||
ComponentUI mui = new MultiPopupMenuUI();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, 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,8 @@ public class MultiProgressBarUI extends ProgressBarUI {
|
||||
* Returns the list of UIs associated with this multiplexing UI. This
|
||||
* allows processing of the UIs by an application aware of multiplexing
|
||||
* UIs on components.
|
||||
*
|
||||
* @return an array of the UI delegates
|
||||
*/
|
||||
public ComponentUI[] getUIs() {
|
||||
return MultiLookAndFeel.uisToArray(uis);
|
||||
@ -98,6 +100,9 @@ public class MultiProgressBarUI extends ProgressBarUI {
|
||||
* Returns a multiplexing UI instance if any of the auxiliary
|
||||
* <code>LookAndFeel</code>s supports this UI. Otherwise, just returns the
|
||||
* UI object obtained from the default <code>LookAndFeel</code>.
|
||||
*
|
||||
* @param a the component to create the UI for
|
||||
* @return the UI delegate created
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent a) {
|
||||
ComponentUI mui = new MultiProgressBarUI();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2014, 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,8 @@ public class MultiRootPaneUI extends RootPaneUI {
|
||||
* Returns the list of UIs associated with this multiplexing UI. This
|
||||
* allows processing of the UIs by an application aware of multiplexing
|
||||
* UIs on components.
|
||||
*
|
||||
* @return an array of the UI delegates
|
||||
*/
|
||||
public ComponentUI[] getUIs() {
|
||||
return MultiLookAndFeel.uisToArray(uis);
|
||||
@ -99,6 +101,9 @@ public class MultiRootPaneUI extends RootPaneUI {
|
||||
* Returns a multiplexing UI instance if any of the auxiliary
|
||||
* <code>LookAndFeel</code>s supports this UI. Otherwise, just returns the
|
||||
* UI object obtained from the default <code>LookAndFeel</code>.
|
||||
*
|
||||
* @param a the component to create the UI for
|
||||
* @return the UI delegate created
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent a) {
|
||||
ComponentUI mui = new MultiRootPaneUI();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, 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,8 @@ public class MultiScrollBarUI extends ScrollBarUI {
|
||||
* Returns the list of UIs associated with this multiplexing UI. This
|
||||
* allows processing of the UIs by an application aware of multiplexing
|
||||
* UIs on components.
|
||||
*
|
||||
* @return an array of the UI delegates
|
||||
*/
|
||||
public ComponentUI[] getUIs() {
|
||||
return MultiLookAndFeel.uisToArray(uis);
|
||||
@ -98,6 +100,9 @@ public class MultiScrollBarUI extends ScrollBarUI {
|
||||
* Returns a multiplexing UI instance if any of the auxiliary
|
||||
* <code>LookAndFeel</code>s supports this UI. Otherwise, just returns the
|
||||
* UI object obtained from the default <code>LookAndFeel</code>.
|
||||
*
|
||||
* @param a the component to create the UI for
|
||||
* @return the UI delegate created
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent a) {
|
||||
ComponentUI mui = new MultiScrollBarUI();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, 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,8 @@ public class MultiScrollPaneUI extends ScrollPaneUI {
|
||||
* Returns the list of UIs associated with this multiplexing UI. This
|
||||
* allows processing of the UIs by an application aware of multiplexing
|
||||
* UIs on components.
|
||||
*
|
||||
* @return an array of the UI delegates
|
||||
*/
|
||||
public ComponentUI[] getUIs() {
|
||||
return MultiLookAndFeel.uisToArray(uis);
|
||||
@ -98,6 +100,9 @@ public class MultiScrollPaneUI extends ScrollPaneUI {
|
||||
* Returns a multiplexing UI instance if any of the auxiliary
|
||||
* <code>LookAndFeel</code>s supports this UI. Otherwise, just returns the
|
||||
* UI object obtained from the default <code>LookAndFeel</code>.
|
||||
*
|
||||
* @param a the component to create the UI for
|
||||
* @return the UI delegate created
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent a) {
|
||||
ComponentUI mui = new MultiScrollPaneUI();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, 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,8 @@ public class MultiSeparatorUI extends SeparatorUI {
|
||||
* Returns the list of UIs associated with this multiplexing UI. This
|
||||
* allows processing of the UIs by an application aware of multiplexing
|
||||
* UIs on components.
|
||||
*
|
||||
* @return an array of the UI delegates
|
||||
*/
|
||||
public ComponentUI[] getUIs() {
|
||||
return MultiLookAndFeel.uisToArray(uis);
|
||||
@ -98,6 +100,9 @@ public class MultiSeparatorUI extends SeparatorUI {
|
||||
* Returns a multiplexing UI instance if any of the auxiliary
|
||||
* <code>LookAndFeel</code>s supports this UI. Otherwise, just returns the
|
||||
* UI object obtained from the default <code>LookAndFeel</code>.
|
||||
*
|
||||
* @param a the component to create the UI for
|
||||
* @return the UI delegate created
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent a) {
|
||||
ComponentUI mui = new MultiSeparatorUI();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, 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,8 @@ public class MultiSliderUI extends SliderUI {
|
||||
* Returns the list of UIs associated with this multiplexing UI. This
|
||||
* allows processing of the UIs by an application aware of multiplexing
|
||||
* UIs on components.
|
||||
*
|
||||
* @return an array of the UI delegates
|
||||
*/
|
||||
public ComponentUI[] getUIs() {
|
||||
return MultiLookAndFeel.uisToArray(uis);
|
||||
@ -96,8 +98,11 @@ public class MultiSliderUI extends SliderUI {
|
||||
|
||||
/**
|
||||
* Returns a multiplexing UI instance if any of the auxiliary
|
||||
* <code>LookAndFeel</code>s supports this UI. Otherwise, just returns the
|
||||
* <code>LookAndFeel</code>s supports this UI. Otherwise, just returns the
|
||||
* UI object obtained from the default <code>LookAndFeel</code>.
|
||||
*
|
||||
* @param a the component to create the UI for
|
||||
* @return the UI delegate created
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent a) {
|
||||
ComponentUI mui = new MultiSliderUI();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2006, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2014, 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,8 @@ public class MultiSpinnerUI extends SpinnerUI {
|
||||
* Returns the list of UIs associated with this multiplexing UI. This
|
||||
* allows processing of the UIs by an application aware of multiplexing
|
||||
* UIs on components.
|
||||
*
|
||||
* @return an array of the UI delegates
|
||||
*/
|
||||
public ComponentUI[] getUIs() {
|
||||
return MultiLookAndFeel.uisToArray(uis);
|
||||
@ -99,6 +101,9 @@ public class MultiSpinnerUI extends SpinnerUI {
|
||||
* Returns a multiplexing UI instance if any of the auxiliary
|
||||
* <code>LookAndFeel</code>s supports this UI. Otherwise, just returns the
|
||||
* UI object obtained from the default <code>LookAndFeel</code>.
|
||||
*
|
||||
* @param a the component to create the UI for
|
||||
* @return the UI delegate created
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent a) {
|
||||
ComponentUI mui = new MultiSpinnerUI();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, 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,8 @@ public class MultiSplitPaneUI extends SplitPaneUI {
|
||||
* Returns the list of UIs associated with this multiplexing UI. This
|
||||
* allows processing of the UIs by an application aware of multiplexing
|
||||
* UIs on components.
|
||||
*
|
||||
* @return an array of the UI delegates
|
||||
*/
|
||||
public ComponentUI[] getUIs() {
|
||||
return MultiLookAndFeel.uisToArray(uis);
|
||||
@ -171,6 +173,9 @@ public class MultiSplitPaneUI extends SplitPaneUI {
|
||||
* Returns a multiplexing UI instance if any of the auxiliary
|
||||
* <code>LookAndFeel</code>s supports this UI. Otherwise, just returns the
|
||||
* UI object obtained from the default <code>LookAndFeel</code>.
|
||||
*
|
||||
* @param a the component to create the UI for
|
||||
* @return the UI delegate created
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent a) {
|
||||
ComponentUI mui = new MultiSplitPaneUI();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, 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
|
||||
@ -59,6 +59,8 @@ public class MultiTabbedPaneUI extends TabbedPaneUI {
|
||||
* Returns the list of UIs associated with this multiplexing UI. This
|
||||
* allows processing of the UIs by an application aware of multiplexing
|
||||
* UIs on components.
|
||||
*
|
||||
* @return an array of the UI delegates
|
||||
*/
|
||||
public ComponentUI[] getUIs() {
|
||||
return MultiLookAndFeel.uisToArray(uis);
|
||||
@ -145,6 +147,9 @@ public class MultiTabbedPaneUI extends TabbedPaneUI {
|
||||
* Returns a multiplexing UI instance if any of the auxiliary
|
||||
* <code>LookAndFeel</code>s supports this UI. Otherwise, just returns the
|
||||
* UI object obtained from the default <code>LookAndFeel</code>.
|
||||
*
|
||||
* @param a the component to create the UI for
|
||||
* @return the UI delegate created
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent a) {
|
||||
ComponentUI mui = new MultiTabbedPaneUI();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, 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,8 @@ public class MultiTableHeaderUI extends TableHeaderUI {
|
||||
* Returns the list of UIs associated with this multiplexing UI. This
|
||||
* allows processing of the UIs by an application aware of multiplexing
|
||||
* UIs on components.
|
||||
*
|
||||
* @return an array of the UI delegates
|
||||
*/
|
||||
public ComponentUI[] getUIs() {
|
||||
return MultiLookAndFeel.uisToArray(uis);
|
||||
@ -98,6 +100,9 @@ public class MultiTableHeaderUI extends TableHeaderUI {
|
||||
* Returns a multiplexing UI instance if any of the auxiliary
|
||||
* <code>LookAndFeel</code>s supports this UI. Otherwise, just returns the
|
||||
* UI object obtained from the default <code>LookAndFeel</code>.
|
||||
*
|
||||
* @param a the component to create the UI for
|
||||
* @return the UI delegate created
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent a) {
|
||||
ComponentUI mui = new MultiTableHeaderUI();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, 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,8 @@ public class MultiTableUI extends TableUI {
|
||||
* Returns the list of UIs associated with this multiplexing UI. This
|
||||
* allows processing of the UIs by an application aware of multiplexing
|
||||
* UIs on components.
|
||||
*
|
||||
* @return an array of the UI delegates
|
||||
*/
|
||||
public ComponentUI[] getUIs() {
|
||||
return MultiLookAndFeel.uisToArray(uis);
|
||||
@ -98,6 +100,9 @@ public class MultiTableUI extends TableUI {
|
||||
* Returns a multiplexing UI instance if any of the auxiliary
|
||||
* <code>LookAndFeel</code>s supports this UI. Otherwise, just returns the
|
||||
* UI object obtained from the default <code>LookAndFeel</code>.
|
||||
*
|
||||
* @param a the component to create the UI for
|
||||
* @return the UI delegate created
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent a) {
|
||||
ComponentUI mui = new MultiTableUI();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, 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
|
||||
@ -65,6 +65,8 @@ public class MultiTextUI extends TextUI {
|
||||
* Returns the list of UIs associated with this multiplexing UI. This
|
||||
* allows processing of the UIs by an application aware of multiplexing
|
||||
* UIs on components.
|
||||
*
|
||||
* @return an array of the UI delegates
|
||||
*/
|
||||
public ComponentUI[] getUIs() {
|
||||
return MultiLookAndFeel.uisToArray(uis);
|
||||
@ -248,6 +250,9 @@ public class MultiTextUI extends TextUI {
|
||||
* Returns a multiplexing UI instance if any of the auxiliary
|
||||
* <code>LookAndFeel</code>s supports this UI. Otherwise, just returns the
|
||||
* UI object obtained from the default <code>LookAndFeel</code>.
|
||||
*
|
||||
* @param a the component to create the UI for
|
||||
* @return the UI delegate created
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent a) {
|
||||
ComponentUI mui = new MultiTextUI();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, 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,8 @@ public class MultiToolBarUI extends ToolBarUI {
|
||||
* Returns the list of UIs associated with this multiplexing UI. This
|
||||
* allows processing of the UIs by an application aware of multiplexing
|
||||
* UIs on components.
|
||||
*
|
||||
* @return an array of the UI delegates
|
||||
*/
|
||||
public ComponentUI[] getUIs() {
|
||||
return MultiLookAndFeel.uisToArray(uis);
|
||||
@ -98,6 +100,9 @@ public class MultiToolBarUI extends ToolBarUI {
|
||||
* Returns a multiplexing UI instance if any of the auxiliary
|
||||
* <code>LookAndFeel</code>s supports this UI. Otherwise, just returns the
|
||||
* UI object obtained from the default <code>LookAndFeel</code>.
|
||||
*
|
||||
* @param a the component to create the UI for
|
||||
* @return the UI delegate created
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent a) {
|
||||
ComponentUI mui = new MultiToolBarUI();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, 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,8 @@ public class MultiToolTipUI extends ToolTipUI {
|
||||
* Returns the list of UIs associated with this multiplexing UI. This
|
||||
* allows processing of the UIs by an application aware of multiplexing
|
||||
* UIs on components.
|
||||
*
|
||||
* @return an array of the UI delegates
|
||||
*/
|
||||
public ComponentUI[] getUIs() {
|
||||
return MultiLookAndFeel.uisToArray(uis);
|
||||
@ -98,6 +100,9 @@ public class MultiToolTipUI extends ToolTipUI {
|
||||
* Returns a multiplexing UI instance if any of the auxiliary
|
||||
* <code>LookAndFeel</code>s supports this UI. Otherwise, just returns the
|
||||
* UI object obtained from the default <code>LookAndFeel</code>.
|
||||
*
|
||||
* @param a the component to create the UI for
|
||||
* @return the UI delegate created
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent a) {
|
||||
ComponentUI mui = new MultiToolTipUI();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, 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
|
||||
@ -60,6 +60,8 @@ public class MultiTreeUI extends TreeUI {
|
||||
* Returns the list of UIs associated with this multiplexing UI. This
|
||||
* allows processing of the UIs by an application aware of multiplexing
|
||||
* UIs on components.
|
||||
*
|
||||
* @return an array of the UI delegates
|
||||
*/
|
||||
public ComponentUI[] getUIs() {
|
||||
return MultiLookAndFeel.uisToArray(uis);
|
||||
@ -239,6 +241,9 @@ public class MultiTreeUI extends TreeUI {
|
||||
* Returns a multiplexing UI instance if any of the auxiliary
|
||||
* <code>LookAndFeel</code>s supports this UI. Otherwise, just returns the
|
||||
* UI object obtained from the default <code>LookAndFeel</code>.
|
||||
*
|
||||
* @param a the component to create the UI for
|
||||
* @return the UI delegate created
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent a) {
|
||||
ComponentUI mui = new MultiTreeUI();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2014, 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,8 @@ public class MultiViewportUI extends ViewportUI {
|
||||
* Returns the list of UIs associated with this multiplexing UI. This
|
||||
* allows processing of the UIs by an application aware of multiplexing
|
||||
* UIs on components.
|
||||
*
|
||||
* @return an array of the UI delegates
|
||||
*/
|
||||
public ComponentUI[] getUIs() {
|
||||
return MultiLookAndFeel.uisToArray(uis);
|
||||
@ -98,6 +100,9 @@ public class MultiViewportUI extends ViewportUI {
|
||||
* Returns a multiplexing UI instance if any of the auxiliary
|
||||
* <code>LookAndFeel</code>s supports this UI. Otherwise, just returns the
|
||||
* UI object obtained from the default <code>LookAndFeel</code>.
|
||||
*
|
||||
* @param a the component to create the UI for
|
||||
* @return the UI delegate created
|
||||
*/
|
||||
public static ComponentUI createUI(JComponent a) {
|
||||
ComponentUI mui = new MultiViewportUI();
|
||||
|
||||
@ -417,6 +417,11 @@ public class BlockView extends BoxView {
|
||||
cssHeight = (CSS.LengthValue) attr.getAttribute(CSS.Attribute.HEIGHT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenient method to get the StyleSheet.
|
||||
*
|
||||
* @return the StyleSheet
|
||||
*/
|
||||
protected StyleSheet getStyleSheet() {
|
||||
HTMLDocument doc = (HTMLDocument) getDocument();
|
||||
return doc.getStyleSheet();
|
||||
|
||||
@ -175,144 +175,285 @@ public class CSS implements Serializable {
|
||||
private boolean inherited;
|
||||
|
||||
|
||||
/**
|
||||
* CSS attribute "background".
|
||||
*/
|
||||
public static final Attribute BACKGROUND =
|
||||
new Attribute("background", null, false);
|
||||
|
||||
/**
|
||||
* CSS attribute "background-attachment".
|
||||
*/
|
||||
public static final Attribute BACKGROUND_ATTACHMENT =
|
||||
new Attribute("background-attachment", "scroll", false);
|
||||
|
||||
/**
|
||||
* CSS attribute "background-color".
|
||||
*/
|
||||
public static final Attribute BACKGROUND_COLOR =
|
||||
new Attribute("background-color", "transparent", false);
|
||||
|
||||
/**
|
||||
* CSS attribute "background-image".
|
||||
*/
|
||||
public static final Attribute BACKGROUND_IMAGE =
|
||||
new Attribute("background-image", "none", false);
|
||||
|
||||
/**
|
||||
* CSS attribute "background-position".
|
||||
*/
|
||||
public static final Attribute BACKGROUND_POSITION =
|
||||
new Attribute("background-position", null, false);
|
||||
|
||||
/**
|
||||
* CSS attribute "background-repeat".
|
||||
*/
|
||||
public static final Attribute BACKGROUND_REPEAT =
|
||||
new Attribute("background-repeat", "repeat", false);
|
||||
|
||||
/**
|
||||
* CSS attribute "border".
|
||||
*/
|
||||
public static final Attribute BORDER =
|
||||
new Attribute("border", null, false);
|
||||
|
||||
/**
|
||||
* CSS attribute "border-bottom".
|
||||
*/
|
||||
public static final Attribute BORDER_BOTTOM =
|
||||
new Attribute("border-bottom", null, false);
|
||||
|
||||
/**
|
||||
* CSS attribute "border-bottom-color".
|
||||
*/
|
||||
public static final Attribute BORDER_BOTTOM_COLOR =
|
||||
new Attribute("border-bottom-color", null, false);
|
||||
|
||||
/**
|
||||
* CSS attribute "border-bottom-style".
|
||||
*/
|
||||
public static final Attribute BORDER_BOTTOM_STYLE =
|
||||
new Attribute("border-bottom-style", "none", false);
|
||||
|
||||
/**
|
||||
* CSS attribute "border-bottom-width".
|
||||
*/
|
||||
public static final Attribute BORDER_BOTTOM_WIDTH =
|
||||
new Attribute("border-bottom-width", "medium", false);
|
||||
|
||||
/**
|
||||
* CSS attribute "border-color".
|
||||
*/
|
||||
public static final Attribute BORDER_COLOR =
|
||||
new Attribute("border-color", null, false);
|
||||
|
||||
/**
|
||||
* CSS attribute "border-left".
|
||||
*/
|
||||
public static final Attribute BORDER_LEFT =
|
||||
new Attribute("border-left", null, false);
|
||||
|
||||
/**
|
||||
* CSS attribute "margin-right".
|
||||
*/
|
||||
public static final Attribute BORDER_LEFT_COLOR =
|
||||
new Attribute("border-left-color", null, false);
|
||||
|
||||
/**
|
||||
* CSS attribute "border-left-style".
|
||||
*/
|
||||
public static final Attribute BORDER_LEFT_STYLE =
|
||||
new Attribute("border-left-style", "none", false);
|
||||
|
||||
/**
|
||||
* CSS attribute "border-left-width".
|
||||
*/
|
||||
public static final Attribute BORDER_LEFT_WIDTH =
|
||||
new Attribute("border-left-width", "medium", false);
|
||||
|
||||
/**
|
||||
* CSS attribute "border-right".
|
||||
*/
|
||||
public static final Attribute BORDER_RIGHT =
|
||||
new Attribute("border-right", null, false);
|
||||
|
||||
/**
|
||||
* CSS attribute "border-right-color".
|
||||
*/
|
||||
public static final Attribute BORDER_RIGHT_COLOR =
|
||||
new Attribute("border-right-color", null, false);
|
||||
|
||||
/**
|
||||
* CSS attribute "border-right-style".
|
||||
*/
|
||||
public static final Attribute BORDER_RIGHT_STYLE =
|
||||
new Attribute("border-right-style", "none", false);
|
||||
|
||||
/**
|
||||
* CSS attribute "border-right-width".
|
||||
*/
|
||||
public static final Attribute BORDER_RIGHT_WIDTH =
|
||||
new Attribute("border-right-width", "medium", false);
|
||||
|
||||
/**
|
||||
* CSS attribute "border-style".
|
||||
*/
|
||||
public static final Attribute BORDER_STYLE =
|
||||
new Attribute("border-style", "none", false);
|
||||
|
||||
/**
|
||||
* CSS attribute "border-top".
|
||||
*/
|
||||
public static final Attribute BORDER_TOP =
|
||||
new Attribute("border-top", null, false);
|
||||
|
||||
/**
|
||||
* CSS attribute "border-top-color".
|
||||
*/
|
||||
public static final Attribute BORDER_TOP_COLOR =
|
||||
new Attribute("border-top-color", null, false);
|
||||
|
||||
/**
|
||||
* CSS attribute "border-top-style".
|
||||
*/
|
||||
public static final Attribute BORDER_TOP_STYLE =
|
||||
new Attribute("border-top-style", "none", false);
|
||||
|
||||
/**
|
||||
* CSS attribute "border-top-width".
|
||||
*/
|
||||
public static final Attribute BORDER_TOP_WIDTH =
|
||||
new Attribute("border-top-width", "medium", false);
|
||||
|
||||
/**
|
||||
* CSS attribute "border-width".
|
||||
*/
|
||||
public static final Attribute BORDER_WIDTH =
|
||||
new Attribute("border-width", "medium", false);
|
||||
|
||||
/**
|
||||
* CSS attribute "clear".
|
||||
*/
|
||||
public static final Attribute CLEAR =
|
||||
new Attribute("clear", "none", false);
|
||||
|
||||
/**
|
||||
* CSS attribute "color".
|
||||
*/
|
||||
public static final Attribute COLOR =
|
||||
new Attribute("color", "black", true);
|
||||
|
||||
/**
|
||||
* CSS attribute "display".
|
||||
*/
|
||||
public static final Attribute DISPLAY =
|
||||
new Attribute("display", "block", false);
|
||||
|
||||
/**
|
||||
* CSS attribute "float".
|
||||
*/
|
||||
public static final Attribute FLOAT =
|
||||
new Attribute("float", "none", false);
|
||||
|
||||
/**
|
||||
* CSS attribute "font".
|
||||
*/
|
||||
public static final Attribute FONT =
|
||||
new Attribute("font", null, true);
|
||||
|
||||
/**
|
||||
* CSS attribute "font-family".
|
||||
*/
|
||||
public static final Attribute FONT_FAMILY =
|
||||
new Attribute("font-family", null, true);
|
||||
|
||||
/**
|
||||
* CSS attribute "font-size".
|
||||
*/
|
||||
public static final Attribute FONT_SIZE =
|
||||
new Attribute("font-size", "medium", true);
|
||||
|
||||
/**
|
||||
* CSS attribute "font-style".
|
||||
*/
|
||||
public static final Attribute FONT_STYLE =
|
||||
new Attribute("font-style", "normal", true);
|
||||
|
||||
/**
|
||||
* CSS attribute "font-variant".
|
||||
*/
|
||||
public static final Attribute FONT_VARIANT =
|
||||
new Attribute("font-variant", "normal", true);
|
||||
|
||||
/**
|
||||
* CSS attribute "font-weight".
|
||||
*/
|
||||
public static final Attribute FONT_WEIGHT =
|
||||
new Attribute("font-weight", "normal", true);
|
||||
|
||||
/**
|
||||
* CSS attribute "height".
|
||||
*/
|
||||
public static final Attribute HEIGHT =
|
||||
new Attribute("height", "auto", false);
|
||||
|
||||
/**
|
||||
* CSS attribute "letter-spacing".
|
||||
*/
|
||||
public static final Attribute LETTER_SPACING =
|
||||
new Attribute("letter-spacing", "normal", true);
|
||||
|
||||
/**
|
||||
* CSS attribute "line-height".
|
||||
*/
|
||||
public static final Attribute LINE_HEIGHT =
|
||||
new Attribute("line-height", "normal", true);
|
||||
|
||||
/**
|
||||
* CSS attribute "list-style".
|
||||
*/
|
||||
public static final Attribute LIST_STYLE =
|
||||
new Attribute("list-style", null, true);
|
||||
|
||||
/**
|
||||
* CSS attribute "list-style-image".
|
||||
*/
|
||||
public static final Attribute LIST_STYLE_IMAGE =
|
||||
new Attribute("list-style-image", "none", true);
|
||||
|
||||
/**
|
||||
* CSS attribute "list-style-position".
|
||||
*/
|
||||
public static final Attribute LIST_STYLE_POSITION =
|
||||
new Attribute("list-style-position", "outside", true);
|
||||
|
||||
/**
|
||||
* CSS attribute "list-style-type".
|
||||
*/
|
||||
public static final Attribute LIST_STYLE_TYPE =
|
||||
new Attribute("list-style-type", "disc", true);
|
||||
|
||||
/**
|
||||
* CSS attribute "margin".
|
||||
*/
|
||||
public static final Attribute MARGIN =
|
||||
new Attribute("margin", null, false);
|
||||
|
||||
/**
|
||||
* CSS attribute "margin-bottom".
|
||||
*/
|
||||
public static final Attribute MARGIN_BOTTOM =
|
||||
new Attribute("margin-bottom", "0", false);
|
||||
|
||||
/**
|
||||
* CSS attribute "margin-left".
|
||||
*/
|
||||
public static final Attribute MARGIN_LEFT =
|
||||
new Attribute("margin-left", "0", false);
|
||||
|
||||
/**
|
||||
* CSS attribute "margin-right".
|
||||
*/
|
||||
public static final Attribute MARGIN_RIGHT =
|
||||
new Attribute("margin-right", "0", false);
|
||||
|
||||
@ -338,45 +479,87 @@ public class CSS implements Serializable {
|
||||
Integer.toString(Integer.MIN_VALUE), false);
|
||||
|
||||
|
||||
/**
|
||||
* CSS attribute "margin-top".
|
||||
*/
|
||||
public static final Attribute MARGIN_TOP =
|
||||
new Attribute("margin-top", "0", false);
|
||||
|
||||
/**
|
||||
* CSS attribute "padding".
|
||||
*/
|
||||
public static final Attribute PADDING =
|
||||
new Attribute("padding", null, false);
|
||||
|
||||
/**
|
||||
* CSS attribute "padding-bottom".
|
||||
*/
|
||||
public static final Attribute PADDING_BOTTOM =
|
||||
new Attribute("padding-bottom", "0", false);
|
||||
|
||||
/**
|
||||
* CSS attribute "padding-left".
|
||||
*/
|
||||
public static final Attribute PADDING_LEFT =
|
||||
new Attribute("padding-left", "0", false);
|
||||
|
||||
/**
|
||||
* CSS attribute "padding-right".
|
||||
*/
|
||||
public static final Attribute PADDING_RIGHT =
|
||||
new Attribute("padding-right", "0", false);
|
||||
|
||||
/**
|
||||
* CSS attribute "padding-top".
|
||||
*/
|
||||
public static final Attribute PADDING_TOP =
|
||||
new Attribute("padding-top", "0", false);
|
||||
|
||||
/**
|
||||
* CSS attribute "text-align".
|
||||
*/
|
||||
public static final Attribute TEXT_ALIGN =
|
||||
new Attribute("text-align", null, true);
|
||||
|
||||
/**
|
||||
* CSS attribute "text-decoration".
|
||||
*/
|
||||
public static final Attribute TEXT_DECORATION =
|
||||
new Attribute("text-decoration", "none", true);
|
||||
|
||||
/**
|
||||
* CSS attribute "text-indent".
|
||||
*/
|
||||
public static final Attribute TEXT_INDENT =
|
||||
new Attribute("text-indent", "0", true);
|
||||
|
||||
/**
|
||||
* CSS attribute "text-transform".
|
||||
*/
|
||||
public static final Attribute TEXT_TRANSFORM =
|
||||
new Attribute("text-transform", "none", true);
|
||||
|
||||
/**
|
||||
* CSS attribute "vertical-align".
|
||||
*/
|
||||
public static final Attribute VERTICAL_ALIGN =
|
||||
new Attribute("vertical-align", "baseline", false);
|
||||
|
||||
/**
|
||||
* CSS attribute "word-spacing".
|
||||
*/
|
||||
public static final Attribute WORD_SPACING =
|
||||
new Attribute("word-spacing", "normal", true);
|
||||
|
||||
/**
|
||||
* CSS attribute "white-space".
|
||||
*/
|
||||
public static final Attribute WHITE_SPACE =
|
||||
new Attribute("white-space", "normal", true);
|
||||
|
||||
/**
|
||||
* CSS attribute "width".
|
||||
*/
|
||||
public static final Attribute WIDTH =
|
||||
new Attribute("width", "auto", false);
|
||||
|
||||
@ -480,6 +663,9 @@ public class CSS implements Serializable {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a CSS object.
|
||||
*/
|
||||
public CSS() {
|
||||
baseFontSize = baseFontSizeIndex + 1;
|
||||
// setup the css conversion table
|
||||
|
||||
@ -40,19 +40,30 @@ public class FormSubmitEvent extends HTMLFrameHyperlinkEvent {
|
||||
/**
|
||||
* Represents an HTML form method type.
|
||||
* <UL>
|
||||
* <LI><code>GET</code> corresponds to the GET form method</LI>
|
||||
* <LI><code>POST</code> corresponds to the POST from method</LI>
|
||||
* <LI>{@code GET} corresponds to the GET form method</LI>
|
||||
* <LI>{@code POST} corresponds to the POST from method</LI>
|
||||
* </UL>
|
||||
* @since 1.5
|
||||
*/
|
||||
public enum MethodType { GET, POST };
|
||||
public enum MethodType {
|
||||
|
||||
/**
|
||||
* {@code GET} corresponds to the GET form method
|
||||
*/
|
||||
GET,
|
||||
|
||||
/**
|
||||
* {@code POST} corresponds to the POST from method
|
||||
*/
|
||||
POST
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new object representing an html form submit event.
|
||||
*
|
||||
* @param source the object responsible for the event
|
||||
* @param type the event type
|
||||
* @param actionURL the form action URL
|
||||
* @param targetURL the form action URL
|
||||
* @param sourceElement the element that corresponds to the source
|
||||
* of the event
|
||||
* @param targetFrame the Frame to display the document in
|
||||
|
||||
@ -156,79 +156,369 @@ public class HTML {
|
||||
|
||||
// --- Tag Names -----------------------------------
|
||||
|
||||
/**
|
||||
* Tag <a>
|
||||
*/
|
||||
public static final Tag A = new Tag("a");
|
||||
|
||||
/**
|
||||
* Tag <address>
|
||||
*/
|
||||
public static final Tag ADDRESS = new Tag("address");
|
||||
/**
|
||||
* Tag <applet>
|
||||
*/
|
||||
public static final Tag APPLET = new Tag("applet");
|
||||
|
||||
/**
|
||||
* Tag <area>
|
||||
*/
|
||||
public static final Tag AREA = new Tag("area");
|
||||
|
||||
/**
|
||||
* Tag <b>
|
||||
*/
|
||||
public static final Tag B = new Tag("b");
|
||||
|
||||
/**
|
||||
* Tag <base>
|
||||
*/
|
||||
public static final Tag BASE = new Tag("base");
|
||||
|
||||
/**
|
||||
* Tag <basefont>
|
||||
*/
|
||||
public static final Tag BASEFONT = new Tag("basefont");
|
||||
|
||||
/**
|
||||
* Tag <big>
|
||||
*/
|
||||
public static final Tag BIG = new Tag("big");
|
||||
|
||||
/**
|
||||
* Tag <blockquote>
|
||||
*/
|
||||
public static final Tag BLOCKQUOTE = new Tag("blockquote", true, true);
|
||||
|
||||
/**
|
||||
* Tag <body>
|
||||
*/
|
||||
public static final Tag BODY = new Tag("body", true, true);
|
||||
|
||||
/**
|
||||
* Tag <br>
|
||||
*/
|
||||
public static final Tag BR = new Tag("br", true, false);
|
||||
|
||||
/**
|
||||
* Tag <caption>
|
||||
*/
|
||||
public static final Tag CAPTION = new Tag("caption");
|
||||
|
||||
/**
|
||||
* Tag <center>
|
||||
*/
|
||||
public static final Tag CENTER = new Tag("center", true, false);
|
||||
|
||||
/**
|
||||
* Tag <cite>
|
||||
*/
|
||||
public static final Tag CITE = new Tag("cite");
|
||||
|
||||
/**
|
||||
* Tag <code>
|
||||
*/
|
||||
public static final Tag CODE = new Tag("code");
|
||||
|
||||
/**
|
||||
* Tag <dd>
|
||||
*/
|
||||
public static final Tag DD = new Tag("dd", true, true);
|
||||
|
||||
/**
|
||||
* Tag <dfn>
|
||||
*/
|
||||
public static final Tag DFN = new Tag("dfn");
|
||||
|
||||
/**
|
||||
* Tag <dir>
|
||||
*/
|
||||
public static final Tag DIR = new Tag("dir", true, true);
|
||||
|
||||
/**
|
||||
* Tag <div>
|
||||
*/
|
||||
public static final Tag DIV = new Tag("div", true, true);
|
||||
|
||||
/**
|
||||
* Tag <dl>
|
||||
*/
|
||||
public static final Tag DL = new Tag("dl", true, true);
|
||||
|
||||
/**
|
||||
* Tag <dt>
|
||||
*/
|
||||
public static final Tag DT = new Tag("dt", true, true);
|
||||
|
||||
/**
|
||||
* Tag <em>
|
||||
*/
|
||||
public static final Tag EM = new Tag("em");
|
||||
|
||||
/**
|
||||
* Tag <font>
|
||||
*/
|
||||
public static final Tag FONT = new Tag("font");
|
||||
|
||||
/**
|
||||
* Tag <form>
|
||||
*/
|
||||
public static final Tag FORM = new Tag("form", true, false);
|
||||
|
||||
/**
|
||||
* Tag <frame>
|
||||
*/
|
||||
public static final Tag FRAME = new Tag("frame");
|
||||
|
||||
/**
|
||||
* Tag <frameset>
|
||||
*/
|
||||
public static final Tag FRAMESET = new Tag("frameset");
|
||||
|
||||
/**
|
||||
* Tag <h1>
|
||||
*/
|
||||
public static final Tag H1 = new Tag("h1", true, true);
|
||||
|
||||
/**
|
||||
* Tag <h2>
|
||||
*/
|
||||
public static final Tag H2 = new Tag("h2", true, true);
|
||||
|
||||
/**
|
||||
* Tag <h3>
|
||||
*/
|
||||
public static final Tag H3 = new Tag("h3", true, true);
|
||||
|
||||
/**
|
||||
* Tag <h4>
|
||||
*/
|
||||
public static final Tag H4 = new Tag("h4", true, true);
|
||||
|
||||
/**
|
||||
* Tag <h5>
|
||||
*/
|
||||
public static final Tag H5 = new Tag("h5", true, true);
|
||||
|
||||
/**
|
||||
* Tag <h6>
|
||||
*/
|
||||
public static final Tag H6 = new Tag("h6", true, true);
|
||||
|
||||
/**
|
||||
* Tag <head>
|
||||
*/
|
||||
public static final Tag HEAD = new Tag("head", true, true);
|
||||
|
||||
/**
|
||||
* Tag <hr>
|
||||
*/
|
||||
public static final Tag HR = new Tag("hr", true, false);
|
||||
|
||||
/**
|
||||
* Tag <html>
|
||||
*/
|
||||
public static final Tag HTML = new Tag("html", true, false);
|
||||
|
||||
/**
|
||||
* Tag <i>
|
||||
*/
|
||||
public static final Tag I = new Tag("i");
|
||||
|
||||
/**
|
||||
* Tag <img>
|
||||
*/
|
||||
public static final Tag IMG = new Tag("img");
|
||||
|
||||
/**
|
||||
* Tag <input>
|
||||
*/
|
||||
public static final Tag INPUT = new Tag("input");
|
||||
|
||||
/**
|
||||
* Tag <isindex>
|
||||
*/
|
||||
public static final Tag ISINDEX = new Tag("isindex", true, false);
|
||||
|
||||
/**
|
||||
* Tag <kbd>
|
||||
*/
|
||||
public static final Tag KBD = new Tag("kbd");
|
||||
|
||||
/**
|
||||
* Tag <li>
|
||||
*/
|
||||
public static final Tag LI = new Tag("li", true, true);
|
||||
|
||||
/**
|
||||
* Tag <link>
|
||||
*/
|
||||
public static final Tag LINK = new Tag("link");
|
||||
|
||||
/**
|
||||
* Tag <map>
|
||||
*/
|
||||
public static final Tag MAP = new Tag("map");
|
||||
|
||||
/**
|
||||
* Tag <menu>
|
||||
*/
|
||||
public static final Tag MENU = new Tag("menu", true, true);
|
||||
|
||||
/**
|
||||
* Tag <meta>
|
||||
*/
|
||||
public static final Tag META = new Tag("meta");
|
||||
/*public*/ static final Tag NOBR = new Tag("nobr");
|
||||
|
||||
/**
|
||||
* Tag <noframes>
|
||||
*/
|
||||
public static final Tag NOFRAMES = new Tag("noframes", true, true);
|
||||
|
||||
/**
|
||||
* Tag <object>
|
||||
*/
|
||||
public static final Tag OBJECT = new Tag("object");
|
||||
|
||||
/**
|
||||
* Tag <ol>
|
||||
*/
|
||||
public static final Tag OL = new Tag("ol", true, true);
|
||||
|
||||
/**
|
||||
* Tag <option>
|
||||
*/
|
||||
public static final Tag OPTION = new Tag("option");
|
||||
|
||||
/**
|
||||
* Tag <p>
|
||||
*/
|
||||
public static final Tag P = new Tag("p", true, true);
|
||||
|
||||
/**
|
||||
* Tag <param>
|
||||
*/
|
||||
public static final Tag PARAM = new Tag("param");
|
||||
|
||||
/**
|
||||
* Tag <pre>
|
||||
*/
|
||||
public static final Tag PRE = new Tag("pre", true, true);
|
||||
|
||||
/**
|
||||
* Tag <samp>
|
||||
*/
|
||||
public static final Tag SAMP = new Tag("samp");
|
||||
|
||||
/**
|
||||
* Tag <script>
|
||||
*/
|
||||
public static final Tag SCRIPT = new Tag("script");
|
||||
|
||||
/**
|
||||
* Tag <select>
|
||||
*/
|
||||
public static final Tag SELECT = new Tag("select");
|
||||
|
||||
/**
|
||||
* Tag <small>
|
||||
*/
|
||||
public static final Tag SMALL = new Tag("small");
|
||||
|
||||
/**
|
||||
* Tag <span>
|
||||
*/
|
||||
public static final Tag SPAN = new Tag("span");
|
||||
|
||||
/**
|
||||
* Tag <strike>
|
||||
*/
|
||||
public static final Tag STRIKE = new Tag("strike");
|
||||
|
||||
/**
|
||||
* Tag <s>
|
||||
*/
|
||||
public static final Tag S = new Tag("s");
|
||||
|
||||
/**
|
||||
* Tag <strong>
|
||||
*/
|
||||
public static final Tag STRONG = new Tag("strong");
|
||||
|
||||
/**
|
||||
* Tag <style>
|
||||
*/
|
||||
public static final Tag STYLE = new Tag("style");
|
||||
|
||||
/**
|
||||
* Tag <sub>
|
||||
*/
|
||||
public static final Tag SUB = new Tag("sub");
|
||||
|
||||
/**
|
||||
* Tag <sup>
|
||||
*/
|
||||
public static final Tag SUP = new Tag("sup");
|
||||
|
||||
/**
|
||||
* Tag <table>
|
||||
*/
|
||||
public static final Tag TABLE = new Tag("table", false, true);
|
||||
|
||||
/**
|
||||
* Tag <td>
|
||||
*/
|
||||
public static final Tag TD = new Tag("td", true, true);
|
||||
|
||||
/**
|
||||
* Tag <textarea>
|
||||
*/
|
||||
public static final Tag TEXTAREA = new Tag("textarea");
|
||||
|
||||
/**
|
||||
* Tag <th>
|
||||
*/
|
||||
public static final Tag TH = new Tag("th", true, true);
|
||||
|
||||
/**
|
||||
* Tag <title>
|
||||
*/
|
||||
public static final Tag TITLE = new Tag("title", true, true);
|
||||
|
||||
/**
|
||||
* Tag <tr>
|
||||
*/
|
||||
public static final Tag TR = new Tag("tr", false, true);
|
||||
|
||||
/**
|
||||
* Tag <tt>
|
||||
*/
|
||||
public static final Tag TT = new Tag("tt");
|
||||
|
||||
/**
|
||||
* Tag <u>
|
||||
*/
|
||||
public static final Tag U = new Tag("u");
|
||||
|
||||
/**
|
||||
* Tag <ul>
|
||||
*/
|
||||
public static final Tag UL = new Tag("ul", true, true);
|
||||
|
||||
/**
|
||||
* Tag <var>
|
||||
*/
|
||||
public static final Tag VAR = new Tag("var");
|
||||
|
||||
/**
|
||||
@ -281,6 +571,9 @@ public class HTML {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class represents unknown HTML tag.
|
||||
*/
|
||||
// There is no unique instance of UnknownTag, so we allow it to be
|
||||
// Serializable.
|
||||
@SuppressWarnings("serial") // Same-version serialization only
|
||||
@ -365,85 +658,405 @@ public class HTML {
|
||||
|
||||
private String name;
|
||||
|
||||
|
||||
/**
|
||||
* Attribute "size"
|
||||
*/
|
||||
public static final Attribute SIZE = new Attribute("size");
|
||||
|
||||
/**
|
||||
* Attribute "color"
|
||||
*/
|
||||
public static final Attribute COLOR = new Attribute("color");
|
||||
|
||||
/**
|
||||
* Attribute "clear"
|
||||
*/
|
||||
public static final Attribute CLEAR = new Attribute("clear");
|
||||
|
||||
/**
|
||||
* Attribute "background"
|
||||
*/
|
||||
public static final Attribute BACKGROUND = new Attribute("background");
|
||||
|
||||
/**
|
||||
* Attribute "bgcolor"
|
||||
*/
|
||||
public static final Attribute BGCOLOR = new Attribute("bgcolor");
|
||||
|
||||
/**
|
||||
* Attribute "text"
|
||||
*/
|
||||
public static final Attribute TEXT = new Attribute("text");
|
||||
|
||||
/**
|
||||
* Attribute "link"
|
||||
*/
|
||||
public static final Attribute LINK = new Attribute("link");
|
||||
|
||||
/**
|
||||
* Attribute "vlink"
|
||||
*/
|
||||
public static final Attribute VLINK = new Attribute("vlink");
|
||||
|
||||
/**
|
||||
* Attribute "alink"
|
||||
*/
|
||||
public static final Attribute ALINK = new Attribute("alink");
|
||||
|
||||
/**
|
||||
* Attribute "width"
|
||||
*/
|
||||
public static final Attribute WIDTH = new Attribute("width");
|
||||
|
||||
/**
|
||||
* Attribute "height"
|
||||
*/
|
||||
public static final Attribute HEIGHT = new Attribute("height");
|
||||
|
||||
/**
|
||||
* Attribute "align"
|
||||
*/
|
||||
public static final Attribute ALIGN = new Attribute("align");
|
||||
|
||||
/**
|
||||
* Attribute "name"
|
||||
*/
|
||||
public static final Attribute NAME = new Attribute("name");
|
||||
|
||||
/**
|
||||
* Attribute "href"
|
||||
*/
|
||||
public static final Attribute HREF = new Attribute("href");
|
||||
|
||||
/**
|
||||
* Attribute "rel"
|
||||
*/
|
||||
public static final Attribute REL = new Attribute("rel");
|
||||
|
||||
/**
|
||||
* Attribute "rev"
|
||||
*/
|
||||
public static final Attribute REV = new Attribute("rev");
|
||||
|
||||
/**
|
||||
* Attribute "title"
|
||||
*/
|
||||
public static final Attribute TITLE = new Attribute("title");
|
||||
|
||||
/**
|
||||
* Attribute "target"
|
||||
*/
|
||||
public static final Attribute TARGET = new Attribute("target");
|
||||
|
||||
/**
|
||||
* Attribute "shape"
|
||||
*/
|
||||
public static final Attribute SHAPE = new Attribute("shape");
|
||||
|
||||
/**
|
||||
* Attribute "coords"
|
||||
*/
|
||||
public static final Attribute COORDS = new Attribute("coords");
|
||||
|
||||
/**
|
||||
* Attribute "ismap"
|
||||
*/
|
||||
public static final Attribute ISMAP = new Attribute("ismap");
|
||||
|
||||
/**
|
||||
* Attribute "nohref"
|
||||
*/
|
||||
public static final Attribute NOHREF = new Attribute("nohref");
|
||||
|
||||
/**
|
||||
* Attribute "alt"
|
||||
*/
|
||||
public static final Attribute ALT = new Attribute("alt");
|
||||
|
||||
/**
|
||||
* Attribute "id"
|
||||
*/
|
||||
public static final Attribute ID = new Attribute("id");
|
||||
|
||||
/**
|
||||
* Attribute "src"
|
||||
*/
|
||||
public static final Attribute SRC = new Attribute("src");
|
||||
|
||||
/**
|
||||
* Attribute "hspace"
|
||||
*/
|
||||
public static final Attribute HSPACE = new Attribute("hspace");
|
||||
|
||||
/**
|
||||
* Attribute "vspace"
|
||||
*/
|
||||
public static final Attribute VSPACE = new Attribute("vspace");
|
||||
|
||||
/**
|
||||
* Attribute "usemap"
|
||||
*/
|
||||
public static final Attribute USEMAP = new Attribute("usemap");
|
||||
|
||||
/**
|
||||
* Attribute "lowsrc"
|
||||
*/
|
||||
public static final Attribute LOWSRC = new Attribute("lowsrc");
|
||||
|
||||
/**
|
||||
* Attribute "codebase"
|
||||
*/
|
||||
public static final Attribute CODEBASE = new Attribute("codebase");
|
||||
|
||||
/**
|
||||
* Attribute "code"
|
||||
*/
|
||||
public static final Attribute CODE = new Attribute("code");
|
||||
|
||||
/**
|
||||
* Attribute "archive"
|
||||
*/
|
||||
public static final Attribute ARCHIVE = new Attribute("archive");
|
||||
|
||||
/**
|
||||
* Attribute "value"
|
||||
*/
|
||||
public static final Attribute VALUE = new Attribute("value");
|
||||
|
||||
/**
|
||||
* Attribute "valuetype"
|
||||
*/
|
||||
public static final Attribute VALUETYPE = new Attribute("valuetype");
|
||||
|
||||
/**
|
||||
* Attribute "type"
|
||||
*/
|
||||
public static final Attribute TYPE = new Attribute("type");
|
||||
|
||||
/**
|
||||
* Attribute "class"
|
||||
*/
|
||||
public static final Attribute CLASS = new Attribute("class");
|
||||
|
||||
/**
|
||||
* Attribute "style"
|
||||
*/
|
||||
public static final Attribute STYLE = new Attribute("style");
|
||||
|
||||
/**
|
||||
* Attribute "lang"
|
||||
*/
|
||||
public static final Attribute LANG = new Attribute("lang");
|
||||
|
||||
/**
|
||||
* Attribute "face"
|
||||
*/
|
||||
public static final Attribute FACE = new Attribute("face");
|
||||
|
||||
/**
|
||||
* Attribute "dir"
|
||||
*/
|
||||
public static final Attribute DIR = new Attribute("dir");
|
||||
|
||||
/**
|
||||
* Attribute "declare"
|
||||
*/
|
||||
public static final Attribute DECLARE = new Attribute("declare");
|
||||
|
||||
/**
|
||||
* Attribute "classid"
|
||||
*/
|
||||
public static final Attribute CLASSID = new Attribute("classid");
|
||||
|
||||
/**
|
||||
* Attribute "data"
|
||||
*/
|
||||
public static final Attribute DATA = new Attribute("data");
|
||||
|
||||
/**
|
||||
* Attribute "codetype"
|
||||
*/
|
||||
public static final Attribute CODETYPE = new Attribute("codetype");
|
||||
|
||||
/**
|
||||
* Attribute "standby"
|
||||
*/
|
||||
public static final Attribute STANDBY = new Attribute("standby");
|
||||
|
||||
/**
|
||||
* Attribute "border"
|
||||
*/
|
||||
public static final Attribute BORDER = new Attribute("border");
|
||||
|
||||
/**
|
||||
* Attribute "shapes"
|
||||
*/
|
||||
public static final Attribute SHAPES = new Attribute("shapes");
|
||||
|
||||
/**
|
||||
* Attribute "noshade"
|
||||
*/
|
||||
public static final Attribute NOSHADE = new Attribute("noshade");
|
||||
|
||||
/**
|
||||
* Attribute "compact"
|
||||
*/
|
||||
public static final Attribute COMPACT = new Attribute("compact");
|
||||
|
||||
/**
|
||||
* Attribute "start"
|
||||
*/
|
||||
public static final Attribute START = new Attribute("start");
|
||||
|
||||
/**
|
||||
* Attribute "action"
|
||||
*/
|
||||
public static final Attribute ACTION = new Attribute("action");
|
||||
|
||||
/**
|
||||
* Attribute "method"
|
||||
*/
|
||||
public static final Attribute METHOD = new Attribute("method");
|
||||
|
||||
/**
|
||||
* Attribute "enctype"
|
||||
*/
|
||||
public static final Attribute ENCTYPE = new Attribute("enctype");
|
||||
|
||||
/**
|
||||
* Attribute "checked"
|
||||
*/
|
||||
public static final Attribute CHECKED = new Attribute("checked");
|
||||
|
||||
/**
|
||||
* Attribute "maxlength"
|
||||
*/
|
||||
public static final Attribute MAXLENGTH = new Attribute("maxlength");
|
||||
|
||||
/**
|
||||
* Attribute "multiple"
|
||||
*/
|
||||
public static final Attribute MULTIPLE = new Attribute("multiple");
|
||||
|
||||
/**
|
||||
* Attribute "selected"
|
||||
*/
|
||||
public static final Attribute SELECTED = new Attribute("selected");
|
||||
|
||||
/**
|
||||
* Attribute "rows"
|
||||
*/
|
||||
public static final Attribute ROWS = new Attribute("rows");
|
||||
|
||||
/**
|
||||
* Attribute "cols"
|
||||
*/
|
||||
public static final Attribute COLS = new Attribute("cols");
|
||||
|
||||
/**
|
||||
* Attribute "dummy"
|
||||
*/
|
||||
public static final Attribute DUMMY = new Attribute("dummy");
|
||||
|
||||
/**
|
||||
* Attribute "cellspacing"
|
||||
*/
|
||||
public static final Attribute CELLSPACING = new Attribute("cellspacing");
|
||||
|
||||
/**
|
||||
* Attribute "cellpadding"
|
||||
*/
|
||||
public static final Attribute CELLPADDING = new Attribute("cellpadding");
|
||||
|
||||
/**
|
||||
* Attribute "valign"
|
||||
*/
|
||||
public static final Attribute VALIGN = new Attribute("valign");
|
||||
|
||||
/**
|
||||
* Attribute "halign"
|
||||
*/
|
||||
public static final Attribute HALIGN = new Attribute("halign");
|
||||
|
||||
/**
|
||||
* Attribute "nowrap"
|
||||
*/
|
||||
public static final Attribute NOWRAP = new Attribute("nowrap");
|
||||
|
||||
/**
|
||||
* Attribute "rowspan"
|
||||
*/
|
||||
public static final Attribute ROWSPAN = new Attribute("rowspan");
|
||||
|
||||
/**
|
||||
* Attribute "colspan"
|
||||
*/
|
||||
public static final Attribute COLSPAN = new Attribute("colspan");
|
||||
|
||||
/**
|
||||
* Attribute "prompt"
|
||||
*/
|
||||
public static final Attribute PROMPT = new Attribute("prompt");
|
||||
|
||||
/**
|
||||
* Attribute "http-equiv"
|
||||
*/
|
||||
public static final Attribute HTTPEQUIV = new Attribute("http-equiv");
|
||||
|
||||
/**
|
||||
* Attribute "content"
|
||||
*/
|
||||
public static final Attribute CONTENT = new Attribute("content");
|
||||
|
||||
/**
|
||||
* Attribute "language"
|
||||
*/
|
||||
public static final Attribute LANGUAGE = new Attribute("language");
|
||||
|
||||
/**
|
||||
* Attribute "version"
|
||||
*/
|
||||
public static final Attribute VERSION = new Attribute("version");
|
||||
|
||||
/**
|
||||
* Attribute "n"
|
||||
*/
|
||||
public static final Attribute N = new Attribute("n");
|
||||
|
||||
/**
|
||||
* Attribute "frameborder"
|
||||
*/
|
||||
public static final Attribute FRAMEBORDER = new Attribute("frameborder");
|
||||
|
||||
/**
|
||||
* Attribute "marginwidth"
|
||||
*/
|
||||
public static final Attribute MARGINWIDTH = new Attribute("marginwidth");
|
||||
|
||||
/**
|
||||
* Attribute "marginheight"
|
||||
*/
|
||||
public static final Attribute MARGINHEIGHT = new Attribute("marginheight");
|
||||
|
||||
/**
|
||||
* Attribute "scrolling"
|
||||
*/
|
||||
public static final Attribute SCROLLING = new Attribute("scrolling");
|
||||
|
||||
/**
|
||||
* Attribute "noresize"
|
||||
*/
|
||||
public static final Attribute NORESIZE = new Attribute("noresize");
|
||||
|
||||
/**
|
||||
* Attribute "endtag"
|
||||
*/
|
||||
public static final Attribute ENDTAG = new Attribute("endtag");
|
||||
|
||||
/**
|
||||
* Attribute "comment"
|
||||
*/
|
||||
public static final Attribute COMMENT = new Attribute("comment");
|
||||
static final Attribute MEDIA = new Attribute("media");
|
||||
|
||||
@ -645,9 +1258,10 @@ public class HTML {
|
||||
return value;
|
||||
}
|
||||
|
||||
// This is used in cases where the value for the attribute has not
|
||||
// been specified.
|
||||
//
|
||||
/**
|
||||
* {@code NULL_ATTRIBUTE_VALUE} used in cases where the value for the attribute has not
|
||||
* been specified.
|
||||
*/
|
||||
public static final String NULL_ATTRIBUTE_VALUE = "#DEFAULT";
|
||||
|
||||
// size determined similar to size of tagHashtable
|
||||
|
||||
@ -2894,6 +2894,9 @@ public class HTMLDocument extends DefaultStyledDocument {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Action assigned by default to handle the Isindex task of the reader.
|
||||
*/
|
||||
public class IsindexAction extends TagAction {
|
||||
|
||||
public void start(HTML.Tag t, MutableAttributeSet a) {
|
||||
@ -3134,7 +3137,9 @@ public class HTMLDocument extends DefaultStyledDocument {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Action assigned by default to handle the Pre block task of the reader.
|
||||
*/
|
||||
public class PreAction extends BlockAction {
|
||||
|
||||
public void start(HTML.Tag t, MutableAttributeSet attr) {
|
||||
|
||||
@ -238,7 +238,7 @@ public class HTMLEditorKit extends StyledEditorKit implements Accessible {
|
||||
* be thrown. When inserting into a non-empty document all tags outside
|
||||
* of the body (head, title) will be dropped.
|
||||
*
|
||||
* @param in the stream to read from
|
||||
* @param in the stream to read from
|
||||
* @param doc the destination for the insertion
|
||||
* @param pos the location in the document to place the
|
||||
* content
|
||||
@ -269,14 +269,18 @@ public class HTMLEditorKit extends StyledEditorKit implements Accessible {
|
||||
/**
|
||||
* Inserts HTML into an existing document.
|
||||
*
|
||||
* @param doc the document to insert into
|
||||
* @param offset the offset to insert HTML at
|
||||
* @param popDepth the number of ElementSpec.EndTagTypes to generate before
|
||||
* inserting
|
||||
* @param doc the document to insert into
|
||||
* @param offset the offset to insert HTML at
|
||||
* @param popDepth the number of ElementSpec.EndTagTypes to generate
|
||||
* before inserting
|
||||
* @param html the HTML string
|
||||
* @param pushDepth the number of ElementSpec.StartTagTypes with a direction
|
||||
* of ElementSpec.JoinNextDirection that should be generated
|
||||
* before inserting, but after the end tags have been generated
|
||||
* of ElementSpec.JoinNextDirection that should be generated
|
||||
* before inserting, but after the end tags have been generated
|
||||
* @param insertTag the first tag to start inserting into document
|
||||
*
|
||||
* @throws BadLocationException if {@code offset} is invalid
|
||||
* @throws IOException on I/O error
|
||||
* @exception RuntimeException (will eventually be a BadLocationException)
|
||||
* if pos is invalid
|
||||
*/
|
||||
@ -302,13 +306,13 @@ public class HTMLEditorKit extends StyledEditorKit implements Accessible {
|
||||
* Write content from a document to the given stream
|
||||
* in a format appropriate for this kind of content handler.
|
||||
*
|
||||
* @param out the stream to write to
|
||||
* @param doc the source for the write
|
||||
* @param pos the location in the document to fetch the
|
||||
* @param out the stream to write to
|
||||
* @param doc the source for the write
|
||||
* @param pos the location in the document to fetch the
|
||||
* content
|
||||
* @param len the amount to write out
|
||||
* @param len the amount to write out
|
||||
* @exception IOException on any I/O error
|
||||
* @exception BadLocationException if pos represents an invalid
|
||||
* @exception BadLocationException if {@code pos} represents an invalid
|
||||
* location within the document
|
||||
*/
|
||||
public void write(Writer out, Document doc, int pos, int len)
|
||||
@ -369,6 +373,8 @@ public class HTMLEditorKit extends StyledEditorKit implements Accessible {
|
||||
* specified is shared by all HTMLEditorKit instances.
|
||||
* This should be reimplemented to provide a finer granularity
|
||||
* if desired.
|
||||
*
|
||||
* @param s a StyleSheet
|
||||
*/
|
||||
public void setStyleSheet(StyleSheet s) {
|
||||
if (s == null) {
|
||||
@ -383,6 +389,8 @@ public class HTMLEditorKit extends StyledEditorKit implements Accessible {
|
||||
* HTML elements. By default the resource specified by
|
||||
* DEFAULT_CSS gets loaded, and is shared by all HTMLEditorKit
|
||||
* instances.
|
||||
*
|
||||
* @return the StyleSheet
|
||||
*/
|
||||
public StyleSheet getStyleSheet() {
|
||||
AppContext appContext = AppContext.getAppContext();
|
||||
@ -412,7 +420,7 @@ public class HTMLEditorKit extends StyledEditorKit implements Accessible {
|
||||
* to function when used in an applet.
|
||||
*
|
||||
* @param name the name of the resource, relative to the
|
||||
* HTMLEditorKit class
|
||||
* HTMLEditorKit class
|
||||
* @return a stream representing the resource
|
||||
*/
|
||||
static InputStream getResourceAsStream(final String name) {
|
||||
@ -506,6 +514,8 @@ public class HTMLEditorKit extends StyledEditorKit implements Accessible {
|
||||
/**
|
||||
* Sets the default cursor.
|
||||
*
|
||||
* @param cursor a cursor
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
public void setDefaultCursor(Cursor cursor) {
|
||||
@ -515,6 +525,8 @@ public class HTMLEditorKit extends StyledEditorKit implements Accessible {
|
||||
/**
|
||||
* Returns the default cursor.
|
||||
*
|
||||
* @return the cursor
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
public Cursor getDefaultCursor() {
|
||||
@ -524,6 +536,8 @@ public class HTMLEditorKit extends StyledEditorKit implements Accessible {
|
||||
/**
|
||||
* Sets the cursor to use over links.
|
||||
*
|
||||
* @param cursor a cursor
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
public void setLinkCursor(Cursor cursor) {
|
||||
@ -532,6 +546,9 @@ public class HTMLEditorKit extends StyledEditorKit implements Accessible {
|
||||
|
||||
/**
|
||||
* Returns the cursor to use over hyper links.
|
||||
*
|
||||
* @return the cursor
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
public Cursor getLinkCursor() {
|
||||
@ -557,6 +574,8 @@ public class HTMLEditorKit extends StyledEditorKit implements Accessible {
|
||||
* automatically or only <code>FormSubmitEvent</code> is fired.
|
||||
* By default it is set to true.
|
||||
*
|
||||
* @param isAuto if {@code true}, html form submission is processed automatically.
|
||||
*
|
||||
* @see #isAutoFormSubmission()
|
||||
* @see FormSubmitEvent
|
||||
* @since 1.5
|
||||
@ -586,6 +605,8 @@ public class HTMLEditorKit extends StyledEditorKit implements Accessible {
|
||||
* to avoid the overhead of loading the default parser if
|
||||
* it's not used. The default parser is the HotJava parser
|
||||
* using an HTML 3.2 DTD.
|
||||
*
|
||||
* @return the parser
|
||||
*/
|
||||
protected Parser getParser() {
|
||||
if (defaultParser == null) {
|
||||
@ -972,6 +993,9 @@ public class HTMLEditorKit extends StyledEditorKit implements Accessible {
|
||||
* with the results of the parse. This method should
|
||||
* be implemented to be thread-safe.
|
||||
*
|
||||
* @param r a reader
|
||||
* @param cb a parser callback
|
||||
* @param ignoreCharSet if {@code true} charset is ignoring
|
||||
* @throws IOException if an I/O exception occurs
|
||||
*/
|
||||
public abstract void parse(Reader r, ParserCallback cb, boolean ignoreCharSet) throws IOException;
|
||||
@ -1000,26 +1024,78 @@ public class HTMLEditorKit extends StyledEditorKit implements Accessible {
|
||||
*/
|
||||
public static final Object IMPLIED = "_implied_";
|
||||
|
||||
|
||||
/**
|
||||
* The last method called on the reader. It allows
|
||||
* any pending changes to be flushed into the document.
|
||||
* Since this is currently loading synchronously, the entire
|
||||
* set of changes are pushed in at this point.
|
||||
*
|
||||
* @throws BadLocationException if the given position does not
|
||||
* represent a valid location in the associated document.
|
||||
*/
|
||||
public void flush() throws BadLocationException {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the parser to indicate a block of text was
|
||||
* encountered.
|
||||
*
|
||||
* @param data a data
|
||||
* @param pos a position
|
||||
*/
|
||||
public void handleText(char[] data, int pos) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the parser to indicate a block of comment was
|
||||
* encountered.
|
||||
*
|
||||
* @param data a data
|
||||
* @param pos a position
|
||||
*/
|
||||
public void handleComment(char[] data, int pos) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback from the parser. Route to the appropriate
|
||||
* handler for the tag.
|
||||
*
|
||||
* @param t an HTML tag
|
||||
* @param a a set of attributes
|
||||
* @param pos a position
|
||||
*/
|
||||
public void handleStartTag(HTML.Tag t, MutableAttributeSet a, int pos) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback from the parser. Route to the appropriate
|
||||
* handler for the tag.
|
||||
*
|
||||
* @param t an HTML tag
|
||||
* @param pos a position
|
||||
*/
|
||||
public void handleEndTag(HTML.Tag t, int pos) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback from the parser. Route to the appropriate
|
||||
* handler for the tag.
|
||||
*
|
||||
* @param t an HTML tag
|
||||
* @param a a set of attributes
|
||||
* @param pos a position
|
||||
*/
|
||||
public void handleSimpleTag(HTML.Tag t, MutableAttributeSet a, int pos) {
|
||||
}
|
||||
|
||||
public void handleError(String errorMsg, int pos){
|
||||
/**
|
||||
* Callback from the parser. Route to the appropriate
|
||||
* handler for the error.
|
||||
*
|
||||
* @param errorMsg a error message
|
||||
* @param pos a position
|
||||
*/
|
||||
public void handleError(String errorMsg, int pos) {
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1489,6 +1565,12 @@ public class HTMLEditorKit extends StyledEditorKit implements Accessible {
|
||||
*/
|
||||
@SuppressWarnings("serial") // Superclass is not serializable across versions
|
||||
public static abstract class HTMLTextAction extends StyledTextAction {
|
||||
|
||||
/**
|
||||
* Creates a new HTMLTextAction from a string action name.
|
||||
*
|
||||
* @param name the name of the action
|
||||
*/
|
||||
public HTMLTextAction(String name) {
|
||||
super(name);
|
||||
}
|
||||
@ -1575,6 +1657,12 @@ public class HTMLEditorKit extends StyledEditorKit implements Accessible {
|
||||
/**
|
||||
* Returns the deepest element at <code>offset</code> matching
|
||||
* <code>tag</code>.
|
||||
*
|
||||
* @param doc an instance of HTMLDocument
|
||||
* @param offset the specified offset >= 0
|
||||
* @param tag an instance of HTML.Tag
|
||||
*
|
||||
* @return the deepest element
|
||||
*/
|
||||
protected Element findElementMatchingTag(HTMLDocument doc, int offset,
|
||||
HTML.Tag tag) {
|
||||
@ -1611,11 +1699,30 @@ public class HTMLEditorKit extends StyledEditorKit implements Accessible {
|
||||
*/
|
||||
@SuppressWarnings("serial") // Superclass is not serializable across versions
|
||||
public static class InsertHTMLTextAction extends HTMLTextAction {
|
||||
|
||||
/**
|
||||
* Creates a new InsertHTMLTextAction.
|
||||
*
|
||||
* @param name a name of the action
|
||||
* @param html an HTML string
|
||||
* @param parentTag a parent tag
|
||||
* @param addTag the first tag to start inserting into document
|
||||
*/
|
||||
public InsertHTMLTextAction(String name, String html,
|
||||
HTML.Tag parentTag, HTML.Tag addTag) {
|
||||
this(name, html, parentTag, addTag, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new InsertHTMLTextAction.
|
||||
*
|
||||
* @param name a name of the action
|
||||
* @param html an HTML string
|
||||
* @param parentTag a parent tag
|
||||
* @param addTag the first tag to start inserting into document
|
||||
* @param alternateParentTag an alternative parent tag
|
||||
* @param alternateAddTag an alternative tag
|
||||
*/
|
||||
public InsertHTMLTextAction(String name, String html,
|
||||
HTML.Tag parentTag,
|
||||
HTML.Tag addTag,
|
||||
@ -1644,6 +1751,17 @@ public class HTMLEditorKit extends StyledEditorKit implements Accessible {
|
||||
/**
|
||||
* A cover for HTMLEditorKit.insertHTML. If an exception it
|
||||
* thrown it is wrapped in a RuntimeException and thrown.
|
||||
*
|
||||
* @param editor an instance of JEditorPane
|
||||
* @param doc the document to insert into
|
||||
* @param offset the offset to insert HTML at
|
||||
* @param html an HTML string
|
||||
* @param popDepth the number of ElementSpec.EndTagTypes to generate
|
||||
* before inserting
|
||||
* @param pushDepth the number of ElementSpec.StartTagTypes with a direction
|
||||
* of ElementSpec.JoinNextDirection that should be generated
|
||||
* before inserting, but after the end tags have been generated
|
||||
* @param addTag the first tag to start inserting into document
|
||||
*/
|
||||
protected void insertHTML(JEditorPane editor, HTMLDocument doc,
|
||||
int offset, String html, int popDepth,
|
||||
@ -1663,7 +1781,17 @@ public class HTMLEditorKit extends StyledEditorKit implements Accessible {
|
||||
* This is invoked when inserting at a boundary. It determines
|
||||
* the number of pops, and then the number of pushes that need
|
||||
* to be performed, and then invokes insertHTML.
|
||||
*
|
||||
* @param editor an instance of JEditorPane
|
||||
* @param doc an instance of HTMLDocument
|
||||
* @param offset an offset to start from
|
||||
* @param insertElement an instance of Element
|
||||
* @param html an HTML string
|
||||
* @param parentTag a parent tag
|
||||
* @param addTag the first tag to start inserting into document
|
||||
*
|
||||
* @since 1.3
|
||||
*
|
||||
*/
|
||||
protected void insertAtBoundary(JEditorPane editor, HTMLDocument doc,
|
||||
int offset, Element insertElement,
|
||||
@ -1678,6 +1806,14 @@ public class HTMLEditorKit extends StyledEditorKit implements Accessible {
|
||||
* the number of pops, and then the number of pushes that need
|
||||
* to be performed, and then invokes insertHTML.
|
||||
* @deprecated As of Java 2 platform v1.3, use insertAtBoundary
|
||||
*
|
||||
* @param editor an instance of JEditorPane
|
||||
* @param doc an instance of HTMLDocument
|
||||
* @param offset an offset to start from
|
||||
* @param insertElement an instance of Element
|
||||
* @param html an HTML string
|
||||
* @param parentTag a parent tag
|
||||
* @param addTag the first tag to start inserting into document
|
||||
*/
|
||||
@Deprecated
|
||||
protected void insertAtBoundry(JEditorPane editor, HTMLDocument doc,
|
||||
@ -2050,7 +2186,7 @@ public class HTMLEditorKit extends StyledEditorKit implements Accessible {
|
||||
* @param offs0 the starting model offset ≥ 0
|
||||
* @param offs1 the ending model offset ≥ offs1
|
||||
* @param bounds the bounding box of the view, which is not
|
||||
* necessarily the region to paint.
|
||||
* necessarily the region to paint.
|
||||
* @param c the editor
|
||||
* @param view View painting for
|
||||
* @return region in which drawing occurred
|
||||
|
||||
@ -361,8 +361,10 @@ public class HTMLWriter extends AbstractWriter {
|
||||
* Writes out a start tag for the element.
|
||||
* Ignores all synthesized elements.
|
||||
*
|
||||
* @param elem an Element
|
||||
* @exception IOException on any I/O error
|
||||
* @param elem an Element
|
||||
* @throws IOException on any I/O error
|
||||
* @throws BadLocationException if pos represents an invalid
|
||||
* location within the document.
|
||||
*/
|
||||
protected void startTag(Element elem) throws IOException, BadLocationException {
|
||||
|
||||
@ -669,9 +671,12 @@ public class HTMLWriter extends AbstractWriter {
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the element is a
|
||||
* Returns {@code true} if the element is a
|
||||
* synthesized element. Currently we are only testing
|
||||
* for the p-implied tag.
|
||||
*
|
||||
* @param elem an element
|
||||
* @return {@code true} if the element is a synthesized element.
|
||||
*/
|
||||
protected boolean synthesizedElement(Element elem) {
|
||||
if (matchNameAttribute(elem.getAttributes(), HTML.Tag.IMPLIED)) {
|
||||
@ -684,6 +689,10 @@ public class HTMLWriter extends AbstractWriter {
|
||||
/**
|
||||
* Returns true if the StyleConstants.NameAttribute is
|
||||
* equal to the tag that is passed in as a parameter.
|
||||
*
|
||||
* @param attr a set of attributes
|
||||
* @param tag an HTML tag
|
||||
* @return {@code true} if the StyleConstants.NameAttribute is equal to the tag that is passed in as a parameter.
|
||||
*/
|
||||
protected boolean matchNameAttribute(AttributeSet attr, HTML.Tag tag) {
|
||||
Object o = attr.getAttribute(StyleConstants.NameAttribute);
|
||||
@ -702,6 +711,7 @@ public class HTMLWriter extends AbstractWriter {
|
||||
* so that when appropriate the corresponding end tags can be
|
||||
* written out.
|
||||
*
|
||||
* @param attr a set of attributes
|
||||
* @exception IOException on any I/O error
|
||||
*/
|
||||
protected void writeEmbeddedTags(AttributeSet attr) throws IOException {
|
||||
@ -756,6 +766,7 @@ public class HTMLWriter extends AbstractWriter {
|
||||
* then the tag is removed from the vector and a corresponding
|
||||
* end tag is written out.
|
||||
*
|
||||
* @param attr a set of attributes
|
||||
* @exception IOException on any I/O error
|
||||
*/
|
||||
protected void closeOutUnwantedEmbeddedTags(AttributeSet attr) throws IOException {
|
||||
|
||||
@ -141,9 +141,11 @@ public class ImageView extends View {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the text to display if the image can't be loaded. This is
|
||||
* Returns the text to display if the image cannot be loaded. This is
|
||||
* obtained from the Elements attribute set with the attribute name
|
||||
* <code>HTML.Attribute.ALT</code>.
|
||||
*
|
||||
* @return the test to display if the image cannot be loaded.
|
||||
*/
|
||||
public String getAltText() {
|
||||
return (String)getElement().getAttributes().getAttribute
|
||||
@ -153,6 +155,8 @@ public class ImageView extends View {
|
||||
/**
|
||||
* Return a URL for the image source,
|
||||
* or null if it could not be determined.
|
||||
*
|
||||
* @return the URL for the image source, or null if it could not be determined.
|
||||
*/
|
||||
public URL getImageURL() {
|
||||
String src = (String)getElement().getAttributes().
|
||||
@ -171,7 +175,9 @@ public class ImageView extends View {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the icon to use if the image couldn't be found.
|
||||
* Returns the icon to use if the image could not be found.
|
||||
*
|
||||
* @return the icon to use if the image could not be found.
|
||||
*/
|
||||
public Icon getNoImageIcon() {
|
||||
return (Icon) UIManager.getLookAndFeelDefaults().get(MISSING_IMAGE);
|
||||
@ -179,6 +185,8 @@ public class ImageView extends View {
|
||||
|
||||
/**
|
||||
* Returns the icon to use while in the process of loading the image.
|
||||
*
|
||||
* @return the icon to use while in the process of loading the image.
|
||||
*/
|
||||
public Icon getLoadingImageIcon() {
|
||||
return (Icon) UIManager.getLookAndFeelDefaults().get(PENDING_IMAGE);
|
||||
@ -186,6 +194,8 @@ public class ImageView extends View {
|
||||
|
||||
/**
|
||||
* Returns the image to render.
|
||||
*
|
||||
* @return the image to render.
|
||||
*/
|
||||
public Image getImage() {
|
||||
sync();
|
||||
@ -205,9 +215,12 @@ public class ImageView extends View {
|
||||
|
||||
/**
|
||||
* Sets how the image is loaded. If <code>newValue</code> is true,
|
||||
* the image we be loaded when first asked for, otherwise it will
|
||||
* the image will be loaded when first asked for, otherwise it will
|
||||
* be loaded asynchronously. The default is to not load synchronously,
|
||||
* that is to load the image asynchronously.
|
||||
*
|
||||
* @param newValue if {@code true} the image will be loaded when first asked for,
|
||||
* otherwise it will be asynchronously.
|
||||
*/
|
||||
public void setLoadsSynchronously(boolean newValue) {
|
||||
synchronized(this) {
|
||||
@ -221,14 +234,18 @@ public class ImageView extends View {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the image should be loaded when first asked for.
|
||||
* Returns {@code true} if the image should be loaded when first asked for.
|
||||
*
|
||||
* @return {@code true} if the image should be loaded when first asked for.
|
||||
*/
|
||||
public boolean getLoadsSynchronously() {
|
||||
return ((state & SYNC_LOAD_FLAG) != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to get the StyleSheet.
|
||||
* Convenient method to get the StyleSheet.
|
||||
*
|
||||
* @return the StyleSheet
|
||||
*/
|
||||
protected StyleSheet getStyleSheet() {
|
||||
HTMLDocument doc = (HTMLDocument) getDocument();
|
||||
@ -613,7 +630,7 @@ public class ImageView extends View {
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method for getting an integer attribute from the elements
|
||||
* Convenient method for getting an integer attribute from the elements
|
||||
* AttributeSet.
|
||||
*/
|
||||
private int getIntAttr(HTML.Attribute name, int deflt) {
|
||||
|
||||
@ -214,7 +214,11 @@ public class InlineView extends LabelView {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convenient method to get the StyleSheet.
|
||||
*
|
||||
* @return the StyleSheet
|
||||
*/
|
||||
protected StyleSheet getStyleSheet() {
|
||||
HTMLDocument doc = (HTMLDocument) getDocument();
|
||||
return doc.getStyleSheet();
|
||||
|
||||
@ -195,6 +195,7 @@ public class MinimalHTMLWriter extends AbstractWriter {
|
||||
* Writes out a start tag appropriately
|
||||
* indented. Also increments the indent level.
|
||||
*
|
||||
* @param tag a start tag
|
||||
* @exception IOException on any I/O error
|
||||
*/
|
||||
protected void writeStartTag(String tag) throws IOException {
|
||||
@ -209,6 +210,7 @@ public class MinimalHTMLWriter extends AbstractWriter {
|
||||
* Writes out an end tag appropriately
|
||||
* indented. Also decrements the indent level.
|
||||
*
|
||||
* @param endTag an end tag
|
||||
* @exception IOException on any I/O error
|
||||
*/
|
||||
protected void writeEndTag(String endTag) throws IOException {
|
||||
@ -284,7 +286,9 @@ public class MinimalHTMLWriter extends AbstractWriter {
|
||||
* branch elements or leaf elements. This method specially handles
|
||||
* leaf elements that are text.
|
||||
*
|
||||
* @exception IOException on any I/O error
|
||||
* @throws IOException on any I/O error
|
||||
* @throws BadLocationException if we are in an invalid
|
||||
* location within the document.
|
||||
*/
|
||||
protected void writeBody() throws IOException, BadLocationException {
|
||||
ElementIterator it = getElementIterator();
|
||||
@ -354,6 +358,7 @@ public class MinimalHTMLWriter extends AbstractWriter {
|
||||
* <p> tag and sets its value to be the name of the
|
||||
* style.
|
||||
*
|
||||
* @param elem an element
|
||||
* @exception IOException on any I/O error
|
||||
*/
|
||||
protected void writeStartParagraph(Element elem) throws IOException {
|
||||
@ -371,6 +376,7 @@ public class MinimalHTMLWriter extends AbstractWriter {
|
||||
* Responsible for writing out other non-text leaf
|
||||
* elements.
|
||||
*
|
||||
* @param elem an element
|
||||
* @exception IOException on any I/O error
|
||||
*/
|
||||
protected void writeLeaf(Element elem) throws IOException {
|
||||
@ -392,7 +398,8 @@ public class MinimalHTMLWriter extends AbstractWriter {
|
||||
* In certain cases it could be a URL, in others it could
|
||||
* be read from a stream.
|
||||
*
|
||||
* @param elem element of type StyleConstants.IconElementName
|
||||
* @param elem an element of type StyleConstants.IconElementName
|
||||
* @throws IOException if I/O error occured.
|
||||
*/
|
||||
protected void writeImage(Element elem) throws IOException {
|
||||
}
|
||||
@ -402,6 +409,9 @@ public class MinimalHTMLWriter extends AbstractWriter {
|
||||
* Responsible for handling Component Elements;
|
||||
* deliberately unimplemented.
|
||||
* How this method is implemented is a matter of policy.
|
||||
*
|
||||
* @param elem an element of type StyleConstants.ComponentElementName
|
||||
* @throws IOException if I/O error occured.
|
||||
*/
|
||||
protected void writeComponent(Element elem) throws IOException {
|
||||
}
|
||||
@ -410,6 +420,8 @@ public class MinimalHTMLWriter extends AbstractWriter {
|
||||
/**
|
||||
* Returns true if the element is a text element.
|
||||
*
|
||||
* @param elem an element
|
||||
* @return {@code true} if the element is a text element.
|
||||
*/
|
||||
protected boolean isText(Element elem) {
|
||||
return (elem.getName() == AbstractDocument.ContentElementName);
|
||||
@ -420,6 +432,8 @@ public class MinimalHTMLWriter extends AbstractWriter {
|
||||
* Writes out the attribute set
|
||||
* in an HTML-compliant manner.
|
||||
*
|
||||
* @param elem an element
|
||||
* @param needsIndenting indention will be added if {@code needsIndenting} is {@code true}
|
||||
* @exception IOException on any I/O error
|
||||
* @exception BadLocationException if pos represents an invalid
|
||||
* location within the document.
|
||||
@ -442,6 +456,7 @@ public class MinimalHTMLWriter extends AbstractWriter {
|
||||
* bold <b>, italic <i>, and <u> tags for the
|
||||
* text based on its attribute settings.
|
||||
*
|
||||
* @param attr a set of attributes
|
||||
* @exception IOException on any I/O error
|
||||
*/
|
||||
|
||||
@ -553,6 +568,7 @@ public class MinimalHTMLWriter extends AbstractWriter {
|
||||
* style attribute is set to contain the list of remaining
|
||||
* attributes just like inline styles.
|
||||
*
|
||||
* @param attr a set of attributes
|
||||
* @exception IOException on any I/O error
|
||||
*/
|
||||
protected void writeNonHTMLAttributes(AttributeSet attr) throws IOException {
|
||||
@ -608,6 +624,8 @@ public class MinimalHTMLWriter extends AbstractWriter {
|
||||
|
||||
/**
|
||||
* Returns true if we are currently in a <font> tag.
|
||||
*
|
||||
* @return {@code true} if we are currently in a <font> tag.
|
||||
*/
|
||||
protected boolean inFontTag() {
|
||||
return (fontAttributes != null);
|
||||
@ -636,6 +654,7 @@ public class MinimalHTMLWriter extends AbstractWriter {
|
||||
* any enclosing font tag before writing out a
|
||||
* new start tag.
|
||||
*
|
||||
* @param style a font style
|
||||
* @exception IOException on any I/O error
|
||||
*/
|
||||
protected void startFontTag(String style) throws IOException {
|
||||
|
||||
@ -61,6 +61,8 @@ public class Option implements Serializable {
|
||||
|
||||
/**
|
||||
* Sets the label to be used for the option.
|
||||
*
|
||||
* @param label a label.
|
||||
*/
|
||||
public void setLabel(String label) {
|
||||
this.label = label;
|
||||
@ -68,6 +70,8 @@ public class Option implements Serializable {
|
||||
|
||||
/**
|
||||
* Fetch the label associated with the option.
|
||||
*
|
||||
* @return the label associated with the option.
|
||||
*/
|
||||
public String getLabel() {
|
||||
return label;
|
||||
@ -75,6 +79,8 @@ public class Option implements Serializable {
|
||||
|
||||
/**
|
||||
* Fetch the attributes associated with this option.
|
||||
*
|
||||
* @return the attributes associated with this option.
|
||||
*/
|
||||
public AttributeSet getAttributes() {
|
||||
return attr;
|
||||
@ -89,6 +95,8 @@ public class Option implements Serializable {
|
||||
|
||||
/**
|
||||
* Sets the selected state.
|
||||
*
|
||||
* @param state a selection state
|
||||
*/
|
||||
protected void setSelection(boolean state) {
|
||||
selected = state;
|
||||
@ -96,16 +104,21 @@ public class Option implements Serializable {
|
||||
|
||||
/**
|
||||
* Fetches the selection state associated with this option.
|
||||
*
|
||||
* @return the selection state.
|
||||
*/
|
||||
public boolean isSelected() {
|
||||
return selected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to return the string associated
|
||||
* with the <code>value</code> attribute. If the
|
||||
* value has not been specified, the label will be
|
||||
* Convenient method to return the string associated
|
||||
* with the {@code value} attribute. If the
|
||||
* {@code value} has not been specified, the {@code label} will be
|
||||
* returned.
|
||||
*
|
||||
* @return the string associated with the {@code value} attribute,
|
||||
* or {@code label} if the value has been not specified.
|
||||
*/
|
||||
public String getValue() {
|
||||
String value = (String) attr.getAttribute(HTML.Attribute.VALUE);
|
||||
|
||||
@ -128,6 +128,11 @@ public class ParagraphView extends javax.swing.text.ParagraphView {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenient method to get the StyleSheet.
|
||||
*
|
||||
* @return the StyleSheet
|
||||
*/
|
||||
protected StyleSheet getStyleSheet() {
|
||||
HTMLDocument doc = (HTMLDocument) getDocument();
|
||||
return doc.getStyleSheet();
|
||||
|
||||
@ -156,7 +156,7 @@ public class StyleSheet extends StyleContext {
|
||||
// . When one of the AttributeSets is mutated by way of a
|
||||
// StyleConstants key, all the associated CSS keys are removed. This is
|
||||
// done so that the two representations don't get out of sync. For
|
||||
// example, if the developer adds StyleConsants.BOLD, FALSE to an
|
||||
// example, if the developer adds StyleConstants.BOLD, FALSE to an
|
||||
// AttributeSet that contains HTML.Tag.B, the HTML.Tag.B entry will
|
||||
// be removed.
|
||||
|
||||
@ -271,6 +271,9 @@ public class StyleSheet extends StyleContext {
|
||||
* with a selector "table p" and a new rule was added with a selector
|
||||
* of "p" the returned Style would include the new attributes from
|
||||
* the rule "p".
|
||||
*
|
||||
* @param selector a space separated String of the element names.
|
||||
* @return the rule that best matches the selector.
|
||||
*/
|
||||
public Style getRule(String selector) {
|
||||
selector = cleanSelectorString(selector);
|
||||
@ -285,6 +288,8 @@ public class StyleSheet extends StyleContext {
|
||||
* Adds a set of rules to the sheet. The rules are expected to
|
||||
* be in valid CSS format. Typically this would be called as
|
||||
* a result of parsing a <style> tag.
|
||||
*
|
||||
* @param rule a set of rules
|
||||
*/
|
||||
public void addRule(String rule) {
|
||||
if (rule != null) {
|
||||
@ -316,6 +321,9 @@ public class StyleSheet extends StyleContext {
|
||||
* Translates a CSS declaration to an AttributeSet that represents
|
||||
* the CSS declaration. Typically this would be called as a
|
||||
* result of encountering an HTML style attribute.
|
||||
*
|
||||
* @param decl a CSS declaration
|
||||
* @return a set of attributes that represents the CSS declaration.
|
||||
*/
|
||||
public AttributeSet getDeclaration(String decl) {
|
||||
if (decl == null) {
|
||||
@ -335,6 +343,7 @@ public class StyleSheet extends StyleContext {
|
||||
* location of the stream and may be null. All relative
|
||||
* URLs specified in the stream will be based upon this
|
||||
* parameter.
|
||||
* @throws java.io.IOException if I/O error occured.
|
||||
*/
|
||||
public void loadRules(Reader in, URL ref) throws IOException {
|
||||
CssParser parser = new CssParser();
|
||||
@ -345,6 +354,9 @@ public class StyleSheet extends StyleContext {
|
||||
* Fetches a set of attributes to use in the view for
|
||||
* displaying. This is basically a set of attributes that
|
||||
* can be used for View.getAttributes.
|
||||
*
|
||||
* @param v a view
|
||||
* @return the of attributes
|
||||
*/
|
||||
public AttributeSet getViewAttributes(View v) {
|
||||
return new ViewAttributeSet(v);
|
||||
@ -389,6 +401,7 @@ public class StyleSheet extends StyleContext {
|
||||
* any previously added style sheets. An added StyleSheet will never
|
||||
* override the rules of the receiving style sheet.
|
||||
*
|
||||
* @param ss a StyleSheet
|
||||
* @since 1.3
|
||||
*/
|
||||
public void addStyleSheet(StyleSheet ss) {
|
||||
@ -411,6 +424,7 @@ public class StyleSheet extends StyleContext {
|
||||
/**
|
||||
* Removes the StyleSheet <code>ss</code> from those of the receiver.
|
||||
*
|
||||
* @param ss a StyleSheet
|
||||
* @since 1.3
|
||||
*/
|
||||
public void removeStyleSheet(StyleSheet ss) {
|
||||
@ -436,6 +450,7 @@ public class StyleSheet extends StyleContext {
|
||||
* Returns an array of the linked StyleSheets. Will return null
|
||||
* if there are no linked StyleSheets.
|
||||
*
|
||||
* @return an array of StyleSheets.
|
||||
* @since 1.3
|
||||
*/
|
||||
public StyleSheet[] getStyleSheets() {
|
||||
@ -459,6 +474,7 @@ public class StyleSheet extends StyleContext {
|
||||
* to become part of the receiver, create a new StyleSheet and use
|
||||
* addStyleSheet to link it in.
|
||||
*
|
||||
* @param url an url
|
||||
* @since 1.3
|
||||
*/
|
||||
public void importStyleSheet(URL url) {
|
||||
@ -481,6 +497,7 @@ public class StyleSheet extends StyleContext {
|
||||
* Sets the base. All import statements that are relative, will be
|
||||
* relative to <code>base</code>.
|
||||
*
|
||||
* @param base a base.
|
||||
* @since 1.3
|
||||
*/
|
||||
public void setBase(URL base) {
|
||||
@ -490,6 +507,7 @@ public class StyleSheet extends StyleContext {
|
||||
/**
|
||||
* Returns the base.
|
||||
*
|
||||
* @return the base.
|
||||
* @since 1.3
|
||||
*/
|
||||
public URL getBase() {
|
||||
@ -499,6 +517,9 @@ public class StyleSheet extends StyleContext {
|
||||
/**
|
||||
* Adds a CSS attribute to the given set.
|
||||
*
|
||||
* @param attr a set of attributes
|
||||
* @param key a CSS property
|
||||
* @param value an HTML attribute value
|
||||
* @since 1.3
|
||||
*/
|
||||
public void addCSSAttribute(MutableAttributeSet attr, CSS.Attribute key,
|
||||
@ -509,6 +530,11 @@ public class StyleSheet extends StyleContext {
|
||||
/**
|
||||
* Adds a CSS attribute to the given set.
|
||||
*
|
||||
* @param attr a set of attributes
|
||||
* @param key a CSS property
|
||||
* @param value an HTML attribute value
|
||||
* @return {@code true} if an HTML attribute {@code value} can be converted
|
||||
* to a CSS attribute, false otherwise.
|
||||
* @since 1.3
|
||||
*/
|
||||
public boolean addCSSAttributeFromHTML(MutableAttributeSet attr,
|
||||
@ -528,6 +554,7 @@ public class StyleSheet extends StyleContext {
|
||||
* set of CSS attributes.
|
||||
*
|
||||
* @param htmlAttrSet AttributeSet containing the HTML attributes.
|
||||
* @return the set of CSS attributes.
|
||||
*/
|
||||
public AttributeSet translateHTMLToCSS(AttributeSet htmlAttrSet) {
|
||||
AttributeSet cssAttrSet = css.translateHTMLToCSS(htmlAttrSet);
|
||||
@ -918,6 +945,9 @@ public class StyleSheet extends StyleContext {
|
||||
/**
|
||||
* Fetches the box formatter to use for the given set
|
||||
* of CSS attributes.
|
||||
*
|
||||
* @param a a set of CSS attributes
|
||||
* @return the box formatter.
|
||||
*/
|
||||
public BoxPainter getBoxPainter(AttributeSet a) {
|
||||
return new BoxPainter(a, css, this);
|
||||
@ -926,6 +956,9 @@ public class StyleSheet extends StyleContext {
|
||||
/**
|
||||
* Fetches the list formatter to use for the given set
|
||||
* of CSS attributes.
|
||||
*
|
||||
* @param a a set of CSS attributes
|
||||
* @return the list formatter.
|
||||
*/
|
||||
public ListPainter getListPainter(AttributeSet a) {
|
||||
return new ListPainter(a, this);
|
||||
@ -933,6 +966,8 @@ public class StyleSheet extends StyleContext {
|
||||
|
||||
/**
|
||||
* Sets the base font size, with valid values between 1 and 7.
|
||||
*
|
||||
* @param sz a font size.
|
||||
*/
|
||||
public void setBaseFontSize(int sz) {
|
||||
css.setBaseFontSize(sz);
|
||||
@ -942,17 +977,29 @@ public class StyleSheet extends StyleContext {
|
||||
* Sets the base font size from the passed in String. The string
|
||||
* can either identify a specific font size, with legal values between
|
||||
* 1 and 7, or identify a relative font size such as +1 or -2.
|
||||
*
|
||||
* @param size a font size.
|
||||
*/
|
||||
public void setBaseFontSize(String size) {
|
||||
css.setBaseFontSize(size);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Returns the index of HTML/CSS size model.
|
||||
*
|
||||
* @param pt a size of point
|
||||
* @return the index of HTML/CSS size model.
|
||||
*/
|
||||
public static int getIndexOfSize(float pt) {
|
||||
return CSS.getIndexOfSize(pt, sizeMapDefault);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the point size, given a size index.
|
||||
*
|
||||
* @param index a size index
|
||||
* @return the point size value.
|
||||
*/
|
||||
public float getPointSize(int index) {
|
||||
return css.getPointSize(index, this);
|
||||
@ -961,6 +1008,9 @@ public class StyleSheet extends StyleContext {
|
||||
/**
|
||||
* Given a string such as "+2", "-2", or "2",
|
||||
* returns a point size value.
|
||||
*
|
||||
* @param size a CSS string describing font size
|
||||
* @return the point size value.
|
||||
*/
|
||||
public float getPointSize(String size) {
|
||||
return css.getPointSize(size, this);
|
||||
@ -971,6 +1021,9 @@ public class StyleSheet extends StyleContext {
|
||||
* Note: This will only convert the HTML3.2 color strings
|
||||
* or a string of length 7;
|
||||
* otherwise, it will return null.
|
||||
*
|
||||
* @param string color string such as "RED" or "#NNNNNN"
|
||||
* @return the color
|
||||
*/
|
||||
public Color stringToColor(String string) {
|
||||
return CSS.stringToColor(string);
|
||||
@ -1822,6 +1875,7 @@ public class StyleSheet extends StyleContext {
|
||||
* @param v the view making the request. This is
|
||||
* used to get the AttributeSet, and may be used to
|
||||
* resolve percentage arguments.
|
||||
* @return the inset needed for the margin, border and padding.
|
||||
* @exception IllegalArgumentException for an invalid direction
|
||||
*/
|
||||
public float getInset(int side, View v) {
|
||||
|
||||
@ -47,11 +47,35 @@ import java.io.*;
|
||||
@SuppressWarnings("serial") // Same-version serialization only
|
||||
public final
|
||||
class AttributeList implements DTDConstants, Serializable {
|
||||
|
||||
/**
|
||||
* The attribute name
|
||||
*/
|
||||
public String name;
|
||||
|
||||
/**
|
||||
* The attribute type
|
||||
*/
|
||||
public int type;
|
||||
|
||||
/**
|
||||
* The possible attribute values
|
||||
*/
|
||||
public Vector<?> values;
|
||||
|
||||
/**
|
||||
* The attribute modifier
|
||||
*/
|
||||
public int modifier;
|
||||
|
||||
/**
|
||||
* The default attribute value
|
||||
*/
|
||||
public String value;
|
||||
|
||||
/**
|
||||
* The next attribute in the list
|
||||
*/
|
||||
public AttributeList next;
|
||||
|
||||
AttributeList() {
|
||||
@ -171,11 +195,23 @@ class AttributeList implements DTDConstants, Serializable {
|
||||
attributeTypes.put("implied", Integer.valueOf(IMPLIED));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an attribute name to the type
|
||||
*
|
||||
* @param nm an attribute name
|
||||
* @return the type
|
||||
*/
|
||||
public static int name2type(String nm) {
|
||||
Integer i = (Integer)attributeTypes.get(nm);
|
||||
return (i == null) ? CDATA : i.intValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a type to the attribute name
|
||||
*
|
||||
* @param tp a type
|
||||
* @return the attribute name
|
||||
*/
|
||||
public static String type2name(int tp) {
|
||||
return (String)attributeTypes.get(Integer.valueOf(tp));
|
||||
}
|
||||
|
||||
@ -57,6 +57,9 @@ public final class ContentModel implements Serializable {
|
||||
*/
|
||||
public ContentModel next;
|
||||
|
||||
/**
|
||||
* Creates {@code ContentModel}
|
||||
*/
|
||||
public ContentModel() {
|
||||
}
|
||||
|
||||
|
||||
@ -57,27 +57,91 @@ import java.net.URL;
|
||||
*/
|
||||
public
|
||||
class DTD implements DTDConstants {
|
||||
|
||||
/**
|
||||
* the name of the DTD
|
||||
*/
|
||||
public String name;
|
||||
|
||||
/**
|
||||
* The vector of elements
|
||||
*/
|
||||
public Vector<Element> elements = new Vector<Element>();
|
||||
|
||||
/**
|
||||
* The hash table contains the name of element and
|
||||
* the corresponding element.
|
||||
*/
|
||||
public Hashtable<String,Element> elementHash
|
||||
= new Hashtable<String,Element>();
|
||||
|
||||
/**
|
||||
* The hash table contains an {@code Object} and the corresponding {@code Entity}
|
||||
*/
|
||||
public Hashtable<Object,Entity> entityHash
|
||||
= new Hashtable<Object,Entity>();
|
||||
|
||||
/**
|
||||
* The element corresponding to pcdata.
|
||||
*/
|
||||
public final Element pcdata = getElement("#pcdata");
|
||||
|
||||
/**
|
||||
* The element corresponding to html.
|
||||
*/
|
||||
public final Element html = getElement("html");
|
||||
|
||||
/**
|
||||
* The element corresponding to meta.
|
||||
*/
|
||||
public final Element meta = getElement("meta");
|
||||
|
||||
/**
|
||||
* The element corresponding to base.
|
||||
*/
|
||||
public final Element base = getElement("base");
|
||||
|
||||
/**
|
||||
* The element corresponding to isindex.
|
||||
*/
|
||||
public final Element isindex = getElement("isindex");
|
||||
|
||||
/**
|
||||
* The element corresponding to head.
|
||||
*/
|
||||
public final Element head = getElement("head");
|
||||
|
||||
/**
|
||||
* The element corresponding to body.
|
||||
*/
|
||||
public final Element body = getElement("body");
|
||||
|
||||
/**
|
||||
* The element corresponding to applet.
|
||||
*/
|
||||
public final Element applet = getElement("applet");
|
||||
|
||||
/**
|
||||
* The element corresponding to param.
|
||||
*/
|
||||
public final Element param = getElement("param");
|
||||
|
||||
/**
|
||||
* The element corresponding to p.
|
||||
*/
|
||||
public final Element p = getElement("p");
|
||||
|
||||
/**
|
||||
* The element corresponding to title.
|
||||
*/
|
||||
public final Element title = getElement("title");
|
||||
final Element style = getElement("style");
|
||||
final Element link = getElement("link");
|
||||
final Element script = getElement("script");
|
||||
|
||||
/**
|
||||
* The version of a file
|
||||
*/
|
||||
public static final int FILE_VERSION = 1;
|
||||
|
||||
/**
|
||||
@ -344,6 +408,12 @@ class DTD implements DTDConstants {
|
||||
*/
|
||||
private static final Object DTD_HASH_KEY = new Object();
|
||||
|
||||
/**
|
||||
* Put a name and appropriate DTD to hashtable.
|
||||
*
|
||||
* @param name the name of the DTD
|
||||
* @param dtd the DTD
|
||||
*/
|
||||
public static void putDTDHash(String name, DTD dtd) {
|
||||
getDtdHash().put(name, dtd);
|
||||
}
|
||||
|
||||
@ -37,46 +37,186 @@ package javax.swing.text.html.parser;
|
||||
public
|
||||
interface DTDConstants {
|
||||
// Attribute value types
|
||||
|
||||
/**
|
||||
* The DTD constant corresponds to CDATA
|
||||
*/
|
||||
int CDATA = 1;
|
||||
|
||||
/**
|
||||
* The DTD constant corresponds to ENTITY
|
||||
*/
|
||||
int ENTITY = 2;
|
||||
|
||||
/**
|
||||
* The DTD constant corresponds to ENTITIES
|
||||
*/
|
||||
int ENTITIES = 3;
|
||||
|
||||
/**
|
||||
* The DTD constant corresponds to ID
|
||||
*/
|
||||
int ID = 4;
|
||||
|
||||
/**
|
||||
* The DTD constant corresponds to IDREF
|
||||
*/
|
||||
int IDREF = 5;
|
||||
|
||||
/**
|
||||
* The DTD constant corresponds to IDREFS
|
||||
*/
|
||||
int IDREFS = 6;
|
||||
|
||||
/**
|
||||
* The DTD constant corresponds to NAME
|
||||
*/
|
||||
int NAME = 7;
|
||||
|
||||
/**
|
||||
* The DTD constant corresponds to NAMES
|
||||
*/
|
||||
int NAMES = 8;
|
||||
|
||||
/**
|
||||
* The DTD constant corresponds to NMTOKEN
|
||||
*/
|
||||
int NMTOKEN = 9;
|
||||
|
||||
/**
|
||||
* The DTD constant corresponds to NMTOKENS
|
||||
*/
|
||||
int NMTOKENS = 10;
|
||||
|
||||
/**
|
||||
* The DTD constant corresponds to NOTATION
|
||||
*/
|
||||
int NOTATION = 11;
|
||||
|
||||
/**
|
||||
* The DTD constant corresponds to NUMBER
|
||||
*/
|
||||
int NUMBER = 12;
|
||||
|
||||
/**
|
||||
* The DTD constant corresponds to NUMBERS
|
||||
*/
|
||||
int NUMBERS = 13;
|
||||
|
||||
/**
|
||||
* The DTD constant corresponds to NUTOKEN
|
||||
*/
|
||||
int NUTOKEN = 14;
|
||||
|
||||
/**
|
||||
* The DTD constant corresponds to NUTOKENS
|
||||
*/
|
||||
int NUTOKENS = 15;
|
||||
|
||||
// Content model types
|
||||
|
||||
/**
|
||||
* The DTD constant corresponds to RCDATA
|
||||
*/
|
||||
int RCDATA = 16;
|
||||
|
||||
/**
|
||||
* The DTD constant corresponds to EMPTY
|
||||
*/
|
||||
int EMPTY = 17;
|
||||
|
||||
/**
|
||||
* The DTD constant corresponds to MODEL
|
||||
*/
|
||||
int MODEL = 18;
|
||||
|
||||
/**
|
||||
* The DTD constant corresponds to ANY
|
||||
*/
|
||||
int ANY = 19;
|
||||
|
||||
// Attribute value modifiers
|
||||
|
||||
/**
|
||||
* The DTD constant corresponds to FIXED
|
||||
*/
|
||||
int FIXED = 1;
|
||||
|
||||
/**
|
||||
* The DTD constant corresponds to REQUIRED
|
||||
*/
|
||||
int REQUIRED = 2;
|
||||
|
||||
/**
|
||||
* The DTD constant corresponds to CURRENT
|
||||
*/
|
||||
int CURRENT = 3;
|
||||
|
||||
/**
|
||||
* The DTD constant corresponds to CONREF
|
||||
*/
|
||||
int CONREF = 4;
|
||||
|
||||
/**
|
||||
* The DTD constant corresponds to IMPLIED
|
||||
*/
|
||||
int IMPLIED = 5;
|
||||
|
||||
// Entity types
|
||||
|
||||
/**
|
||||
* The DTD constant corresponds to PUBLIC
|
||||
*/
|
||||
int PUBLIC = 10;
|
||||
|
||||
/**
|
||||
* The DTD constant corresponds to SDATA
|
||||
*/
|
||||
int SDATA = 11;
|
||||
|
||||
/**
|
||||
* The DTD constant corresponds to PI
|
||||
*/
|
||||
int PI = 12;
|
||||
|
||||
/**
|
||||
* The DTD constant corresponds to STARTTAG
|
||||
*/
|
||||
int STARTTAG = 13;
|
||||
|
||||
/**
|
||||
* The DTD constant corresponds to ENDTAG
|
||||
*/
|
||||
int ENDTAG = 14;
|
||||
|
||||
/**
|
||||
* The DTD constant corresponds to MS
|
||||
*/
|
||||
int MS = 15;
|
||||
|
||||
/**
|
||||
* The DTD constant corresponds to MD
|
||||
*/
|
||||
int MD = 16;
|
||||
|
||||
/**
|
||||
* The DTD constant corresponds to SYSTEM
|
||||
*/
|
||||
int SYSTEM = 17;
|
||||
|
||||
/**
|
||||
* The DTD constant corresponds to GENERAL
|
||||
*/
|
||||
|
||||
int GENERAL = 1<<16;
|
||||
|
||||
/**
|
||||
* The DTD constant corresponds to DEFAULT
|
||||
*/
|
||||
int DEFAULT = 1<<17;
|
||||
|
||||
/**
|
||||
* The DTD constant corresponds to PARAMETER
|
||||
*/
|
||||
int PARAMETER = 1<<18;
|
||||
}
|
||||
|
||||
@ -112,11 +112,24 @@ public class DocumentParser extends javax.swing.text.html.parser.Parser {
|
||||
private boolean ignoreCharSet = false;
|
||||
private static final boolean debugFlag = false;
|
||||
|
||||
/**
|
||||
* Creates document parser with the specified {@code dtd}.
|
||||
*
|
||||
* @param dtd the dtd.
|
||||
*/
|
||||
public DocumentParser(DTD dtd) {
|
||||
super(dtd);
|
||||
}
|
||||
|
||||
public void parse(Reader in, HTMLEditorKit.ParserCallback callback, boolean ignoreCharSet) throws IOException {
|
||||
/**
|
||||
* Parse an HTML stream, given a DTD.
|
||||
*
|
||||
* @param in the reader to read the source from
|
||||
* @param callback the callback
|
||||
* @param ignoreCharSet if {@code true} the charset is ignored
|
||||
* @throws IOException if an I/O error occurs
|
||||
*/
|
||||
public void parse(Reader in, HTMLEditorKit.ParserCallback callback, boolean ignoreCharSet) throws IOException {
|
||||
this.ignoreCharSet = ignoreCharSet;
|
||||
this.callback = callback;
|
||||
parse(in);
|
||||
|
||||
@ -43,14 +43,50 @@ import sun.awt.AppContext;
|
||||
@SuppressWarnings("serial") // Same-version serialization only
|
||||
public final
|
||||
class Element implements DTDConstants, Serializable {
|
||||
|
||||
/**
|
||||
* The element index
|
||||
*/
|
||||
public int index;
|
||||
|
||||
/**
|
||||
* The name of the element
|
||||
*/
|
||||
public String name;
|
||||
|
||||
/**
|
||||
* {@code true} if the start tag can be omitted
|
||||
*/
|
||||
public boolean oStart;
|
||||
|
||||
/**
|
||||
* {@code true} if the end tag can be omitted
|
||||
*/
|
||||
public boolean oEnd;
|
||||
|
||||
/**
|
||||
* The set of elements that can occur inside the element
|
||||
*/
|
||||
public BitSet inclusions;
|
||||
|
||||
/**
|
||||
* The set of elements that must not occur inside the element
|
||||
*/
|
||||
public BitSet exclusions;
|
||||
|
||||
/**
|
||||
* The element type
|
||||
*/
|
||||
public int type = ANY;
|
||||
|
||||
/**
|
||||
* The content model
|
||||
*/
|
||||
public ContentModel content;
|
||||
|
||||
/**
|
||||
* The attributes
|
||||
*/
|
||||
public AttributeList atts;
|
||||
|
||||
/**
|
||||
@ -208,6 +244,14 @@ class Element implements DTDConstants, Serializable {
|
||||
contentTypes.put("ANY", Integer.valueOf(ANY));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts {@code nm} to type. Returns appropriate DTDConstants
|
||||
* if the {@code nm} is equal to CDATA, RCDATA, EMPTY or ANY, 0 otherwise.
|
||||
*
|
||||
* @param nm a name
|
||||
* @return appropriate DTDConstants if the {@code nm} is equal to
|
||||
* CDATA, RCDATA, EMPTY or ANY, 0 otherwise.
|
||||
*/
|
||||
public static int name2type(String nm) {
|
||||
Integer val = contentTypes.get(nm);
|
||||
return (val != null) ? val.intValue() : 0;
|
||||
|
||||
@ -42,8 +42,19 @@ import java.net.URL;
|
||||
*/
|
||||
public final
|
||||
class Entity implements DTDConstants {
|
||||
/**
|
||||
* The name of the entity.
|
||||
*/
|
||||
public String name;
|
||||
|
||||
/**
|
||||
* The type of the entity.
|
||||
*/
|
||||
public int type;
|
||||
|
||||
/**
|
||||
* The char array of data.
|
||||
*/
|
||||
public char data[];
|
||||
|
||||
/**
|
||||
|
||||
@ -88,6 +88,9 @@ class Parser implements DTDConstants {
|
||||
private char str[] = new char[128];
|
||||
private int strpos = 0;
|
||||
|
||||
/**
|
||||
* The dtd.
|
||||
*/
|
||||
protected DTD dtd = null;
|
||||
|
||||
private int ch;
|
||||
@ -198,6 +201,11 @@ class Parser implements DTDConstants {
|
||||
376 // Ÿ
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates parser with the specified {@code dtd}.
|
||||
*
|
||||
* @param dtd the dtd.
|
||||
*/
|
||||
public Parser(DTD dtd) {
|
||||
this.dtd = dtd;
|
||||
}
|
||||
@ -421,12 +429,32 @@ class Parser implements DTDConstants {
|
||||
handleError(ln, err + " " + arg1 + " " + arg2 + " " + arg3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes the error handler with the 3rd error message argument "?".
|
||||
*
|
||||
* @param err the error type
|
||||
* @param arg1 the 1st error message argument
|
||||
* @param arg2 the 2nd error message argument
|
||||
*/
|
||||
protected void error(String err, String arg1, String arg2) {
|
||||
error(err, arg1, arg2, "?");
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes the error handler with the 2nd and 3rd error message argument "?".
|
||||
*
|
||||
* @param err the error type
|
||||
* @param arg1 the 1st error message argument
|
||||
*/
|
||||
protected void error(String err, String arg1) {
|
||||
error(err, arg1, "?", "?");
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes the error handler with the 1st, 2nd and 3rd error message argument "?".
|
||||
*
|
||||
* @param err the error type
|
||||
*/
|
||||
protected void error(String err) {
|
||||
error(err, "?", "?", "?");
|
||||
}
|
||||
@ -2407,6 +2435,11 @@ class Parser implements DTDConstants {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the current position.
|
||||
*
|
||||
* @return the current position
|
||||
*/
|
||||
protected int getCurrentPos() {
|
||||
return currentPosition;
|
||||
}
|
||||
|
||||
@ -48,6 +48,9 @@ import java.security.PrivilegedAction;
|
||||
public class ParserDelegator extends HTMLEditorKit.Parser implements Serializable {
|
||||
private static final Object DTD_KEY = new Object();
|
||||
|
||||
/**
|
||||
* Sets the default DTD.
|
||||
*/
|
||||
protected static void setDefaultDTD() {
|
||||
getDefaultDTD();
|
||||
}
|
||||
@ -75,6 +78,13 @@ public class ParserDelegator extends HTMLEditorKit.Parser implements Serializabl
|
||||
return dtd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recreates a DTD from an archived format with the specified {@code name}.
|
||||
*
|
||||
* @param dtd a DTD
|
||||
* @param name the name of the resource, relative to the ParserDelegator class.
|
||||
* @return the DTD with the specified {@code name}.
|
||||
*/
|
||||
protected static DTD createDTD(DTD dtd, String name) {
|
||||
|
||||
InputStream in = null;
|
||||
@ -92,7 +102,9 @@ public class ParserDelegator extends HTMLEditorKit.Parser implements Serializabl
|
||||
return dtd;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates {@code ParserDelegator} with default DTD.
|
||||
*/
|
||||
public ParserDelegator() {
|
||||
setDefaultDTD();
|
||||
}
|
||||
@ -109,7 +121,7 @@ public class ParserDelegator extends HTMLEditorKit.Parser implements Serializabl
|
||||
*
|
||||
* @param name the name of the resource, relative to the
|
||||
* ParserDelegator class.
|
||||
* @returns a stream representing the resource
|
||||
* @return a stream representing the resource
|
||||
*/
|
||||
static InputStream getResourceAsStream(final String name) {
|
||||
return AccessController.doPrivileged(
|
||||
|
||||
@ -39,10 +39,21 @@ public class TagElement {
|
||||
HTML.Tag htmlTag;
|
||||
boolean insertedByErrorRecovery;
|
||||
|
||||
public TagElement ( Element elem ) {
|
||||
/**
|
||||
* Creates a generic HTML TagElement class with {@code fictional} equals to {@code false}.
|
||||
*
|
||||
* @param elem an element
|
||||
*/
|
||||
public TagElement(Element elem) {
|
||||
this(elem, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a generic HTML TagElement class.
|
||||
*
|
||||
* @param elem an element
|
||||
* @param fictional if {@code true} the tag is inserted by error recovery.
|
||||
*/
|
||||
public TagElement (Element elem, boolean fictional) {
|
||||
this.elem = elem;
|
||||
htmlTag = HTML.getTag(elem.getName());
|
||||
@ -52,22 +63,52 @@ public class TagElement {
|
||||
insertedByErrorRecovery = fictional;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if this tag causes a
|
||||
* line break to the flow of data, otherwise returns
|
||||
* {@code false}.
|
||||
*
|
||||
* @return {@code true} if this tag causes a
|
||||
* line break to the flow of data, otherwise returns
|
||||
* {@code false}
|
||||
*/
|
||||
public boolean breaksFlow() {
|
||||
return htmlTag.breaksFlow();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if this tag is pre-formatted.
|
||||
*
|
||||
* @return {@code true} if this tag is pre-formatted,
|
||||
* otherwise returns {@code false}
|
||||
*/
|
||||
public boolean isPreformatted() {
|
||||
return htmlTag.isPreformatted();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the element.
|
||||
*
|
||||
* @return the element
|
||||
*/
|
||||
public Element getElement() {
|
||||
return elem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the tag constant corresponding to the name of the {@code element}
|
||||
*
|
||||
* @return the tag constant corresponding to the name of the {@code element}
|
||||
*/
|
||||
public HTML.Tag getHTMLTag() {
|
||||
return htmlTag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the tag is fictional.
|
||||
*
|
||||
* @return {@code true} if the tag is fictional.
|
||||
*/
|
||||
public boolean fictional() {
|
||||
return insertedByErrorRecovery;
|
||||
}
|
||||
|
||||
@ -28,7 +28,7 @@ package javax.swing.tree;
|
||||
import javax.swing.event.TreeExpansionEvent;
|
||||
|
||||
/**
|
||||
* Exception used to stop and expand/collapse from happening.
|
||||
* Exception used to stop an expand/collapse from happening.
|
||||
* See <a
|
||||
href="http://docs.oracle.com/javase/tutorial/uiswing/events/treewillexpandlistener.html">How to Write a Tree-Will-Expand Listener</a>
|
||||
* in <em>The Java Tutorial</em>
|
||||
|
||||
@ -550,6 +550,7 @@ public class InsnList {
|
||||
}
|
||||
|
||||
// this class is not generified because it will create bridges
|
||||
@SuppressWarnings("rawtypes")
|
||||
private final class InsnListIterator implements ListIterator {
|
||||
|
||||
AbstractInsnNode next;
|
||||
|
||||
@ -399,6 +399,7 @@ public class MethodNode extends MethodVisitor {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public AnnotationVisitor visitParameterAnnotation(final int parameter,
|
||||
final String desc, final boolean visible) {
|
||||
AnnotationNode an = new AnnotationNode(desc);
|
||||
|
||||
@ -131,6 +131,7 @@ public class Analyzer<V extends Value> implements Opcodes {
|
||||
* @throws AnalyzerException
|
||||
* if a problem occurs during the analysis.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Frame<V>[] analyze(final String owner, final MethodNode m)
|
||||
throws AnalyzerException {
|
||||
if ((m.access & (ACC_ABSTRACT | ACC_NATIVE)) != 0) {
|
||||
|
||||
@ -112,6 +112,7 @@ public class Frame<V extends Value> {
|
||||
* @param nStack
|
||||
* the maximum stack size of the frame.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Frame(final int nLocals, final int nStack) {
|
||||
this.values = (V[]) new Value[nLocals + nStack];
|
||||
this.locals = nLocals;
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
Path: .
|
||||
Working Copy Root Path: /hudson/jobs/objectweb-pull/workspace/asm-svn-2014-05-27
|
||||
Working Copy Root Path: /hudson/jobs/objectweb-pull/workspace/asm-svn-2014-06-19
|
||||
URL: file:///svnroot/asm/trunk/asm
|
||||
Repository Root: file:///svnroot/asm
|
||||
Repository UUID: 271bd773-ee82-43a6-9b2b-1890ed8ce7f9
|
||||
Revision: 1748
|
||||
Revision: 1750
|
||||
Node Kind: directory
|
||||
Schedule: normal
|
||||
Last Changed Author: ebruneton
|
||||
Last Changed Rev: 1747
|
||||
Last Changed Date: 2014-05-24 10:22:13 +0200 (Sat, 24 May 2014)
|
||||
Last Changed Author: forax
|
||||
Last Changed Rev: 1750
|
||||
Last Changed Date: 2014-06-06 00:31:02 +0200 (Fri, 06 Jun 2014)
|
||||
|
||||
|
||||
@ -31,10 +31,13 @@
|
||||
package sun.security.krb5;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FilePermission;
|
||||
import java.nio.file.DirectoryStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.Path;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.*;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
@ -196,8 +199,11 @@ public class Config {
|
||||
}
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
// I/O error, mostly like krb5.conf missing.
|
||||
// No problem. We'll use DNS or system property etc.
|
||||
if (DEBUG) {
|
||||
System.out.println("Exception thrown in loading config:");
|
||||
ioe.printStackTrace(System.out);
|
||||
}
|
||||
throw new KrbException("krb5.conf loading failed");
|
||||
}
|
||||
}
|
||||
|
||||
@ -206,7 +212,7 @@ public class Config {
|
||||
* @param keys the keys, as an array from section name, sub-section names
|
||||
* (if any), to value name.
|
||||
* @return the value. When there are multiple values for the same key,
|
||||
* returns the last one. {@code null} is returned if not all the keys are
|
||||
* returns the first one. {@code null} is returned if not all the keys are
|
||||
* defined. For example, {@code get("libdefaults", "forwardable")} will
|
||||
* return null if "forwardable" is not defined in [libdefaults], and
|
||||
* {@code get("realms", "R", "kdc")} will return null if "R" is not
|
||||
@ -223,7 +229,7 @@ public class Config {
|
||||
public String get(String... keys) {
|
||||
Vector<String> v = getString0(keys);
|
||||
if (v == null) return null;
|
||||
return v.lastElement();
|
||||
return v.firstElement();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -273,7 +279,7 @@ public class Config {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if keys exists, can be either final string(s) or sub-stanza
|
||||
* Returns true if keys exists, can be final string(s) or a sub-section
|
||||
* @throws IllegalArgumentException if any of the keys is illegal
|
||||
* (See {@link #get})
|
||||
*/
|
||||
@ -291,9 +297,9 @@ public class Config {
|
||||
}
|
||||
}
|
||||
|
||||
// Internal method. Returns the value for keys, which can be a sub-stanza
|
||||
// or final string value(s).
|
||||
// The only method (except for toString) that reads stanzaTable directly.
|
||||
// Internal method. Returns the value for keys, which can be a sub-section
|
||||
// (as a Hashtable) or final string value(s) (as a Vector). This is the
|
||||
// only method (except for toString) that reads stanzaTable directly.
|
||||
@SuppressWarnings("unchecked")
|
||||
private Object get0(String... keys) {
|
||||
Object current = stanzaTable;
|
||||
@ -453,142 +459,207 @@ public class Config {
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads lines to the memory from the configuration file.
|
||||
* Reads the lines of the configuration file. All include and includedir
|
||||
* directives are resolved by calling this method recursively.
|
||||
*
|
||||
* Configuration file contains information about the default realm,
|
||||
* ticket parameters, location of the KDC and the admin server for
|
||||
* known realms, etc. The file is divided into sections. Each section
|
||||
* contains one or more name/value pairs with one pair per line. A
|
||||
* typical file would be:
|
||||
* <pre>
|
||||
* [libdefaults]
|
||||
* default_realm = EXAMPLE.COM
|
||||
* default_tgs_enctypes = des-cbc-md5
|
||||
* default_tkt_enctypes = des-cbc-md5
|
||||
* [realms]
|
||||
* EXAMPLE.COM = {
|
||||
* kdc = kerberos.example.com
|
||||
* kdc = kerberos-1.example.com
|
||||
* admin_server = kerberos.example.com
|
||||
* }
|
||||
* SAMPLE_COM = {
|
||||
* kdc = orange.sample.com
|
||||
* admin_server = orange.sample.com
|
||||
* }
|
||||
* [domain_realm]
|
||||
* blue.sample.com = TEST.SAMPLE.COM
|
||||
* .backup.com = EXAMPLE.COM
|
||||
* </pre>
|
||||
* @return an ordered list of strings representing the config file after
|
||||
* some initial processing, including:<ol>
|
||||
* <li> Comment lines and empty lines are removed
|
||||
* <li> "{" not at the end of a line is appended to the previous line
|
||||
* <li> The content of a section is also placed between "{" and "}".
|
||||
* <li> Lines are trimmed</ol>
|
||||
* @param file the krb5.conf file, must be absolute
|
||||
* @param content the lines. Comment and empty lines are removed,
|
||||
* all lines trimmed, include and includedir
|
||||
* directives resolved, unknown directives ignored
|
||||
* @param dups a set of Paths to check for possible infinite loop
|
||||
* @throws IOException if there is an I/O error
|
||||
* @throws KrbException if there is a file format error
|
||||
*/
|
||||
private List<String> loadConfigFile(final String fileName)
|
||||
throws IOException, KrbException {
|
||||
try {
|
||||
List<String> v = new ArrayList<>();
|
||||
try (BufferedReader br = new BufferedReader(new InputStreamReader(
|
||||
AccessController.doPrivileged(
|
||||
new PrivilegedExceptionAction<FileInputStream> () {
|
||||
public FileInputStream run() throws IOException {
|
||||
return new FileInputStream(fileName);
|
||||
}
|
||||
})))) {
|
||||
String line;
|
||||
String previous = null;
|
||||
while ((line = br.readLine()) != null) {
|
||||
line = line.trim();
|
||||
if (line.startsWith("#") || line.isEmpty()) {
|
||||
// ignore comments and blank line
|
||||
// Comments start with #.
|
||||
continue;
|
||||
}
|
||||
// In practice, a subsection might look like:
|
||||
// [realms]
|
||||
// EXAMPLE.COM =
|
||||
// {
|
||||
// kdc = kerberos.example.com
|
||||
// ...
|
||||
// }
|
||||
// Before parsed into stanza table, it needs to be
|
||||
// converted into a canonicalized style (no indent):
|
||||
// realms = {
|
||||
// EXAMPLE.COM = {
|
||||
// kdc = kerberos.example.com
|
||||
// ...
|
||||
// }
|
||||
// }
|
||||
//
|
||||
if (line.startsWith("[")) {
|
||||
if (!line.endsWith("]")) {
|
||||
throw new KrbException("Illegal config content:"
|
||||
+ line);
|
||||
}
|
||||
if (previous != null) {
|
||||
v.add(previous);
|
||||
v.add("}");
|
||||
}
|
||||
String title = line.substring(
|
||||
1, line.length()-1).trim();
|
||||
if (title.isEmpty()) {
|
||||
throw new KrbException("Illegal config content:"
|
||||
+ line);
|
||||
}
|
||||
previous = title + " = {";
|
||||
} else if (line.startsWith("{")) {
|
||||
if (previous == null) {
|
||||
throw new KrbException(
|
||||
"Config file should not start with \"{\"");
|
||||
}
|
||||
previous += " {";
|
||||
if (line.length() > 1) {
|
||||
// { and content on the same line
|
||||
v.add(previous);
|
||||
previous = line.substring(1).trim();
|
||||
}
|
||||
} else {
|
||||
// Lines before the first section are ignored
|
||||
if (previous != null) {
|
||||
v.add(previous);
|
||||
previous = line;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (previous != null) {
|
||||
v.add(previous);
|
||||
v.add("}");
|
||||
}
|
||||
}
|
||||
return v;
|
||||
} catch (java.security.PrivilegedActionException pe) {
|
||||
throw (IOException)pe.getException();
|
||||
private static Void readConfigFileLines(
|
||||
Path file, List<String> content, Set<Path> dups)
|
||||
throws IOException {
|
||||
|
||||
if (DEBUG) {
|
||||
System.out.println("Loading krb5 profile at " + file);
|
||||
}
|
||||
if (!file.isAbsolute()) {
|
||||
throw new IOException("Profile path not absolute");
|
||||
}
|
||||
|
||||
if (!dups.add(file)) {
|
||||
throw new IOException("Profile path included more than once");
|
||||
}
|
||||
|
||||
List<String> lines = Files.readAllLines(file);
|
||||
|
||||
boolean inDirectives = true;
|
||||
for (String line: lines) {
|
||||
line = line.trim();
|
||||
if (line.isEmpty() || line.startsWith("#")) {
|
||||
continue;
|
||||
}
|
||||
if (inDirectives) {
|
||||
if (line.charAt(0) == '[') {
|
||||
inDirectives = false;
|
||||
content.add(line);
|
||||
} else if (line.startsWith("includedir ")) {
|
||||
Path dir = Paths.get(
|
||||
line.substring("includedir ".length()).trim());
|
||||
try (DirectoryStream<Path> files =
|
||||
Files.newDirectoryStream(dir)) {
|
||||
for (Path p: files) {
|
||||
if (Files.isDirectory(p)) continue;
|
||||
String name = p.getFileName().toString();
|
||||
if (name.matches("[a-zA-Z0-9_-]+")) {
|
||||
// if dir is absolute, so is p
|
||||
readConfigFileLines(p, content, dups);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (line.startsWith("include ")) {
|
||||
readConfigFileLines(
|
||||
Paths.get(line.substring("include ".length()).trim()),
|
||||
content, dups);
|
||||
} else {
|
||||
// Unsupported directives
|
||||
if (DEBUG) {
|
||||
System.out.println("Unknown directive: " + line);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
content.add(line);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses stanza names and values from configuration file to
|
||||
* stanzaTable (Hashtable). Hashtable key would be stanza names,
|
||||
* (libdefaults, realms, domain_realms, etc), and the hashtable value
|
||||
* would be another hashtable which contains the key-value pairs under
|
||||
* a stanza name. The value of this sub-hashtable can be another hashtable
|
||||
* containing another sub-sub-section or a vector of strings for
|
||||
* final values (even if there is only one value defined).
|
||||
* Reads the configuration file and return normalized lines.
|
||||
* If the original file is:
|
||||
*
|
||||
* [realms]
|
||||
* EXAMPLE.COM =
|
||||
* {
|
||||
* kdc = kerberos.example.com
|
||||
* ...
|
||||
* }
|
||||
* ...
|
||||
*
|
||||
* The result will be (no indentations):
|
||||
*
|
||||
* {
|
||||
* realms = {
|
||||
* EXAMPLE.COM = {
|
||||
* kdc = kerberos.example.com
|
||||
* ...
|
||||
* }
|
||||
* }
|
||||
* ...
|
||||
* }
|
||||
*
|
||||
* @param fileName the configuration file
|
||||
* @return normalized lines
|
||||
*/
|
||||
private List<String> loadConfigFile(final String fileName)
|
||||
throws IOException, KrbException {
|
||||
|
||||
List<String> result = new ArrayList<>();
|
||||
List<String> raw = new ArrayList<>();
|
||||
Set<Path> dupsCheck = new HashSet<>();
|
||||
|
||||
try {
|
||||
Path fullp = AccessController.doPrivileged((PrivilegedAction<Path>)
|
||||
() -> Paths.get(fileName).toAbsolutePath(),
|
||||
null,
|
||||
new PropertyPermission("user.dir", "read"));
|
||||
AccessController.doPrivileged(
|
||||
new PrivilegedExceptionAction<Void>() {
|
||||
@Override
|
||||
public Void run() throws IOException {
|
||||
Path path = Paths.get(fileName);
|
||||
if (!Files.exists(path)) {
|
||||
// This is OK. There are other ways to get
|
||||
// Kerberos 5 settings
|
||||
return null;
|
||||
} else {
|
||||
return readConfigFileLines(
|
||||
fullp, raw, dupsCheck);
|
||||
}
|
||||
}
|
||||
},
|
||||
null,
|
||||
// include/includedir can go anywhere
|
||||
new FilePermission("<<ALL FILES>>", "read"));
|
||||
} catch (java.security.PrivilegedActionException pe) {
|
||||
throw (IOException)pe.getException();
|
||||
}
|
||||
String previous = null;
|
||||
for (String line: raw) {
|
||||
if (line.startsWith("[")) {
|
||||
if (!line.endsWith("]")) {
|
||||
throw new KrbException("Illegal config content:"
|
||||
+ line);
|
||||
}
|
||||
if (previous != null) {
|
||||
result.add(previous);
|
||||
result.add("}");
|
||||
}
|
||||
String title = line.substring(
|
||||
1, line.length()-1).trim();
|
||||
if (title.isEmpty()) {
|
||||
throw new KrbException("Illegal config content:"
|
||||
+ line);
|
||||
}
|
||||
previous = title + " = {";
|
||||
} else if (line.startsWith("{")) {
|
||||
if (previous == null) {
|
||||
throw new KrbException(
|
||||
"Config file should not start with \"{\"");
|
||||
}
|
||||
previous += " {";
|
||||
if (line.length() > 1) {
|
||||
// { and content on the same line
|
||||
result.add(previous);
|
||||
previous = line.substring(1).trim();
|
||||
}
|
||||
} else {
|
||||
if (previous == null) {
|
||||
// This won't happen, because before a section
|
||||
// all directives have been resolved
|
||||
throw new KrbException(
|
||||
"Config file must starts with a section");
|
||||
}
|
||||
result.add(previous);
|
||||
previous = line;
|
||||
}
|
||||
}
|
||||
if (previous != null) {
|
||||
result.add(previous);
|
||||
result.add("}");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the input lines to a hashtable. The key would be section names
|
||||
* (libdefaults, realms, domain_realms, etc), and the value would be
|
||||
* another hashtable which contains the key-value pairs inside the section.
|
||||
* The value of this sub-hashtable can be another hashtable containing
|
||||
* another sub-sub-section or a non-empty vector of strings for final values
|
||||
* (even if there is only one value defined).
|
||||
* <p>
|
||||
* For duplicates section names, the latter overwrites the former. For
|
||||
* duplicate value names, the values are in a vector in its appearing order.
|
||||
* </ol>
|
||||
* Please note that this behavior is Java traditional. and it is
|
||||
* not the same as the MIT krb5 behavior, where:<ol>
|
||||
* <li>Duplicated root sections will be merged
|
||||
* <li>For duplicated sub-sections, the former overwrites the latter
|
||||
* <li>Duplicate keys for values are always saved in a vector
|
||||
* </ol>
|
||||
* @param v the strings in the file, never null, might be empty
|
||||
* For top-level sections with duplicates names, their contents are merged.
|
||||
* For sub-sections the former overwrites the latter. For final values,
|
||||
* they are stored in a vector in their appearing order. Please note these
|
||||
* values must appear in the same sub-section. Otherwise, the sub-section
|
||||
* appears first should have already overridden the others.
|
||||
* <p>
|
||||
* As a corner case, if the same name is used as both a section name and a
|
||||
* value name, the first appearance decides the type. That is to say, if the
|
||||
* first one is for a section, all latter appearances are ignored. If it's
|
||||
* a value, latter appearances as sections are ignored, but those as values
|
||||
* are added to the vector.
|
||||
* <p>
|
||||
* The behavior described above is compatible to other krb5 implementations
|
||||
* but it's not decumented publicly anywhere. the best practice is not to
|
||||
* assume any kind of override functionality and only specify values for
|
||||
* a particular key in one place.
|
||||
*
|
||||
* @param v the normalized input as return by loadConfigFile
|
||||
* @throws KrbException if there is a file format error
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@ -596,7 +667,7 @@ public class Config {
|
||||
throws KrbException {
|
||||
Hashtable<String,Object> current = stanzaTable;
|
||||
for (String line: v) {
|
||||
// There are 3 kinds of lines
|
||||
// There are only 3 kinds of lines
|
||||
// 1. a = b
|
||||
// 2. a = {
|
||||
// 3. }
|
||||
@ -612,14 +683,25 @@ public class Config {
|
||||
throw new KrbException("Illegal config content:" + line);
|
||||
}
|
||||
String key = line.substring(0, pos).trim();
|
||||
String value = trimmed(line.substring(pos+1));
|
||||
String value = unquote(line.substring(pos + 1));
|
||||
if (value.equals("{")) {
|
||||
Hashtable<String,Object> subTable;
|
||||
if (current == stanzaTable) {
|
||||
key = key.toLowerCase(Locale.US);
|
||||
}
|
||||
subTable = new Hashtable<>();
|
||||
current.put(key, subTable);
|
||||
// When there are dup names for sections
|
||||
if (current.containsKey(key)) {
|
||||
if (current == stanzaTable) { // top-level, merge
|
||||
// The value at top-level must be another Hashtable
|
||||
subTable = (Hashtable<String,Object>)current.get(key);
|
||||
} else { // otherwise, ignored
|
||||
// read and ignore it (do not put into current)
|
||||
subTable = new Hashtable<>();
|
||||
}
|
||||
} else {
|
||||
subTable = new Hashtable<>();
|
||||
current.put(key, subTable);
|
||||
}
|
||||
// A special entry for its parent. Put whitespaces around,
|
||||
// so will never be confused with a normal key
|
||||
subTable.put(" PARENT ", current);
|
||||
@ -628,20 +710,19 @@ public class Config {
|
||||
Vector<String> values;
|
||||
if (current.containsKey(key)) {
|
||||
Object obj = current.get(key);
|
||||
// If a key first shows as a section and then a value,
|
||||
// this is illegal. However, we haven't really forbid
|
||||
// first value then section, which the final result
|
||||
// is a section.
|
||||
if (!(obj instanceof Vector)) {
|
||||
throw new KrbException("Key " + key
|
||||
+ "used for both value and section");
|
||||
if (obj instanceof Vector) {
|
||||
// String values are merged
|
||||
values = (Vector<String>)obj;
|
||||
values.add(value);
|
||||
} else {
|
||||
// If a key shows as section first and then a value,
|
||||
// ignore the value.
|
||||
}
|
||||
values = (Vector<String>)current.get(key);
|
||||
} else {
|
||||
values = new Vector<String>();
|
||||
values.add(value);
|
||||
current.put(key, values);
|
||||
}
|
||||
values.add(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -764,7 +845,7 @@ public class Config {
|
||||
return "/etc/krb5.conf";
|
||||
}
|
||||
|
||||
private static String trimmed(String s) {
|
||||
private static String unquote(String s) {
|
||||
s = s.trim();
|
||||
if (s.isEmpty()) return s;
|
||||
if (s.charAt(0) == '"' && s.charAt(s.length()-1) == '"' ||
|
||||
|
||||
@ -62,6 +62,13 @@ int main(int argc, char **argv) {
|
||||
return unpacker::run(argc, argv);
|
||||
}
|
||||
|
||||
// Dealing with big-endian arch
|
||||
#ifdef _BIG_ENDIAN
|
||||
#define SWAP_INT(a) (((a>>24)&0xff) | ((a<<8)&0xff0000) | ((a>>8)&0xff00) | ((a<<24)&0xff000000))
|
||||
#else
|
||||
#define SWAP_INT(a) (a)
|
||||
#endif
|
||||
|
||||
// Single-threaded, implementation, not reentrant.
|
||||
// Includes a weak error check against MT access.
|
||||
#ifndef THREAD_SELF
|
||||
@ -385,6 +392,7 @@ int unpacker::run(int argc, char **argv) {
|
||||
u.start();
|
||||
}
|
||||
} else {
|
||||
u.gzcrc = 0;
|
||||
u.start(peek, sizeof(peek));
|
||||
}
|
||||
|
||||
@ -425,7 +433,23 @@ int unpacker::run(int argc, char **argv) {
|
||||
status = 1;
|
||||
}
|
||||
|
||||
if (u.infileptr != null) {
|
||||
if (!u.aborting() && u.infileptr != null) {
|
||||
if (u.gzcrc != 0) {
|
||||
// Read the CRC information from the gzip container
|
||||
fseek(u.infileptr, -8, SEEK_END);
|
||||
uint filecrc;
|
||||
fread(&filecrc, sizeof(filecrc), 1, u.infileptr);
|
||||
if (u.gzcrc != SWAP_INT(filecrc)) { // CRC error
|
||||
if (strcmp(destination_file, "-") != 0) {
|
||||
// Output is not stdout, remove it, it's broken
|
||||
if (u.jarout != null)
|
||||
u.jarout->closeJarFile(false);
|
||||
remove(destination_file);
|
||||
}
|
||||
// Print out the error and exit with return code != 0
|
||||
u.abort("CRC error, invalid compressed data.");
|
||||
}
|
||||
}
|
||||
fclose(u.infileptr);
|
||||
u.infileptr = null;
|
||||
}
|
||||
|
||||
@ -171,6 +171,7 @@ struct unpacker {
|
||||
bytes inbytes; // direct
|
||||
gunzip* gzin; // gunzip filter, if any
|
||||
jar* jarout; // output JAR file
|
||||
uint gzcrc; // CRC gathered from gzip content
|
||||
|
||||
#ifndef PRODUCT
|
||||
int nowrite;
|
||||
|
||||
@ -435,7 +435,7 @@ uLong jar::get_dostime(int modtime) {
|
||||
struct tm* s = gmtime_r(&t, &sbuf);
|
||||
if (s == NULL) {
|
||||
fprintf(u->errstrm, "Error: gmtime failure, invalid input archive\n");
|
||||
exit(2);
|
||||
exit(-1);
|
||||
}
|
||||
modtime_cache = modtime;
|
||||
dostime_cache = dostime(s->tm_year + 1900, s->tm_mon + 1, s->tm_mday,
|
||||
@ -551,6 +551,7 @@ static jlong read_input_via_gzip(unpacker* u,
|
||||
break;
|
||||
}
|
||||
int nr = readlen - zs.avail_out;
|
||||
u->gzcrc = crc32(u->gzcrc, (const unsigned char *)bufptr, nr);
|
||||
numread += nr;
|
||||
bufptr += nr;
|
||||
assert(numread <= maxlen);
|
||||
@ -589,6 +590,7 @@ void gunzip::init(unpacker* u_) {
|
||||
zstream = NEW(z_stream, 1);
|
||||
u->gzin = this;
|
||||
u->read_input_fn = read_input_via_gzip;
|
||||
u->gzcrc = crc32(0L, Z_NULL, 0);
|
||||
}
|
||||
|
||||
void gunzip::start(int magic) {
|
||||
|
||||
@ -200,17 +200,6 @@ sysIPMutexEnter(sys_ipmutex_t mutex, sys_event_t event)
|
||||
rc = WaitForMultipleObjects(count, handles,
|
||||
FALSE, /* wait for either, not both */
|
||||
INFINITE); /* infinite timeout */
|
||||
|
||||
/* If the mutex is abandoned we will consider this a fatal error
|
||||
* and abort with appropriate message.
|
||||
*
|
||||
* Note that only mutexes can be abandoned and that our mutex is
|
||||
* always at position 0 in the handles array. Thus we only need
|
||||
* to check WAIT_ABANDONED_0 (not WAIT_ABANDONED_0 + x).
|
||||
*/
|
||||
if (rc == WAIT_ABANDONED_0) {
|
||||
exitTransportWithError("Observed abandoned IP mutex. Aborting.",THIS_FILE, __DATE__, __LINE__);
|
||||
}
|
||||
return (rc == WAIT_OBJECT_0) ? SYS_OK : SYS_ERR;
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user