This commit is contained in:
David Dehaven 2016-07-28 09:01:30 -07:00
commit dd116aa128
96 changed files with 2458 additions and 1786 deletions
jdk
make
src
test

@ -21,4 +21,4 @@
# or visit www.oracle.com if you need additional information or have any
# questions.
#
tzdata2016d
tzdata2016f

@ -366,6 +366,12 @@ Rule Egypt 2007 only - Sep Thu>=1 24:00 0 -
# decision to abandon DST permanently. See Ahram Online 2015-04-24.
# http://english.ahram.org.eg/NewsContent/1/64/128509/Egypt/Politics-/Sisi-cancels-daylight-saving-time-in-Egypt.aspx
# From Steffen Thorsen (2016-04-29):
# Egypt will have DST from July 7 until the end of October....
# http://english.ahram.org.eg/NewsContentP/1/204655/Egypt/Daylight-savings-time-returning-to-Egypt-on--July.aspx
# From Mina Samuel (2016-07-04):
# Egyptian government took the decision to cancel the DST,
Rule Egypt 2008 only - Aug lastThu 24:00 0 -
Rule Egypt 2009 only - Aug 20 24:00 0 -
Rule Egypt 2010 only - Aug 10 24:00 0 -
@ -881,11 +887,11 @@ Rule Morocco 2009 only - Aug 21 0:00 0 -
Rule Morocco 2010 only - May 2 0:00 1:00 S
Rule Morocco 2010 only - Aug 8 0:00 0 -
Rule Morocco 2011 only - Apr 3 0:00 1:00 S
Rule Morocco 2011 only - Jul 31 0 0 -
Rule Morocco 2011 only - Jul 31 0:00 0 -
Rule Morocco 2012 2013 - Apr lastSun 2:00 1:00 S
Rule Morocco 2012 only - Sep 30 3:00 0 -
Rule Morocco 2012 only - Jul 20 3:00 0 -
Rule Morocco 2012 only - Aug 20 2:00 1:00 S
Rule Morocco 2012 only - Sep 30 3:00 0 -
Rule Morocco 2013 only - Jul 7 3:00 0 -
Rule Morocco 2013 only - Aug 10 2:00 1:00 S
Rule Morocco 2013 max - Oct lastSun 3:00 0 -

@ -36,7 +36,7 @@
#
# Except for the French entries,
# I made up all time zone abbreviations mentioned here; corrections welcome!
# FORMAT is 'zzz' and GMTOFF is 0 for locations while uninhabited.
# FORMAT is '-00' and GMTOFF is 0 for locations while uninhabited.
# Argentina - year-round bases
# Belgrano II, Confin Coast, -770227-0343737, since 1972-02-05
@ -90,22 +90,22 @@
# http://www.timeanddate.com/news/time/antartica-time-changes-2010.html
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Antarctica/Casey 0 - zzz 1969
Zone Antarctica/Casey 0 - -00 1969
8:00 - AWST 2009 Oct 18 2:00
# Australian Western Std Time
11:00 - CAST 2010 Mar 5 2:00 # Casey Time
8:00 - AWST 2011 Oct 28 2:00
11:00 - CAST 2012 Feb 21 17:00u
8:00 - AWST
Zone Antarctica/Davis 0 - zzz 1957 Jan 13
Zone Antarctica/Davis 0 - -00 1957 Jan 13
7:00 - DAVT 1964 Nov # Davis Time
0 - zzz 1969 Feb
0 - -00 1969 Feb
7:00 - DAVT 2009 Oct 18 2:00
5:00 - DAVT 2010 Mar 10 20:00u
7:00 - DAVT 2011 Oct 28 2:00
5:00 - DAVT 2012 Feb 21 20:00u
7:00 - DAVT
Zone Antarctica/Mawson 0 - zzz 1954 Feb 13
Zone Antarctica/Mawson 0 - -00 1954 Feb 13
6:00 - MAWT 2009 Oct 18 2:00 # Mawson Time
5:00 - MAWT
# References:
@ -160,7 +160,7 @@ Zone Antarctica/Mawson 0 - zzz 1954 Feb 13
# fishing stations operated variously 1819/1931
#
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Indian/Kerguelen 0 - zzz 1950 # Port-aux-Français
Zone Indian/Kerguelen 0 - -00 1950 # Port-aux-Français
5:00 - TFT # ISO code TF Time
#
# year-round base in the main continent
@ -171,9 +171,9 @@ Zone Indian/Kerguelen 0 - zzz 1950 # Port-aux-Français
# It was destroyed by fire on 1952-01-14.
#
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Antarctica/DumontDUrville 0 - zzz 1947
Zone Antarctica/DumontDUrville 0 - -00 1947
10:00 - PMT 1952 Jan 14 # Port-Martin Time
0 - zzz 1956 Nov
0 - -00 1956 Nov
10:00 - DDUT # Dumont-d'Urville Time
# France & Italy - year-round base
@ -199,7 +199,7 @@ Zone Antarctica/DumontDUrville 0 - zzz 1947
# was established on 1957-01-29. Since Syowa station is still the main
# station of Japan, it's appropriate for the principal location.
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Antarctica/Syowa 0 - zzz 1957 Jan 29
Zone Antarctica/Syowa 0 - -00 1957 Jan 29
3:00 - SYOT # Syowa Time
# See:
# NIPR Antarctic Research Activities (1999-08-17)
@ -249,7 +249,7 @@ Rule Troll 2005 max - Mar lastSun 1:00u 2:00 CEST
# Remove the following line when uncommenting the above '#Rule' lines.
Rule Troll 2004 max - Oct lastSun 1:00u 0:00 UTC
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Antarctica/Troll 0 - zzz 2005 Feb 12
Zone Antarctica/Troll 0 - -00 2005 Feb 12
0:00 Troll %s
# Poland - year-round base
@ -290,7 +290,7 @@ Zone Antarctica/Troll 0 - zzz 2005 Feb 12
# happened to be during their visit. So we still don't really know what time
# it is at Vostok. But we'll guess UTC+6.
#
Zone Antarctica/Vostok 0 - zzz 1957 Dec 16
Zone Antarctica/Vostok 0 - -00 1957 Dec 16
6:00 - VOST # Vostok time
# S Africa - year-round bases
@ -323,7 +323,7 @@ Zone Antarctica/Vostok 0 - zzz 1957 Dec 16
# <http://webexhibits.org/daylightsaving/g.html> says Rothera is -03 all year.
#
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Antarctica/Rothera 0 - zzz 1976 Dec 1
Zone Antarctica/Rothera 0 - -00 1976 Dec 1
-3:00 - ROTT # Rothera time
# Uruguay - year round base

@ -169,7 +169,7 @@ Zone Asia/Baku 3:19:24 - LMT 1924 May 2
3:00 - BAKT 1957 Mar # Baku Time
4:00 RussiaAsia BAK%sT 1991 Mar 31 2:00s
3:00 1:00 BAKST 1991 Aug 30 # independence
3:00 RussiaAsia AZ%sT 1992 Sep lastSat 23:00
3:00 RussiaAsia AZ%sT 1992 Sep lastSun 2:00s
4:00 - AZT 1996 # Azerbaijan Time
4:00 EUAsia AZ%sT 1997
4:00 Azer AZ%sT

@ -266,11 +266,11 @@ Zone Australia/Lord_Howe 10:36:20 - LMT 1895 Feb
# will produce a binary file with an [A]EST-type as the first 32-bit type;
# this is required for correct handling of times before 1916 by
# pre-2013 versions of localtime.
Zone Antarctica/Macquarie 0 - zzz 1899 Nov
Zone Antarctica/Macquarie 0 - -00 1899 Nov
10:00 - AEST 1916 Oct 1 2:00
10:00 1:00 AEDT 1917 Feb
10:00 Aus AE%sT 1919 Apr 1 0:00s
0 - zzz 1948 Mar 25
0 - -00 1948 Mar 25
10:00 Aus AE%sT 1967
10:00 AT AE%sT 2010 Apr 4 3:00
11:00 - MIST # Macquarie I Standard Time

@ -778,6 +778,14 @@ Zone Europe/Vienna 1:05:21 - LMT 1893 Apr
1:00 EU CE%sT
# Belarus
#
# From Stepan Golosunov (2016-07-02):
# http://www.lawbelarus.com/repub/sub30/texf9611.htm
# (Act of the Cabinet of Ministers of the Republic of Belarus from
# 1992-03-25 No. 157) ... says clocks were to be moved forward at 2:00
# on last Sunday of March and backward at 3:00 on last Sunday of September
# (the same as previous USSR and contemporary Russian regulations).
#
# From Yauhen Kharuzhy (2011-09-16):
# By latest Belarus government act Europe/Minsk timezone was changed to
# GMT+3 without DST (was GMT+2 with DST).
@ -801,9 +809,6 @@ Zone Europe/Minsk 1:50:16 - LMT 1880
1:00 C-Eur CE%sT 1944 Jul 3
3:00 Russia MSK/MSD 1990
3:00 - MSK 1991 Mar 31 2:00s
2:00 1:00 EEST 1991 Sep 29 2:00s
2:00 - EET 1992 Mar 29 0:00s
2:00 1:00 EEST 1992 Sep 27 0:00s
2:00 Russia EE%sT 2011 Mar 27 2:00s
3:00 - FET 2014 Oct 26 1:00s
3:00 - MSK
@ -2746,14 +2751,22 @@ Zone Asia/Barnaul 5:35:00 - LMT 1919 Dec 10
# Asia/Novosibirsk covers:
# 54 RU-NVS Novosibirsk Oblast
# From Stepan Golosunov (2016-05-30):
# http://asozd2.duma.gov.ru/main.nsf/(Spravka)?OpenAgent&RN=1085784-6
# moves Novosibirsk oblast from UTC+6 to UTC+7.
# From Stepan Golosunov (2016-07-04):
# The law was signed yesterday and published today on
# http://publication.pravo.gov.ru/Document/View/0001201607040064
Zone Asia/Novosibirsk 5:31:40 - LMT 1919 Dec 14 6:00
6:00 - NOVT 1930 Jun 21 # Novosibirsk Time
7:00 Russia NOV%sT 1991 Mar 31 2:00s
6:00 Russia NOV%sT 1992 Jan 19 2:00s
7:00 Russia NOV%sT 1993 May 23 # say Shanks & P.
6:00 Russia NOV%sT 2011 Mar 27 2:00s
7:00 - NOVT 2014 Oct 26 2:00s
6:00 - NOVT
6:00 - +06 1930 Jun 21
7:00 Russia +07/+08 1991 Mar 31 2:00s
6:00 Russia +06/+07 1992 Jan 19 2:00s
7:00 Russia +07/+08 1993 May 23 # say Shanks & P.
6:00 Russia +06/+07 2011 Mar 27 2:00s
7:00 - +07 2014 Oct 26 2:00s
6:00 - +06 2016 Jul 24 2:00s
7:00 - +07
# From Paul Eggert (2016-03-18):
# Asia/Tomsk covers:
@ -2794,6 +2807,9 @@ Zone Asia/Novosibirsk 5:31:40 - LMT 1919 Dec 14 6:00
# approved by the Federation Council on 2016-04-20, signed by the President and
# published as a law around 2016-04-26.
# From Matt Johnson (2016-04-26):
# http://publication.pravo.gov.ru/Document/View/0001201604260048
Zone Asia/Tomsk 5:39:51 - LMT 1919 Dec 22
6:00 - +06 1930 Jun 21
7:00 Russia +07/+08 1991 Mar 31 2:00s
@ -2833,14 +2849,12 @@ Zone Asia/Tomsk 5:39:51 - LMT 1919 Dec 22
# realigning itself with KRAT.
Zone Asia/Novokuznetsk 5:48:48 - LMT 1924 May 1
6:00 - KRAT 1930 Jun 21 # Krasnoyarsk Time
7:00 Russia KRA%sT 1991 Mar 31 2:00s
6:00 Russia KRA%sT 1992 Jan 19 2:00s
7:00 Russia KRA%sT 2010 Mar 28 2:00s
6:00 Russia NOV%sT 2011 Mar 27 2:00s # Novosibirsk
7:00 - NOVT 2014 Oct 26 2:00s
7:00 - KRAT # Krasnoyarsk Time
6:00 - +06 1930 Jun 21
7:00 Russia +07/+08 1991 Mar 31 2:00s
6:00 Russia +06/+07 1992 Jan 19 2:00s
7:00 Russia +07/+08 2010 Mar 28 2:00s
6:00 Russia +06/+07 2011 Mar 27 2:00s
7:00 - +07
# From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2001-08-25):
# Asia/Krasnoyarsk covers...

@ -2214,39 +2214,39 @@ Rule NT_YK 1980 2006 - Oct lastSun 2:00 0 S
Rule NT_YK 1987 2006 - Apr Sun>=1 2:00 1:00 D
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
# aka Panniqtuuq
Zone America/Pangnirtung 0 - zzz 1921 # trading post est.
Zone America/Pangnirtung 0 - -00 1921 # trading post est.
-4:00 NT_YK A%sT 1995 Apr Sun>=1 2:00
-5:00 Canada E%sT 1999 Oct 31 2:00
-6:00 Canada C%sT 2000 Oct 29 2:00
-5:00 Canada E%sT
# formerly Frobisher Bay
Zone America/Iqaluit 0 - zzz 1942 Aug # Frobisher Bay est.
Zone America/Iqaluit 0 - -00 1942 Aug # Frobisher Bay est.
-5:00 NT_YK E%sT 1999 Oct 31 2:00
-6:00 Canada C%sT 2000 Oct 29 2:00
-5:00 Canada E%sT
# aka Qausuittuq
Zone America/Resolute 0 - zzz 1947 Aug 31 # Resolute founded
Zone America/Resolute 0 - -00 1947 Aug 31 # Resolute founded
-6:00 NT_YK C%sT 2000 Oct 29 2:00
-5:00 - EST 2001 Apr 1 3:00
-6:00 Canada C%sT 2006 Oct 29 2:00
-5:00 - EST 2007 Mar 11 3:00
-6:00 Canada C%sT
# aka Kangiqiniq
Zone America/Rankin_Inlet 0 - zzz 1957 # Rankin Inlet founded
Zone America/Rankin_Inlet 0 - -00 1957 # Rankin Inlet founded
-6:00 NT_YK C%sT 2000 Oct 29 2:00
-5:00 - EST 2001 Apr 1 3:00
-6:00 Canada C%sT
# aka Iqaluktuuttiaq
Zone America/Cambridge_Bay 0 - zzz 1920 # trading post est.?
Zone America/Cambridge_Bay 0 - -00 1920 # trading post est.?
-7:00 NT_YK M%sT 1999 Oct 31 2:00
-6:00 Canada C%sT 2000 Oct 29 2:00
-5:00 - EST 2000 Nov 5 0:00
-6:00 - CST 2001 Apr 1 3:00
-7:00 Canada M%sT
Zone America/Yellowknife 0 - zzz 1935 # Yellowknife founded?
Zone America/Yellowknife 0 - -00 1935 # Yellowknife founded?
-7:00 NT_YK M%sT 1980
-7:00 Canada M%sT
Zone America/Inuvik 0 - zzz 1953 # Inuvik founded
Zone America/Inuvik 0 - -00 1953 # Inuvik founded
-8:00 NT_YK P%sT 1979 Apr lastSun 2:00
-7:00 NT_YK M%sT 1980
-7:00 Canada M%sT

@ -1332,7 +1332,7 @@ Zone Pacific/Easter -7:17:28 - LMT 1890
# Palmer used to be supplied from Argentina.
#
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Antarctica/Palmer 0 - zzz 1965
Zone Antarctica/Palmer 0 - -00 1965
-4:00 Arg AR%sT 1969 Oct 5
-3:00 Arg AR%sT 1982 May
-4:00 Chile CL%sT
@ -1782,16 +1782,16 @@ Zone America/Montevideo -3:44:44 - LMT 1898 Jun 28
# https://actualidad.rt.com/actualidad/204758-venezuela-modificar-huso-horario-sequia-elnino
#
# From Paul Eggert (2016-04-15):
# Clocks advance 30 minutes on 2016-05-01 at 02:30. See:
# Barboza AD. Huso horario en Venezuela volverá a 4 horas menos con
# respecto al "Greenwich". Panorama 2016-04-15 12:20 -0430.
# http://www.panorama.com.ve/ciudad/Huso-horario-en-Venezuela-volvera-a-4-horas-menos-con-respecto-al-Greenwich-20160415-0032.html
#
# Clocks advance 30 minutes on 2016-05-01 at 02:30....
# "'Venezuela's new time-zone: hours without light, hours without water,
# hours of presidential broadcasts, hours of lines," quipped comedian
# Jean Mary Curro ...". See: Cawthorne A, Kai D. Venezuela scraps
# hours of presidential broadcasts, hours of lines,' quipped comedian
# Jean Mary Curró ...". See: Cawthorne A, Kai D. Venezuela scraps
# half-hour time difference set by Chavez. Reuters 2016-04-15 14:50 -0400
# http://www.reuters.com/article/us-venezuela-timezone-idUSKCN0XC2BE
#
# From Matt Johnson (2016-04-20):
# ... published in the official Gazette [2016-04-18], here:
# http://historico.tsj.gob.ve/gaceta_ext/abril/1842016/E-1842016-4551.pdf
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone America/Caracas -4:27:44 - LMT 1890

@ -136,10 +136,6 @@ SUNWprivate_1.1 {
Java_sun_nio_ch_UnixAsynchronousServerSocketChannelImpl_accept0;
Java_sun_nio_ch_UnixAsynchronousServerSocketChannelImpl_initIDs;
Java_sun_nio_ch_UnixAsynchronousSocketChannelImpl_checkConnect;
Java_sun_nio_fs_GioFileTypeDetector_initializeGio;
Java_sun_nio_fs_GioFileTypeDetector_probeGio;
Java_sun_nio_fs_MagicFileTypeDetector_initialize0;
Java_sun_nio_fs_MagicFileTypeDetector_probe0;
Java_sun_nio_fs_LinuxWatchService_eventSize;
Java_sun_nio_fs_LinuxWatchService_eventOffsets;
Java_sun_nio_fs_LinuxWatchService_inotifyInit;

@ -1,83 +0,0 @@
/*
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.nio.fs;
import java.nio.file.Path;
import java.io.IOException;
import java.security.AccessController;
import java.security.PrivilegedAction;
/**
* File type detector that uses the GNOME I/O library to guess the
* MIME type of a file.
*/
public class GioFileTypeDetector
extends AbstractFileTypeDetector
{
// true if GIO is available
private final boolean gioAvailable;
public GioFileTypeDetector() {
gioAvailable = initializeGio();
}
@Override
public String implProbeContentType(Path obj) throws IOException {
if (!gioAvailable)
return null;
if (!(obj instanceof UnixPath))
return null;
UnixPath path = (UnixPath)obj;
NativeBuffer buffer = NativeBuffers.asNativeBuffer(path.getByteArrayForSysCalls());
try {
// GIO may access file so need permission check
path.checkRead();
byte[] type = probeGio(buffer.address());
return (type == null) ? null : Util.toString(type);
} finally {
buffer.release();
}
}
// GIO
private static native boolean initializeGio();
//
// The probeGIO() method is synchronized to avert potential problems
// such as crashes due to a suspected lack of thread safety in GIO.
//
private static synchronized native byte[] probeGio(long pathAddress);
static {
AccessController.doPrivileged(new PrivilegedAction<>() {
public Void run() {
System.loadLibrary("nio");
return null;
}});
}
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2016, 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
@ -106,9 +106,7 @@ public class LinuxFileSystemProvider extends UnixFileSystemProvider {
Path userMimeTypes = Paths.get(userHome, ".mime.types");
Path etcMimeTypes = Paths.get("/etc/mime.types");
return chain(new GioFileTypeDetector(),
new MimeTypesFileTypeDetector(userMimeTypes),
new MimeTypesFileTypeDetector(etcMimeTypes),
new MagicFileTypeDetector());
return chain(new MimeTypesFileTypeDetector(userMimeTypes),
new MimeTypesFileTypeDetector(etcMimeTypes));
}
}

@ -1,79 +0,0 @@
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.nio.fs;
import java.io.IOException;
import java.nio.file.Path;
import java.security.AccessController;
import java.security.PrivilegedAction;
/**
* File type detector that uses the libmagic to guess the MIME type of a file.
*/
class MagicFileTypeDetector extends AbstractFileTypeDetector {
private static final String UNKNOWN_MIME_TYPE = "application/octet-stream";
// true if libmagic is available and successfully loaded
private final boolean libmagicAvailable;
public MagicFileTypeDetector() {
libmagicAvailable = initialize0();
}
@Override
protected String implProbeContentType(Path obj) throws IOException {
if (!libmagicAvailable || !(obj instanceof UnixPath))
return null;
UnixPath path = (UnixPath) obj;
path.checkRead();
NativeBuffer buffer = NativeBuffers.asNativeBuffer(path.getByteArrayForSysCalls());
try {
byte[] type = probe0(buffer.address());
String mimeType = (type == null) ? null : new String(type);
return UNKNOWN_MIME_TYPE.equals(mimeType) ? null : mimeType;
} finally {
buffer.release();
}
}
private static native boolean initialize0();
private static native byte[] probe0(long pathAddress);
static {
AccessController.doPrivileged(new PrivilegedAction<>() {
@Override
public Void run() {
System.loadLibrary("nio");
return null;
}
});
}
}

@ -1,148 +0,0 @@
/*
* Copyright (c) 2008, 2016, 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.
*/
#include "jni.h"
#include "jni_util.h"
#include "jvm.h"
#include "jlong.h"
#include <stdlib.h>
#include <dlfcn.h>
#ifdef __solaris__
#include <strings.h>
#endif
#if defined(__linux__)
#include <string.h>
#endif
/*
* For reference see for example the GFileInfo section at
* https://developer.gnome.org/gio/unstable/.
*/
/* Definitions for GIO */
#define G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE "standard::content-type"
typedef void* gpointer;
typedef struct _GFile GFile;
typedef struct _GFileInfo GFileInfo;
typedef struct _GCancellable GCancellable;
typedef struct _GError GError;
typedef enum {
G_FILE_QUERY_INFO_NONE = 0
} GFileQueryInfoFlags;
typedef void (*g_type_init_func)(void);
typedef void (*g_object_unref_func)(gpointer object);
typedef GFile* (*g_file_new_for_path_func)(const char* path);
typedef GFileInfo* (*g_file_query_info_func)(GFile *file,
const char *attributes, GFileQueryInfoFlags flags,
GCancellable *cancellable, GError **error);
typedef char* (*g_file_info_get_content_type_func)(GFileInfo *info);
static g_type_init_func g_type_init;
static g_object_unref_func g_object_unref;
static g_file_new_for_path_func g_file_new_for_path;
static g_file_query_info_func g_file_query_info;
static g_file_info_get_content_type_func g_file_info_get_content_type;
#include "sun_nio_fs_GioFileTypeDetector.h"
JNIEXPORT jboolean JNICALL
Java_sun_nio_fs_GioFileTypeDetector_initializeGio
(JNIEnv* env, jclass this)
{
void* gio_handle;
gio_handle = dlopen("libgio-2.0.so", RTLD_LAZY);
if (gio_handle == NULL) {
gio_handle = dlopen("libgio-2.0.so.0", RTLD_LAZY);
if (gio_handle == NULL) {
return JNI_FALSE;
}
}
g_type_init = (g_type_init_func)dlsym(gio_handle, "g_type_init");
g_object_unref = (g_object_unref_func)dlsym(gio_handle, "g_object_unref");
g_file_new_for_path =
(g_file_new_for_path_func)dlsym(gio_handle, "g_file_new_for_path");
g_file_query_info =
(g_file_query_info_func)dlsym(gio_handle, "g_file_query_info");
g_file_info_get_content_type = (g_file_info_get_content_type_func)
dlsym(gio_handle, "g_file_info_get_content_type");
if (g_object_unref == NULL ||
g_file_new_for_path == NULL ||
g_file_query_info == NULL ||
g_file_info_get_content_type == NULL)
{
dlclose(gio_handle);
return JNI_FALSE;
}
if (g_type_init != NULL) {
(*g_type_init)();
}
return JNI_TRUE;
}
JNIEXPORT jbyteArray JNICALL
Java_sun_nio_fs_GioFileTypeDetector_probeGio
(JNIEnv* env, jclass this, jlong pathAddress)
{
char* path = (char*)jlong_to_ptr(pathAddress);
GFile* gfile;
GFileInfo* gfileinfo;
jbyteArray result = NULL;
gfile = (*g_file_new_for_path)(path);
gfileinfo = (*g_file_query_info)(gfile, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
G_FILE_QUERY_INFO_NONE, NULL, NULL);
if (gfileinfo != NULL) {
const char* mime = (*g_file_info_get_content_type)(gfileinfo);
if (mime != NULL) {
jsize len = strlen(mime);
result = (*env)->NewByteArray(env, len);
if (result != NULL) {
(*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)mime);
}
}
(*g_object_unref)(gfileinfo);
}
(*g_object_unref)(gfile);
return result;
}

@ -1,108 +0,0 @@
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#include "jni.h"
#include "jni_util.h"
#include "jvm.h"
#include "jlong.h"
#include <dlfcn.h>
#include <string.h>
#define MAGIC_MIME_TYPE 0x000010 /* Return the MIME type */
typedef struct magic_set magic_t;
typedef magic_t* (*magic_open_func)(int flags);
typedef int (*magic_load_func)(magic_t* cookie, const char* filename);
typedef const char* (*magic_file_func)(magic_t* cookie, const char* filename);
typedef void (*magic_close_func)(magic_t* cookie);
static void* magic_handle;
static magic_open_func magic_open;
static magic_load_func magic_load;
static magic_file_func magic_file;
static magic_close_func magic_close;
#include "sun_nio_fs_MagicFileTypeDetector.h"
JNIEXPORT jboolean JNICALL
Java_sun_nio_fs_MagicFileTypeDetector_initialize0
(JNIEnv* env, jclass this)
{
magic_handle = dlopen("libmagic.so", RTLD_LAZY);
if (magic_handle == NULL) {
magic_handle = dlopen("libmagic.so.1", RTLD_LAZY);
if (magic_handle == NULL) {
return JNI_FALSE;
}
}
magic_open = (magic_open_func)dlsym(magic_handle, "magic_open");
magic_load = (magic_load_func)dlsym(magic_handle, "magic_load");
magic_file = (magic_file_func)dlsym(magic_handle, "magic_file");
magic_close = (magic_close_func)dlsym(magic_handle, "magic_close");
if (magic_open == NULL ||
magic_load == NULL ||
magic_file == NULL ||
magic_close == NULL)
{
dlclose(magic_handle);
return JNI_FALSE;
}
return JNI_TRUE;
}
JNIEXPORT jbyteArray JNICALL
Java_sun_nio_fs_MagicFileTypeDetector_probe0
(JNIEnv* env, jclass this, jlong pathAddress)
{
char* path = (char*)jlong_to_ptr(pathAddress);
magic_t* cookie;
jbyteArray result = NULL;
cookie = (*magic_open)(MAGIC_MIME_TYPE);
if (cookie != NULL) {
if ((*magic_load)(cookie, NULL) != -1) {
const char* type = (*magic_file)(cookie, path);
if (type != NULL) {
jsize len = strlen(type);
result = (*env)->NewByteArray(env, len);
if (result != NULL) {
(*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)type);
}
}
}
(*magic_close)(cookie);
}
return result;
}

@ -236,10 +236,12 @@ public final class System {
* @since 1.6
*/
public static Console console() {
Console c = cons;
if (c == null) {
Console c;
if ((c = cons) == null) {
synchronized (System.class) {
cons = c = SharedSecrets.getJavaIOAccess().console();
if ((c = cons) == null) {
cons = c = SharedSecrets.getJavaIOAccess().console();
}
}
}
return c;

@ -338,6 +338,7 @@ public final class LocalDate
* @throws DateTimeException if the epoch day exceeds the supported date range
*/
public static LocalDate ofEpochDay(long epochDay) {
EPOCH_DAY.checkValidValue(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

@ -928,7 +928,24 @@ public final class DateTimeFormatterBuilder {
* second if non-zero, no colon
* <li>{@code +HH:mm:ss} - hour, with minute if non-zero or with minute and
* second if non-zero, with colon
* <li>{@code +H} - hour only, ignoring minute and second
* <li>{@code +Hmm} - hour, with minute if non-zero, ignoring second, no colon
* <li>{@code +H:mm} - hour, with minute if non-zero, ignoring second, with colon
* <li>{@code +HMM} - hour and minute, ignoring second, no colon
* <li>{@code +H:MM} - hour and minute, ignoring second, with colon
* <li>{@code +HMMss} - hour and minute, with second if non-zero, no colon
* <li>{@code +H:MM:ss} - hour and minute, with second if non-zero, with colon
* <li>{@code +HMMSS} - hour, minute and second, no colon
* <li>{@code +H:MM:SS} - hour, minute and second, with colon
* <li>{@code +Hmmss} - hour, with minute if non-zero or with minute and
* second if non-zero, no colon
* <li>{@code +H:mm:ss} - hour, with minute if non-zero or with minute and
* second if non-zero, with colon
* </ul>
* Patterns containing "HH" will format and parse a two digit hour,
* zero-padded if necessary. Patterns containing "H" will format with no
* zero-padding, and parse either one or two digits.
* In lenient mode, the parser will be greedy and parse the maximum digits possible.
* The "no offset" text controls what text is printed when the total amount of
* the offset fields to be output is zero.
* Example values would be 'Z', '+00:00', 'UTC' or 'GMT'.
@ -3475,13 +3492,15 @@ public final class DateTimeFormatterBuilder {
*/
static final class OffsetIdPrinterParser implements DateTimePrinterParser {
static final String[] PATTERNS = new String[] {
"+HH", "+HHmm", "+HH:mm", "+HHMM", "+HH:MM", "+HHMMss", "+HH:MM:ss", "+HHMMSS", "+HH:MM:SS", "+HHmmss", "+HH:mm:ss",
"+HH", "+HHmm", "+HH:mm", "+HHMM", "+HH:MM", "+HHMMss", "+HH:MM:ss", "+HHMMSS", "+HH:MM:SS", "+HHmmss", "+HH:mm:ss",
"+H", "+Hmm", "+H:mm", "+HMM", "+H:MM", "+HMMss", "+H:MM:ss", "+HMMSS", "+H:MM:SS", "+Hmmss", "+H:mm:ss",
}; // order used in pattern builder
static final OffsetIdPrinterParser INSTANCE_ID_Z = new OffsetIdPrinterParser("+HH:MM:ss", "Z");
static final OffsetIdPrinterParser INSTANCE_ID_ZERO = new OffsetIdPrinterParser("+HH:MM:ss", "0");
private final String noOffsetText;
private final int type;
private final int style;
/**
* Constructor.
@ -3493,6 +3512,7 @@ public final class DateTimeFormatterBuilder {
Objects.requireNonNull(pattern, "pattern");
Objects.requireNonNull(noOffsetText, "noOffsetText");
this.type = checkPattern(pattern);
this.style = type % 11;
this.noOffsetText = noOffsetText;
}
@ -3505,6 +3525,14 @@ public final class DateTimeFormatterBuilder {
throw new IllegalArgumentException("Invalid zone offset pattern: " + pattern);
}
private boolean isPaddedHour() {
return type < 11;
}
private boolean isColon() {
return style > 0 && (style % 2) == 0;
}
@Override
public boolean format(DateTimePrintContext context, StringBuilder buf) {
Long offsetSecs = context.getValue(OFFSET_SECONDS);
@ -3520,15 +3548,17 @@ public final class DateTimeFormatterBuilder {
int absSeconds = Math.abs(totalSecs % 60);
int bufPos = buf.length();
int output = absHours;
buf.append(totalSecs < 0 ? "-" : "+")
.append((char) (absHours / 10 + '0')).append((char) (absHours % 10 + '0'));
if ((type >= 3 && type < 9) || (type >= 9 && absSeconds > 0) || (type >= 1 && absMinutes > 0)) {
buf.append((type % 2) == 0 ? ":" : "")
.append((char) (absMinutes / 10 + '0')).append((char) (absMinutes % 10 + '0'));
buf.append(totalSecs < 0 ? "-" : "+");
if (isPaddedHour() || absHours >= 10) {
formatZeroPad(false, absHours, buf);
} else {
buf.append((char) (absHours + '0'));
}
if ((style >= 3 && style <= 8) || (style >= 9 && absSeconds > 0) || (style >= 1 && absMinutes > 0)) {
formatZeroPad(isColon(), absMinutes, buf);
output += absMinutes;
if (type == 7 || type == 8 || (type >= 5 && absSeconds > 0)) {
buf.append((type % 2) == 0 ? ":" : "")
.append((char) (absSeconds / 10 + '0')).append((char) (absSeconds % 10 + '0'));
if (style == 7 || style == 8 || (style >= 5 && absSeconds > 0)) {
formatZeroPad(isColon(), absSeconds, buf);
output += absSeconds;
}
}
@ -3540,19 +3570,16 @@ public final class DateTimeFormatterBuilder {
return true;
}
private void formatZeroPad(boolean colon, int value, StringBuilder buf) {
buf.append(colon ? ":" : "")
.append((char) (value / 10 + '0'))
.append((char) (value % 10 + '0'));
}
@Override
public int parse(DateTimeParseContext context, CharSequence text, int position) {
int length = text.length();
int noOffsetLen = noOffsetText.length();
int parseType = type;
if (context.isStrict() == false) {
if ((parseType > 0 && (parseType % 2) == 0) ||
(parseType == 0 && length > position + 3 && text.charAt(position + 3) == ':')) {
parseType = 10;
} else {
parseType = 9;
}
}
if (noOffsetLen == 0) {
if (position == length) {
return context.setParsedField(OFFSET_SECONDS, 0, position, position);
@ -3571,12 +3598,87 @@ public final class DateTimeFormatterBuilder {
if (sign == '+' || sign == '-') {
// starts
int negative = (sign == '-' ? -1 : 1);
boolean isColon = isColon();
boolean paddedHour = isPaddedHour();
int[] array = new int[4];
array[0] = position + 1;
if ((parseNumber(array, 1, text, true, parseType) ||
parseNumber(array, 2, text, parseType >= 3 && parseType < 9, parseType) ||
parseNumber(array, 3, text, parseType == 7 || parseType == 8, parseType)) == false) {
// success
int parseType = type;
// select parse type when lenient
if (!context.isStrict()) {
if (paddedHour) {
if (isColon || (parseType == 0 && length > position + 3 && text.charAt(position + 3) == ':')) {
isColon = true; // needed in cases like ("+HH", "+01:01")
parseType = 10;
} else {
parseType = 9;
}
} else {
if (isColon || (parseType == 11 && length > position + 3 && (text.charAt(position + 2) == ':' || text.charAt(position + 3) == ':'))) {
isColon = true;
parseType = 21; // needed in cases like ("+H", "+1:01")
} else {
parseType = 20;
}
}
}
// parse according to the selected pattern
switch (parseType) {
case 0: // +HH
case 11: // +H
parseHour(text, paddedHour, array);
break;
case 1: // +HHmm
case 2: // +HH:mm
case 13: // +H:mm
parseHour(text, paddedHour, array);
parseMinute(text, isColon, false, array);
break;
case 3: // +HHMM
case 4: // +HH:MM
case 15: // +H:MM
parseHour(text, paddedHour, array);
parseMinute(text, isColon, true, array);
break;
case 5: // +HHMMss
case 6: // +HH:MM:ss
case 17: // +H:MM:ss
parseHour(text, paddedHour, array);
parseMinute(text, isColon, true, array);
parseSecond(text, isColon, false, array);
break;
case 7: // +HHMMSS
case 8: // +HH:MM:SS
case 19: // +H:MM:SS
parseHour(text, paddedHour, array);
parseMinute(text, isColon, true, array);
parseSecond(text, isColon, true, array);
break;
case 9: // +HHmmss
case 10: // +HH:mm:ss
case 21: // +H:mm:ss
parseHour(text, paddedHour, array);
parseOptionalMinuteSecond(text, isColon, array);
break;
case 12: // +Hmm
parseVariableWidthDigits(text, 1, 4, array);
break;
case 14: // +HMM
parseVariableWidthDigits(text, 3, 4, array);
break;
case 16: // +HMMss
parseVariableWidthDigits(text, 3, 6, array);
break;
case 18: // +HMMSS
parseVariableWidthDigits(text, 5, 6, array);
break;
case 20: // +Hmmss
parseVariableWidthDigits(text, 1, 6, array);
break;
}
if (array[0] > 0) {
if (array[1] > 23 || array[2] > 59 || array[3] > 59) {
throw new DateTimeException("Value out of range: Hour[0-23], Minute[0-59], Second[0-59]");
}
long offsetSecs = negative * (array[1] * 3600L + array[2] * 60L + array[3]);
return context.setParsedField(OFFSET_SECONDS, offsetSecs, position, array[0]);
}
@ -3588,42 +3690,118 @@ public final class DateTimeFormatterBuilder {
return ~position;
}
/**
* Parse a two digit zero-prefixed number.
*
* @param array the array of parsed data, 0=pos,1=hours,2=mins,3=secs, not null
* @param arrayIndex the index to parse the value into
* @param parseText the offset ID, not null
* @param required whether this number is required
* @param parseType the offset pattern type
* @return true if an error occurred
*/
private boolean parseNumber(int[] array, int arrayIndex, CharSequence parseText, boolean required, int parseType) {
if ((parseType + 3) / 2 < arrayIndex) {
return false; // ignore seconds/minutes
private void parseHour(CharSequence parseText, boolean paddedHour, int[] array) {
if (paddedHour) {
// parse two digits
if (!parseDigits(parseText, false, 1, array)) {
array[0] = ~array[0];
}
} else {
// parse one or two digits
parseVariableWidthDigits(parseText, 1, 2, array);
}
}
private void parseMinute(CharSequence parseText, boolean isColon, boolean mandatory, int[] array) {
if (!parseDigits(parseText, isColon, 2, array)) {
if (mandatory) {
array[0] = ~array[0];
}
}
}
private void parseSecond(CharSequence parseText, boolean isColon, boolean mandatory, int[] array) {
if (!parseDigits(parseText, isColon, 3, array)) {
if (mandatory) {
array[0] = ~array[0];
}
}
}
private void parseOptionalMinuteSecond(CharSequence parseText, boolean isColon, int[] array) {
if (parseDigits(parseText, isColon, 2, array)) {
parseDigits(parseText, isColon, 3, array);
}
}
private boolean parseDigits(CharSequence parseText, boolean isColon, int arrayIndex, int[] array) {
int pos = array[0];
if ((parseType % 2) == 0 && arrayIndex > 1) {
if (pos < 0) {
return true;
}
if (isColon && arrayIndex != 1) { // ':' will precede only in case of minute/second
if (pos + 1 > parseText.length() || parseText.charAt(pos) != ':') {
return required;
return false;
}
pos++;
}
if (pos + 2 > parseText.length()) {
return required;
return false;
}
char ch1 = parseText.charAt(pos++);
char ch2 = parseText.charAt(pos++);
if (ch1 < '0' || ch1 > '9' || ch2 < '0' || ch2 > '9') {
return required;
return false;
}
int value = (ch1 - 48) * 10 + (ch2 - 48);
if (value < 0 || value > 59) {
return required;
return false;
}
array[arrayIndex] = value;
array[0] = pos;
return false;
return true;
}
private void parseVariableWidthDigits(CharSequence parseText, int minDigits, int maxDigits, int[] array) {
// scan the text to find the available number of digits up to maxDigits
// so long as the number available is minDigits or more, the input is valid
// then parse the number of available digits
int pos = array[0];
int available = 0;
char[] chars = new char[maxDigits];
for (int i = 0; i < maxDigits; i++) {
if (pos + 1 > parseText.length()) {
break;
}
char ch = parseText.charAt(pos++);
if (ch < '0' || ch > '9') {
pos--;
break;
}
chars[i] = ch;
available++;
}
if (available < minDigits) {
array[0] = ~array[0];
return;
}
switch (available) {
case 1:
array[1] = (chars[0] - 48);
break;
case 2:
array[1] = ((chars[0] - 48) * 10 + (chars[1] - 48));
break;
case 3:
array[1] = (chars[0] - 48);
array[2] = ((chars[1] - 48) * 10 + (chars[2] - 48));
break;
case 4:
array[1] = ((chars[0] - 48) * 10 + (chars[1] - 48));
array[2] = ((chars[2] - 48) * 10 + (chars[3] - 48));
break;
case 5:
array[1] = (chars[0] - 48);
array[2] = ((chars[1] - 48) * 10 + (chars[2] - 48));
array[3] = ((chars[3] - 48) * 10 + (chars[4] - 48));
break;
case 6:
array[1] = ((chars[0] - 48) * 10 + (chars[1] - 48));
array[2] = ((chars[2] - 48) * 10 + (chars[3] - 48));
array[3] = ((chars[4] - 48) * 10 + (chars[5] - 48));
break;
}
array[0] = pos;
}
@Override

@ -427,8 +427,11 @@ public enum ChronoField implements TemporalField {
* <p>
* This field is strictly defined to have the same meaning in all calendar systems.
* This is necessary to ensure interoperation between calendars.
* <p>
* Range of EpochDay is between (LocalDate.MIN.toEpochDay(), LocalDate.MAX.toEpochDay())
* both inclusive.
*/
EPOCH_DAY("EpochDay", DAYS, FOREVER, ValueRange.of((long) (Year.MIN_VALUE * 365.25), (long) (Year.MAX_VALUE * 365.25))),
EPOCH_DAY("EpochDay", DAYS, FOREVER, ValueRange.of(-365243219162L, 365241780471L)),
/**
* The aligned week within a month.
* <p>

@ -153,10 +153,11 @@ public class HandshakeCompletedEvent extends EventObject
* @exception SSLPeerUnverifiedException if the peer is not verified.
* @see #getPeerPrincipal()
* @deprecated The {@link #getPeerCertificates()} method that returns an
* array of {@code java.security.cert.Certificate} should
* be used instead.
* array of {@code java.security.cert.Certificate} should
* be used instead. This method is subject to removal in
* a future version of Java SE.
*/
@Deprecated
@Deprecated(since="9", forRemoval=true)
public javax.security.cert.X509Certificate [] getPeerCertificateChain()
throws SSLPeerUnverifiedException
{

@ -273,10 +273,11 @@ public interface SSLSession {
* has not been verified
* @see #getPeerPrincipal()
* @deprecated The {@link #getPeerCertificates()} method that returns an
* array of {@code java.security.cert.Certificate} should
* be used instead.
* array of {@code java.security.cert.Certificate} should
* be used instead. This method is subject to removal in
* a future version of Java SE.
*/
@Deprecated
@Deprecated(since="9", forRemoval=true)
public javax.security.cert.X509Certificate [] getPeerCertificateChain()
throws SSLPeerUnverifiedException;

@ -122,6 +122,14 @@ grant codeBase "jrt:/java.xml.bind" {
permission java.util.PropertyPermission "*", "read";
};
grant codeBase "jrt:/java.xml.crypto" {
permission java.util.PropertyPermission "*", "read";
permission java.security.SecurityPermission "putProviderProperty.XMLDSig";
permission java.security.SecurityPermission "clearProviderProperties.XMLDSig";
permission java.security.SecurityPermission "removeProviderProperty.XMLDSig";
permission java.security.SecurityPermission "com.sun.org.apache.xml.internal.security.register";
};
grant codeBase "jrt:/java.xml.ws" {
permission java.lang.RuntimePermission "accessClassInPackage.com.sun.xml.internal.*";
permission java.lang.RuntimePermission "accessClassInPackage.com.sun.istack.internal";

@ -39,6 +39,7 @@ import java.security.PrivilegedAction;
import com.sun.jndi.ldap.pool.PoolCleaner;
import com.sun.jndi.ldap.pool.Pool;
import jdk.internal.misc.InnocuousThread;
/**
* Contains utilities for managing connection pools of LdapClient.
@ -163,7 +164,17 @@ public final class LdapPoolManager {
if (idleTimeout > 0) {
// Create cleaner to expire idle connections
new PoolCleaner(idleTimeout, pools).start();
PrivilegedAction<Void> pa = new PrivilegedAction<Void>() {
public Void run() {
Thread t = InnocuousThread.newSystemThread(
"LDAP PoolCleaner",
new PoolCleaner(idleTimeout, pools));
assert t.getContextClassLoader() == null;
t.setDaemon(true);
t.start();
return null;
}};
AccessController.doPrivileged(pa);
}
if (debug) {

@ -30,7 +30,7 @@ package com.sun.jndi.ldap.pool;
*
* @author Rosanna Lee
*/
final public class PoolCleaner extends Thread {
final public class PoolCleaner implements Runnable {
final private Pool[] pools;
final private long period;
@ -42,9 +42,9 @@ final public class PoolCleaner extends Thread {
super();
this.period = period;
this.pools = pools.clone();
setDaemon(true);
}
@Override
public void run() {
long threshold;
while (true) {

@ -29,6 +29,7 @@ import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.SortedSet;
import java.util.TreeSet;
import jdk.internal.misc.InnocuousThread;
/**
@ -90,8 +91,9 @@ class GC {
}});
}
private static class Daemon extends Thread {
private static class Daemon implements Runnable {
@Override
public void run() {
for (;;) {
long l;
@ -129,23 +131,17 @@ class GC {
}
}
private Daemon(ThreadGroup tg) {
super(tg, null, "GC Daemon", 0L, false);
}
/* Create a new daemon thread in the root thread group */
/* Create a new daemon thread */
public static void create() {
PrivilegedAction<Void> pa = new PrivilegedAction<Void>() {
public Void run() {
ThreadGroup tg = Thread.currentThread().getThreadGroup();
for (ThreadGroup tgn = tg;
tgn != null;
tg = tgn, tgn = tg.getParent());
Daemon d = new Daemon(tg);
d.setDaemon(true);
d.setPriority(Thread.MIN_PRIORITY + 1);
d.start();
GC.daemon = d;
Thread t = InnocuousThread.newSystemThread("RMI GC Daemon",
new Daemon());
assert t.getContextClassLoader() == null;
t.setDaemon(true);
t.setPriority(Thread.MIN_PRIORITY + 1);
t.start();
GC.daemon = t;
return null;
}};
AccessController.doPrivileged(pa);

@ -39,8 +39,6 @@ import javax.xml.crypto.XMLStructure;
import javax.xml.crypto.XMLCryptoContext;
import javax.xml.crypto.dsig.spec.TransformParameterSpec;
import sun.security.jca.*;
import sun.security.jca.GetInstance.Instance;
/**
* A Service Provider Interface for transform and canonicalization algorithms.
@ -165,18 +163,23 @@ public abstract class TransformService implements Transform {
if (mechanismType.equals("DOM")) {
dom = true;
}
List<Service> services = GetInstance.getServices("TransformService", algorithm);
for (Iterator<Service> t = services.iterator(); t.hasNext(); ) {
Service s = t.next();
String value = s.getAttribute("MechanismType");
if ((value == null && dom) ||
(value != null && value.equals(mechanismType))) {
Instance instance = GetInstance.getInstance(s, null);
TransformService ts = (TransformService) instance.impl;
ts.algorithm = algorithm;
ts.mechanism = mechanismType;
ts.provider = instance.provider;
return ts;
Provider[] provs = Security.getProviders();
for (Provider p : provs) {
Service s = p.getService("TransformService", algorithm);
if (s != null) {
String value = s.getAttribute("MechanismType");
if ((value == null && dom) ||
(value != null && value.equals(mechanismType))) {
Object obj = s.newInstance(null);
if (obj instanceof TransformService) {
TransformService ts = (TransformService) obj;
ts.algorithm = algorithm;
ts.mechanism = mechanismType;
ts.provider = p;
return ts;
}
}
}
}
throw new NoSuchAlgorithmException
@ -215,21 +218,24 @@ public abstract class TransformService implements Transform {
if (mechanismType.equals("DOM")) {
dom = true;
}
Service s = GetInstance.getService
("TransformService", algorithm, provider);
String value = s.getAttribute("MechanismType");
if ((value == null && dom) ||
(value != null && value.equals(mechanismType))) {
Instance instance = GetInstance.getInstance(s, null);
TransformService ts = (TransformService) instance.impl;
ts.algorithm = algorithm;
ts.mechanism = mechanismType;
ts.provider = instance.provider;
return ts;
Service s = provider.getService("TransformService", algorithm);
if (s != null) {
String value = s.getAttribute("MechanismType");
if ((value == null && dom) ||
(value != null && value.equals(mechanismType))) {
Object obj = s.newInstance(null);
if (obj instanceof TransformService) {
TransformService ts = (TransformService) obj;
ts.algorithm = algorithm;
ts.mechanism = mechanismType;
ts.provider = provider;
return ts;
}
}
}
throw new NoSuchAlgorithmException
(algorithm + " algorithm and " + mechanismType
+ " mechanism not available");
+ " mechanism not available from " + provider.getName());
}
/**
@ -268,21 +274,25 @@ public abstract class TransformService implements Transform {
if (mechanismType.equals("DOM")) {
dom = true;
}
Service s = GetInstance.getService
("TransformService", algorithm, provider);
String value = s.getAttribute("MechanismType");
if ((value == null && dom) ||
(value != null && value.equals(mechanismType))) {
Instance instance = GetInstance.getInstance(s, null);
TransformService ts = (TransformService) instance.impl;
ts.algorithm = algorithm;
ts.mechanism = mechanismType;
ts.provider = instance.provider;
return ts;
Provider p = Security.getProvider(provider);
Service s = p.getService("TransformService", algorithm);
if (s != null) {
String value = s.getAttribute("MechanismType");
if ((value == null && dom) ||
(value != null && value.equals(mechanismType))) {
Object obj = s.newInstance(null);
if (obj instanceof TransformService) {
TransformService ts = (TransformService) obj;
ts.algorithm = algorithm;
ts.mechanism = mechanismType;
ts.provider = p;
return ts;
}
}
}
throw new NoSuchAlgorithmException
(algorithm + " algorithm and " + mechanismType
+ " mechanism not available");
+ " mechanism not available from " + provider);
}
private static class MechanismMapEntry implements Map.Entry<String,String> {

@ -43,11 +43,10 @@ import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Provider;
import java.security.Provider.Service;
import java.security.Security;
import java.util.List;
import sun.security.jca.*;
import sun.security.jca.GetInstance.Instance;
/**
* A factory for creating {@link XMLSignature} objects from scratch or
@ -198,17 +197,26 @@ public abstract class XMLSignatureFactory {
if (mechanismType == null) {
throw new NullPointerException("mechanismType cannot be null");
}
Instance instance;
try {
instance = GetInstance.getInstance
("XMLSignatureFactory", null, mechanismType);
} catch (NoSuchAlgorithmException nsae) {
throw new NoSuchMechanismException(nsae);
Provider[] provs = Security.getProviders();
for (Provider p : provs) {
Service s = p.getService("XMLSignatureFactory", mechanismType);
if (s != null) {
Object obj = null;
try {
obj = s.newInstance(null);
} catch (NoSuchAlgorithmException nsae) {
throw new NoSuchMechanismException(nsae);
}
if (obj instanceof XMLSignatureFactory) {
XMLSignatureFactory factory = (XMLSignatureFactory) obj;
factory.mechanismType = mechanismType;
factory.provider = p;
return factory;
}
}
}
XMLSignatureFactory factory = (XMLSignatureFactory) instance.impl;
factory.mechanismType = mechanismType;
factory.provider = instance.provider;
return factory;
throw new NoSuchMechanismException
("Mechanism " + mechanismType + " not available");
}
/**
@ -240,17 +248,25 @@ public abstract class XMLSignatureFactory {
throw new NullPointerException("provider cannot be null");
}
Instance instance;
try {
instance = GetInstance.getInstance
("XMLSignatureFactory", null, mechanismType, provider);
} catch (NoSuchAlgorithmException nsae) {
throw new NoSuchMechanismException(nsae);
Service s = provider.getService("XMLSignatureFactory", mechanismType);
if (s != null) {
Object obj = null;
try {
obj = s.newInstance(null);
} catch (NoSuchAlgorithmException nsae) {
throw new NoSuchMechanismException(nsae);
}
if (obj instanceof XMLSignatureFactory) {
XMLSignatureFactory factory = (XMLSignatureFactory) obj;
factory.mechanismType = mechanismType;
factory.provider = provider;
return factory;
}
}
XMLSignatureFactory factory = (XMLSignatureFactory) instance.impl;
factory.mechanismType = mechanismType;
factory.provider = instance.provider;
return factory;
throw new NoSuchMechanismException
("Mechanism " + mechanismType + " not available from " +
provider.getName());
}
/**
@ -288,17 +304,24 @@ public abstract class XMLSignatureFactory {
throw new NoSuchProviderException();
}
Instance instance;
try {
instance = GetInstance.getInstance
("XMLSignatureFactory", null, mechanismType, provider);
} catch (NoSuchAlgorithmException nsae) {
throw new NoSuchMechanismException(nsae);
Provider p = Security.getProvider(provider);
Service s = p.getService("XMLSignatureFactory", mechanismType);
if (s != null) {
Object obj = null;
try {
obj = s.newInstance(null);
} catch (NoSuchAlgorithmException nsae) {
throw new NoSuchMechanismException(nsae);
}
if (obj instanceof XMLSignatureFactory) {
XMLSignatureFactory factory = (XMLSignatureFactory) obj;
factory.mechanismType = mechanismType;
factory.provider = p;
return factory;
}
}
XMLSignatureFactory factory = (XMLSignatureFactory) instance.impl;
factory.mechanismType = mechanismType;
factory.provider = instance.provider;
return factory;
throw new NoSuchMechanismException
("Mechanism " + mechanismType + " not available from " + provider);
}
/**

@ -32,6 +32,7 @@ import java.security.KeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Provider;
import java.security.Provider.Service;
import java.security.PublicKey;
import java.security.Security;
import java.security.cert.X509CRL;
@ -43,8 +44,6 @@ import javax.xml.crypto.XMLStructure;
import javax.xml.crypto.dom.DOMStructure;
import javax.xml.crypto.dsig.*;
import sun.security.jca.*;
import sun.security.jca.GetInstance.Instance;
/**
* A factory for creating {@link KeyInfo} objects from scratch or for
@ -153,17 +152,26 @@ public abstract class KeyInfoFactory {
if (mechanismType == null) {
throw new NullPointerException("mechanismType cannot be null");
}
Instance instance;
try {
instance = GetInstance.getInstance
("KeyInfoFactory", null, mechanismType);
} catch (NoSuchAlgorithmException nsae) {
throw new NoSuchMechanismException(nsae);
Provider[] provs = Security.getProviders();
for (Provider p : provs) {
Service s = p.getService("KeyInfoFactory", mechanismType);
if (s != null) {
Object obj = null;
try {
obj = s.newInstance(null);
} catch (NoSuchAlgorithmException nsae) {
throw new NoSuchMechanismException(nsae);
}
if (obj instanceof KeyInfoFactory) {
KeyInfoFactory factory = (KeyInfoFactory) obj;
factory.mechanismType = mechanismType;
factory.provider = p;
return factory;
}
}
}
KeyInfoFactory factory = (KeyInfoFactory) instance.impl;
factory.mechanismType = mechanismType;
factory.provider = instance.provider;
return factory;
throw new NoSuchMechanismException
("Mechanism " + mechanismType + " not available");
}
/**
@ -195,17 +203,24 @@ public abstract class KeyInfoFactory {
throw new NullPointerException("provider cannot be null");
}
Instance instance;
try {
instance = GetInstance.getInstance
("KeyInfoFactory", null, mechanismType, provider);
} catch (NoSuchAlgorithmException nsae) {
throw new NoSuchMechanismException(nsae);
Service s = provider.getService("KeyInfoFactory", mechanismType);
if (s != null) {
Object obj = null;
try {
obj = s.newInstance(null);
} catch (NoSuchAlgorithmException nsae) {
throw new NoSuchMechanismException(nsae);
}
if (obj instanceof KeyInfoFactory) {
KeyInfoFactory factory = (KeyInfoFactory) obj;
factory.mechanismType = mechanismType;
factory.provider = provider;
return factory;
}
}
KeyInfoFactory factory = (KeyInfoFactory) instance.impl;
factory.mechanismType = mechanismType;
factory.provider = instance.provider;
return factory;
throw new NoSuchMechanismException
("Mechanism " + mechanismType + " not available from " + provider.getName());
}
/**
@ -242,18 +257,24 @@ public abstract class KeyInfoFactory {
} else if (provider.length() == 0) {
throw new NoSuchProviderException();
}
Instance instance;
try {
instance = GetInstance.getInstance
("KeyInfoFactory", null, mechanismType, provider);
} catch (NoSuchAlgorithmException nsae) {
throw new NoSuchMechanismException(nsae);
Provider p = Security.getProvider(provider);
Service s = p.getService("KeyInfoFactory", mechanismType);
if (s != null) {
Object obj = null;
try {
obj = s.newInstance(null);
} catch (NoSuchAlgorithmException nsae) {
throw new NoSuchMechanismException(nsae);
}
if (obj instanceof KeyInfoFactory) {
KeyInfoFactory factory = (KeyInfoFactory) obj;
factory.mechanismType = mechanismType;
factory.provider = p;
return factory;
}
}
KeyInfoFactory factory = (KeyInfoFactory) instance.impl;
factory.mechanismType = mechanismType;
factory.provider = instance.provider;
return factory;
throw new NoSuchMechanismException
("Mechanism " + mechanismType + " not available from " + provider);
}
/**

@ -58,8 +58,8 @@ import jdk.tools.jlink.internal.BasicImageWriter;
import jdk.tools.jlink.internal.plugins.FileCopierPlugin;
import jdk.tools.jlink.internal.plugins.FileCopierPlugin.SymImageFile;
import jdk.tools.jlink.internal.ExecutableImage;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolEntry;
import jdk.tools.jlink.plugin.PluginException;
/**
@ -170,10 +170,10 @@ public final class DefaultImageBuilder implements ImageBuilder {
}
@Override
public void storeFiles(ModulePool files) {
public void storeFiles(ResourcePool files) {
try {
files.entries().forEach(f -> {
if (!f.getType().equals(ModuleEntry.Type.CLASS_OR_RESOURCE)) {
if (!f.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)) {
try {
accept(f);
} catch (IOException ioExp) {
@ -181,17 +181,17 @@ public final class DefaultImageBuilder implements ImageBuilder {
}
}
});
files.modules().forEach(m -> {
files.moduleView().modules().forEach(m -> {
// Only add modules that contain packages
if (!m.getAllPackages().isEmpty()) {
if (!m.packages().isEmpty()) {
// Skip the fake module used by FileCopierPlugin when copying files.
if (m.getName().equals(FileCopierPlugin.FAKE_MODULE)) {
if (m.name().equals(FileCopierPlugin.FAKE_MODULE)) {
return;
}
modules.add(m.getName());
modules.add(m.name());
}
});
storeFiles(modules, files.getReleaseProperties());
storeFiles(modules, files.releaseProperties());
if (Files.getFileStore(root).supportsFileAttributeView(PosixFileAttributeView.class)) {
// launchers in the bin directory need execute permission
@ -226,16 +226,16 @@ public final class DefaultImageBuilder implements ImageBuilder {
* @param modules The set of modules that the runtime image contains.
* @throws IOException
*/
protected void prepareApplicationFiles(ModulePool imageContent, Set<String> modules) throws IOException {
protected void prepareApplicationFiles(ResourcePool imageContent, Set<String> modules) throws IOException {
// generate launch scripts for the modules with a main class
for (String module : modules) {
String path = "/" + module + "/module-info.class";
Optional<ModuleEntry> res = imageContent.findEntry(path);
Optional<ResourcePoolEntry> res = imageContent.findEntry(path);
if (!res.isPresent()) {
throw new IOException("module-info.class not found for " + module + " module");
}
Optional<String> mainClass;
ByteArrayInputStream stream = new ByteArrayInputStream(res.get().getBytes());
ByteArrayInputStream stream = new ByteArrayInputStream(res.get().contentBytes());
mainClass = ModuleDescriptor.read(stream).mainClass();
if (mainClass.isPresent()) {
Path cmd = root.resolve("bin").resolve(module);
@ -298,14 +298,14 @@ public final class DefaultImageBuilder implements ImageBuilder {
}
}
private void accept(ModuleEntry file) throws IOException {
String fullPath = file.getPath();
String module = "/" + file.getModule() + "/";
private void accept(ResourcePoolEntry file) throws IOException {
String fullPath = file.path();
String module = "/" + file.moduleName() + "/";
String filename = fullPath.substring(module.length());
// Remove radical native|config|...
filename = filename.substring(filename.indexOf('/') + 1);
try (InputStream in = file.stream()) {
switch (file.getType()) {
try (InputStream in = file.content()) {
switch (file.type()) {
case NATIVE_LIB:
writeEntry(in, destFile(nativeDir(filename), filename));
break;

@ -29,7 +29,7 @@ import java.util.Properties;
import jdk.tools.jlink.internal.ExecutableImage;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.ResourcePool;
/**
* Implement this interface to develop your own image layout. First the jimage
@ -45,7 +45,7 @@ public interface ImageBuilder {
* @param release the release properties
* @throws PluginException
*/
public default void storeFiles(ModulePool content, Properties release) {
public default void storeFiles(ResourcePool content, Properties release) {
storeFiles(content);
}
@ -55,7 +55,7 @@ public interface ImageBuilder {
* @param content Pool of module content.
* @throws PluginException
*/
public default void storeFiles(ModulePool content) {
public default void storeFiles(ResourcePool content) {
throw new UnsupportedOperationException("storeFiles");
}

@ -26,14 +26,14 @@
package jdk.tools.jlink.internal;
import java.util.Objects;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ResourcePoolEntry;
/**
* A LinkModuleEntry is the elementary unit of data inside an image. It is
* A LinkResourcePoolEntry is the elementary unit of data inside an image. It is
* generally a file. e.g.: a java class file, a resource file, a shared library,
* ...
* <br>
* A LinkModuleEntry is identified by a path of the form:
* A LinkResourcePoolEntry is identified by a path of the form:
* <ul>
* <li>For jimage content: /{module name}/{package1}/.../{packageN}/{file
* name}</li>
@ -41,36 +41,36 @@ import jdk.tools.jlink.plugin.ModuleEntry;
* {@literal bin|conf|native}/{dir1}>/.../{dirN}/{file name}</li>
* </ul>
*/
abstract class AbstractModuleEntry implements ModuleEntry {
abstract class AbstractResourcePoolEntry implements ResourcePoolEntry {
private final String path;
private final String module;
private final Type type;
/**
* Create a new AbstractModuleEntry.
* Create a new AbstractResourcePoolEntry.
*
* @param module The module name.
* @param path The data path identifier.
* @param type The data type.
*/
AbstractModuleEntry(String module, String path, Type type) {
AbstractResourcePoolEntry(String module, String path, Type type) {
this.module = Objects.requireNonNull(module);
this.path = Objects.requireNonNull(path);
this.type = Objects.requireNonNull(type);
}
@Override
public final String getModule() {
public final String moduleName() {
return module;
}
@Override
public final String getPath() {
public final String path() {
return path;
}
@Override
public final Type getType() {
public final Type type() {
return type;
}
@ -81,15 +81,15 @@ abstract class AbstractModuleEntry implements ModuleEntry {
@Override
public boolean equals(Object other) {
if (!(other instanceof AbstractModuleEntry)) {
if (!(other instanceof AbstractResourcePoolEntry)) {
return false;
}
AbstractModuleEntry f = (AbstractModuleEntry) other;
AbstractResourcePoolEntry f = (AbstractResourcePoolEntry) other;
return f.path.equals(path);
}
@Override
public String toString() {
return getPath();
return path();
}
}

@ -29,28 +29,28 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.util.Objects;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ResourcePoolEntry;
/**
* A ModuleEntry backed by a given Archive Entry.
* A ResourcePoolEntry backed by a given Archive Entry.
*/
final class ArchiveEntryModuleEntry extends AbstractModuleEntry {
final class ArchiveEntryResourcePoolEntry extends AbstractResourcePoolEntry {
private final Archive.Entry entry;
/**
* Create a new ArchiveModuleEntry.
* Create a new ArchiveResourcePoolEntry.
*
* @param module The module name.
* @param path The data path identifier.
* @param entry The archive Entry.
*/
ArchiveEntryModuleEntry(String module, String path, Archive.Entry entry) {
ArchiveEntryResourcePoolEntry(String module, String path, Archive.Entry entry) {
super(module, path, getImageFileType(Objects.requireNonNull(entry)));
this.entry = entry;
}
@Override
public InputStream stream() {
public InputStream content() {
try {
return entry.stream();
} catch (IOException ex) {
@ -59,22 +59,22 @@ final class ArchiveEntryModuleEntry extends AbstractModuleEntry {
}
@Override
public long getLength() {
public long contentLength() {
return entry.size();
}
private static ModuleEntry.Type getImageFileType(Archive.Entry entry) {
private static ResourcePoolEntry.Type getImageFileType(Archive.Entry entry) {
switch(entry.type()) {
case CLASS_OR_RESOURCE:
return ModuleEntry.Type.CLASS_OR_RESOURCE;
return ResourcePoolEntry.Type.CLASS_OR_RESOURCE;
case CONFIG:
return ModuleEntry.Type.CONFIG;
return ResourcePoolEntry.Type.CONFIG;
case NATIVE_CMD:
return ModuleEntry.Type.NATIVE_CMD;
return ResourcePoolEntry.Type.NATIVE_CMD;
case NATIVE_LIB:
return ModuleEntry.Type.NATIVE_LIB;
return ResourcePoolEntry.Type.NATIVE_LIB;
default:
return ModuleEntry.Type.OTHER;
return ResourcePoolEntry.Type.OTHER;
}
}
}

@ -33,31 +33,31 @@ import java.io.UncheckedIOException;
import java.util.Objects;
/**
* A ModuleEntry backed by a given byte[].
* A ResourcePoolEntry backed by a given byte[].
*/
class ByteArrayModuleEntry extends AbstractModuleEntry {
class ByteArrayResourcePoolEntry extends AbstractResourcePoolEntry {
private final byte[] buffer;
/**
* Create a new ByteArrayModuleEntry.
* Create a new ByteArrayResourcePoolEntry.
*
* @param module The module name.
* @param path The data path identifier.
* @param type The data type.
* @param buf The byte buffer.
*/
ByteArrayModuleEntry(String module, String path, Type type, byte[] buffer) {
ByteArrayResourcePoolEntry(String module, String path, Type type, byte[] buffer) {
super(module, path, type);
this.buffer = Objects.requireNonNull(buffer);
}
@Override
public byte[] getBytes() {
public byte[] contentBytes() {
return buffer.clone();
}
@Override
public InputStream stream() {
public InputStream content() {
return new ByteArrayInputStream(buffer);
}
@ -71,7 +71,7 @@ class ByteArrayModuleEntry extends AbstractModuleEntry {
}
@Override
public long getLength() {
public long contentLength() {
return buffer.length;
}
}

@ -42,9 +42,10 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
import jdk.tools.jlink.internal.Archive.Entry;
import jdk.tools.jlink.internal.Archive.Entry.EntryType;
import jdk.tools.jlink.internal.ModulePoolImpl.CompressedModuleData;
import jdk.tools.jlink.internal.ResourcePoolManager.CompressedModuleData;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolEntry;
/**
* An image (native endian.)
@ -140,7 +141,7 @@ public final class ImageFileCreator {
}));
ByteOrder order = ByteOrder.nativeOrder();
BasicImageWriter writer = new BasicImageWriter(order);
ModulePoolImpl pool = createPools(archives, entriesForModule, order, writer);
ResourcePoolManager pool = createPoolManager(archives, entriesForModule, order, writer);
try (OutputStream fos = Files.newOutputStream(jimageFile);
BufferedOutputStream bos = new BufferedOutputStream(fos);
DataOutputStream out = new DataOutputStream(bos)) {
@ -158,52 +159,61 @@ public final class ImageFileCreator {
ByteOrder byteOrder)
throws IOException {
BasicImageWriter writer = new BasicImageWriter(byteOrder);
ModulePoolImpl allContent = createPools(archives,
ResourcePoolManager allContent = createPoolManager(archives,
entriesForModule, byteOrder, writer);
ModulePoolImpl result = generateJImage(allContent,
ResourcePool result = generateJImage(allContent,
writer, plugins, plugins.getJImageFileOutputStream());
//Handle files.
try {
plugins.storeFiles(allContent, result, writer);
plugins.storeFiles(allContent.resourcePool(), result, writer);
} catch (Exception ex) {
if (JlinkTask.DEBUG) {
ex.printStackTrace();
}
throw new IOException(ex);
}
}
private static ModulePoolImpl generateJImage(ModulePoolImpl allContent,
private static ResourcePool generateJImage(ResourcePoolManager allContent,
BasicImageWriter writer,
ImagePluginStack pluginSupport,
DataOutputStream out
) throws IOException {
ModulePoolImpl resultResources;
ResourcePool resultResources;
try {
resultResources = pluginSupport.visitResources(allContent);
} catch (PluginException pe) {
if (JlinkTask.DEBUG) {
pe.printStackTrace();
}
throw pe;
} catch (Exception ex) {
if (JlinkTask.DEBUG) {
ex.printStackTrace();
}
throw new IOException(ex);
}
Set<String> duplicates = new HashSet<>();
long[] offset = new long[1];
List<ModuleEntry> content = new ArrayList<>();
List<ResourcePoolEntry> content = new ArrayList<>();
List<String> paths = new ArrayList<>();
// the order of traversing the resources and the order of
// the module content being written must be the same
resultResources.entries().forEach(res -> {
if (res.getType().equals(ModuleEntry.Type.CLASS_OR_RESOURCE)) {
String path = res.getPath();
if (res.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)) {
String path = res.path();
content.add(res);
long uncompressedSize = res.getLength();
long uncompressedSize = res.contentLength();
long compressedSize = 0;
if (res instanceof CompressedModuleData) {
CompressedModuleData comp
= (CompressedModuleData) res;
compressedSize = res.getLength();
compressedSize = res.contentLength();
uncompressedSize = comp.getUncompressedSize();
}
long onFileSize = res.getLength();
long onFileSize = res.contentLength();
if (duplicates.contains(path)) {
System.err.format("duplicate resource \"%s\", skipping%n",
@ -239,11 +249,11 @@ public final class ImageFileCreator {
return resultResources;
}
private static ModulePoolImpl createPools(Set<Archive> archives,
private static ResourcePoolManager createPoolManager(Set<Archive> archives,
Map<String, List<Entry>> entriesForModule,
ByteOrder byteOrder,
BasicImageWriter writer) throws IOException {
ModulePoolImpl resources = new ModulePoolImpl(byteOrder, new StringTable() {
ResourcePoolManager resources = new ResourcePoolManager(byteOrder, new StringTable() {
@Override
public int addString(String str) {
@ -273,7 +283,7 @@ public final class ImageFileCreator {
path = "/" + mn + "/" + entry.path();
}
resources.add(new ArchiveEntryModuleEntry(mn, path, entry));
resources.add(new ArchiveEntryResourcePoolEntry(mn, path, entry));
}
}
return resources;

@ -37,7 +37,7 @@ import jdk.tools.jlink.Jlink;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.plugin.Plugin.Category;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.ResourcePool;
/**
* Plugins configuration.
@ -122,7 +122,7 @@ public final class ImagePluginConfiguration {
}
@Override
public void storeFiles(ModulePool files) {
public void storeFiles(ResourcePool files) {
throw new PluginException("No directory setup to store files");
}
};

@ -46,9 +46,10 @@ import jdk.internal.jimage.decompressor.Decompressor;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.builder.ImageBuilder;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.LinkModule;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolModule;
import jdk.tools.jlink.plugin.ResourcePoolEntry;
import jdk.tools.jlink.internal.ResourcePoolManager.ResourcePoolImpl;
/**
* Plugins Stack. Plugins entry point to apply transformations onto resources
@ -61,36 +62,47 @@ public final class ImagePluginStack {
ExecutableImage retrieve(ImagePluginStack stack) throws IOException;
}
public static final class OrderedResourcePool extends ModulePoolImpl {
public static final class OrderedResourcePoolManager extends ResourcePoolManager {
class OrderedResourcePool extends ResourcePoolImpl {
List<ResourcePoolEntry> getOrderedList() {
return OrderedResourcePoolManager.this.getOrderedList();
}
}
private final List<ModuleEntry> orderedList = new ArrayList<>();
private final List<ResourcePoolEntry> orderedList = new ArrayList<>();
private final ResourcePoolImpl poolImpl = new OrderedResourcePool();
public OrderedResourcePool(ByteOrder order, StringTable table) {
public OrderedResourcePoolManager(ByteOrder order, StringTable table) {
super(order, table);
}
@Override
public ResourcePool resourcePool() {
return poolImpl;
}
/**
* Add a resource.
*
* @param resource The Resource to add.
*/
@Override
public void add(ModuleEntry resource) {
public void add(ResourcePoolEntry resource) {
super.add(resource);
orderedList.add(resource);
}
List<ModuleEntry> getOrderedList() {
List<ResourcePoolEntry> getOrderedList() {
return Collections.unmodifiableList(orderedList);
}
}
private final static class CheckOrderResourcePool extends ModulePoolImpl {
private final static class CheckOrderResourcePoolManager extends ResourcePoolManager {
private final List<ModuleEntry> orderedList;
private final List<ResourcePoolEntry> orderedList;
private int currentIndex;
public CheckOrderResourcePool(ByteOrder order, List<ModuleEntry> orderedList, StringTable table) {
public CheckOrderResourcePoolManager(ByteOrder order, List<ResourcePoolEntry> orderedList, StringTable table) {
super(order, table);
this.orderedList = Objects.requireNonNull(orderedList);
}
@ -101,10 +113,10 @@ public final class ImagePluginStack {
* @param resource The Resource to add.
*/
@Override
public void add(ModuleEntry resource) {
ModuleEntry ordered = orderedList.get(currentIndex);
public void add(ResourcePoolEntry resource) {
ResourcePoolEntry ordered = orderedList.get(currentIndex);
if (!resource.equals(ordered)) {
throw new PluginException("Resource " + resource.getPath() + " not in the right order");
throw new PluginException("Resource " + resource.path() + " not in the right order");
}
super.add(resource);
currentIndex += 1;
@ -209,17 +221,16 @@ public final class ImagePluginStack {
* @return The result of the visit.
* @throws IOException
*/
public ModulePoolImpl visitResources(ModulePoolImpl resources)
public ResourcePool visitResources(ResourcePoolManager resources)
throws Exception {
Objects.requireNonNull(resources);
resources.setReadOnly();
if (resources.isEmpty()) {
return new ModulePoolImpl(resources.getByteOrder(),
resources.getStringTable());
return new ResourcePoolManager(resources.byteOrder(),
resources.getStringTable()).resourcePool();
}
PreVisitStrings previsit = new PreVisitStrings();
resourcePrevisitors.stream().forEach((p) -> {
p.previsit(resources, previsit);
p.previsit(resources.resourcePool(), previsit);
});
// Store the strings resulting from the previsit.
@ -228,89 +239,80 @@ public final class ImagePluginStack {
resources.getStringTable().addString(s);
});
ModulePoolImpl current = resources;
List<ModuleEntry> frozenOrder = null;
ResourcePool resPool = resources.resourcePool();
List<ResourcePoolEntry> frozenOrder = null;
for (Plugin p : plugins) {
current.setReadOnly();
ModulePoolImpl output = null;
ResourcePoolManager resMgr = null;
if (p == lastSorter) {
if (frozenOrder != null) {
throw new Exception("Order of resources is already frozen. Plugin "
+ p.getName() + " is badly located");
}
// Create a special Resource pool to compute the indexes.
output = new OrderedResourcePool(current.getByteOrder(),
resMgr = new OrderedResourcePoolManager(resPool.byteOrder(),
resources.getStringTable());
} else {// If we have an order, inject it
if (frozenOrder != null) {
output = new CheckOrderResourcePool(current.getByteOrder(),
resMgr = new CheckOrderResourcePoolManager(resPool.byteOrder(),
frozenOrder, resources.getStringTable());
} else {
output = new ModulePoolImpl(current.getByteOrder(),
resMgr = new ResourcePoolManager(resPool.byteOrder(),
resources.getStringTable());
}
}
p.visit(current, output);
if (output.isEmpty()) {
resPool = p.transform(resPool, resMgr.resourcePoolBuilder());
if (resPool.isEmpty()) {
throw new Exception("Invalid resource pool for plugin " + p);
}
if (output instanceof OrderedResourcePool) {
frozenOrder = ((OrderedResourcePool) output).getOrderedList();
if (resPool instanceof OrderedResourcePoolManager.OrderedResourcePool) {
frozenOrder = ((OrderedResourcePoolManager.OrderedResourcePool)resPool).getOrderedList();
}
current = output;
}
current.setReadOnly();
return current;
return resPool;
}
/**
* This pool wrap the original pool and automatically uncompress ModuleEntry
* This pool wrap the original pool and automatically uncompress ResourcePoolEntry
* if needed.
*/
private class LastPool implements ModulePool {
private class LastModule implements LinkModule {
private class LastPoolManager extends ResourcePoolManager {
private class LastModule implements ResourcePoolModule {
final LinkModule module;
final ResourcePoolModule module;
LastModule(LinkModule module) {
LastModule(ResourcePoolModule module) {
this.module = module;
}
@Override
public String getName() {
return module.getName();
public String name() {
return module.name();
}
@Override
public Optional<ModuleEntry> findEntry(String path) {
Optional<ModuleEntry> d = module.findEntry(path);
public Optional<ResourcePoolEntry> findEntry(String path) {
Optional<ResourcePoolEntry> d = module.findEntry(path);
return d.isPresent()? Optional.of(getUncompressed(d.get())) : Optional.empty();
}
@Override
public ModuleDescriptor getDescriptor() {
return module.getDescriptor();
public ModuleDescriptor descriptor() {
return module.descriptor();
}
@Override
public void add(ModuleEntry data) {
throw new PluginException("pool is readonly");
}
@Override
public Set<String> getAllPackages() {
return module.getAllPackages();
public Set<String> packages() {
return module.packages();
}
@Override
public String toString() {
return getName();
return name();
}
@Override
public Stream<ModuleEntry> entries() {
List<ModuleEntry> lst = new ArrayList<>();
public Stream<ResourcePoolEntry> entries() {
List<ResourcePoolEntry> lst = new ArrayList<>();
module.entries().forEach(md -> {
lst.add(getUncompressed(md));
});
@ -318,31 +320,27 @@ public final class ImagePluginStack {
}
@Override
public int getEntryCount() {
return module.getEntryCount();
public int entryCount() {
return module.entryCount();
}
}
private final ModulePoolImpl pool;
Decompressor decompressor = new Decompressor();
Collection<ModuleEntry> content;
LastPool(ModulePoolImpl pool) {
private final ResourcePool pool;
Decompressor decompressor = new Decompressor();
Collection<ResourcePoolEntry> content;
LastPoolManager(ResourcePool pool) {
this.pool = pool;
}
@Override
public boolean isReadOnly() {
return true;
}
@Override
public void add(ModuleEntry resource) {
public void add(ResourcePoolEntry resource) {
throw new PluginException("pool is readonly");
}
@Override
public Optional<LinkModule> findModule(String name) {
Optional<LinkModule> module = pool.findModule(name);
public Optional<ResourcePoolModule> findModule(String name) {
Optional<ResourcePoolModule> module = pool.moduleView().findModule(name);
return module.isPresent()? Optional.of(new LastModule(module.get())) : Optional.empty();
}
@ -352,17 +350,17 @@ public final class ImagePluginStack {
* @return The collection of modules.
*/
@Override
public Stream<? extends LinkModule> modules() {
List<LinkModule> modules = new ArrayList<>();
pool.modules().forEach(m -> {
public Stream<ResourcePoolModule> modules() {
List<ResourcePoolModule> modules = new ArrayList<>();
pool.moduleView().modules().forEach(m -> {
modules.add(new LastModule(m));
});
return modules.stream();
}
@Override
public int getModuleCount() {
return pool.getModuleCount();
public int moduleCount() {
return pool.moduleView().moduleCount();
}
/**
@ -371,7 +369,7 @@ public final class ImagePluginStack {
* @return The stream of resources;
*/
@Override
public Stream<? extends ModuleEntry> entries() {
public Stream<ResourcePoolEntry> entries() {
if (content == null) {
content = new ArrayList<>();
pool.entries().forEach(md -> {
@ -382,8 +380,8 @@ public final class ImagePluginStack {
}
@Override
public int getEntryCount() {
return pool.getEntryCount();
public int entryCount() {
return pool.entryCount();
}
/**
@ -393,22 +391,22 @@ public final class ImagePluginStack {
* @return A Resource instance if the resource is found
*/
@Override
public Optional<ModuleEntry> findEntry(String path) {
public Optional<ResourcePoolEntry> findEntry(String path) {
Objects.requireNonNull(path);
Optional<ModuleEntry> res = pool.findEntry(path);
Optional<ResourcePoolEntry> res = pool.findEntry(path);
return res.isPresent()? Optional.of(getUncompressed(res.get())) : Optional.empty();
}
@Override
public Optional<ModuleEntry> findEntryInContext(String path, ModuleEntry context) {
public Optional<ResourcePoolEntry> findEntryInContext(String path, ResourcePoolEntry context) {
Objects.requireNonNull(path);
Objects.requireNonNull(context);
Optional<ModuleEntry> res = pool.findEntryInContext(path, context);
Optional<ResourcePoolEntry> res = pool.findEntryInContext(path, context);
return res.map(this::getUncompressed);
}
@Override
public boolean contains(ModuleEntry res) {
public boolean contains(ResourcePoolEntry res) {
return pool.contains(res);
}
@ -418,29 +416,27 @@ public final class ImagePluginStack {
}
@Override
public void transformAndCopy(Function<ModuleEntry, ModuleEntry> visitor, ModulePool output) {
pool.transformAndCopy(visitor, output);
public ByteOrder byteOrder() {
return pool.byteOrder();
}
@Override
public ByteOrder getByteOrder() {
return pool.getByteOrder();
public Map<String, String> releaseProperties() {
return pool.releaseProperties();
}
@Override
public Map<String, String> getReleaseProperties() {
return Collections.unmodifiableMap(pool.getReleaseProperties());
}
private ModuleEntry getUncompressed(ModuleEntry res) {
private ResourcePoolEntry getUncompressed(ResourcePoolEntry res) {
if (res != null) {
if (res instanceof ModulePoolImpl.CompressedModuleData) {
if (res instanceof ResourcePoolManager.CompressedModuleData) {
try {
byte[] bytes = decompressor.decompressResource(getByteOrder(),
(int offset) -> pool.getStringTable().getString(offset),
res.getBytes());
res = res.create(bytes);
byte[] bytes = decompressor.decompressResource(byteOrder(),
(int offset) -> ((ResourcePoolImpl)pool).getStringTable().getString(offset),
res.contentBytes());
res = res.copyWithContent(bytes);
} catch (IOException ex) {
if (JlinkTask.DEBUG) {
ex.printStackTrace();
}
throw new PluginException(ex);
}
}
@ -457,24 +453,24 @@ public final class ImagePluginStack {
* @param writer
* @throws java.lang.Exception
*/
public void storeFiles(ModulePoolImpl original, ModulePoolImpl transformed,
public void storeFiles(ResourcePool original, ResourcePool transformed,
BasicImageWriter writer)
throws Exception {
Objects.requireNonNull(original);
Objects.requireNonNull(transformed);
Optional<LinkModule> javaBase = transformed.findModule("java.base");
Optional<ResourcePoolModule> javaBase = transformed.moduleView().findModule("java.base");
javaBase.ifPresent(mod -> {
try {
Map<String, String> release = transformed.getReleaseProperties();
Map<String, String> release = transformed.releaseProperties();
// fill release information available from transformed "java.base" module!
ModuleDescriptor desc = mod.getDescriptor();
ModuleDescriptor desc = mod.descriptor();
desc.osName().ifPresent(s -> release.put("OS_NAME", s));
desc.osVersion().ifPresent(s -> release.put("OS_VERSION", s));
desc.osArch().ifPresent(s -> release.put("OS_ARCH", s));
} catch (Exception ignored) {}
});
imageBuilder.storeFiles(new LastPool(transformed));
imageBuilder.storeFiles(new LastPoolManager(transformed).resourcePool());
}
public ExecutableImage getExecutableImage() throws IOException {

@ -61,7 +61,7 @@ import jdk.tools.jlink.plugin.Plugin;
* ## Should use jdk.joptsimple some day.
*/
public class JlinkTask {
private static final boolean DEBUG = Boolean.getBoolean("jlink.debug");
static final boolean DEBUG = Boolean.getBoolean("jlink.debug");
private static <T extends Throwable> void fail(Class<T> type,
String format,

@ -33,20 +33,20 @@ import java.nio.file.Path;
import java.util.Objects;
/**
* A ModuleEntry backed by a given nio Path.
* A ResourcePoolEntry backed by a given nio Path.
*/
public class PathModuleEntry extends AbstractModuleEntry {
public class PathResourcePoolEntry extends AbstractResourcePoolEntry {
private final Path file;
/**
* Create a new PathModuleEntry.
* Create a new PathResourcePoolEntry.
*
* @param module The module name.
* @param path The path for the resource content.
* @param type The data type.
* @param file The data file identifier.
*/
public PathModuleEntry(String module, String path, Type type, Path file) {
public PathResourcePoolEntry(String module, String path, Type type, Path file) {
super(module, path, type);
this.file = Objects.requireNonNull(file);
if (!Files.isRegularFile(file)) {
@ -55,7 +55,7 @@ public class PathModuleEntry extends AbstractModuleEntry {
}
@Override
public final InputStream stream() {
public final InputStream content() {
try {
return Files.newInputStream(file);
} catch (IOException ex) {
@ -64,7 +64,7 @@ public class PathModuleEntry extends AbstractModuleEntry {
}
@Override
public final long getLength() {
public final long contentLength() {
try {
return Files.size(file);
} catch (IOException ex) {

@ -26,57 +26,41 @@ package jdk.tools.jlink.internal;
import java.nio.file.Path;
import java.util.Objects;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ResourcePoolEntry;
public final class ModuleEntryFactory {
private ModuleEntryFactory() {}
public final class ResourcePoolEntryFactory {
private ResourcePoolEntryFactory() {}
public static ModuleEntry create(String path,
ModuleEntry.Type type, byte[] content) {
return new ByteArrayModuleEntry(moduleFrom(path), path, type, content);
public static ResourcePoolEntry create(String path,
ResourcePoolEntry.Type type, byte[] content) {
return new ByteArrayResourcePoolEntry(moduleFrom(path), path, type, content);
}
public static ModuleEntry create(String path,
ModuleEntry.Type type, Path file) {
return new PathModuleEntry(moduleFrom(path), path, type, file);
public static ResourcePoolEntry create(String path,
ResourcePoolEntry.Type type, Path file) {
return new PathResourcePoolEntry(moduleFrom(path), path, type, file);
}
public static ModuleEntry create(ModuleEntry original, byte[] content) {
return new ByteArrayModuleEntry(original.getModule(),
original.getPath(), original.getType(), content);
public static ResourcePoolEntry create(ResourcePoolEntry original, byte[] content) {
return new ByteArrayResourcePoolEntry(original.moduleName(),
original.path(), original.type(), content);
}
public static ModuleEntry create(ModuleEntry original, Path file) {
return new PathModuleEntry(original.getModule(),
original.getPath(), original.getType(), file);
public static ResourcePoolEntry create(ResourcePoolEntry original, Path file) {
return new PathResourcePoolEntry(original.moduleName(),
original.path(), original.type(), file);
}
static String moduleFrom(String path) {
private static String moduleFrom(String path) {
Objects.requireNonNull(path);
if (path.isEmpty() || path.charAt(0) != '/') {
throw new IllegalArgumentException(path + " must start with /");
}
int idx = path.indexOf('/', 1);
String noRoot = path.substring(1);
int idx = noRoot.indexOf('/');
if (idx == -1) {
throw new IllegalArgumentException("/ missing after module: " + path);
}
return path.substring(1, idx);
}
static String packageFrom(String path) {
Objects.requireNonNull(path);
int idx = path.lastIndexOf('/');
if (idx == -1) {
throw new IllegalArgumentException("/ missing from path: " + path);
}
if (path.startsWith("/")) {
int jdx = path.indexOf('/', 1);
if (jdx == -1) {
throw new IllegalArgumentException("/ missing after module: " + path);
}
return path.substring(jdx + 1, idx);
} else {
return path.substring(0, idx);
}
return noRoot.substring(0, idx);
}
}

@ -38,34 +38,36 @@ import java.util.Set;
import java.util.function.Function;
import java.util.stream.Stream;
import jdk.internal.jimage.decompressor.CompressedResourceHeader;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.LinkModule;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
import jdk.tools.jlink.plugin.ResourcePoolEntry;
import jdk.tools.jlink.plugin.ResourcePoolModule;
import jdk.tools.jlink.plugin.ResourcePoolModuleView;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.internal.plugins.FileCopierPlugin;
/**
* Pool of module data.
* A manager for pool of resources.
*/
public class ModulePoolImpl implements ModulePool {
public class ResourcePoolManager {
private class ModuleImpl implements LinkModule {
class ResourcePoolModuleImpl implements ResourcePoolModule {
final Map<String, ModuleEntry> moduleContent = new LinkedHashMap<>();
final Map<String, ResourcePoolEntry> moduleContent = new LinkedHashMap<>();
private ModuleDescriptor descriptor;
final String name;
private ModuleImpl(String name) {
private ResourcePoolModuleImpl(String name) {
this.name = name;
}
@Override
public String getName() {
public String name() {
return name;
}
@Override
public Optional<ModuleEntry> findEntry(String path) {
public Optional<ResourcePoolEntry> findEntry(String path) {
if (!path.startsWith("/")) {
path = "/" + path;
}
@ -76,41 +78,28 @@ public class ModulePoolImpl implements ModulePool {
}
@Override
public ModuleDescriptor getDescriptor() {
public ModuleDescriptor descriptor() {
if (descriptor == null) {
String p = "/" + name + "/module-info.class";
Optional<ModuleEntry> content = findEntry(p);
Optional<ResourcePoolEntry> content = findEntry(p);
if (!content.isPresent()) {
throw new PluginException("No module-info for " + name
+ " module");
}
ByteBuffer bb = ByteBuffer.wrap(content.get().getBytes());
ByteBuffer bb = ByteBuffer.wrap(content.get().contentBytes());
descriptor = ModuleDescriptor.read(bb);
}
return descriptor;
}
@Override
public void add(ModuleEntry data) {
if (isReadOnly()) {
throw new PluginException("ModulePool is readonly");
}
Objects.requireNonNull(data);
if (!data.getModule().equals(name)) {
throw new PluginException("Can't add resource " + data.getPath()
+ " to module " + name);
}
ModulePoolImpl.this.add(data);
}
@Override
public Set<String> getAllPackages() {
public Set<String> packages() {
Set<String> pkgs = new HashSet<>();
moduleContent.values().stream().filter(m -> m.getType().
equals(ModuleEntry.Type.CLASS_OR_RESOURCE)).forEach(res -> {
moduleContent.values().stream().filter(m -> m.type().
equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)).forEach(res -> {
// Module metadata only contains packages with .class files
if (ImageFileCreator.isClassPackage(res.getPath())) {
String[] split = ImageFileCreator.splitPath(res.getPath());
if (ImageFileCreator.isClassPackage(res.path())) {
String[] split = ImageFileCreator.splitPath(res.path());
String pkg = split[1];
if (pkg != null && !pkg.isEmpty()) {
pkgs.add(pkg);
@ -122,35 +111,121 @@ public class ModulePoolImpl implements ModulePool {
@Override
public String toString() {
return getName();
return name();
}
@Override
public Stream<? extends ModuleEntry> entries() {
public Stream<ResourcePoolEntry> entries() {
return moduleContent.values().stream();
}
@Override
public int getEntryCount() {
public int entryCount() {
return moduleContent.values().size();
}
}
private final Map<String, ModuleEntry> resources = new LinkedHashMap<>();
private final Map<String, ModuleImpl> modules = new LinkedHashMap<>();
private final ModuleImpl fileCopierModule = new ModuleImpl(FileCopierPlugin.FAKE_MODULE);
public class ResourcePoolImpl implements ResourcePool {
@Override
public ResourcePoolModuleView moduleView() {
return ResourcePoolManager.this.moduleView();
}
@Override
public Stream<ResourcePoolEntry> entries() {
return ResourcePoolManager.this.entries();
}
@Override
public int entryCount() {
return ResourcePoolManager.this.entryCount();
}
@Override
public Optional<ResourcePoolEntry> findEntry(String path) {
return ResourcePoolManager.this.findEntry(path);
}
@Override
public Optional<ResourcePoolEntry> findEntryInContext(String path, ResourcePoolEntry context) {
return ResourcePoolManager.this.findEntryInContext(path, context);
}
@Override
public boolean contains(ResourcePoolEntry data) {
return ResourcePoolManager.this.contains(data);
}
@Override
public boolean isEmpty() {
return ResourcePoolManager.this.isEmpty();
}
@Override
public ByteOrder byteOrder() {
return ResourcePoolManager.this.byteOrder();
}
@Override
public Map<String, String> releaseProperties() {
return ResourcePoolManager.this.releaseProperties();
}
public StringTable getStringTable() {
return ResourcePoolManager.this.getStringTable();
}
}
class ResourcePoolBuilderImpl implements ResourcePoolBuilder {
private boolean built;
@Override
public void add(ResourcePoolEntry data) {
if (built) {
throw new IllegalStateException("resource pool already built!");
}
ResourcePoolManager.this.add(data);
}
@Override
public ResourcePool build() {
built = true;
return ResourcePoolManager.this.resourcePool();
}
}
class ResourcePoolModuleViewImpl implements ResourcePoolModuleView {
@Override
public Optional<ResourcePoolModule> findModule(String name) {
return ResourcePoolManager.this.findModule(name);
}
@Override
public Stream<ResourcePoolModule> modules() {
return ResourcePoolManager.this.modules();
}
@Override
public int moduleCount() {
return ResourcePoolManager.this.moduleCount();
}
}
private final Map<String, ResourcePoolEntry> resources = new LinkedHashMap<>();
private final Map<String, ResourcePoolModule> modules = new LinkedHashMap<>();
private final ResourcePoolModuleImpl fileCopierModule = new ResourcePoolModuleImpl(FileCopierPlugin.FAKE_MODULE);
private Map<String, String> releaseProps = new HashMap<>();
private final ByteOrder order;
private boolean isReadOnly;
private final StringTable table;
private final ResourcePool poolImpl;
private final ResourcePoolBuilder poolBuilderImpl;
private final ResourcePoolModuleView moduleViewImpl;
public ModulePoolImpl() {
public ResourcePoolManager() {
this(ByteOrder.nativeOrder());
}
public ModulePoolImpl(ByteOrder order) {
public ResourcePoolManager(ByteOrder order) {
this(order, new StringTable() {
@Override
@ -165,39 +240,50 @@ public class ModulePoolImpl implements ModulePool {
});
}
public ModulePoolImpl(ByteOrder order, StringTable table) {
public ResourcePoolManager(ByteOrder order, StringTable table) {
this.order = Objects.requireNonNull(order);
this.table = Objects.requireNonNull(table);
this.poolImpl = new ResourcePoolImpl();
this.poolBuilderImpl = new ResourcePoolBuilderImpl();
this.moduleViewImpl = new ResourcePoolModuleViewImpl();
}
public ResourcePool resourcePool() {
return poolImpl;
}
public ResourcePoolBuilder resourcePoolBuilder() {
return poolBuilderImpl;
}
public ResourcePoolModuleView moduleView() {
return moduleViewImpl;
}
/**
* Add a ModuleEntry.
* Add a ResourcePoolEntry.
*
* @param data The ModuleEntry to add.
* @param data The ResourcePoolEntry to add.
*/
@Override
public void add(ModuleEntry data) {
if (isReadOnly()) {
throw new PluginException("ModulePool is readonly");
}
public void add(ResourcePoolEntry data) {
Objects.requireNonNull(data);
if (resources.get(data.getPath()) != null) {
throw new PluginException("Resource " + data.getPath()
if (resources.get(data.path()) != null) {
throw new PluginException("Resource " + data.path()
+ " already present");
}
String modulename = data.getModule();
ModuleImpl m = modules.get(modulename);
String modulename = data.moduleName();
ResourcePoolModuleImpl m = (ResourcePoolModuleImpl)modules.get(modulename);
// ## TODO: FileCopierPlugin should not add content to a module
// FAKE_MODULE is not really a module to be added in the image
if (FileCopierPlugin.FAKE_MODULE.equals(modulename)) {
m = fileCopierModule;
}
if (m == null) {
m = new ModuleImpl(modulename);
m = new ResourcePoolModuleImpl(modulename);
modules.put(modulename, m);
}
resources.put(data.getPath(), data);
m.moduleContent.put(data.getPath(), data);
resources.put(data.path(), data);
m.moduleContent.put(data.path(), data);
}
/**
@ -206,175 +292,123 @@ public class ModulePoolImpl implements ModulePool {
* @param name The module name
* @return the module of matching name, if found
*/
@Override
public Optional<LinkModule> findModule(String name) {
public Optional<ResourcePoolModule> findModule(String name) {
Objects.requireNonNull(name);
return Optional.ofNullable(modules.get(name));
}
/**
* The stream of modules contained in this ModulePool.
* The stream of modules contained in this ResourcePool.
*
* @return The stream of modules.
*/
@Override
public Stream<? extends LinkModule> modules() {
public Stream<ResourcePoolModule> modules() {
return modules.values().stream();
}
/**
* Return the number of LinkModule count in this ModulePool.
* Return the number of ResourcePoolModule count in this ResourcePool.
*
* @return the module count.
*/
@Override
public int getModuleCount() {
public int moduleCount() {
return modules.size();
}
/**
* Get all ModuleEntry contained in this ModulePool instance.
* Get all ResourcePoolEntry contained in this ResourcePool instance.
*
* @return The stream of LinkModuleEntries.
* @return The stream of ResourcePoolModuleEntries.
*/
@Override
public Stream<? extends ModuleEntry> entries() {
public Stream<ResourcePoolEntry> entries() {
return resources.values().stream();
}
/**
* Return the number of ModuleEntry count in this ModulePool.
* Return the number of ResourcePoolEntry count in this ResourcePool.
*
* @return the entry count.
*/
@Override
public int getEntryCount() {
public int entryCount() {
return resources.values().size();
}
/**
* Get the ModuleEntry for the passed path.
* Get the ResourcePoolEntry for the passed path.
*
* @param path A data path
* @return A ModuleEntry instance or null if the data is not found
* @return A ResourcePoolEntry instance or null if the data is not found
*/
@Override
public Optional<ModuleEntry> findEntry(String path) {
public Optional<ResourcePoolEntry> findEntry(String path) {
Objects.requireNonNull(path);
return Optional.ofNullable(resources.get(path));
}
/**
* Get the ModuleEntry for the passed path restricted to supplied context.
* Get the ResourcePoolEntry for the passed path restricted to supplied context.
*
* @param path A data path
* @param context A context of the search
* @return A ModuleEntry instance or null if the data is not found
* @return A ResourcePoolEntry instance or null if the data is not found
*/
@Override
public Optional<ModuleEntry> findEntryInContext(String path, ModuleEntry context) {
public Optional<ResourcePoolEntry> findEntryInContext(String path, ResourcePoolEntry context) {
Objects.requireNonNull(path);
Objects.requireNonNull(context);
LinkModule module = modules.get(context.getModule());
ResourcePoolModule module = modules.get(context.moduleName());
Objects.requireNonNull(module);
Optional<ModuleEntry> entry = module.findEntry(path);
Optional<ResourcePoolEntry> entry = module.findEntry(path);
// Navigating other modules via requires and exports is problematic
// since we cannot construct the runtime model of loaders and layers.
return entry;
}
/**
* Check if the ModulePool contains the given ModuleEntry.
* Check if the ResourcePool contains the given ResourcePoolEntry.
*
* @param data The module data to check existence for.
* @return The module data or null if not found.
*/
@Override
public boolean contains(ModuleEntry data) {
public boolean contains(ResourcePoolEntry data) {
Objects.requireNonNull(data);
return findEntry(data.getPath()).isPresent();
return findEntry(data.path()).isPresent();
}
/**
* Check if the ModulePool contains some content at all.
* Check if the ResourcePool contains some content at all.
*
* @return True, no content, false otherwise.
*/
@Override
public boolean isEmpty() {
return resources.isEmpty();
}
/**
* Visit each ModuleEntry in this ModulePool to transform it and
* copy the transformed ModuleEntry to the output ModulePool.
*
* @param transform The function called for each ModuleEntry found in
* the ModulePool. The transform function should return a
* ModuleEntry instance which will be added to the output or it should
* return null if the passed ModuleEntry is to be ignored for the
* output.
*
* @param output The ModulePool to be filled with Visitor returned
* ModuleEntry.
*/
@Override
public void transformAndCopy(Function<ModuleEntry, ModuleEntry> transform,
ModulePool output) {
entries().forEach(resource -> {
ModuleEntry res = transform.apply(resource);
if (res != null) {
output.add(res);
}
});
}
/**
* The ByteOrder currently in use when generating the jimage file.
*
* @return The ByteOrder.
*/
@Override
public ByteOrder getByteOrder() {
public ByteOrder byteOrder() {
return order;
}
@Override
public Map<String, String> getReleaseProperties() {
return isReadOnly()? Collections.unmodifiableMap(releaseProps) : releaseProps;
public Map<String, String> releaseProperties() {
return releaseProps;
}
public StringTable getStringTable() {
return table;
}
/**
* Make this Resources instance read-only. No resource can be added.
*/
public void setReadOnly() {
isReadOnly = true;
}
/**
* Read only state.
*
* @return true if readonly false otherwise.
*/
@Override
public boolean isReadOnly() {
return isReadOnly;
}
/**
* A resource that has been compressed.
*/
public static final class CompressedModuleData extends ByteArrayModuleEntry {
public static final class CompressedModuleData extends ByteArrayResourcePoolEntry {
final long uncompressed_size;
private CompressedModuleData(String module, String path,
byte[] content, long uncompressed_size) {
super(module, path, ModuleEntry.Type.CLASS_OR_RESOURCE, content);
super(module, path, ResourcePoolEntry.Type.CLASS_OR_RESOURCE, content);
this.uncompressed_size = uncompressed_size;
}
@ -388,7 +422,7 @@ public class ModulePoolImpl implements ModulePool {
return false;
}
CompressedModuleData f = (CompressedModuleData) other;
return f.getPath().equals(getPath());
return f.path().equals(path());
}
@Override
@ -397,7 +431,7 @@ public class ModulePoolImpl implements ModulePool {
}
}
public static CompressedModuleData newCompressedResource(ModuleEntry original,
public static CompressedModuleData newCompressedResource(ResourcePoolEntry original,
ByteBuffer compressed,
String plugin, String pluginConfig, StringTable strings,
ByteOrder order) {
@ -406,7 +440,7 @@ public class ModulePoolImpl implements ModulePool {
Objects.requireNonNull(plugin);
boolean isTerminal = !(original instanceof CompressedModuleData);
long uncompressed_size = original.getLength();
long uncompressed_size = original.contentLength();
if (original instanceof CompressedModuleData) {
CompressedModuleData comp = (CompressedModuleData) original;
uncompressed_size = comp.getUncompressedSize();
@ -417,7 +451,7 @@ public class ModulePoolImpl implements ModulePool {
configOffset = strings.addString(plugin);
}
CompressedResourceHeader rh
= new CompressedResourceHeader(compressed.limit(), original.getLength(),
= new CompressedResourceHeader(compressed.limit(), original.contentLength(),
nameOffset, configOffset, isTerminal);
// Merge header with content;
byte[] h = rh.getBytes(order);
@ -428,9 +462,8 @@ public class ModulePoolImpl implements ModulePool {
byte[] contentWithHeader = bb.array();
CompressedModuleData compressedResource
= new CompressedModuleData(original.getModule(), original.getPath(),
= new CompressedModuleData(original.moduleName(), original.path(),
contentWithHeader, uncompressed_size);
return compressedResource;
}
}

@ -24,7 +24,7 @@
*/
package jdk.tools.jlink.internal;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.ResourcePool;
/**
* Plugin wishing to pre-visit the resources must implement this interface.
@ -43,5 +43,5 @@ public interface ResourcePrevisitor {
* @param strings StringTable instance. Add string to the StringTable to track string
* usage.
*/
public void previsit(ModulePool resources, StringTable strings);
public void previsit(ResourcePool resources, StringTable strings);
}

@ -29,7 +29,8 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
import jdk.tools.jlink.plugin.Plugin.Category;
import jdk.internal.org.objectweb.asm.ClassReader;
import static jdk.internal.org.objectweb.asm.ClassReader.*;
@ -44,7 +45,7 @@ import jdk.internal.org.objectweb.asm.tree.LdcInsnNode;
import jdk.internal.org.objectweb.asm.tree.LineNumberNode;
import jdk.internal.org.objectweb.asm.tree.MethodInsnNode;
import jdk.internal.org.objectweb.asm.tree.MethodNode;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ResourcePoolEntry;
import jdk.tools.jlink.plugin.Plugin;
public final class ClassForNamePlugin implements Plugin {
@ -55,8 +56,8 @@ public final class ClassForNamePlugin implements Plugin {
path.length() - ".class".length());
}
private static int getAccess(ModuleEntry resource) {
ClassReader cr = new ClassReader(resource.getBytes());
private static int getAccess(ResourcePoolEntry resource) {
ClassReader cr = new ClassReader(resource.contentBytes());
return cr.getAccess();
}
@ -67,8 +68,8 @@ public final class ClassForNamePlugin implements Plugin {
return index == -1 ? "" : binaryName.substring(0, index);
}
private ModuleEntry transform(ModuleEntry resource, ModulePool pool) {
byte[] inBytes = resource.getBytes();
private ResourcePoolEntry transform(ResourcePoolEntry resource, ResourcePool pool) {
byte[] inBytes = resource.contentBytes();
ClassReader cr = new ClassReader(inBytes);
ClassNode cn = new ClassNode();
cr.accept(cn, EXPAND_FRAMES);
@ -76,7 +77,7 @@ public final class ClassForNamePlugin implements Plugin {
boolean modified = false;
LdcInsnNode ldc = null;
String thisPackage = getPackage(binaryClassName(resource.getPath()));
String thisPackage = getPackage(binaryClassName(resource.path()));
for (MethodNode mn : ms) {
InsnList il = mn.instructions;
@ -96,7 +97,7 @@ public final class ClassForNamePlugin implements Plugin {
min.desc.equals("(Ljava/lang/String;)Ljava/lang/Class;")) {
String ldcClassName = ldc.cst.toString();
String thatClassName = ldcClassName.replaceAll("\\.", "/");
Optional<ModuleEntry> thatClass =
Optional<ResourcePoolEntry> thatClass =
pool.findEntryInContext(thatClassName + ".class", resource);
if (thatClass.isPresent()) {
@ -128,7 +129,7 @@ public final class ClassForNamePlugin implements Plugin {
cn.accept(cw);
byte[] outBytes = cw.toByteArray();
return resource.create(outBytes);
return resource.copyWithContent(outBytes);
}
return resource;
@ -140,13 +141,13 @@ public final class ClassForNamePlugin implements Plugin {
}
@Override
public void visit(ModulePool in, ModulePool out) {
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
Objects.requireNonNull(in);
Objects.requireNonNull(out);
in.entries()
.forEach(resource -> {
String path = resource.getPath();
String path = resource.path();
if (path.endsWith(".class") && !path.endsWith("/module-info.class")) {
out.add(transform(resource, in));
@ -154,6 +155,7 @@ public final class ClassForNamePlugin implements Plugin {
out.add(resource);
}
});
return out.build();
}
@Override

@ -26,10 +26,12 @@ package jdk.tools.jlink.internal.plugins;
import java.util.Map;
import jdk.tools.jlink.internal.ModulePoolImpl;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.internal.ResourcePoolManager.ResourcePoolImpl;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.internal.ImagePluginStack;
import jdk.tools.jlink.internal.ResourcePoolManager;
import jdk.tools.jlink.internal.ResourcePrevisitor;
import jdk.tools.jlink.internal.StringTable;
@ -53,21 +55,22 @@ public final class DefaultCompressPlugin implements Plugin, ResourcePrevisitor {
}
@Override
public void visit(ModulePool in, ModulePool out) {
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
if (ss != null && zip != null) {
ModulePool output = new ImagePluginStack.OrderedResourcePool(in.getByteOrder(),
((ModulePoolImpl) in).getStringTable());
ss.visit(in, output);
zip.visit(output, out);
ResourcePoolManager resMgr = new ImagePluginStack.OrderedResourcePoolManager(
in.byteOrder(), ((ResourcePoolImpl)in).getStringTable());
return zip.transform(ss.transform(in, resMgr.resourcePoolBuilder()), out);
} else if (ss != null) {
ss.visit(in, out);
return ss.transform(in, out);
} else if (zip != null) {
zip.visit(in, out);
return zip.transform(in, out);
}
return out.build();
}
@Override
public void previsit(ModulePool resources, StringTable strings) {
public void previsit(ResourcePool resources, StringTable strings) {
if (ss != null) {
ss.previsit(resources, strings);
}

@ -27,8 +27,9 @@ package jdk.tools.jlink.internal.plugins;
import java.util.Map;
import java.util.function.Predicate;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
import jdk.tools.jlink.plugin.ResourcePoolEntry;
/**
*
@ -45,13 +46,14 @@ public final class ExcludeFilesPlugin implements Plugin {
}
@Override
public void visit(ModulePool in, ModulePool out) {
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
in.transformAndCopy((file) -> {
if (!file.getType().equals(ModuleEntry.Type.CLASS_OR_RESOURCE)) {
file = predicate.test(file.getPath()) ? file : null;
if (!file.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)) {
file = predicate.test(file.path()) ? file : null;
}
return file;
}, out);
return out.build();
}
@Override

@ -27,8 +27,9 @@ package jdk.tools.jlink.internal.plugins;
import java.util.Map;
import java.util.function.Predicate;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
import jdk.tools.jlink.plugin.ResourcePoolEntry;
/**
*
@ -45,13 +46,14 @@ public final class ExcludePlugin implements Plugin {
}
@Override
public void visit(ModulePool in, ModulePool out) {
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
in.transformAndCopy((resource) -> {
if (resource.getType().equals(ModuleEntry.Type.CLASS_OR_RESOURCE)) {
resource = predicate.test(resource.getPath()) ? resource : null;
if (resource.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)) {
resource = predicate.test(resource.path()) ? resource : null;
}
return resource;
}, out);
return out.build();
}
@Override

@ -36,8 +36,9 @@ import java.util.TreeSet;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
import jdk.tools.jlink.plugin.ResourcePoolEntry;
import jdk.tools.jlink.plugin.PluginException;
/**
@ -97,25 +98,25 @@ public final class ExcludeVMPlugin implements Plugin {
* e.g.: /java.base/native/amd64/server/libjvm.so
* /java.base/native/server/libjvm.dylib
*/
private List<ModuleEntry> getVMs(ModulePool in) {
private List<ResourcePoolEntry> getVMs(ResourcePool in) {
String jvmlib = jvmlib();
List<ModuleEntry> ret = in.findModule("java.base").get().entries().filter((t) -> {
return t.getPath().endsWith("/" + jvmlib);
List<ResourcePoolEntry> ret = in.moduleView().findModule("java.base").get().entries().filter((t) -> {
return t.path().endsWith("/" + jvmlib);
}).collect(Collectors.toList());
return ret;
}
@Override
public void visit(ModulePool in, ModulePool out) {
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
String jvmlib = jvmlib();
TreeSet<Jvm> existing = new TreeSet<>(new JvmComparator());
TreeSet<Jvm> removed = new TreeSet<>(new JvmComparator());
if (!keepAll) {
// First retrieve all available VM names and removed VM
List<ModuleEntry> jvms = getVMs(in);
List<ResourcePoolEntry> jvms = getVMs(in);
for (Jvm jvm : Jvm.values()) {
for (ModuleEntry md : jvms) {
if (md.getPath().endsWith("/" + jvm.getName() + "/" + jvmlib)) {
for (ResourcePoolEntry md : jvms) {
if (md.path().endsWith("/" + jvm.getName() + "/" + jvmlib)) {
existing.add(jvm);
if (isRemoved(md)) {
removed.add(jvm);
@ -134,8 +135,8 @@ public final class ExcludeVMPlugin implements Plugin {
// Rewrite the jvm.cfg file.
in.transformAndCopy((file) -> {
if (!keepAll) {
if (file.getType().equals(ModuleEntry.Type.NATIVE_LIB)) {
if (file.getPath().endsWith(JVM_CFG)) {
if (file.type().equals(ResourcePoolEntry.Type.NATIVE_LIB)) {
if (file.path().endsWith(JVM_CFG)) {
try {
file = handleJvmCfgFile(file, existing, removed);
} catch (IOException ex) {
@ -148,10 +149,11 @@ public final class ExcludeVMPlugin implements Plugin {
return file;
}, out);
return out.build();
}
private boolean isRemoved(ModuleEntry file) {
return !predicate.test(file.getPath());
private boolean isRemoved(ResourcePoolEntry file) {
return !predicate.test(file.path());
}
@Override
@ -206,7 +208,7 @@ public final class ExcludeVMPlugin implements Plugin {
predicate = ResourceFilter.excludeFilter(exclude);
}
private ModuleEntry handleJvmCfgFile(ModuleEntry orig,
private ResourcePoolEntry handleJvmCfgFile(ResourcePoolEntry orig,
TreeSet<Jvm> existing,
TreeSet<Jvm> removed) throws IOException {
if (keepAll) {
@ -215,7 +217,7 @@ public final class ExcludeVMPlugin implements Plugin {
StringBuilder builder = new StringBuilder();
// Keep comments
try (BufferedReader reader
= new BufferedReader(new InputStreamReader(orig.stream(),
= new BufferedReader(new InputStreamReader(orig.content(),
StandardCharsets.UTF_8))) {
reader.lines().forEach((s) -> {
if (s.startsWith("#")) {
@ -242,7 +244,7 @@ public final class ExcludeVMPlugin implements Plugin {
byte[] content = builder.toString().getBytes(StandardCharsets.UTF_8);
return orig.create(content);
return orig.copyWithContent(content);
}
private static String jvmlib() {

@ -37,10 +37,11 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import jdk.tools.jlink.internal.PathModuleEntry;
import jdk.tools.jlink.internal.PathResourcePoolEntry;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
import jdk.tools.jlink.plugin.ResourcePoolEntry;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.internal.Utils;
@ -64,12 +65,12 @@ public class FileCopierPlugin implements Plugin {
/**
* Symbolic link to another path.
*/
public static abstract class SymImageFile extends PathModuleEntry {
public static abstract class SymImageFile extends PathResourcePoolEntry {
private final String targetPath;
public SymImageFile(String targetPath, String module, String path,
ModuleEntry.Type type, Path file) {
ResourcePoolEntry.Type type, Path file) {
super(module, path, type, file);
this.targetPath = targetPath;
}
@ -82,7 +83,7 @@ public class FileCopierPlugin implements Plugin {
private static final class SymImageFileImpl extends SymImageFile {
public SymImageFileImpl(String targetPath, Path file, String module,
String path, ModuleEntry.Type type) {
String path, ResourcePoolEntry.Type type) {
super(targetPath, module, path, type, file);
}
}
@ -90,11 +91,11 @@ public class FileCopierPlugin implements Plugin {
private static final class DirectoryCopy implements FileVisitor<Path> {
private final Path source;
private final ModulePool pool;
private final ResourcePoolBuilder pool;
private final String targetDir;
private final List<SymImageFile> symlinks = new ArrayList<>();
DirectoryCopy(Path source, ModulePool pool, String targetDir) {
DirectoryCopy(Path source, ResourcePoolBuilder pool, String targetDir) {
this.source = source;
this.pool = pool;
this.targetDir = targetDir;
@ -128,7 +129,7 @@ public class FileCopierPlugin implements Plugin {
}
SymImageFileImpl impl = new SymImageFileImpl(symTarget.toString(),
file, path, Objects.requireNonNull(file.getFileName()).toString(),
ModuleEntry.Type.OTHER);
ResourcePoolEntry.Type.OTHER);
symlinks.add(impl);
} else {
addFile(pool, file, path);
@ -152,14 +153,14 @@ public class FileCopierPlugin implements Plugin {
}
}
private static void addFile(ModulePool pool, Path file, String path)
private static void addFile(ResourcePoolBuilder pool, Path file, String path)
throws IOException {
Objects.requireNonNull(pool);
Objects.requireNonNull(file);
Objects.requireNonNull(path);
ModuleEntry impl = ModuleEntry.create(
ResourcePoolEntry impl = ResourcePoolEntry.create(
"/" + FAKE_MODULE + "/other/" + path,
ModuleEntry.Type.OTHER, file);
ResourcePoolEntry.Type.OTHER, file);
try {
pool.add(impl);
} catch (Exception ex) {
@ -211,7 +212,7 @@ public class FileCopierPlugin implements Plugin {
}
@Override
public void visit(ModulePool in, ModulePool out) {
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
in.transformAndCopy((file) -> {
return file;
}, out);
@ -238,6 +239,8 @@ public class FileCopierPlugin implements Plugin {
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
return out.build();
}
@Override

@ -31,9 +31,10 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ResourcePoolEntry;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
import jdk.tools.jlink.plugin.Plugin;
/**
@ -145,22 +146,22 @@ public final class GenerateJLIClassesPlugin implements Plugin {
}
@Override
public void visit(ModulePool in, ModulePool out) {
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
in.entries().forEach(data -> {
if (("/java.base/" + BMH + ".class").equals(data.getPath())) {
if (("/java.base/" + BMH + ".class").equals(data.path())) {
// Add BoundMethodHandle unchanged
out.add(data);
speciesTypes.forEach(types -> generateConcreteClass(types, data, out));
} else {
if (!out.contains(data)) {
out.add(data);
}
out.add(data);
}
});
return out.build();
}
@SuppressWarnings("unchecked")
private void generateConcreteClass(String types, ModuleEntry data, ModulePool out) {
private void generateConcreteClass(String types, ResourcePoolEntry data, ResourcePoolBuilder out) {
try {
// Generate class
Map.Entry<String, byte[]> result = (Map.Entry<String, byte[]>)
@ -169,12 +170,10 @@ public final class GenerateJLIClassesPlugin implements Plugin {
byte[] bytes = result.getValue();
// Add class to pool
ModuleEntry ndata = ModuleEntry.create(
ResourcePoolEntry ndata = ResourcePoolEntry.create(
"/java.base/" + className + ".class",
bytes);
if (!out.contains(ndata)) {
out.add(ndata);
}
out.add(ndata);
} catch (Exception ex) {
throw new PluginException(ex);
}

@ -42,10 +42,11 @@ import java.util.stream.Stream;
import jdk.internal.org.objectweb.asm.ClassReader;
import jdk.tools.jlink.internal.ResourcePrevisitor;
import jdk.tools.jlink.internal.StringTable;
import jdk.tools.jlink.plugin.LinkModule;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ResourcePoolModule;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
import jdk.tools.jlink.plugin.ResourcePoolEntry;
import jdk.tools.jlink.plugin.Plugin;
import sun.util.cldr.CLDRBaseLocaleDataMetaInfo;
import sun.util.locale.provider.LocaleProviderAdapter;
@ -151,24 +152,26 @@ public final class IncludeLocalesPlugin implements Plugin, ResourcePrevisitor {
}
@Override
public void visit(ModulePool in, ModulePool out) {
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
in.transformAndCopy((resource) -> {
if (resource.getModule().equals(MODULENAME)) {
String path = resource.getPath();
if (resource.moduleName().equals(MODULENAME)) {
String path = resource.path();
resource = predicate.test(path) ? resource: null;
if (resource != null &&
resource.getType().equals(ModuleEntry.Type.CLASS_OR_RESOURCE)) {
byte[] bytes = resource.getBytes();
resource.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)) {
byte[] bytes = resource.contentBytes();
ClassReader cr = new ClassReader(bytes);
if (Arrays.stream(cr.getInterfaces())
.anyMatch(i -> i.contains(METAINFONAME)) &&
stripUnsupportedLocales(bytes, cr)) {
resource = resource.create(bytes);
resource = resource.copyWithContent(bytes);
}
}
}
return resource;
}, out);
return out.build();
}
@Override
@ -205,14 +208,14 @@ public final class IncludeLocalesPlugin implements Plugin, ResourcePrevisitor {
}
@Override
public void previsit(ModulePool resources, StringTable strings) {
public void previsit(ResourcePool resources, StringTable strings) {
final Pattern p = Pattern.compile(".*((Data_)|(Names_))(?<tag>.*)\\.class");
Optional<LinkModule> optMod = resources.findModule(MODULENAME);
Optional<ResourcePoolModule> optMod = resources.moduleView().findModule(MODULENAME);
// jdk.localedata module validation
if (optMod.isPresent()) {
LinkModule module = optMod.get();
Set<String> packages = module.getAllPackages();
ResourcePoolModule module = optMod.get();
Set<String> packages = module.packages();
if (!packages.containsAll(LOCALEDATA_PACKAGES)) {
throw new PluginException(PluginsResourceBundle.getMessage(NAME + ".missingpackages") +
LOCALEDATA_PACKAGES.stream()
@ -221,7 +224,7 @@ public final class IncludeLocalesPlugin implements Plugin, ResourcePrevisitor {
}
available = Stream.concat(module.entries()
.map(md -> p.matcher(md.getPath()))
.map(md -> p.matcher(md.path()))
.filter(m -> m.matches())
.map(m -> m.group("tag").replaceAll("_", "-")),
Stream.concat(Stream.of(jaJPJPTag), Stream.of(thTHTHTag)))

@ -35,8 +35,9 @@ import java.util.List;
import java.util.Map;
import java.util.function.ToIntFunction;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
import jdk.tools.jlink.plugin.ResourcePoolEntry;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.internal.Utils;
@ -62,20 +63,20 @@ public final class OrderResourcesPlugin implements Plugin {
}
static class SortWrapper {
private final ModuleEntry resource;
private final ResourcePoolEntry resource;
private final int ordinal;
SortWrapper(ModuleEntry resource, int ordinal) {
SortWrapper(ResourcePoolEntry resource, int ordinal) {
this.resource = resource;
this.ordinal = ordinal;
}
ModuleEntry getResource() {
ResourcePoolEntry getResource() {
return resource;
}
String getPath() {
return resource.getPath();
return resource.path();
}
int getOrdinal() {
@ -95,8 +96,8 @@ public final class OrderResourcesPlugin implements Plugin {
return path;
}
private int getOrdinal(ModuleEntry resource) {
String path = resource.getPath();
private int getOrdinal(ResourcePoolEntry resource) {
String path = resource.path();
Integer value = orderedPaths.get(stripModule(path));
@ -126,17 +127,19 @@ public final class OrderResourcesPlugin implements Plugin {
}
@Override
public void visit(ModulePool in, ModulePool out) {
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
in.entries()
.filter(resource -> resource.getType()
.equals(ModuleEntry.Type.CLASS_OR_RESOURCE))
.filter(resource -> resource.type()
.equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE))
.map((resource) -> new SortWrapper(resource, getOrdinal(resource)))
.sorted(OrderResourcesPlugin::compare)
.forEach((wrapper) -> out.add(wrapper.getResource()));
in.entries()
.filter(other -> !other.getType()
.equals(ModuleEntry.Type.CLASS_OR_RESOURCE))
.filter(other -> !other.type()
.equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE))
.forEach((other) -> out.add(other));
return out.build();
}
@Override

@ -33,7 +33,8 @@ import java.util.Properties;
import java.util.Set;
import java.util.function.Function;
import jdk.tools.jlink.internal.Utils;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
import jdk.tools.jlink.plugin.Plugin.Category;
import jdk.tools.jlink.plugin.Plugin.State;
import jdk.tools.jlink.plugin.Plugin;
@ -117,9 +118,8 @@ public final class ReleaseInfoPlugin implements Plugin {
}
@Override
public void visit(ModulePool in, ModulePool out) {
in.transformAndCopy(Function.identity(), out);
out.getReleaseProperties().putAll(in.getReleaseProperties());
out.getReleaseProperties().putAll(release);
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
in.releaseProperties().putAll(release);
return in;
}
}

@ -55,11 +55,13 @@ import java.util.stream.Collectors;
import jdk.internal.jimage.decompressor.CompressIndexes;
import jdk.internal.jimage.decompressor.SignatureParser;
import jdk.internal.jimage.decompressor.StringSharingDecompressor;
import jdk.tools.jlink.internal.ModulePoolImpl;
import jdk.tools.jlink.internal.ResourcePoolManager.ResourcePoolImpl;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
import jdk.tools.jlink.plugin.ResourcePoolEntry;
import jdk.tools.jlink.internal.ResourcePoolManager;
import jdk.tools.jlink.internal.ResourcePrevisitor;
import jdk.tools.jlink.internal.StringTable;
@ -226,22 +228,22 @@ public class StringSharingPlugin implements Plugin, ResourcePrevisitor {
}
}
public byte[] transform(ModuleEntry resource, ModulePool out,
public byte[] transform(ResourcePoolEntry resource, ResourcePoolBuilder out,
StringTable strings) throws IOException, Exception {
byte[] content = resource.getBytes();
byte[] content = resource.contentBytes();
ClassFile cf;
try (InputStream stream = new ByteArrayInputStream(content)) {
cf = ClassFile.read(stream);
} catch (ConstantPoolException ex) {
throw new IOException("Compressor EX " + ex + " for "
+ resource.getPath() + " content.length " + content.length, ex);
+ resource.path() + " content.length " + content.length, ex);
}
DescriptorsScanner scanner = new DescriptorsScanner(cf);
return optimize(resource, out, strings, scanner.scan(), content);
}
@SuppressWarnings("fallthrough")
private byte[] optimize(ModuleEntry resource, ModulePool resources,
private byte[] optimize(ResourcePoolEntry resource, ResourcePoolBuilder resources,
StringTable strings,
Set<Integer> descriptorIndexes, byte[] content) throws Exception {
DataInputStream stream = new DataInputStream(new ByteArrayInputStream(content));
@ -347,23 +349,25 @@ public class StringSharingPlugin implements Plugin, ResourcePrevisitor {
}
@Override
public void visit(ModulePool in, ModulePool result) {
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder result) {
CompactCPHelper visit = new CompactCPHelper();
in.transformAndCopy((resource) -> {
ModuleEntry res = resource;
if (predicate.test(resource.getPath()) && resource.getPath().endsWith(".class")) {
ResourcePoolEntry res = resource;
if (predicate.test(resource.path()) && resource.path().endsWith(".class")) {
byte[] compressed = null;
try {
compressed = visit.transform(resource, result, ((ModulePoolImpl) in).getStringTable());
compressed = visit.transform(resource, result, ((ResourcePoolImpl)in).getStringTable());
} catch (Exception ex) {
throw new PluginException(ex);
}
res = ModulePoolImpl.newCompressedResource(resource,
res = ResourcePoolManager.newCompressedResource(resource,
ByteBuffer.wrap(compressed), getName(), null,
((ModulePoolImpl) in).getStringTable(), in.getByteOrder());
((ResourcePoolImpl)in).getStringTable(), in.byteOrder());
}
return res;
}, result);
return result.build();
}
@Override
@ -392,11 +396,11 @@ public class StringSharingPlugin implements Plugin, ResourcePrevisitor {
}
@Override
public void previsit(ModulePool resources, StringTable strings) {
public void previsit(ResourcePool resources, StringTable strings) {
CompactCPHelper preVisit = new CompactCPHelper();
resources.entries().forEach(resource -> {
if (resource.getType().equals(ModuleEntry.Type.CLASS_OR_RESOURCE)
&& resource.getPath().endsWith(".class") && predicate.test(resource.getPath())) {
if (resource.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)
&& resource.path().endsWith(".class") && predicate.test(resource.path())) {
try {
preVisit.transform(resource, null, strings);
} catch (Exception ex) {

@ -27,8 +27,9 @@ package jdk.tools.jlink.internal.plugins;
import java.util.function.Predicate;
import jdk.internal.org.objectweb.asm.ClassReader;
import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
import jdk.tools.jlink.plugin.ResourcePoolEntry;
import jdk.tools.jlink.plugin.Plugin;
/**
@ -58,27 +59,29 @@ public final class StripDebugPlugin implements Plugin {
}
@Override
public void visit(ModulePool in, ModulePool out) {
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
//remove *.diz files as well as debug attributes.
in.transformAndCopy((resource) -> {
ModuleEntry res = resource;
if (resource.getType().equals(ModuleEntry.Type.CLASS_OR_RESOURCE)) {
String path = resource.getPath();
ResourcePoolEntry res = resource;
if (resource.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)) {
String path = resource.path();
if (path.endsWith(".class")) {
if (path.endsWith("module-info.class")) {
// XXX. Do we have debug info? Is Asm ready for module-info?
} else {
ClassReader reader = new ClassReader(resource.getBytes());
ClassReader reader = new ClassReader(resource.contentBytes());
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
reader.accept(writer, ClassReader.SKIP_DEBUG);
byte[] content = writer.toByteArray();
res = resource.create(content);
res = resource.copyWithContent(content);
}
}
} else if (predicate.test(res.getPath())) {
} else if (predicate.test(res.path())) {
res = null;
}
return res;
}, out);
return out.build();
}
}

@ -24,8 +24,9 @@
*/
package jdk.tools.jlink.internal.plugins;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
import jdk.tools.jlink.plugin.ResourcePoolEntry;
import jdk.tools.jlink.plugin.Plugin;
/**
@ -47,10 +48,12 @@ public final class StripNativeCommandsPlugin implements Plugin {
}
@Override
public void visit(ModulePool in, ModulePool out) {
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
in.transformAndCopy((file) -> {
return file.getType() == ModuleEntry.Type.NATIVE_CMD ? null : file;
return file.type() == ResourcePoolEntry.Type.NATIVE_CMD ? null : file;
}, out);
return out.build();
}
@Override

@ -51,10 +51,11 @@ import jdk.internal.org.objectweb.asm.Opcodes;
import static jdk.internal.org.objectweb.asm.Opcodes.*;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.internal.plugins.SystemModuleDescriptorPlugin.Builder.*;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
import jdk.tools.jlink.plugin.ResourcePoolEntry;
/**
* Jlink plugin to reconstitute module descriptors for installed modules.
@ -107,7 +108,7 @@ public final class SystemModuleDescriptorPlugin implements Plugin {
@Override
public void visit(ModulePool in, ModulePool out) {
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
if (!enabled) {
throw new PluginException(NAME + " was set");
}
@ -116,30 +117,30 @@ public final class SystemModuleDescriptorPlugin implements Plugin {
// generate the byte code to create ModuleDescriptors
// skip parsing module-info.class and skip name check
in.modules().forEach(module -> {
Optional<ModuleEntry> optData = module.findEntry("module-info.class");
in.moduleView().modules().forEach(module -> {
Optional<ResourcePoolEntry> optData = module.findEntry("module-info.class");
if (! optData.isPresent()) {
// automatic module not supported yet
throw new PluginException("module-info.class not found for " +
module.getName() + " module");
module.name() + " module");
}
ModuleEntry data = optData.get();
assert module.getName().equals(data.getModule());
ResourcePoolEntry data = optData.get();
assert module.name().equals(data.moduleName());
try {
ByteArrayInputStream bain = new ByteArrayInputStream(data.getBytes());
ByteArrayInputStream bain = new ByteArrayInputStream(data.contentBytes());
ModuleDescriptor md = ModuleDescriptor.read(bain);
validateNames(md);
ModuleDescriptorBuilder mbuilder = builder.module(md, module.getAllPackages());
ModuleDescriptorBuilder mbuilder = builder.module(md, module.packages());
int packages = md.exports().size() + md.conceals().size();
if (md.conceals().isEmpty() &&
packages != module.getAllPackages().size()) {
packages != module.packages().size()) {
// add ConcealedPackages attribute if not exist
bain.reset();
ModuleInfoRewriter minfoWriter =
new ModuleInfoRewriter(bain, mbuilder.conceals());
// replace with the overridden version
data = data.create(minfoWriter.getBytes());
data = data.copyWithContent(minfoWriter.getBytes());
}
out.add(data);
} catch (IOException e) {
@ -150,16 +151,18 @@ public final class SystemModuleDescriptorPlugin implements Plugin {
// Generate the new class
ClassWriter cwriter = builder.build();
in.entries().forEach(data -> {
if (data.getPath().endsWith("module-info.class"))
if (data.path().endsWith("module-info.class"))
return;
if (builder.isOverriddenClass(data.getPath())) {
if (builder.isOverriddenClass(data.path())) {
byte[] bytes = cwriter.toByteArray();
ModuleEntry ndata = data.create(bytes);
ResourcePoolEntry ndata = data.copyWithContent(bytes);
out.add(ndata);
} else {
out.add(data);
}
});
return out.build();
}
/*

@ -31,9 +31,11 @@ import java.util.Arrays;
import java.util.Map;
import java.util.function.Predicate;
import java.util.zip.Deflater;
import jdk.tools.jlink.internal.ModulePoolImpl;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.internal.ResourcePoolManager;
import jdk.tools.jlink.internal.ResourcePoolManager.ResourcePoolImpl;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
import jdk.tools.jlink.plugin.ResourcePoolEntry;
import jdk.tools.jlink.plugin.Plugin;
/**
@ -112,18 +114,20 @@ public final class ZipPlugin implements Plugin {
}
@Override
public void visit(ModulePool in, ModulePool out) {
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
in.transformAndCopy((resource) -> {
ModuleEntry res = resource;
if (resource.getType().equals(ModuleEntry.Type.CLASS_OR_RESOURCE)
&& predicate.test(resource.getPath())) {
ResourcePoolEntry res = resource;
if (resource.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)
&& predicate.test(resource.path())) {
byte[] compressed;
compressed = compress(resource.getBytes());
res = ModulePoolImpl.newCompressedResource(resource,
compressed = compress(resource.contentBytes());
res = ResourcePoolManager.newCompressedResource(resource,
ByteBuffer.wrap(compressed), getName(), null,
((ModulePoolImpl) in).getStringTable(), in.getByteOrder());
((ResourcePoolImpl)in).getStringTable(), in.byteOrder());
}
return res;
}, out);
return out.build();
}
}

@ -191,5 +191,5 @@ public interface Plugin {
*
* @throws PluginException
*/
public void visit(ModulePool in, ModulePool out);
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out);
}

@ -31,65 +31,37 @@ import java.util.function.Function;
import java.util.stream.Stream;
/**
* Pool of module data.
* A Pool of Java resources.
*/
public interface ModulePool {
/**
* Is this a read-only ModulePool?
public interface ResourcePool {
/**
* Return the module view of this resource pool.
*
* @return true if this is a read-only configuration.
* @return a module based view of this resource pool.
*/
public boolean isReadOnly();
public ResourcePoolModuleView moduleView();
/**
* Add a ModuleEntry.
* Get all ResourcePoolEntry contained in this ResourcePool instance.
*
* @param data The ModuleEntry to add.
* @return The stream of ResourcePoolEntries.
*/
public void add(ModuleEntry data);
/**
* Retrieves the module for the provided name.
*
* @param name The module name
* @return the module of matching name, if found
*/
public Optional<LinkModule> findModule(String name);
public Stream<ResourcePoolEntry> entries();
/**
* The stream of modules contained in this ModulePool.
*
* @return The stream of modules.
*/
public Stream<? extends LinkModule> modules();
/**
* Return the number of LinkModule count in this ModulePool.
*
* @return the module count.
*/
public int getModuleCount();
/**
* Get all ModuleEntry contained in this ModulePool instance.
*
* @return The stream of LinkModuleEntries.
*/
public Stream<? extends ModuleEntry> entries();
/**
* Return the number of ModuleEntry count in this ModulePool.
* Return the number of ResourcePoolEntry count in this ResourcePool.
*
* @return the entry count.
*/
public int getEntryCount();
public int entryCount();
/**
* Get the ModuleEntry for the passed path.
* Get the ResourcePoolEntry for the passed path.
*
* @param path A data path
* @return A ModuleEntry instance or null if the data is not found
* @return A ResourcePoolEntry instance or null if the data is not found
*/
public Optional<ModuleEntry> findEntry(String path);
public Optional<ResourcePoolEntry> findEntry(String path);
/**
* Get the ModuleEntry for the passed path restricted to supplied context.
@ -98,48 +70,57 @@ public interface ModulePool {
* @param context A context of the search
* @return A ModuleEntry instance or null if the data is not found
*/
public Optional<ModuleEntry> findEntryInContext(String path, ModuleEntry context);
public Optional<ResourcePoolEntry> findEntryInContext(String path, ResourcePoolEntry context);
/**
* Check if the ModulePool contains the given ModuleEntry.
* Check if the ResourcePool contains the given ResourcePoolEntry.
*
* @param data The module data to check existence for.
* @return The module data or null if not found.
*/
public boolean contains(ModuleEntry data);
public boolean contains(ResourcePoolEntry data);
/**
* Check if the ModulePool contains some content at all.
* Check if the ResourcePool contains some content at all.
*
* @return True, no content, false otherwise.
*/
public boolean isEmpty();
/**
* Visit each ModuleEntry in this ModulePool to transform it and copy
* the transformed ModuleEntry to the output ModulePool.
*
* @param transform The function called for each ModuleEntry found in the
* ModulePool. The transform function should return a ModuleEntry
* instance which will be added to the output or it should return null if
* the passed ModuleEntry is to be ignored for the output.
*
* @param output The ModulePool to be filled with Visitor returned
* ModuleEntry.
*/
public void transformAndCopy(Function<ModuleEntry, ModuleEntry> transform, ModulePool output);
/**
* The ByteOrder currently in use when generating the jimage file.
*
* @return The ByteOrder.
*/
public ByteOrder getByteOrder();
public ByteOrder byteOrder();
/**
* Release properties such as OS, CPU name, version etc.
*
* @return the release properties
*/
public Map<String, String> getReleaseProperties();
public Map<String, String> releaseProperties();
/**
* Visit each ResourcePoolEntry in this ResourcePool to transform it and copy
* the transformed ResourcePoolEntry to the output ResourcePoolBuilder.
*
* @param transform The function called for each ResourcePoolEntry found in the
* ResourcePool. The transform function should return a ResourcePoolEntry
* instance which will be added to the output or it should return null if
* the passed ResourcePoolEntry is to be ignored for the output.
*
* @param outBuilder The ResourcePoolBuilder to be filled with Visitor returned
* ResourcePoolEntries.
*/
public default void transformAndCopy(
Function<ResourcePoolEntry, ResourcePoolEntry> transform,
ResourcePoolBuilder outBuilder) {
entries().forEach(resource -> {
ResourcePoolEntry res = transform.apply(resource);
if (res != null) {
outBuilder.add(res);
}
});
}
}

@ -0,0 +1,52 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. 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 jdk.tools.jlink.plugin;
import java.nio.ByteOrder;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Stream;
/**
* Resource pool builder to build a resource pool by incrementally
* adding a set of resources one at a time.
*/
public interface ResourcePoolBuilder {
/**
* Add a ResourcePoolEntry.
*
* @param data The ResourcePoolEntry to add.
*/
public void add(ResourcePoolEntry data);
/**
* Done with adding resource entries. Construct
* a ResourcePool with the added resource entries.
*
* @return a new ResourcePool filled with entries added.
*/
public ResourcePool build();
}

@ -31,13 +31,13 @@ import java.io.OutputStream;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;
import jdk.tools.jlink.internal.ModuleEntryFactory;
import jdk.tools.jlink.internal.ResourcePoolEntryFactory;
/**
* A ModuleEntry is the elementary unit of data inside an image. It is
* A ResourcePoolEntry is the elementary unit of data inside an image. It is
* generally a file. e.g.: a java class file, a resource file, a shared library.
* <br>
* A ModuleEntry is identified by a path of the form:
* A ResourcePoolEntry is identified by a path of the form:
* <ul>
* <li>For jimage content: /{module name}/{package1}/.../{packageN}/{file
* name}</li>
@ -45,7 +45,7 @@ import jdk.tools.jlink.internal.ModuleEntryFactory;
* {@literal bin|conf|native}/{dir1}/.../{dirN}/{file name}</li>
* </ul>
*/
public interface ModuleEntry {
public interface ResourcePoolEntry {
/**
* Type of module data.
@ -64,34 +64,49 @@ public interface ModuleEntry {
NATIVE_LIB,
OTHER
}
/**
* The ModuleEntry module name.
* The module name of this ResourcePoolEntry.
*
* @return The module name.
*/
public String getModule();
public String moduleName();
/**
* The ModuleEntry path.
* The path of this ResourcePoolEntry.
*
* @return The module path.
*/
public String getPath();
public String path();
/**
* The ModuleEntry's type.
* The ResourcePoolEntry's type.
*
* @return The data type.
*/
public Type getType();
public Type type();
/**
* The ModuleEntry content as an array of bytes.
* The ResourcePoolEntry content length.
*
* @return The content length.
*/
public long contentLength();
/**
* The ResourcePoolEntry content as an InputStream.
*
* @return The resource content as an InputStream.
*/
public InputStream content();
/**
* The ResourcePoolEntry content as an array of bytes.
*
* @return An Array of bytes.
*/
public default byte[] getBytes() {
try (InputStream is = stream()) {
public default byte[] contentBytes() {
try (InputStream is = content()) {
return is.readAllBytes();
} catch (IOException ex) {
throw new UncheckedIOException(ex);
@ -99,99 +114,85 @@ public interface ModuleEntry {
}
/**
* The ModuleEntry content length.
*
* @return The length.
*/
public long getLength();
/**
* The ModuleEntry stream.
*
* @return The module data stream.
*/
public InputStream stream();
/**
* Write the content of this ModuleEntry to stream.
* Write the content of this ResourcePoolEntry to an OutputStream.
*
* @param out the output stream
*/
public default void write(OutputStream out) {
try {
out.write(getBytes());
out.write(contentBytes());
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
}
/**
* Create a ModuleEntry with new content but other information
* copied from this ModuleEntry.
* Create a ResourcePoolEntry with new content but other information
* copied from this ResourcePoolEntry.
*
* @param content The new resource content.
* @return A new ModuleEntry.
* @return A new ResourcePoolEntry.
*/
public default ModuleEntry create(byte[] content) {
return ModuleEntryFactory.create(this, content);
public default ResourcePoolEntry copyWithContent(byte[] content) {
return ResourcePoolEntryFactory.create(this, content);
}
/**
* Create a ModuleEntry with new content but other information
* copied from this ModuleEntry.
* Create a ResourcePoolEntry with new content but other information
* copied from this ResourcePoolEntry.
*
* @param file The new resource content.
* @return A new ModuleEntry.
* @return A new ResourcePoolEntry.
*/
public default ModuleEntry create(Path file) {
return ModuleEntryFactory.create(this, file);
public default ResourcePoolEntry copyWithContent(Path file) {
return ResourcePoolEntryFactory.create(this, file);
}
/**
* Create a ModuleEntry for a resource of the given type.
* Create a ResourcePoolEntry for a resource of the given type.
*
* @param path The resource path.
* @param type The ModuleEntry type.
* @param type The ResourcePoolEntry type.
* @param content The resource content.
* @return A new ModuleEntry.
* @return A new ResourcePoolEntry.
*/
public static ModuleEntry create(String path,
ModuleEntry.Type type, byte[] content) {
return ModuleEntryFactory.create(path, type, content);
public static ResourcePoolEntry create(String path,
ResourcePoolEntry.Type type, byte[] content) {
return ResourcePoolEntryFactory.create(path, type, content);
}
/**
* Create a ModuleEntry for a resource of type {@link Type#CLASS_OR_RESOURCE}.
* Create a ResourcePoolEntry for a resource of type {@link Type#CLASS_OR_RESOURCE}.
*
* @param path The resource path.
* @param content The resource content.
* @return A new ModuleEntry.
* @return A new ResourcePoolEntry.
*/
public static ModuleEntry create(String path, byte[] content) {
public static ResourcePoolEntry create(String path, byte[] content) {
return create(path, Type.CLASS_OR_RESOURCE, content);
}
/**
* Create a ModuleEntry for a resource of the given type.
* Create a ResourcePoolEntry for a resource of the given type.
*
* @param path The resource path.
* @param type The ModuleEntry type.
* @param type The ResourcePoolEntry type.
* @param file The resource file.
* @return A new ModuleEntry.
* @return A new ResourcePoolEntry.
*/
public static ModuleEntry create(String path,
ModuleEntry.Type type, Path file) {
return ModuleEntryFactory.create(path, type, file);
public static ResourcePoolEntry create(String path,
ResourcePoolEntry.Type type, Path file) {
return ResourcePoolEntryFactory.create(path, type, file);
}
/**
* Create a ModuleEntry for a resource of type {@link Type#CLASS_OR_RESOURCE}.
* Create a ResourcePoolEntry for a resource of type {@link Type#CLASS_OR_RESOURCE}.
*
* @param path The resource path.
* @param file The resource file.
* @return A new ModuleEntry.
* @return A new ResourcePoolEntry.
*/
public static ModuleEntry create(String path, Path file) {
public static ResourcePoolEntry create(String path, Path file) {
return create(path, Type.CLASS_OR_RESOURCE, file);
}
}

@ -30,58 +30,50 @@ import java.util.Set;
import java.util.stream.Stream;
/**
* Link-time representation of a Java module.
* Link-time representation of a module.
*/
public interface LinkModule {
public interface ResourcePoolModule {
/**
* The module name.
*
* @return The name.
* @return The module name.
*/
public String getName();
public String name();
/**
* Retrieves a LinkModuleEntry from the given path (e.g:
* Retrieves a ResourcePoolEntry from the given path (e.g:
* /mymodule/com.foo.bar/MyClass.class)
*
* @param path The piece of data path.
* @return A LinkModuleEntry of the given path, if found.
* @return A ResourcePoolEntry of the given path, if found.
*/
public Optional<ModuleEntry> findEntry(String path);
public Optional<ResourcePoolEntry> findEntry(String path);
/**
* The module descriptor of this module.
*
* @return The module descriptor.
*/
public ModuleDescriptor getDescriptor();
/**
* Add a LinkModuleEntry to this module.
*
* @param data The LinkModuleEntry to add.
*/
public void add(ModuleEntry data);
public ModuleDescriptor descriptor();
/**
* Retrieves all the packages located in this module.
*
* @return The set of packages.
*/
public Set<String> getAllPackages();
public Set<String> packages();
/**
* Retrieves the stream of LinkModuleEntry.
* Retrieves the stream of ResourcePoolEntry.
*
* @return The LinkModuleEntry stream.
* @return The ResourcePoolEntry stream.
*/
public Stream<? extends ModuleEntry> entries();
public Stream<ResourcePoolEntry> entries();
/**
* Return the number of LinkModuleEntry count in this LinkModule.
* Return the number of ResourcePoolEntry count in this ResourcePoolModule.
*
* @return the entry count.
*/
public int getEntryCount();
public int entryCount();
}

@ -0,0 +1,67 @@
/*
* Copyright (c) 2016, 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 jdk.tools.jlink.plugin;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Stream;
/**
* The module view of a ResourcePool.
*/
public interface ResourcePoolModuleView {
/**
* Find the module, if any, of the given name.
*
* @param name name of the module
* @return Optional containing the module of the given name.
*/
public Optional<ResourcePoolModule> findModule(String name);
/**
* Find the module, if any, of the given ResourcePoolEntry
*
* @param entry The ResourcePoolEntry whose module is looked up.
* @return Optional containing the module of the given ResourcePoolEntry
*/
public default Optional<ResourcePoolModule> findModule(ResourcePoolEntry entry) {
String name = Objects.requireNonNull(entry).moduleName();
return name != null? findModule(name) : Optional.empty();
}
/**
* The stream of modules contained in this ResourcePool.
*
* @return The stream of modules.
*/
public Stream<ResourcePoolModule> modules();
/**
* Return the number of ResourcePoolModule count in this ResourcePool.
*
* @return the module count.
*/
public int moduleCount();
}

@ -22,7 +22,7 @@
*/
/* @test
* @bug 4313887 8129632 8129633
* @bug 4313887 8129632 8129633 8162624
* @summary Unit test for probeContentType method
* @library ../..
* @build Basic SimpleFileTypeDetector

@ -407,6 +407,127 @@ public class TCKDateTimeFormatterBuilder {
{"+HH:mm:ss", 2, 0, 45, "+02:00:45"},
{"+HH:mm:ss", 2, 30, 45, "+02:30:45"},
{"+H", 2, 0, 0, "+2"},
{"+H", -2, 0, 0, "-2"},
{"+H", 2, 30, 0, "+2"},
{"+H", 2, 0, 45, "+2"},
{"+H", 2, 30, 45, "+2"},
{"+H", 12, 0, 0, "+12"},
{"+H", -12, 0, 0, "-12"},
{"+H", 12, 30, 0, "+12"},
{"+H", 12, 0, 45, "+12"},
{"+H", 12, 30, 45, "+12"},
{"+Hmm", 2, 0, 0, "+2"},
{"+Hmm", -2, 0, 0, "-2"},
{"+Hmm", 2, 30, 0, "+230"},
{"+Hmm", 2, 0, 45, "+2"},
{"+Hmm", 2, 30, 45, "+230"},
{"+Hmm", 12, 0, 0, "+12"},
{"+Hmm", -12, 0, 0, "-12"},
{"+Hmm", 12, 30, 0, "+1230"},
{"+Hmm", 12, 0, 45, "+12"},
{"+Hmm", 12, 30, 45, "+1230"},
{"+H:mm", 2, 0, 0, "+2"},
{"+H:mm", -2, 0, 0, "-2"},
{"+H:mm", 2, 30, 0, "+2:30"},
{"+H:mm", 2, 0, 45, "+2"},
{"+H:mm", 2, 30, 45, "+2:30"},
{"+H:mm", 12, 0, 0, "+12"},
{"+H:mm", -12, 0, 0, "-12"},
{"+H:mm", 12, 30, 0, "+12:30"},
{"+H:mm", 12, 0, 45, "+12"},
{"+H:mm", 12, 30, 45, "+12:30"},
{"+HMM", 2, 0, 0, "+200"},
{"+HMM", -2, 0, 0, "-200"},
{"+HMM", 2, 30, 0, "+230"},
{"+HMM", 2, 0, 45, "+200"},
{"+HMM", 2, 30, 45, "+230"},
{"+HMM", 12, 0, 0, "+1200"},
{"+HMM", -12, 0, 0, "-1200"},
{"+HMM", 12, 30, 0, "+1230"},
{"+HMM", 12, 0, 45, "+1200"},
{"+HMM", 12, 30, 45, "+1230"},
{"+H:MM", 2, 0, 0, "+2:00"},
{"+H:MM", -2, 0, 0, "-2:00"},
{"+H:MM", 2, 30, 0, "+2:30"},
{"+H:MM", 2, 0, 45, "+2:00"},
{"+H:MM", 2, 30, 45, "+2:30"},
{"+H:MM", 12, 0, 0, "+12:00"},
{"+H:MM", -12, 0, 0, "-12:00"},
{"+H:MM", 12, 30, 0, "+12:30"},
{"+H:MM", 12, 0, 45, "+12:00"},
{"+H:MM", 12, 30, 45, "+12:30"},
{"+HMMss", 2, 0, 0, "+200"},
{"+HMMss", -2, 0, 0, "-200"},
{"+HMMss", 2, 30, 0, "+230"},
{"+HMMss", 2, 0, 45, "+20045"},
{"+HMMss", 2, 30, 45, "+23045"},
{"+HMMss", 12, 0, 0, "+1200"},
{"+HMMss", -12, 0, 0, "-1200"},
{"+HMMss", 12, 30, 0, "+1230"},
{"+HMMss", 12, 0, 45, "+120045"},
{"+HMMss", 12, 30, 45, "+123045"},
{"+H:MM:ss", 2, 0, 0, "+2:00"},
{"+H:MM:ss", -2, 0, 0, "-2:00"},
{"+H:MM:ss", 2, 30, 0, "+2:30"},
{"+H:MM:ss", 2, 0, 45, "+2:00:45"},
{"+H:MM:ss", 2, 30, 45, "+2:30:45"},
{"+H:MM:ss", 12, 0, 0, "+12:00"},
{"+H:MM:ss", -12, 0, 0, "-12:00"},
{"+H:MM:ss", 12, 30, 0, "+12:30"},
{"+H:MM:ss", 12, 0, 45, "+12:00:45"},
{"+H:MM:ss", 12, 30, 45, "+12:30:45"},
{"+HMMSS", 2, 0, 0, "+20000"},
{"+HMMSS", -2, 0, 0, "-20000"},
{"+HMMSS", 2, 30, 0, "+23000"},
{"+HMMSS", 2, 0, 45, "+20045"},
{"+HMMSS", 2, 30, 45, "+23045"},
{"+HMMSS", 12, 0, 0, "+120000"},
{"+HMMSS", -12, 0, 0, "-120000"},
{"+HMMSS", 12, 30, 0, "+123000"},
{"+HMMSS", 12, 0, 45, "+120045"},
{"+HMMSS", 12, 30, 45, "+123045"},
{"+H:MM:SS", 2, 0, 0, "+2:00:00"},
{"+H:MM:SS", -2, 0, 0, "-2:00:00"},
{"+H:MM:SS", 2, 30, 0, "+2:30:00"},
{"+H:MM:SS", 2, 0, 45, "+2:00:45"},
{"+H:MM:SS", 2, 30, 45, "+2:30:45"},
{"+H:MM:SS", 12, 0, 0, "+12:00:00"},
{"+H:MM:SS", -12, 0, 0, "-12:00:00"},
{"+H:MM:SS", 12, 30, 0, "+12:30:00"},
{"+H:MM:SS", 12, 0, 45, "+12:00:45"},
{"+H:MM:SS", 12, 30, 45, "+12:30:45"},
{"+Hmmss", 2, 0, 0, "+2"},
{"+Hmmss", -2, 0, 0, "-2"},
{"+Hmmss", 2, 30, 0, "+230"},
{"+Hmmss", 2, 0, 45, "+20045"},
{"+Hmmss", 2, 30, 45, "+23045"},
{"+Hmmss", 12, 0, 0, "+12"},
{"+Hmmss", -12, 0, 0, "-12"},
{"+Hmmss", 12, 30, 0, "+1230"},
{"+Hmmss", 12, 0, 45, "+120045"},
{"+Hmmss", 12, 30, 45, "+123045"},
{"+H:mm:ss", 2, 0, 0, "+2"},
{"+H:mm:ss", -2, 0, 0, "-2"},
{"+H:mm:ss", 2, 30, 0, "+2:30"},
{"+H:mm:ss", 2, 0, 45, "+2:00:45"},
{"+H:mm:ss", 2, 30, 45, "+2:30:45"},
{"+H:mm:ss", 12, 0, 0, "+12"},
{"+H:mm:ss", -12, 0, 0, "-12"},
{"+H:mm:ss", 12, 30, 0, "+12:30"},
{"+H:mm:ss", 12, 0, 45, "+12:00:45"},
{"+H:mm:ss", 12, 30, 45, "+12:30:45"},
};
}
@ -437,8 +558,6 @@ public class TCKDateTimeFormatterBuilder {
{"HH:MM:ss"},
{"HHMMSS"},
{"HH:MM:SS"},
{"+H"},
{"+HMM"},
{"+HHM"},
{"+A"},
};
@ -1188,6 +1307,146 @@ public class TCKDateTimeFormatterBuilder {
{"+HH:mm:ss", "+01", 3600},
{"+HH:mm:ss", "+01:01", 3660},
{"+HH:mm:ss", "+01:01:01", 3661},
{"+H", "+1", 3600},
{"+H", "+101", 3660},
{"+H", "+10101", 3661},
{"+H", "+1:01", 3660},
{"+H", "+1:01:01", 3661},
{"+H", "+01", 3600},
{"+H", "+0101", 3660},
{"+H", "+010101", 3661},
{"+H", "+01:01", 3660},
{"+H", "+01:01:01", 3661},
{"+Hmm", "+1", 3600},
{"+Hmm", "+101", 3660},
{"+Hmm", "+10101", 3661},
{"+Hmm", "+01", 3600},
{"+Hmm", "+0101", 3660},
{"+Hmm", "+010101", 3661},
{"+H:mm", "+1", 3600},
{"+H:mm", "+1:01", 3660},
{"+H:mm", "+1:01:01", 3661},
{"+H:mm", "+01", 3600},
{"+H:mm", "+01:01", 3660},
{"+H:mm", "+01:01:01", 3661},
{"+HMM", "+1", 3600},
{"+HMM", "+101", 3660},
{"+HMM", "+10101", 3661},
{"+HMM", "+01", 3600},
{"+HMM", "+0101", 3660},
{"+HMM", "+010101", 3661},
{"+H:MM", "+1", 3600},
{"+H:MM", "+1:01", 3660},
{"+H:MM", "+1:01:01", 3661},
{"+H:MM", "+01", 3600},
{"+H:MM", "+01:01", 3660},
{"+H:MM", "+01:01:01", 3661},
{"+HMMss", "+1", 3600},
{"+HMMss", "+101", 3660},
{"+HMMss", "+10101", 3661},
{"+HMMss", "+01", 3600},
{"+HMMss", "+0101", 3660},
{"+HMMss", "+010101", 3661},
{"+H:MM:ss", "+1", 3600},
{"+H:MM:ss", "+1:01", 3660},
{"+H:MM:ss", "+1:01:01", 3661},
{"+H:MM:ss", "+01", 3600},
{"+H:MM:ss", "+01:01", 3660},
{"+H:MM:ss", "+01:01:01", 3661},
{"+HMMSS", "+1", 3600},
{"+HMMSS", "+101", 3660},
{"+HMMSS", "+10101", 3661},
{"+HMMSS", "+01", 3600},
{"+HMMSS", "+0101", 3660},
{"+HMMSS", "+010101", 3661},
{"+H:MM:SS", "+1", 3600},
{"+H:MM:SS", "+1:01", 3660},
{"+H:MM:SS", "+1:01:01", 3661},
{"+H:MM:SS", "+01", 3600},
{"+H:MM:SS", "+01:01", 3660},
{"+H:MM:SS", "+01:01:01", 3661},
{"+Hmmss", "+1", 3600},
{"+Hmmss", "+101", 3660},
{"+Hmmss", "+10101", 3661},
{"+Hmmss", "+01", 3600},
{"+Hmmss", "+0101", 3660},
{"+Hmmss", "+010101", 3661},
{"+H:mm:ss", "+1", 3600},
{"+H:mm:ss", "+1:01", 3660},
{"+H:mm:ss", "+1:01:01", 3661},
{"+H:mm:ss", "+01", 3600},
{"+H:mm:ss", "+01:01", 3660},
{"+H:mm:ss", "+01:01:01", 3661},
};
}
@DataProvider(name="strictDoubleDigitHourOffsetParseData")
Object[][] data_strictDoubleDigitHour_offset_parse() {
return new Object[][] {
{"+HH", "+01", 3600},
{"+HHmm", "+01", 3600},
{"+HHmm", "+0101", 3660},
{"+HH:mm", "+01", 3600},
{"+HH:mm", "+01:01", 3660},
{"+HHMM", "+0101", 3660},
{"+HH:MM", "+01:01", 3660},
{"+HHMMss", "+0101", 3660},
{"+HHMMss", "+010101", 3661},
{"+HH:MM:ss", "+01:01", 3660},
{"+HH:MM:ss", "+01:01:01", 3661},
{"+HHMMSS", "+010101", 3661},
{"+HH:MM:SS", "+01:01:01", 3661},
{"+HHmmss", "+01", 3600},
{"+HHmmss", "+0101", 3660},
{"+HHmmss", "+010101", 3661},
{"+HH:mm:ss", "+01", 3600},
{"+HH:mm:ss", "+01:01", 3660},
{"+HH:mm:ss", "+01:01:01", 3661},
};
}
@DataProvider(name="strictSingleDigitHourOffsetParseData")
Object[][] data_strictSingleDigitHour_offset_parse() {
return new Object[][] {
{"+H", "+01", 3600},
{"+H", "+1", 3600},
{"+Hmm", "+01", 3600},
{"+Hmm", "+0101", 3660},
{"+Hmm", "+1", 3600},
{"+Hmm", "+101", 3660},
{"+H:mm", "+01", 3600},
{"+H:mm", "+01:01", 3660},
{"+H:mm", "+1", 3600},
{"+H:mm", "+1:01", 3660},
{"+HMM", "+0101", 3660},
{"+HMM", "+101", 3660},
{"+H:MM", "+01:01", 3660},
{"+H:MM", "+1:01", 3660},
{"+HMMss", "+0101", 3660},
{"+HMMss", "+010101", 3661},
{"+HMMss", "+101", 3660},
{"+HMMss", "+10101", 3661},
{"+H:MM:ss", "+01:01", 3660},
{"+H:MM:ss", "+01:01:01", 3661},
{"+H:MM:ss", "+1:01", 3660},
{"+H:MM:ss", "+1:01:01", 3661},
{"+HMMSS", "+010101", 3661},
{"+HMMSS", "+10101", 3661},
{"+H:MM:SS", "+01:01:01", 3661},
{"+H:MM:SS", "+1:01:01", 3661},
{"+Hmmss", "+01", 3600},
{"+Hmmss", "+0101", 3660},
{"+Hmmss", "+010101", 3661},
{"+Hmmss", "+1", 3600},
{"+Hmmss", "+101", 3660},
{"+Hmmss", "+10101", 3661},
{"+H:mm:ss", "+01", 3600},
{"+H:mm:ss", "+01:01", 3660},
{"+H:mm:ss", "+01:01:01", 3661},
{"+H:mm:ss", "+1", 3600},
{"+H:mm:ss", "+1:01", 3660},
{"+H:mm:ss", "+1:01:01", 3661},
};
}
@ -1203,22 +1462,226 @@ public class TCKDateTimeFormatterBuilder {
3600);
}
@Test(dataProvider="strictDoubleDigitHourOffsetParseData")
public void test_strictDoubleDigitHour_offset_parse_1(String pattern, String offset, int offsetSeconds) {
assertEquals(new DateTimeFormatterBuilder().appendOffset(pattern, "Z").toFormatter()
.parse(offset).get(OFFSET_SECONDS), offsetSeconds);
}
@Test(dataProvider="strictDoubleDigitHourOffsetParseData")
public void test_strictDoubleDigitHour_offset_parse_2(String pattern, String offset, int offsetSeconds) {
assertEquals(new DateTimeFormatterBuilder().appendOffset(pattern, "Z")
.appendLiteral("text").toFormatter().parse(offset + "text").get(OFFSET_SECONDS), offsetSeconds);
}
@Test(dataProvider="strictSingleDigitHourOffsetParseData")
public void test_strictSingleDigitHour_offset_parse_1(String pattern, String offset, int offsetSeconds) {
assertEquals(new DateTimeFormatterBuilder().appendOffset(pattern, "Z").toFormatter()
.parse(offset).get(OFFSET_SECONDS), offsetSeconds);
}
@Test(dataProvider="strictSingleDigitHourOffsetParseData")
public void test_strictSingleDigitHour_offset_parse_2(String pattern, String offset, int offsetSeconds) {
assertEquals(new DateTimeFormatterBuilder().appendOffset(pattern, "Z")
.appendLiteral("text").toFormatter().parse(offset + "text").get(OFFSET_SECONDS), offsetSeconds);
}
@DataProvider(name="strictOffsetAdjacentParseValidPatternData")
Object[][] data_strict_offset_adjacentParse_validPattern() {
return new Object[][] {
{"+HH", "+01", 3600},
{"+HHmm", "+0101", 3660},
{"+HH:mm", "+01", 3600},
{"+HH:mm", "+01:01", 3660},
{"+HHMM", "+0101", 3660},
{"+HH:MM", "+01:01", 3660},
{"+HHMMss", "+010101", 3661},
{"+HH:MM:ss", "+01:01", 3660},
{"+HH:MM:ss", "+01:01:01", 3661},
{"+HHMMSS", "+010101", 3661},
{"+HH:MM:SS", "+01:01:01", 3661},
{"+HHmmss", "+010101", 3661},
{"+HH:mm:ss", "+01", 3600},
{"+HH:mm:ss", "+01:01", 3660},
{"+HH:mm:ss", "+01:01:01", 3661},
{"+H", "+01", 3600},
{"+Hmm", "+0101", 3660},
{"+H:mm", "+01", 3600},
{"+H:mm", "+01:01", 3660},
{"+H:mm", "+1:01", 3660},
{"+HMM", "+0101", 3660},
{"+H:MM", "+01:01", 3660},
{"+H:MM", "+1:01", 3660},
{"+HMMss", "+010101", 3661},
{"+H:MM:ss", "+01:01", 3660},
{"+H:MM:ss", "+01:01:01", 3661},
{"+H:MM:ss", "+1:01", 3660},
{"+H:MM:ss", "+1:01:01", 3661},
{"+HMMSS", "+010101", 3661},
{"+H:MM:SS", "+01:01:01", 3661},
{"+H:MM:SS", "+1:01:01", 3661},
{"+Hmmss", "+010101", 3661},
{"+H:mm:ss", "+01", 3600},
{"+H:mm:ss", "+01:01", 3660},
{"+H:mm:ss", "+01:01:01", 3661},
{"+H:mm:ss", "+1:01", 3660},
{"+H:mm:ss", "+1:01:01", 3661},
};
}
@Test(dataProvider="strictOffsetAdjacentParseValidPatternData")
public void test_strict_offset_adjacentValidPattern_parse(String pattern, String offset, int offsetSeconds) {
TemporalAccessor tmp = new DateTimeFormatterBuilder().appendOffset(pattern, "Z")
.appendValue(HOUR_OF_DAY, 2).toFormatter().parse(offset + "12");
assertEquals(tmp.get(OFFSET_SECONDS), offsetSeconds);
assertEquals(tmp.get(HOUR_OF_DAY), 12);
}
@DataProvider(name="strictOffsetAdjacentParseInvalidPatternData")
Object[][] data_strict_offset_adjacentParse_invalidPattern() {
return new Object[][] {
{"+HHmm", "+01", 3600},
{"+HHMMss", "+0101", 3660},
{"+HHmmss", "+01", 3600},
{"+HHmmss", "+0101", 3660},
{"+H", "+1", 3600},
{"+Hmm", "+01", 3600},
{"+H:mm", "+1", 3600},
{"+Hmm", "+1", 3600},
{"+Hmm", "+101", 3660},
{"+HMM", "+101", 3660},
{"+HMMss", "+0101", 3660},
{"+HMMss", "+101", 3660},
{"+HMMss", "+10101", 3661},
{"+HMMSS", "+10101", 3661},
{"+Hmmss", "+01", 3600},
{"+Hmmss", "+0101", 3660},
{"+Hmmss", "+1", 3600},
{"+Hmmss", "+101", 3660},
{"+Hmmss", "+10101", 3661},
{"+H:mm:ss", "+1", 3600},
};
}
@Test(dataProvider="strictOffsetAdjacentParseInvalidPatternData", expectedExceptions=DateTimeParseException.class)
public void test_strict_offset_adjacentInvalidPattern_parse(String pattern, String offset, int offsetSeconds) {
new DateTimeFormatterBuilder().appendOffset(pattern, "Z").appendValue(HOUR_OF_DAY, 2)
.toFormatter().parse(offset + "12");
}
@DataProvider(name="lenientOffsetAdjacentParseValidPatternData")
Object[][] data_lenient_offset_adjacentParse_validPattern() {
return new Object[][] {
{"+HH:mm", "+01", 3600},
{"+HH:mm", "+01:01", 3660},
{"+HH:MM", "+01:01", 3660},
{"+HH:MM:ss", "+01:01", 3660},
{"+HH:MM:ss", "+01:01:01", 3661},
{"+HHMMSS", "+010101", 3661},
{"+HH:MM:SS", "+01:01:01", 3661},
{"+HHmmss", "+010101", 3661},
{"+HH:mm:ss", "+01", 3600},
{"+HH:mm:ss", "+01:01", 3660},
{"+HH:mm:ss", "+01:01:01", 3661},
{"+H:mm", "+01", 3600},
{"+H:mm", "+01:01", 3660},
{"+H:mm", "+1:01", 3660},
{"+H:MM", "+01:01", 3660},
{"+H:MM", "+1:01", 3660},
{"+HMMss", "+010101", 3661},
{"+H:MM:ss", "+01:01", 3660},
{"+H:MM:ss", "+01:01:01", 3661},
{"+H:MM:ss", "+1:01", 3660},
{"+H:MM:ss", "+1:01:01", 3661},
{"+HMMSS", "+010101", 3661},
{"+H:MM:SS", "+01:01:01", 3661},
{"+H:MM:SS", "+1:01:01", 3661},
{"+Hmmss", "+010101", 3661},
{"+H:mm:ss", "+01", 3600},
{"+H:mm:ss", "+01:01", 3660},
{"+H:mm:ss", "+01:01:01", 3661},
{"+H:mm:ss", "+1:01", 3660},
{"+H:mm:ss", "+1:01:01", 3661},
};
}
@Test(dataProvider="lenientOffsetAdjacentParseValidPatternData")
public void test_lenient_offset_adjacentValidPattern_parse(String pattern, String offset, int offsetSeconds) {
TemporalAccessor tmp = new DateTimeFormatterBuilder().parseLenient()
.appendOffset(pattern, "Z").appendValue(HOUR_OF_DAY, 2).toFormatter().parse(offset + "12");
assertEquals(tmp.get(OFFSET_SECONDS), offsetSeconds);
assertEquals(tmp.get(HOUR_OF_DAY), 12);
}
@Test
public void test_lenient_offset_adjacentValidPattern_parse1() {
TemporalAccessor tmp = new DateTimeFormatterBuilder().parseLenient()
.appendOffset("+HMMSS", "Z").appendValue(HOUR_OF_DAY, 2).toFormatter().parse("+10101" + "12");
//Equivalent to +101011. In lenient mode, offset will parse upto 6 digit if possible.
//It will take 1 digit from HOUR_OF_DAY.
assertEquals(tmp.get(OFFSET_SECONDS), 36611);
assertEquals(tmp.get(HOUR_OF_DAY), 2);
}
@DataProvider(name="lenientOffsetAdjacentParseInvalidPatternData")
Object[][] data_lenient_offset_adjacentParse_invalidPattern() {
return new Object[][] {
{"+HH", "+01", 3600},
{"+HHmm", "+0101", 3660},
{"+HHMM", "+0101", 3660},
{"+H", "+01", 3600},
{"+Hmm", "+0101", 3660},
{"+HMM", "+0101", 3660},
};
}
@Test(dataProvider="lenientOffsetAdjacentParseInvalidPatternData", expectedExceptions=DateTimeParseException.class)
public void test_lenient_offset_adjacentInvalidPattern_parse(String pattern, String offset, int offsetSeconds) {
new DateTimeFormatterBuilder().parseLenient().appendOffset(pattern, "Z")
.appendValue(HOUR_OF_DAY, 2).toFormatter().parse(offset + "12");
}
@DataProvider(name="badValues")
Object[][] data_badOffsetValues() {
return new Object[][] {
{"+HH", "+24"},
{"+HHMM", "-1361"},
{"+HH:MM:ss", "+13:12:66"},
{"+HH:MM:SS", "+24:60:60"},
{"+HHMMSS", "369999"},
{"+H:MM", "+28:12"},
};
}
@Test(dataProvider="badValues", expectedExceptions=DateTimeParseException.class)
public void test_badOffset_parse(String pattern, String offset) {
new DateTimeFormatterBuilder().appendOffset(pattern, "Z").toFormatter().parse(offset);
}
@Test(expectedExceptions=DateTimeParseException.class)
public void test_strict_appendOffsetId() {
assertEquals(new DateTimeFormatterBuilder().appendOffsetId().toFormatter().parse("+01").get(OFFSET_SECONDS),
3600);
new DateTimeFormatterBuilder().appendOffsetId().toFormatter().parse("+01");
}
@Test(expectedExceptions=DateTimeParseException.class)
public void test_strict_appendOffset_1() {
assertEquals(new DateTimeFormatterBuilder().appendOffset("+HH:MM:ss", "Z").toFormatter().parse("+01").get(OFFSET_SECONDS),
3600);
new DateTimeFormatterBuilder().appendOffset("+HH:MM:ss", "Z").toFormatter().parse("+01");
}
@Test(expectedExceptions=DateTimeParseException.class)
public void test_strict_appendOffset_2() {
assertEquals(new DateTimeFormatterBuilder().appendOffset("+HHMMss", "Z").toFormatter().parse("+01").get(OFFSET_SECONDS),
3600);
new DateTimeFormatterBuilder().appendOffset("+HHMMss", "Z").toFormatter().parse("+01");
}
@Test(expectedExceptions=DateTimeParseException.class)
public void test_strict_appendOffset_3() {
new DateTimeFormatterBuilder().appendOffset("+H:MM:ss", "Z").toFormatter().parse("+1");
}
@Test(expectedExceptions=DateTimeParseException.class)
public void test_strict_appendOffset_4() {
new DateTimeFormatterBuilder().appendOffset("+HMMss", "Z").toFormatter().parse("+1");
}
@Test

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2016, 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
@ -93,6 +93,14 @@ public class TCKOffsetPrinterParser {
private static final ZoneOffset OFFSET_M000045 = ZoneOffset.ofHoursMinutesSeconds(0, 0, -45);
private static final LocalDateTime DT_2012_06_30_12_30_40 = LocalDateTime.of(2012, 6, 30, 12, 30, 40);
private static final ZoneOffset OFFSET_P1100 = ZoneOffset.ofHours(11);
private static final ZoneOffset OFFSET_P1123 = ZoneOffset.ofHoursMinutes(11, 23);
private static final ZoneOffset OFFSET_P1023 = ZoneOffset.ofHoursMinutes(10, 23);
private static final ZoneOffset OFFSET_P112345 = ZoneOffset.ofHoursMinutesSeconds(11, 23, 45);
private static final ZoneOffset OFFSET_P100045 = ZoneOffset.ofHoursMinutesSeconds(10, 0, 45);
private static final ZoneOffset OFFSET_M1100 = ZoneOffset.ofHours(-11);
private static final ZoneOffset OFFSET_M1123 = ZoneOffset.ofHoursMinutes(-11, -23);
private static final ZoneOffset OFFSET_M112345 = ZoneOffset.ofHoursMinutesSeconds(-11, -23, -45);
private DateTimeFormatterBuilder builder;
@BeforeMethod
@ -223,6 +231,212 @@ public class TCKOffsetPrinterParser {
{"+HHmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_M0023, "-0023"},
{"+HHmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_M012345, "-012345"},
{"+HHmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_M000045, "-000045"},
{"+H", "Z", DT_2012_06_30_12_30_40, OFFSET_UTC, "Z"},
{"+H", "Z", DT_2012_06_30_12_30_40, OFFSET_P0100, "+1"},
{"+H", "Z", DT_2012_06_30_12_30_40, OFFSET_P0123, "+1"},
{"+H", "Z", DT_2012_06_30_12_30_40, OFFSET_P0023, "Z"},
{"+H", "Z", DT_2012_06_30_12_30_40, OFFSET_P012345, "+1"},
{"+H", "Z", DT_2012_06_30_12_30_40, OFFSET_P000045, "Z"},
{"+H", "Z", DT_2012_06_30_12_30_40, OFFSET_M0100, "-1"},
{"+H", "Z", DT_2012_06_30_12_30_40, OFFSET_M0123, "-1"},
{"+H", "Z", DT_2012_06_30_12_30_40, OFFSET_M0023, "Z"},
{"+H", "Z", DT_2012_06_30_12_30_40, OFFSET_M012345, "-1"},
{"+H", "Z", DT_2012_06_30_12_30_40, OFFSET_M000045, "Z"},
{"+Hmm", "Z", DT_2012_06_30_12_30_40, OFFSET_UTC, "Z"},
{"+Hmm", "Z", DT_2012_06_30_12_30_40, OFFSET_P0100, "+1"},
{"+Hmm", "Z", DT_2012_06_30_12_30_40, OFFSET_P0123, "+123"},
{"+Hmm", "Z", DT_2012_06_30_12_30_40, OFFSET_P0023, "+023"},
{"+Hmm", "Z", DT_2012_06_30_12_30_40, OFFSET_P012345, "+123"},
{"+Hmm", "Z", DT_2012_06_30_12_30_40, OFFSET_P000045, "Z"},
{"+Hmm", "Z", DT_2012_06_30_12_30_40, OFFSET_M0100, "-1"},
{"+Hmm", "Z", DT_2012_06_30_12_30_40, OFFSET_M0123, "-123"},
{"+Hmm", "Z", DT_2012_06_30_12_30_40, OFFSET_M0023, "-023"},
{"+Hmm", "Z", DT_2012_06_30_12_30_40, OFFSET_M012345, "-123"},
{"+Hmm", "Z", DT_2012_06_30_12_30_40, OFFSET_M000045, "Z"},
{"+HMM", "Z", DT_2012_06_30_12_30_40, OFFSET_UTC, "Z"},
{"+HMM", "Z", DT_2012_06_30_12_30_40, OFFSET_P0100, "+100"},
{"+HMM", "Z", DT_2012_06_30_12_30_40, OFFSET_P0123, "+123"},
{"+HMM", "Z", DT_2012_06_30_12_30_40, OFFSET_P0023, "+023"},
{"+HMM", "Z", DT_2012_06_30_12_30_40, OFFSET_P012345, "+123"},
{"+HMM", "Z", DT_2012_06_30_12_30_40, OFFSET_P000045, "Z"},
{"+HMM", "Z", DT_2012_06_30_12_30_40, OFFSET_M0100, "-100"},
{"+HMM", "Z", DT_2012_06_30_12_30_40, OFFSET_M0123, "-123"},
{"+HMM", "Z", DT_2012_06_30_12_30_40, OFFSET_M0023, "-023"},
{"+HMM", "Z", DT_2012_06_30_12_30_40, OFFSET_M012345, "-123"},
{"+HMM", "Z", DT_2012_06_30_12_30_40, OFFSET_M000045, "Z"},
{"+H:MM", "Z", DT_2012_06_30_12_30_40, OFFSET_UTC, "Z"},
{"+H:MM", "Z", DT_2012_06_30_12_30_40, OFFSET_P0100, "+1:00"},
{"+H:MM", "Z", DT_2012_06_30_12_30_40, OFFSET_P0123, "+1:23"},
{"+H:MM", "Z", DT_2012_06_30_12_30_40, OFFSET_P0023, "+0:23"},
{"+H:MM", "Z", DT_2012_06_30_12_30_40, OFFSET_P012345, "+1:23"},
{"+H:MM", "Z", DT_2012_06_30_12_30_40, OFFSET_P000045, "Z"},
{"+H:MM", "Z", DT_2012_06_30_12_30_40, OFFSET_M0100, "-1:00"},
{"+H:MM", "Z", DT_2012_06_30_12_30_40, OFFSET_M0123, "-1:23"},
{"+H:MM", "Z", DT_2012_06_30_12_30_40, OFFSET_M0023, "-0:23"},
{"+H:MM", "Z", DT_2012_06_30_12_30_40, OFFSET_M012345, "-1:23"},
{"+H:MM", "Z", DT_2012_06_30_12_30_40, OFFSET_M000045, "Z"},
{"+HMMss", "Z", DT_2012_06_30_12_30_40, OFFSET_UTC, "Z"},
{"+HMMss", "Z", DT_2012_06_30_12_30_40, OFFSET_P0100, "+100"},
{"+HMMss", "Z", DT_2012_06_30_12_30_40, OFFSET_P0123, "+123"},
{"+HMMss", "Z", DT_2012_06_30_12_30_40, OFFSET_P0023, "+023"},
{"+HMMss", "Z", DT_2012_06_30_12_30_40, OFFSET_P012345, "+12345"},
{"+HMMss", "Z", DT_2012_06_30_12_30_40, OFFSET_P000045, "+00045"},
{"+HMMss", "Z", DT_2012_06_30_12_30_40, OFFSET_M0100, "-100"},
{"+HMMss", "Z", DT_2012_06_30_12_30_40, OFFSET_M0123, "-123"},
{"+HMMss", "Z", DT_2012_06_30_12_30_40, OFFSET_M0023, "-023"},
{"+HMMss", "Z", DT_2012_06_30_12_30_40, OFFSET_M012345, "-12345"},
{"+HMMss", "Z", DT_2012_06_30_12_30_40, OFFSET_M000045, "-00045"},
{"+H:MM:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_UTC, "Z"},
{"+H:MM:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_P0100, "+1:00"},
{"+H:MM:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_P0123, "+1:23"},
{"+H:MM:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_P0023, "+0:23"},
{"+H:MM:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_P012345, "+1:23:45"},
{"+H:MM:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_M000045, "-0:00:45"},
{"+H:MM:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_M0100, "-1:00"},
{"+H:MM:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_M0123, "-1:23"},
{"+H:MM:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_M0023, "-0:23"},
{"+H:MM:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_M012345, "-1:23:45"},
{"+H:MM:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_M000045, "-0:00:45"},
{"+HMMSS", "Z", DT_2012_06_30_12_30_40, OFFSET_UTC, "Z"},
{"+HMMSS", "Z", DT_2012_06_30_12_30_40, OFFSET_P0100, "+10000"},
{"+HMMSS", "Z", DT_2012_06_30_12_30_40, OFFSET_P0123, "+12300"},
{"+HMMSS", "Z", DT_2012_06_30_12_30_40, OFFSET_P0023, "+02300"},
{"+HMMSS", "Z", DT_2012_06_30_12_30_40, OFFSET_P012345, "+12345"},
{"+HMMSS", "Z", DT_2012_06_30_12_30_40, OFFSET_M000045, "-00045"},
{"+HMMSS", "Z", DT_2012_06_30_12_30_40, OFFSET_M0100, "-10000"},
{"+HMMSS", "Z", DT_2012_06_30_12_30_40, OFFSET_M0123, "-12300"},
{"+HMMSS", "Z", DT_2012_06_30_12_30_40, OFFSET_M0023, "-02300"},
{"+HMMSS", "Z", DT_2012_06_30_12_30_40, OFFSET_M012345, "-12345"},
{"+HMMSS", "Z", DT_2012_06_30_12_30_40, OFFSET_M000045, "-00045"},
{"+H:MM:SS", "Z", DT_2012_06_30_12_30_40, OFFSET_UTC, "Z"},
{"+H:MM:SS", "Z", DT_2012_06_30_12_30_40, OFFSET_P0100, "+1:00:00"},
{"+H:MM:SS", "Z", DT_2012_06_30_12_30_40, OFFSET_P0123, "+1:23:00"},
{"+H:MM:SS", "Z", DT_2012_06_30_12_30_40, OFFSET_P0023, "+0:23:00"},
{"+H:MM:SS", "Z", DT_2012_06_30_12_30_40, OFFSET_P012345, "+1:23:45"},
{"+H:MM:SS", "Z", DT_2012_06_30_12_30_40, OFFSET_M000045, "-0:00:45"},
{"+H:MM:SS", "Z", DT_2012_06_30_12_30_40, OFFSET_M0100, "-1:00:00"},
{"+H:MM:SS", "Z", DT_2012_06_30_12_30_40, OFFSET_M0123, "-1:23:00"},
{"+H:MM:SS", "Z", DT_2012_06_30_12_30_40, OFFSET_M0023, "-0:23:00"},
{"+H:MM:SS", "Z", DT_2012_06_30_12_30_40, OFFSET_M012345, "-1:23:45"},
{"+H:MM:SS", "Z", DT_2012_06_30_12_30_40, OFFSET_M000045, "-0:00:45"},
{"+H:mm:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_UTC, "Z"},
{"+H:mm:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_P0100, "+1"},
{"+H:mm:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_P0123, "+1:23"},
{"+H:mm:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_P0023, "+0:23"},
{"+H:mm:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_P012345, "+1:23:45"},
{"+H:mm:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_M000045, "-0:00:45"},
{"+H:mm:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_M0100, "-1"},
{"+H:mm:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_M0123, "-1:23"},
{"+H:mm:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_M0023, "-0:23"},
{"+H:mm:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_M012345, "-1:23:45"},
{"+H:mm:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_M000045, "-0:00:45"},
{"+Hmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_UTC, "Z"},
{"+Hmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_P0100, "+1"},
{"+Hmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_P0123, "+123"},
{"+Hmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_P0023, "+023"},
{"+Hmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_P012345, "+12345"},
{"+Hmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_P000045, "+00045"},
{"+Hmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_M0100, "-1"},
{"+Hmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_M0123, "-123"},
{"+Hmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_M0023, "-023"},
{"+Hmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_M012345, "-12345"},
{"+Hmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_M000045, "-00045"},
{"+H", "Z", DT_2012_06_30_12_30_40, OFFSET_P1100, "+11"},
{"+H", "Z", DT_2012_06_30_12_30_40, OFFSET_P1123, "+11"},
{"+H", "Z", DT_2012_06_30_12_30_40, OFFSET_P1023, "+10"},
{"+H", "Z", DT_2012_06_30_12_30_40, OFFSET_P112345, "+11"},
{"+H", "Z", DT_2012_06_30_12_30_40, OFFSET_P100045, "+10"},
{"+H", "Z", DT_2012_06_30_12_30_40, OFFSET_M1100, "-11"},
{"+H", "Z", DT_2012_06_30_12_30_40, OFFSET_M1123, "-11"},
{"+H", "Z", DT_2012_06_30_12_30_40, OFFSET_M112345, "-11"},
{"+Hmm", "Z", DT_2012_06_30_12_30_40, OFFSET_P1100, "+11"},
{"+Hmm", "Z", DT_2012_06_30_12_30_40, OFFSET_P1123, "+1123"},
{"+Hmm", "Z", DT_2012_06_30_12_30_40, OFFSET_P1023, "+1023"},
{"+Hmm", "Z", DT_2012_06_30_12_30_40, OFFSET_P112345, "+1123"},
{"+Hmm", "Z", DT_2012_06_30_12_30_40, OFFSET_P100045, "+10"},
{"+Hmm", "Z", DT_2012_06_30_12_30_40, OFFSET_M1100, "-11"},
{"+Hmm", "Z", DT_2012_06_30_12_30_40, OFFSET_M1123, "-1123"},
{"+Hmm", "Z", DT_2012_06_30_12_30_40, OFFSET_M112345, "-1123"},
{"+HMM", "Z", DT_2012_06_30_12_30_40, OFFSET_P1100, "+1100"},
{"+HMM", "Z", DT_2012_06_30_12_30_40, OFFSET_P1123, "+1123"},
{"+HMM", "Z", DT_2012_06_30_12_30_40, OFFSET_P1023, "+1023"},
{"+HMM", "Z", DT_2012_06_30_12_30_40, OFFSET_P112345, "+1123"},
{"+HMM", "Z", DT_2012_06_30_12_30_40, OFFSET_P100045, "+1000"},
{"+HMM", "Z", DT_2012_06_30_12_30_40, OFFSET_M1100, "-1100"},
{"+HMM", "Z", DT_2012_06_30_12_30_40, OFFSET_M1123, "-1123"},
{"+HMM", "Z", DT_2012_06_30_12_30_40, OFFSET_M112345, "-1123"},
{"+H:MM", "Z", DT_2012_06_30_12_30_40, OFFSET_P1100, "+11:00"},
{"+H:MM", "Z", DT_2012_06_30_12_30_40, OFFSET_P1123, "+11:23"},
{"+H:MM", "Z", DT_2012_06_30_12_30_40, OFFSET_P1023, "+10:23"},
{"+H:MM", "Z", DT_2012_06_30_12_30_40, OFFSET_P112345, "+11:23"},
{"+H:MM", "Z", DT_2012_06_30_12_30_40, OFFSET_P100045, "+10:00"},
{"+H:MM", "Z", DT_2012_06_30_12_30_40, OFFSET_M1100, "-11:00"},
{"+H:MM", "Z", DT_2012_06_30_12_30_40, OFFSET_M1123, "-11:23"},
{"+H:MM", "Z", DT_2012_06_30_12_30_40, OFFSET_M112345, "-11:23"},
{"+HMMss", "Z", DT_2012_06_30_12_30_40, OFFSET_P1100, "+1100"},
{"+HMMss", "Z", DT_2012_06_30_12_30_40, OFFSET_P1123, "+1123"},
{"+HMMss", "Z", DT_2012_06_30_12_30_40, OFFSET_P1023, "+1023"},
{"+HMMss", "Z", DT_2012_06_30_12_30_40, OFFSET_P112345, "+112345"},
{"+HMMss", "Z", DT_2012_06_30_12_30_40, OFFSET_P100045, "+100045"},
{"+HMMss", "Z", DT_2012_06_30_12_30_40, OFFSET_M1100, "-1100"},
{"+HMMss", "Z", DT_2012_06_30_12_30_40, OFFSET_M1123, "-1123"},
{"+HMMss", "Z", DT_2012_06_30_12_30_40, OFFSET_M112345, "-112345"},
{"+H:MM:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_P1100, "+11:00"},
{"+H:MM:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_P1123, "+11:23"},
{"+H:MM:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_P1023, "+10:23"},
{"+H:MM:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_P112345, "+11:23:45"},
{"+H:MM:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_M1100, "-11:00"},
{"+H:MM:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_M1123, "-11:23"},
{"+H:MM:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_M112345, "-11:23:45"},
{"+HMMSS", "Z", DT_2012_06_30_12_30_40, OFFSET_P1100, "+110000"},
{"+HMMSS", "Z", DT_2012_06_30_12_30_40, OFFSET_P1123, "+112300"},
{"+HMMSS", "Z", DT_2012_06_30_12_30_40, OFFSET_P1023, "+102300"},
{"+HMMSS", "Z", DT_2012_06_30_12_30_40, OFFSET_P112345, "+112345"},
{"+HMMSS", "Z", DT_2012_06_30_12_30_40, OFFSET_M1100, "-110000"},
{"+HMMSS", "Z", DT_2012_06_30_12_30_40, OFFSET_M1123, "-112300"},
{"+HMMSS", "Z", DT_2012_06_30_12_30_40, OFFSET_M112345, "-112345"},
{"+H:MM:SS", "Z", DT_2012_06_30_12_30_40, OFFSET_P1100, "+11:00:00"},
{"+H:MM:SS", "Z", DT_2012_06_30_12_30_40, OFFSET_P1123, "+11:23:00"},
{"+H:MM:SS", "Z", DT_2012_06_30_12_30_40, OFFSET_P1023, "+10:23:00"},
{"+H:MM:SS", "Z", DT_2012_06_30_12_30_40, OFFSET_P112345, "+11:23:45"},
{"+H:MM:SS", "Z", DT_2012_06_30_12_30_40, OFFSET_M1100, "-11:00:00"},
{"+H:MM:SS", "Z", DT_2012_06_30_12_30_40, OFFSET_M1123, "-11:23:00"},
{"+H:MM:SS", "Z", DT_2012_06_30_12_30_40, OFFSET_M112345, "-11:23:45"},
{"+H:mm:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_P1100, "+11"},
{"+H:mm:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_P1123, "+11:23"},
{"+H:mm:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_P1023, "+10:23"},
{"+H:mm:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_P112345, "+11:23:45"},
{"+H:mm:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_M1100, "-11"},
{"+H:mm:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_M1123, "-11:23"},
{"+H:mm:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_M112345, "-11:23:45"},
{"+Hmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_P1100, "+11"},
{"+Hmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_P1123, "+1123"},
{"+Hmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_P1023, "+1023"},
{"+Hmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_P112345, "+112345"},
{"+Hmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_P100045, "+100045"},
{"+Hmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_M1100, "-11"},
{"+Hmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_M1123, "-1123"},
{"+Hmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_M112345, "-112345"},
};
}

@ -484,8 +484,6 @@ public class TestDateTimeFormatterBuilder {
{"HH:MM:ss"},
{"HHMMSS"},
{"HH:MM:SS"},
{"+H"},
{"+HMM"},
{"+HHM"},
{"+A"},
};

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2016, 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
@ -296,7 +296,7 @@ public class TestZoneOffsetParser extends AbstractTestPrinterParser {
@DataProvider(name="bigOffsets")
Object[][] provider_bigOffsets() {
return new Object[][] {
{"+HH", "+59", 59 * 3600},
{"+HH", "+19", 19 * 3600},
{"+HH", "-19", -(19 * 3600)},
{"+HHMM", "+1801", 18 * 3600 + 1 * 60},

@ -24,7 +24,7 @@
/*
* @test
* @bug 4028006 4044013 4096694 4107276 4107570 4112869 4130885 7039469 7126465 7158483
* 8008577 8077685 8098547 8133321 8138716 8148446 8151876
* 8008577 8077685 8098547 8133321 8138716 8148446 8151876 8159684
* @modules java.base/sun.util.resources
* @library /java/text/testlib
* @summary test TimeZone

@ -0,0 +1,97 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 8159488
* @summary Basic tests for the various getInstance() methods of
* XMLSignatureFactory, TransformService, and KeyInfoFactory classes
* @run main GetInstanceTests
*/
import java.security.*;
import javax.xml.crypto.dsig.*;
import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
public class GetInstanceTests {
public static void main(String[] argv) throws Exception {
TestTransformService(CanonicalizationMethod.INCLUSIVE, "DOM");
TestTransformService(CanonicalizationMethod.EXCLUSIVE_WITH_COMMENTS, "DOM");
TestTransformService(Transform.BASE64, "DOM");
TestTransformService(Transform.XPATH2, "DOM");
TestXMLSignatureFactory();
TestKeyInfoFactory();
}
private static void TestTransformService(String algo,
String mechType) throws Exception {
TransformService ts = TransformService.getInstance(algo, mechType);
Provider p = ts.getProvider();
try {
ts = TransformService.getInstance(algo, mechType, p);
ts = TransformService.getInstance(algo, mechType, p.getName());
} catch (Exception ex) {
throw new RuntimeException("Error: Unexpected exception", ex);
}
}
private static void TestXMLSignatureFactory() throws Exception {
XMLSignatureFactory fac = XMLSignatureFactory.getInstance();
Provider p = fac.getProvider();
String mechType = fac.getMechanismType();
Provider p2;
try {
fac = XMLSignatureFactory.getInstance(mechType);
p2 = fac.getProvider();
fac = XMLSignatureFactory.getInstance(mechType, p);
fac = XMLSignatureFactory.getInstance(mechType, p.getName());
} catch (Exception ex) {
throw new RuntimeException("Error: Unexpected exception", ex);
}
if (p2.getName() != p.getName()) {
throw new RuntimeException("Error: Provider equality check failed");
}
if (p2.getName() != p.getName()) {
throw new RuntimeException("Error: Provider equality check failed");
}
}
private static void TestKeyInfoFactory() throws Exception {
KeyInfoFactory fac = KeyInfoFactory.getInstance();
Provider p = fac.getProvider();
String mechType = fac.getMechanismType();
Provider p2;
try {
fac = KeyInfoFactory.getInstance(mechType);
p2 = fac.getProvider();
fac = KeyInfoFactory.getInstance(mechType, p);
fac = KeyInfoFactory.getInstance(mechType, p.getName());
} catch (Exception ex) {
throw new RuntimeException("Error: Unexpected exception", ex);
}
if (p2.getName() != p.getName()) {
throw new RuntimeException("Error: Provider equality check failed");
}
}
}

@ -21,4 +21,4 @@
# or visit www.oracle.com if you need additional information or have any
# questions.
#
tzdata2016d
tzdata2016f

@ -366,6 +366,12 @@ Rule Egypt 2007 only - Sep Thu>=1 24:00 0 -
# decision to abandon DST permanently. See Ahram Online 2015-04-24.
# http://english.ahram.org.eg/NewsContent/1/64/128509/Egypt/Politics-/Sisi-cancels-daylight-saving-time-in-Egypt.aspx
# From Steffen Thorsen (2016-04-29):
# Egypt will have DST from July 7 until the end of October....
# http://english.ahram.org.eg/NewsContentP/1/204655/Egypt/Daylight-savings-time-returning-to-Egypt-on--July.aspx
# From Mina Samuel (2016-07-04):
# Egyptian government took the decision to cancel the DST,
Rule Egypt 2008 only - Aug lastThu 24:00 0 -
Rule Egypt 2009 only - Aug 20 24:00 0 -
Rule Egypt 2010 only - Aug 10 24:00 0 -
@ -881,11 +887,11 @@ Rule Morocco 2009 only - Aug 21 0:00 0 -
Rule Morocco 2010 only - May 2 0:00 1:00 S
Rule Morocco 2010 only - Aug 8 0:00 0 -
Rule Morocco 2011 only - Apr 3 0:00 1:00 S
Rule Morocco 2011 only - Jul 31 0 0 -
Rule Morocco 2011 only - Jul 31 0:00 0 -
Rule Morocco 2012 2013 - Apr lastSun 2:00 1:00 S
Rule Morocco 2012 only - Sep 30 3:00 0 -
Rule Morocco 2012 only - Jul 20 3:00 0 -
Rule Morocco 2012 only - Aug 20 2:00 1:00 S
Rule Morocco 2012 only - Sep 30 3:00 0 -
Rule Morocco 2013 only - Jul 7 3:00 0 -
Rule Morocco 2013 only - Aug 10 2:00 1:00 S
Rule Morocco 2013 max - Oct lastSun 3:00 0 -

@ -36,7 +36,7 @@
#
# Except for the French entries,
# I made up all time zone abbreviations mentioned here; corrections welcome!
# FORMAT is 'zzz' and GMTOFF is 0 for locations while uninhabited.
# FORMAT is '-00' and GMTOFF is 0 for locations while uninhabited.
# Argentina - year-round bases
# Belgrano II, Confin Coast, -770227-0343737, since 1972-02-05
@ -90,22 +90,22 @@
# http://www.timeanddate.com/news/time/antartica-time-changes-2010.html
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Antarctica/Casey 0 - zzz 1969
Zone Antarctica/Casey 0 - -00 1969
8:00 - AWST 2009 Oct 18 2:00
# Australian Western Std Time
11:00 - CAST 2010 Mar 5 2:00 # Casey Time
8:00 - AWST 2011 Oct 28 2:00
11:00 - CAST 2012 Feb 21 17:00u
8:00 - AWST
Zone Antarctica/Davis 0 - zzz 1957 Jan 13
Zone Antarctica/Davis 0 - -00 1957 Jan 13
7:00 - DAVT 1964 Nov # Davis Time
0 - zzz 1969 Feb
0 - -00 1969 Feb
7:00 - DAVT 2009 Oct 18 2:00
5:00 - DAVT 2010 Mar 10 20:00u
7:00 - DAVT 2011 Oct 28 2:00
5:00 - DAVT 2012 Feb 21 20:00u
7:00 - DAVT
Zone Antarctica/Mawson 0 - zzz 1954 Feb 13
Zone Antarctica/Mawson 0 - -00 1954 Feb 13
6:00 - MAWT 2009 Oct 18 2:00 # Mawson Time
5:00 - MAWT
# References:
@ -160,7 +160,7 @@ Zone Antarctica/Mawson 0 - zzz 1954 Feb 13
# fishing stations operated variously 1819/1931
#
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Indian/Kerguelen 0 - zzz 1950 # Port-aux-Français
Zone Indian/Kerguelen 0 - -00 1950 # Port-aux-Français
5:00 - TFT # ISO code TF Time
#
# year-round base in the main continent
@ -171,9 +171,9 @@ Zone Indian/Kerguelen 0 - zzz 1950 # Port-aux-Français
# It was destroyed by fire on 1952-01-14.
#
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Antarctica/DumontDUrville 0 - zzz 1947
Zone Antarctica/DumontDUrville 0 - -00 1947
10:00 - PMT 1952 Jan 14 # Port-Martin Time
0 - zzz 1956 Nov
0 - -00 1956 Nov
10:00 - DDUT # Dumont-d'Urville Time
# France & Italy - year-round base
@ -199,7 +199,7 @@ Zone Antarctica/DumontDUrville 0 - zzz 1947
# was established on 1957-01-29. Since Syowa station is still the main
# station of Japan, it's appropriate for the principal location.
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Antarctica/Syowa 0 - zzz 1957 Jan 29
Zone Antarctica/Syowa 0 - -00 1957 Jan 29
3:00 - SYOT # Syowa Time
# See:
# NIPR Antarctic Research Activities (1999-08-17)
@ -249,7 +249,7 @@ Rule Troll 2005 max - Mar lastSun 1:00u 2:00 CEST
# Remove the following line when uncommenting the above '#Rule' lines.
Rule Troll 2004 max - Oct lastSun 1:00u 0:00 UTC
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Antarctica/Troll 0 - zzz 2005 Feb 12
Zone Antarctica/Troll 0 - -00 2005 Feb 12
0:00 Troll %s
# Poland - year-round base
@ -290,7 +290,7 @@ Zone Antarctica/Troll 0 - zzz 2005 Feb 12
# happened to be during their visit. So we still don't really know what time
# it is at Vostok. But we'll guess UTC+6.
#
Zone Antarctica/Vostok 0 - zzz 1957 Dec 16
Zone Antarctica/Vostok 0 - -00 1957 Dec 16
6:00 - VOST # Vostok time
# S Africa - year-round bases
@ -323,7 +323,7 @@ Zone Antarctica/Vostok 0 - zzz 1957 Dec 16
# <http://webexhibits.org/daylightsaving/g.html> says Rothera is -03 all year.
#
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Antarctica/Rothera 0 - zzz 1976 Dec 1
Zone Antarctica/Rothera 0 - -00 1976 Dec 1
-3:00 - ROTT # Rothera time
# Uruguay - year round base

@ -169,7 +169,7 @@ Zone Asia/Baku 3:19:24 - LMT 1924 May 2
3:00 - BAKT 1957 Mar # Baku Time
4:00 RussiaAsia BAK%sT 1991 Mar 31 2:00s
3:00 1:00 BAKST 1991 Aug 30 # independence
3:00 RussiaAsia AZ%sT 1992 Sep lastSat 23:00
3:00 RussiaAsia AZ%sT 1992 Sep lastSun 2:00s
4:00 - AZT 1996 # Azerbaijan Time
4:00 EUAsia AZ%sT 1997
4:00 Azer AZ%sT

@ -266,11 +266,11 @@ Zone Australia/Lord_Howe 10:36:20 - LMT 1895 Feb
# will produce a binary file with an [A]EST-type as the first 32-bit type;
# this is required for correct handling of times before 1916 by
# pre-2013 versions of localtime.
Zone Antarctica/Macquarie 0 - zzz 1899 Nov
Zone Antarctica/Macquarie 0 - -00 1899 Nov
10:00 - AEST 1916 Oct 1 2:00
10:00 1:00 AEDT 1917 Feb
10:00 Aus AE%sT 1919 Apr 1 0:00s
0 - zzz 1948 Mar 25
0 - -00 1948 Mar 25
10:00 Aus AE%sT 1967
10:00 AT AE%sT 2010 Apr 4 3:00
11:00 - MIST # Macquarie I Standard Time

@ -778,6 +778,14 @@ Zone Europe/Vienna 1:05:21 - LMT 1893 Apr
1:00 EU CE%sT
# Belarus
#
# From Stepan Golosunov (2016-07-02):
# http://www.lawbelarus.com/repub/sub30/texf9611.htm
# (Act of the Cabinet of Ministers of the Republic of Belarus from
# 1992-03-25 No. 157) ... says clocks were to be moved forward at 2:00
# on last Sunday of March and backward at 3:00 on last Sunday of September
# (the same as previous USSR and contemporary Russian regulations).
#
# From Yauhen Kharuzhy (2011-09-16):
# By latest Belarus government act Europe/Minsk timezone was changed to
# GMT+3 without DST (was GMT+2 with DST).
@ -801,9 +809,6 @@ Zone Europe/Minsk 1:50:16 - LMT 1880
1:00 C-Eur CE%sT 1944 Jul 3
3:00 Russia MSK/MSD 1990
3:00 - MSK 1991 Mar 31 2:00s
2:00 1:00 EEST 1991 Sep 29 2:00s
2:00 - EET 1992 Mar 29 0:00s
2:00 1:00 EEST 1992 Sep 27 0:00s
2:00 Russia EE%sT 2011 Mar 27 2:00s
3:00 - FET 2014 Oct 26 1:00s
3:00 - MSK
@ -2746,14 +2751,22 @@ Zone Asia/Barnaul 5:35:00 - LMT 1919 Dec 10
# Asia/Novosibirsk covers:
# 54 RU-NVS Novosibirsk Oblast
# From Stepan Golosunov (2016-05-30):
# http://asozd2.duma.gov.ru/main.nsf/(Spravka)?OpenAgent&RN=1085784-6
# moves Novosibirsk oblast from UTC+6 to UTC+7.
# From Stepan Golosunov (2016-07-04):
# The law was signed yesterday and published today on
# http://publication.pravo.gov.ru/Document/View/0001201607040064
Zone Asia/Novosibirsk 5:31:40 - LMT 1919 Dec 14 6:00
6:00 - NOVT 1930 Jun 21 # Novosibirsk Time
7:00 Russia NOV%sT 1991 Mar 31 2:00s
6:00 Russia NOV%sT 1992 Jan 19 2:00s
7:00 Russia NOV%sT 1993 May 23 # say Shanks & P.
6:00 Russia NOV%sT 2011 Mar 27 2:00s
7:00 - NOVT 2014 Oct 26 2:00s
6:00 - NOVT
6:00 - +06 1930 Jun 21
7:00 Russia +07/+08 1991 Mar 31 2:00s
6:00 Russia +06/+07 1992 Jan 19 2:00s
7:00 Russia +07/+08 1993 May 23 # say Shanks & P.
6:00 Russia +06/+07 2011 Mar 27 2:00s
7:00 - +07 2014 Oct 26 2:00s
6:00 - +06 2016 Jul 24 2:00s
7:00 - +07
# From Paul Eggert (2016-03-18):
# Asia/Tomsk covers:
@ -2794,6 +2807,9 @@ Zone Asia/Novosibirsk 5:31:40 - LMT 1919 Dec 14 6:00
# approved by the Federation Council on 2016-04-20, signed by the President and
# published as a law around 2016-04-26.
# From Matt Johnson (2016-04-26):
# http://publication.pravo.gov.ru/Document/View/0001201604260048
Zone Asia/Tomsk 5:39:51 - LMT 1919 Dec 22
6:00 - +06 1930 Jun 21
7:00 Russia +07/+08 1991 Mar 31 2:00s
@ -2833,14 +2849,12 @@ Zone Asia/Tomsk 5:39:51 - LMT 1919 Dec 22
# realigning itself with KRAT.
Zone Asia/Novokuznetsk 5:48:48 - LMT 1924 May 1
6:00 - KRAT 1930 Jun 21 # Krasnoyarsk Time
7:00 Russia KRA%sT 1991 Mar 31 2:00s
6:00 Russia KRA%sT 1992 Jan 19 2:00s
7:00 Russia KRA%sT 2010 Mar 28 2:00s
6:00 Russia NOV%sT 2011 Mar 27 2:00s # Novosibirsk
7:00 - NOVT 2014 Oct 26 2:00s
7:00 - KRAT # Krasnoyarsk Time
6:00 - +06 1930 Jun 21
7:00 Russia +07/+08 1991 Mar 31 2:00s
6:00 Russia +06/+07 1992 Jan 19 2:00s
7:00 Russia +07/+08 2010 Mar 28 2:00s
6:00 Russia +06/+07 2011 Mar 27 2:00s
7:00 - +07
# From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2001-08-25):
# Asia/Krasnoyarsk covers...

@ -2214,39 +2214,39 @@ Rule NT_YK 1980 2006 - Oct lastSun 2:00 0 S
Rule NT_YK 1987 2006 - Apr Sun>=1 2:00 1:00 D
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
# aka Panniqtuuq
Zone America/Pangnirtung 0 - zzz 1921 # trading post est.
Zone America/Pangnirtung 0 - -00 1921 # trading post est.
-4:00 NT_YK A%sT 1995 Apr Sun>=1 2:00
-5:00 Canada E%sT 1999 Oct 31 2:00
-6:00 Canada C%sT 2000 Oct 29 2:00
-5:00 Canada E%sT
# formerly Frobisher Bay
Zone America/Iqaluit 0 - zzz 1942 Aug # Frobisher Bay est.
Zone America/Iqaluit 0 - -00 1942 Aug # Frobisher Bay est.
-5:00 NT_YK E%sT 1999 Oct 31 2:00
-6:00 Canada C%sT 2000 Oct 29 2:00
-5:00 Canada E%sT
# aka Qausuittuq
Zone America/Resolute 0 - zzz 1947 Aug 31 # Resolute founded
Zone America/Resolute 0 - -00 1947 Aug 31 # Resolute founded
-6:00 NT_YK C%sT 2000 Oct 29 2:00
-5:00 - EST 2001 Apr 1 3:00
-6:00 Canada C%sT 2006 Oct 29 2:00
-5:00 - EST 2007 Mar 11 3:00
-6:00 Canada C%sT
# aka Kangiqiniq
Zone America/Rankin_Inlet 0 - zzz 1957 # Rankin Inlet founded
Zone America/Rankin_Inlet 0 - -00 1957 # Rankin Inlet founded
-6:00 NT_YK C%sT 2000 Oct 29 2:00
-5:00 - EST 2001 Apr 1 3:00
-6:00 Canada C%sT
# aka Iqaluktuuttiaq
Zone America/Cambridge_Bay 0 - zzz 1920 # trading post est.?
Zone America/Cambridge_Bay 0 - -00 1920 # trading post est.?
-7:00 NT_YK M%sT 1999 Oct 31 2:00
-6:00 Canada C%sT 2000 Oct 29 2:00
-5:00 - EST 2000 Nov 5 0:00
-6:00 - CST 2001 Apr 1 3:00
-7:00 Canada M%sT
Zone America/Yellowknife 0 - zzz 1935 # Yellowknife founded?
Zone America/Yellowknife 0 - -00 1935 # Yellowknife founded?
-7:00 NT_YK M%sT 1980
-7:00 Canada M%sT
Zone America/Inuvik 0 - zzz 1953 # Inuvik founded
Zone America/Inuvik 0 - -00 1953 # Inuvik founded
-8:00 NT_YK P%sT 1979 Apr lastSun 2:00
-7:00 NT_YK M%sT 1980
-7:00 Canada M%sT

@ -1332,7 +1332,7 @@ Zone Pacific/Easter -7:17:28 - LMT 1890
# Palmer used to be supplied from Argentina.
#
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Antarctica/Palmer 0 - zzz 1965
Zone Antarctica/Palmer 0 - -00 1965
-4:00 Arg AR%sT 1969 Oct 5
-3:00 Arg AR%sT 1982 May
-4:00 Chile CL%sT
@ -1782,16 +1782,16 @@ Zone America/Montevideo -3:44:44 - LMT 1898 Jun 28
# https://actualidad.rt.com/actualidad/204758-venezuela-modificar-huso-horario-sequia-elnino
#
# From Paul Eggert (2016-04-15):
# Clocks advance 30 minutes on 2016-05-01 at 02:30. See:
# Barboza AD. Huso horario en Venezuela volverá a 4 horas menos con
# respecto al "Greenwich". Panorama 2016-04-15 12:20 -0430.
# http://www.panorama.com.ve/ciudad/Huso-horario-en-Venezuela-volvera-a-4-horas-menos-con-respecto-al-Greenwich-20160415-0032.html
#
# Clocks advance 30 minutes on 2016-05-01 at 02:30....
# "'Venezuela's new time-zone: hours without light, hours without water,
# hours of presidential broadcasts, hours of lines," quipped comedian
# Jean Mary Curro ...". See: Cawthorne A, Kai D. Venezuela scraps
# hours of presidential broadcasts, hours of lines,' quipped comedian
# Jean Mary Curró ...". See: Cawthorne A, Kai D. Venezuela scraps
# half-hour time difference set by Chavez. Reuters 2016-04-15 14:50 -0400
# http://www.reuters.com/article/us-venezuela-timezone-idUSKCN0XC2BE
#
# From Matt Johnson (2016-04-20):
# ... published in the official Gazette [2016-04-18], here:
# http://historico.tsj.gob.ve/gaceta_ext/abril/1842016/E-1842016-4551.pdf
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone America/Caracas -4:27:44 - LMT 1890

@ -32,7 +32,8 @@ import java.util.Set;
import jdk.tools.jlink.internal.PluginRepository;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
import tests.Helper;
/*
@ -69,7 +70,7 @@ public class DefaultProviderTest {
}
@Override
public void visit(ModulePool in, ModulePool out) {
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
if (!enabled) {
throw new PluginException(NAME + " was set");
}
@ -78,6 +79,8 @@ public class DefaultProviderTest {
in.transformAndCopy(content -> {
return content;
}, out);
return out.build();
}
@Override

@ -39,7 +39,7 @@ import jdk.tools.jlink.internal.ImageFileCreator;
import jdk.tools.jlink.internal.ImagePluginStack;
import jdk.tools.jlink.internal.ExecutableImage;
import jdk.tools.jlink.builder.ImageBuilder;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.ResourcePool;
/*
@ -215,7 +215,7 @@ public class ImageFileCreatorTest {
}
@Override
public void storeFiles(ModulePool content) {
public void storeFiles(ResourcePool content) {
}
};

@ -33,10 +33,10 @@
import java.io.ByteArrayInputStream;
import java.util.Optional;
import java.util.function.Function;
import jdk.tools.jlink.internal.ModuleEntryFactory;
import jdk.tools.jlink.internal.ModulePoolImpl;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.internal.ResourcePoolEntryFactory;
import jdk.tools.jlink.internal.ResourcePoolManager;
import jdk.tools.jlink.plugin.ResourcePoolEntry;
import jdk.tools.jlink.plugin.ResourcePool;
public class ImageFilePoolTest {
public static void main(String[] args) throws Exception {
@ -51,55 +51,55 @@ public class ImageFilePoolTest {
private static final String SUFFIX = "END";
private void checkVisitor() throws Exception {
ModulePool input = new ModulePoolImpl();
ResourcePoolManager input = new ResourcePoolManager();
for (int i = 0; i < 1000; ++i) {
String module = "module" + (i / 100);
input.add(newInMemoryImageFile("/" + module + "/java/class" + i,
ModuleEntry.Type.CONFIG, "class" + i));
ResourcePoolEntry.Type.CONFIG, "class" + i));
}
if (input.getEntryCount() != 1000) {
if (input.entryCount() != 1000) {
throw new AssertionError();
}
ModulePool output = new ModulePoolImpl();
ResourcePoolManager output = new ResourcePoolManager();
ResourceVisitor visitor = new ResourceVisitor();
input.transformAndCopy(visitor, output);
input.resourcePool().transformAndCopy(visitor, output.resourcePoolBuilder());
if (visitor.getAmountBefore() == 0) {
throw new AssertionError("Resources not found");
}
if (visitor.getAmountBefore() != input.getEntryCount()) {
if (visitor.getAmountBefore() != input.entryCount()) {
throw new AssertionError("Number of visited resources. Expected: " +
visitor.getAmountBefore() + ", got: " + input.getEntryCount());
visitor.getAmountBefore() + ", got: " + input.entryCount());
}
if (visitor.getAmountAfter() != output.getEntryCount()) {
if (visitor.getAmountAfter() != output.entryCount()) {
throw new AssertionError("Number of added resources. Expected: " +
visitor.getAmountAfter() + ", got: " + output.getEntryCount());
visitor.getAmountAfter() + ", got: " + output.entryCount());
}
output.entries().forEach(outFile -> {
String path = outFile.getPath().replaceAll(SUFFIX + "$", "");
Optional<ModuleEntry> inFile = input.findEntry(path);
String path = outFile.path().replaceAll(SUFFIX + "$", "");
Optional<ResourcePoolEntry> inFile = input.findEntry(path);
if (!inFile.isPresent()) {
throw new AssertionError("Unknown resource: " + path);
}
});
}
private static class ResourceVisitor implements Function<ModuleEntry, ModuleEntry> {
private static class ResourceVisitor implements Function<ResourcePoolEntry, ResourcePoolEntry> {
private int amountBefore;
private int amountAfter;
@Override
public ModuleEntry apply(ModuleEntry file) {
public ResourcePoolEntry apply(ResourcePoolEntry file) {
int index = ++amountBefore % 3;
switch (index) {
case 0:
++amountAfter;
return newInMemoryImageFile(file.getPath() + SUFFIX,
file.getType(), file.getPath());
return newInMemoryImageFile(file.path() + SUFFIX,
file.type(), file.path());
case 1:
++amountAfter;
return newInMemoryImageFile(file.getPath(),
file.getType(), file.getPath());
return newInMemoryImageFile(file.path(),
file.type(), file.path());
}
return null;
}
@ -114,7 +114,7 @@ public class ImageFilePoolTest {
}
private void checkNegative() throws Exception {
ModulePoolImpl input = new ModulePoolImpl();
ResourcePoolManager input = new ResourcePoolManager();
try {
input.add(null);
throw new AssertionError("NullPointerException is not thrown");
@ -128,29 +128,22 @@ public class ImageFilePoolTest {
// expected
}
if (input.findEntry("unknown").isPresent()) {
throw new AssertionError("ImageFileModulePool does not return null for unknown file");
throw new AssertionError("ImageFileResourcePool does not return null for unknown file");
}
if (input.contains(newInMemoryImageFile("/unknown/foo", ModuleEntry.Type.CONFIG, "unknown"))) {
if (input.contains(newInMemoryImageFile("/unknown/foo", ResourcePoolEntry.Type.CONFIG, "unknown"))) {
throw new AssertionError("'contain' returns true for /unknown/foo file");
}
input.add(newInMemoryImageFile("/aaa/bbb", ModuleEntry.Type.CONFIG, ""));
input.add(newInMemoryImageFile("/aaa/bbb", ResourcePoolEntry.Type.CONFIG, ""));
try {
input.add(newInMemoryImageFile("/aaa/bbb", ModuleEntry.Type.CONFIG, ""));
throw new AssertionError("Exception expected");
} catch (Exception e) {
// expected
}
input.setReadOnly();
try {
input.add(newInMemoryImageFile("/aaa/ccc", ModuleEntry.Type.CONFIG, ""));
input.add(newInMemoryImageFile("/aaa/bbb", ResourcePoolEntry.Type.CONFIG, ""));
throw new AssertionError("Exception expected");
} catch (Exception e) {
// expected
}
}
private static ModuleEntry newInMemoryImageFile(String path,
ModuleEntry.Type type, String content) {
return ModuleEntryFactory.create(path, type, content.getBytes());
private static ResourcePoolEntry newInMemoryImageFile(String path,
ResourcePoolEntry.Type type, String content) {
return ResourcePoolEntryFactory.create(path, type, content.getBytes());
}
}

@ -39,7 +39,8 @@ import jdk.tools.jlink.Jlink;
import jdk.tools.jlink.Jlink.JlinkConfiguration;
import jdk.tools.jlink.Jlink.PluginsConfiguration;
import jdk.tools.jlink.builder.DefaultImageBuilder;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.internal.ExecutableImage;
import jdk.tools.jlink.internal.PostProcessor;
@ -100,8 +101,9 @@ public class IntegrationTest {
}
@Override
public void visit(ModulePool in, ModulePool out) {
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
in.transformAndCopy(Function.identity(), out);
return out.build();
}
}

@ -24,7 +24,8 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
import jdk.tools.jlink.internal.PluginRepository;
import jdk.tools.jlink.plugin.Plugin;
@ -62,8 +63,8 @@ public class JLinkOptionsTest {
}
@Override
public void visit(ModulePool in, ModulePool out) {
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
return out.build();
}
@Override

@ -31,7 +31,8 @@ import java.util.Map;
import java.util.function.Function;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
import jdk.tools.jlink.internal.PluginRepository;
import jdk.tools.jlink.internal.PostProcessor;
import jdk.tools.jlink.internal.ExecutableImage;
@ -71,8 +72,9 @@ public class JLinkPostProcessingTest {
}
@Override
public void visit(ModulePool in, ModulePool out) {
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
in.transformAndCopy(Function.identity(), out);
return out.build();
}
@Override

@ -40,11 +40,11 @@ import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import jdk.tools.jlink.internal.ModulePoolImpl;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.LinkModule;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.internal.ResourcePoolManager;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolModule;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolEntry;
public class ResourcePoolTest {
@ -61,51 +61,51 @@ public class ResourcePoolTest {
private static final String SUFFIX = "END";
private void checkResourceVisitor() throws Exception {
ModulePool input = new ModulePoolImpl();
ResourcePoolManager input = new ResourcePoolManager();
for (int i = 0; i < 1000; ++i) {
String module = "/module" + (i / 10);
String resourcePath = module + "/java/package" + i;
byte[] bytes = resourcePath.getBytes();
input.add(ModuleEntry.create(resourcePath, bytes));
input.add(ResourcePoolEntry.create(resourcePath, bytes));
}
ModulePool output = new ModulePoolImpl();
ResourcePoolManager output = new ResourcePoolManager();
ResourceVisitor visitor = new ResourceVisitor();
input.transformAndCopy(visitor, output);
input.resourcePool().transformAndCopy(visitor, output.resourcePoolBuilder());
if (visitor.getAmountBefore() == 0) {
throw new AssertionError("Resources not found");
}
if (visitor.getAmountBefore() != input.getEntryCount()) {
if (visitor.getAmountBefore() != input.entryCount()) {
throw new AssertionError("Number of visited resources. Expected: " +
visitor.getAmountBefore() + ", got: " + input.getEntryCount());
visitor.getAmountBefore() + ", got: " + input.entryCount());
}
if (visitor.getAmountAfter() != output.getEntryCount()) {
if (visitor.getAmountAfter() != output.entryCount()) {
throw new AssertionError("Number of added resources. Expected: " +
visitor.getAmountAfter() + ", got: " + output.getEntryCount());
visitor.getAmountAfter() + ", got: " + output.entryCount());
}
output.entries().forEach(outResource -> {
String path = outResource.getPath().replaceAll(SUFFIX + "$", "");
String path = outResource.path().replaceAll(SUFFIX + "$", "");
if (!input.findEntry(path).isPresent()) {
throw new AssertionError("Unknown resource: " + path);
}
});
}
private static class ResourceVisitor implements Function<ModuleEntry, ModuleEntry> {
private static class ResourceVisitor implements Function<ResourcePoolEntry, ResourcePoolEntry> {
private int amountBefore;
private int amountAfter;
@Override
public ModuleEntry apply(ModuleEntry resource) {
public ResourcePoolEntry apply(ResourcePoolEntry resource) {
int index = ++amountBefore % 3;
switch (index) {
case 0:
++amountAfter;
return ModuleEntry.create(resource.getPath() + SUFFIX,
resource.getType(), resource.getBytes());
return ResourcePoolEntry.create(resource.path() + SUFFIX,
resource.type(), resource.contentBytes());
case 1:
++amountAfter;
return resource.create(resource.getBytes());
return resource.copyWithContent(resource.contentBytes());
}
return null;
}
@ -129,17 +129,17 @@ public class ResourcePoolTest {
samples.add("javax/management/ObjectName");
test(samples, (resources, module, path) -> {
try {
resources.add(ModuleEntry.create(path, new byte[0]));
resources.add(ResourcePoolEntry.create(path, new byte[0]));
} catch (Exception ex) {
throw new RuntimeException(ex);
}
});
test(samples, (resources, module, path) -> {
try {
resources.add(ModulePoolImpl.
newCompressedResource(ModuleEntry.create(path, new byte[0]),
resources.add(ResourcePoolManager.
newCompressedResource(ResourcePoolEntry.create(path, new byte[0]),
ByteBuffer.allocate(99), "bitcruncher", null,
((ModulePoolImpl)resources).getStringTable(), ByteOrder.nativeOrder()));
((ResourcePoolManager)resources).getStringTable(), ByteOrder.nativeOrder()));
} catch (Exception ex) {
throw new RuntimeException(ex);
}
@ -150,7 +150,7 @@ public class ResourcePoolTest {
if (samples.isEmpty()) {
throw new AssertionError("No sample to test");
}
ModulePool resources = new ModulePoolImpl();
ResourcePoolManager resources = new ResourcePoolManager();
Set<String> modules = new HashSet<>();
for (int i = 0; i < samples.size(); i++) {
String module = samples.get(i);
@ -165,68 +165,68 @@ public class ResourcePoolTest {
i++;
String clazz = samples.get(i);
String path = "/" + module + "/" + clazz + ".class";
Optional<ModuleEntry> res = resources.findEntry(path);
Optional<ResourcePoolEntry> res = resources.findEntry(path);
if (!res.isPresent()) {
throw new AssertionError("Resource not found " + path);
}
checkModule(resources, res.get());
checkModule(resources.resourcePool(), res.get());
if (resources.findEntry(clazz).isPresent()) {
throw new AssertionError("Resource found " + clazz);
}
}
if (resources.getEntryCount() != samples.size() / 2) {
if (resources.entryCount() != samples.size() / 2) {
throw new AssertionError("Invalid number of resources");
}
}
private void checkModule(ModulePool resources, ModuleEntry res) {
Optional<LinkModule> optMod = resources.findModule(res.getModule());
private void checkModule(ResourcePool resources, ResourcePoolEntry res) {
Optional<ResourcePoolModule> optMod = resources.moduleView().findModule(res.moduleName());
if (!optMod.isPresent()) {
throw new AssertionError("No module " + res.getModule());
throw new AssertionError("No module " + res.moduleName());
}
LinkModule m = optMod.get();
if (!m.getName().equals(res.getModule())) {
throw new AssertionError("Not right module name " + res.getModule());
ResourcePoolModule m = optMod.get();
if (!m.name().equals(res.moduleName())) {
throw new AssertionError("Not right module name " + res.moduleName());
}
if (!m.findEntry(res.getPath()).isPresent()) {
throw new AssertionError("resource " + res.getPath()
+ " not in module " + m.getName());
if (!m.findEntry(res.path()).isPresent()) {
throw new AssertionError("resource " + res.path()
+ " not in module " + m.name());
}
}
private void checkResourcesAfterCompression() throws Exception {
ModulePoolImpl resources1 = new ModulePoolImpl();
ModuleEntry res1 = ModuleEntry.create("/module1/toto1", new byte[0]);
ModuleEntry res2 = ModuleEntry.create("/module2/toto1", new byte[0]);
ResourcePoolManager resources1 = new ResourcePoolManager();
ResourcePoolEntry res1 = ResourcePoolEntry.create("/module1/toto1", new byte[0]);
ResourcePoolEntry res2 = ResourcePoolEntry.create("/module2/toto1", new byte[0]);
resources1.add(res1);
resources1.add(res2);
checkResources(resources1, res1, res2);
ModulePool resources2 = new ModulePoolImpl();
ModuleEntry res3 = ModuleEntry.create("/module2/toto1", new byte[7]);
ResourcePoolManager resources2 = new ResourcePoolManager();
ResourcePoolEntry res3 = ResourcePoolEntry.create("/module2/toto1", new byte[7]);
resources2.add(res3);
resources2.add(ModulePoolImpl.newCompressedResource(res1,
resources2.add(ResourcePoolManager.newCompressedResource(res1,
ByteBuffer.allocate(7), "zip", null, resources1.getStringTable(),
ByteOrder.nativeOrder()));
checkResources(resources2, res1, res2);
}
private void checkResources(ModulePool resources, ModuleEntry... expected) {
private void checkResources(ResourcePoolManager resources, ResourcePoolEntry... expected) {
List<String> modules = new ArrayList();
resources.modules().forEach(m -> {
modules.add(m.getName());
modules.add(m.name());
});
for (ModuleEntry res : expected) {
for (ResourcePoolEntry res : expected) {
if (!resources.contains(res)) {
throw new AssertionError("Resource not found: " + res);
}
if (!resources.findEntry(res.getPath()).isPresent()) {
if (!resources.findEntry(res.path()).isPresent()) {
throw new AssertionError("Resource not found: " + res);
}
if (!modules.contains(res.getModule())) {
throw new AssertionError("Module not found: " + res.getModule());
if (!modules.contains(res.moduleName())) {
throw new AssertionError("Module not found: " + res.moduleName());
}
if (!resources.contains(res)) {
@ -241,20 +241,15 @@ public class ResourcePoolTest {
}
}
if (resources.isReadOnly()) {
throw new AssertionError("ReadOnly resources");
}
((ModulePoolImpl) resources).setReadOnly();
try {
resources.add(ModuleEntry.create("/module2/toto1", new byte[0]));
throw new AssertionError("ModulePool is read-only, but an exception is not thrown");
resources.add(ResourcePoolEntry.create("/module2/toto1", new byte[0]));
throw new AssertionError("ResourcePool is read-only, but an exception is not thrown");
} catch (Exception ex) {
// Expected
}
}
interface ResourceAdder {
void add(ModulePool resources, String module, String path);
void add(ResourcePoolManager resources, String module, String path);
}
}

@ -25,8 +25,9 @@ package plugin;
import java.util.Collections;
import java.util.Map;
import java.util.function.Function;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.ResourcePoolEntry;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
import jdk.tools.jlink.plugin.Plugin;
public class CustomPlugin implements Plugin {
@ -37,8 +38,9 @@ public class CustomPlugin implements Plugin {
}
@Override
public void visit(ModulePool in, ModulePool out) {
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
in.transformAndCopy(Function.identity(), out);
return out.build();
}
@Override

@ -27,8 +27,9 @@ import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.Collections;
import java.util.Map;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.ResourcePoolEntry;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
import jdk.tools.jlink.plugin.Plugin;
/**
@ -47,7 +48,7 @@ public final class HelloPlugin implements Plugin {
}
@Override
public void visit(ModulePool inResources, ModulePool outResources) {
public ResourcePool transform(ResourcePool inResources, ResourcePoolBuilder outResources) {
try {
System.out.println("Hello!!!!!!!!!!");
File f = new File(OUTPUT_FILE);
@ -58,6 +59,7 @@ public final class HelloPlugin implements Plugin {
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
return outResources.build();
}
@Override

@ -53,14 +53,15 @@ import jdk.internal.jimage.decompressor.ResourceDecompressor;
import jdk.internal.jimage.decompressor.ResourceDecompressorFactory;
import jdk.internal.jimage.decompressor.StringSharingDecompressorFactory;
import jdk.internal.jimage.decompressor.ZipDecompressorFactory;
import jdk.tools.jlink.internal.ModulePoolImpl;
import jdk.tools.jlink.internal.ResourcePoolManager;
import jdk.tools.jlink.internal.StringTable;
import jdk.tools.jlink.internal.plugins.DefaultCompressPlugin;
import jdk.tools.jlink.internal.plugins.StringSharingPlugin;
import jdk.tools.jlink.internal.plugins.ZipPlugin;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
import jdk.tools.jlink.plugin.ResourcePoolEntry;
public class CompressorPluginTest {
@ -85,7 +86,7 @@ public class CompressorPluginTest {
new ZipDecompressorFactory()
});
ModulePool classes = gatherClasses(javabase);
ResourcePool classes = gatherClasses(javabase);
// compress = String sharing
checkCompress(classes, new StringSharingPlugin(), null,
new ResourceDecompressorFactory[]{
@ -168,8 +169,8 @@ public class CompressorPluginTest {
}, Collections.singletonList(".*Exception.class"));
}
private ModulePool gatherResources(Path module) throws Exception {
ModulePool pool = new ModulePoolImpl(ByteOrder.nativeOrder(), new StringTable() {
private ResourcePool gatherResources(Path module) throws Exception {
ResourcePoolManager poolMgr = new ResourcePoolManager(ByteOrder.nativeOrder(), new StringTable() {
@Override
public int addString(String str) {
@ -181,20 +182,22 @@ public class CompressorPluginTest {
return null;
}
});
ResourcePoolBuilder poolBuilder = poolMgr.resourcePoolBuilder();
try (Stream<Path> stream = Files.walk(module)) {
for (Iterator<Path> iterator = stream.iterator(); iterator.hasNext();) {
Path p = iterator.next();
if (Files.isRegularFile(p)) {
byte[] content = Files.readAllBytes(p);
pool.add(ModuleEntry.create(p.toString(), content));
poolBuilder.add(ResourcePoolEntry.create(p.toString(), content));
}
}
}
return pool;
return poolBuilder.build();
}
private ModulePool gatherClasses(Path module) throws Exception {
ModulePool pool = new ModulePoolImpl(ByteOrder.nativeOrder(), new StringTable() {
private ResourcePool gatherClasses(Path module) throws Exception {
ResourcePoolManager poolMgr = new ResourcePoolManager(ByteOrder.nativeOrder(), new StringTable() {
@Override
public int addString(String str) {
@ -206,25 +209,27 @@ public class CompressorPluginTest {
return null;
}
});
ResourcePoolBuilder poolBuilder = poolMgr.resourcePoolBuilder();
try (Stream<Path> stream = Files.walk(module)) {
for (Iterator<Path> iterator = stream.iterator(); iterator.hasNext();) {
Path p = iterator.next();
if (Files.isRegularFile(p) && p.toString().endsWith(".class")) {
byte[] content = Files.readAllBytes(p);
pool.add(ModuleEntry.create(p.toString(), content));
poolBuilder.add(ResourcePoolEntry.create(p.toString(), content));
}
}
}
return pool;
return poolBuilder.build();
}
private void checkCompress(ModulePool resources, Plugin prov,
private void checkCompress(ResourcePool resources, Plugin prov,
Properties config,
ResourceDecompressorFactory[] factories) throws Exception {
checkCompress(resources, prov, config, factories, Collections.emptyList());
}
private void checkCompress(ModulePool resources, Plugin prov,
private void checkCompress(ResourcePool resources, Plugin prov,
Properties config,
ResourceDecompressorFactory[] factories,
List<String> includes) throws Exception {
@ -243,7 +248,7 @@ public class CompressorPluginTest {
}
prov.configure(props);
final Map<Integer, String> strings = new HashMap<>();
ModulePoolImpl inputResources = new ModulePoolImpl(ByteOrder.nativeOrder(), new StringTable() {
ResourcePoolManager inputResourcesMgr = new ResourcePoolManager(ByteOrder.nativeOrder(), new StringTable() {
@Override
public int addString(String str) {
int id = strID;
@ -257,11 +262,11 @@ public class CompressorPluginTest {
return strings.get(id);
}
});
inputResources.add(resource);
ModulePool compressedResources = applyCompressor(prov, inputResources, resource, includesPatterns);
original[0] += resource.getLength();
compressed[0] += compressedResources.findEntry(resource.getPath()).get().getLength();
applyDecompressors(factories, inputResources, compressedResources, strings, includesPatterns);
inputResourcesMgr.add(resource);
ResourcePool compressedResources = applyCompressor(prov, inputResourcesMgr, resource, includesPatterns);
original[0] += resource.contentLength();
compressed[0] += compressedResources.findEntry(resource.path()).get().contentLength();
applyDecompressors(factories, inputResourcesMgr.resourcePool(), compressedResources, strings, includesPatterns);
});
String compressors = Stream.of(factories)
.map(Object::getClass)
@ -274,16 +279,18 @@ public class CompressorPluginTest {
}
}
private ModulePool applyCompressor(Plugin plugin,
ModulePoolImpl inputResources,
ModuleEntry res,
private ResourcePool applyCompressor(Plugin plugin,
ResourcePoolManager inputResources,
ResourcePoolEntry res,
List<Pattern> includesPatterns) {
ModulePool compressedModulePool = new ModulePoolImpl(ByteOrder.nativeOrder(), inputResources.getStringTable());
plugin.visit(inputResources, compressedModulePool);
String path = res.getPath();
ModuleEntry compressed = compressedModulePool.findEntry(path).get();
ResourcePoolManager resMgr = new ResourcePoolManager(ByteOrder.nativeOrder(),
inputResources.getStringTable());
ResourcePool compressedResourcePool = plugin.transform(inputResources.resourcePool(),
resMgr.resourcePoolBuilder());
String path = res.path();
ResourcePoolEntry compressed = compressedResourcePool.findEntry(path).get();
CompressedResourceHeader header
= CompressedResourceHeader.readFromResource(ByteOrder.nativeOrder(), compressed.getBytes());
= CompressedResourceHeader.readFromResource(ByteOrder.nativeOrder(), compressed.contentBytes());
if (isIncluded(includesPatterns, path)) {
if (header == null) {
throw new AssertionError("Path should be compressed: " + path);
@ -299,23 +306,23 @@ public class CompressorPluginTest {
} else if (header != null) {
throw new AssertionError("Path should not be compressed: " + path);
}
return compressedModulePool;
return compressedResourcePool;
}
private void applyDecompressors(ResourceDecompressorFactory[] decompressors,
ModulePool inputResources,
ModulePool compressedResources,
ResourcePool inputResources,
ResourcePool compressedResources,
Map<Integer, String> strings,
List<Pattern> includesPatterns) {
compressedResources.entries().forEach(compressed -> {
CompressedResourceHeader header = CompressedResourceHeader.readFromResource(
ByteOrder.nativeOrder(), compressed.getBytes());
String path = compressed.getPath();
ModuleEntry orig = inputResources.findEntry(path).get();
ByteOrder.nativeOrder(), compressed.contentBytes());
String path = compressed.path();
ResourcePoolEntry orig = inputResources.findEntry(path).get();
if (!isIncluded(includesPatterns, path)) {
return;
}
byte[] decompressed = compressed.getBytes();
byte[] decompressed = compressed.contentBytes();
for (ResourceDecompressorFactory factory : decompressors) {
try {
ResourceDecompressor decompressor = factory.newDecompressor(new Properties());
@ -327,11 +334,11 @@ public class CompressorPluginTest {
}
}
if (decompressed.length != orig.getLength()) {
if (decompressed.length != orig.contentLength()) {
throw new AssertionError("Invalid uncompressed size "
+ header.getUncompressedSize());
}
byte[] origContent = orig.getBytes();
byte[] origContent = orig.contentBytes();
for (int i = 0; i < decompressed.length; i++) {
if (decompressed[i] != origContent[i]) {
throw new AssertionError("Decompressed and original differ at index " + i);

@ -35,11 +35,11 @@ import java.io.File;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.Map;
import jdk.tools.jlink.internal.ModulePoolImpl;
import jdk.tools.jlink.internal.ResourcePoolManager;
import jdk.tools.jlink.internal.plugins.ExcludeFilesPlugin;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolEntry;
public class ExcludeFilesPluginTest {
public static void main(String[] args) throws Exception {
@ -71,20 +71,20 @@ public class ExcludeFilesPluginTest {
prop.put(ExcludeFilesPlugin.NAME, s);
ExcludeFilesPlugin fplug = new ExcludeFilesPlugin();
fplug.configure(prop);
ModulePoolImpl files = new ModulePoolImpl();
ModulePoolImpl fresult = new ModulePoolImpl();
ModuleEntry f = ModuleEntry.create("/" + module + "/" + sample,
ModuleEntry.Type.CONFIG, new byte[0]);
ResourcePoolManager files = new ResourcePoolManager();
ResourcePoolManager fresult = new ResourcePoolManager();
ResourcePoolEntry f = ResourcePoolEntry.create("/" + module + "/" + sample,
ResourcePoolEntry.Type.CONFIG, new byte[0]);
files.add(f);
fplug.visit(files, fresult);
ResourcePool resPool = fplug.transform(files.resourcePool(), fresult.resourcePoolBuilder());
if (exclude) {
if (fresult.contains(f)) {
if (resPool.contains(f)) {
throw new Exception(sample + " should be excluded by " + s);
}
} else {
if (!fresult.contains(f)) {
if (!resPool.contains(f)) {
throw new Exception(sample + " shouldn't be excluded by " + s);
}
}

@ -34,11 +34,12 @@ import java.io.File;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.Map;
import jdk.tools.jlink.internal.ModulePoolImpl;
import jdk.tools.jlink.internal.ResourcePoolManager;
import jdk.tools.jlink.internal.plugins.ExcludePlugin;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
import jdk.tools.jlink.plugin.ResourcePoolEntry;
public class ExcludePluginTest {
@ -75,17 +76,18 @@ public class ExcludePluginTest {
prop.put(ExcludePlugin.NAME, s);
ExcludePlugin excludePlugin = new ExcludePlugin();
excludePlugin.configure(prop);
ModulePool resources = new ModulePoolImpl();
ModuleEntry resource = ModuleEntry.create(sample, new byte[0]);
resources.add(resource);
ModulePool result = new ModulePoolImpl();
excludePlugin.visit(resources, result);
ResourcePoolManager resourcesMgr = new ResourcePoolManager();
ResourcePoolEntry resource = ResourcePoolEntry.create(sample, new byte[0]);
resourcesMgr.add(resource);
ResourcePoolManager resultMgr = new ResourcePoolManager();
ResourcePool resPool = excludePlugin.transform(resourcesMgr.resourcePool(),
resultMgr.resourcePoolBuilder());
if (exclude) {
if (result.contains(resource)) {
if (resPool.contains(resource)) {
throw new AssertionError(sample + " should be excluded by " + s);
}
} else {
if (!result.contains(resource)) {
if (!resPool.contains(resource)) {
throw new AssertionError(sample + " shouldn't be excluded by " + s);
}
}

@ -32,12 +32,12 @@
import java.io.ByteArrayInputStream;
import java.util.HashMap;
import java.util.Map;
import jdk.tools.jlink.internal.ModulePoolImpl;
import jdk.tools.jlink.internal.ResourcePoolManager;
import jdk.tools.jlink.internal.plugins.ExcludeVMPlugin;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolEntry;
public class ExcludeVMPluginTest {
@ -163,14 +163,15 @@ public class ExcludeVMPluginTest {
private void doCheckVM(String vm, String[] input, String jvmcfg, String[] expectedOutput, String expectdJvmCfg) throws Exception {
// Create a pool with jvm.cfg and the input paths.
byte[] jvmcfgContent = jvmcfg.getBytes();
ModulePool pool = new ModulePoolImpl();
pool.add(ModuleEntry.create("/java.base/native/jvm.cfg",
ModuleEntry.Type.NATIVE_LIB, jvmcfgContent));
ResourcePoolManager poolMgr = new ResourcePoolManager();
poolMgr.add(
ResourcePoolEntry.create("/java.base/native/jvm.cfg",
ResourcePoolEntry.Type.NATIVE_LIB, jvmcfgContent));
for (String in : input) {
pool.add(ModuleEntry.create(in,
ModuleEntry.Type.NATIVE_LIB, new byte[0]));
poolMgr.add(ResourcePoolEntry.create(in,
ResourcePoolEntry.Type.NATIVE_LIB, new byte[0]));
}
ModulePool out = new ModulePoolImpl();
ResourcePoolManager outMgr = new ResourcePoolManager();
Plugin p = new ExcludeVMPlugin();
Map<String, String> config = new HashMap<>();
@ -178,34 +179,34 @@ public class ExcludeVMPluginTest {
config.put(ExcludeVMPlugin.NAME, vm);
}
p.configure(config);
p.visit(pool, out);
ResourcePool out = p.transform(poolMgr.resourcePool(), outMgr.resourcePoolBuilder());
String newContent = new String(out.findEntry("/java.base/native/jvm.cfg").get().stream().readAllBytes());
String newContent = new String(out.findEntry("/java.base/native/jvm.cfg").get().contentBytes());
if (!expectdJvmCfg.equals(newContent)) {
throw new Exception("Got content " + newContent + " expected " + expectdJvmCfg);
}
if (out.getEntryCount() != (expectedOutput.length + 1)) {
if (out.entryCount() != (expectedOutput.length + 1)) {
out.entries().forEach(m -> {
System.err.println(m.getPath());
System.err.println(m.path());
});
throw new Exception("Invalid output size " + out.getEntryCount() + " expected " + (expectedOutput.length + 1));
throw new Exception("Invalid output size " + out.entryCount() + " expected " + (expectedOutput.length + 1));
}
out.entries().forEach(md -> {
if (md.getPath().equals("/java.base/native/jvm.cfg")) {
if (md.path().equals("/java.base/native/jvm.cfg")) {
return;
}
boolean contained = false;
for (String o : expectedOutput) {
if (md.getPath().equals(o)) {
if (md.path().equals(o)) {
contained = true;
break;
}
}
if (!contained) {
throw new RuntimeException(md.getPath() + " not expected");
throw new RuntimeException(md.path() + " not expected");
}
});

@ -37,12 +37,12 @@ import java.nio.file.Path;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import jdk.tools.jlink.internal.ModulePoolImpl;
import jdk.tools.jlink.internal.ResourcePoolManager;
import jdk.tools.jlink.builder.DefaultImageBuilder;
import jdk.tools.jlink.internal.plugins.FileCopierPlugin;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.ResourcePoolEntry;
import jdk.tools.jlink.plugin.ResourcePool;
public class FileCopierPluginTest {
@ -85,18 +85,20 @@ public class FileCopierPluginTest {
Map<String, String> conf = new HashMap<>();
conf.put(FileCopierPlugin.NAME, builder.toString());
plug.configure(conf);
ModulePool pool = new ModulePoolImpl();
plug.visit(new ModulePoolImpl(), pool);
if (pool.getEntryCount() != expected) {
ResourcePoolManager poolMgr = new ResourcePoolManager();
ResourcePool pool = plug.transform(
new ResourcePoolManager().resourcePool(),
poolMgr.resourcePoolBuilder());
if (pool.entryCount() != expected) {
throw new AssertionError("Wrong number of added files");
}
pool.entries().forEach(f -> {
if (!f.getType().equals(ModuleEntry.Type.OTHER)) {
throw new AssertionError("Invalid type " + f.getType()
+ " for file " + f.getPath());
if (!f.type().equals(ResourcePoolEntry.Type.OTHER)) {
throw new AssertionError("Invalid type " + f.type()
+ " for file " + f.path());
}
if (f.stream() == null) {
throw new AssertionError("Null stream for file " + f.getPath());
if (f.content() == null) {
throw new AssertionError("Null stream for file " + f.path());
}
});
Path root = new File(".").toPath();

@ -39,12 +39,13 @@ import java.util.Map;
import jdk.tools.jlink.internal.ImagePluginConfiguration;
import jdk.tools.jlink.internal.PluginRepository;
import jdk.tools.jlink.internal.ImagePluginStack;
import jdk.tools.jlink.internal.ModulePoolImpl;
import jdk.tools.jlink.internal.ResourcePoolManager;
import jdk.tools.jlink.Jlink;
import jdk.tools.jlink.Jlink.PluginsConfiguration;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
import jdk.tools.jlink.plugin.ResourcePoolEntry;
public class LastSorterTest {
@ -78,7 +79,7 @@ public class LastSorterTest {
ImagePluginStack stack = ImagePluginConfiguration.parseConfiguration(config);
// check order
ModulePoolImpl res = fillOutResourceModulePool();
ResourcePoolManager res = fillOutResourceResourcePool();
try {
stack.visitResources(res);
@ -89,18 +90,18 @@ public class LastSorterTest {
}
}
private ModulePoolImpl fillOutResourceModulePool() throws Exception {
ModulePoolImpl res = new ModulePoolImpl();
res.add(ModuleEntry.create("/eee/bbb/res1.class", new byte[90]));
res.add(ModuleEntry.create("/aaaa/bbb/res2.class", new byte[90]));
res.add(ModuleEntry.create("/bbb/aa/res1.class", new byte[90]));
res.add(ModuleEntry.create("/aaaa/bbb/res3.class", new byte[90]));
res.add(ModuleEntry.create("/bbb/aa/res2.class", new byte[90]));
res.add(ModuleEntry.create("/fff/bbb/res1.class", new byte[90]));
res.add(ModuleEntry.create("/aaaa/bbb/res1.class", new byte[90]));
res.add(ModuleEntry.create("/bbb/aa/res3.class", new byte[90]));
res.add(ModuleEntry.create("/ccc/bbb/res1.class", new byte[90]));
res.add(ModuleEntry.create("/ddd/bbb/res1.class", new byte[90]));
private ResourcePoolManager fillOutResourceResourcePool() throws Exception {
ResourcePoolManager res = new ResourcePoolManager();
res.add(ResourcePoolEntry.create("/eee/bbb/res1.class", new byte[90]));
res.add(ResourcePoolEntry.create("/aaaa/bbb/res2.class", new byte[90]));
res.add(ResourcePoolEntry.create("/bbb/aa/res1.class", new byte[90]));
res.add(ResourcePoolEntry.create("/aaaa/bbb/res3.class", new byte[90]));
res.add(ResourcePoolEntry.create("/bbb/aa/res2.class", new byte[90]));
res.add(ResourcePoolEntry.create("/fff/bbb/res1.class", new byte[90]));
res.add(ResourcePoolEntry.create("/aaaa/bbb/res1.class", new byte[90]));
res.add(ResourcePoolEntry.create("/bbb/aa/res3.class", new byte[90]));
res.add(ResourcePoolEntry.create("/ccc/bbb/res1.class", new byte[90]));
res.add(ResourcePoolEntry.create("/ddd/bbb/res1.class", new byte[90]));
return res;
}
@ -122,7 +123,7 @@ public class LastSorterTest {
ImagePluginStack stack = ImagePluginConfiguration.parseConfiguration(config);
// check order
ModulePoolImpl res = fillOutResourceModulePool();
ResourcePoolManager res = fillOutResourceResourcePool();
stack.visitResources(res);
}
@ -157,7 +158,7 @@ public class LastSorterTest {
ImagePluginStack stack = ImagePluginConfiguration.parseConfiguration(config);
// check order
ModulePoolImpl res = fillOutResourceModulePool();
ResourcePoolManager res = fillOutResourceResourcePool();
try {
stack.visitResources(res);
throw new AssertionError("Order was changed after the last sorter, but no exception occurred");
@ -176,19 +177,21 @@ public class LastSorterTest {
}
@Override
public void visit(ModulePool resources, ModulePool output) {
List<ModuleEntry> paths = new ArrayList<>();
public ResourcePool transform(ResourcePool resources, ResourcePoolBuilder output) {
List<ResourcePoolEntry> paths = new ArrayList<>();
resources.entries().forEach(res -> {
if (res.getPath().startsWith(starts)) {
if (res.path().startsWith(starts)) {
paths.add(0, res);
} else {
paths.add(res);
}
});
for (ModuleEntry r : paths) {
for (ResourcePoolEntry r : paths) {
output.add(r);
}
return output.build();
}
@Override

@ -1,145 +0,0 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @summary Test sorter plugin
* @author Jean-Francois Denise
* @modules jdk.jlink/jdk.tools.jlink.internal
* jdk.jlink/jdk.tools.jlink.internal.plugins
* @run main OrderResourcesPluginTest
*/
import java.io.File;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
import jdk.tools.jlink.internal.ModulePoolImpl;
import jdk.tools.jlink.internal.plugins.OrderResourcesPlugin;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.Plugin;
public class OrderResourcesPluginTest {
public static void main(String[] args) throws Exception {
new OrderResourcesPluginTest().test();
}
public void test() throws Exception {
ModuleEntry[] array = {
ModuleEntry.create("/module1/toto1.class", new byte[0]),
ModuleEntry.create("/module2/toto2.class", new byte[0]),
ModuleEntry.create("/module3/toto3.class", new byte[0]),
ModuleEntry.create("/module3/toto3/module-info.class", new byte[0]),
ModuleEntry.create("/zazou/toto.class", new byte[0]),
ModuleEntry.create("/module4/zazou.class", new byte[0]),
ModuleEntry.create("/module5/toto5.class", new byte[0]),
ModuleEntry.create("/module6/toto6/module-info.class", new byte[0])
};
ModuleEntry[] sorted = {
ModuleEntry.create("/zazou/toto.class", new byte[0]),
ModuleEntry.create("/module3/toto3/module-info.class", new byte[0]),
ModuleEntry.create("/module6/toto6/module-info.class", new byte[0]),
ModuleEntry.create("/module1/toto1.class", new byte[0]),
ModuleEntry.create("/module2/toto2.class", new byte[0]),
ModuleEntry.create("/module3/toto3.class", new byte[0]),
ModuleEntry.create("/module4/zazou.class", new byte[0]),
ModuleEntry.create("/module5/toto5.class", new byte[0])
};
ModuleEntry[] sorted2 = {
ModuleEntry.create("/module5/toto5.class", new byte[0]),
ModuleEntry.create("/module6/toto6/module-info.class", new byte[0]),
ModuleEntry.create("/module4/zazou.class", new byte[0]),
ModuleEntry.create("/module3/toto3.class", new byte[0]),
ModuleEntry.create("/module3/toto3/module-info.class", new byte[0]),
ModuleEntry.create("/module1/toto1.class", new byte[0]),
ModuleEntry.create("/module2/toto2.class", new byte[0]),
ModuleEntry.create("/zazou/toto.class", new byte[0])
};
ModulePool resources = new ModulePoolImpl();
for (ModuleEntry r : array) {
resources.add(r);
}
{
ModulePool out = new ModulePoolImpl();
Map<String, String> config = new HashMap<>();
config.put(OrderResourcesPlugin.NAME, "/zazou/**,**/module-info.class");
Plugin p = new OrderResourcesPlugin();
p.configure(config);
p.visit(resources, out);
check(out.entries().collect(Collectors.toList()), sorted);
}
{
// Order of resources in the file, then un-ordered resources.
File order = new File("resources.order");
order.createNewFile();
StringBuilder builder = new StringBuilder();
// 5 first resources come from file
for (int i = 0; i < 5; i++) {
String path = sorted2[i].getPath();
int index = path.indexOf('/', 1);
path = path.substring(index + 1, path.length() - ".class".length());
builder.append(path).append("\n");
}
Files.write(order.toPath(), builder.toString().getBytes());
ModulePool out = new ModulePoolImpl();
Map<String, String> config = new HashMap<>();
config.put(OrderResourcesPlugin.NAME, "@" + order.getAbsolutePath());
Plugin p = new OrderResourcesPlugin();
p.configure(config);
p.visit(resources, out);
check(out.entries().collect(Collectors.toList()), sorted2);
}
}
private void check(Collection<ModuleEntry> outResources,
ModuleEntry[] sorted) {
if (outResources.size() != sorted.length) {
throw new AssertionError("Wrong number of resources:\n"
+ "expected: " + Arrays.toString(sorted) + ",\n"
+ " got: " + outResources);
}
int i = 0;
for (ModuleEntry r : outResources) {
System.err.println("Resource: " + r);
if (!sorted[i].getPath().equals(r.getPath())) {
throw new AssertionError("Resource not properly sorted, difference at: " + i + "\n"
+ "expected: " + Arrays.toString(sorted) + ",\n"
+ " got: " + outResources);
}
i++;
}
}
}

@ -38,12 +38,13 @@ import java.util.Map;
import jdk.tools.jlink.internal.ImagePluginConfiguration;
import jdk.tools.jlink.internal.PluginRepository;
import jdk.tools.jlink.internal.ImagePluginStack;
import jdk.tools.jlink.internal.ModulePoolImpl;
import jdk.tools.jlink.internal.ResourcePoolManager;
import jdk.tools.jlink.Jlink;
import jdk.tools.jlink.Jlink.PluginsConfiguration;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
import jdk.tools.jlink.plugin.ResourcePoolEntry;
public class PluginsNegativeTest {
@ -95,8 +96,8 @@ public class PluginsNegativeTest {
plugins.add(createPlugin("plugin"));
ImagePluginStack stack = ImagePluginConfiguration.parseConfiguration(new PluginsConfiguration(plugins,
null, null));
ModulePoolImpl inResources = new ModulePoolImpl();
inResources.add(ModuleEntry.create("/aaa/bbb/A", new byte[10]));
ResourcePoolManager inResources = new ResourcePoolManager();
inResources.add(ResourcePoolEntry.create("/aaa/bbb/A", new byte[10]));
try {
stack.visitResources(inResources);
throw new AssertionError("Exception expected when output resource is empty");
@ -109,8 +110,8 @@ public class PluginsNegativeTest {
plugins.add(createPlugin("plugin"));
ImagePluginStack stack = ImagePluginConfiguration.parseConfiguration(new PluginsConfiguration(plugins,
null, null));
ModulePoolImpl inResources = new ModulePoolImpl();
ModulePoolImpl outResources = (ModulePoolImpl) stack.visitResources(inResources);
ResourcePoolManager inResources = new ResourcePoolManager();
ResourcePool outResources = stack.visitResources(inResources);
if (!outResources.isEmpty()) {
throw new AssertionError("Output resource is not empty");
}
@ -125,8 +126,9 @@ public class PluginsNegativeTest {
}
@Override
public void visit(ModulePool inResources, ModulePool outResources) {
// do nothing
public ResourcePool transform(ResourcePool inResources, ResourcePoolBuilder outResources) {
// don't add anything to the builder
return outResources.build();
}
@Override

@ -42,13 +42,15 @@ import java.util.stream.Collectors;
import jdk.tools.jlink.internal.ImagePluginConfiguration;
import jdk.tools.jlink.internal.PluginRepository;
import jdk.tools.jlink.internal.ImagePluginStack;
import jdk.tools.jlink.internal.ModulePoolImpl;
import jdk.tools.jlink.internal.ResourcePoolManager;
import jdk.tools.jlink.internal.ResourcePoolManager.ResourcePoolImpl;
import jdk.tools.jlink.internal.ResourcePrevisitor;
import jdk.tools.jlink.internal.StringTable;
import jdk.tools.jlink.Jlink;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
import jdk.tools.jlink.plugin.ResourcePoolEntry;
public class PrevisitorTest {
@ -67,13 +69,13 @@ public class PrevisitorTest {
plugins.add(createPlugin(CustomPlugin.NAME));
ImagePluginStack stack = ImagePluginConfiguration.parseConfiguration(new Jlink.PluginsConfiguration(plugins,
null, null));
ModulePoolImpl inResources = new ModulePoolImpl(ByteOrder.nativeOrder(), new CustomStringTable());
inResources.add(ModuleEntry.create("/aaa/bbb/res1.class", new byte[90]));
inResources.add(ModuleEntry.create("/aaa/bbb/res2.class", new byte[90]));
inResources.add(ModuleEntry.create("/aaa/bbb/res3.class", new byte[90]));
inResources.add(ModuleEntry.create("/aaa/ddd/res1.class", new byte[90]));
inResources.add(ModuleEntry.create("/aaa/res1.class", new byte[90]));
ModulePool outResources = stack.visitResources(inResources);
ResourcePoolManager inResources = new ResourcePoolManager(ByteOrder.nativeOrder(), new CustomStringTable());
inResources.add(ResourcePoolEntry.create("/aaa/bbb/res1.class", new byte[90]));
inResources.add(ResourcePoolEntry.create("/aaa/bbb/res2.class", new byte[90]));
inResources.add(ResourcePoolEntry.create("/aaa/bbb/res3.class", new byte[90]));
inResources.add(ResourcePoolEntry.create("/aaa/ddd/res1.class", new byte[90]));
inResources.add(ResourcePoolEntry.create("/aaa/res1.class", new byte[90]));
ResourcePool outResources = stack.visitResources(inResources);
Collection<String> input = inResources.entries()
.map(Object::toString)
.collect(Collectors.toList());
@ -113,19 +115,18 @@ public class PrevisitorTest {
private boolean isPrevisitCalled = false;
@Override
public void visit(ModulePool inResources, ModulePool outResources) {
public ResourcePool transform(ResourcePool inResources, ResourcePoolBuilder outResources) {
if (!isPrevisitCalled) {
throw new AssertionError("Previsit was not called");
}
CustomStringTable table = (CustomStringTable)
((ModulePoolImpl) inResources).getStringTable();
CustomStringTable table = (CustomStringTable)((ResourcePoolImpl)inResources).getStringTable();
if (table.size() == 0) {
throw new AssertionError("Table is empty");
}
Map<String, Integer> count = new HashMap<>();
for (int i = 0; i < table.size(); ++i) {
String s = table.getString(i);
Optional<ModuleEntry> e = inResources.findEntry(s);
Optional<ResourcePoolEntry> e = inResources.findEntry(s);
if (e.isPresent()) {
throw new AssertionError();
}
@ -139,6 +140,8 @@ public class PrevisitorTest {
inResources.entries().forEach(r -> {
outResources.add(r);
});
return outResources.build();
}
@Override
@ -147,10 +150,10 @@ public class PrevisitorTest {
}
@Override
public void previsit(ModulePool resources, StringTable strings) {
public void previsit(ResourcePool resources, StringTable strings) {
isPrevisitCalled = true;
resources.entries().forEach(r -> {
String s = r.getPath();
String s = r.path();
int lastIndexOf = s.lastIndexOf('/');
if (lastIndexOf >= 0) {
strings.addString(s.substring(0, lastIndexOf));

@ -52,11 +52,11 @@ import java.util.function.Consumer;
import jdk.internal.jimage.decompressor.CompressedResourceHeader;
import jdk.internal.jimage.decompressor.StringSharingDecompressor;
import jdk.tools.jlink.internal.ModulePoolImpl;
import jdk.tools.jlink.internal.ResourcePoolManager;
import jdk.tools.jlink.internal.StringTable;
import jdk.tools.jlink.internal.plugins.StringSharingPlugin;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.ResourcePoolEntry;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.Plugin;
import tests.Helper;
import tests.JImageValidator;
@ -80,7 +80,7 @@ public class StringSharingPluginTest {
Map<String, Integer> map = new HashMap<>();
Map<Integer, String> reversedMap = new HashMap<>();
ModulePoolImpl resources = new ModulePoolImpl(ByteOrder.nativeOrder(), new StringTable() {
ResourcePoolManager resources = new ResourcePoolManager(ByteOrder.nativeOrder(), new StringTable() {
@Override
public int addString(String str) {
Integer id = map.get(str);
@ -109,7 +109,7 @@ public class StringSharingPluginTest {
if (path.charAt(0) != '/') {
path = "/" + path;
}
ModuleEntry res = ModuleEntry.create(path, content);
ResourcePoolEntry res = ResourcePoolEntry.create(path, content);
resources.add(res);
} catch (Exception ex) {
throw new RuntimeException(ex);
@ -120,17 +120,17 @@ public class StringSharingPluginTest {
stream.forEach(c);
}
Plugin plugin = new StringSharingPlugin();
ModulePoolImpl result = new ModulePoolImpl(resources.getByteOrder(), resources.getStringTable());
plugin.visit(resources, result);
ResourcePoolManager resultMgr = new ResourcePoolManager(resources.byteOrder(), resources.getStringTable());
ResourcePool result = plugin.transform(resources.resourcePool(), resultMgr.resourcePoolBuilder());
if (result.isEmpty()) {
throw new AssertionError("No result");
}
result.entries().forEach(res -> {
if (res.getPath().endsWith(".class")) {
if (res.path().endsWith(".class")) {
try {
byte[] uncompacted = StringSharingDecompressor.normalize(reversedMap::get, res.getBytes(),
byte[] uncompacted = StringSharingDecompressor.normalize(reversedMap::get, res.contentBytes(),
CompressedResourceHeader.getSize());
JImageValidator.readClass(uncompacted);
} catch (IOException exp) {

@ -54,10 +54,10 @@ import com.sun.tools.classfile.ConstantPoolException;
import com.sun.tools.classfile.Method;
import java.util.HashMap;
import java.util.Map;
import jdk.tools.jlink.internal.ModulePoolImpl;
import jdk.tools.jlink.internal.ResourcePoolManager;
import jdk.tools.jlink.internal.plugins.StripDebugPlugin;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.ResourcePoolEntry;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.Plugin;
import tests.Helper;
@ -106,36 +106,38 @@ public class StripDebugPluginTest {
path = path.replace('\\', '/');
StripDebugPlugin debug = new StripDebugPlugin();
debug.configure(new HashMap<>());
ModuleEntry result1 = stripDebug(debug, ModuleEntry.create(path,content), path, infoPath, moduleInfo);
ResourcePoolEntry result1 = stripDebug(debug, ResourcePoolEntry.create(path,content), path, infoPath, moduleInfo);
if (!path.endsWith("module-info.class")) {
if (result1.getLength() >= content.length) {
if (result1.contentLength() >= content.length) {
throw new AssertionError("Class size not reduced, debug info not "
+ "removed for " + path);
}
checkDebugAttributes(result1.getBytes());
checkDebugAttributes(result1.contentBytes());
}
ModuleEntry result2 = stripDebug(debug, result1, path, infoPath, moduleInfo);
if (result1.getLength() != result2.getLength()) {
ResourcePoolEntry result2 = stripDebug(debug, result1, path, infoPath, moduleInfo);
if (result1.contentLength() != result2.contentLength()) {
throw new AssertionError("removing debug info twice reduces class size of "
+ path);
}
checkDebugAttributes(result1.getBytes());
checkDebugAttributes(result1.contentBytes());
}
private ModuleEntry stripDebug(Plugin debug, ModuleEntry classResource,
private ResourcePoolEntry stripDebug(Plugin debug, ResourcePoolEntry classResource,
String path, String infoPath, byte[] moduleInfo) throws Exception {
ModulePool resources = new ModulePoolImpl();
ResourcePoolManager resources = new ResourcePoolManager();
resources.add(classResource);
if (!path.endsWith("module-info.class")) {
ModuleEntry res2 = ModuleEntry.create(infoPath, moduleInfo);
ResourcePoolEntry res2 = ResourcePoolEntry.create(infoPath, moduleInfo);
resources.add(res2);
}
ModulePool results = new ModulePoolImpl();
debug.visit(resources, results);
System.out.println(classResource.getPath());
return results.findEntry(classResource.getPath()).get();
ResourcePoolManager results = new ResourcePoolManager();
ResourcePool resPool = debug.transform(resources.resourcePool(),
results.resourcePoolBuilder());
System.out.println(classResource.path());
return resPool.findEntry(classResource.path()).get();
}
private void checkDebugAttributes(byte[] strippedClassFile) throws IOException, ConstantPoolException {