rangeSet;
+
+ private static final long serialVersionUID = -8022764705923730308L;
+
/** Identifies the Latin-1 (European) and extended range, and
* Latin-1 (European) decimal base.
*/
@@ -105,9 +379,8 @@ public final class NumericShaper implements java.io.Serializable {
/** Identifies the ORIYA range and decimal base. */
public static final int ORIYA = 1<<7;
- /** Identifies the TAMIL range and decimal base. Tamil does not have a
- * decimal digit 0 so Latin-1 (European) 0 is used.
- */
+ /** Identifies the TAMIL range and decimal base. */
+ // TAMIL DIGIT ZERO was added in Unicode 4.1
public static final int TAMIL = 1<<8;
/** Identifies the TELUGU range and decimal base. */
@@ -140,7 +413,12 @@ public final class NumericShaper implements java.io.Serializable {
/** Identifies the MONGOLIAN range and decimal base. */
public static final int MONGOLIAN = 1<<18;
- /** Identifies all ranges, for full contextual shaping. */
+ /** Identifies all ranges, for full contextual shaping.
+ *
+ * This constant specifies all of the bit mask-based
+ * ranges. Use {@code EmunSet.allOf(NumericShaper.Range.class)} to
+ * specify all of the enum-based ranges.
+ */
public static final int ALL_RANGES = 0x0007ffff;
private static final int EUROPEAN_KEY = 0;
@@ -163,42 +441,20 @@ public final class NumericShaper implements java.io.Serializable {
private static final int KHMER_KEY = 17;
private static final int MONGOLIAN_KEY = 18;
- private static final int NUM_KEYS = 19;
-
- private static final String[] keyNames = {
- "EUROPEAN",
- "ARABIC",
- "EASTERN_ARABIC",
- "DEVANAGARI",
- "BENGALI",
- "GURMUKHI",
- "GUJARATI",
- "ORIYA",
- "TAMIL",
- "TELUGU",
- "KANNADA",
- "MALAYALAM",
- "THAI",
- "LAO",
- "TIBETAN",
- "MYANMAR",
- "ETHIOPIC",
- "KHMER",
- "MONGOLIAN"
- };
+ private static final int NUM_KEYS = MONGOLIAN_KEY + 1; // fixed
private static final int CONTEXTUAL_MASK = 1<<31;
private static final char[] bases = {
'\u0030' - '\u0030', // EUROPEAN
- '\u0660' - '\u0030', // ARABIC
- '\u06f0' - '\u0030', // EASTERN_ARABIC
+ '\u0660' - '\u0030', // ARABIC-INDIC
+ '\u06f0' - '\u0030', // EXTENDED ARABIC-INDIC (EASTERN_ARABIC)
'\u0966' - '\u0030', // DEVANAGARI
'\u09e6' - '\u0030', // BENGALI
'\u0a66' - '\u0030', // GURMUKHI
'\u0ae6' - '\u0030', // GUJARATI
'\u0b66' - '\u0030', // ORIYA
- '\u0be7' - '\u0030', // TAMIL - note missing zero
+ '\u0be6' - '\u0030', // TAMIL - zero was added in Unicode 4.1
'\u0c66' - '\u0030', // TELUGU
'\u0ce6' - '\u0030', // KANNADA
'\u0d66' - '\u0030', // MALAYALAM
@@ -206,7 +462,7 @@ public final class NumericShaper implements java.io.Serializable {
'\u0ed0' - '\u0030', // LAO
'\u0f20' - '\u0030', // TIBETAN
'\u1040' - '\u0030', // MYANMAR
- '\u1369' - '\u0030', // ETHIOPIC
+ '\u1369' - '\u0031', // ETHIOPIC - no zero
'\u17e0' - '\u0030', // KHMER
'\u1810' - '\u0030', // MONGOLIAN
};
@@ -215,14 +471,14 @@ public final class NumericShaper implements java.io.Serializable {
private static final char[] contexts = {
'\u0000', '\u0300', // 'EUROPEAN' (really latin-1 and extended)
- '\u0600', '\u0700', // ARABIC
- '\u0600', '\u0700', // EASTERN_ARABIC -- note overlap with arabic
+ '\u0600', '\u0780', // ARABIC
+ '\u0600', '\u0780', // EASTERN_ARABIC -- note overlap with arabic
'\u0900', '\u0980', // DEVANAGARI
'\u0980', '\u0a00', // BENGALI
'\u0a00', '\u0a80', // GURMUKHI
'\u0a80', '\u0b00', // GUJARATI
'\u0b00', '\u0b80', // ORIYA
- '\u0b80', '\u0c00', // TAMIL - note missing zero
+ '\u0b80', '\u0c00', // TAMIL
'\u0c00', '\u0c80', // TELUGU
'\u0c80', '\u0d00', // KANNADA
'\u0d00', '\u0d80', // MALAYALAM
@@ -230,7 +486,7 @@ public final class NumericShaper implements java.io.Serializable {
'\u0e80', '\u0f00', // LAO
'\u0f00', '\u1000', // TIBETAN
'\u1000', '\u1080', // MYANMAR
- '\u1200', '\u1380', // ETHIOPIC
+ '\u1200', '\u1380', // ETHIOPIC - note missing zero
'\u1780', '\u1800', // KHMER
'\u1800', '\u1900', // MONGOLIAN
'\uffff',
@@ -254,378 +510,290 @@ public final class NumericShaper implements java.io.Serializable {
return (ctCache & 0x1) == 0 ? (ctCache / 2) : EUROPEAN_KEY;
}
+ // cache for the NumericShaper.Range version
+ private transient volatile Range currentRange = Range.EUROPEAN;
+
+ private Range rangeForCodePoint(int codepoint) {
+ Range range = currentRange;
+ if (range.inRange(codepoint)) {
+ return range;
+ }
+
+ final Range[] ranges = Range.ranges;
+ int lo = 0;
+ int hi = ranges.length - 1;
+ while (lo <= hi) {
+ int mid = (lo + hi) / 2;
+ range = ranges[mid];
+ if (codepoint < range.start) {
+ hi = mid - 1;
+ } else if (codepoint >= range.end) {
+ lo = mid + 1;
+ } else {
+ currentRange = range;
+ return range;
+ }
+ }
+ return Range.EUROPEAN;
+ }
+
/*
* A range table of strong directional characters (types L, R, AL).
* Even (left) indexes are starts of ranges of non-strong-directional (or undefined)
* characters, odd (right) indexes are starts of ranges of strong directional
* characters.
*/
- private static char[] strongTable = {
- '\u0000', '\u0041',
- '\u005b', '\u0061',
- '\u007b', '\u00aa',
- '\u00ab', '\u00b5',
- '\u00b6', '\u00ba',
- '\u00bb', '\u00c0',
- '\u00d7', '\u00d8',
- '\u00f7', '\u00f8',
- '\u0220', '\u0222',
- '\u0234', '\u0250',
- '\u02ae', '\u02b0',
- '\u02b9', '\u02bb',
- '\u02c2', '\u02d0',
- '\u02d2', '\u02e0',
- '\u02e5', '\u02ee',
- '\u02ef', '\u037a',
- '\u037b', '\u0386',
- '\u0387', '\u0388',
- '\u038b', '\u038c',
- '\u038d', '\u038e',
- '\u03a2', '\u03a3',
- '\u03cf', '\u03d0',
- '\u03d8', '\u03da',
- '\u03f4', '\u0400',
- '\u0483', '\u048c',
- '\u04c5', '\u04c7',
- '\u04c9', '\u04cb',
- '\u04cd', '\u04d0',
- '\u04f6', '\u04f8',
- '\u04fa', '\u0531',
- '\u0557', '\u0559',
- '\u0560', '\u0561',
- '\u0588', '\u0589',
- '\u058a', '\u05be',
- '\u05bf', '\u05c0',
- '\u05c1', '\u05c3',
- '\u05c4', '\u05d0',
- '\u05eb', '\u05f0',
- '\u05f5', '\u061b',
- '\u061c', '\u061f',
- '\u0620', '\u0621',
- '\u063b', '\u0640',
- '\u064b', '\u066d',
- '\u066e', '\u0671',
- '\u06d6', '\u06e5',
- '\u06e7', '\u06fa',
- '\u06ff', '\u0700',
- '\u070e', '\u0710',
- '\u0711', '\u0712',
- '\u072d', '\u0780',
- '\u07a6', '\u0903',
- '\u0904', '\u0905',
- '\u093a', '\u093d',
- '\u0941', '\u0949',
- '\u094d', '\u0950',
- '\u0951', '\u0958',
- '\u0962', '\u0964',
- '\u0971', '\u0982',
- '\u0984', '\u0985',
- '\u098d', '\u098f',
- '\u0991', '\u0993',
- '\u09a9', '\u09aa',
- '\u09b1', '\u09b2',
- '\u09b3', '\u09b6',
- '\u09ba', '\u09be',
- '\u09c1', '\u09c7',
- '\u09c9', '\u09cb',
- '\u09cd', '\u09d7',
- '\u09d8', '\u09dc',
- '\u09de', '\u09df',
- '\u09e2', '\u09e6',
- '\u09f2', '\u09f4',
- '\u09fb', '\u0a05',
- '\u0a0b', '\u0a0f',
- '\u0a11', '\u0a13',
- '\u0a29', '\u0a2a',
- '\u0a31', '\u0a32',
- '\u0a34', '\u0a35',
- '\u0a37', '\u0a38',
- '\u0a3a', '\u0a3e',
- '\u0a41', '\u0a59',
- '\u0a5d', '\u0a5e',
- '\u0a5f', '\u0a66',
- '\u0a70', '\u0a72',
- '\u0a75', '\u0a83',
- '\u0a84', '\u0a85',
- '\u0a8c', '\u0a8d',
- '\u0a8e', '\u0a8f',
- '\u0a92', '\u0a93',
- '\u0aa9', '\u0aaa',
- '\u0ab1', '\u0ab2',
- '\u0ab4', '\u0ab5',
- '\u0aba', '\u0abd',
- '\u0ac1', '\u0ac9',
- '\u0aca', '\u0acb',
- '\u0acd', '\u0ad0',
- '\u0ad1', '\u0ae0',
- '\u0ae1', '\u0ae6',
- '\u0af0', '\u0b02',
- '\u0b04', '\u0b05',
- '\u0b0d', '\u0b0f',
- '\u0b11', '\u0b13',
- '\u0b29', '\u0b2a',
- '\u0b31', '\u0b32',
- '\u0b34', '\u0b36',
- '\u0b3a', '\u0b3d',
- '\u0b3f', '\u0b40',
- '\u0b41', '\u0b47',
- '\u0b49', '\u0b4b',
- '\u0b4d', '\u0b57',
- '\u0b58', '\u0b5c',
- '\u0b5e', '\u0b5f',
- '\u0b62', '\u0b66',
- '\u0b71', '\u0b83',
- '\u0b84', '\u0b85',
- '\u0b8b', '\u0b8e',
- '\u0b91', '\u0b92',
- '\u0b96', '\u0b99',
- '\u0b9b', '\u0b9c',
- '\u0b9d', '\u0b9e',
- '\u0ba0', '\u0ba3',
- '\u0ba5', '\u0ba8',
- '\u0bab', '\u0bae',
- '\u0bb6', '\u0bb7',
- '\u0bba', '\u0bbe',
- '\u0bc0', '\u0bc1',
- '\u0bc3', '\u0bc6',
- '\u0bc9', '\u0bca',
- '\u0bcd', '\u0bd7',
- '\u0bd8', '\u0be7',
- '\u0bf3', '\u0c01',
- '\u0c04', '\u0c05',
- '\u0c0d', '\u0c0e',
- '\u0c11', '\u0c12',
- '\u0c29', '\u0c2a',
- '\u0c34', '\u0c35',
- '\u0c3a', '\u0c41',
- '\u0c45', '\u0c60',
- '\u0c62', '\u0c66',
- '\u0c70', '\u0c82',
- '\u0c84', '\u0c85',
- '\u0c8d', '\u0c8e',
- '\u0c91', '\u0c92',
- '\u0ca9', '\u0caa',
- '\u0cb4', '\u0cb5',
- '\u0cba', '\u0cbe',
- '\u0cbf', '\u0cc0',
- '\u0cc5', '\u0cc7',
- '\u0cc9', '\u0cca',
- '\u0ccc', '\u0cd5',
- '\u0cd7', '\u0cde',
- '\u0cdf', '\u0ce0',
- '\u0ce2', '\u0ce6',
- '\u0cf0', '\u0d02',
- '\u0d04', '\u0d05',
- '\u0d0d', '\u0d0e',
- '\u0d11', '\u0d12',
- '\u0d29', '\u0d2a',
- '\u0d3a', '\u0d3e',
- '\u0d41', '\u0d46',
- '\u0d49', '\u0d4a',
- '\u0d4d', '\u0d57',
- '\u0d58', '\u0d60',
- '\u0d62', '\u0d66',
- '\u0d70', '\u0d82',
- '\u0d84', '\u0d85',
- '\u0d97', '\u0d9a',
- '\u0db2', '\u0db3',
- '\u0dbc', '\u0dbd',
- '\u0dbe', '\u0dc0',
- '\u0dc7', '\u0dcf',
- '\u0dd2', '\u0dd8',
- '\u0de0', '\u0df2',
- '\u0df5', '\u0e01',
- '\u0e31', '\u0e32',
- '\u0e34', '\u0e40',
- '\u0e47', '\u0e4f',
- '\u0e5c', '\u0e81',
- '\u0e83', '\u0e84',
- '\u0e85', '\u0e87',
- '\u0e89', '\u0e8a',
- '\u0e8b', '\u0e8d',
- '\u0e8e', '\u0e94',
- '\u0e98', '\u0e99',
- '\u0ea0', '\u0ea1',
- '\u0ea4', '\u0ea5',
- '\u0ea6', '\u0ea7',
- '\u0ea8', '\u0eaa',
- '\u0eac', '\u0ead',
- '\u0eb1', '\u0eb2',
- '\u0eb4', '\u0ebd',
- '\u0ebe', '\u0ec0',
- '\u0ec5', '\u0ec6',
- '\u0ec7', '\u0ed0',
- '\u0eda', '\u0edc',
- '\u0ede', '\u0f00',
- '\u0f18', '\u0f1a',
- '\u0f35', '\u0f36',
- '\u0f37', '\u0f38',
- '\u0f39', '\u0f3e',
- '\u0f48', '\u0f49',
- '\u0f6b', '\u0f7f',
- '\u0f80', '\u0f85',
- '\u0f86', '\u0f88',
- '\u0f8c', '\u0fbe',
- '\u0fc6', '\u0fc7',
- '\u0fcd', '\u0fcf',
- '\u0fd0', '\u1000',
- '\u1022', '\u1023',
- '\u1028', '\u1029',
- '\u102b', '\u102c',
- '\u102d', '\u1031',
- '\u1032', '\u1038',
- '\u1039', '\u1040',
- '\u1058', '\u10a0',
- '\u10c6', '\u10d0',
- '\u10f7', '\u10fb',
- '\u10fc', '\u1100',
- '\u115a', '\u115f',
- '\u11a3', '\u11a8',
- '\u11fa', '\u1200',
- '\u1207', '\u1208',
- '\u1247', '\u1248',
- '\u1249', '\u124a',
- '\u124e', '\u1250',
- '\u1257', '\u1258',
- '\u1259', '\u125a',
- '\u125e', '\u1260',
- '\u1287', '\u1288',
- '\u1289', '\u128a',
- '\u128e', '\u1290',
- '\u12af', '\u12b0',
- '\u12b1', '\u12b2',
- '\u12b6', '\u12b8',
- '\u12bf', '\u12c0',
- '\u12c1', '\u12c2',
- '\u12c6', '\u12c8',
- '\u12cf', '\u12d0',
- '\u12d7', '\u12d8',
- '\u12ef', '\u12f0',
- '\u130f', '\u1310',
- '\u1311', '\u1312',
- '\u1316', '\u1318',
- '\u131f', '\u1320',
- '\u1347', '\u1348',
- '\u135b', '\u1361',
- '\u137d', '\u13a0',
- '\u13f5', '\u1401',
- '\u1677', '\u1681',
- '\u169b', '\u16a0',
- '\u16f1', '\u1780',
- '\u17b7', '\u17be',
- '\u17c6', '\u17c7',
- '\u17c9', '\u17d4',
- '\u17db', '\u17dc',
- '\u17dd', '\u17e0',
- '\u17ea', '\u1810',
- '\u181a', '\u1820',
- '\u1878', '\u1880',
- '\u18a9', '\u1e00',
- '\u1e9c', '\u1ea0',
- '\u1efa', '\u1f00',
- '\u1f16', '\u1f18',
- '\u1f1e', '\u1f20',
- '\u1f46', '\u1f48',
- '\u1f4e', '\u1f50',
- '\u1f58', '\u1f59',
- '\u1f5a', '\u1f5b',
- '\u1f5c', '\u1f5d',
- '\u1f5e', '\u1f5f',
- '\u1f7e', '\u1f80',
- '\u1fb5', '\u1fb6',
- '\u1fbd', '\u1fbe',
- '\u1fbf', '\u1fc2',
- '\u1fc5', '\u1fc6',
- '\u1fcd', '\u1fd0',
- '\u1fd4', '\u1fd6',
- '\u1fdc', '\u1fe0',
- '\u1fed', '\u1ff2',
- '\u1ff5', '\u1ff6',
- '\u1ffd', '\u200e',
- '\u2010', '\u207f',
- '\u2080', '\u2102',
- '\u2103', '\u2107',
- '\u2108', '\u210a',
- '\u2114', '\u2115',
- '\u2116', '\u2119',
- '\u211e', '\u2124',
- '\u2125', '\u2126',
- '\u2127', '\u2128',
- '\u2129', '\u212a',
- '\u212e', '\u212f',
- '\u2132', '\u2133',
- '\u213a', '\u2160',
- '\u2184', '\u2336',
- '\u237b', '\u2395',
- '\u2396', '\u249c',
- '\u24ea', '\u3005',
- '\u3008', '\u3021',
- '\u302a', '\u3031',
- '\u3036', '\u3038',
- '\u303b', '\u3041',
- '\u3095', '\u309d',
- '\u309f', '\u30a1',
- '\u30fb', '\u30fc',
- '\u30ff', '\u3105',
- '\u312d', '\u3131',
- '\u318f', '\u3190',
- '\u31b8', '\u3200',
- '\u321d', '\u3220',
- '\u3244', '\u3260',
- '\u327c', '\u327f',
- '\u32b1', '\u32c0',
- '\u32cc', '\u32d0',
- '\u32ff', '\u3300',
- '\u3377', '\u337b',
- '\u33de', '\u33e0',
- '\u33ff', '\u3400',
- '\u4db6', '\u4e00',
- '\u9fa6', '\ua000',
- '\ua48d', '\uac00',
- '\ud7a4', '\uf900',
- '\ufa2e', '\ufb00',
- '\ufb07', '\ufb13',
- '\ufb18', '\ufb1d',
- '\ufb1e', '\ufb1f',
- '\ufb29', '\ufb2a',
- '\ufb37', '\ufb38',
- '\ufb3d', '\ufb3e',
- '\ufb3f', '\ufb40',
- '\ufb42', '\ufb43',
- '\ufb45', '\ufb46',
- '\ufbb2', '\ufbd3',
- '\ufd3e', '\ufd50',
- '\ufd90', '\ufd92',
- '\ufdc8', '\ufdf0',
- '\ufdfc', '\ufe70',
- '\ufe73', '\ufe74',
- '\ufe75', '\ufe76',
- '\ufefd', '\uff21',
- '\uff3b', '\uff41',
- '\uff5b', '\uff66',
- '\uffbf', '\uffc2',
- '\uffc8', '\uffca',
- '\uffd0', '\uffd2',
- '\uffd8', '\uffda',
- '\uffdd', '\uffff' // last entry is sentinel, actually never checked
+ private static int[] strongTable = {
+ 0x0000, 0x0041,
+ 0x005b, 0x0061,
+ 0x007b, 0x00aa,
+ 0x00ab, 0x00b5,
+ 0x00b6, 0x00ba,
+ 0x00bb, 0x00c0,
+ 0x00d7, 0x00d8,
+ 0x00f7, 0x00f8,
+ 0x02b9, 0x02bb,
+ 0x02c2, 0x02d0,
+ 0x02d2, 0x02e0,
+ 0x02e5, 0x02ee,
+ 0x02ef, 0x0370,
+ 0x0374, 0x0376,
+ 0x037e, 0x0386,
+ 0x0387, 0x0388,
+ 0x03f6, 0x03f7,
+ 0x0483, 0x048a,
+ 0x058a, 0x05be,
+ 0x05bf, 0x05c0,
+ 0x05c1, 0x05c3,
+ 0x05c4, 0x05c6,
+ 0x05c7, 0x05d0,
+ 0x0600, 0x0608,
+ 0x0609, 0x060b,
+ 0x060c, 0x060d,
+ 0x060e, 0x061b,
+ 0x064b, 0x066d,
+ 0x0670, 0x0671,
+ 0x06d6, 0x06e5,
+ 0x06e7, 0x06ee,
+ 0x06f0, 0x06fa,
+ 0x070f, 0x0710,
+ 0x0711, 0x0712,
+ 0x0730, 0x074d,
+ 0x07a6, 0x07b1,
+ 0x07eb, 0x07f4,
+ 0x07f6, 0x07fa,
+ 0x0901, 0x0903,
+ 0x093c, 0x093d,
+ 0x0941, 0x0949,
+ 0x094d, 0x0950,
+ 0x0951, 0x0958,
+ 0x0962, 0x0964,
+ 0x0981, 0x0982,
+ 0x09bc, 0x09bd,
+ 0x09c1, 0x09c7,
+ 0x09cd, 0x09ce,
+ 0x09e2, 0x09e6,
+ 0x09f2, 0x09f4,
+ 0x0a01, 0x0a03,
+ 0x0a3c, 0x0a3e,
+ 0x0a41, 0x0a59,
+ 0x0a70, 0x0a72,
+ 0x0a75, 0x0a83,
+ 0x0abc, 0x0abd,
+ 0x0ac1, 0x0ac9,
+ 0x0acd, 0x0ad0,
+ 0x0ae2, 0x0ae6,
+ 0x0af1, 0x0b02,
+ 0x0b3c, 0x0b3d,
+ 0x0b3f, 0x0b40,
+ 0x0b41, 0x0b47,
+ 0x0b4d, 0x0b57,
+ 0x0b62, 0x0b66,
+ 0x0b82, 0x0b83,
+ 0x0bc0, 0x0bc1,
+ 0x0bcd, 0x0bd0,
+ 0x0bf3, 0x0c01,
+ 0x0c3e, 0x0c41,
+ 0x0c46, 0x0c58,
+ 0x0c62, 0x0c66,
+ 0x0c78, 0x0c7f,
+ 0x0cbc, 0x0cbd,
+ 0x0ccc, 0x0cd5,
+ 0x0ce2, 0x0ce6,
+ 0x0cf1, 0x0d02,
+ 0x0d41, 0x0d46,
+ 0x0d4d, 0x0d57,
+ 0x0d62, 0x0d66,
+ 0x0dca, 0x0dcf,
+ 0x0dd2, 0x0dd8,
+ 0x0e31, 0x0e32,
+ 0x0e34, 0x0e40,
+ 0x0e47, 0x0e4f,
+ 0x0eb1, 0x0eb2,
+ 0x0eb4, 0x0ebd,
+ 0x0ec8, 0x0ed0,
+ 0x0f18, 0x0f1a,
+ 0x0f35, 0x0f36,
+ 0x0f37, 0x0f38,
+ 0x0f39, 0x0f3e,
+ 0x0f71, 0x0f7f,
+ 0x0f80, 0x0f85,
+ 0x0f86, 0x0f88,
+ 0x0f90, 0x0fbe,
+ 0x0fc6, 0x0fc7,
+ 0x102d, 0x1031,
+ 0x1032, 0x1038,
+ 0x1039, 0x103b,
+ 0x103d, 0x103f,
+ 0x1058, 0x105a,
+ 0x105e, 0x1061,
+ 0x1071, 0x1075,
+ 0x1082, 0x1083,
+ 0x1085, 0x1087,
+ 0x108d, 0x108e,
+ 0x135f, 0x1360,
+ 0x1390, 0x13a0,
+ 0x1680, 0x1681,
+ 0x169b, 0x16a0,
+ 0x1712, 0x1720,
+ 0x1732, 0x1735,
+ 0x1752, 0x1760,
+ 0x1772, 0x1780,
+ 0x17b7, 0x17be,
+ 0x17c6, 0x17c7,
+ 0x17c9, 0x17d4,
+ 0x17db, 0x17dc,
+ 0x17dd, 0x17e0,
+ 0x17f0, 0x1810,
+ 0x18a9, 0x18aa,
+ 0x1920, 0x1923,
+ 0x1927, 0x1929,
+ 0x1932, 0x1933,
+ 0x1939, 0x1946,
+ 0x19de, 0x1a00,
+ 0x1a17, 0x1a19,
+ 0x1b00, 0x1b04,
+ 0x1b34, 0x1b35,
+ 0x1b36, 0x1b3b,
+ 0x1b3c, 0x1b3d,
+ 0x1b42, 0x1b43,
+ 0x1b6b, 0x1b74,
+ 0x1b80, 0x1b82,
+ 0x1ba2, 0x1ba6,
+ 0x1ba8, 0x1baa,
+ 0x1c2c, 0x1c34,
+ 0x1c36, 0x1c3b,
+ 0x1dc0, 0x1e00,
+ 0x1fbd, 0x1fbe,
+ 0x1fbf, 0x1fc2,
+ 0x1fcd, 0x1fd0,
+ 0x1fdd, 0x1fe0,
+ 0x1fed, 0x1ff2,
+ 0x1ffd, 0x200e,
+ 0x2010, 0x2071,
+ 0x2074, 0x207f,
+ 0x2080, 0x2090,
+ 0x20a0, 0x2102,
+ 0x2103, 0x2107,
+ 0x2108, 0x210a,
+ 0x2114, 0x2115,
+ 0x2116, 0x2119,
+ 0x211e, 0x2124,
+ 0x2125, 0x2126,
+ 0x2127, 0x2128,
+ 0x2129, 0x212a,
+ 0x212e, 0x212f,
+ 0x213a, 0x213c,
+ 0x2140, 0x2145,
+ 0x214a, 0x214e,
+ 0x2153, 0x2160,
+ 0x2190, 0x2336,
+ 0x237b, 0x2395,
+ 0x2396, 0x249c,
+ 0x24ea, 0x26ac,
+ 0x26ad, 0x2800,
+ 0x2900, 0x2c00,
+ 0x2ce5, 0x2d00,
+ 0x2de0, 0x3005,
+ 0x3008, 0x3021,
+ 0x302a, 0x3031,
+ 0x3036, 0x3038,
+ 0x303d, 0x3041,
+ 0x3099, 0x309d,
+ 0x30a0, 0x30a1,
+ 0x30fb, 0x30fc,
+ 0x31c0, 0x31f0,
+ 0x321d, 0x3220,
+ 0x3250, 0x3260,
+ 0x327c, 0x327f,
+ 0x32b1, 0x32c0,
+ 0x32cc, 0x32d0,
+ 0x3377, 0x337b,
+ 0x33de, 0x33e0,
+ 0x33ff, 0x3400,
+ 0x4dc0, 0x4e00,
+ 0xa490, 0xa500,
+ 0xa60d, 0xa610,
+ 0xa66f, 0xa680,
+ 0xa700, 0xa722,
+ 0xa788, 0xa789,
+ 0xa802, 0xa803,
+ 0xa806, 0xa807,
+ 0xa80b, 0xa80c,
+ 0xa825, 0xa827,
+ 0xa828, 0xa840,
+ 0xa874, 0xa880,
+ 0xa8c4, 0xa8ce,
+ 0xa926, 0xa92e,
+ 0xa947, 0xa952,
+ 0xaa29, 0xaa2f,
+ 0xaa31, 0xaa33,
+ 0xaa35, 0xaa40,
+ 0xaa43, 0xaa44,
+ 0xaa4c, 0xaa4d,
+ 0xfb1e, 0xfb1f,
+ 0xfb29, 0xfb2a,
+ 0xfd3e, 0xfd50,
+ 0xfdfd, 0xfe70,
+ 0xfeff, 0xff21,
+ 0xff3b, 0xff41,
+ 0xff5b, 0xff66,
+ 0xffe0, 0x10000,
+ 0x10101, 0x10102,
+ 0x10140, 0x101d0,
+ 0x101fd, 0x10280,
+ 0x1091f, 0x10920,
+ 0x10a01, 0x10a10,
+ 0x10a38, 0x10a40,
+ 0x1d167, 0x1d16a,
+ 0x1d173, 0x1d183,
+ 0x1d185, 0x1d18c,
+ 0x1d1aa, 0x1d1ae,
+ 0x1d200, 0x1d360,
+ 0x1d7ce, 0x20000,
+ 0xe0001, 0xf0000,
+ 0x10fffe, 0x10ffff // sentinel
};
// use a binary search with a cache
- private static int stCache = 0;
+ private transient volatile int stCache = 0;
- // warning, synchronize access to this as it modifies state
- private static boolean isStrongDirectional(char c) {
- if (c < strongTable[stCache]) {
- stCache = search(c, strongTable, 0, stCache);
- } else if (c >= strongTable[stCache + 1]) {
- stCache = search(c, strongTable, stCache + 1, strongTable.length - stCache - 1);
+ private boolean isStrongDirectional(char c) {
+ int cachedIndex = stCache;
+ if (c < strongTable[cachedIndex]) {
+ cachedIndex = search(c, strongTable, 0, cachedIndex);
+ } else if (c >= strongTable[cachedIndex + 1]) {
+ cachedIndex = search(c, strongTable, cachedIndex + 1,
+ strongTable.length - cachedIndex - 1);
}
- return (stCache & 0x1) == 1;
+ boolean val = (cachedIndex & 0x1) == 1;
+ stCache = cachedIndex;
+ return val;
}
- static private int getKeyFromMask(int mask) {
+ private static int getKeyFromMask(int mask) {
int key = 0;
while (key < NUM_KEYS && ((mask & (1<The shaper assumes EUROPEAN as the starting context, that
+ * is, if EUROPEAN digits are encountered before any strong
+ * directional text in the string, the context is presumed to be
+ * EUROPEAN, and so the digits will not shape.
+ *
+ * @param ranges the specified Unicode ranges
+ * @return a contextual shaper for the specified ranges
+ * @throws NullPointerException if {@code ranges} is {@code null}.
+ * @since 1.7
+ */
+ public static NumericShaper getContextualShaper(Set ranges) {
+ NumericShaper shaper = new NumericShaper(Range.EUROPEAN, ranges);
+ shaper.mask = CONTEXTUAL_MASK;
+ return shaper;
+ }
+
/**
* Returns a contextual shaper for the provided unicode range(s).
* Latin-1 (EUROPEAN) digits will be converted to the decimal digits
@@ -683,12 +888,37 @@ public final class NumericShaper implements java.io.Serializable {
* @throws IllegalArgumentException if the specified
* defaultContext is not a single valid range.
*/
- static public NumericShaper getContextualShaper(int ranges, int defaultContext) {
+ public static NumericShaper getContextualShaper(int ranges, int defaultContext) {
int key = getKeyFromMask(defaultContext);
ranges |= CONTEXTUAL_MASK;
return new NumericShaper(key, ranges);
}
+ /**
+ * Returns a contextual shaper for the provided Unicode range(s).
+ * The Latin-1 (EUROPEAN) digits will be converted to the decimal
+ * digits corresponding to the range of the preceding text, if the
+ * range is one of the provided ranges. The shaper uses {@code
+ * defaultContext} as the starting context.
+ *
+ * @param ranges the specified Unicode ranges
+ * @param defaultContext the starting context, such as
+ * {@code NumericShaper.Range.EUROPEAN}
+ * @return a contextual shaper for the specified Unicode ranges.
+ * @throws NullPointerException
+ * if {@code ranges} or {@code defaultContext} is {@code null}
+ * @since 1.7
+ */
+ public static NumericShaper getContextualShaper(Set ranges,
+ Range defaultContext) {
+ if (defaultContext == null) {
+ throw new NullPointerException();
+ }
+ NumericShaper shaper = new NumericShaper(defaultContext, ranges);
+ shaper.mask = CONTEXTUAL_MASK;
+ return shaper;
+ }
+
/**
* Private constructor.
*/
@@ -697,6 +927,11 @@ public final class NumericShaper implements java.io.Serializable {
this.mask = mask;
}
+ private NumericShaper(Range defaultContext, Set ranges) {
+ this.shapingRange = defaultContext;
+ this.rangeSet = EnumSet.copyOf(ranges); // throws NPE if ranges is null.
+ }
+
/**
* Converts the digits in the text that occur between start and
* start + count.
@@ -710,19 +945,13 @@ public final class NumericShaper implements java.io.Serializable {
* @throws NullPointerException if text is null
*/
public void shape(char[] text, int start, int count) {
- if (text == null) {
- throw new NullPointerException("text is null");
- }
- if ((start < 0)
- || (start > text.length)
- || ((start + count) < 0)
- || ((start + count) > text.length)) {
- throw new IndexOutOfBoundsException(
- "bad start or count for text of length " + text.length);
- }
-
+ checkParams(text, start, count);
if (isContextual()) {
- shapeContextually(text, start, count, key);
+ if (rangeSet == null) {
+ shapeContextually(text, start, count, key);
+ } else {
+ shapeContextually(text, start, count, shapingRange);
+ }
} else {
shapeNonContextually(text, start, count);
}
@@ -747,6 +976,60 @@ public final class NumericShaper implements java.io.Serializable {
* range.
*/
public void shape(char[] text, int start, int count, int context) {
+ checkParams(text, start, count);
+ if (isContextual()) {
+ int ctxKey = getKeyFromMask(context);
+ if (rangeSet == null) {
+ shapeContextually(text, start, count, ctxKey);
+ } else {
+ shapeContextually(text, start, count, Range.values()[ctxKey]);
+ }
+ } else {
+ shapeNonContextually(text, start, count);
+ }
+ }
+
+ /**
+ * Converts the digits in the text that occur between {@code
+ * start} and {@code start + count}, using the provided {@code
+ * context}. {@code Context} is ignored if the shaper is not a
+ * contextual shaper.
+ *
+ * @param text a {@code char} array
+ * @param start the index into {@code text} to start converting
+ * @param count the number of {@code char}s in {@code text}
+ * to convert
+ * @param context the context to which to convert the characters,
+ * such as {@code NumericShaper.Range.EUROPEAN}
+ * @throws IndexOutOfBoundsException
+ * if {@code start} or {@code start + count} is out of bounds
+ * @throws NullPointerException
+ * if {@code text} or {@code context} is null
+ * @since 1.7
+ */
+ public void shape(char[] text, int start, int count, Range context) {
+ checkParams(text, start, count);
+ if (context == null) {
+ throw new NullPointerException("context is null");
+ }
+
+ if (isContextual()) {
+ if (rangeSet != null) {
+ shapeContextually(text, start, count, context);
+ } else {
+ int key = Range.toRangeIndex(context);
+ if (key >= 0) {
+ shapeContextually(text, start, count, key);
+ } else {
+ shapeContextually(text, start, count, shapingRange);
+ }
+ }
+ } else {
+ shapeNonContextually(text, start, count);
+ }
+ }
+
+ private void checkParams(char[] text, int start, int count) {
if (text == null) {
throw new NullPointerException("text is null");
}
@@ -757,13 +1040,6 @@ public final class NumericShaper implements java.io.Serializable {
throw new IndexOutOfBoundsException(
"bad start or count for text of length " + text.length);
}
-
- if (isContextual()) {
- int ctxKey = getKeyFromMask(context);
- shapeContextually(text, start, count, ctxKey);
- } else {
- shapeNonContextually(text, start, count);
- }
}
/**
@@ -785,18 +1061,45 @@ public final class NumericShaper implements java.io.Serializable {
*
* if ((shaper.getRanges() & shaper.ARABIC) != 0) { ...
*
+ *
+ * Note that this method supports only the bit mask-based
+ * ranges. Call {@link #getRangeSet()} for the enum-based ranges.
+ *
* @return the values for all the ranges to be shaped.
*/
public int getRanges() {
return mask & ~CONTEXTUAL_MASK;
}
+ /**
+ * Returns a {@code Set} representing all the Unicode ranges in
+ * this {@code NumericShaper} that will be shaped.
+ *
+ * @return all the Unicode ranges to be shaped.
+ * @since 1.7
+ */
+ public Set getRangeSet() {
+ if (rangeSet != null) {
+ return EnumSet.copyOf(rangeSet);
+ }
+ return Range.maskToRangeSet(mask);
+ }
+
/**
* Perform non-contextual shaping.
*/
private void shapeNonContextually(char[] text, int start, int count) {
- int base = bases[key];
- char minDigit = key == TAMIL_KEY ? '\u0031' : '\u0030'; // Tamil doesn't use decimal zero
+ int base;
+ char minDigit = '0';
+ if (shapingRange != null) {
+ base = shapingRange.getDigitBase();
+ minDigit += shapingRange.getNumericBase();
+ } else {
+ base = bases[key];
+ if (key == ETHIOPIC_KEY) {
+ minDigit++; // Ethiopic doesn't use decimal zero
+ }
+ }
for (int i = start, e = start + count; i < e; ++i) {
char c = text[i];
if (c >= minDigit && c <= '\u0039') {
@@ -807,7 +1110,7 @@ public final class NumericShaper implements java.io.Serializable {
/**
* Perform contextual shaping.
- * Synchronized to protect caches used in getContextKey and isStrongDirectional.
+ * Synchronized to protect caches used in getContextKey.
*/
private synchronized void shapeContextually(char[] text, int start, int count, int ctxKey) {
@@ -818,29 +1121,64 @@ public final class NumericShaper implements java.io.Serializable {
int lastkey = ctxKey;
int base = bases[ctxKey];
- char minDigit = ctxKey == TAMIL_KEY ? '\u0031' : '\u0030'; // Tamil doesn't use decimal zero
+ char minDigit = ctxKey == ETHIOPIC_KEY ? '1' : '0'; // Ethiopic doesn't use decimal zero
- for (int i = start, e = start + count; i < e; ++i) {
+ synchronized (NumericShaper.class) {
+ for (int i = start, e = start + count; i < e; ++i) {
+ char c = text[i];
+ if (c >= minDigit && c <= '\u0039') {
+ text[i] = (char)(c + base);
+ }
+
+ if (isStrongDirectional(c)) {
+ int newkey = getContextKey(c);
+ if (newkey != lastkey) {
+ lastkey = newkey;
+
+ ctxKey = newkey;
+ if (((mask & EASTERN_ARABIC) != 0) && (ctxKey == ARABIC_KEY || ctxKey == EASTERN_ARABIC_KEY)) {
+ ctxKey = EASTERN_ARABIC_KEY;
+ } else if ((mask & (1<= minDigit && c <= '\u0039') {
+ if (c >= minDigit && c <= '9') {
text[i] = (char)(c + base);
+ continue;
}
-
if (isStrongDirectional(c)) {
- int newkey = getContextKey(c);
- if (newkey != lastkey) {
- lastkey = newkey;
-
- ctxKey = newkey;
- if (((mask & EASTERN_ARABIC) != 0) && (ctxKey == ARABIC_KEY || ctxKey == EASTERN_ARABIC_KEY)) {
- ctxKey = EASTERN_ARABIC_KEY;
- } else if ((mask & (1<NumericShaper and shapes identically to this one.
+ * Returns {@code true} if the specified object is an instance of
+ * NumericShaper and shapes identically to this one,
+ * regardless of the range representations, the bit mask or the
+ * enum. For example, the following code produces {@code "true"}.
+ *
+ * NumericShaper ns1 = NumericShaper.getShaper(NumericShaper.ARABIC);
+ * NumericShaper ns2 = NumericShaper.getShaper(NumericShaper.Range.ARABIC);
+ * System.out.println(ns1.equals(ns2));
+ *
+ *
* @param o the specified object to compare to this
* NumericShaper
* @return true if o is an instance
@@ -869,6 +1223,22 @@ public final class NumericShaper implements java.io.Serializable {
if (o != null) {
try {
NumericShaper rhs = (NumericShaper)o;
+ if (rangeSet != null) {
+ if (rhs.rangeSet != null) {
+ return isContextual() == rhs.isContextual()
+ && rangeSet.equals(rhs.rangeSet)
+ && shapingRange == rhs.shapingRange;
+ }
+ return isContextual() == rhs.isContextual()
+ && rangeSet.equals(Range.maskToRangeSet(rhs.mask))
+ && shapingRange == Range.indexToRange(rhs.key);
+ } else if (rhs.rangeSet != null) {
+ Set rset = Range.maskToRangeSet(mask);
+ Range srange = Range.indexToRange(key);
+ return isContextual() == rhs.isContextual()
+ && rset.equals(rhs.rangeSet)
+ && srange == rhs.shapingRange;
+ }
return rhs.mask == mask && rhs.key == key;
}
catch (ClassCastException e) {
@@ -885,23 +1255,29 @@ public final class NumericShaper implements java.io.Serializable {
public String toString() {
StringBuilder buf = new StringBuilder(super.toString());
- buf.append("[contextual:" + isContextual());
+ buf.append("[contextual:").append(isContextual());
+ String[] keyNames = null;
if (isContextual()) {
- buf.append(", context:" + keyNames[key]);
+ buf.append(", context:");
+ buf.append(shapingRange == null ? Range.values()[key] : shapingRange);
}
- buf.append(", range(s): ");
- boolean first = true;
- for (int i = 0; i < NUM_KEYS; ++i) {
- if ((mask & (1 << i)) != 0) {
- if (first) {
- first = false;
- } else {
- buf.append(", ");
+ if (rangeSet == null) {
+ buf.append(", range(s): ");
+ boolean first = true;
+ for (int i = 0; i < NUM_KEYS; ++i) {
+ if ((mask & (1 << i)) != 0) {
+ if (first) {
+ first = false;
+ } else {
+ buf.append(", ");
+ }
+ buf.append(Range.values()[i]);
}
- buf.append(keyNames[i]);
}
+ } else {
+ buf.append(", range set: ").append(rangeSet);
}
buf.append(']');
@@ -940,7 +1316,6 @@ public final class NumericShaper implements java.io.Serializable {
}
if (value >= 1 << 1) {
- value >>= 1;
bit += 1;
}
@@ -950,7 +1325,7 @@ public final class NumericShaper implements java.io.Serializable {
/**
* fast binary search over subrange of array.
*/
- private static int search(char value, char[] array, int start, int length)
+ private static int search(int value, int[] array, int start, int length)
{
int power = 1 << getHighBit(length);
int extra = length - power;
@@ -971,4 +1346,27 @@ public final class NumericShaper implements java.io.Serializable {
return index;
}
+
+ /**
+ * Converts the {@code NumericShaper.Range} enum-based parameters,
+ * if any, to the bit mask-based counterparts and writes this
+ * object to the {@code stream}. Any enum constants that have no
+ * bit mask-based counterparts are ignored in the conversion.
+ *
+ * @param stream the output stream to write to
+ * @throws IOException if an I/O error occurs while writing to {@code stream}
+ * @since 1.7
+ */
+ private void writeObject(ObjectOutputStream stream) throws IOException {
+ if (shapingRange != null) {
+ int index = Range.toRangeIndex(shapingRange);
+ if (index >= 0) {
+ key = index;
+ }
+ }
+ if (rangeSet != null) {
+ mask |= Range.toRangeMask(rangeSet);
+ }
+ stream.defaultWriteObject();
+ }
}
diff --git a/src/share/classes/javax/print/attribute/standard/PrinterStateReasons.java b/src/share/classes/javax/print/attribute/standard/PrinterStateReasons.java
index 14225b90e46f6d1bb68ba379faf015dd2d4c1c60..2b0e8d2ab0c081aeed37d7b1c13967baaf88765b 100644
--- a/src/share/classes/javax/print/attribute/standard/PrinterStateReasons.java
+++ b/src/share/classes/javax/print/attribute/standard/PrinterStateReasons.java
@@ -65,7 +65,7 @@ import javax.print.attribute.PrintServiceAttribute;
* PrinterStateReason PrinterStateReason} objects to an existing
* PrinterStateReasons object and remove them again. However, like class
* {@link java.util.HashMap java.util.HashMap}, class PrinterStateReasons is
- * bot multiple thread safe. If a PrinterStateReasons object will be used by
+ * not multiple thread safe. If a PrinterStateReasons object will be used by
* multiple threads, be sure to synchronize its operations (e.g., using a
* synchronized map view obtained from class {@link java.util.Collections
* java.util.Collections}).
diff --git a/src/share/classes/javax/swing/JComponent.java b/src/share/classes/javax/swing/JComponent.java
index f0be74509f99e93ed5aaec6bf2fbaecb5e962b63..37f7e7d47307da81e9aa15ba02f542780e345f1f 100644
--- a/src/share/classes/javax/swing/JComponent.java
+++ b/src/share/classes/javax/swing/JComponent.java
@@ -795,7 +795,6 @@ public abstract class JComponent extends Container implements Serializable,
* @see java.awt.Container#paint
*/
protected void paintChildren(Graphics g) {
- boolean isJComponent;
Graphics sg = g;
synchronized(getTreeLock()) {
@@ -826,12 +825,21 @@ public abstract class JComponent extends Container implements Serializable,
}
}
boolean printing = getFlag(IS_PRINTING);
+ final Window window = SwingUtilities.getWindowAncestor(this);
+ final boolean isWindowOpaque = window == null || window.isOpaque();
for (; i >= 0 ; i--) {
Component comp = getComponent(i);
- isJComponent = (comp instanceof JComponent);
- if (comp != null &&
- (isJComponent || isLightweightComponent(comp)) &&
- (comp.isVisible() == true)) {
+ if (comp == null) {
+ continue;
+ }
+
+ final boolean isJComponent = comp instanceof JComponent;
+
+ // Enable painting of heavyweights in non-opaque windows.
+ // See 6884960
+ if ((!isWindowOpaque || isJComponent ||
+ isLightweightComponent(comp)) && comp.isVisible())
+ {
Rectangle cr;
cr = comp.getBounds(tmpRect);
@@ -887,6 +895,8 @@ public abstract class JComponent extends Container implements Serializable,
}
}
} else {
+ // The component is either lightweight, or
+ // heavyweight in a non-opaque window
if (!printing) {
comp.paint(cg);
}
@@ -4868,7 +4878,9 @@ public abstract class JComponent extends Container implements Serializable,
* @see #revalidate
* @see java.awt.Component#invalidate
* @see java.awt.Container#validate
+ * @see java.awt.Container#isValidateRoot
*/
+ @Override
public boolean isValidateRoot() {
return false;
}
diff --git a/src/share/classes/javax/swing/JEditorPane.java b/src/share/classes/javax/swing/JEditorPane.java
index 4dfbf92488ea19183bbf62437b4d7899ee382e56..eaf61f1e60e33d38d1d648efe86c6d77d466ebdd 100644
--- a/src/share/classes/javax/swing/JEditorPane.java
+++ b/src/share/classes/javax/swing/JEditorPane.java
@@ -1330,7 +1330,7 @@ public class JEditorPane extends JTextComponent {
*/
public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
- JViewport port = SwingUtilities2.getViewport(this);
+ JViewport port = SwingUtilities.getParentViewport(this);
if (port != null) {
TextUI ui = getUI();
int prefWidth = d.width;
@@ -1452,7 +1452,7 @@ public class JEditorPane extends JTextComponent {
* match its own, false otherwise
*/
public boolean getScrollableTracksViewportWidth() {
- JViewport port = SwingUtilities2.getViewport(this);
+ JViewport port = SwingUtilities.getParentViewport(this);
if (port != null) {
TextUI ui = getUI();
int w = port.getWidth();
@@ -1474,7 +1474,7 @@ public class JEditorPane extends JTextComponent {
* false otherwise
*/
public boolean getScrollableTracksViewportHeight() {
- JViewport port = SwingUtilities2.getViewport(this);
+ JViewport port = SwingUtilities.getParentViewport(this);
if (port != null) {
TextUI ui = getUI();
int h = port.getHeight();
diff --git a/src/share/classes/javax/swing/JList.java b/src/share/classes/javax/swing/JList.java
index 796ac11ba6c91060e7f016179cae6bbef3cc9f00..6c06c5ea6827a245dddd804e8d8fc4accc3fae3c 100644
--- a/src/share/classes/javax/swing/JList.java
+++ b/src/share/classes/javax/swing/JList.java
@@ -2722,7 +2722,7 @@ public class JList extends JComponent implements Scrollable, Accessible
getVisibleRowCount() <= 0) {
return true;
}
- JViewport port = SwingUtilities2.getViewport(this);
+ JViewport port = SwingUtilities.getParentViewport(this);
if (port != null) {
return port.getWidth() > getPreferredSize().width;
}
@@ -2748,7 +2748,7 @@ public class JList extends JComponent implements Scrollable, Accessible
getVisibleRowCount() <= 0) {
return true;
}
- JViewport port = SwingUtilities2.getViewport(this);
+ JViewport port = SwingUtilities.getParentViewport(this);
if (port != null) {
return port.getHeight() > getPreferredSize().height;
}
diff --git a/src/share/classes/javax/swing/JRootPane.java b/src/share/classes/javax/swing/JRootPane.java
index a210c3791c4e889e21ef2b2cd56ae4256b064f40..f6964f728ef73809f5c9cb91e2ad4d083b1e3c16 100644
--- a/src/share/classes/javax/swing/JRootPane.java
+++ b/src/share/classes/javax/swing/JRootPane.java
@@ -725,8 +725,10 @@ public class JRootPane extends JComponent implements Accessible {
* because both classes override isValidateRoot to return true.
*
* @see JComponent#isValidateRoot
+ * @see java.awt.Container#isValidateRoot
* @return true
*/
+ @Override
public boolean isValidateRoot() {
return true;
}
diff --git a/src/share/classes/javax/swing/JScrollPane.java b/src/share/classes/javax/swing/JScrollPane.java
index b2be43cd15fc8fed68cff816399266e945f28828..b813d4fccdc0747857874c3dfc8df0f1757f0bab 100644
--- a/src/share/classes/javax/swing/JScrollPane.java
+++ b/src/share/classes/javax/swing/JScrollPane.java
@@ -453,10 +453,12 @@ public class JScrollPane extends JComponent implements ScrollPaneConstants, Acce
* @see java.awt.Container#validate
* @see JComponent#revalidate
* @see JComponent#isValidateRoot
+ * @see java.awt.Container#isValidateRoot
*
* @beaninfo
* hidden: true
*/
+ @Override
public boolean isValidateRoot() {
return true;
}
diff --git a/src/share/classes/javax/swing/JSplitPane.java b/src/share/classes/javax/swing/JSplitPane.java
index b5d8ec7d2b513997df020fb823acf83e2c2c85f4..f3baff66492b2d23590f6067b118e72403023dce 100644
--- a/src/share/classes/javax/swing/JSplitPane.java
+++ b/src/share/classes/javax/swing/JSplitPane.java
@@ -947,10 +947,12 @@ public class JSplitPane extends JComponent implements Accessible
*
* @return true
* @see JComponent#revalidate
+ * @see java.awt.Container#isValidateRoot
*
* @beaninfo
* hidden: true
*/
+ @Override
public boolean isValidateRoot() {
return true;
}
diff --git a/src/share/classes/javax/swing/JTable.java b/src/share/classes/javax/swing/JTable.java
index 521f17ab8a5d9bf4b6451c08452d8d8a941e58e4..5489c380f1a143124855ca094604fc0db38e4467 100644
--- a/src/share/classes/javax/swing/JTable.java
+++ b/src/share/classes/javax/swing/JTable.java
@@ -57,6 +57,7 @@ import sun.swing.SwingUtilities2;
import sun.swing.SwingUtilities2.Section;
import static sun.swing.SwingUtilities2.Section.*;
import sun.swing.PrintingStatus;
+import sun.swing.SwingLazyValue;
/**
* The JTable is used to display and edit regular two-dimensional tables
@@ -718,7 +719,7 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
* @see #addNotify
*/
protected void configureEnclosingScrollPane() {
- JViewport port = SwingUtilities2.getViewport(this);
+ JViewport port = SwingUtilities.getParentViewport(this);
if (port != null) {
Container gp = port.getParent();
if (gp instanceof JScrollPane) {
@@ -727,7 +728,8 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
// example, the rowHeaderView of the scrollPane -
// an implementor of fixed columns might do this.
JViewport viewport = scrollPane.getViewport();
- if (viewport == null || viewport.getView() != this) {
+ if (viewport == null ||
+ SwingUtilities.getUnwrappedView(viewport) != this) {
return;
}
scrollPane.setColumnHeaderView(getTableHeader());
@@ -750,7 +752,7 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
* from configureEnclosingScrollPane() and updateUI() in a safe manor.
*/
private void configureEnclosingScrollPaneUI() {
- JViewport port = SwingUtilities2.getViewport(this);
+ JViewport port = SwingUtilities.getParentViewport(this);
if (port != null) {
Container gp = port.getParent();
if (gp instanceof JScrollPane) {
@@ -759,7 +761,8 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
// example, the rowHeaderView of the scrollPane -
// an implementor of fixed columns might do this.
JViewport viewport = scrollPane.getViewport();
- if (viewport == null || viewport.getView() != this) {
+ if (viewport == null ||
+ SwingUtilities.getUnwrappedView(viewport) != this) {
return;
}
// scrollPane.getViewport().setBackingStoreEnabled(true);
@@ -819,7 +822,7 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
* @since 1.3
*/
protected void unconfigureEnclosingScrollPane() {
- JViewport port = SwingUtilities2.getViewport(this);
+ JViewport port = SwingUtilities.getParentViewport(this);
if (port != null) {
Container gp = port.getParent();
if (gp instanceof JScrollPane) {
@@ -828,7 +831,8 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
// example, the rowHeaderView of the scrollPane -
// an implementor of fixed columns might do this.
JViewport viewport = scrollPane.getViewport();
- if (viewport == null || viewport.getView() != this) {
+ if (viewport == null ||
+ SwingUtilities.getUnwrappedView(viewport) != this) {
return;
}
scrollPane.setColumnHeaderView(null);
@@ -5215,7 +5219,7 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
* @see #getFillsViewportHeight
*/
public boolean getScrollableTracksViewportHeight() {
- JViewport port = SwingUtilities2.getViewport(this);
+ JViewport port = SwingUtilities.getParentViewport(this);
return getFillsViewportHeight()
&& port != null
&& port.getHeight() > getPreferredSize().height;
@@ -5316,7 +5320,7 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
}
private void setLazyValue(Hashtable h, Class c, String s) {
- h.put(c, new UIDefaults.ProxyLazyValue(s));
+ h.put(c, new SwingLazyValue(s));
}
private void setLazyRenderer(Class c, String s) {
diff --git a/src/share/classes/javax/swing/JTextField.java b/src/share/classes/javax/swing/JTextField.java
index de408914d2222c156ba4530bda43237b00b3f4af..24a3408d1b4a98b947919f33a680a0ebed1a9b2f 100644
--- a/src/share/classes/javax/swing/JTextField.java
+++ b/src/share/classes/javax/swing/JTextField.java
@@ -288,9 +288,11 @@ public class JTextField extends JTextComponent implements SwingConstants {
*
* @see JComponent#revalidate
* @see JComponent#isValidateRoot
+ * @see java.awt.Container#isValidateRoot
*/
+ @Override
public boolean isValidateRoot() {
- return SwingUtilities2.getViewport(this) == null;
+ return SwingUtilities.getParentViewport(this) == null;
}
diff --git a/src/share/classes/javax/swing/JTree.java b/src/share/classes/javax/swing/JTree.java
index 1b200f78591a476b0e10f1555af558fe08ae57b7..55815b81dc26ae851921d8278ff202558d97f0d7 100644
--- a/src/share/classes/javax/swing/JTree.java
+++ b/src/share/classes/javax/swing/JTree.java
@@ -3498,7 +3498,7 @@ public class JTree extends JComponent implements Scrollable, Accessible
* @see Scrollable#getScrollableTracksViewportWidth
*/
public boolean getScrollableTracksViewportWidth() {
- JViewport port = SwingUtilities2.getViewport(this);
+ JViewport port = SwingUtilities.getParentViewport(this);
if (port != null) {
return port.getWidth() > getPreferredSize().width;
}
@@ -3515,7 +3515,7 @@ public class JTree extends JComponent implements Scrollable, Accessible
* @see Scrollable#getScrollableTracksViewportHeight
*/
public boolean getScrollableTracksViewportHeight() {
- JViewport port = SwingUtilities2.getViewport(this);
+ JViewport port = SwingUtilities.getParentViewport(this);
if (port != null) {
return port.getHeight() > getPreferredSize().height;
}
diff --git a/src/share/classes/javax/swing/JViewport.java b/src/share/classes/javax/swing/JViewport.java
index 734e80a05570d03e004aad8a37ee557811b592d0..5073a891af4e76db0ae31d3b532f116d483e65d9 100644
--- a/src/share/classes/javax/swing/JViewport.java
+++ b/src/share/classes/javax/swing/JViewport.java
@@ -469,49 +469,12 @@ public class JViewport extends JComponent implements Accessible
* is the synchronous version of a revalidate.
*/
private void validateView() {
- Component validateRoot = null;
+ Component validateRoot = SwingUtilities.getValidateRoot(this, false);
- /* Find the first JComponent ancestor of this component whose
- * isValidateRoot() method returns true.
- */
- for(Component c = this; c != null; c = c.getParent()) {
- if ((c instanceof CellRendererPane) || (c.getPeer() == null)) {
- return;
- }
- if ((c instanceof JComponent) &&
- (((JComponent)c).isValidateRoot())) {
- validateRoot = c;
- break;
- }
- }
-
- // If no validateRoot, nothing to validate from.
if (validateRoot == null) {
return;
}
- // Make sure all ancestors are visible.
- Component root = null;
-
- for(Component c = validateRoot; c != null; c = c.getParent()) {
- // We don't check isVisible here, otherwise if the component
- // is contained in something like a JTabbedPane when the
- // component is made visible again it won't have scrolled
- // to the correct location.
- if (c.getPeer() == null) {
- return;
- }
- if ((c instanceof Window) || (c instanceof Applet)) {
- root = c;
- break;
- }
- }
-
- // Make sure there is a Window ancestor.
- if (root == null) {
- return;
- }
-
// Validate the root.
validateRoot.validate();
diff --git a/src/share/classes/javax/swing/RepaintManager.java b/src/share/classes/javax/swing/RepaintManager.java
index a988b99fbd35d6a0b45d061a28410bac51a9f8a7..c8607d2e4b99042daaa42dda75cf00c9f8900b76 100644
--- a/src/share/classes/javax/swing/RepaintManager.java
+++ b/src/share/classes/javax/swing/RepaintManager.java
@@ -310,47 +310,13 @@ public class RepaintManager
delegate.addInvalidComponent(invalidComponent);
return;
}
- Component validateRoot = null;
+ Component validateRoot =
+ SwingUtilities.getValidateRoot(invalidComponent, true);
- /* Find the first JComponent ancestor of this component whose
- * isValidateRoot() method returns true.
- */
- for(Component c = invalidComponent; c != null; c = c.getParent()) {
- if ((c instanceof CellRendererPane) || (c.getPeer() == null)) {
- return;
- }
- if ((c instanceof JComponent) && (((JComponent)c).isValidateRoot())) {
- validateRoot = c;
- break;
- }
- }
-
- /* There's no validateRoot to apply validate to, so we're done.
- */
if (validateRoot == null) {
return;
}
- /* If the validateRoot and all of its ancestors aren't visible
- * then we don't do anything. While we're walking up the tree
- * we find the root Window or Applet.
- */
- Component root = null;
-
- for(Component c = validateRoot; c != null; c = c.getParent()) {
- if (!c.isVisible() || (c.getPeer() == null)) {
- return;
- }
- if ((c instanceof Window) || (c instanceof Applet)) {
- root = c;
- break;
- }
- }
-
- if (root == null) {
- return;
- }
-
/* Lazily create the invalidateComponents vector and add the
* validateRoot if it's not there already. If this validateRoot
* is already in the vector, we're done.
diff --git a/src/share/classes/javax/swing/SwingUtilities.java b/src/share/classes/javax/swing/SwingUtilities.java
index d7a26a0dd729555011a93a6ead80acf5c54f6b87..1221c4bce748a9f78a0c4fb48091fa7764d60527 100644
--- a/src/share/classes/javax/swing/SwingUtilities.java
+++ b/src/share/classes/javax/swing/SwingUtilities.java
@@ -1967,4 +1967,114 @@ public class SwingUtilities implements SwingConstants
SwingUtilities.updateComponentTreeUI(component);
}
}
+
+ /**
+ * Looks for the first ancestor of the {@code component}
+ * which is not an instance of {@link JLayer}.
+ * If this ancestor is an instance of {@code JViewport},
+ * this {@code JViewport} is returned, otherwise returns {@code null}.
+ * The following way of obtaining the parent {@code JViewport}
+ * is not recommended any more:
+ *
+ * JViewport port = null;
+ * Container parent = component.getParent();
+ * // not recommended any more
+ * if(parent instanceof JViewport) {
+ * port = (JViewport) parent;
+ * }
+ *
+ * Here is the way to go:
+ *
+ * // the correct way:
+ * JViewport port = SwingUtilities.getParentViewport(component);
+ *
+ * @param component {@code Component} to get the parent {@code JViewport} of.
+ * @return the {@code JViewport} instance for the {@code component}
+ * or {@code null}
+ * @throws NullPointerException if {@code component} is {@code null}
+ *
+ * @since 1.7
+ */
+ public static JViewport getParentViewport(Component component) {
+ do {
+ component = component.getParent();
+ if (component instanceof JViewport) {
+ return (JViewport) component;
+ }
+ } while(component instanceof JLayer);
+ return null;
+ }
+
+ /**
+ * Returns the first {@code JViewport}'s descendant
+ * which is not an instance of {@code JLayer} or {@code null}.
+ *
+ * If the {@code viewport}'s view component is not a {@code JLayer},
+ * this method is equal to {@link JViewport#getView()}
+ * otherwise {@link JLayer#getView()} will be recursively tested
+ *
+ * @return the first {@code JViewport}'s descendant
+ * which is not an instance of {@code JLayer} or {@code null}.
+ *
+ * @throws NullPointerException if {@code viewport} is {@code null}
+ * @see JViewport#getView()
+ * @see JLayer
+ */
+ static Component getUnwrappedView(JViewport viewport) {
+ Component view = viewport.getView();
+ while (view instanceof JLayer) {
+ view = ((JLayer)view).getView();
+ }
+ return view;
+ }
+
+ /**
+ * Retrieves the validate root of a given container.
+ *
+ * If the container is contained within a {@code CellRendererPane}, this
+ * method returns {@code null} due to the synthetic nature of the {@code
+ * CellRendererPane}.
+ *
+ * The component hierarchy must be displayable up to the toplevel component
+ * (either a {@code Frame} or an {@code Applet} object.) Otherwise this
+ * method returns {@code null}.
+ *
+ * If the {@code visibleOnly} argument is {@code true}, the found validate
+ * root and all its parents up to the toplevel component must also be
+ * visible. Otherwise this method returns {@code null}.
+ *
+ * @return the validate root of the given container or null
+ * @see java.awt.Component#isDisplayable()
+ * @see java.awt.Component#isVisible()
+ * @since 1.7
+ */
+ static Container getValidateRoot(Container c, boolean visibleOnly) {
+ Container root = null;
+
+ for (; c != null; c = c.getParent())
+ {
+ if (!c.isDisplayable() || c instanceof CellRendererPane) {
+ return null;
+ }
+ if (c.isValidateRoot()) {
+ root = c;
+ break;
+ }
+ }
+
+ if (root == null) {
+ return null;
+ }
+
+ for (; c != null; c = c.getParent()) {
+ if (!c.isDisplayable() || (visibleOnly && !c.isVisible())) {
+ return null;
+ }
+ if (c instanceof Window || c instanceof Applet) {
+ return root;
+ }
+ }
+
+ return null;
+ }
}
diff --git a/src/share/classes/javax/swing/filechooser/FileSystemView.java b/src/share/classes/javax/swing/filechooser/FileSystemView.java
index 9f969796bddfdd64b1a26801a519298d9d67ce46..7c7ef7b668697a712703bae9bd5ceb38ce0a9888 100644
--- a/src/share/classes/javax/swing/filechooser/FileSystemView.java
+++ b/src/share/classes/javax/swing/filechooser/FileSystemView.java
@@ -33,7 +33,8 @@ import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.MessageFormat;
-import java.util.Vector;
+import java.util.List;
+import java.util.ArrayList;
import java.lang.ref.WeakReference;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeEvent;
@@ -173,22 +174,27 @@ public abstract class FileSystemView {
* @since 1.4
*/
public String getSystemDisplayName(File f) {
- String name = null;
- if (f != null) {
- name = f.getName();
- if (!name.equals("..") && !name.equals(".") &&
- (useSystemExtensionHiding ||
- !isFileSystem(f) ||
- isFileSystemRoot(f)) &&
- ((f instanceof ShellFolder) ||
- f.exists())) {
+ if (f == null) {
+ return null;
+ }
+
+ String name = f.getName();
+
+ if (!name.equals("..") && !name.equals(".") &&
+ (useSystemExtensionHiding || !isFileSystem(f) || isFileSystemRoot(f)) &&
+ (f instanceof ShellFolder || f.exists())) {
+ try {
name = getShellFolder(f).getDisplayName();
- if (name == null || name.length() == 0) {
- name = f.getPath(); // e.g. "/"
- }
+ } catch (FileNotFoundException e) {
+ return null;
+ }
+
+ if (name == null || name.length() == 0) {
+ name = f.getPath(); // e.g. "/"
}
}
+
return name;
}
@@ -222,17 +228,25 @@ public abstract class FileSystemView {
* @since 1.4
*/
public Icon getSystemIcon(File f) {
- if (f != null) {
- ShellFolder sf = getShellFolder(f);
- Image img = sf.getIcon(false);
- if (img != null) {
- return new ImageIcon(img, sf.getFolderType());
- } else {
- return UIManager.getIcon(f.isDirectory() ? "FileView.directoryIcon" : "FileView.fileIcon");
- }
- } else {
+ if (f == null) {
return null;
}
+
+ ShellFolder sf;
+
+ try {
+ sf = getShellFolder(f);
+ } catch (FileNotFoundException e) {
+ return null;
+ }
+
+ Image img = sf.getIcon(false);
+
+ if (img != null) {
+ return new ImageIcon(img, sf.getFolderType());
+ } else {
+ return UIManager.getIcon(f.isDirectory() ? "FileView.directoryIcon" : "FileView.fileIcon");
+ }
}
/**
@@ -446,24 +460,28 @@ public abstract class FileSystemView {
* Gets the list of shown (i.e. not hidden) files.
*/
public File[] getFiles(File dir, boolean useFileHiding) {
- Vector files = new Vector();
-
+ List files = new ArrayList();
// add all files in dir
- File[] names;
- if (!(dir instanceof ShellFolder)) {
+ if (!(dir instanceof ShellFolder)) {
+ try {
dir = getShellFolder(dir);
+ } catch (FileNotFoundException e) {
+ return new File[0];
}
+ }
- names = ((ShellFolder)dir).listFiles(!useFileHiding);
- File f;
+ File[] names = ((ShellFolder) dir).listFiles(!useFileHiding);
- int nameCount = (names == null) ? 0 : names.length;
- for (int i = 0; i < nameCount; i++) {
+ if (names == null) {
+ return new File[0];
+ }
+
+ for (File f : names) {
if (Thread.currentThread().isInterrupted()) {
break;
}
- f = names[i];
+
if (!(f instanceof ShellFolder)) {
if (isFileSystemRoot(f)) {
f = createFileSystemRoot(f);
@@ -481,7 +499,7 @@ public abstract class FileSystemView {
}
}
if (!useFileHiding || !isHiddenFile(f)) {
- files.addElement(f);
+ files.add(f);
}
}
@@ -497,42 +515,50 @@ public abstract class FileSystemView {
* null if dir is null
*/
public File getParentDirectory(File dir) {
- if (dir != null && dir.exists()) {
- ShellFolder sf = getShellFolder(dir);
- File psf = sf.getParentFile();
- if (psf != null) {
- if (isFileSystem(psf)) {
- File f = psf;
- if (f != null && !f.exists()) {
- // This could be a node under "Network Neighborhood".
- File ppsf = psf.getParentFile();
- if (ppsf == null || !isFileSystem(ppsf)) {
- // We're mostly after the exists() override for windows below.
- f = createFileSystemRoot(f);
- }
- }
- return f;
- } else {
- return psf;
+ if (dir == null || !dir.exists()) {
+ return null;
+ }
+
+ ShellFolder sf;
+
+ try {
+ sf = getShellFolder(dir);
+ } catch (FileNotFoundException e) {
+ return null;
+ }
+
+ File psf = sf.getParentFile();
+
+ if (psf == null) {
+ return null;
+ }
+
+ if (isFileSystem(psf)) {
+ File f = psf;
+ if (!f.exists()) {
+ // This could be a node under "Network Neighborhood".
+ File ppsf = psf.getParentFile();
+ if (ppsf == null || !isFileSystem(ppsf)) {
+ // We're mostly after the exists() override for windows below.
+ f = createFileSystemRoot(f);
}
}
+ return f;
+ } else {
+ return psf;
}
- return null;
}
- ShellFolder getShellFolder(File f) {
- if (!(f instanceof ShellFolder)
- && !(f instanceof FileSystemRoot)
- && isFileSystemRoot(f)) {
-
+ /**
+ * Throws {@code FileNotFoundException} if file not found or current thread was interrupted
+ */
+ ShellFolder getShellFolder(File f) throws FileNotFoundException {
+ if (!(f instanceof ShellFolder) && !(f instanceof FileSystemRoot) && isFileSystemRoot(f)) {
f = createFileSystemRoot(f);
}
+
try {
return ShellFolder.getShellFolder(f);
- } catch (FileNotFoundException e) {
- System.err.println("FileSystemView.getShellFolder: f="+f);
- e.printStackTrace();
- return null;
} catch (InternalError e) {
System.err.println("FileSystemView.getShellFolder: f="+f);
e.printStackTrace();
@@ -596,9 +622,9 @@ class UnixFileSystemView extends FileSystemView {
// Unix - using OpenWindows' default folder name. Can't find one for Motif/CDE.
newFolder = createFileObject(containingDir, newFolderString);
int i = 1;
- while (newFolder.exists() && (i < 100)) {
+ while (newFolder.exists() && i < 100) {
newFolder = createFileObject(containingDir, MessageFormat.format(
- newFolderNextString, new Object[] { new Integer(i) }));
+ newFolderNextString, new Integer(i)));
i++;
}
@@ -612,7 +638,7 @@ class UnixFileSystemView extends FileSystemView {
}
public boolean isFileSystemRoot(File dir) {
- return (dir != null && dir.getAbsolutePath().equals("/"));
+ return dir != null && dir.getAbsolutePath().equals("/");
}
public boolean isDrive(File dir) {
@@ -654,7 +680,7 @@ class WindowsFileSystemView extends FileSystemView {
public File getChild(File parent, String fileName) {
if (fileName.startsWith("\\")
- && !(fileName.startsWith("\\\\"))
+ && !fileName.startsWith("\\\\")
&& isFileSystem(parent)) {
//Path is relative to the root of parent's drive
@@ -677,9 +703,13 @@ class WindowsFileSystemView extends FileSystemView {
* The Windows implementation gets information from the ShellFolder class.
*/
public String getSystemTypeDescription(File f) {
- if (f != null) {
+ if (f == null) {
+ return null;
+ }
+
+ try {
return getShellFolder(f).getFolderType();
- } else {
+ } catch (FileNotFoundException e) {
return null;
}
}
@@ -701,9 +731,9 @@ class WindowsFileSystemView extends FileSystemView {
// Using NT's default folder name
File newFolder = createFileObject(containingDir, newFolderString);
int i = 2;
- while (newFolder.exists() && (i < 100)) {
+ while (newFolder.exists() && i < 100) {
newFolder = createFileObject(containingDir, MessageFormat.format(
- newFolderNextString, new Object[] { new Integer(i) }));
+ newFolderNextString, new Integer(i)));
i++;
}
@@ -727,7 +757,7 @@ class WindowsFileSystemView extends FileSystemView {
}
});
- return (path != null && (path.equals("A:\\") || path.equals("B:\\")));
+ return path != null && (path.equals("A:\\") || path.equals("B:\\"));
}
/**
diff --git a/src/share/classes/javax/swing/plaf/LayerUI.java b/src/share/classes/javax/swing/plaf/LayerUI.java
index cf64687421a9606add6adcc07102eef7bc9bc45a..7f2967bf465553e453a60b3f4225f878e71789ff 100644
--- a/src/share/classes/javax/swing/plaf/LayerUI.java
+++ b/src/share/classes/javax/swing/plaf/LayerUI.java
@@ -71,33 +71,410 @@ public class LayerUI
* Subclasses should override this method and use
* the specified {@code Graphics} object to
* render the content of the component.
+ *
+ * If {@code g} is not an instance of {@code Graphics2D},
+ * this method is no-op.
*
* @param g the {@code Graphics} context in which to paint;
* @param c the component being painted;
- * it can be safely cast to the {@code JLayer}
+ * it can be safely cast to {@code JLayer extends V>}
+ *
+ * @see #configureGraphics(Graphics2D, JLayer)
+ * @see #paintLayer(Graphics2D, JLayer)
*/
- @Override
public void paint(Graphics g, JComponent c) {
- c.paint(g);
+ if (g instanceof Graphics2D) {
+ Graphics2D g2 = (Graphics2D) g.create();
+ JLayer extends V> l = (JLayer extends V>) c;
+ configureGraphics(g2, l);
+ paintLayer(g2, l);
+ g2.dispose();
+ }
+ }
+
+ /**
+ * This method is called by the {@link #paint} method prior to
+ * {@link #paintLayer} to configure the {@code Graphics2D} object.
+ * The default implementation is empty.
+ *
+ * @param g2 the {@code Graphics2D} object to configure
+ * @param l the {@code JLayer} being painted
+ *
+ * @see #paintLayer(Graphics2D, JLayer)
+ */
+ protected void configureGraphics(Graphics2D g2, JLayer extends V> l) {
+ }
+
+ /**
+ * Called by the {@link #paint} method,
+ * subclasses should override this method
+ * to perform any custom painting operations.
+ *
+ * The default implementation paints the passed {@code JLayer} as is.
+ *
+ * @param g2 the {@code Graphics2D} context in which to paint
+ * @param l the {@code JLayer} being painted
+ *
+ * @see #configureGraphics(Graphics2D, JLayer)
+ */
+ protected void paintLayer(Graphics2D g2, JLayer extends V> l) {
+ l.paint(g2);
}
/**
* Dispatches {@code AWTEvent}s for {@code JLayer}
- * and all it subcomponents to this {@code LayerUI} instance.
- *
- * To enable the {@code AWTEvent} of the particular type,
- * you call {@link javax.swing.JLayer#setLayerEventMask}
+ * and all its subcomponents to this {@code LayerUI} instance.
+ *
+ * To enable the {@code AWTEvent}s of a particular type,
+ * you call {@link JLayer#setLayerEventMask}
* in {@link #installUI(javax.swing.JComponent)}
* and set the layer event mask to {@code 0}
- * in {@link #uninstallUI(javax.swing.JComponent)} after that
+ * in {@link #uninstallUI(javax.swing.JComponent)} after that.
+ * By default this method calls the appropriate
+ * {@code process<event type>Event}
+ * method for the given class of event.
*
* @param e the event to be dispatched
* @param l the layer this LayerUI is set to
*
* @see JLayer#setLayerEventMask(long)
- * @see javax.swing.JLayer#getLayerEventMask()
+ * @see #installUI(javax.swing.JComponent)
+ * @see #uninstallUI(javax.swing.JComponent)
+ * @see #processComponentEvent
+ * @see #processFocusEvent
+ * @see #processKeyEvent
+ * @see #processMouseEvent
+ * @see #processMouseMotionEvent
+ * @see #processInputMethodEvent
+ * @see #processHierarchyEvent
+ * @see #processMouseWheelEvent
*/
public void eventDispatched(AWTEvent e, JLayer extends V> l){
+ if (e instanceof FocusEvent) {
+ processFocusEvent((FocusEvent)e, l);
+
+ } else if (e instanceof MouseEvent) {
+ switch(e.getID()) {
+ case MouseEvent.MOUSE_PRESSED:
+ case MouseEvent.MOUSE_RELEASED:
+ case MouseEvent.MOUSE_CLICKED:
+ case MouseEvent.MOUSE_ENTERED:
+ case MouseEvent.MOUSE_EXITED:
+ processMouseEvent((MouseEvent)e, l);
+ break;
+ case MouseEvent.MOUSE_MOVED:
+ case MouseEvent.MOUSE_DRAGGED:
+ processMouseMotionEvent((MouseEvent)e, l);
+ break;
+ case MouseEvent.MOUSE_WHEEL:
+ processMouseWheelEvent((MouseWheelEvent)e, l);
+ break;
+ }
+ } else if (e instanceof KeyEvent) {
+ processKeyEvent((KeyEvent)e, l);
+ } else if (e instanceof ComponentEvent) {
+ processComponentEvent((ComponentEvent)e, l);
+ } else if (e instanceof InputMethodEvent) {
+ processInputMethodEvent((InputMethodEvent)e, l);
+ } else if (e instanceof HierarchyEvent) {
+ switch (e.getID()) {
+ case HierarchyEvent.HIERARCHY_CHANGED:
+ processHierarchyEvent((HierarchyEvent)e, l);
+ break;
+ case HierarchyEvent.ANCESTOR_MOVED:
+ case HierarchyEvent.ANCESTOR_RESIZED:
+ processHierarchyBoundsEvent((HierarchyEvent)e, l);
+ break;
+ }
+ }
+ }
+
+ /**
+ * Processes component events occurring on the {@link JLayer}
+ * or any of its subcomponents.
+ *
+ * This method is not called unless component events are
+ * enabled for the {@code JLayer} objects, this {@code LayerUI} is set to.
+ * Component events are enabled in the overridden {@link #installUI} method
+ * and should be disabled in the {@link #uninstallUI} method after that.
+ *
+ * public void installUI(JComponent c) {
+ * super.installUI(c);
+ * JLayer l = (JLayer) c;
+ * l.setLayerEventMask(AWTEvent.COMPONENT_EVENT_MASK);
+ * }
+ *
+ * public void unistallUI(JComponent c) {
+ * super.uninstallUI(c);
+ * JLayer l = (JLayer) c;
+ * l.setLayerEventMask(0);
+ * }
+ *
+ *
+ * @param e the {@code ComponentEvent} to be processed
+ * @param l the layer this {@code LayerUI} instance is set to
+ *
+ * @see JLayer#setLayerEventMask(long)
+ * @see #installUI(javax.swing.JComponent)
+ * @see #uninstallUI(javax.swing.JComponent)
+ */
+ protected void processComponentEvent(ComponentEvent e, JLayer extends V> l) {
+ }
+
+ /**
+ * Processes focus events occurring on the {@link JLayer}
+ * or any of its subcomponents.
+ *
+ * This method is not called unless focus events are
+ * enabled for the {@code JLayer} objects, this {@code LayerUI} is set to.
+ * Focus events are enabled in the overridden {@link #installUI} method
+ * and should be disabled in the {@link #uninstallUI} method after that.
+ *
+ * public void installUI(JComponent c) {
+ * super.installUI(c);
+ * JLayer l = (JLayer) c;
+ * l.setLayerEventMask(AWTEvent.FOCUS_EVENT_MASK);
+ * }
+ *
+ * public void unistallUI(JComponent c) {
+ * super.uninstallUI(c);
+ * JLayer l = (JLayer) c;
+ * l.setLayerEventMask(0);
+ * }
+ *
+ *
+ * @param e the {@code FocusEvent} to be processed
+ * @param l the layer this {@code LayerUI} instance is set to
+ *
+ * @see JLayer#setLayerEventMask(long)
+ * @see #installUI(javax.swing.JComponent)
+ * @see #uninstallUI(javax.swing.JComponent)
+ */
+ protected void processFocusEvent(FocusEvent e, JLayer extends V> l) {
+ }
+
+ /**
+ * Processes key events occurring on the {@link JLayer}
+ * or any of its subcomponents.
+ *
+ * This method is not called unless key events are
+ * enabled for the {@code JLayer} objects, this {@code LayerUI} is set to.
+ * Key events are enabled in the overridden {@link #installUI} method
+ * and should be disabled in the {@link #uninstallUI} method after that.
+ *
+ * public void installUI(JComponent c) {
+ * super.installUI(c);
+ * JLayer l = (JLayer) c;
+ * l.setLayerEventMask(AWTEvent.KEY_EVENT_MASK);
+ * }
+ *
+ * public void unistallUI(JComponent c) {
+ * super.uninstallUI(c);
+ * JLayer l = (JLayer) c;
+ * l.setLayerEventMask(0);
+ * }
+ *
+ *
+ * @param e the {@code KeyEvent} to be processed
+ * @param l the layer this {@code LayerUI} instance is set to
+ *
+ * @see JLayer#setLayerEventMask(long)
+ * @see #installUI(javax.swing.JComponent)
+ * @see #uninstallUI(javax.swing.JComponent)
+ */
+ protected void processKeyEvent(KeyEvent e, JLayer extends V> l) {
+ }
+
+ /**
+ * Processes mouse events occurring on the {@link JLayer}
+ * or any of its subcomponents.
+ *
+ * This method is not called unless mouse events are
+ * enabled for the {@code JLayer} objects, this {@code LayerUI} is set to.
+ * Mouse events are enabled in the overridden {@link #installUI} method
+ * and should be disabled in the {@link #uninstallUI} method after that.
+ *
+ * public void installUI(JComponent c) {
+ * super.installUI(c);
+ * JLayer l = (JLayer) c;
+ * l.setLayerEventMask(AWTEvent.MOUSE_EVENT_MASK);
+ * }
+ *
+ * public void unistallUI(JComponent c) {
+ * super.uninstallUI(c);
+ * JLayer l = (JLayer) c;
+ * l.setLayerEventMask(0);
+ * }
+ *
+ *
+ * @param e the {@code MouseEvent} to be processed
+ * @param l the layer this {@code LayerUI} instance is set to
+ *
+ * @see JLayer#setLayerEventMask(long)
+ * @see #installUI(javax.swing.JComponent)
+ * @see #uninstallUI(javax.swing.JComponent)
+ */
+ protected void processMouseEvent(MouseEvent e, JLayer extends V> l) {
+ }
+
+ /**
+ * Processes mouse motion event occurring on the {@link JLayer}
+ * or any of its subcomponents.
+ *
+ * This method is not called unless mouse motion events are
+ * enabled for the {@code JLayer} objects, this {@code LayerUI} is set to.
+ * Mouse motion events are enabled in the overridden {@link #installUI} method
+ * and should be disabled in the {@link #uninstallUI} method after that.
+ *
+ * public void installUI(JComponent c) {
+ * super.installUI(c);
+ * JLayer l = (JLayer) c;
+ * l.setLayerEventMask(AWTEvent.MOUSE_MOTION_EVENT_MASK);
+ * }
+ *
+ * public void unistallUI(JComponent c) {
+ * super.uninstallUI(c);
+ * JLayer l = (JLayer) c;
+ * l.setLayerEventMask(0);
+ * }
+ *
+ *
+ * @param e the {@code MouseEvent} to be processed
+ * @param l the layer this {@code LayerUI} instance is set to
+ *
+ * @see JLayer#setLayerEventMask(long)
+ * @see #installUI(javax.swing.JComponent)
+ * @see #uninstallUI(javax.swing.JComponent)
+ */
+ protected void processMouseMotionEvent(MouseEvent e, JLayer extends V> l) {
+ }
+
+ /**
+ * Processes mouse wheel event occurring on the {@link JLayer}
+ * or any of its subcomponents.
+ *
+ * This method is not called unless mouse wheel events are
+ * enabled for the {@code JLayer} objects, this {@code LayerUI} is set to.
+ * Mouse wheel events are enabled in the overridden {@link #installUI} method
+ * and should be disabled in the {@link #uninstallUI} method after that.
+ *
+ * public void installUI(JComponent c) {
+ * super.installUI(c);
+ * JLayer l = (JLayer) c;
+ * l.setLayerEventMask(AWTEvent.MOUSE_WHEEL_EVENT_MASK);
+ * }
+ *
+ * public void unistallUI(JComponent c) {
+ * super.uninstallUI(c);
+ * JLayer l = (JLayer) c;
+ * l.setLayerEventMask(0);
+ * }
+ *
+ *
+ * @param e the {@code MouseEvent} to be processed
+ * @param l the layer this {@code LayerUI} instance is set to
+ *
+ * @see JLayer#setLayerEventMask(long)
+ * @see #installUI(javax.swing.JComponent)
+ * @see #uninstallUI(javax.swing.JComponent)
+ */
+ protected void processMouseWheelEvent(MouseWheelEvent e, JLayer extends V> l) {
+ }
+
+ /**
+ * Processes input event occurring on the {@link JLayer}
+ * or any of its subcomponents.
+ *
+ * This method is not called unless input events are
+ * enabled for the {@code JLayer} objects, this {@code LayerUI} is set to.
+ * Input events are enabled in the overridden {@link #installUI} method
+ * and should be disabled in the {@link #uninstallUI} method after that.
+ *
+ * public void installUI(JComponent c) {
+ * super.installUI(c);
+ * JLayer l = (JLayer) c;
+ * l.setLayerEventMask(AWTEvent.INPUT_METHOD_EVENT_MASK);
+ * }
+ *
+ * public void unistallUI(JComponent c) {
+ * super.uninstallUI(c);
+ * JLayer l = (JLayer) c;
+ * l.setLayerEventMask(0);
+ * }
+ *
+ *
+ * @param e the {@code InputMethodEvent} to be processed
+ * @param l the layer this {@code LayerUI} instance is set to
+ *
+ * @see JLayer#setLayerEventMask(long)
+ * @see #installUI(javax.swing.JComponent)
+ * @see #uninstallUI(javax.swing.JComponent)
+ */
+ protected void processInputMethodEvent(InputMethodEvent e, JLayer extends V> l) {
+ }
+
+ /**
+ * Processes hierarchy event occurring on the {@link JLayer}
+ * or any of its subcomponents.
+ *
+ * This method is not called unless hierarchy events are
+ * enabled for the {@code JLayer} objects, this {@code LayerUI} is set to.
+ * Hierarchy events are enabled in the overridden {@link #installUI} method
+ * and should be disabled in the {@link #uninstallUI} method after that.
+ *
+ * public void installUI(JComponent c) {
+ * super.installUI(c);
+ * JLayer l = (JLayer) c;
+ * l.setLayerEventMask(AWTEvent.HIERARCHY_EVENT_MASK);
+ * }
+ *
+ * public void unistallUI(JComponent c) {
+ * super.uninstallUI(c);
+ * JLayer l = (JLayer) c;
+ * l.setLayerEventMask(0);
+ * }
+ *
+ *
+ * @param e the {@code HierarchyEvent} to be processed
+ * @param l the layer this {@code LayerUI} instance is set to
+ *
+ * @see JLayer#setLayerEventMask(long)
+ * @see #installUI(javax.swing.JComponent)
+ * @see #uninstallUI(javax.swing.JComponent)
+ */
+ protected void processHierarchyEvent(HierarchyEvent e, JLayer extends V> l) {
+ }
+
+ /**
+ * Processes hierarchy bounds event occurring on the {@link JLayer}
+ * or any of its subcomponents.
+ *
+ * This method is not called unless hierarchy bounds events are
+ * enabled for the {@code JLayer} objects, this {@code LayerUI} is set to.
+ * Hierarchy bounds events are enabled in the overridden {@link #installUI}
+ * method and should be disabled in the {@link #uninstallUI} method after that.
+ *
+ * public void installUI(JComponent c) {
+ * super.installUI(c);
+ * JLayer l = (JLayer) c;
+ * l.setLayerEventMask(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK);
+ * }
+ *
+ * public void unistallUI(JComponent c) {
+ * super.uninstallUI(c);
+ * JLayer l = (JLayer) c;
+ * l.setLayerEventMask(0);
+ * }
+ *
+ *
+ * @param e the {@code HierarchyEvent} to be processed
+ * @param l the layer this {@code LayerUI} instance is set to
+ *
+ * @see JLayer#setLayerEventMask(long)
+ * @see #installUI(javax.swing.JComponent)
+ * @see #uninstallUI(javax.swing.JComponent)
+ */
+ protected void processHierarchyBoundsEvent(HierarchyEvent e, JLayer extends V> l) {
}
/**
@@ -250,14 +627,29 @@ public class LayerUI
propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
}
+ /**
+ * Repaints all {@code JLayer} instances this {@code LayerUI} is set to.
+ * Call this method when the state of this {@code LayerUI} is changed
+ * and the visual appearance of its {@code JLayer} objects needs to be updated.
+ *
+ * @see Component#repaint()
+ */
+ protected void repaintLayer() {
+ firePropertyChange("dirty", null, null);
+ }
+
/**
* Notifies the {@code LayerUI} when any of its property are changed
- * and enables updating every {@code JLayer} this {@code LayerUI} instance is set to.
+ * and enables updating every {@code JLayer}
+ * this {@code LayerUI} instance is set to.
*
* @param evt the PropertyChangeEvent generated by this {@code LayerUI}
* @param l the {@code JLayer} this LayerUI is set to
*/
public void applyPropertyChange(PropertyChangeEvent evt, JLayer extends V> l) {
+ if ("dirty".equals(evt.getPropertyName())) {
+ l.repaint();
+ }
}
/**
diff --git a/src/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java b/src/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java
index 1e5d80f8ea24bcd48d302437490f7aeab8f1672f..77709a94401336d4bf5ae813fc52e91c8b8da95e 100644
--- a/src/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java
+++ b/src/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java
@@ -486,7 +486,7 @@ public class BasicDirectoryModel extends AbstractListModel implements PropertyCh
}
if (remSize > 0 && addSize == 0) {
fireIntervalRemoved(BasicDirectoryModel.this, remStart, remStart + remSize - 1);
- } else if (addSize > 0 && remSize == 0 && fileCache.size() > addSize) {
+ } else if (addSize > 0 && remSize == 0 && addStart + addSize <= fileCache.size()) {
fireIntervalAdded(BasicDirectoryModel.this, addStart, addStart + addSize - 1);
} else {
fireContentsChanged();
diff --git a/src/share/classes/javax/swing/plaf/metal/OceanTheme.java b/src/share/classes/javax/swing/plaf/metal/OceanTheme.java
index 2aa299fe5cc60845d22fb52442191fb727aca0dd..2e1a8b2b4bf4cb75020ca5cae9984b7b932599ca 100644
--- a/src/share/classes/javax/swing/plaf/metal/OceanTheme.java
+++ b/src/share/classes/javax/swing/plaf/metal/OceanTheme.java
@@ -32,6 +32,7 @@ import javax.swing.*;
import javax.swing.plaf.*;
import sun.swing.SwingUtilities2;
import sun.swing.PrintColorUIResource;
+import sun.swing.SwingLazyValue;
/**
* The default theme for the {@code MetalLookAndFeel}.
@@ -128,7 +129,7 @@ public class OceanTheme extends DefaultMetalTheme {
* @throws NullPointerException if {@code table} is {@code null}
*/
public void addCustomEntriesToTable(UIDefaults table) {
- Object focusBorder = new UIDefaults.ProxyLazyValue(
+ Object focusBorder = new SwingLazyValue(
"javax.swing.plaf.BorderUIResource$LineBorderUIResource",
new Object[] {getPrimary1()});
// .30 0 DDE8F3 white secondary2
diff --git a/src/share/classes/javax/swing/plaf/synth/SynthTableUI.java b/src/share/classes/javax/swing/plaf/synth/SynthTableUI.java
index 1b8cf9894465b4c8f915973d8176c014cb96d407..dcd6b6275bf4c969571e386cb7136945eb7fe1d5 100644
--- a/src/share/classes/javax/swing/plaf/synth/SynthTableUI.java
+++ b/src/share/classes/javax/swing/plaf/synth/SynthTableUI.java
@@ -638,7 +638,7 @@ class SynthTableUI extends BasicTableUI implements SynthUI,
if ((b == null || b instanceof UIResource
|| component instanceof SynthBooleanTableCellRenderer)
&& !table.isCellSelected(row, column)) {
- if (alternateColor != null && row % 2 == 0) {
+ if (alternateColor != null && row % 2 != 0) {
component.setBackground(alternateColor);
}
}
diff --git a/src/share/classes/javax/swing/table/DefaultTableCellRenderer.java b/src/share/classes/javax/swing/table/DefaultTableCellRenderer.java
index 07e7265c9bf6d6bcee3b78efa4ec40e36e2b46db..0c2b6a97367f4a101bf1fa0d5c09d87d1a2bafab 100644
--- a/src/share/classes/javax/swing/table/DefaultTableCellRenderer.java
+++ b/src/share/classes/javax/swing/table/DefaultTableCellRenderer.java
@@ -214,8 +214,9 @@ public class DefaultTableCellRenderer extends JLabel
: table.getBackground();
if (background == null || background instanceof javax.swing.plaf.UIResource) {
Color alternateColor = DefaultLookup.getColor(this, ui, "Table.alternateRowColor");
- if (alternateColor != null && row % 2 == 0)
+ if (alternateColor != null && row % 2 != 0) {
background = alternateColor;
+ }
}
super.setForeground(unselectedForeground != null
? unselectedForeground
diff --git a/src/share/classes/javax/swing/text/JTextComponent.java b/src/share/classes/javax/swing/text/JTextComponent.java
index 371afda48b049020ac985b62b64e7417acf7abd9..25ddaf9e3cc4dd4e992266dc8406a04678d9fdd2 100644
--- a/src/share/classes/javax/swing/text/JTextComponent.java
+++ b/src/share/classes/javax/swing/text/JTextComponent.java
@@ -2069,7 +2069,7 @@ public abstract class JTextComponent extends JComponent implements Scrollable, A
* width to match its own
*/
public boolean getScrollableTracksViewportWidth() {
- JViewport port = SwingUtilities2.getViewport(this);
+ JViewport port = SwingUtilities.getParentViewport(this);
if (port != null) {
return port.getWidth() > getPreferredSize().width;
}
@@ -2090,7 +2090,7 @@ public abstract class JTextComponent extends JComponent implements Scrollable, A
* to match its own
*/
public boolean getScrollableTracksViewportHeight() {
- JViewport port = SwingUtilities2.getViewport(this);
+ JViewport port = SwingUtilities.getParentViewport(this);
if (port != null) {
return (port.getHeight() > getPreferredSize().height);
}
diff --git a/src/share/classes/org/ietf/jgss/GSSContext.java b/src/share/classes/org/ietf/jgss/GSSContext.java
index 5fb769dc523ab75fef8ad883f3e9633c16fca23c..e8eb70275807d16ad854100b2f4982fdd8518d80 100644
--- a/src/share/classes/org/ietf/jgss/GSSContext.java
+++ b/src/share/classes/org/ietf/jgss/GSSContext.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2001 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2000-2009 Sun Microsystems, Inc. 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
@@ -678,7 +678,7 @@ public interface GSSContext {
* are not definitive then the method will attempt to treat all
* available bytes as part of the token.
*
- * Other than the possible blocking behaviour described above, this
+ * Other than the possible blocking behavior described above, this
* method is equivalent to the byte array based {@link #unwrap(byte[],
* int, int, MessageProp) unwrap} method.
*
@@ -826,7 +826,7 @@ public interface GSSContext {
* are not definitive then the method will attempt to treat all
* available bytes as part of the token.
*
- * Other than the possible blocking behaviour described above, this
+ * Other than the possible blocking behavior described above, this
* method is equivalent to the byte array based {@link #verifyMIC(byte[],
* int, int, byte[], int, int, MessageProp) verifyMIC} method.
*
@@ -917,7 +917,7 @@ public interface GSSContext {
* getMutualAuthState} method.
*
* @param state a boolean value indicating whether mutual
- * authentication shouls be used or not.
+ * authentication should be used or not.
* @see #getMutualAuthState()
*
* @throws GSSException containing the following
@@ -928,7 +928,7 @@ public interface GSSContext {
/**
* Requests that replay detection be enabled for the
- * per-message security services after context establishemnt. This
+ * per-message security services after context establishment. This
* request can only be made on the context initiator's side and it has
* to be done prior to the first call to
* initSecContext. During context establishment replay
@@ -958,7 +958,7 @@ public interface GSSContext {
/**
* Requests that sequence checking be enabled for the
- * per-message security services after context establishemnt. This
+ * per-message security services after context establishment. This
* request can only be made on the context initiator's side and it has
* to be done prior to the first call to
* initSecContext. During context establishment sequence
diff --git a/src/share/classes/sun/awt/datatransfer/DataTransferer.java b/src/share/classes/sun/awt/datatransfer/DataTransferer.java
index 521e691024c5ef6e4732938dbedfeceda1a9e0a4..277d3bd9e28a48c0bd92eac5c31526845e246774 100644
--- a/src/share/classes/sun/awt/datatransfer/DataTransferer.java
+++ b/src/share/classes/sun/awt/datatransfer/DataTransferer.java
@@ -63,8 +63,6 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
-import java.rmi.MarshalledObject;
-
import java.security.AccessControlContext;
import java.security.AccessControlException;
import java.security.AccessController;
@@ -493,6 +491,13 @@ public abstract class DataTransferer {
}
}
+ /**
+ * Returns {@code true} if the given type is a java.rmi.Remote.
+ */
+ public static boolean isRemote(Class> type) {
+ return RMI.isRemote(type);
+ }
+
/**
* Returns an Iterator which traverses a SortedSet of Strings which are
* a total order of the standard character sets supported by the JRE. The
@@ -1360,7 +1365,7 @@ search:
// Source data is an RMI object
} else if (flavor.isRepresentationClassRemote()) {
- MarshalledObject mo = new MarshalledObject(obj);
+ Object mo = RMI.newMarshalledObject(obj);
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(mo);
oos.close();
@@ -1671,7 +1676,7 @@ search:
try {
byte[] ba = inputStreamToByteArray(str);
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(ba));
- Object ret = ((MarshalledObject)(ois.readObject())).get();
+ Object ret = RMI.getMarshalledObject(ois.readObject());
ois.close();
str.close();
return ret;
@@ -2669,8 +2674,12 @@ search:
Integer.valueOf(0));
nonTextRepresentationsMap.put(java.io.Serializable.class,
Integer.valueOf(1));
- nonTextRepresentationsMap.put(java.rmi.Remote.class,
- Integer.valueOf(2));
+
+ Class> remoteClass = RMI.remoteClass();
+ if (remoteClass != null) {
+ nonTextRepresentationsMap.put(remoteClass,
+ Integer.valueOf(2));
+ }
nonTextRepresentations =
Collections.unmodifiableMap(nonTextRepresentationsMap);
@@ -2900,4 +2909,95 @@ search:
}
}
}
+
+ /**
+ * A class that provides access to java.rmi.Remote and java.rmi.MarshalledObject
+ * without creating a static dependency.
+ */
+ private static class RMI {
+ private static final Class> remoteClass = getClass("java.rmi.Remote");
+ private static final Class> marshallObjectClass =
+ getClass("java.rmi.MarshalledObject");
+ private static final Constructor> marshallCtor =
+ getConstructor(marshallObjectClass, Object.class);
+ private static final Method marshallGet =
+ getMethod(marshallObjectClass, "get");
+
+ private static Class> getClass(String name) {
+ try {
+ return Class.forName(name, true, null);
+ } catch (ClassNotFoundException e) {
+ return null;
+ }
+ }
+
+ private static Constructor> getConstructor(Class> c, Class>... types) {
+ try {
+ return (c == null) ? null : c.getDeclaredConstructor(types);
+ } catch (NoSuchMethodException x) {
+ throw new AssertionError(x);
+ }
+ }
+
+ private static Method getMethod(Class> c, String name, Class>... types) {
+ try {
+ return (c == null) ? null : c.getMethod(name, types);
+ } catch (NoSuchMethodException e) {
+ throw new AssertionError(e);
+ }
+ }
+
+ /**
+ * Returns {@code true} if the given class is java.rmi.Remote.
+ */
+ static boolean isRemote(Class> c) {
+ return (remoteClass == null) ? null : remoteClass.isAssignableFrom(c);
+ }
+
+ /**
+ * Returns java.rmi.Remote.class if RMI is present; otherwise {@code null}.
+ */
+ static Class> remoteClass() {
+ return remoteClass;
+ }
+
+ /**
+ * Returns a new MarshalledObject containing the serialized representation
+ * of the given object.
+ */
+ static Object newMarshalledObject(Object obj) throws IOException {
+ try {
+ return marshallCtor.newInstance(obj);
+ } catch (InstantiationException x) {
+ throw new AssertionError(x);
+ } catch (IllegalAccessException x) {
+ throw new AssertionError(x);
+ } catch (InvocationTargetException x) {
+ Throwable cause = x.getCause();
+ if (cause instanceof IOException)
+ throw (IOException)cause;
+ throw new AssertionError(x);
+ }
+ }
+
+ /**
+ * Returns a new copy of the contained marshalled object.
+ */
+ static Object getMarshalledObject(Object obj)
+ throws IOException, ClassNotFoundException
+ {
+ try {
+ return marshallGet.invoke(obj);
+ } catch (IllegalAccessException x) {
+ throw new AssertionError(x);
+ } catch (InvocationTargetException x) {
+ Throwable cause = x.getCause();
+ if (cause instanceof IOException)
+ throw (IOException)cause;
+ if (cause instanceof ClassNotFoundException)
+ throw (ClassNotFoundException)cause;
+ throw new AssertionError(x);
+ }
+ }
+ }
}
diff --git a/src/share/classes/sun/awt/im/InputMethodManager.java b/src/share/classes/sun/awt/im/InputMethodManager.java
index caba8d6a15263d4b4ffd4356bf4030e68c251985..9ee45e28e5339ddcf60d0677969049e60a6f70dc 100644
--- a/src/share/classes/sun/awt/im/InputMethodManager.java
+++ b/src/share/classes/sun/awt/im/InputMethodManager.java
@@ -358,7 +358,9 @@ class ExecutableInputMethodManager extends InputMethodManager
AppContext requesterAppContext = SunToolkit.targetToAppContext(requester);
synchronized (lock) {
SunToolkit.postEvent(requesterAppContext, event);
- lock.wait();
+ while (!event.isDispatched()) {
+ lock.wait();
+ }
}
Throwable eventThrowable = event.getThrowable();
diff --git a/src/share/classes/sun/awt/shell/ShellFolder.java b/src/share/classes/sun/awt/shell/ShellFolder.java
index cf3c78933849048a44d5ba1506b25ed32d37c337..c5b2296b2b754eb2781ac35eeb042997bcdc3ddc 100644
--- a/src/share/classes/sun/awt/shell/ShellFolder.java
+++ b/src/share/classes/sun/awt/shell/ShellFolder.java
@@ -201,6 +201,8 @@ public abstract class ShellFolder extends File {
private static ShellFolderManager shellFolderManager;
+ private static Invoker invoker;
+
static {
String managerClassName = (String)Toolkit.getDefaultToolkit().
getDesktopProperty("Shell.shellFolderManager");
@@ -225,6 +227,8 @@ public abstract class ShellFolder extends File {
throw new Error ("Could not access Shell Folder Manager: "
+ managerClass.getName());
}
+
+ invoker = shellFolderManager.createInvoker();
}
/**
@@ -486,21 +490,6 @@ public abstract class ShellFolder extends File {
return null;
}
- private static Invoker invoker;
-
- /**
- * Provides the single access point to the {@link Invoker}. It is guaranteed that the value
- * returned by this method will be always the same.
- *
- * @return the singleton instance of {@link Invoker}
- */
- public static Invoker getInvoker() {
- if (invoker == null) {
- invoker = shellFolderManager.createInvoker();
- }
- return invoker;
- }
-
/**
* Invokes the {@code task} which doesn't throw checked exceptions
* from its {@code call} method. If invokation is interrupted then Thread.currentThread().isInterrupted() will
@@ -522,7 +511,7 @@ public abstract class ShellFolder extends File {
public static T invoke(Callable task, Class exceptionClass)
throws InterruptedException, E {
try {
- return getInvoker().invoke(task);
+ return invoker.invoke(task);
} catch (Exception e) {
if (e instanceof RuntimeException) {
// Rethrow unchecked exceptions
diff --git a/src/share/classes/sun/font/Font2D.java b/src/share/classes/sun/font/Font2D.java
index c344ebb70076c004770ae78fe7c908f95aaaf423..3a930d6502e601d529e4d0e3a029019f6052530e 100644
--- a/src/share/classes/sun/font/Font2D.java
+++ b/src/share/classes/sun/font/Font2D.java
@@ -320,21 +320,6 @@ public abstract class Font2D {
lastFontStrike = new SoftReference(strike);
StrikeCache.refStrike(strike);
return strike;
- } else {
- /* We have found a cleared reference that has not yet
- * been removed by the disposer.
- * If we make this reference unreachable by removing it
- * from the map,or overwriting it with a new reference to
- * a new strike, then it is possible it may never be
- * enqueued for disposal. That is the implication of
- * the docs for java.lang.ref. So on finding a cleared
- * reference, we need to dispose the native resources,
- * if they haven't already been freed.
- * The reference object needs to have a reference to
- * the disposer instance for this to occur.
- */
- ((StrikeCache.DisposableStrike)strikeRef)
- .getDisposer().dispose();
}
}
/* When we create a new FontStrike instance, we *must*
diff --git a/src/share/classes/sun/font/FontDesignMetrics.java b/src/share/classes/sun/font/FontDesignMetrics.java
index 929c0d21dd8d42b9d03ad4dde3fbadc73970d9fc..e81c397fdea60ea3a7809cba1c21d83ca6248d9d 100644
--- a/src/share/classes/sun/font/FontDesignMetrics.java
+++ b/src/share/classes/sun/font/FontDesignMetrics.java
@@ -171,7 +171,7 @@ public final class FontDesignMetrics extends FontMetrics {
* out we can clear the keys from the table.
*/
private static class KeyReference extends SoftReference
- implements DisposerRecord {
+ implements DisposerRecord, Disposer.PollDisposable {
static ReferenceQueue queue = Disposer.getQueue();
diff --git a/src/share/classes/sun/font/FontStrikeDisposer.java b/src/share/classes/sun/font/FontStrikeDisposer.java
index 7245cc3736f0ac0c5cef8b4b2808e2e3d5f80edf..3ee33eccea61cb6a0f5d1e8f6582814c2cf13a93 100644
--- a/src/share/classes/sun/font/FontStrikeDisposer.java
+++ b/src/share/classes/sun/font/FontStrikeDisposer.java
@@ -25,6 +25,7 @@
package sun.font;
+import sun.java2d.Disposer;
import sun.java2d.DisposerRecord;
/*
@@ -49,7 +50,8 @@ import sun.java2d.DisposerRecord;
* entries would be removed much more promptly than we need.
*/
-class FontStrikeDisposer implements DisposerRecord {
+class FontStrikeDisposer
+ implements DisposerRecord, Disposer.PollDisposable {
Font2D font2D;
FontStrikeDesc desc;
diff --git a/src/share/classes/sun/font/StrikeCache.java b/src/share/classes/sun/font/StrikeCache.java
index 945b01f867ec3d4fbb814b97a98f735500b38b24..9e5b02a865031a9d1606d80768f6ff0103a82d50 100644
--- a/src/share/classes/sun/font/StrikeCache.java
+++ b/src/share/classes/sun/font/StrikeCache.java
@@ -254,9 +254,20 @@ public final class StrikeCache {
// because they may be accessed on that thread at the time of the
// disposal (for example, when the accel. cache is invalidated)
- // REMIND: this look a bit heavyweight, but should be ok
- // because strike disposal is a relatively infrequent operation,
- // more worrisome is the necessity of getting a GC here.
+ // Whilst this is a bit heavyweight, in most applications
+ // strike disposal is a relatively infrequent operation, so it
+ // doesn't matter. But in some tests that use vast numbers
+ // of strikes, the switching back and forth is measurable.
+ // So the "pollRemove" call is added to batch up the work.
+ // If we are polling we know we've already been called back
+ // and can directly dispose the record.
+ // Also worrisome is the necessity of getting a GC here.
+
+ if (Disposer.pollingQueue) {
+ doDispose(disposer);
+ return;
+ }
+
RenderQueue rq = null;
GraphicsEnvironment ge =
GraphicsEnvironment.getLocalGraphicsEnvironment();
@@ -277,6 +288,7 @@ public final class StrikeCache {
rq.flushAndInvokeNow(new Runnable() {
public void run() {
doDispose(disposer);
+ Disposer.pollRemove();
}
});
} finally {
diff --git a/src/share/classes/sun/java2d/Disposer.java b/src/share/classes/sun/java2d/Disposer.java
index bf9ea8ad71a7b7146dbf4bbe19520aa64cb81ce1..4433a278d5d12d4792d8b93357a2d72dad96c6fc 100644
--- a/src/share/classes/sun/java2d/Disposer.java
+++ b/src/share/classes/sun/java2d/Disposer.java
@@ -29,6 +29,7 @@ import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.PhantomReference;
import java.lang.ref.WeakReference;
+import java.util.ArrayList;
import java.util.Hashtable;
/**
@@ -146,6 +147,7 @@ public class Disposer implements Runnable {
rec.dispose();
obj = null;
rec = null;
+ clearDeferredRecords();
} catch (Exception e) {
System.out.println("Exception while removing reference: " + e);
e.printStackTrace();
@@ -153,6 +155,85 @@ public class Disposer implements Runnable {
}
}
+ /*
+ * This is a marker interface that, if implemented, means it
+ * doesn't acquire any special locks, and is safe to
+ * be disposed in the poll loop on whatever thread
+ * which happens to be the Toolkit thread, is in use.
+ */
+ public static interface PollDisposable {
+ };
+
+ private static ArrayList deferredRecords = null;
+
+ private static void clearDeferredRecords() {
+ if (deferredRecords == null || deferredRecords.isEmpty()) {
+ return;
+ }
+ for (int i=0;i(5);
+ }
+ deferredRecords.add(rec);
+ }
+ }
+ } catch (Exception e) {
+ System.out.println("Exception while removing reference: " + e);
+ e.printStackTrace();
+ } finally {
+ pollingQueue = false;
+ }
+ }
+
private static native void initIDs();
/*
diff --git a/src/share/classes/sun/java2d/SunGraphics2D.java b/src/share/classes/sun/java2d/SunGraphics2D.java
index c63db02e75673be2538d1401b8ec62295db0ad86..951876eb23753a1c55b90083d6178fc1e6e6ef96 100644
--- a/src/share/classes/sun/java2d/SunGraphics2D.java
+++ b/src/share/classes/sun/java2d/SunGraphics2D.java
@@ -257,7 +257,6 @@ public final class SunGraphics2D
font = defaultFont;
}
- loops = sd.getRenderLoops(this);
setDevClip(sd.getBounds());
invalidatePipe();
}
@@ -367,6 +366,7 @@ public final class SunGraphics2D
shapepipe = invalidpipe;
textpipe = invalidpipe;
imagepipe = invalidpipe;
+ loops = null;
}
public void validatePipe() {
diff --git a/src/share/classes/sun/java2d/SurfaceData.java b/src/share/classes/sun/java2d/SurfaceData.java
index 65a04c23220c726a9981d5d85d045cff35387a8d..95ef18c85f4231af965664dd5d7c1e19ee2c15fe 100644
--- a/src/share/classes/sun/java2d/SurfaceData.java
+++ b/src/share/classes/sun/java2d/SurfaceData.java
@@ -69,6 +69,7 @@ import sun.java2d.pipe.DrawImagePipe;
import sun.java2d.pipe.DrawImage;
import sun.awt.SunHints;
import sun.awt.image.SurfaceManager;
+import sun.java2d.pipe.LoopBasedPipe;
/**
* This class provides various pieces of information relevant to a
@@ -506,7 +507,6 @@ public abstract class SurfaceData
sg2d.textpipe = solidTextRenderer;
}
sg2d.shapepipe = colorPrimitives;
- sg2d.loops = getRenderLoops(sg2d);
// assert(sg2d.surfaceData == this);
}
} else if (sg2d.compositeState == sg2d.COMP_CUSTOM) {
@@ -603,9 +603,18 @@ public abstract class SurfaceData
sg2d.textpipe = getTextPipe(sg2d, false /* AA==OFF */);
sg2d.shapepipe = colorPrimitives;
- sg2d.loops = getRenderLoops(sg2d);
// assert(sg2d.surfaceData == this);
}
+
+ // check for loops
+ if (sg2d.textpipe instanceof LoopBasedPipe ||
+ sg2d.shapepipe instanceof LoopBasedPipe ||
+ sg2d.fillpipe instanceof LoopBasedPipe ||
+ sg2d.drawpipe instanceof LoopBasedPipe ||
+ sg2d.imagepipe instanceof LoopBasedPipe)
+ {
+ sg2d.loops = getRenderLoops(sg2d);
+ }
}
/* Return the text pipe to be used based on the graphics AA hint setting,
diff --git a/src/share/classes/sun/java2d/pipe/AATextRenderer.java b/src/share/classes/sun/java2d/pipe/AATextRenderer.java
index 389db9cbefdfbe41d4ffc34a36b57eb905036d01..602e5be5ef80340a8823863b6948b9d094b60982 100644
--- a/src/share/classes/sun/java2d/pipe/AATextRenderer.java
+++ b/src/share/classes/sun/java2d/pipe/AATextRenderer.java
@@ -34,8 +34,9 @@ import sun.font.GlyphList;
* a solid source colour to an opaque destination.
*/
-public class AATextRenderer extends GlyphListLoopPipe {
-
+public class AATextRenderer extends GlyphListLoopPipe
+ implements LoopBasedPipe
+{
protected void drawGlyphList(SunGraphics2D sg2d, GlyphList gl) {
sg2d.loops.drawGlyphListAALoop.DrawGlyphListAA(sg2d, sg2d.surfaceData,
gl);
diff --git a/src/share/classes/sun/java2d/pipe/GlyphListLoopPipe.java b/src/share/classes/sun/java2d/pipe/GlyphListLoopPipe.java
index cbe76016cf748c9670972911e9de2714a133a019..385a768cf9e9f4bb6ddbfc5e8d66143e1f2bbcd7 100644
--- a/src/share/classes/sun/java2d/pipe/GlyphListLoopPipe.java
+++ b/src/share/classes/sun/java2d/pipe/GlyphListLoopPipe.java
@@ -36,8 +36,9 @@ import sun.font.GlyphList;
* the installed loop may not match the glyphvector.
*/
-public abstract class GlyphListLoopPipe extends GlyphListPipe {
-
+public abstract class GlyphListLoopPipe extends GlyphListPipe
+ implements LoopBasedPipe
+{
protected void drawGlyphList(SunGraphics2D sg2d, GlyphList gl,
int aaHint) {
switch (aaHint) {
diff --git a/test/tools/launcher/libraryCaller.h b/src/share/classes/sun/java2d/pipe/LoopBasedPipe.java
similarity index 63%
rename from test/tools/launcher/libraryCaller.h
rename to src/share/classes/sun/java2d/pipe/LoopBasedPipe.java
index df2ce33f8b665934012580356ceeb8142b1c793f..34b9067335c4564dd67bf1fc42f769edaada6dda 100644
--- a/test/tools/launcher/libraryCaller.h
+++ b/src/share/classes/sun/java2d/pipe/LoopBasedPipe.java
@@ -1,11 +1,12 @@
-
/*
- * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009 Sun Microsystems, Inc. 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.
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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
@@ -22,25 +23,15 @@
* have any questions.
*/
-/* DO NOT EDIT THIS FILE - it is machine generated */
-
-#include
-/* Header for class libraryCaller */
+package sun.java2d.pipe;
-#ifndef _Included_libraryCaller
-#define _Included_libraryCaller
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * Class: libraryCaller
- * Method: number
- * Signature: ()I
+/**
+ * This is a marker interface used by Pipes that need RenderLoops.
+ * RenderLoops are validated in SurfaceData when a pipe is recognised to
+ * implement this interface.
+ *
+ * @author Mario Torre
*/
-JNIEXPORT jint JNICALL Java_libraryCaller_number
- (JNIEnv *, jclass);
+public interface LoopBasedPipe {
-#ifdef __cplusplus
}
-#endif
-#endif
diff --git a/src/share/classes/sun/java2d/pipe/LoopPipe.java b/src/share/classes/sun/java2d/pipe/LoopPipe.java
index 93334e56fac5098859b7a66c92e00df46871edd9..a7d2c1dae23e26f7e7200225859ced9fbf305c9b 100644
--- a/src/share/classes/sun/java2d/pipe/LoopPipe.java
+++ b/src/share/classes/sun/java2d/pipe/LoopPipe.java
@@ -46,7 +46,8 @@ import sun.awt.SunHints;
public class LoopPipe
implements PixelDrawPipe,
PixelFillPipe,
- ShapeDrawPipe
+ ShapeDrawPipe,
+ LoopBasedPipe
{
final static RenderingEngine RenderEngine = RenderingEngine.getInstance();
diff --git a/src/share/classes/sun/java2d/pipe/SolidTextRenderer.java b/src/share/classes/sun/java2d/pipe/SolidTextRenderer.java
index 52d1a709a531232f48ad3cb56ac0344190c9315c..bb8778aba93a9334f8218ff53a29f8d11f69029e 100644
--- a/src/share/classes/sun/java2d/pipe/SolidTextRenderer.java
+++ b/src/share/classes/sun/java2d/pipe/SolidTextRenderer.java
@@ -35,8 +35,9 @@ import sun.font.GlyphList;
* a solid source colour to an opaque destination.
*/
-public class SolidTextRenderer extends GlyphListLoopPipe {
-
+public class SolidTextRenderer extends GlyphListLoopPipe
+ implements LoopBasedPipe
+{
protected void drawGlyphList(SunGraphics2D sg2d, GlyphList gl) {
sg2d.loops.drawGlyphListLoop.DrawGlyphList(sg2d, sg2d.surfaceData, gl);
}
diff --git a/src/share/classes/sun/java2d/pipe/SpanShapeRenderer.java b/src/share/classes/sun/java2d/pipe/SpanShapeRenderer.java
index 574ebed818842409068d5a2156c9db7fbd577578..a02b761c8dcf97f12215b58373ca47b84a1e35d3 100644
--- a/src/share/classes/sun/java2d/pipe/SpanShapeRenderer.java
+++ b/src/share/classes/sun/java2d/pipe/SpanShapeRenderer.java
@@ -65,7 +65,9 @@ public abstract class SpanShapeRenderer implements ShapeDrawPipe {
}
}
- public static class Simple extends SpanShapeRenderer {
+ public static class Simple extends SpanShapeRenderer
+ implements LoopBasedPipe
+ {
public Object startSequence(SunGraphics2D sg, Shape s,
Rectangle devR, int[] bbox) {
return sg;
diff --git a/src/share/classes/sun/java2d/pisces/Renderer.java b/src/share/classes/sun/java2d/pisces/Renderer.java
index 3ada6c73600118ebf22387cffda6a2333b381ca7..2aba41121611d35314763e1b0263063362ff7f19 100644
--- a/src/share/classes/sun/java2d/pisces/Renderer.java
+++ b/src/share/classes/sun/java2d/pisces/Renderer.java
@@ -775,10 +775,12 @@ public class Renderer extends LineSink {
// Free sorting arrays if larger than maximum size
private void crossingListFinished() {
- if (crossings.length > DEFAULT_CROSSINGS_SIZE) {
+ if (crossings != null && crossings.length > DEFAULT_CROSSINGS_SIZE) {
crossings = new int[DEFAULT_CROSSINGS_SIZE];
}
- if (crossingIndices.length > DEFAULT_INDICES_SIZE) {
+ if (crossingIndices != null &&
+ crossingIndices.length > DEFAULT_INDICES_SIZE)
+ {
crossingIndices = new int[DEFAULT_INDICES_SIZE];
}
}
diff --git a/src/share/classes/sun/net/www/protocol/http/spnego/NegotiatorImpl.java b/src/share/classes/sun/net/www/protocol/http/spnego/NegotiatorImpl.java
index dd4a39bd875ce78ee51855952e3e61b2cbf8850e..af0c9726ad9e06ba1515bc12611ec618db2f27a5 100644
--- a/src/share/classes/sun/net/www/protocol/http/spnego/NegotiatorImpl.java
+++ b/src/share/classes/sun/net/www/protocol/http/spnego/NegotiatorImpl.java
@@ -25,6 +25,7 @@
package sun.net.www.protocol.http.spnego;
+import com.sun.security.jgss.ExtendedGSSContext;
import java.io.IOException;
import org.ietf.jgss.GSSContext;
@@ -100,15 +101,10 @@ public class NegotiatorImpl extends Negotiator {
null,
GSSContext.DEFAULT_LIFETIME);
- // In order to support credential delegation in HTTP/SPNEGO,
- // we always request it before initSecContext. The current
- // implementation will check the OK-AS-DELEGATE flag inside
- // the service ticket of the web server, and only enable
- // delegation when this flag is set. This check is only
- // performed when the GSS caller is CALLER_HTTP_NEGOTIATE,
- // so all other normal GSS-API calls are not affected.
-
- context.requestCredDeleg(true);
+ // Always respect delegation policy in HTTP/SPNEGO.
+ if (context instanceof ExtendedGSSContext) {
+ ((ExtendedGSSContext)context).requestDelegPolicy(true);
+ }
oneToken = context.initSecContext(new byte[0], 0, 0);
}
diff --git a/src/share/classes/sun/security/jgss/GSSContextImpl.java b/src/share/classes/sun/security/jgss/GSSContextImpl.java
index de703ef4dedba60c655e48a6c0b3f64197535e4e..210ba5b869ae59d721567961a8e9628696492a60 100644
--- a/src/share/classes/sun/security/jgss/GSSContextImpl.java
+++ b/src/share/classes/sun/security/jgss/GSSContextImpl.java
@@ -89,7 +89,8 @@ import com.sun.security.jgss.*;
*/
class GSSContextImpl implements ExtendedGSSContext {
- private GSSManagerImpl gssManager = null;
+ private final GSSManagerImpl gssManager;
+ private final boolean initiator;
// private flags for the context state
private static final int PRE_INIT = 1;
@@ -99,14 +100,12 @@ class GSSContextImpl implements ExtendedGSSContext {
// instance variables
private int currentState = PRE_INIT;
- private boolean initiator;
private GSSContextSpi mechCtxt = null;
private Oid mechOid = null;
private ObjectIdentifier objId = null;
private GSSCredentialImpl myCred = null;
- private GSSCredentialImpl delegCred = null;
private GSSNameImpl srcName = null;
private GSSNameImpl targName = null;
@@ -121,6 +120,7 @@ class GSSContextImpl implements ExtendedGSSContext {
private boolean reqSequenceDetState = true;
private boolean reqCredDelegState = false;
private boolean reqAnonState = false;
+ private boolean reqDelegPolicyState = false;
/**
* Creates a GSSContextImp on the context initiator's side.
@@ -221,6 +221,7 @@ class GSSContextImpl implements ExtendedGSSContext {
mechCtxt.requestSequenceDet(reqSequenceDetState);
mechCtxt.requestAnonymity(reqAnonState);
mechCtxt.setChannelBinding(channelBindings);
+ mechCtxt.requestDelegPolicy(reqDelegPolicyState);
objId = new ObjectIdentifier(mechOid.toString());
@@ -465,42 +466,42 @@ class GSSContextImpl implements ExtendedGSSContext {
}
public void requestMutualAuth(boolean state) throws GSSException {
- if (mechCtxt == null)
+ if (mechCtxt == null && initiator)
reqMutualAuthState = state;
}
public void requestReplayDet(boolean state) throws GSSException {
- if (mechCtxt == null)
+ if (mechCtxt == null && initiator)
reqReplayDetState = state;
}
public void requestSequenceDet(boolean state) throws GSSException {
- if (mechCtxt == null)
+ if (mechCtxt == null && initiator)
reqSequenceDetState = state;
}
public void requestCredDeleg(boolean state) throws GSSException {
- if (mechCtxt == null)
+ if (mechCtxt == null && initiator)
reqCredDelegState = state;
}
public void requestAnonymity(boolean state) throws GSSException {
- if (mechCtxt == null)
+ if (mechCtxt == null && initiator)
reqAnonState = state;
}
public void requestConf(boolean state) throws GSSException {
- if (mechCtxt == null)
+ if (mechCtxt == null && initiator)
reqConfState = state;
}
public void requestInteg(boolean state) throws GSSException {
- if (mechCtxt == null)
+ if (mechCtxt == null && initiator)
reqIntegState = state;
}
public void requestLifetime(int lifetime) throws GSSException {
- if (mechCtxt == null)
+ if (mechCtxt == null && initiator)
reqLifetime = lifetime;
}
@@ -630,6 +631,8 @@ class GSSContextImpl implements ExtendedGSSContext {
targName = null;
}
+ // ExtendedGSSContext methods:
+
@Override
public Object inquireSecContext(InquireType type) throws GSSException {
SecurityManager security = System.getSecurityManager();
@@ -641,4 +644,18 @@ class GSSContextImpl implements ExtendedGSSContext {
}
return mechCtxt.inquireSecContext(type);
}
+
+ @Override
+ public void requestDelegPolicy(boolean state) throws GSSException {
+ if (mechCtxt == null && initiator)
+ reqDelegPolicyState = state;
+ }
+
+ @Override
+ public boolean getDelegPolicyState() {
+ if (mechCtxt != null)
+ return mechCtxt.getDelegPolicyState();
+ else
+ return reqDelegPolicyState;
+ }
}
diff --git a/src/share/classes/sun/security/jgss/krb5/InitialToken.java b/src/share/classes/sun/security/jgss/krb5/InitialToken.java
index 2f0b834c1b91cb118f2000fb348fcc939cb20621..ed7eb8c6e18fbbe434cea569a27548aeb38e153f 100644
--- a/src/share/classes/sun/security/jgss/krb5/InitialToken.java
+++ b/src/share/classes/sun/security/jgss/krb5/InitialToken.java
@@ -85,32 +85,39 @@ abstract class InitialToken extends Krb5Token {
int size = CHECKSUM_LENGTH_SIZE + CHECKSUM_BINDINGS_SIZE +
CHECKSUM_FLAGS_SIZE;
+ if (!tgt.isForwardable()) {
+ context.setCredDelegState(false);
+ context.setDelegPolicyState(false);
+ } else if (context.getCredDelegState()) {
+ if (context.getDelegPolicyState()) {
+ if (!serviceTicket.checkDelegate()) {
+ // delegation not permitted by server policy, mark it
+ context.setDelegPolicyState(false);
+ }
+ }
+ } else if (context.getDelegPolicyState()) {
+ if (serviceTicket.checkDelegate()) {
+ context.setCredDelegState(true);
+ } else {
+ context.setDelegPolicyState(false);
+ }
+ }
+
if (context.getCredDelegState()) {
- if (context.getCaller() instanceof HttpCaller &&
- !serviceTicket.getFlags()[Krb5.TKT_OPTS_DELEGATE]) {
- // When the caller is HTTP/SPNEGO and OK-AS-DELEGATE
- // is not present in the service ticket, delegation
- // is disabled.
- context.setCredDelegState(false);
- } else if (!tgt.isForwardable()) {
- // XXX log this resetting of delegation state
- context.setCredDelegState(false);
+ KrbCred krbCred = null;
+ CipherHelper cipherHelper =
+ context.getCipherHelper(serviceTicket.getSessionKey());
+ if (useNullKey(cipherHelper)) {
+ krbCred = new KrbCred(tgt, serviceTicket,
+ EncryptionKey.NULL_KEY);
} else {
- KrbCred krbCred = null;
- CipherHelper cipherHelper =
- context.getCipherHelper(serviceTicket.getSessionKey());
- if (useNullKey(cipherHelper)) {
- krbCred = new KrbCred(tgt, serviceTicket,
- EncryptionKey.NULL_KEY);
- } else {
- krbCred = new KrbCred(tgt, serviceTicket,
- serviceTicket.getSessionKey());
- }
- krbCredMessage = krbCred.getMessage();
- size += CHECKSUM_DELEG_OPT_SIZE +
- CHECKSUM_DELEG_LGTH_SIZE +
- krbCredMessage.length;
+ krbCred = new KrbCred(tgt, serviceTicket,
+ serviceTicket.getSessionKey());
}
+ krbCredMessage = krbCred.getMessage();
+ size += CHECKSUM_DELEG_OPT_SIZE +
+ CHECKSUM_DELEG_LGTH_SIZE +
+ krbCredMessage.length;
}
checksumBytes = new byte[size];
@@ -296,6 +303,7 @@ abstract class InitialToken extends Krb5Token {
return delegCreds;
}
+ // Only called by acceptor
public void setContextFlags(Krb5Context context) {
// default for cred delegation is false
if ((flags & CHECKSUM_DELEG_FLAG) > 0)
diff --git a/src/share/classes/sun/security/jgss/krb5/Krb5Context.java b/src/share/classes/sun/security/jgss/krb5/Krb5Context.java
index 4fe1e80f5f94afca5173933ce397374cfc1ec78c..8810ed606f9350f6bbfb644038185fa22ebce315 100644
--- a/src/share/classes/sun/security/jgss/krb5/Krb5Context.java
+++ b/src/share/classes/sun/security/jgss/krb5/Krb5Context.java
@@ -78,6 +78,7 @@ class Krb5Context implements GSSContextSpi {
private boolean sequenceDetState = true;
private boolean confState = true;
private boolean integState = true;
+ private boolean delegPolicyState = false;
private int mySeqNumber;
private int peerSeqNumber;
@@ -299,6 +300,21 @@ class Krb5Context implements GSSContextSpi {
return sequenceDetState || replayDetState;
}
+ /**
+ * Requests that the deleg policy be respected.
+ */
+ public final void requestDelegPolicy(boolean value) {
+ if (state == STATE_NEW && isInitiator())
+ delegPolicyState = value;
+ }
+
+ /**
+ * Is deleg policy respected?
+ */
+ public final boolean getDelegPolicyState() {
+ return delegPolicyState;
+ }
+
/*
* Anonymity is a little different in that after an application
* requests anonymity it will want to know whether the mechanism
@@ -422,6 +438,10 @@ class Krb5Context implements GSSContextSpi {
integState = state;
}
+ final void setDelegPolicyState(boolean state) {
+ delegPolicyState = state;
+ }
+
/**
* Sets the channel bindings to be used during context
* establishment.
diff --git a/src/share/classes/sun/security/jgss/spi/GSSContextSpi.java b/src/share/classes/sun/security/jgss/spi/GSSContextSpi.java
index 5bf359a1f8ccf1d776a6ef8272a8b88d28e28aaf..aaf4eebc29fbd3ee7e8063ad9978b811f7df063b 100644
--- a/src/share/classes/sun/security/jgss/spi/GSSContextSpi.java
+++ b/src/share/classes/sun/security/jgss/spi/GSSContextSpi.java
@@ -124,6 +124,8 @@ public interface GSSContextSpi {
public void requestInteg(boolean state) throws GSSException;
+ public void requestDelegPolicy(boolean state) throws GSSException;
+
public void setChannelBinding(ChannelBinding cb) throws GSSException;
public boolean getCredDelegState();
@@ -136,6 +138,8 @@ public interface GSSContextSpi {
public boolean getAnonymityState();
+ public boolean getDelegPolicyState();
+
public boolean isTransferable() throws GSSException;
public boolean isProtReady();
diff --git a/src/share/classes/sun/security/jgss/spnego/SpNegoContext.java b/src/share/classes/sun/security/jgss/spnego/SpNegoContext.java
index a436092f1bb6b4f98e0373b2960a6df648a78729..b002082d8cb1a99c7262bafab1737343490bb54e 100644
--- a/src/share/classes/sun/security/jgss/spnego/SpNegoContext.java
+++ b/src/share/classes/sun/security/jgss/spnego/SpNegoContext.java
@@ -63,6 +63,7 @@ public class SpNegoContext implements GSSContextSpi {
private boolean sequenceDetState = true;
private boolean confState = true;
private boolean integState = true;
+ private boolean delegPolicyState = false;
private GSSNameSpi peerName = null;
private GSSNameSpi myName = null;
@@ -153,6 +154,14 @@ public class SpNegoContext implements GSSContextSpi {
integState = value;
}
+ /**
+ * Requests that deleg policy be respected.
+ */
+ public final void requestDelegPolicy(boolean value) throws GSSException {
+ if (state == STATE_NEW && isInitiator())
+ delegPolicyState = value;
+ }
+
/**
* Is integrity available?
*/
@@ -160,6 +169,19 @@ public class SpNegoContext implements GSSContextSpi {
return integState;
}
+ /**
+ * Is deleg policy respected?
+ */
+ public final boolean getDelegPolicyState() {
+ if (isInitiator() && mechContext != null &&
+ mechContext instanceof ExtendedGSSContext &&
+ (state == STATE_IN_PROCESS || state == STATE_DONE)) {
+ return ((ExtendedGSSContext)mechContext).getDelegPolicyState();
+ } else {
+ return delegPolicyState;
+ }
+ }
+
/**
* Requests that credential delegation be done during context
* establishment.
@@ -173,7 +195,7 @@ public class SpNegoContext implements GSSContextSpi {
* Is credential delegation enabled?
*/
public final boolean getCredDelegState() {
- if (mechContext != null &&
+ if (isInitiator() && mechContext != null &&
(state == STATE_IN_PROCESS || state == STATE_DONE)) {
return mechContext.getCredDelegState();
} else {
@@ -201,30 +223,6 @@ public class SpNegoContext implements GSSContextSpi {
return mutualAuthState;
}
- final void setCredDelegState(boolean state) {
- credDelegState = state;
- }
-
- final void setMutualAuthState(boolean state) {
- mutualAuthState = state;
- }
-
- final void setReplayDetState(boolean state) {
- replayDetState = state;
- }
-
- final void setSequenceDetState(boolean state) {
- sequenceDetState = state;
- }
-
- final void setConfState(boolean state) {
- confState = state;
- }
-
- final void setIntegState(boolean state) {
- integState = state;
- }
-
/**
* Returns the mechanism oid.
*
@@ -319,14 +317,9 @@ public class SpNegoContext implements GSSContextSpi {
mechToken = GSS_initSecContext(null);
errorCode = GSSException.DEFECTIVE_TOKEN;
- byte[] micToken = null;
- if (!GSSUtil.useMSInterop()) {
- // calculate MIC only in normal mode
- micToken = generateMechListMIC(DER_mechTypes);
- }
// generate SPNEGO token
initToken = new NegTokenInit(DER_mechTypes, getContextFlags(),
- mechToken, micToken);
+ mechToken, null);
if (DEBUG) {
System.out.println("SpNegoContext.initSecContext: " +
"sending token of type = " +
@@ -585,15 +578,9 @@ public class SpNegoContext implements GSSContextSpi {
"negotiated result = " + negoResult);
}
- // calculate MIC only in normal mode
- byte[] micToken = null;
- if (!GSSUtil.useMSInterop() && valid) {
- micToken = generateMechListMIC(DER_mechTypes);
- }
-
// generate SPNEGO token
NegTokenTarg targToken = new NegTokenTarg(negoResult.ordinal(),
- mech_wanted, accept_token, micToken);
+ mech_wanted, accept_token, null);
if (DEBUG) {
System.out.println("SpNegoContext.acceptSecContext: " +
"sending token of type = " +
@@ -653,6 +640,10 @@ public class SpNegoContext implements GSSContextSpi {
throw gssException;
}
+ if (state == STATE_DONE) {
+ // now set the context flags for acceptor
+ setContextFlags();
+ }
return retVal;
}
@@ -703,36 +694,39 @@ public class SpNegoContext implements GSSContextSpi {
return out;
}
+ // Only called on acceptor side. On the initiator side, most flags
+ // are already set at request. For those that might get chanegd,
+ // state from mech below is used.
private void setContextFlags() {
if (mechContext != null) {
// default for cred delegation is false
if (mechContext.getCredDelegState()) {
- setCredDelegState(true);
+ credDelegState = true;
}
// default for the following are true
if (!mechContext.getMutualAuthState()) {
- setMutualAuthState(false);
+ mutualAuthState = false;
}
if (!mechContext.getReplayDetState()) {
- setReplayDetState(false);
+ replayDetState = false;
}
if (!mechContext.getSequenceDetState()) {
- setSequenceDetState(false);
+ sequenceDetState = false;
}
if (!mechContext.getIntegState()) {
- setIntegState(false);
+ integState = false;
}
if (!mechContext.getConfState()) {
- setConfState(false);
+ confState = false;
}
}
}
/**
- * generate MIC on mechList
+ * generate MIC on mechList. Not used at the moment.
*/
- private byte[] generateMechListMIC(byte[] mechTypes)
+ /*private byte[] generateMechListMIC(byte[] mechTypes)
throws GSSException {
// sanity check the required input
@@ -769,7 +763,7 @@ public class SpNegoContext implements GSSContextSpi {
}
}
return mic;
- }
+ }*/
/**
* verify MIC on MechList
@@ -837,6 +831,10 @@ public class SpNegoContext implements GSSContextSpi {
mechContext.requestMutualAuth(mutualAuthState);
mechContext.requestReplayDet(replayDetState);
mechContext.requestSequenceDet(sequenceDetState);
+ if (mechContext instanceof ExtendedGSSContext) {
+ ((ExtendedGSSContext)mechContext).requestDelegPolicy(
+ delegPolicyState);
+ }
}
// pass token
@@ -1202,5 +1200,5 @@ public class SpNegoContext implements GSSContextSpi {
"inquireSecContext not supported by underlying mech.");
}
}
-
}
+
diff --git a/src/share/classes/sun/security/jgss/spnego/SpNegoMechFactory.java b/src/share/classes/sun/security/jgss/spnego/SpNegoMechFactory.java
index ae12d6b3a7854a61966011f099164ac64ff7cfdb..72b77ac716625ab8452541ae07c1556f94aaae10 100644
--- a/src/share/classes/sun/security/jgss/spnego/SpNegoMechFactory.java
+++ b/src/share/classes/sun/security/jgss/spnego/SpNegoMechFactory.java
@@ -57,6 +57,12 @@ public final class SpNegoMechFactory implements MechanismFactory {
GSSName.NT_HOSTBASED_SERVICE,
GSSName.NT_EXPORT_NAME};
+ // The default underlying mech of SPNEGO, must not be SPNEGO itself.
+ private static final Oid DEFAULT_SPNEGO_MECH_OID =
+ ProviderList.DEFAULT_MECH_OID.equals(GSS_SPNEGO_MECH_OID)?
+ GSSUtil.GSS_KRB5_MECH_OID:
+ ProviderList.DEFAULT_MECH_OID;
+
// Use an instance of a GSSManager whose provider list
// does not include native provider
final GSSManagerImpl manager;
@@ -100,18 +106,27 @@ public final class SpNegoMechFactory implements MechanismFactory {
availableMechs[j++] = mechs[i];
}
}
+ // Move the preferred mech to first place
+ for (int i=0; i>> Credentials acquireServiceCreds: " +
+ "global OK-AS-DELEGATE turned off at " +
+ newTgt.getServer());
+ }
+ okAsDelegate = false;
+ }
if (DEBUG)
{
@@ -283,6 +293,9 @@ rs.
System.out.println(">>> Credentials acquireServiceCreds: returning creds:");
Credentials.printDebug(theCreds);
}
+ if (!okAsDelegate) {
+ theCreds.resetDelegate();
+ }
return theCreds;
}
throw new KrbApErrException(Krb5.KRB_AP_ERR_GEN_CRED,
diff --git a/src/share/classes/sun/swing/SwingLazyValue.java b/src/share/classes/sun/swing/SwingLazyValue.java
index f5587282abb89cf1aca3a7f412dcbef56cc18e92..02236ddff738c8dcb5257be307060018c8c88a6c 100644
--- a/src/share/classes/sun/swing/SwingLazyValue.java
+++ b/src/share/classes/sun/swing/SwingLazyValue.java
@@ -26,6 +26,9 @@ package sun.swing;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
+import java.lang.reflect.AccessibleObject;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import javax.swing.UIDefaults;
/**
@@ -65,13 +68,15 @@ public class SwingLazyValue implements UIDefaults.LazyValue {
if (methodName != null) {
Class[] types = getClassArray(args);
Method m = c.getMethod(methodName, types);
+ makeAccessible(m);
return m.invoke(c, args);
} else {
Class[] types = getClassArray(args);
Constructor constructor = c.getConstructor(types);
+ makeAccessible(constructor);
return constructor.newInstance(args);
}
- } catch(Exception e) {
+ } catch (Exception e) {
// Ideally we would throw an exception, unfortunately
// often times there are errors as an initial look and
// feel is loaded before one can be switched. Perhaps a
@@ -81,6 +86,15 @@ public class SwingLazyValue implements UIDefaults.LazyValue {
return null;
}
+ private void makeAccessible(final AccessibleObject object) {
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Void run() {
+ object.setAccessible(true);
+ return null;
+ }
+ });
+ }
+
private Class[] getClassArray(Object[] args) {
Class[] types = null;
if (args!=null) {
diff --git a/src/share/classes/sun/swing/SwingUtilities2.java b/src/share/classes/sun/swing/SwingUtilities2.java
index 60681d56fbc951f2aa1db1105d0acdca58606f41..5b835bfec54def2784100183d5aaba3bba6d856b 100644
--- a/src/share/classes/sun/swing/SwingUtilities2.java
+++ b/src/share/classes/sun/swing/SwingUtilities2.java
@@ -1807,22 +1807,4 @@ public class SwingUtilities2 {
boolean three) {
return liesIn(rect, p, false, false, three);
}
-
- /**
- * Returns the {@code JViewport} instance for the {@code component}
- * or {@code null}.
- *
- * @return the {@code JViewport} instance for the {@code component}
- * or {@code null}
- * @throws NullPointerException if {@code component} is {@code null}
- */
- public static JViewport getViewport(Component component) {
- do {
- component = component.getParent();
- if (component instanceof JViewport) {
- return (JViewport) component;
- }
- } while(component instanceof JLayer);
- return null;
- }
}
diff --git a/src/share/classes/sun/util/resources/TimeZoneNames.java b/src/share/classes/sun/util/resources/TimeZoneNames.java
index 7f2c570cceab6df37314d9ab84018cc3c36ac859..ef9dfdc8c5a2bd458bc3b30334dfb56dba1a57ff 100644
--- a/src/share/classes/sun/util/resources/TimeZoneNames.java
+++ b/src/share/classes/sun/util/resources/TimeZoneNames.java
@@ -141,6 +141,8 @@ public final class TimeZoneNames extends TimeZoneNamesBundle {
"Malaysia Summer Time", "MYST"};
String NORONHA[] = new String[] {"Fernando de Noronha Time", "FNT",
"Fernando de Noronha Summer Time", "FNST"};
+ String NOVT[] = new String[] {"Novosibirsk Time", "NOVT",
+ "Novosibirsk Summer Time", "NOVST"};
String NPT[] = new String[] {"Nepal Time", "NPT",
"Nepal Summer Time", "NPST"};
String NST[] = new String[] {"Newfoundland Standard Time", "NST",
@@ -441,7 +443,8 @@ public final class TimeZoneNames extends TimeZoneNamesBundle {
{"America/Winnipeg", CST},
{"America/Yakutat", AKST},
{"America/Yellowknife", MST},
- {"Antarctica/Casey", WST_AUS},
+ {"Antarctica/Casey", new String[] {"Casey Time", "CAST",
+ "Casey Summer Time", "CAST"}},
{"Antarctica/Davis", new String[] {"Davis Time", "DAVT",
"Davis Summer Time", "DAVST"}},
{"Antarctica/DumontDUrville", new String[] {"Dumont-d'Urville Time", "DDUT",
@@ -529,8 +532,8 @@ public final class TimeZoneNames extends TimeZoneNamesBundle {
"Philippines Summer Time", "PHST"}},
{"Asia/Muscat", GST},
{"Asia/Nicosia", EET},
- {"Asia/Novosibirsk", new String[] {"Novosibirsk Time", "NOVT",
- "Novosibirsk Summer Time", "NOVST"}},
+ {"Asia/Novokuznetsk", NOVT},
+ {"Asia/Novosibirsk", NOVT},
{"Asia/Oral", new String[] {"Oral Time", "ORAT",
"Oral Summer Time", "ORAST"}},
{"Asia/Omsk", new String[] {"Omsk Time", "OMST",
diff --git a/src/share/classes/sun/util/resources/TimeZoneNames_de.java b/src/share/classes/sun/util/resources/TimeZoneNames_de.java
index 7ff10f89df545133ab21b175dd3d869c6f5296f9..896d72a5c532c9126049c80840dde32c479ce5ac 100644
--- a/src/share/classes/sun/util/resources/TimeZoneNames_de.java
+++ b/src/share/classes/sun/util/resources/TimeZoneNames_de.java
@@ -141,6 +141,8 @@ public final class TimeZoneNames_de extends TimeZoneNamesBundle {
"Malaysische Sommerzeit", "MYST"};
String NORONHA[] = new String[] {"Fernando de Noronha Zeit", "FNT",
"Fernando de Noronha Sommerzeit", "FNST"};
+ String NOVT[] = new String[] {"Nowosibirsker Zeit", "NOVT",
+ "Nowosibirsker Sommerzeit", "NOVST"};
String NPT[] = new String[] {"Nepalesische Zeit", "NPT",
"Nepalesische Sommerzeit", "NPST"};
String NST[] = new String[] {"Neufundland Normalzeit", "NST",
@@ -441,7 +443,6 @@ public final class TimeZoneNames_de extends TimeZoneNamesBundle {
{"America/Winnipeg", CST},
{"America/Yakutat", AKST},
{"America/Yellowknife", MST},
- {"Antarctica/Casey", WST_AUS},
{"Antarctica/Davis", new String[] {"Davis Zeit", "DAVT",
"Davis Sommerzeit", "DAVST"}},
{"Antarctica/DumontDUrville", new String[] {"Dumont-d'Urville Zeit", "DDUT",
@@ -529,8 +530,8 @@ public final class TimeZoneNames_de extends TimeZoneNamesBundle {
"Philippinische Sommerzeit", "PHST"}},
{"Asia/Muscat", GST},
{"Asia/Nicosia", EET},
- {"Asia/Novosibirsk", new String[] {"Nowosibirsker Zeit", "NOVT",
- "Nowosibirsker Sommerzeit", "NOVST"}},
+ {"Asia/Novokuznetsk", NOVT},
+ {"Asia/Novosibirsk", NOVT},
{"Asia/Oral", new String[] {"Oral Zeit", "ORAT",
"Oral Sommerzeit", "ORAST"}},
{"Asia/Omsk", new String[] {"Omsk Zeit", "OMST",
diff --git a/src/share/classes/sun/util/resources/TimeZoneNames_es.java b/src/share/classes/sun/util/resources/TimeZoneNames_es.java
index 9e1ffa8397cbd89f4e4c01e42942ca8994c198ba..20605d1187a332dde3f255583b07a12ef8aa650b 100644
--- a/src/share/classes/sun/util/resources/TimeZoneNames_es.java
+++ b/src/share/classes/sun/util/resources/TimeZoneNames_es.java
@@ -141,6 +141,8 @@ public final class TimeZoneNames_es extends TimeZoneNamesBundle {
"Hora de verano de Malasia", "MYST"};
String NORONHA[] = new String[] {"Hora de Fernando de Noronha", "FNT",
"Hora de verano de Fernando de Noronha", "FNST"};
+ String NOVT[] = new String[] {"Hora de Novosibirsk", "NOVT",
+ "Hora de verano de Novosibirsk", "NOVST"};
String NPT[] = new String[] {"Hora de Nepal", "NPT",
"Hora de verano de Nepal", "NPST"};
String NST[] = new String[] {"Hora est\u00e1ndar de Terranova", "NST",
@@ -441,7 +443,6 @@ public final class TimeZoneNames_es extends TimeZoneNamesBundle {
{"America/Winnipeg", CST},
{"America/Yakutat", AKST},
{"America/Yellowknife", MST},
- {"Antarctica/Casey", WST_AUS},
{"Antarctica/Davis", new String[] {"Hora de Davis", "DAVT",
"Hora de verano de Davis", "DAVST"}},
{"Antarctica/DumontDUrville", new String[] {"Hora de Dumont-d'Urville", "DDUT",
@@ -529,8 +530,9 @@ public final class TimeZoneNames_es extends TimeZoneNamesBundle {
"Hora de verano de Filipinas", "PHST"}},
{"Asia/Muscat", GST},
{"Asia/Nicosia", EET},
- {"Asia/Novosibirsk", new String[] {"Hora de Novosibirsk", "NOVT",
- "Hora de verano de Novosibirsk", "NOVST"}},
+
+ {"Asia/Novokuznetsk", NOVT},
+ {"Asia/Novosibirsk", NOVT},
{"Asia/Oral", new String[] {"Hora de Uralsk", "ORAT",
"Hora de verano de Uralsk", "ORAST"}},
{"Asia/Omsk", new String[] {"Hora de Omsk", "OMST",
diff --git a/src/share/classes/sun/util/resources/TimeZoneNames_fr.java b/src/share/classes/sun/util/resources/TimeZoneNames_fr.java
index 941bc4e972a8e694e3fe49dc0f498810b440e5f3..e3f8205584a730e79a2bc7a26ad35989418aae5e 100644
--- a/src/share/classes/sun/util/resources/TimeZoneNames_fr.java
+++ b/src/share/classes/sun/util/resources/TimeZoneNames_fr.java
@@ -141,6 +141,8 @@ public final class TimeZoneNames_fr extends TimeZoneNamesBundle {
"Heure d'\u00e9t\u00e9 de Malaisie", "MYST"};
String NORONHA[] = new String[] {"Heure de Fernando de Noronha", "FNT",
"Heure d'\u00e9t\u00e9 de Fernando de Noronha", "FNST"};
+ String NOVT[] = new String[] {"Heure de Novossibirsk", "NOVT",
+ "Heure d'\u00e9t\u00e9 de Novossibirsk", "NOVST"};
String NPT[] = new String[] {"Heure du N\u00e9pal", "NPT",
"Heure d'\u00e9t\u00e9 du N\u00e9pal", "NPST"};
String NST[] = new String[] {"Heure normale de Terre-Neuve", "NST",
@@ -441,7 +443,6 @@ public final class TimeZoneNames_fr extends TimeZoneNamesBundle {
{"America/Winnipeg", CST},
{"America/Yakutat", AKST},
{"America/Yellowknife", MST},
- {"Antarctica/Casey", WST_AUS},
{"Antarctica/Davis", new String[] {"Heure de Davis", "DAVT",
"Heure d'\u00e9t\u00e9 de Davis", "DAVST"}},
{"Antarctica/DumontDUrville", new String[] {"Heure de Dumont-d'Urville", "DDUT",
@@ -529,8 +530,8 @@ public final class TimeZoneNames_fr extends TimeZoneNamesBundle {
"Heure d'\u00e9t\u00e9 des Philippines", "PHST"}},
{"Asia/Muscat", GST},
{"Asia/Nicosia", EET},
- {"Asia/Novosibirsk", new String[] {"Heure de Novossibirsk", "NOVT",
- "Heure d'\u00e9t\u00e9 de Novossibirsk", "NOVST"}},
+ {"Asia/Novokuznetsk", NOVT},
+ {"Asia/Novosibirsk", NOVT},
{"Asia/Oral", new String[] {"Heure d'Oral", "ORAT",
"Heure d'\u00e9t\u00e9 d'Oral", "ORAST"}},
{"Asia/Omsk", new String[] {"Heure d'Omsk", "OMST",
diff --git a/src/share/classes/sun/util/resources/TimeZoneNames_it.java b/src/share/classes/sun/util/resources/TimeZoneNames_it.java
index 499f0fe2d954b1cbd2d5f238acf1a5ec041f2db2..e464618f2af92eed9bb5719bcb633b97eb5bc24b 100644
--- a/src/share/classes/sun/util/resources/TimeZoneNames_it.java
+++ b/src/share/classes/sun/util/resources/TimeZoneNames_it.java
@@ -141,6 +141,8 @@ public final class TimeZoneNames_it extends TimeZoneNamesBundle {
"Ora estiva della Malaysia", "MYST"};
String NORONHA[] = new String[] {"Ora di Fernando de Noronha", "FNT",
"Ora estiva di Fernando de Noronha", "FNST"};
+ String NOVT[] = new String[] {"Ora di Novosibirsk", "NOVT",
+ "Ora estiva di Novosibirsk", "NOVST"};
String NPT[] = new String[] {"Ora del Nepal", "NPT",
"Ora estiva del Nepal", "NPST"};
String NST[] = new String[] {"Ora solare di Terranova", "NST",
@@ -441,7 +443,6 @@ public final class TimeZoneNames_it extends TimeZoneNamesBundle {
{"America/Winnipeg", CST},
{"America/Yakutat", AKST},
{"America/Yellowknife", MST},
- {"Antarctica/Casey", WST_AUS},
{"Antarctica/Davis", new String[] {"Ora di Davis", "DAVT",
"Ora estiva di Davis", "DAVST"}},
{"Antarctica/DumontDUrville", new String[] {"Ora di Dumont-d'Urville", "DDUT",
@@ -529,8 +530,8 @@ public final class TimeZoneNames_it extends TimeZoneNamesBundle {
"Ora estiva delle Filippine", "PHST"}},
{"Asia/Muscat", GST},
{"Asia/Nicosia", EET},
- {"Asia/Novosibirsk", new String[] {"Ora di Novosibirsk", "NOVT",
- "Ora estiva di Novosibirsk", "NOVST"}},
+ {"Asia/Novokuznetsk", NOVT},
+ {"Asia/Novosibirsk", NOVT},
{"Asia/Oral", new String[] {"Ora di Oral", "ORAT",
"Ora estiva di Oral", "ORAST"}},
{"Asia/Omsk", new String[] {"Ora di Omsk", "OMST",
diff --git a/src/share/classes/sun/util/resources/TimeZoneNames_ja.java b/src/share/classes/sun/util/resources/TimeZoneNames_ja.java
index 583a0a4e1c889cf1ec245b0c4350d76c6fdc1955..1292e4b8045b59e1914d8319425c3af1f578c170 100644
--- a/src/share/classes/sun/util/resources/TimeZoneNames_ja.java
+++ b/src/share/classes/sun/util/resources/TimeZoneNames_ja.java
@@ -141,6 +141,8 @@ public final class TimeZoneNames_ja extends TimeZoneNamesBundle {
"\u30de\u30ec\u30fc\u30b7\u30a2\u590f\u6642\u9593", "MYST"};
String NORONHA[] = new String[] {"\u30d5\u30a7\u30eb\u30ca\u30f3\u30c9\u30fb\u30c7\u30fb\u30ce\u30ed\u30fc\u30cb\u30e3\u6642\u9593", "FNT",
"\u30d5\u30a7\u30eb\u30ca\u30f3\u30c9\u30fb\u30c7\u30fb\u30ce\u30ed\u30fc\u30cb\u30e3\u590f\u6642\u9593", "FNST"};
+ String NOVT[] = new String[] {"\u30ce\u30dc\u30b7\u30d3\u30eb\u30b9\u30af\u6642\u9593", "NOVT",
+ "\u30ce\u30dc\u30b7\u30d3\u30eb\u30b9\u30af\u590f\u6642\u9593", "NOVST"};
String NPT[] = new String[] {"\u30cd\u30d1\u30fc\u30eb\u6642\u9593", "NPT",
"\u30cd\u30d1\u30fc\u30eb\u590f\u6642\u9593", "NPST"};
String NST[] = new String[] {"\u30cb\u30e5\u30fc\u30d5\u30a1\u30f3\u30c9\u30e9\u30f3\u30c9\u6a19\u6e96\u6642", "NST",
@@ -441,7 +443,6 @@ public final class TimeZoneNames_ja extends TimeZoneNamesBundle {
{"America/Winnipeg", CST},
{"America/Yakutat", AKST},
{"America/Yellowknife", MST},
- {"Antarctica/Casey", WST_AUS},
{"Antarctica/Davis", new String[] {"\u30c7\u30a4\u30d3\u30b9\u6642\u9593", "DAVT",
"\u30c7\u30a4\u30d3\u30b9\u590f\u6642\u9593", "DAVST"}},
{"Antarctica/DumontDUrville", new String[] {"\u30c7\u30e5\u30e2\u30f3\u30c7\u30e5\u30eb\u30f4\u30a3\u30eb\u6642\u9593", "DDUT",
@@ -529,8 +530,8 @@ public final class TimeZoneNames_ja extends TimeZoneNamesBundle {
"\u30d5\u30a3\u30ea\u30d4\u30f3\u590f\u6642\u9593", "PHST"}},
{"Asia/Muscat", GST},
{"Asia/Nicosia", EET},
- {"Asia/Novosibirsk", new String[] {"\u30ce\u30dc\u30b7\u30d3\u30eb\u30b9\u30af\u6642\u9593", "NOVT",
- "\u30ce\u30dc\u30b7\u30d3\u30eb\u30b9\u30af\u590f\u6642\u9593", "NOVST"}},
+ {"Asia/Novokuznetsk", NOVT},
+ {"Asia/Novosibirsk", NOVT},
{"Asia/Oral", new String[] {"\u30aa\u30e9\u30eb\u6642\u9593", "ORAT",
"\u30aa\u30e9\u30eb\u590f\u6642\u9593", "ORAST"}},
{"Asia/Omsk", new String[] {"\u30aa\u30e0\u30b9\u30af\u6642\u9593", "OMST",
diff --git a/src/share/classes/sun/util/resources/TimeZoneNames_ko.java b/src/share/classes/sun/util/resources/TimeZoneNames_ko.java
index 3e179dad3a81a432347c27bd15ac30e8a21a13a4..f69e08b250eb62135da6934b8307113206e1f85b 100644
--- a/src/share/classes/sun/util/resources/TimeZoneNames_ko.java
+++ b/src/share/classes/sun/util/resources/TimeZoneNames_ko.java
@@ -141,6 +141,8 @@ public final class TimeZoneNames_ko extends TimeZoneNamesBundle {
"\ub9d0\ub808\uc774\uc2dc\uc544 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "MYST"};
String NORONHA[] = new String[] {"Fernando de Noronha \uc2dc\uac04", "FNT",
"Fernando de Noronha \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "FNST"};
+ String NOVT[] = new String[] {"\ub178\ube0c\uc2dc\ube4c\uc2a4\ud06c \uc2dc\uac04", "NOVT",
+ "\ub178\ube0c\uc2dc\ube4c\uc2a4\ud06c \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "NOVST"};
String NPT[] = new String[] {"\ub124\ud314 \uc2dc\uac04", "NPT",
"\ub124\ud314 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "NPST"};
String NST[] = new String[] {"\ub274\ud380\ub4e4\ub79c\ub4dc \ud45c\uc900\uc2dc", "NST",
@@ -441,7 +443,6 @@ public final class TimeZoneNames_ko extends TimeZoneNamesBundle {
{"America/Winnipeg", CST},
{"America/Yakutat", AKST},
{"America/Yellowknife", MST},
- {"Antarctica/Casey", WST_AUS},
{"Antarctica/Davis", new String[] {"Davis \uc2dc\uac04", "DAVT",
"Davis \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "DAVST"}},
{"Antarctica/DumontDUrville", new String[] {"\ub4a4\ubabd \ub4a4\ub974\ube4c \uc2dc\uac04", "DDUT",
@@ -529,8 +530,8 @@ public final class TimeZoneNames_ko extends TimeZoneNamesBundle {
"\ud544\ub9ac\ud540 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "PHST"}},
{"Asia/Muscat", GST},
{"Asia/Nicosia", EET},
- {"Asia/Novosibirsk", new String[] {"\ub178\ube0c\uc2dc\ube4c\uc2a4\ud06c \uc2dc\uac04", "NOVT",
- "\ub178\ube0c\uc2dc\ube4c\uc2a4\ud06c \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "NOVST"}},
+ {"Asia/Novokuznetsk", NOVT},
+ {"Asia/Novosibirsk", NOVT},
{"Asia/Oral", new String[] {"Oral \ud45c\uc900\uc2dc", "ORAT",
"Oral \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "ORAST"}},
{"Asia/Omsk", new String[] {"Omsk \uc2dc\uac04", "OMST",
diff --git a/src/share/classes/sun/util/resources/TimeZoneNames_sv.java b/src/share/classes/sun/util/resources/TimeZoneNames_sv.java
index ab13cd9216bcc9fbb1c6dd3707fb333ae24feb02..35ce2d11c5170dd19ada97f65d4b2fd53fcee656 100644
--- a/src/share/classes/sun/util/resources/TimeZoneNames_sv.java
+++ b/src/share/classes/sun/util/resources/TimeZoneNames_sv.java
@@ -141,6 +141,8 @@ public final class TimeZoneNames_sv extends TimeZoneNamesBundle {
"Malaysia, sommartid", "MYST"};
String NORONHA[] = new String[] {"Fernando de Noronha, normaltid", "FNT",
"Fernando de Noronha, sommartid", "FNST"};
+ String NOVT[] = new String[] {"Novosibirsk, normaltid", "NOVT",
+ "Novosibirsk, sommartid", "NOVST"};
String NPT[] = new String[] {"Nepal, normaltid", "NPT",
"Nepal, sommartid", "NPST"};
String NST[] = new String[] {"Newfoundland, normaltid", "NST",
@@ -441,7 +443,6 @@ public final class TimeZoneNames_sv extends TimeZoneNamesBundle {
{"America/Winnipeg", CST},
{"America/Yakutat", AKST},
{"America/Yellowknife", MST},
- {"Antarctica/Casey", WST_AUS},
{"Antarctica/Davis", new String[] {"Davis, normaltid", "DAVT",
"Davis, sommartid", "DAVST"}},
{"Antarctica/DumontDUrville", new String[] {"Dumont-d'Urville, normaltid", "DDUT",
@@ -529,8 +530,8 @@ public final class TimeZoneNames_sv extends TimeZoneNamesBundle {
"Filippinerna, sommartid", "PHST"}},
{"Asia/Muscat", GST},
{"Asia/Nicosia", EET},
- {"Asia/Novosibirsk", new String[] {"Novosibirsk, normaltid", "NOVT",
- "Novosibirsk, sommartid", "NOVST"}},
+ {"Asia/Novokuznetsk", NOVT},
+ {"Asia/Novosibirsk", NOVT},
{"Asia/Oral", new String[] {"Oral, normaltid", "ORAT",
"Oral, sommartid", "ORAST"}},
{"Asia/Omsk", new String[] {"Omsk, normaltid", "OMST",
diff --git a/src/share/classes/sun/util/resources/TimeZoneNames_zh_CN.java b/src/share/classes/sun/util/resources/TimeZoneNames_zh_CN.java
index e0dc1ec7ea3c746310886694ee30a61f9eabb3d5..70cdbd0a9879551e5f070f023e2aacbcaf9158b4 100644
--- a/src/share/classes/sun/util/resources/TimeZoneNames_zh_CN.java
+++ b/src/share/classes/sun/util/resources/TimeZoneNames_zh_CN.java
@@ -141,6 +141,8 @@ public final class TimeZoneNames_zh_CN extends TimeZoneNamesBundle {
"\u9a6c\u6765\u897f\u4e9a\u590f\u4ee4\u65f6", "MYST"};
String NORONHA[] = new String[] {"\u8d39\u5c14\u5357\u591a\u5fb7\u8bfa\u7f57\u5c3c\u4e9a\u65f6\u95f4", "FNT",
"\u8d39\u5c14\u5357\u591a\u5fb7\u8bfa\u7f57\u5c3c\u4e9a\u590f\u4ee4\u65f6", "FNST"};
+ String NOVT[] = new String[] {"Novosibirsk \u65f6\u95f4", "NOVT",
+ "Novosibirsk \u590f\u4ee4\u65f6", "NOVST"};
String NPT[] = new String[] {"\u5c3c\u6cca\u5c14\u65f6\u95f4", "NPT",
"\u5c3c\u6cca\u5c14\u590f\u4ee4\u65f6", "NPST"};
String NST[] = new String[] {"\u7ebd\u82ac\u5170\u6807\u51c6\u65f6\u95f4", "NST",
@@ -441,7 +443,6 @@ public final class TimeZoneNames_zh_CN extends TimeZoneNamesBundle {
{"America/Winnipeg", CST},
{"America/Yakutat", AKST},
{"America/Yellowknife", MST},
- {"Antarctica/Casey", WST_AUS},
{"Antarctica/Davis", new String[] {"\u6234\u7ef4\u65af\u65f6\u95f4", "DAVT",
"\u6234\u7ef4\u65af\u590f\u4ee4\u65f6", "DAVST"}},
{"Antarctica/DumontDUrville", new String[] {"Dumont-d'Urville \u65f6\u95f4", "DDUT",
@@ -529,8 +530,8 @@ public final class TimeZoneNames_zh_CN extends TimeZoneNamesBundle {
"\u83f2\u5f8b\u5bbe\u590f\u4ee4\u65f6", "PHST"}},
{"Asia/Muscat", GST},
{"Asia/Nicosia", EET},
- {"Asia/Novosibirsk", new String[] {"Novosibirsk \u65f6\u95f4", "NOVT",
- "Novosibirsk \u590f\u4ee4\u65f6", "NOVST"}},
+ {"Asia/Novokuznetsk", NOVT},
+ {"Asia/Novosibirsk", NOVT},
{"Asia/Oral", new String[] {"Oral \u65f6\u95f4", "ORAT",
"Oral \u590f\u4ee4\u65f6", "ORAST"}},
{"Asia/Omsk", new String[] {"\u9102\u6728\u65af\u514b\u65f6\u95f4", "OMST",
diff --git a/src/share/classes/sun/util/resources/TimeZoneNames_zh_TW.java b/src/share/classes/sun/util/resources/TimeZoneNames_zh_TW.java
index 73dd22cad1e45b044e00aa211008067c0ea21aa4..f5b89286ed07754a72a75222cbc030ddf674b57d 100644
--- a/src/share/classes/sun/util/resources/TimeZoneNames_zh_TW.java
+++ b/src/share/classes/sun/util/resources/TimeZoneNames_zh_TW.java
@@ -141,6 +141,8 @@ public final class TimeZoneNames_zh_TW extends TimeZoneNamesBundle {
"\u99ac\u4f86\u897f\u4e9e\u590f\u4ee4\u6642\u9593", "MYST"};
String NORONHA[] = new String[] {"\u8cbb\u723e\u5357\u591a-\u8fea\u8afe\u7f85\u5c3c\u4e9e\u6642\u9593", "FNT",
"\u8cbb\u723e\u5357\u591a-\u8fea\u8afe\u7f85\u5c3c\u4e9e\u590f\u4ee4\u6642\u9593", "FNST"};
+ String NOVT[] = new String[] {"Novosibirsk \u6642\u9593", "NOVT",
+ "Novosibirsk \u590f\u4ee4\u6642\u9593", "NOVST"};
String NPT[] = new String[] {"\u5c3c\u6cca\u723e\u6642\u9593", "NPT",
"\u5c3c\u6cca\u723e\u590f\u4ee4\u6642\u9593", "NPST"};
String NST[] = new String[] {"\u7d10\u82ac\u862d\u6a19\u6e96\u6642\u9593", "NST",
@@ -441,7 +443,6 @@ public final class TimeZoneNames_zh_TW extends TimeZoneNamesBundle {
{"America/Winnipeg", CST},
{"America/Yakutat", AKST},
{"America/Yellowknife", MST},
- {"Antarctica/Casey", WST_AUS},
{"Antarctica/Davis", new String[] {"\u81fa\u7dad\u65af\u6642\u9593", "DAVT",
"\u81fa\u7dad\u65af\u590f\u4ee4\u6642\u9593", "DAVST"}},
{"Antarctica/DumontDUrville", new String[] {"Dumont-d'Urville \u6642\u9593", "DDUT",
@@ -529,8 +530,8 @@ public final class TimeZoneNames_zh_TW extends TimeZoneNamesBundle {
"\u83f2\u5f8b\u8cd3\u590f\u4ee4\u6642\u9593", "PHST"}},
{"Asia/Muscat", GST},
{"Asia/Nicosia", EET},
- {"Asia/Novosibirsk", new String[] {"Novosibirsk \u6642\u9593", "NOVT",
- "Novosibirsk \u590f\u4ee4\u6642\u9593", "NOVST"}},
+ {"Asia/Novokuznetsk", NOVT},
+ {"Asia/Novosibirsk", NOVT},
{"Asia/Oral", new String[] {"\u6b50\u4f5b\u6642\u9593", "ORAT",
"\u6b50\u4f5b\u590f\u4ee4\u6642\u9593", "ORAST"}},
{"Asia/Omsk", new String[] {"\u6b50\u59c6\u65af\u514b (Omsk) \u6642\u9593", "OMST",
diff --git a/src/share/native/sun/awt/image/jpeg/imageioJPEG.c b/src/share/native/sun/awt/image/jpeg/imageioJPEG.c
index 3897ddc86c6dfda9ea3cd1e790d019e638ad4a63..001d7de936fac125d99e0e643925445262304b9e 100644
--- a/src/share/native/sun/awt/image/jpeg/imageioJPEG.c
+++ b/src/share/native/sun/awt/image/jpeg/imageioJPEG.c
@@ -1460,6 +1460,7 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_initJPEGImageReader
JNU_ThrowByName( env,
"java/lang/OutOfMemoryError",
"Initializing Reader");
+ free(cinfo);
return 0;
}
@@ -1496,6 +1497,7 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_initJPEGImageReader
JNU_ThrowByName(env,
"java/lang/OutOfMemoryError",
"Initializing Reader");
+ imageio_dispose((j_common_ptr)cinfo);
return 0;
}
cinfo->src->bytes_in_buffer = 0;
@@ -1512,6 +1514,7 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_initJPEGImageReader
JNU_ThrowByName( env,
"java/lang/OutOfMemoryError",
"Initializing Reader");
+ imageio_dispose((j_common_ptr)cinfo);
return 0;
}
return (jlong) ret;
@@ -2450,8 +2453,7 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_initJPEGImageWriter
JNU_ThrowByName( env,
"java/lang/OutOfMemoryError",
"Initializing Writer");
- free(cinfo);
- free(jerr);
+ imageio_dispose((j_common_ptr)cinfo);
return 0;
}
@@ -2469,8 +2471,7 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_initJPEGImageWriter
JNU_ThrowByName( env,
"java/lang/OutOfMemoryError",
"Initializing Writer");
- free(cinfo);
- free(jerr);
+ imageio_dispose((j_common_ptr)cinfo);
return 0;
}
return (jlong) ret;
diff --git a/src/share/native/sun/awt/medialib/awt_ImagingLib.c b/src/share/native/sun/awt/medialib/awt_ImagingLib.c
index 157827fef29b105239e913872854a3c7c98cc02e..07f9187ffc88120242e9841e7270355c5f059388 100644
--- a/src/share/native/sun/awt/medialib/awt_ImagingLib.c
+++ b/src/share/native/sun/awt/medialib/awt_ImagingLib.c
@@ -960,21 +960,15 @@ Java_sun_awt_image_ImagingLib_transformRaster(JNIEnv *env, jobject this,
mlib_filter filter;
unsigned int *dP;
- if ((srcRasterP = (RasterS_t *) calloc(1, sizeof(RasterS_t))) == NULL) {
- JNU_ThrowOutOfMemoryError(env, "Out of memory");
- return -1;
- }
-
- if ((dstRasterP = (RasterS_t *) calloc(1, sizeof(RasterS_t))) == NULL) {
- JNU_ThrowOutOfMemoryError(env, "Out of memory");
- free(srcRasterP);
- return -1;
- }
-
/* This function requires a lot of local refs ??? Is 64 enough ??? */
if ((*env)->EnsureLocalCapacity(env, 64) < 0)
return 0;
+ if (s_nomlib) return 0;
+ if (s_timeIt) {
+ (*start_timer)(3600);
+ }
+
switch(interpType) {
case java_awt_image_AffineTransformOp_TYPE_BILINEAR:
filter = MLIB_BILINEAR;
@@ -990,9 +984,15 @@ Java_sun_awt_image_ImagingLib_transformRaster(JNIEnv *env, jobject this,
return -1;
}
- if (s_nomlib) return 0;
- if (s_timeIt) {
- (*start_timer)(3600);
+ if ((srcRasterP = (RasterS_t *) calloc(1, sizeof(RasterS_t))) == NULL) {
+ JNU_ThrowOutOfMemoryError(env, "Out of memory");
+ return -1;
+ }
+
+ if ((dstRasterP = (RasterS_t *) calloc(1, sizeof(RasterS_t))) == NULL) {
+ JNU_ThrowOutOfMemoryError(env, "Out of memory");
+ free(srcRasterP);
+ return -1;
}
if ((*env)->GetArrayLength(env, jmatrix) < 6) {
@@ -1215,6 +1215,9 @@ Java_sun_awt_image_ImagingLib_lookupByteBI(JNIEnv *env, jobject this,
}
if (tbl == NULL || table == NULL || jtable == NULL) {
+ if (tbl != NULL) free(tbl);
+ if (table != NULL) free(table);
+ if (jtable != NULL) free(jtable);
awt_freeParsedImage(srcImageP, TRUE);
awt_freeParsedImage(dstImageP, TRUE);
JNU_ThrowNullPointerException(env, "NULL LUT");
@@ -1224,6 +1227,11 @@ Java_sun_awt_image_ImagingLib_lookupByteBI(JNIEnv *env, jobject this,
for (i=0; i < jlen; i++) {
jtable[i] = (*env)->GetObjectArrayElement(env, jtableArrays, i);
if (jtable[i] == NULL) {
+ free(tbl);
+ free(table);
+ free(jtable);
+ awt_freeParsedImage(srcImageP, TRUE);
+ awt_freeParsedImage(dstImageP, TRUE);
return 0;
}
}
@@ -1232,6 +1240,9 @@ Java_sun_awt_image_ImagingLib_lookupByteBI(JNIEnv *env, jobject this,
FALSE, &hint);
if (nbands < 1) {
/* Can't handle any custom images */
+ free(tbl);
+ free(table);
+ free(jtable);
awt_freeParsedImage(srcImageP, TRUE);
awt_freeParsedImage(dstImageP, TRUE);
return 0;
@@ -1240,12 +1251,18 @@ Java_sun_awt_image_ImagingLib_lookupByteBI(JNIEnv *env, jobject this,
/* Allocate the arrays */
if (allocateArray(env, srcImageP, &src, &sdata, TRUE, FALSE, FALSE) < 0) {
/* Must be some problem */
+ free(tbl);
+ free(table);
+ free(jtable);
awt_freeParsedImage(srcImageP, TRUE);
awt_freeParsedImage(dstImageP, TRUE);
return 0;
}
if (allocateArray(env, dstImageP, &dst, &ddata, FALSE, FALSE, FALSE) < 0) {
/* Must be some problem */
+ free(tbl);
+ free(table);
+ free(jtable);
freeArray(env, srcImageP, src, sdata, NULL, NULL, NULL);
awt_freeParsedImage(srcImageP, TRUE);
awt_freeParsedImage(dstImageP, TRUE);
@@ -1284,6 +1301,9 @@ Java_sun_awt_image_ImagingLib_lookupByteBI(JNIEnv *env, jobject this,
(jbyte *) table[j],
JNI_ABORT);
}
+ free(tbl);
+ free(table);
+ free(jtable);
freeArray(env, srcImageP, src, sdata, NULL, NULL, NULL);
awt_freeParsedImage(srcImageP, TRUE);
awt_freeParsedImage(dstImageP, TRUE);
@@ -1413,12 +1433,15 @@ Java_sun_awt_image_ImagingLib_lookupByteRaster(JNIEnv *env,
/* Parse the source raster - reject custom images */
if ((status = awt_parseRaster(env, jsrc, srcRasterP)) <= 0) {
+ free(srcRasterP);
+ free(dstRasterP);
return 0;
}
/* Parse the destination image - reject custom images */
if ((status = awt_parseRaster(env, jdst, dstRasterP)) <= 0) {
awt_freeParsedRaster(srcRasterP, TRUE);
+ free(dstRasterP);
return 0;
}
diff --git a/src/share/native/sun/font/freetypeScaler.c b/src/share/native/sun/font/freetypeScaler.c
index 4028d4d97c4bb68abdd41452bfdd373c848235a0..93baaea47cd4e05d2ed0a4891d940d277e5ac6c9 100644
--- a/src/share/native/sun/font/freetypeScaler.c
+++ b/src/share/native/sun/font/freetypeScaler.c
@@ -102,9 +102,21 @@ Java_sun_font_FreetypeFontScaler_initIDs(
}
static void freeNativeResources(JNIEnv *env, FTScalerInfo* scalerInfo) {
+ void *stream;
+
if (scalerInfo == NULL)
return;
+ //apparently Done_Face will only close the stream
+ // but will not relase the memory of stream structure.
+ // We need to free it explicitly to avoid leak.
+ //Direct access to the stream field might be not ideal solution as
+ // it is considred to be "private".
+ //Alternatively we could have stored pointer to the structure
+ // in the scalerInfo but this will increase size of the structure
+ // for no good reason
+ stream = scalerInfo->face->stream;
+
FT_Done_Face(scalerInfo->face);
FT_Done_FreeType(scalerInfo->library);
@@ -116,6 +128,10 @@ static void freeNativeResources(JNIEnv *env, FTScalerInfo* scalerInfo) {
free(scalerInfo->fontData);
}
+ if (stream != NULL) {
+ free(stream);
+ }
+
free(scalerInfo);
}
diff --git a/src/solaris/bin/java_md.c b/src/solaris/bin/java_md.c
index 73efc1090fddb70c1e82ef639f8bcf9cef8ebe76..7c68ed0831632a057c030c52200962224f23a151 100644
--- a/src/solaris/bin/java_md.c
+++ b/src/solaris/bin/java_md.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1998-2009 Sun Microsystems, Inc. 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
@@ -51,9 +51,9 @@
* two data models and cohabitation of jre/jdk bits with both data
* models is supported, then DUAL_MODE is defined. When DUAL_MODE is
* defined, the architecture names for the narrow and wide version of
- * the architecture are defined in LIBARCH64NAME and LIBARCH32NAME. Currently
- * only Solaris on sparc/sparcv9 and i586/amd64 is DUAL_MODE; linux
- * i586/amd64 could be defined as DUAL_MODE but that is not the
+ * the architecture are defined in LIBARCH64NAME and LIBARCH32NAME.
+ * Currently only Solaris on sparc/sparcv9 and i586/amd64 is DUAL_MODE;
+ * linux i586/amd64 could be defined as DUAL_MODE but that is not the
* current policy.
*/
@@ -103,49 +103,56 @@ static char *execname = NULL;
* platform independent routine SelectVersion. This may result in
* the exec of the specified launcher version.
*
- * Typically, the launcher execs at least once to ensure a suitable
- * LD_LIBRARY_PATH is in effect for the process. The first exec
- * screens out all the data model options; leaving the choice of data
- * model implicit in the binary selected to run. However, in case no
- * exec is done, the data model options are screened out before the vm
- * is invoked.
+ * Previously the launcher modified the LD_LIBRARY_PATH appropriately for the
+ * desired data model path, regardless if data models matched or not. The
+ * launcher subsequently exec'ed the desired executable, in order to make the
+ * LD_LIBRARY_PATH path available for the runtime linker. This is no longer the
+ * case, the launcher dlopens the target libjvm.so. All other required
+ * libraries are loaded by the runtime linker, by virtue of the $ORIGIN paths
+ * baked into the shared libraries, by the build infrastructure at compile time.
*
- * incoming argv ------------------------------
- * | |
- * \|/ |
- * CheckJVMType |
- * (removes -client, -server, etc.) |
- * \|/
- * CreateExecutionEnvironment
- * (removes -d32 and -d64,
- * determines desired data model,
- * sets up LD_LIBRARY_PATH,
- * and exec's)
- * |
- * --------------------------------------------
+ * Main
+ * (incoming argv)
+ * |
+ * \|/
+ * SelectVersion
+ * (selects the JRE version, note: not data model)
+ * |
+ * \|/
+ * CreateExecutionEnvironment
+ * (determines desired data model)
+ * |
* |
* \|/
- * exec child 1 incoming argv -----------------
+ * Have Desired Model ? --> NO --> Is Dual-Mode ? --> NO --> Exit(with error)
+ * | |
+ * | |
+ * | \|/
+ * | YES
+ * | |
* | |
- * \|/ |
- * CheckJVMType |
- * (removes -client, -server, etc.) |
* | \|/
- * | CreateExecutionEnvironment
- * | (verifies desired data model
- * | is running and acceptable
- * | LD_LIBRARY_PATH;
- * | no-op in child)
+ * | CheckJvmType
+ * | (removes -client, -server etc.)
+ * | |
+ * | |
+ * \|/ \|/
+ * YES (find the desired executable and exec child)
+ * | |
+ * | |
+ * \|/ \|/
+ * CheckJvmType Main
+ * (removes -client, -server, etc.)
+ * |
* |
* \|/
* TranslateDashJArgs...
* (Prepare to pass args to vm)
* |
* |
- * |
* \|/
* ParseArguments
- * (ignores -d32 and -d64,
+ * (removes -d32 and -d64 if any,
* processes version options,
* creates argument list for vm,
* etc.)
@@ -199,17 +206,13 @@ CreateExecutionEnvironment(int *_argcp,
/* Compute/set the name of the executable */
SetExecname(*_argvp);
- /* Set the LD_LIBRARY_PATH environment variable, check data model
- flags, and exec process, if needed */
+ /* Check data model flags, and exec process, if needed */
{
char *arch = (char *)GetArch(); /* like sparc or sparcv9 */
char * jvmtype = NULL;
int argc = *_argcp;
char **argv = original_argv;
- char *runpath = NULL; /* existing effective LD_LIBRARY_PATH
- setting */
-
int running = CURRENT_DATA_MODEL;
int wanted = running; /* What data mode is being
@@ -217,18 +220,8 @@ CreateExecutionEnvironment(int *_argcp,
fine unless another model
is asked for */
- char* new_runpath = NULL; /* desired new LD_LIBRARY_PATH string */
- char* newpath = NULL; /* path on new LD_LIBRARY_PATH */
- char* lastslash = NULL;
-
- char** newenvp = NULL; /* current environment */
-
char** newargv = NULL;
int newargc = 0;
-#ifdef __solaris__
- char* dmpath = NULL; /* data model specific LD_LIBRARY_PATH,
- Solaris only */
-#endif
/*
* Starting in 1.5, all unix platforms accept the -d32 and -d64
@@ -306,6 +299,11 @@ CreateExecutionEnvironment(int *_argcp,
JLI_ReportErrorMessage(CFG_ERROR8, jvmtype, jvmpath);
exit(4);
}
+ /*
+ * we seem to have everything we need, so without further ado
+ * we return back.
+ */
+ return;
} else { /* do the same speculatively or exit */
#ifdef DUAL_MODE
if (running != wanted) {
@@ -335,190 +333,6 @@ CreateExecutionEnvironment(int *_argcp,
#endif
}
- /*
- * We will set the LD_LIBRARY_PATH as follows:
- *
- * o $JVMPATH (directory portion only)
- * o $JRE/lib/$LIBARCHNAME
- * o $JRE/../lib/$LIBARCHNAME
- *
- * followed by the user's previous effective LD_LIBRARY_PATH, if
- * any.
- */
-
-#ifdef __solaris__
- /*
- * Starting in Solaris 7, ld.so.1 supports three LD_LIBRARY_PATH
- * variables:
- *
- * 1. LD_LIBRARY_PATH -- used for 32 and 64 bit searches if
- * data-model specific variables are not set.
- *
- * 2. LD_LIBRARY_PATH_64 -- overrides and replaces LD_LIBRARY_PATH
- * for 64-bit binaries.
- *
- * 3. LD_LIBRARY_PATH_32 -- overrides and replaces LD_LIBRARY_PATH
- * for 32-bit binaries.
- *
- * The vm uses LD_LIBRARY_PATH to set the java.library.path system
- * property. To shield the vm from the complication of multiple
- * LD_LIBRARY_PATH variables, if the appropriate data model
- * specific variable is set, we will act as if LD_LIBRARY_PATH had
- * the value of the data model specific variant and the data model
- * specific variant will be unset. Note that the variable for the
- * *wanted* data model must be used (if it is set), not simply the
- * current running data model.
- */
-
- switch(wanted) {
- case 0:
- if(running == 32) {
- dmpath = getenv("LD_LIBRARY_PATH_32");
- wanted = 32;
- }
- else {
- dmpath = getenv("LD_LIBRARY_PATH_64");
- wanted = 64;
- }
- break;
-
- case 32:
- dmpath = getenv("LD_LIBRARY_PATH_32");
- break;
-
- case 64:
- dmpath = getenv("LD_LIBRARY_PATH_64");
- break;
-
- default:
- JLI_ReportErrorMessage(JRE_ERROR3, __LINE__);
- exit(1); /* unknown value in wanted */
- break;
- }
-
- /*
- * If dmpath is NULL, the relevant data model specific variable is
- * not set and normal LD_LIBRARY_PATH should be used.
- */
- if( dmpath == NULL) {
- runpath = getenv("LD_LIBRARY_PATH");
- }
- else {
- runpath = dmpath;
- }
-#else
- /*
- * If not on Solaris, assume only a single LD_LIBRARY_PATH
- * variable.
- */
- runpath = getenv("LD_LIBRARY_PATH");
-#endif /* __solaris__ */
-
-#ifdef __linux
- /*
- * On linux, if a binary is running as sgid or suid, glibc sets
- * LD_LIBRARY_PATH to the empty string for security purposes. (In
- * contrast, on Solaris the LD_LIBRARY_PATH variable for a
- * privileged binary does not lose its settings; but the dynamic
- * linker does apply more scrutiny to the path.) The launcher uses
- * the value of LD_LIBRARY_PATH to prevent an exec loop.
- * Therefore, if we are running sgid or suid, this function's
- * setting of LD_LIBRARY_PATH will be ineffective and we should
- * return from the function now. Getting the right libraries to
- * be found must be handled through other mechanisms.
- */
- if((getgid() != getegid()) || (getuid() != geteuid()) ) {
- return;
- }
-#endif
-
- /* runpath contains current effective LD_LIBRARY_PATH setting */
-
- jvmpath = JLI_StringDup(jvmpath);
- new_runpath = JLI_MemAlloc( ((runpath!=NULL)?JLI_StrLen(runpath):0) +
- 2*JLI_StrLen(jrepath) + 2*JLI_StrLen(arch) +
- JLI_StrLen(jvmpath) + 52);
- newpath = new_runpath + JLI_StrLen("LD_LIBRARY_PATH=");
-
-
- /*
- * Create desired LD_LIBRARY_PATH value for target data model.
- */
- {
- /* remove the name of the .so from the JVM path */
- lastslash = JLI_StrRChr(jvmpath, '/');
- if (lastslash)
- *lastslash = '\0';
-
-
- /* jvmpath, ((running != wanted)?((wanted==64)?"/"LIBARCH64NAME:"/.."):""), */
-
- sprintf(new_runpath, "LD_LIBRARY_PATH="
- "%s:"
- "%s/lib/%s:"
- "%s/../lib/%s",
- jvmpath,
-#ifdef DUAL_MODE
- jrepath, GetArchPath(wanted),
- jrepath, GetArchPath(wanted)
-#else
- jrepath, arch,
- jrepath, arch
-#endif
- );
-
-
- /*
- * Check to make sure that the prefix of the current path is the
- * desired environment variable setting.
- */
- if (runpath != NULL &&
- JLI_StrNCmp(newpath, runpath, JLI_StrLen(newpath))==0 &&
- (runpath[JLI_StrLen(newpath)] == 0 || runpath[JLI_StrLen(newpath)] == ':') &&
- (running == wanted) /* data model does not have to be changed */
-#ifdef __solaris__
- && (dmpath == NULL) /* data model specific variables not set */
-#endif
- ) {
-
- return;
-
- }
- }
-
- /*
- * Place the desired environment setting onto the prefix of
- * LD_LIBRARY_PATH. Note that this prevents any possible infinite
- * loop of execv() because we test for the prefix, above.
- */
- if (runpath != 0) {
- JLI_StrCat(new_runpath, ":");
- JLI_StrCat(new_runpath, runpath);
- }
-
- if( putenv(new_runpath) != 0) {
- exit(1); /* problem allocating memory; LD_LIBRARY_PATH not set
- properly */
- }
-
- /*
- * Unix systems document that they look at LD_LIBRARY_PATH only
- * once at startup, so we have to re-exec the current executable
- * to get the changed environment variable to have an effect.
- */
-
-#ifdef __solaris__
- /*
- * If dmpath is not NULL, remove the data model specific string
- * in the environment for the exec'ed child.
- */
-
- if( dmpath != NULL)
- (void)UnsetEnv((wanted==32)?"LD_LIBRARY_PATH_32":"LD_LIBRARY_PATH_64");
-#endif
-
- newenvp = environ;
-
{
char *newexec = execname;
#ifdef DUAL_MODE
@@ -549,17 +363,16 @@ CreateExecutionEnvironment(int *_argcp,
argv[0] = newexec;
}
#endif
-
+ JLI_TraceLauncher("TRACER_MARKER:About to EXEC\n");
(void)fflush(stdout);
(void)fflush(stderr);
- execve(newexec, argv, newenvp);
+ execv(newexec, argv);
JLI_ReportErrorMessageSys(JRE_ERROR4, newexec);
#ifdef DUAL_MODE
if (running != wanted) {
JLI_ReportErrorMessage(JRE_ERROR5, wanted, running);
# ifdef __solaris__
-
# ifdef __sparc
JLI_ReportErrorMessage(JRE_ERROR6);
# else
@@ -570,13 +383,11 @@ CreateExecutionEnvironment(int *_argcp,
#endif
}
-
exit(1);
}
}
-
/*
* On Solaris VM choosing is done by the launcher (java.c).
*/
@@ -1123,6 +934,7 @@ ExecJRE(char *jre, char **argv)
printf(" %s", argv[i]);
printf("\n");
}
+ JLI_TraceLauncher("TRACER_MARKER:About to EXEC\n");
(void)fflush(stdout);
(void)fflush(stderr);
execv(wanted, argv);
diff --git a/src/solaris/classes/sun/awt/X11/XDropTargetRegistry.java b/src/solaris/classes/sun/awt/X11/XDropTargetRegistry.java
index 509a5e3274555e5f95881397438e8a130f4bd5ea..96040316391b8550310a409124b1a5c2a29050d4 100644
--- a/src/solaris/classes/sun/awt/X11/XDropTargetRegistry.java
+++ b/src/solaris/classes/sun/awt/X11/XDropTargetRegistry.java
@@ -534,71 +534,71 @@ final class XDropTargetRegistry {
return entry.getSite(x, y);
}
+ /*
+ * Note: this method should be called under AWT lock.
+ */
public void registerDropSite(long window) {
+ assert XToolkit.isAWTLockHeldByCurrentThread();
+
if (window == 0) {
throw new IllegalArgumentException();
}
XDropTargetEventProcessor.activate();
- XToolkit.awtLock();
- try {
- long toplevel = getToplevelWindow(window);
-
- /*
- * No window with WM_STATE property is found.
- * Since the window can be a plugin window reparented to the browser
- * toplevel, we cannot determine which window will eventually have
- * WM_STATE property set. So we schedule a timer callback that will
- * periodically attempt to find an ancestor with WM_STATE and
- * register the drop site appropriately.
- */
- if (toplevel == 0) {
- addDelayedRegistrationEntry(window);
- return;
- }
+ long toplevel = getToplevelWindow(window);
- if (toplevel == window) {
- Iterator dropTargetProtocols =
- XDragAndDropProtocols.getDropTargetProtocols();
+ /*
+ * No window with WM_STATE property is found.
+ * Since the window can be a plugin window reparented to the browser
+ * toplevel, we cannot determine which window will eventually have
+ * WM_STATE property set. So we schedule a timer callback that will
+ * periodically attempt to find an ancestor with WM_STATE and
+ * register the drop site appropriately.
+ */
+ if (toplevel == 0) {
+ addDelayedRegistrationEntry(window);
+ return;
+ }
- while (dropTargetProtocols.hasNext()) {
- XDropTargetProtocol dropTargetProtocol =
- (XDropTargetProtocol)dropTargetProtocols.next();
- dropTargetProtocol.registerDropTarget(toplevel);
- }
- } else {
- registerEmbeddedDropSite(toplevel, window);
+ if (toplevel == window) {
+ Iterator dropTargetProtocols =
+ XDragAndDropProtocols.getDropTargetProtocols();
+
+ while (dropTargetProtocols.hasNext()) {
+ XDropTargetProtocol dropTargetProtocol =
+ (XDropTargetProtocol)dropTargetProtocols.next();
+ dropTargetProtocol.registerDropTarget(toplevel);
}
- } finally {
- XToolkit.awtUnlock();
+ } else {
+ registerEmbeddedDropSite(toplevel, window);
}
}
+ /*
+ * Note: this method should be called under AWT lock.
+ */
public void unregisterDropSite(long window) {
+ assert XToolkit.isAWTLockHeldByCurrentThread();
+
if (window == 0) {
throw new IllegalArgumentException();
}
- XToolkit.awtLock();
- try {
- long toplevel = getToplevelWindow(window);
+ long toplevel = getToplevelWindow(window);
- if (toplevel == window) {
- Iterator dropProtocols =
- XDragAndDropProtocols.getDropTargetProtocols();
+ if (toplevel == window) {
+ Iterator dropProtocols =
+ XDragAndDropProtocols.getDropTargetProtocols();
- removeDelayedRegistrationEntry(window);
+ removeDelayedRegistrationEntry(window);
- while (dropProtocols.hasNext()) {
- XDropTargetProtocol dropProtocol = (XDropTargetProtocol)dropProtocols.next();
- dropProtocol.unregisterDropTarget(window);
- }
- } else {
- unregisterEmbeddedDropSite(toplevel, window);
+ while (dropProtocols.hasNext()) {
+ XDropTargetProtocol dropProtocol = (XDropTargetProtocol)dropProtocols.next();
+ dropProtocol.unregisterDropTarget(window);
}
- } finally {
- XToolkit.awtUnlock();
+ } else {
+ unregisterEmbeddedDropSite(toplevel, window);
}
}
diff --git a/src/solaris/classes/sun/awt/X11/XWindow.java b/src/solaris/classes/sun/awt/X11/XWindow.java
index 8c44c3280823c32281223e5b224f26964b148ac3..58d1fe8bd7c37e14fa1a216c9ee32c8d6aacebe2 100644
--- a/src/solaris/classes/sun/awt/X11/XWindow.java
+++ b/src/solaris/classes/sun/awt/X11/XWindow.java
@@ -1509,4 +1509,24 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
return new XAtomList();
}
+ /**
+ * Indicates if the window is currently in the FSEM.
+ * Synchronization: state lock.
+ */
+ private boolean fullScreenExclusiveModeState = false;
+
+ // Implementation of the X11ComponentPeer
+ @Override
+ public void setFullScreenExclusiveModeState(boolean state) {
+ synchronized (getStateLock()) {
+ fullScreenExclusiveModeState = state;
+ }
+ }
+
+ public final boolean isFullScreenExclusiveMode() {
+ synchronized (getStateLock()) {
+ return fullScreenExclusiveModeState;
+ }
+ }
+
}
diff --git a/src/solaris/classes/sun/awt/X11/XWindowPeer.java b/src/solaris/classes/sun/awt/X11/XWindowPeer.java
index f87ec27c56542758eb113fe6862848fdc114364e..52e7a531188e0aed3cb067153efa3996d88adf30 100644
--- a/src/solaris/classes/sun/awt/X11/XWindowPeer.java
+++ b/src/solaris/classes/sun/awt/X11/XWindowPeer.java
@@ -1079,31 +1079,39 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
updateSecurityWarningVisibility();
}
+ @Override
+ public void setFullScreenExclusiveModeState(boolean state) {
+ super.setFullScreenExclusiveModeState(state);
+ updateSecurityWarningVisibility();
+ }
+
public void updateSecurityWarningVisibility() {
if (warningWindow == null) {
return;
}
- boolean show = false;
-
- int state = getWMState();
-
if (!isVisible()) {
return; // The warning window should already be hidden.
}
- // getWMState() always returns 0 (Withdrawn) for simple windows. Hence
- // we ignore the state for such windows.
- if (isVisible() && (state == XUtilConstants.NormalState || isSimpleWindow())) {
- if (XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow() ==
- getTarget())
- {
- show = true;
- }
+ boolean show = false;
- if (isMouseAbove() || warningWindow.isMouseAbove())
- {
- show = true;
+ if (!isFullScreenExclusiveMode()) {
+ int state = getWMState();
+
+ // getWMState() always returns 0 (Withdrawn) for simple windows. Hence
+ // we ignore the state for such windows.
+ if (isVisible() && (state == XUtilConstants.NormalState || isSimpleWindow())) {
+ if (XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow() ==
+ getTarget())
+ {
+ show = true;
+ }
+
+ if (isMouseAbove() || warningWindow.isMouseAbove())
+ {
+ show = true;
+ }
}
}
@@ -1756,25 +1764,36 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
}
}
+ // should be synchronized on awtLock
private int dropTargetCount = 0;
- public synchronized void addDropTarget() {
- if (dropTargetCount == 0) {
- long window = getWindow();
- if (window != 0) {
- XDropTargetRegistry.getRegistry().registerDropSite(window);
+ public void addDropTarget() {
+ XToolkit.awtLock();
+ try {
+ if (dropTargetCount == 0) {
+ long window = getWindow();
+ if (window != 0) {
+ XDropTargetRegistry.getRegistry().registerDropSite(window);
+ }
}
+ dropTargetCount++;
+ } finally {
+ XToolkit.awtUnlock();
}
- dropTargetCount++;
}
- public synchronized void removeDropTarget() {
- dropTargetCount--;
- if (dropTargetCount == 0) {
- long window = getWindow();
- if (window != 0) {
- XDropTargetRegistry.getRegistry().unregisterDropSite(window);
+ public void removeDropTarget() {
+ XToolkit.awtLock();
+ try {
+ dropTargetCount--;
+ if (dropTargetCount == 0) {
+ long window = getWindow();
+ if (window != 0) {
+ XDropTargetRegistry.getRegistry().unregisterDropSite(window);
+ }
}
+ } finally {
+ XToolkit.awtUnlock();
}
}
void addRootPropertyEventDispatcher() {
@@ -1837,13 +1856,18 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
}
}
- protected synchronized void updateDropTarget() {
- if (dropTargetCount > 0) {
- long window = getWindow();
- if (window != 0) {
- XDropTargetRegistry.getRegistry().unregisterDropSite(window);
- XDropTargetRegistry.getRegistry().registerDropSite(window);
+ protected void updateDropTarget() {
+ XToolkit.awtLock();
+ try {
+ if (dropTargetCount > 0) {
+ long window = getWindow();
+ if (window != 0) {
+ XDropTargetRegistry.getRegistry().unregisterDropSite(window);
+ XDropTargetRegistry.getRegistry().registerDropSite(window);
+ }
}
+ } finally {
+ XToolkit.awtUnlock();
}
}
diff --git a/src/solaris/classes/sun/awt/X11ComponentPeer.java b/src/solaris/classes/sun/awt/X11ComponentPeer.java
index a4a0750689473c0069b441cf79048b452a187e50..24b24809285af0e52b8131af2e511c0ac7f45bd9 100644
--- a/src/solaris/classes/sun/awt/X11ComponentPeer.java
+++ b/src/solaris/classes/sun/awt/X11ComponentPeer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -39,4 +39,5 @@ public interface X11ComponentPeer {
Rectangle getBounds();
Graphics getGraphics();
Object getTarget();
+ void setFullScreenExclusiveModeState(boolean state);
}
diff --git a/src/solaris/classes/sun/awt/X11GraphicsDevice.java b/src/solaris/classes/sun/awt/X11GraphicsDevice.java
index 81491abeea359bab34dfa0064219ac1fe67134b7..115320bb0564020976100d096284b7f1636d62ca 100644
--- a/src/solaris/classes/sun/awt/X11GraphicsDevice.java
+++ b/src/solaris/classes/sun/awt/X11GraphicsDevice.java
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc. 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
@@ -306,12 +306,14 @@ public class X11GraphicsDevice
X11ComponentPeer peer = (X11ComponentPeer)w.getPeer();
if (peer != null) {
enterFullScreenExclusive(peer.getContentWindow());
+ peer.setFullScreenExclusiveModeState(true);
}
}
private static void exitFullScreenExclusive(Window w) {
X11ComponentPeer peer = (X11ComponentPeer)w.getPeer();
if (peer != null) {
+ peer.setFullScreenExclusiveModeState(false);
exitFullScreenExclusive(peer.getContentWindow());
}
}
diff --git a/src/solaris/classes/sun/java2d/x11/X11SurfaceData.java b/src/solaris/classes/sun/java2d/x11/X11SurfaceData.java
index f613c11883179c94d88455288abf65d623395775..943f6e73a063c3d67e79b3ab1a7584a5793a083c 100644
--- a/src/solaris/classes/sun/java2d/x11/X11SurfaceData.java
+++ b/src/solaris/classes/sun/java2d/x11/X11SurfaceData.java
@@ -388,7 +388,10 @@ public abstract class X11SurfaceData extends SurfaceData {
// if a GlyphVector overrides the AA setting.
// We use getRenderLoops() rather than setting solidloops
// directly so that we get the appropriate loops in XOR mode.
- sg2d.loops = getRenderLoops(sg2d);
+ if (sg2d.loops == null) {
+ // assert(some pipe will always be a LoopBasedPipe)
+ sg2d.loops = getRenderLoops(sg2d);
+ }
} else {
super.validatePipe(sg2d);
}
diff --git a/src/solaris/native/sun/awt/awt_GraphicsEnv.c b/src/solaris/native/sun/awt/awt_GraphicsEnv.c
index 7afdf1681c62c89e725f05162b8e0b6dad1bc8ee..ef4fa15afa59642322366a86382f687813a39084 100644
--- a/src/solaris/native/sun/awt/awt_GraphicsEnv.c
+++ b/src/solaris/native/sun/awt/awt_GraphicsEnv.c
@@ -1654,6 +1654,7 @@ Java_sun_awt_X11GraphicsEnvironment_getXineramaCenterPoint(JNIEnv *env,
#ifndef HEADLESS
#define BIT_DEPTH_MULTI java_awt_DisplayMode_BIT_DEPTH_MULTI
+#define REFRESH_RATE_UNKNOWN java_awt_DisplayMode_REFRESH_RATE_UNKNOWN
typedef Status
(*XRRQueryVersionType) (Display *dpy, int *major_versionp, int *minor_versionp);
@@ -1680,6 +1681,9 @@ typedef Status
Rotation rotation,
short rate,
Time timestamp);
+typedef Rotation
+ (*XRRConfigRotationsType)(XRRScreenConfiguration *config,
+ Rotation *current_rotation);
static XRRQueryVersionType awt_XRRQueryVersion;
static XRRGetScreenInfoType awt_XRRGetScreenInfo;
@@ -1689,6 +1693,7 @@ static XRRConfigCurrentRateType awt_XRRConfigCurrentRate;
static XRRConfigSizesType awt_XRRConfigSizes;
static XRRConfigCurrentConfigurationType awt_XRRConfigCurrentConfiguration;
static XRRSetScreenConfigAndRateType awt_XRRSetScreenConfigAndRate;
+static XRRConfigRotationsType awt_XRRConfigRotations;
#define LOAD_XRANDR_FUNC(f) \
do { \
@@ -1755,6 +1760,7 @@ X11GD_InitXrandrFuncs(JNIEnv *env)
LOAD_XRANDR_FUNC(XRRConfigSizes);
LOAD_XRANDR_FUNC(XRRConfigCurrentConfiguration);
LOAD_XRANDR_FUNC(XRRSetScreenConfigAndRate);
+ LOAD_XRANDR_FUNC(XRRConfigRotations);
return JNI_TRUE;
}
@@ -1765,6 +1771,7 @@ X11GD_CreateDisplayMode(JNIEnv *env, jint width, jint height,
{
jclass displayModeClass;
jmethodID cid;
+ jint validRefreshRate = refreshRate;
displayModeClass = (*env)->FindClass(env, "java/awt/DisplayMode");
if (JNU_IsNull(env, displayModeClass)) {
@@ -1780,8 +1787,13 @@ X11GD_CreateDisplayMode(JNIEnv *env, jint width, jint height,
return NULL;
}
+ // early versions of xrandr may report "empty" rates (6880694)
+ if (validRefreshRate <= 0) {
+ validRefreshRate = REFRESH_RATE_UNKNOWN;
+ }
+
return (*env)->NewObject(env, displayModeClass, cid,
- width, height, bitDepth, refreshRate);
+ width, height, bitDepth, validRefreshRate);
}
static void
@@ -1926,8 +1938,7 @@ Java_sun_awt_X11GraphicsDevice_getCurrentDisplayMode
curRate = awt_XRRConfigCurrentRate(config);
if ((sizes != NULL) &&
- (curSizeIndex < nsizes) &&
- (curRate > 0))
+ (curSizeIndex < nsizes))
{
XRRScreenSize curSize = sizes[curSizeIndex];
displayMode = X11GD_CreateDisplayMode(env,
@@ -2004,6 +2015,7 @@ Java_sun_awt_X11GraphicsDevice_configDisplayMode
jboolean success = JNI_FALSE;
XRRScreenConfiguration *config;
Drawable root;
+ Rotation currentRotation = RR_Rotate_0;
AWT_LOCK();
@@ -2015,6 +2027,7 @@ Java_sun_awt_X11GraphicsDevice_configDisplayMode
short chosenRate = -1;
int nsizes;
XRRScreenSize *sizes = awt_XRRConfigSizes(config, &nsizes);
+ awt_XRRConfigRotations(config, ¤tRotation);
if (sizes != NULL) {
int i, j;
@@ -2048,7 +2061,7 @@ Java_sun_awt_X11GraphicsDevice_configDisplayMode
Status status =
awt_XRRSetScreenConfigAndRate(awt_display, config, root,
chosenSizeIndex,
- RR_Rotate_0,
+ currentRotation,
chosenRate,
CurrentTime);
diff --git a/src/solaris/native/sun/awt/awt_GraphicsEnv.h b/src/solaris/native/sun/awt/awt_GraphicsEnv.h
index 224c55404444c8faf80a8da30a4bd8cba5d80108..330b605143d1d557fb9061b9cefbaba9ce99d2a7 100644
--- a/src/solaris/native/sun/awt/awt_GraphicsEnv.h
+++ b/src/solaris/native/sun/awt/awt_GraphicsEnv.h
@@ -42,6 +42,10 @@
#include
#include
#include
+#ifndef X_ShmAttach
+#include
+#include
+#endif
extern int XShmQueryExtension();
diff --git a/src/solaris/native/sun/awt/gtk2_interface.c b/src/solaris/native/sun/awt/gtk2_interface.c
index 1afeeef173b292515b6ee55ab846078eb0842970..e6ede30682402feef6bbfaf8ee791e69407a36ff 100644
--- a/src/solaris/native/sun/awt/gtk2_interface.c
+++ b/src/solaris/native/sun/awt/gtk2_interface.c
@@ -637,13 +637,13 @@ gboolean gtk2_load()
if (gtk_modules_env && strstr (gtk_modules_env, "atk-bridge") ||
gtk_modules_env && strstr (gtk_modules_env, "gail"))
{
- gchar *tmp_env = strdup (gtk_modules_env);
/* the new env will be smaller than the old one */
gchar *s, *new_env = malloc (sizeof(ENV_PREFIX)+strlen (gtk_modules_env));
if (new_env != NULL )
{
/* careful, strtok modifies its args */
+ gchar *tmp_env = strdup (gtk_modules_env);
strcpy(new_env, ENV_PREFIX);
/* strip out 'atk-bridge' and 'gail' */
diff --git a/src/solaris/native/sun/xawt/XToolkit.c b/src/solaris/native/sun/xawt/XToolkit.c
index 6ce5876c54478972fa18dd670bda76388714adb9..a4323b31995cd919fa7dbe8db5879b374addbfe3 100644
--- a/src/solaris/native/sun/xawt/XToolkit.c
+++ b/src/solaris/native/sun/xawt/XToolkit.c
@@ -677,7 +677,7 @@ JNIEXPORT jstring JNICALL Java_sun_awt_X11_XToolkit_getEnv
jstring ret = NULL;
keystr = JNU_GetStringPlatformChars(env, key, NULL);
- if (key) {
+ if (keystr) {
ptr = getenv(keystr);
if (ptr) {
ret = JNU_NewStringPlatform(env, (const char *) ptr);
diff --git a/src/windows/classes/sun/awt/Win32GraphicsDevice.java b/src/windows/classes/sun/awt/Win32GraphicsDevice.java
index 8a0960bc6d8d57755bc4abc728b4665bc5eb7a96..4be644c2f7176d962cac504cde485abf5b7a4a6c 100644
--- a/src/windows/classes/sun/awt/Win32GraphicsDevice.java
+++ b/src/windows/classes/sun/awt/Win32GraphicsDevice.java
@@ -353,6 +353,7 @@ public class Win32GraphicsDevice extends GraphicsDevice implements
}
WWindowPeer peer = (WWindowPeer)old.getPeer();
if (peer != null) {
+ peer.setFullScreenExclusiveModeState(false);
// we used to destroy the buffers on exiting fs mode, this
// is no longer needed since fs change will cause a surface
// data replacement
@@ -370,12 +371,15 @@ public class Win32GraphicsDevice extends GraphicsDevice implements
addFSWindowListener(w);
// Enter full screen exclusive mode.
WWindowPeer peer = (WWindowPeer)w.getPeer();
- synchronized(peer) {
- enterFullScreenExclusive(screen, peer);
- // Note: removed replaceSurfaceData() call because
- // changing the window size or making it visible
- // will cause this anyway, and both of these events happen
- // as part of switching into fullscreen mode.
+ if (peer != null) {
+ synchronized(peer) {
+ enterFullScreenExclusive(screen, peer);
+ // Note: removed replaceSurfaceData() call because
+ // changing the window size or making it visible
+ // will cause this anyway, and both of these events happen
+ // as part of switching into fullscreen mode.
+ }
+ peer.setFullScreenExclusiveModeState(true);
}
// fix for 4868278
diff --git a/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java b/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java
index 36636aef64cf6f8db82a5c807d25b43ac718b777..f9b2f4c42802929ebbdfb6f8e79ac017ee7ed783 100644
--- a/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java
+++ b/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java
@@ -524,7 +524,7 @@ final class Win32ShellFolder2 extends ShellFolder {
// NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
private static native int compareIDs(long pParentIShellFolder, long pidl1, long pidl2);
- private Boolean cachedIsFileSystem;
+ private volatile Boolean cachedIsFileSystem;
/**
* @return Whether this is a file system shell folder
@@ -693,29 +693,32 @@ final class Win32ShellFolder2 extends ShellFolder {
ArrayList list = new ArrayList();
long pEnumObjects = getEnumObjects(includeHiddenFiles);
if (pEnumObjects != 0) {
- long childPIDL;
- int testedAttrs = ATTRIB_FILESYSTEM | ATTRIB_FILESYSANCESTOR;
- do {
- childPIDL = getNextChild(pEnumObjects);
- boolean releasePIDL = true;
- if (childPIDL != 0 &&
- (getAttributes0(pIShellFolder, childPIDL, testedAttrs) & testedAttrs) != 0) {
- Win32ShellFolder2 childFolder;
- if (Win32ShellFolder2.this.equals(desktop)
- && personal != null
- && pidlsEqual(pIShellFolder, childPIDL, personal.disposer.relativePIDL)) {
- childFolder = personal;
- } else {
- childFolder = new Win32ShellFolder2(Win32ShellFolder2.this, childPIDL);
- releasePIDL = false;
+ try {
+ long childPIDL;
+ int testedAttrs = ATTRIB_FILESYSTEM | ATTRIB_FILESYSANCESTOR;
+ do {
+ childPIDL = getNextChild(pEnumObjects);
+ boolean releasePIDL = true;
+ if (childPIDL != 0 &&
+ (getAttributes0(pIShellFolder, childPIDL, testedAttrs) & testedAttrs) != 0) {
+ Win32ShellFolder2 childFolder;
+ if (Win32ShellFolder2.this.equals(desktop)
+ && personal != null
+ && pidlsEqual(pIShellFolder, childPIDL, personal.disposer.relativePIDL)) {
+ childFolder = personal;
+ } else {
+ childFolder = new Win32ShellFolder2(Win32ShellFolder2.this, childPIDL);
+ releasePIDL = false;
+ }
+ list.add(childFolder);
}
- list.add(childFolder);
- }
- if (releasePIDL) {
- releasePIDL(childPIDL);
- }
- } while (childPIDL != 0 && !Thread.currentThread().isInterrupted());
- releaseEnumObjects(pEnumObjects);
+ if (releasePIDL) {
+ releasePIDL(childPIDL);
+ }
+ } while (childPIDL != 0 && !Thread.currentThread().isInterrupted());
+ } finally {
+ releaseEnumObjects(pEnumObjects);
+ }
}
return Thread.currentThread().isInterrupted()
? new File[0]
@@ -759,7 +762,7 @@ final class Win32ShellFolder2 extends ShellFolder {
}, InterruptedException.class);
}
- private Boolean cachedIsLink;
+ private volatile Boolean cachedIsLink;
/**
* @return Whether this shell folder is a link
diff --git a/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java b/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java
index 97cc532d36937a56de21dc4ccef2d48e7dca1dc9..b7639fa77bbda34c41d72871fdadfd53651974d3 100644
--- a/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java
+++ b/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java
@@ -79,9 +79,12 @@ public class Win32ShellFolderManager2 extends ShellFolderManager {
// Shouldn't happen but watch for it anyway
throw new FileNotFoundException("File " + file.getAbsolutePath() + " not found");
}
- Win32ShellFolder2 folder = createShellFolderFromRelativePIDL(parent, pIDL);
- Win32ShellFolder2.releasePIDL(pIDL);
- return folder;
+
+ try {
+ return createShellFolderFromRelativePIDL(parent, pIDL);
+ } finally {
+ Win32ShellFolder2.releasePIDL(pIDL);
+ }
}
static Win32ShellFolder2 createShellFolderFromRelativePIDL(Win32ShellFolder2 parent, long pIDL)
@@ -269,7 +272,7 @@ public class Win32ShellFolderManager2 extends ShellFolderManager {
Arrays.sort(secondLevelFolders);
for (File secondLevelFolder : secondLevelFolders) {
Win32ShellFolder2 folder = (Win32ShellFolder2) secondLevelFolder;
- if (!folder.isFileSystem() || folder.isDirectory()) {
+ if (!folder.isFileSystem() || (folder.isDirectory() && !folder.isLink())) {
folders.add(folder);
// Add third level for "My Computer"
if (folder.equals(drives)) {
diff --git a/src/windows/classes/sun/awt/windows/WComponentPeer.java b/src/windows/classes/sun/awt/windows/WComponentPeer.java
index 4b73c2e4fe7850d503920ed2f1b413dc6643ddea..e5c51d7b77f384bd64dea5eb8813e219ee3055a2 100644
--- a/src/windows/classes/sun/awt/windows/WComponentPeer.java
+++ b/src/windows/classes/sun/awt/windows/WComponentPeer.java
@@ -550,8 +550,34 @@ public abstract class WComponentPeer extends WObjectPeer
final static Font defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12);
public Graphics getGraphics() {
+ if (isDisposed()) {
+ return null;
+ }
+
+ Component target = (Component)getTarget();
+ Window window = SunToolkit.getContainingWindow(target);
+ if (window != null && !window.isOpaque()) {
+ // Non-opaque windows do not support heavyweight children.
+ // Redirect all painting to the Window's Graphics instead.
+ // The caller is responsible for calling the
+ // WindowPeer.updateWindow() after painting has finished.
+ int x = 0, y = 0;
+ for (Component c = target; c != window; c = c.getParent()) {
+ x += c.getX();
+ y += c.getY();
+ }
+
+ Graphics g =
+ ((WWindowPeer)window.getPeer()).getTranslucentGraphics();
+
+ g.translate(x, y);
+ g.clipRect(0, 0, target.getWidth(), target.getHeight());
+
+ return g;
+ }
+
SurfaceData surfaceData = this.surfaceData;
- if (!isDisposed() && surfaceData != null) {
+ if (surfaceData != null) {
/* Fix for bug 4746122. Color and Font shouldn't be null */
Color bgColor = background;
if (bgColor == null) {
diff --git a/src/windows/classes/sun/awt/windows/WWindowPeer.java b/src/windows/classes/sun/awt/windows/WWindowPeer.java
index 009593ac3cf3bc12171d98ea52d91c053d3c7924..6189738da206ddf56b5c95ce90c8f848b087c560 100644
--- a/src/windows/classes/sun/awt/windows/WWindowPeer.java
+++ b/src/windows/classes/sun/awt/windows/WWindowPeer.java
@@ -510,6 +510,9 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer,
private native int getScreenImOn();
+ // Used in Win32GraphicsDevice.
+ public final native void setFullScreenExclusiveModeState(boolean state);
+
/*
* ----END DISPLAY CHANGE SUPPORT----
*/
@@ -575,11 +578,17 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer,
}
}
+ public final Graphics getTranslucentGraphics() {
+ synchronized (getStateLock()) {
+ return isOpaque ? null : painter.getBackBuffer(false).getGraphics();
+ }
+ }
+
@Override
public Graphics getGraphics() {
synchronized (getStateLock()) {
if (!isOpaque) {
- return painter.getBackBuffer(false).getGraphics();
+ return getTranslucentGraphics();
}
}
return super.getGraphics();
diff --git a/src/windows/classes/sun/java2d/windows/GDIWindowSurfaceData.java b/src/windows/classes/sun/java2d/windows/GDIWindowSurfaceData.java
index e246a7fc63d13a1ee819bb97164b61c64d59e806..c55b54d9f6b1e0fb54783f8b21bfad31a4a42d97 100644
--- a/src/windows/classes/sun/java2d/windows/GDIWindowSurfaceData.java
+++ b/src/windows/classes/sun/java2d/windows/GDIWindowSurfaceData.java
@@ -210,7 +210,10 @@ public class GDIWindowSurfaceData extends SurfaceData {
// if a GlyphVector overrides the AA setting.
// We use getRenderLoops() rather than setting solidloops
// directly so that we get the appropriate loops in XOR mode.
- sg2d.loops = getRenderLoops(sg2d);
+ if (sg2d.loops == null) {
+ // assert(some pipe will always be a LoopBasedPipe)
+ sg2d.loops = getRenderLoops(sg2d);
+ }
} else {
super.validatePipe(sg2d);
}
diff --git a/src/windows/native/sun/windows/awt_PrintControl.cpp b/src/windows/native/sun/windows/awt_PrintControl.cpp
index cc562ec0056999411a4b4837c0a09515251b653c..b68bb5f3bdd7328a7b27fff3eb04ef996e38de87 100644
--- a/src/windows/native/sun/windows/awt_PrintControl.cpp
+++ b/src/windows/native/sun/windows/awt_PrintControl.cpp
@@ -687,7 +687,7 @@ BOOL AwtPrintControl::InitPrintDialog(JNIEnv *env,
// Now, set-up the struct for the real calls to ::PrintDlg and ::CreateDC
pd.hwndOwner = hwndOwner;
- pd.Flags = PD_ENABLEPRINTHOOK | PD_RETURNDC;
+ pd.Flags = PD_ENABLEPRINTHOOK | PD_RETURNDC | PD_USEDEVMODECOPIESANDCOLLATE;
pd.lpfnPrintHook = (LPPRINTHOOKPROC)PrintDlgHook;
if (env->CallBooleanMethod(printCtrl, AwtPrintControl::getCollateID)) {
diff --git a/src/windows/native/sun/windows/awt_TrayIcon.cpp b/src/windows/native/sun/windows/awt_TrayIcon.cpp
index 9165314bbc567ac4e8bbe98ad0e71c14c494d650..6b4f8b6bcfca6e0f071f9947ad6a20b9ce6ca3ca 100644
--- a/src/windows/native/sun/windows/awt_TrayIcon.cpp
+++ b/src/windows/native/sun/windows/awt_TrayIcon.cpp
@@ -59,7 +59,7 @@ struct DisplayMessageStruct {
};
typedef struct tagBitmapheader {
- BITMAPINFOHEADER bmiHeader;
+ BITMAPV5HEADER bmiHeader;
DWORD dwMasks[256];
} Bitmapheader, *LPBITMAPHEADER;
@@ -638,12 +638,12 @@ void AwtTrayIcon::UnlinkObjects()
HBITMAP AwtTrayIcon::CreateBMP(HWND hW,int* imageData,int nSS, int nW, int nH)
{
- Bitmapheader bmhHeader;
+ Bitmapheader bmhHeader = {0};
HDC hDC;
char *ptrImageData;
HBITMAP hbmpBitmap;
HBITMAP hBitmap;
- int nNumChannels = 3;
+ int nNumChannels = 4;
if (!hW) {
hW = ::GetDesktopWindow();
@@ -653,14 +653,20 @@ HBITMAP AwtTrayIcon::CreateBMP(HWND hW,int* imageData,int nSS, int nW, int nH)
return NULL;
}
- memset(&bmhHeader, 0, sizeof(Bitmapheader));
- bmhHeader.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bmhHeader.bmiHeader.biWidth = nW;
- bmhHeader.bmiHeader.biHeight = -nH;
- bmhHeader.bmiHeader.biPlanes = 1;
+ bmhHeader.bmiHeader.bV5Size = sizeof(BITMAPV5HEADER);
+ bmhHeader.bmiHeader.bV5Width = nW;
+ bmhHeader.bmiHeader.bV5Height = -nH;
+ bmhHeader.bmiHeader.bV5Planes = 1;
- bmhHeader.bmiHeader.biBitCount = 24;
- bmhHeader.bmiHeader.biCompression = BI_RGB;
+ bmhHeader.bmiHeader.bV5BitCount = 32;
+ bmhHeader.bmiHeader.bV5Compression = BI_BITFIELDS;
+
+ // The following mask specification specifies a supported 32 BPP
+ // alpha format for Windows XP.
+ bmhHeader.bmiHeader.bV5RedMask = 0x00FF0000;
+ bmhHeader.bmiHeader.bV5GreenMask = 0x0000FF00;
+ bmhHeader.bmiHeader.bV5BlueMask = 0x000000FF;
+ bmhHeader.bmiHeader.bV5AlphaMask = 0xFF000000;
hbmpBitmap = ::CreateDIBSection(hDC, (BITMAPINFO*)&(bmhHeader),
DIB_RGB_COLORS,
@@ -674,6 +680,7 @@ HBITMAP AwtTrayIcon::CreateBMP(HWND hW,int* imageData,int nSS, int nW, int nH)
}
for (int nOutern = 0; nOutern < nH; nOutern++) {
for (int nInner = 0; nInner < nSS; nInner++) {
+ dstPtr[3] = (*srcPtr >> 0x18) & 0xFF;
dstPtr[2] = (*srcPtr >> 0x10) & 0xFF;
dstPtr[1] = (*srcPtr >> 0x08) & 0xFF;
dstPtr[0] = *srcPtr & 0xFF;
diff --git a/src/windows/native/sun/windows/awt_Window.cpp b/src/windows/native/sun/windows/awt_Window.cpp
index 4c902c3fb47b97973d0336c8ac3b739fbc4b3c19..8bb5c90021939c326d2d2a5966477fda3be60d37 100644
--- a/src/windows/native/sun/windows/awt_Window.cpp
+++ b/src/windows/native/sun/windows/awt_Window.cpp
@@ -143,6 +143,11 @@ struct RepositionSecurityWarningStruct {
jobject window;
};
+struct SetFullScreenExclusiveModeStateStruct {
+ jobject window;
+ jboolean isFSEMState;
+};
+
/************************************************************************
* AwtWindow fields
@@ -915,7 +920,9 @@ void AwtWindow::UpdateSecurityWarningVisibility()
bool show = false;
- if (IsVisible() && currentWmSizeState != SIZE_MINIMIZED) {
+ if (IsVisible() && currentWmSizeState != SIZE_MINIMIZED &&
+ !isFullScreenExclusiveMode())
+ {
if (AwtComponent::GetFocusedWindow() == GetHWnd()) {
show = true;
}
@@ -2954,6 +2961,25 @@ void AwtWindow::_UpdateWindow(void* param)
delete uws;
}
+void AwtWindow::_SetFullScreenExclusiveModeState(void *param)
+{
+ JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
+
+ SetFullScreenExclusiveModeStateStruct * data =
+ (SetFullScreenExclusiveModeStateStruct*)param;
+ jobject self = data->window;
+ jboolean state = data->isFSEMState;
+
+ PDATA pData;
+ JNI_CHECK_PEER_GOTO(self, ret);
+ AwtWindow *window = (AwtWindow *)pData;
+
+ window->setFullScreenExclusiveModeState(state != 0);
+
+ ret:
+ env->DeleteGlobalRef(self);
+ delete data;
+}
extern "C" {
@@ -3333,6 +3359,29 @@ Java_sun_awt_windows_WWindowPeer_getScreenImOn(JNIEnv *env, jobject self)
CATCH_BAD_ALLOC_RET(-1);
}
+/*
+ * Class: sun_awt_windows_WWindowPeer
+ * Method: setFullScreenExclusiveModeState
+ * Signature: (Z)V
+ */
+JNIEXPORT void JNICALL
+Java_sun_awt_windows_WWindowPeer_setFullScreenExclusiveModeState(JNIEnv *env,
+ jobject self, jboolean state)
+{
+ TRY;
+
+ SetFullScreenExclusiveModeStateStruct *data =
+ new SetFullScreenExclusiveModeStateStruct;
+ data->window = env->NewGlobalRef(self);
+ data->isFSEMState = state;
+
+ AwtToolkit::GetInstance().SyncCall(
+ AwtWindow::_SetFullScreenExclusiveModeState, data);
+ // global ref and data are deleted in the invoked method
+
+ CATCH_BAD_ALLOC;
+}
+
/*
* Class: sun_awt_windows_WWindowPeer
* Method: modalDisable
diff --git a/src/windows/native/sun/windows/awt_Window.h b/src/windows/native/sun/windows/awt_Window.h
index 1d238b44dac1df0390039fd167f8f1479c1ac215..001062835e3a733ea369580f01eb2e503e7c017a 100644
--- a/src/windows/native/sun/windows/awt_Window.h
+++ b/src/windows/native/sun/windows/awt_Window.h
@@ -229,6 +229,7 @@ public:
static void _SetOpaque(void* param);
static void _UpdateWindow(void* param);
static void _RepositionSecurityWarning(void* param);
+ static void _SetFullScreenExclusiveModeState(void* param);
inline static BOOL IsResizing() {
return sm_resizing;
@@ -331,6 +332,16 @@ private:
static void SetLayered(HWND window, bool layered);
static bool IsLayered(HWND window);
+ BOOL fullScreenExclusiveModeState;
+ inline void setFullScreenExclusiveModeState(BOOL isEntered) {
+ fullScreenExclusiveModeState = isEntered;
+ UpdateSecurityWarningVisibility();
+ }
+ inline BOOL isFullScreenExclusiveMode() {
+ return fullScreenExclusiveModeState;
+ }
+
+
public:
void UpdateSecurityWarningVisibility();
static bool IsWarningWindow(HWND hWnd);
diff --git a/test/java/awt/Container/ValidateRoot/InvalidateMustRespectValidateRoots.java b/test/java/awt/Container/ValidateRoot/InvalidateMustRespectValidateRoots.java
new file mode 100644
index 0000000000000000000000000000000000000000..7bf34012dd9155b0257c5eeda5c865cb5292a8da
--- /dev/null
+++ b/test/java/awt/Container/ValidateRoot/InvalidateMustRespectValidateRoots.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ @test
+ @bug 6852592
+ @summary invalidate() must stop when it encounters a validate root
+ @author anthony.petrov@sun.com
+ @run main InvalidateMustRespectValidateRoots
+*/
+
+import javax.swing.*;
+import java.awt.event.*;
+
+public class InvalidateMustRespectValidateRoots {
+ private static volatile JRootPane rootPane;
+
+ public static void main(String args[]) throws Exception {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ // The JRootPane is a validate root. We'll check if
+ // invalidate() stops on the root pane, or goes further
+ // up to the frame.
+ JFrame frame = new JFrame();
+ final JButton button = new JButton();
+
+ frame.add(button);
+
+ // To enable running the test manually: use the Ctrl-Shift-F1
+ // to print the component hierarchy to the console
+ button.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent ev) {
+ if (button.isValid()) {
+ button.invalidate();
+ } else {
+ button.revalidate();
+ }
+ }
+ });
+
+ rootPane = frame.getRootPane();
+
+ // Now the component hierarchy looks like:
+ // frame
+ // --> rootPane
+ // --> layered pane
+ // --> content pane
+ // --> button
+
+ // Make all components valid first via showing the frame
+ // We have to make the frame visible. Otherwise revalidate() is
+ // useless (see RepaintManager.addInvalidComponent()).
+ frame.pack(); // To enable running this test manually
+ frame.setVisible(true);
+
+ if (!frame.isValid()) {
+ throw new RuntimeException(
+ "setVisible(true) failed to validate the frame");
+ }
+
+ // Now invalidate the button
+ button.invalidate();
+
+ // Check if the 'valid' status is what we expect it to be
+ if (rootPane.isValid()) {
+ throw new RuntimeException(
+ "invalidate() failed to invalidate the root pane");
+ }
+
+ if (!frame.isValid()) {
+ throw new RuntimeException(
+ "invalidate() invalidated the frame");
+ }
+
+ // Now validate the hierarchy again
+ button.revalidate();
+
+ // Now let the validation happen on the EDT
+ }
+ });
+
+ Thread.sleep(1000);
+
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ // Check if the root pane finally became valid
+ if (!rootPane.isValid()) {
+ throw new RuntimeException(
+ "revalidate() failed to validate the hierarchy");
+ }
+ }
+ });
+ }
+}
diff --git a/test/java/awt/event/InvocationEvent/InvocationEventTest.java b/test/java/awt/event/InvocationEvent/InvocationEventTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..5fb83d10acf2aeabed6609c9b0d0c980af7db66b
--- /dev/null
+++ b/test/java/awt/event/InvocationEvent/InvocationEventTest.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ @test
+ @bug 6852111
+ @summary Unhandled 'spurious wakeup' in java.awt.EventQueue.invokeAndWait()
+ @author dmitry.cherepanov@sun.com: area=awt.event
+ @run main InvocationEventTest
+*/
+
+/**
+ * InvocationEventTest.java
+ *
+ * summary: Tests new isDispatched method of the InvocationEvent class
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+
+public class InvocationEventTest
+{
+ public static void main(String []s) throws Exception
+ {
+ Toolkit tk = Toolkit.getDefaultToolkit();
+ Runnable runnable = new Runnable() {
+ public void run() {
+ }
+ };
+ Object lock = new Object();
+ InvocationEvent event = new InvocationEvent(tk, runnable, lock, true);
+
+ if (event.isDispatched()) {
+ throw new RuntimeException(" Initially, the event shouldn't be dispatched ");
+ }
+
+ synchronized(lock) {
+ tk.getSystemEventQueue().postEvent(event);
+ while(!event.isDispatched()) {
+ lock.wait();
+ }
+ }
+
+ if(!event.isDispatched()) {
+ throw new RuntimeException(" Finally, the event should be dispatched ");
+ }
+ }
+}
diff --git a/test/java/awt/font/NumericShaper/EqualsTest.java b/test/java/awt/font/NumericShaper/EqualsTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..b71bacf42fe5d1953d3b5dbcebae96969145a02d
--- /dev/null
+++ b/test/java/awt/font/NumericShaper/EqualsTest.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6842557
+ * @summary confirm that an instance which is created with new Enum ranges is
+ * equivalent to another instance which is created with equivalent traditional
+ * ranges or the same Enum ranges.
+ */
+
+import java.awt.font.NumericShaper;
+import java.util.EnumSet;
+import static java.awt.font.NumericShaper.*;
+
+public class EqualsTest {
+ public static void main(String[] args) {
+ NumericShaper ns1 = getContextualShaper(ARABIC | TAMIL, TAMIL);
+ NumericShaper ns2 = getContextualShaper(
+ EnumSet.of(Range.ARABIC, Range.TAMIL),
+ Range.TAMIL);
+ NumericShaper ns3 = getContextualShaper(
+ EnumSet.of(Range.ARABIC, Range.TAMIL),
+ Range.TAMIL);
+ NumericShaper ns4 = getContextualShaper(
+ EnumSet.of(Range.ARABIC, Range.TAMIL),
+ Range.ARABIC);
+
+ if (!ns1.equals(ns2)) {
+ throw new RuntimeException("ns1 != ns2: ns1=" + ns1 + ", ns2=" + ns2);
+ }
+ if (!ns2.equals(ns1)) {
+ throw new RuntimeException("ns2 != ns1: ns1=" + ns1 + ", ns2=" + ns2);
+ }
+ if (!ns2.equals(ns3)) {
+ throw new RuntimeException("ns2 != ns3: ns2=" + ns2 + ", ns3=" + ns3);
+ }
+ if (ns1.equals(ns4)) {
+ throw new RuntimeException("ns1 == ns4: ns1=" + ns1 + ", ns4=" + ns4);
+ }
+ if (ns2.equals(ns4)) {
+ throw new RuntimeException("ns2 == ns4: ns2=" + ns2 + ", ns4=" + ns4);
+ }
+ }
+}
diff --git a/test/java/awt/font/NumericShaper/MTTest.java b/test/java/awt/font/NumericShaper/MTTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..e2598c3c36d7f89a58a9a1886521d695728bd573
--- /dev/null
+++ b/test/java/awt/font/NumericShaper/MTTest.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6843181
+ * @summary Confirm that NumericShaper is thread-safe.
+ * @run main/timeout=300/othervm MTTest
+ */
+
+import java.awt.font.NumericShaper;
+import java.util.Arrays;
+import java.util.EnumSet;
+import static java.awt.font.NumericShaper.*;
+
+public class MTTest {
+ static volatile boolean runrun = true;
+ static volatile boolean err = false;
+
+ final static String text = "-123 (English) 456.00 (Arabic) \u0641\u0642\u0643 -789 (Thai) \u0e01\u0e33 01.23";
+ static char[] t1, t2;
+ static NumericShaper ns1, ns2, ns3, ns4;
+
+ public static void main(String[] args) {
+ System.out.println(" original: " + text);
+ ns1 = getContextualShaper(EnumSet.of(Range.ARABIC), Range.ARABIC);
+ t1 = text.toCharArray();
+ ns1.shape(t1, 0, t1.length);
+ System.out.println("expected t1: " + String.valueOf(t1));
+
+ ns2 = getContextualShaper(EnumSet.of(Range.THAI), Range.THAI);
+ t2 = text.toCharArray();
+ ns2.shape(t2, 0, t2.length);
+ System.out.println("expected t2: " + String.valueOf(t2));
+
+ ns3 = getContextualShaper(ARABIC, ARABIC);
+ ns4 = getContextualShaper(THAI, THAI);
+
+ Thread th1 = new Thread(new Work(ns1, t1));
+ Thread th2 = new Thread(new Work(ns2, t2));
+ Thread th3 = new Thread(new Work(ns1, t1));
+ Thread th4 = new Thread(new Work(ns2, t2));
+ Thread th5 = new Thread(new Work(ns3, t1));
+ Thread th6 = new Thread(new Work(ns4, t2));
+ Thread th7 = new Thread(new Work(ns3, t1));
+ Thread th8 = new Thread(new Work(ns4, t2));
+
+ th1.start();
+ th2.start();
+ th3.start();
+ th4.start();
+ th5.start();
+ th6.start();
+ th7.start();
+ th8.start();
+
+ try {
+ for (int i = 0; runrun && i < 180; i++) {
+ Thread.sleep(1000); // 1 seconds
+ }
+ runrun = false;
+ th1.join();
+ th2.join();
+ th3.join();
+ th4.join();
+ th5.join();
+ th6.join();
+ th7.join();
+ th8.join();
+ }
+ catch (InterruptedException e) {
+ }
+
+ if (err) {
+ throw new RuntimeException("Thread-safe test failed.");
+ }
+ }
+
+ private static class Work implements Runnable {
+ NumericShaper ns;
+ char[] expectedText;
+
+ Work(NumericShaper ns, char[] expectedText) {
+ this.ns = ns;
+ this.expectedText = expectedText;
+
+ }
+
+ public void run() {
+ int count = 0;
+ while (runrun) {
+ char[] t = text.toCharArray();
+ try {
+ count++;
+ ns.shape(t, 0, t.length);
+ } catch (Exception e) {
+ System.err.println("Error: Unexpected exception: " + e);
+ runrun = false;
+ err = true;
+ return;
+ }
+ if (!Arrays.equals(t, expectedText)) {
+ System.err.println("Error: shape() returned unexpected value: ");
+ System.err.println("count = " + count);
+ System.err.println(" expected: " + String.valueOf(expectedText));
+ System.err.println(" got: " + String.valueOf(t));
+ runrun = false;
+ err = true;
+ return;
+ }
+ }
+ }
+ }
+}
diff --git a/test/java/awt/font/NumericShaper/ShapingTest.java b/test/java/awt/font/NumericShaper/ShapingTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..047e67f12d344f1264b5f9ab0b854b632506077f
--- /dev/null
+++ b/test/java/awt/font/NumericShaper/ShapingTest.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6842557
+ * @summary confirm that shaping works as expected. (Mainly for new characters which were added in Unicode 5)
+ * used where appropriate.
+ */
+
+import java.awt.font.NumericShaper;
+import java.util.EnumSet;
+import static java.awt.font.NumericShaper.*;
+
+public class ShapingTest {
+ public static void main(String[] args) {
+ NumericShaper ns_old = getContextualShaper(ARABIC | TAMIL | ETHIOPIC,
+ EUROPEAN);
+ NumericShaper ns_new = getContextualShaper(EnumSet.of(
+ Range.ARABIC, Range.TAMIL, Range.ETHIOPIC),
+ Range.EUROPEAN);
+
+ boolean err = false;
+
+ String[][] data = {
+ // Arabic "October 10"
+ {"\u0623\u0643\u062a\u0648\u0628\u0631 10",
+ "\u0623\u0643\u062a\u0648\u0628\u0631 \u0661\u0660"},
+
+ // Tamil "Year 2009"
+ {"\u0b86\u0ba3\u0bcd\u0b9f\u0bc1 2009",
+ "\u0b86\u0ba3\u0bcd\u0b9f\u0bc1 \u0be8\u0be6\u0be6\u0bef"},
+ // "\u0be800\u0bef is returned by pre-JDK7 because Tamil zero was not
+ // included in Unicode 4.0.0.
+
+ // Ethiopic "Syllable 2009"
+ {"\u1200 2009",
+ "\u1200 \u136a00\u1371"},
+ // Ethiopic zero doesn't exist even in Unicode 5.1.0.
+ };
+
+ for (int i = 0; i < data.length; i++) {
+ String expected = data[i][1];
+
+ char[] text = data[i][0].toCharArray();
+ ns_old.shape(text, 0, text.length);
+ String got = new String(text);
+
+ if (!expected.equals(got)) {
+ err = true;
+ System.err.println("Error with traditional range.");
+ System.err.println(" text = " + data[i][0]);
+ System.err.println(" got = " + got);
+ System.err.println(" expected = " + expected);
+ } else {
+ System.err.println("OK with traditional range.");
+ System.err.println(" text = " + data[i][0]);
+ System.err.println(" got = " + got);
+ System.err.println(" expected = " + expected);
+ }
+
+ text = data[i][0].toCharArray();
+ ns_new.shape(text, 0, text.length);
+ got = new String(text);
+
+ if (!expected.equals(got)) {
+ err = true;
+ System.err.println("Error with new Enum range.");
+ System.err.println(" text = " + data[i][0]);
+ System.err.println(" got = " + got);
+ System.err.println(" expected = " + expected);
+ } else {
+ System.err.println("OK with new Enum range.");
+ System.err.println(" text = " + data[i][0]);
+ System.err.println(" got = " + got);
+ System.err.println(" expected = " + expected);
+ }
+ }
+
+ if (err) {
+ throw new RuntimeException("shape() returned unexpected value.");
+ }
+ }
+
+}
diff --git a/test/javax/swing/JFileChooser/6550546/bug6550546.java b/test/javax/swing/JFileChooser/6550546/bug6550546.java
new file mode 100644
index 0000000000000000000000000000000000000000..84277edf54aac05434a3715a0276a262341fea41
--- /dev/null
+++ b/test/javax/swing/JFileChooser/6550546/bug6550546.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ @bug 6550546
+ @summary Win LAF: JFileChooser -> Look in Drop down should not display any shortcuts created on desktop
+ @author Pavel Porvatov
+ @run main bug6550546
+*/
+
+import sun.awt.OSInfo;
+import sun.awt.shell.ShellFolder;
+
+import javax.swing.*;
+import java.io.File;
+
+public class bug6550546 {
+ public static void main(String[] args) throws Exception {
+ if (OSInfo.getOSType() != OSInfo.OSType.WINDOWS) {
+ System.out.println("The test is suitable only for Windows, skipped.");
+
+ return;
+ }
+
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ File[] files = (File[]) ShellFolder.get("fileChooserComboBoxFolders");
+
+ for (File file : files) {
+ if (file instanceof ShellFolder && ((ShellFolder) file).isLink()) {
+ throw new RuntimeException("Link shouldn't be in FileChooser combobox, " + file.getPath());
+ }
+ }
+ }
+ });
+ }
+}
diff --git a/test/javax/swing/JFileChooser/6741890/bug6741890.java b/test/javax/swing/JFileChooser/6741890/bug6741890.java
new file mode 100644
index 0000000000000000000000000000000000000000..1e670e704044db0a7fe9ba5030aea8e1c7129309
--- /dev/null
+++ b/test/javax/swing/JFileChooser/6741890/bug6741890.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ @bug 6741890
+ @summary Deadlock in Win32ShellFolderManager2
+ @author Pavel Porvatov
+ @run main bug6741890
+*/
+
+import sun.awt.shell.ShellFolder;
+import sun.awt.OSInfo;
+
+import java.io.File;
+import java.lang.reflect.Field;
+import java.util.concurrent.Callable;
+
+public class bug6741890 {
+ /**
+ * This mux is used to prevent NPE in the isLink and isFileSystem methods
+ */
+ private static final Object mux = new Object();
+
+ private static final int COUNT = 100000;
+
+ public static void main(String[] args) throws Exception {
+ if (OSInfo.getOSType() != OSInfo.OSType.WINDOWS) {
+ System.out.println("The test is applicable only for Windows. Skipped.");
+
+ return;
+ }
+
+ String tmpDir = System.getProperty("java.io.tmpdir");
+
+ if (tmpDir.length() == 0) { //'java.io.tmpdir' isn't guaranteed to be defined
+ tmpDir = System.getProperty("user.home");
+ }
+
+ final ShellFolder tmpFile = ShellFolder.getShellFolder(new File(tmpDir));
+
+ System.out.println("Temp directory: " + tmpDir);
+
+ System.out.println("Stress test was run");
+
+ Thread thread = new Thread() {
+ public void run() {
+ while (!isInterrupted()) {
+ ShellFolder.invoke(new Callable() {
+ public Void call() throws Exception {
+ synchronized (mux) {
+ tmpFile.isFileSystem();
+ tmpFile.isLink();
+ }
+
+ return null;
+ }
+ });
+ }
+ }
+ };
+
+ thread.start();
+
+ for (int i = 0; i < COUNT; i++) {
+ synchronized (mux) {
+ clearField(tmpFile, "cachedIsLink");
+ clearField(tmpFile, "cachedIsFileSystem");
+ }
+
+ tmpFile.isFileSystem();
+ tmpFile.isLink();
+ }
+
+ thread.interrupt();
+ thread.join();
+
+ System.out.println("Test passed successfully");
+ }
+
+ private static void clearField(Object o, String fieldName) throws Exception {
+ Field field = o.getClass().getDeclaredField(fieldName);
+
+ field.setAccessible(true);
+
+ field.set(o, null);
+ }
+}
diff --git a/test/javax/swing/JFileChooser/6868611/bug6868611.java b/test/javax/swing/JFileChooser/6868611/bug6868611.java
new file mode 100644
index 0000000000000000000000000000000000000000..fa555c7659b262e0d2611400779b34c049ef43ef
--- /dev/null
+++ b/test/javax/swing/JFileChooser/6868611/bug6868611.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ @bug 6868611
+ @summary FileSystemView throws NullPointerException
+ @author Pavel Porvatov
+ @run main bug6868611
+*/
+
+import javax.swing.*;
+import javax.swing.filechooser.FileSystemView;
+import java.io.File;
+
+public class bug6868611 {
+ private static final int COUNT = 1000;
+
+ public static void main(String[] args) throws Exception {
+ String tempDirProp = System.getProperty("java.io.tmpdir");
+
+ final String tempDir = tempDirProp == null || !new File(tempDirProp).isDirectory() ?
+ System.getProperty("user.home") : tempDirProp;
+
+ System.out.println("Temp directory: " + tempDir);
+
+ // Create 1000 files
+ for (int i = 0; i < 1000; i++) {
+ new File(tempDir, "temp" + i).createNewFile();
+ }
+
+ // Init default FileSystemView
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ FileSystemView.getFileSystemView().getFiles(new File(tempDir), false);
+ }
+ });
+
+ for (int i = 0; i < COUNT; i++) {
+ Thread thread = new MyThread(tempDir);
+
+ thread.start();
+
+ Thread.sleep((long) (Math.random() * 100));
+
+ thread.interrupt();
+
+ if (i % 100 == 0) {
+ System.out.print("*");
+ }
+ }
+
+ System.out.println();
+
+ // Remove 1000 files
+ for (int i = 0; i < 1000; i++) {
+ new File(tempDir, "temp" + i).delete();
+ }
+ }
+
+ private static class MyThread extends Thread {
+ private final String dir;
+
+ private MyThread(String dir) {
+ this.dir = dir;
+ }
+
+ public void run() {
+ FileSystemView fileSystemView = FileSystemView.getFileSystemView();
+
+ fileSystemView.getFiles(new File(dir), false);
+ }
+ }
+}
diff --git a/test/tools/launcher/libraryCaller.java b/test/javax/swing/UIDefaults/6795356/SwingLazyValueTest.java
similarity index 64%
rename from test/tools/launcher/libraryCaller.java
rename to test/javax/swing/UIDefaults/6795356/SwingLazyValueTest.java
index f938a2fce233ce4dfdad84513cb1d0d0849d1437..4211e53cd8ef6d022d4826a99a1226607082a19a 100644
--- a/test/tools/launcher/libraryCaller.java
+++ b/test/javax/swing/UIDefaults/6795356/SwingLazyValueTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009 Sun Microsystems, Inc. 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
@@ -21,26 +21,24 @@
* have any questions.
*/
-
/*
- *
- *
- * Used by SolarisRunpath.sh to help test if the launcher fully
- * respects Solaris LD_LIBRARY_PATH semantics. The ./lib directory is
- * structured so that the results of the dynamically linked number
- * method varies depending on the value the data model dependent
- * LD_LIBRARY_PATH variable.
+ * @test
+ * @bug 6795356
+ * @summary Checks that SwingLazyValue class correclty works
+ * @author Alexander Potochkin
+ * @run main SwingLazyValueTest
*/
+import sun.swing.SwingLazyValue;
+import javax.swing.*;
-class libraryCaller {
- static {
- System.loadLibrary("library");
- }
- static native int number();
+public class SwingLazyValueTest {
- public static void main(String argv[]) {
- System.out.println(number());
+ public static void main(String[] args) throws Exception {
+ if(new SwingLazyValue("javax.swing.JTable$DoubleRenderer").
+ createValue(null) == null) {
+ throw new RuntimeException("SwingLazyValue doesn't work");
+ }
}
}
diff --git a/test/tools/launcher/libraryCaller.c b/test/javax/swing/UIDefaults/6795356/TableTest.java
similarity index 54%
rename from test/tools/launcher/libraryCaller.c
rename to test/javax/swing/UIDefaults/6795356/TableTest.java
index e77f402b799f86e02d2b65146f4c7f04a4e9c6a8..6002f816979a7c72cf566a03b4c214b52a164735 100644
--- a/test/tools/launcher/libraryCaller.c
+++ b/test/javax/swing/UIDefaults/6795356/TableTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009 Sun Microsystems, Inc. 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
@@ -22,35 +22,31 @@
*/
/*
- *
- *
- * Indictly used by SolarisRunpath.sh; this file is used to generate
- * the shared objects:
- *
- * ./lib/sparc/lib32/liblibrary.so
- * ./lib/sparc/lib32/lib32/liblibrary.so
- *
- * ./lib/sparc/lib64/liblibrary.so
- * ./lib/sparc/lib64/lib64/liblibrary.so
- *
- * ./lib/i386/lib32/liblibrary.so
- * ./lib/i386/lib32/lib32/liblibrary.so
- *
- * The function defined below returns either 0 or the size of an
- * integer in the data model used to compile the file (32 for ILP; 64
- * for LP). The libraries in ./lib/$ARCH/lib$DM return 0; those in
- * ./lib/$ARCH/lib$DM/lib$DM return 32 or 64.
+ * @test
+ * @bug 6795356
+ * @summary Checks that SwingLazyValue class correclty works
+ * @author Alexander Potochkin
+ * @run main/othervm TableTest
*/
+import sun.applet.AppletSecurity;
+
+import javax.swing.*;
+import javax.swing.table.TableCellEditor;
+import java.awt.*;
-#include
-#include "libraryCaller.h"
+public class TableTest {
-#ifndef RETURN_VALUE
-#define RETURN_VALUE 0
-#endif
+ public static void main(String[] args) throws Exception {
-JNIEXPORT jint JNICALL Java_libraryCaller_number
-(JNIEnv *je, jclass jc) {
- return RETURN_VALUE;
+ KeyboardFocusManager.getCurrentKeyboardFocusManager();
+ System.setSecurityManager(new AppletSecurity());
+
+ JTable table = new JTable();
+ TableCellEditor de = table.getDefaultEditor(Double.class);
+ if (de == null) {
+ throw new RuntimeException("Table default editor is null");
+ }
+ }
}
+
diff --git a/test/javax/swing/UIDefaults/6795356/bug6795356.java b/test/javax/swing/UIDefaults/6795356/bug6795356.java
new file mode 100644
index 0000000000000000000000000000000000000000..89e33f1cf82c5f5456b8f28b322363d2970f03f4
--- /dev/null
+++ b/test/javax/swing/UIDefaults/6795356/bug6795356.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6795356
+ * @summary Leak caused by javax.swing.UIDefaults.ProxyLazyValue.acc
+ * @author Alexander Potochkin
+ * @run main bug6795356
+ */
+
+import java.lang.ref.WeakReference;
+import java.security.ProtectionDomain;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.AccessControlContext;
+import java.util.LinkedList;
+import java.util.List;
+import javax.swing.*;
+
+public class bug6795356 {
+ volatile static WeakReference weakRef;
+
+ public static void main(String[] args) throws Exception {
+
+ ProtectionDomain domain = new ProtectionDomain(null, null);
+
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+
+ // this initialize ProxyLazyValues
+ UIManager.getLookAndFeel();
+
+ return null;
+ }
+ }, new AccessControlContext(new ProtectionDomain[]{domain}));
+
+ weakRef = new WeakReference(domain);
+ domain = null;
+
+ // Generate OutOfMemory and check the weak ref
+ generateOOME();
+
+ if (weakRef.get() != null) {
+ throw new RuntimeException("Memory leak found!");
+ }
+ System.out.println("Test passed");
+ }
+
+ static void generateOOME() {
+ List bigLeak = new LinkedList();
+ boolean oome = false;
+ System.out.print("Filling the heap");
+ try {
+ for(int i = 0; true ; i++) {
+ // Now, use up all RAM
+ bigLeak.add(new byte[1024 * 1024]);
+ System.out.print(".");
+
+ // Give the GC a change at that weakref
+ if (i % 10 == 0) {
+ System.gc();
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ } catch (OutOfMemoryError e) {
+ bigLeak = null;
+ oome = true;
+ }
+ System.out.println("");
+ if (!oome) {
+ throw new RuntimeException("Problem with test case - never got OOME");
+ }
+ System.out.println("Got OOME");
+ }
+}
diff --git a/test/sun/java2d/pisces/Renderer/TestNPE.java b/test/sun/java2d/pisces/Renderer/TestNPE.java
new file mode 100644
index 0000000000000000000000000000000000000000..440860c9272a52641cfb7c65024846596ad5a955
--- /dev/null
+++ b/test/sun/java2d/pisces/Renderer/TestNPE.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6887494
+ *
+ * @summary Verifies that no NullPointerException is thrown in Pisces Renderer
+ * under certain circumstances.
+ *
+ * @run main TestNPE
+ */
+
+import java.awt.*;
+import java.awt.geom.*;
+import java.awt.image.BufferedImage;
+
+public class TestNPE {
+
+ private static void paint(Graphics g) {
+ Graphics2D g2d = (Graphics2D) g;
+ g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_ON);
+ g2d.setClip(0, 0, 0, 0);
+ g2d.setTransform(
+ new AffineTransform(4.0f, 0.0f, 0.0f, 4.0f, -1248.0f, -744.0f));
+ g2d.draw(new Line2D.Float(131.21428571428572f, 33.0f,
+ 131.21428571428572f, 201.0f));
+ }
+
+ public static void main(String[] args) {
+ BufferedImage im = new BufferedImage(100, 100,
+ BufferedImage.TYPE_INT_ARGB);
+
+ // Trigger exception in main thread.
+ Graphics g = im.getGraphics();
+ paint(g);
+ }
+}
diff --git a/test/sun/security/jgss/spnego/NoSpnegoAsDefMech.java b/test/sun/security/jgss/spnego/NoSpnegoAsDefMech.java
new file mode 100644
index 0000000000000000000000000000000000000000..2f23de385fe1f8f432ddc33f5fbe2540415b6c66
--- /dev/null
+++ b/test/sun/security/jgss/spnego/NoSpnegoAsDefMech.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6770883
+ * @summary Infinite loop if SPNEGO specified as sun.security.jgss.mechanism
+ */
+
+import org.ietf.jgss.*;
+import sun.security.jgss.*;
+
+public class NoSpnegoAsDefMech {
+
+ public static void main(String[] argv) throws Exception {
+ System.setProperty("sun.security.jgss.mechanism", GSSUtil.GSS_SPNEGO_MECH_OID.toString());
+ try {
+ GSSManager.getInstance().createName("service@host", GSSName.NT_HOSTBASED_SERVICE, new Oid("1.3.6.1.5.5.2"));
+ } catch (GSSException e) {
+ // This is OK, for example, krb5.conf is missing or other problems
+ }
+ }
+}
diff --git a/test/sun/security/krb5/auto/Context.java b/test/sun/security/krb5/auto/Context.java
index 140623f83103117ee371be9a3f6904800fcc1f47..3187e99d87e2ff87c883086ab39ca8d8cb93bb43 100644
--- a/test/sun/security/krb5/auto/Context.java
+++ b/test/sun/security/krb5/auto/Context.java
@@ -72,7 +72,7 @@ import com.sun.security.jgss.AuthorizationDataEntry;
public class Context {
private Subject s;
- private GSSContext x;
+ private ExtendedGSSContext x;
private boolean f; // context established?
private String name;
private GSSCredential cred; // see static method delegated().
@@ -147,8 +147,8 @@ public class Context {
@Override
public byte[] run(Context me, byte[] dummy) throws Exception {
GSSManager m = GSSManager.getInstance();
- me.x = m.createContext(
- target.indexOf('@') < 0 ?
+ me.x = (ExtendedGSSContext)m.createContext(
+ target.indexOf('@') < 0 ?
m.createName(target, null) :
m.createName(target, GSSName.NT_HOSTBASED_SERVICE),
mech,
@@ -170,7 +170,7 @@ public class Context {
@Override
public byte[] run(Context me, byte[] dummy) throws Exception {
GSSManager m = GSSManager.getInstance();
- me.x = m.createContext(m.createCredential(
+ me.x = (ExtendedGSSContext)m.createContext(m.createCredential(
null,
GSSCredential.INDEFINITE_LIFETIME,
mech,
@@ -193,7 +193,7 @@ public class Context {
*
* @return the GSSContext object
*/
- public GSSContext x() {
+ public ExtendedGSSContext x() {
return x;
}
@@ -255,6 +255,11 @@ public class Context {
if (x.getSequenceDetState()) {
sb.append("seq det, ");
}
+ if (x instanceof ExtendedGSSContext) {
+ if (((ExtendedGSSContext)x).getDelegPolicyState()) {
+ sb.append("deleg policy, ");
+ }
+ }
System.out.println("Context status of " + name + ": " + sb.toString());
System.out.println(x.getSrcName() + " -> " + x.getTargName());
} catch (Exception e) {
diff --git a/test/sun/security/krb5/auto/KDC.java b/test/sun/security/krb5/auto/KDC.java
index 586d8b23e61d71aad61b70d4a1eb2695ba34baec..169094c779ba8a9421826a5d7db9dc232d31aea4 100644
--- a/test/sun/security/krb5/auto/KDC.java
+++ b/test/sun/security/krb5/auto/KDC.java
@@ -63,6 +63,14 @@ import sun.security.util.DerValue;
* settings after calling a KDC method, call Config.refresh() to
* make sure your changes are reflected in the Config object.
*
+ * System properties recognized:
+ *
+ * test.kdc.save.ccache
+ *
+ * Support policies:
+ *
* Issues and TODOs:
*
* Generates krb5.conf to be used on another machine, currently the kdc is
@@ -151,7 +159,7 @@ public class KDC {
* A standalone KDC server.
*/
public static void main(String[] args) throws Exception {
- KDC kdc = create("RABBIT.HOLE", "kdc.rabbit,hole", 0, false);
+ KDC kdc = create("RABBIT.HOLE", "kdc.rabbit.hole", 0, false);
kdc.addPrincipal("dummy", "bogus".toCharArray());
kdc.addPrincipal("foo", "bar".toCharArray());
kdc.addPrincipalRandKey("krbtgt/RABBIT.HOLE");
@@ -426,14 +434,17 @@ public class KDC {
* @throws sun.security.krb5.KrbException when the principal is not inside
* the database.
*/
- private char[] getPassword(PrincipalName p) throws KrbException {
+ private char[] getPassword(PrincipalName p, boolean server)
+ throws KrbException {
String pn = p.toString();
if (p.getRealmString() == null) {
pn = pn + "@" + getRealm();
}
char[] pass = passwords.get(pn);
if (pass == null) {
- throw new KrbException(Krb5.KDC_ERR_C_PRINCIPAL_UNKNOWN);
+ throw new KrbException(server?
+ Krb5.KDC_ERR_S_PRINCIPAL_UNKNOWN:
+ Krb5.KDC_ERR_C_PRINCIPAL_UNKNOWN);
}
return pass;
}
@@ -457,10 +468,12 @@ public class KDC {
* Returns the key for a given principal of the given encryption type
* @param p the principal
* @param etype the encryption type
+ * @param server looking for a server principal?
* @return the key
* @throws sun.security.krb5.KrbException for unknown/unsupported etype
*/
- private EncryptionKey keyForUser(PrincipalName p, int etype) throws KrbException {
+ private EncryptionKey keyForUser(PrincipalName p, int etype, boolean server)
+ throws KrbException {
try {
// Do not call EncryptionKey.acquireSecretKeys(), otherwise
// the krb5.conf config file would be loaded.
@@ -469,22 +482,71 @@ public class KDC {
Integer kvno = null;
// For service whose password ending with a number, use it as kvno
if (p.toString().indexOf('/') >= 0) {
- char[] pass = getPassword(p);
+ char[] pass = getPassword(p, server);
if (Character.isDigit(pass[pass.length-1])) {
kvno = pass[pass.length-1] - '0';
}
}
return new EncryptionKey((byte[]) stringToKey.invoke(
- null, getPassword(p), getSalt(p), null, etype),
+ null, getPassword(p, server), getSalt(p), null, etype),
etype, kvno);
} catch (InvocationTargetException ex) {
KrbException ke = (KrbException)ex.getCause();
throw ke;
+ } catch (KrbException ke) {
+ throw ke;
} catch (Exception e) {
throw new RuntimeException(e); // should not happen
}
}
+ private Map policies = new HashMap();
+
+ public void setPolicy(String rule, String value) {
+ if (value == null) {
+ policies.remove(rule);
+ } else {
+ policies.put(rule, value);
+ }
+ }
+ /**
+ * If the provided client/server pair matches a rule
+ *
+ * A system property named test.kdc.policy.RULE will be consulted.
+ * If it's unset, returns false. If its value is "", any pair is
+ * matched. Otherwise, it should contains the server name matched.
+ *
+ * TODO: client name is not used currently.
+ *
+ * @param c client name
+ * @param s server name
+ * @param rule rule name
+ * @return if a match is found
+ */
+ private boolean configMatch(String c, String s, String rule) {
+ String policy = policies.get(rule);
+ boolean result = false;
+ if (policy == null) {
+ result = false;
+ } else if (policy.length() == 0) {
+ result = true;
+ } else {
+ String[] names = policy.split("\\s+");
+ for (String name: names) {
+ if (name.equals(s)) {
+ result = true;
+ break;
+ }
+ }
+ }
+ if (result) {
+ System.out.printf(">>>> Policy match result (%s vs %s on %s) %b\n",
+ c, s, rule, result);
+ }
+ return result;
+ }
+
+
/**
* Processes an incoming request and generates a response.
* @param in the request
@@ -530,7 +592,7 @@ public class KDC {
tkt = apReq.ticket;
etype = tkt.encPart.getEType();
tkt.sname.setRealm(tkt.realm);
- EncryptionKey kkey = keyForUser(tkt.sname, etype);
+ EncryptionKey kkey = keyForUser(tkt.sname, etype, true);
byte[] bb = tkt.encPart.decrypt(kkey, KeyUsage.KU_TICKET);
DerInputStream derIn = new DerInputStream(bb);
DerValue der = derIn.getDerValue();
@@ -541,7 +603,7 @@ public class KDC {
throw new KrbException(Krb5.KDC_ERR_PADATA_TYPE_NOSUPP);
}
}
- EncryptionKey skey = keyForUser(body.sname, etype);
+ EncryptionKey skey = keyForUser(body.sname, etype, true);
if (skey == null) {
throw new KrbException(Krb5.KDC_ERR_SUMTYPE_NOSUPP); // TODO
}
@@ -581,6 +643,10 @@ public class KDC {
if (body.kdcOptions.get(KDCOptions.ALLOW_POSTDATE)) {
bFlags[Krb5.TKT_OPTS_MAY_POSTDATE] = true;
}
+
+ if (configMatch("", body.sname.getNameString(), "ok-as-delegate")) {
+ bFlags[Krb5.TKT_OPTS_DELEGATE] = true;
+ }
bFlags[Krb5.TKT_OPTS_INITIAL] = true;
TicketFlags tFlags = new TicketFlags(bFlags);
@@ -671,8 +737,8 @@ public class KDC {
eTypes = (int[])f.get(body);
int eType = eTypes[0];
- EncryptionKey ckey = keyForUser(body.cname, eType);
- EncryptionKey skey = keyForUser(body.sname, eType);
+ EncryptionKey ckey = keyForUser(body.cname, eType, false);
+ EncryptionKey skey = keyForUser(body.sname, eType, true);
if (ckey == null) {
throw new KrbException(Krb5.KDC_ERR_ETYPE_NOSUPP);
}
diff --git a/test/sun/security/krb5/auto/OkAsDelegate.java b/test/sun/security/krb5/auto/OkAsDelegate.java
new file mode 100644
index 0000000000000000000000000000000000000000..fee677b536b8a39f603afe93fa5696a35176296f
--- /dev/null
+++ b/test/sun/security/krb5/auto/OkAsDelegate.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import com.sun.security.jgss.ExtendedGSSContext;
+import org.ietf.jgss.GSSCredential;
+import org.ietf.jgss.GSSException;
+import org.ietf.jgss.Oid;
+import sun.security.jgss.GSSUtil;
+import sun.security.krb5.Config;
+
+public class OkAsDelegate {
+
+ public static void main(String[] args)
+ throws Exception {
+ OkAsDelegate ok = new OkAsDelegate();
+ ok.go(
+ Boolean.valueOf(args[0]), // FORWARDABLE in krb5.conf on?
+ Boolean.valueOf(args[1]), // requestDelegState
+ Boolean.valueOf(args[2]), // requestDelegPolicyState
+ Boolean.valueOf(args[3]), // DelegState in response
+ Boolean.valueOf(args[4]), // DelegPolicyState in response
+ Boolean.valueOf(args[5]) // getDelegCred OK?
+ );
+ }
+
+ void go(
+ boolean forwardable,
+ boolean requestDelegState,
+ boolean requestDelegPolicyState,
+ boolean delegState,
+ boolean delegPolicyState,
+ boolean delegated
+ ) throws Exception {
+ OneKDC kdc = new OneKDC(null);
+ kdc.setPolicy("ok-as-delegate",
+ System.getProperty("test.kdc.policy.ok-as-delegate"));
+ kdc.writeJAASConf();
+ if (!forwardable) {
+ // The default OneKDC always includes "forwardable = true"
+ // in krb5.conf, override it.
+ KDC.saveConfig(OneKDC.KRB5_CONF, kdc,
+ "default_keytab_name = " + OneKDC.KTAB);
+ Config.refresh();
+ }
+
+ Context c, s;
+ c = Context.fromJAAS("client");
+ s = Context.fromJAAS("server");
+
+ Oid mech = GSSUtil.GSS_KRB5_MECH_OID;
+ if (System.getProperty("test.spnego") != null) {
+ mech = GSSUtil.GSS_SPNEGO_MECH_OID;
+ }
+ c.startAsClient(OneKDC.SERVER, mech);
+ ExtendedGSSContext cx = (ExtendedGSSContext)c.x();
+ cx.requestCredDeleg(requestDelegState);
+ cx.requestDelegPolicy(requestDelegPolicyState);
+ s.startAsServer(mech);
+ ExtendedGSSContext sx = (ExtendedGSSContext)s.x();
+
+ Context.handshake(c, s);
+
+ if (cx.getCredDelegState() != delegState) {
+ throw new Exception("Initiator cred state error");
+ }
+ if (sx.getCredDelegState() != delegState) {
+ throw new Exception("Acceptor cred state error");
+ }
+ if (cx.getDelegPolicyState() != delegPolicyState) {
+ throw new Exception("Initiator cred policy state error");
+ }
+
+ GSSCredential cred = null;
+ try {
+ cred = s.x().getDelegCred();
+ } catch (GSSException e) {
+ // leave cred as null
+ }
+
+ if (delegated != (cred != null)) {
+ throw new Exception("get cred error");
+ }
+ }
+}
diff --git a/test/sun/security/krb5/auto/OkAsDelegateXRealm.java b/test/sun/security/krb5/auto/OkAsDelegateXRealm.java
new file mode 100644
index 0000000000000000000000000000000000000000..54c181fc8f61f93e785e4a7628ec338b5efb0761
--- /dev/null
+++ b/test/sun/security/krb5/auto/OkAsDelegateXRealm.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import com.sun.security.jgss.ExtendedGSSContext;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.security.Security;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import org.ietf.jgss.GSSContext;
+import org.ietf.jgss.GSSCredential;
+import org.ietf.jgss.GSSException;
+import org.ietf.jgss.GSSManager;
+import org.ietf.jgss.GSSName;
+import sun.security.jgss.GSSUtil;
+import sun.security.krb5.Config;
+
+public class OkAsDelegateXRealm implements CallbackHandler {
+
+ /**
+ * @param args boolean if the program should succeed
+ */
+ public static void main(String[] args)
+ throws Exception {
+
+ // Create and start the KDCs. Here we have 3 realms: R1, R2 and R3.
+ // R1 is trusted by R2, and R2 trusted by R3.
+ KDC kdc1 = KDC.create("R1");
+ kdc1.setPolicy("ok-as-delegate",
+ System.getProperty("test.kdc.policy.ok-as-delegate"));
+ kdc1.addPrincipal("dummy", "bogus".toCharArray());
+ kdc1.addPrincipalRandKey("krbtgt/R1");
+ kdc1.addPrincipal("krbtgt/R2@R1", "r1->r2".toCharArray());
+
+ KDC kdc2 = KDC.create("R2");
+ kdc2.setPolicy("ok-as-delegate",
+ System.getProperty("test.kdc.policy.ok-as-delegate"));
+ kdc2.addPrincipalRandKey("krbtgt/R2");
+ kdc2.addPrincipal("krbtgt/R2@R1", "r1->r2".toCharArray());
+ kdc2.addPrincipal("krbtgt/R3@R2", "r2->r3".toCharArray());
+
+ KDC kdc3 = KDC.create("R3");
+ kdc3.setPolicy("ok-as-delegate",
+ System.getProperty("test.kdc.policy.ok-as-delegate"));
+ kdc3.addPrincipalRandKey("krbtgt/R3");
+ kdc3.addPrincipal("krbtgt/R3@R2", "r2->r3".toCharArray());
+ kdc3.addPrincipalRandKey("host/host.r3.local");
+
+ KDC.saveConfig("krb5-localkdc.conf", kdc1, kdc2, kdc3,
+ "forwardable=true",
+ "[capaths]",
+ "R1 = {",
+ " R2 = .",
+ " R3 = R2",
+ "}",
+ "[domain_realm]",
+ ".r3.local=R3"
+ );
+
+ System.setProperty("java.security.krb5.conf", "krb5-localkdc.conf");
+ kdc3.writeKtab("localkdc.ktab");
+
+ FileOutputStream fos = new FileOutputStream("jaas-localkdc.conf");
+
+ // Defines the client and server on R1 and R3 respectively.
+ fos.write(("com.sun.security.jgss.krb5.initiate {\n" +
+ " com.sun.security.auth.module.Krb5LoginModule\n" +
+ " required\n" +
+ " principal=dummy\n" +
+ " doNotPrompt=false\n" +
+ " useTicketCache=false\n" +
+ " ;\n};\n" +
+ "com.sun.security.jgss.krb5.accept {\n" +
+ " com.sun.security.auth.module.Krb5LoginModule required\n" +
+ " principal=\"host/host.r3.local@R3\"\n" +
+ " useKeyTab=true\n" +
+ " keyTab=localkdc.ktab\n" +
+ " isInitiator=false\n" +
+ " storeKey=true;\n};\n" +
+ "\n").getBytes());
+ fos.close();
+
+ Security.setProperty("auth.login.defaultCallbackHandler",
+ "OkAsDelegateXRealm");
+
+ System.setProperty("java.security.auth.login.config", "jaas-localkdc.conf");
+
+ new File("krb5-localkdc.conf").deleteOnExit();
+ new File("localkdc.ktab").deleteOnExit();
+ new File("jaas-localkdc.conf").deleteOnExit();
+ Config.refresh();
+
+ Context c = Context.fromJAAS("com.sun.security.jgss.krb5.initiate");
+ Context s = Context.fromJAAS("com.sun.security.jgss.krb5.accept");
+
+ // Test twice. The frist time the whole cross realm process is tried,
+ // the second time the cached service ticket is used. This is to make sure
+ // the behaviors are the same, especailly for the case when one of the
+ // cross-realm TGTs does not have OK-AS-DELEGATE on.
+
+ for (int i=0; i<2; i++) {
+ c.startAsClient("host@host.r3.local", GSSUtil.GSS_KRB5_MECH_OID);
+ s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID);
+ c.x().requestDelegPolicy(true);
+
+ Context.handshake(c, s);
+ boolean succeed = true;
+ try {
+ s.x().getDelegCred();
+ } catch (GSSException gsse) {
+ succeed = false;
+ }
+ if (succeed != Boolean.parseBoolean(args[0])) {
+ throw new Exception("Test fail at round #" + i);
+ }
+ }
+ }
+
+ @Override
+ public void handle(Callback[] callbacks)
+ throws IOException, UnsupportedCallbackException {
+ for (Callback callback : callbacks) {
+ if (callback instanceof NameCallback) {
+ ((NameCallback) callback).setName("dummy");
+ }
+ if (callback instanceof PasswordCallback) {
+ ((PasswordCallback) callback).setPassword("bogus".toCharArray());
+ }
+ }
+ }
+}
+
diff --git a/test/sun/security/krb5/auto/ok-as-delegate-xrealm.sh b/test/sun/security/krb5/auto/ok-as-delegate-xrealm.sh
new file mode 100644
index 0000000000000000000000000000000000000000..850dae3e443f7fcb197762c9105b794a08e01515
--- /dev/null
+++ b/test/sun/security/krb5/auto/ok-as-delegate-xrealm.sh
@@ -0,0 +1,79 @@
+#
+# Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+# @test
+# @bug 6853328
+# @summary Support OK-AS-DELEGATE flag
+# @run shell/timeout=600 ok-as-delegate-xrealm.sh
+#
+
+if [ "${TESTSRC}" = "" ] ; then
+ TESTSRC=`dirname $0`
+fi
+
+if [ "${TESTJAVA}" = "" ] ; then
+ JAVAC_CMD=`which javac`
+ TESTJAVA=`dirname $JAVAC_CMD`/..
+fi
+
+# set platform-dependent variables
+OS=`uname -s`
+case "$OS" in
+ Windows_* )
+ FS="\\"
+ SEP=";"
+ ;;
+ CYGWIN* )
+ FS="/"
+ SEP=";"
+ ;;
+ * )
+ FS="/"
+ SEP=":"
+ ;;
+esac
+
+${TESTJAVA}${FS}bin${FS}javac -XDignore.symbol.file -d . \
+ ${TESTSRC}${FS}OkAsDelegateXRealm.java \
+ ${TESTSRC}${FS}KDC.java \
+ ${TESTSRC}${FS}OneKDC.java \
+ ${TESTSRC}${FS}Action.java \
+ ${TESTSRC}${FS}Context.java \
+ || exit 10
+
+# Add $TESTSRC to classpath so that customized nameservice can be used
+J="${TESTJAVA}${FS}bin${FS}java -cp $TESTSRC${SEP}."
+
+# KDC no OK-AS-DELEGATE, fail
+$J OkAsDelegateXRealm false || exit 1
+
+# KDC set OK-AS-DELEGATE for all, succeed
+$J -Dtest.kdc.policy.ok-as-delegate OkAsDelegateXRealm true || exit 2
+
+# KDC set OK-AS-DELEGATE for host/host.r3.local only, fail
+$J -Dtest.kdc.policy.ok-as-delegate=host/host.r3.local OkAsDelegateXRealm false || exit 3
+
+# KDC set OK-AS-DELEGATE for all, succeed
+$J "-Dtest.kdc.policy.ok-as-delegate=host/host.r3.local krbtgt/R2 krbtgt/R3" OkAsDelegateXRealm true || exit 4
+
+exit 0
diff --git a/test/sun/security/krb5/auto/ok-as-delegate.sh b/test/sun/security/krb5/auto/ok-as-delegate.sh
new file mode 100644
index 0000000000000000000000000000000000000000..1647e1561f54b61def80b9461654e59c6ba2f783
--- /dev/null
+++ b/test/sun/security/krb5/auto/ok-as-delegate.sh
@@ -0,0 +1,118 @@
+#
+# Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+# @test
+# @bug 6853328
+# @summary Support OK-AS-DELEGATE flag
+# @run shell/timeout=600 ok-as-delegate.sh
+#
+
+if [ "${TESTSRC}" = "" ] ; then
+ TESTSRC=`dirname $0`
+fi
+
+if [ "${TESTJAVA}" = "" ] ; then
+ JAVAC_CMD=`which javac`
+ TESTJAVA=`dirname $JAVAC_CMD`/..
+fi
+
+# set platform-dependent variables
+OS=`uname -s`
+case "$OS" in
+ Windows_* )
+ FS="\\"
+ SEP=";"
+ ;;
+ CYGWIN* )
+ FS="/"
+ SEP=";"
+ ;;
+ * )
+ FS="/"
+ SEP=":"
+ ;;
+esac
+
+${TESTJAVA}${FS}bin${FS}javac -XDignore.symbol.file -d . \
+ ${TESTSRC}${FS}OkAsDelegate.java \
+ ${TESTSRC}${FS}KDC.java \
+ ${TESTSRC}${FS}OneKDC.java \
+ ${TESTSRC}${FS}Action.java \
+ ${TESTSRC}${FS}Context.java \
+ || exit 10
+
+# Testing Kerberos 5
+
+# Add $TESTSRC to classpath so that customized nameservice can be used
+J="${TESTJAVA}${FS}bin${FS}java -cp $TESTSRC${SEP}. OkAsDelegate"
+JOK="${TESTJAVA}${FS}bin${FS}java -cp $TESTSRC${SEP}. -Dtest.kdc.policy.ok-as-delegate OkAsDelegate"
+
+# FORWARDABLE ticket not allowed, always fail
+$J false true true false false false || exit 1
+
+# Service ticket no OK-AS-DELEGATE
+
+# Request nothing, gain nothing
+$J true false false false false false || exit 2
+# Request deleg policy, gain nothing
+$J true false true false false false || exit 3
+# Request deleg, granted
+$J true true false true false true || exit 4
+# Request deleg and deleg policy, granted, with info not by policy
+$J true true true true false true || exit 5
+
+# Service ticket has OK-AS-DELEGATE
+
+# Request deleg policy, granted
+$JOK true false true true true true || exit 6
+# Request deleg and deleg policy, granted, with info by policy
+$JOK true true true true true true || exit 7
+
+# Testing SPNEGO
+
+# Add $TESTSRC to classpath so that customized nameservice can be used
+J="${TESTJAVA}${FS}bin${FS}java -cp $TESTSRC${SEP}. -Dtest.spnego OkAsDelegate"
+JOK="${TESTJAVA}${FS}bin${FS}java -cp $TESTSRC${SEP}. -Dtest.spnego -Dtest.kdc.policy.ok-as-delegate OkAsDelegate"
+
+# FORWARDABLE ticket not allowed, always fail
+$J false true true false false false || exit 11
+
+# Service ticket no OK-AS-DELEGATE
+
+# Request nothing, gain nothing
+$J true false false false false false || exit 12
+# Request deleg policy, gain nothing
+$J true false true false false false || exit 13
+# Request deleg, granted
+$J true true false true false true || exit 14
+# Request deleg and deleg policy, granted, with info not by policy
+$J true true true true false true || exit 15
+
+# Service ticket has OK-AS-DELEGATE
+
+# Request deleg policy, granted
+$JOK true false true true true true || exit 16
+# Request deleg and deleg policy, granted, with info by policy
+$JOK true true true true true true || exit 17
+
+exit 0
diff --git a/test/tools/launcher/Arrrghs.java b/test/tools/launcher/Arrrghs.java
index 4853b90516624ea19d4ef20ecde3b558fbc3f86f..b7ba2737dfa2aba2126e3a19b2c8245d1f7888e1 100644
--- a/test/tools/launcher/Arrrghs.java
+++ b/test/tools/launcher/Arrrghs.java
@@ -25,7 +25,7 @@
* @test
* @bug 5030233 6214916 6356475 6571029 6684582 6742159 4459600 6758881
* @summary Argument parsing validation.
- * @compile Arrrghs.java TestHelper.java
+ * @compile -XDignore.symbol.file Arrrghs.java TestHelper.java
* @run main Arrrghs
*/
diff --git a/test/tools/launcher/ExecutionEnvironment.java b/test/tools/launcher/ExecutionEnvironment.java
new file mode 100644
index 0000000000000000000000000000000000000000..217de4670e0ea6765de946522fc98b66ce6dc605
--- /dev/null
+++ b/test/tools/launcher/ExecutionEnvironment.java
@@ -0,0 +1,358 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4780570 4731671 6354700 6367077 6670965 4882974
+ * @summary Checks for LD_LIBRARY_PATH and execution on *nixes
+ * @compile -XDignore.symbol.file ExecutionEnvironment.java TestHelper.java
+ * @run main ExecutionEnvironment
+ */
+
+/*
+ * This test tests for various things as follows:
+ * Ensures that:
+ * 1. uneccessary execs do not occur
+ * 2. the environment is pristine, users environment variable wrt.
+ * LD_LIBRARY_PATH if set are not modified in any way.
+ * 3. the correct vm is chosen with -server and -client options
+ * 4. the VM on Solaris correctly interprets the LD_LIBRARY_PATH32
+ * and LD_LIBRARY_PATH64 variables if set by the user, ie.
+ * i. on 32 bit systems:
+ * a. if LD_LIBRARY_PATH32 is set it will override LD_LIBRARY_PATH
+ * b. LD_LIBRARY_PATH64 is ignored if set
+ * ii. on 64 bit systems:
+ * a. if LD_LIBRARY_PATH64 is set it will override LD_LIBRARY_PATH
+ * b. LD_LIBRARY_PATH32 is ignored if set
+ * 5. no extra symlink exists on Solaris ie.
+ * jre/lib/$arch/libjvm.so -> client/libjvm.so
+ * TODO:
+ * a. perhaps we need to add a test to audit all environment variables are
+ * in pristine condition after the launch, there may be a few that the
+ * launcher may add as implementation details.
+ * b. add a pldd for solaris to ensure only one libjvm.so is linked
+ */
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+public class ExecutionEnvironment {
+ static final String LD_LIBRARY_PATH = "LD_LIBRARY_PATH";
+ static final String LD_LIBRARY_PATH_32 = LD_LIBRARY_PATH + "_32";
+ static final String LD_LIBRARY_PATH_64 = LD_LIBRARY_PATH + "_64";
+
+ // Note: these paths need not exist on the filesytem
+ static final String LD_LIBRARY_PATH_VALUE = "/Bridge/On/The/River/Kwai";
+ static final String LD_LIBRARY_PATH_32_VALUE = "/Lawrence/Of/Arabia";
+ static final String LD_LIBRARY_PATH_64_VALUE = "/A/Passage/To/India";
+
+ static final String JLDEBUG_KEY = "_JAVA_LAUNCHER_DEBUG";
+ static final String EXPECTED_MARKER = "TRACER_MARKER:About to EXEC";
+
+ static final String[] LD_PATH_STRINGS = {
+ LD_LIBRARY_PATH + "=" + LD_LIBRARY_PATH_VALUE,
+ LD_LIBRARY_PATH_32 + "=" + LD_LIBRARY_PATH_32_VALUE,
+ LD_LIBRARY_PATH_64 + "=" + LD_LIBRARY_PATH_64_VALUE
+ };
+
+ static final File testJarFile = new File("EcoFriendly.jar");
+
+ static int errors = 0;
+ static int passes = 0;
+
+ private static void createTestJar() {
+ try {
+ List codeList = new ArrayList();
+ codeList.add("static void printValue(String name, boolean property) {\n");
+ codeList.add(" String value = (property) ? System.getProperty(name) : System.getenv(name);\n");
+ codeList.add(" System.out.println(name + \"=\" + value);\n");
+ codeList.add("}\n");
+ codeList.add("public static void main(String... args) {\n");
+ codeList.add(" System.out.println(\"Execute test:\");\n");
+ codeList.add(" printValue(\"os.name\", true);\n");
+ codeList.add(" printValue(\"os.arch\", true);\n");
+ codeList.add(" printValue(\"os.version\", true);\n");
+ codeList.add(" printValue(\"sun.arch.data.model\", true);\n");
+ codeList.add(" printValue(\"java.library.path\", true);\n");
+ codeList.add(" printValue(\"" + LD_LIBRARY_PATH + "\", false);\n");
+ codeList.add(" printValue(\"" + LD_LIBRARY_PATH_32 + "\", false);\n");
+ codeList.add(" printValue(\"" + LD_LIBRARY_PATH_64 + "\", false);\n");
+ codeList.add("}\n");
+ String[] clist = new String[codeList.size()];
+ TestHelper.createJar(testJarFile, codeList.toArray(clist));
+ } catch (FileNotFoundException fnfe) {
+ throw new RuntimeException(fnfe);
+ }
+ }
+
+ /*
+ * tests if the launcher pollutes the LD_LIBRARY_PATH variables ie. there
+ * should not be any new variables or pollution/mutations of any kind, the
+ * environment should be pristine.
+ */
+ private static void ensureEcoFriendly() {
+ TestHelper.TestResult tr = null;
+
+ Map env = new HashMap();
+ for (String x : LD_PATH_STRINGS) {
+ String pairs[] = x.split("=");
+ env.put(pairs[0], pairs[1]);
+ }
+
+ tr = TestHelper.doExec(env, TestHelper.javaCmd, "-jar",
+ testJarFile.getAbsolutePath());
+
+ if (!tr.isNotZeroOutput()) {
+ throw new RuntimeException("Error: No output at all. Did the test execute ?");
+ }
+
+ for (String x : LD_PATH_STRINGS) {
+ if (!tr.contains(x)) {
+ System.out.println("FAIL: did not get <" + x + ">");
+ System.out.println(tr);
+ errors++;
+ } else {
+ passes++;
+ }
+ }
+ }
+
+ /*
+ * ensures that there are no execs as long as we are in the same
+ * data model
+ */
+ static void ensureNoExec() {
+ Map env = new HashMap();
+ env.put(JLDEBUG_KEY, "true");
+ TestHelper.TestResult tr =
+ TestHelper.doExec(env, TestHelper.javaCmd, "-version");
+ if (tr.testOutput.contains(EXPECTED_MARKER)) {
+ System.out.println("FAIL: EnsureNoExecs: found expected warning <" +
+ EXPECTED_MARKER +
+ "> the process execing ?");
+ errors++;
+ } else {
+ passes++;
+ }
+ return;
+ }
+
+ /*
+ * This test ensures that LD_LIBRARY_PATH* values are interpreted by the VM
+ * and the expected java.library.path behaviour.
+ * For Generic platforms (All *nixes):
+ * * All LD_LIBRARY_PATH variable should be on java.library.path
+ * For Solaris 32-bit
+ * * The LD_LIBRARY_PATH_32 should override LD_LIBRARY_PATH if specified
+ * For Solaris 64-bit
+ * * The LD_LIBRARY_PATH_64 should override LD_LIBRARY_PATH if specified
+ */
+
+ static void verifyJavaLibraryPath() {
+ TestHelper.TestResult tr = null;
+
+ Map env = new HashMap();
+
+
+ if (TestHelper.isLinux) {
+ for (String x : LD_PATH_STRINGS) {
+ String pairs[] = x.split("=");
+ env.put(pairs[0], pairs[1]);
+ }
+
+ tr = TestHelper.doExec(env, TestHelper.javaCmd, "-jar",
+ testJarFile.getAbsolutePath());
+ verifyJavaLibraryPathGeneric(tr);
+ } else {
+ // no override
+ env.clear();
+ env.put(LD_LIBRARY_PATH, LD_LIBRARY_PATH_VALUE);
+ tr = TestHelper.doExec(env, TestHelper.javaCmd, "-jar",
+ testJarFile.getAbsolutePath());
+ verifyJavaLibraryPathGeneric(tr);
+
+ env.clear();
+ for (String x : LD_PATH_STRINGS) {
+ String pairs[] = x.split("=");
+ env.put(pairs[0], pairs[1]);
+ }
+
+ // verify the override occurs, since we know the invocation always
+ // uses by default is 32-bit, therefore we also set the test
+ // expectation to be the same.
+ tr = TestHelper.doExec(env, TestHelper.javaCmd, "-jar",
+ testJarFile.getAbsolutePath());
+ verifyJavaLibraryPathOverride(tr, true);
+
+ // try changing the model from 32 to 64 bit
+ if (TestHelper.java64Cmd != null && TestHelper.is32Bit) {
+ // verify the override occurs
+ env.clear();
+ for (String x : LD_PATH_STRINGS) {
+ String pairs[] = x.split("=");
+ env.put(pairs[0], pairs[1]);
+ }
+ tr = TestHelper.doExec(env, TestHelper.javaCmd, "-d64", "-jar",
+ testJarFile.getAbsolutePath());
+ verifyJavaLibraryPathOverride(tr, false);
+
+ // no override
+ env.clear();
+ env.put(LD_LIBRARY_PATH, LD_LIBRARY_PATH_VALUE);
+ tr = TestHelper.doExec(env, TestHelper.javaCmd, "-jar",
+ testJarFile.getAbsolutePath());
+ verifyJavaLibraryPathGeneric(tr);
+ }
+
+ // try changing the model from 64 to 32 bit
+ if (TestHelper.java64Cmd != null && TestHelper.is64Bit) {
+ // verify the override occurs
+ env.clear();
+ for (String x : LD_PATH_STRINGS) {
+ String pairs[] = x.split("=");
+ env.put(pairs[0], pairs[1]);
+ }
+ tr = TestHelper.doExec(env, TestHelper.java64Cmd, "-d32", "-jar",
+ testJarFile.getAbsolutePath());
+ verifyJavaLibraryPathOverride(tr, true);
+
+ // no override
+ env.clear();
+ env.put(LD_LIBRARY_PATH, LD_LIBRARY_PATH_VALUE);
+ tr = TestHelper.doExec(env, TestHelper.java64Cmd, "-d32", "-jar",
+ testJarFile.getAbsolutePath());
+ verifyJavaLibraryPathGeneric(tr);
+ }
+ }
+ }
+
+ private static void verifyJavaLibraryPathGeneric(TestHelper.TestResult tr) {
+ if (!tr.matches("java.library.path=.*" + LD_LIBRARY_PATH_VALUE + ".*")) {
+ System.out.print("FAIL: verifyJavaLibraryPath: ");
+ System.out.println(" java.library.path does not contain " +
+ LD_LIBRARY_PATH_VALUE);
+ System.out.println(tr);
+ errors++;
+ } else {
+ passes++;
+ }
+ }
+
+ private static void verifyJavaLibraryPathOverride(TestHelper.TestResult tr,
+ boolean is32Bit) {
+ // make sure the 32/64 bit value exists
+ if (!tr.matches("java.library.path=.*" +
+ (is32Bit ? LD_LIBRARY_PATH_32_VALUE : LD_LIBRARY_PATH_64_VALUE) + ".*")) {
+ System.out.print("FAIL: verifyJavaLibraryPathOverride: ");
+ System.out.println(" java.library.path does not contain " +
+ (is32Bit ? LD_LIBRARY_PATH_32_VALUE : LD_LIBRARY_PATH_64_VALUE));
+ System.out.println(tr);
+ errors++;
+ } else {
+ passes++;
+ }
+ // make sure the generic value is absent
+ if (tr.matches("java.library.path=.*" + LD_LIBRARY_PATH_VALUE + ".*")) {
+ System.out.print("FAIL: verifyJavaLibraryPathOverride: ");
+ System.out.println(" java.library.path contains " +
+ LD_LIBRARY_PATH_VALUE);
+ System.out.println(tr);
+ errors++;
+ } else {
+ passes++;
+ }
+ }
+
+ /*
+ * ensures we have indeed exec'ed the correct vm of choice, all VMs support
+ * -server, however 32-bit VMs support -client and -server.
+ */
+ static void verifyVmSelection() {
+
+ TestHelper.TestResult tr = null;
+
+ if (TestHelper.is32Bit) {
+ tr = TestHelper.doExec(TestHelper.javaCmd, "-client", "-version");
+ if (!tr.matches("Java.*Client VM.*")) {
+ System.out.println("FAIL: the expected vm -client did launch");
+ System.out.println(tr);
+ errors++;
+ } else {
+ passes++;
+ }
+ }
+ tr = TestHelper.doExec(TestHelper.javaCmd, "-server", "-version");
+ if (!tr.matches("Java.*Server VM.*")) {
+ System.out.println("FAIL: the expected vm -server did launch");
+ System.out.println(tr);
+ errors++;
+ } else {
+ passes++;
+ }
+ }
+
+ /*
+ * checks to see there is no extra libjvm.so than needed
+ */
+ static void verifyNoSymLink() {
+ if (TestHelper.is64Bit) {
+ return;
+ }
+
+ File symLink = null;
+ String libPathPrefix = TestHelper.isSDK ? "jre/lib" : "/lib";
+ symLink = new File(TestHelper.JAVAHOME, libPathPrefix +
+ TestHelper.getJreArch() + "/libjvm.so");
+ if (symLink.exists()) {
+ System.out.println("FAIL: The symlink exists " +
+ symLink.getAbsolutePath());
+ errors++;
+ } else {
+ passes++;
+ }
+ }
+
+ public static void main(String... args) throws Exception {
+ if (TestHelper.isWindows) {
+ System.out.println("Warning: noop on windows");
+ return;
+ }
+ // create our test jar first
+ createTestJar();
+ ensureNoExec();
+ verifyVmSelection();
+ ensureEcoFriendly();
+ verifyJavaLibraryPath();
+ verifyNoSymLink();
+ if (errors > 0) {
+ throw new Exception("ExecutionEnvironment: FAIL: with " +
+ errors + " errors and passes " + passes );
+ } else {
+ System.out.println("ExecutionEnvironment: PASS " + passes);
+ }
+ }
+}
diff --git a/test/tools/launcher/SolarisDataModel.sh b/test/tools/launcher/SolarisDataModel.sh
deleted file mode 100644
index 36398d7fe3913f7fe5f650591aa5f8aeee1a262c..0000000000000000000000000000000000000000
--- a/test/tools/launcher/SolarisDataModel.sh
+++ /dev/null
@@ -1,219 +0,0 @@
-# Copyright 2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
-# CA 95054 USA or visit www.sun.com if you need additional information or
-# have any questions.
-
-# @test
-# @bug 4780570
-# @run shell SolarisDataModel.sh
-# @summary Verify Solaris SPARC -d32 and -d64 options work with preset LD_LIBRARY_PATH
-# @author Joseph D. Darcy
-
-# Test to see if presetting LD_LIBRARY_PATH affects the treatment of
-# -d32 and -d64 options; also checks that -d options result in the
-# desired data model.
-
-# If the test is not being run on a Solaris SPARC box SPARC the test
-# succeeds immediately.
-
-OS=`uname -s`;
-
-case "$OS" in
- SunOS )
- # ARCH should be sparc or i386
- ARCH=`uname -p`
- case "$ARCH" in
- sparc)
- PATHSEP=":"
- ;;
-
- * )
- echo "Non-SPARC Solaris environment; test vacuously succeeds."
- exit 0
- esac
- ;;
-
- * )
- echo "Not a Solaris SPARC environment; test vacuously succeeds."
- exit 0;
- ;;
-esac
-
-
-# Verify directory context variables are set
-if [ "${TESTJAVA}" = "" ]
-then
- echo "TESTJAVA not set. Test cannot execute. Failed."
- exit 1
-fi
-
-if [ "${TESTSRC}" = "" ]
-then
- echo "TESTSRC not set. Test cannot execute. Failed."
- exit 1
-fi
-
-
-if [ "${TESTCLASSES}" = "" ]
-then
- echo "TESTCLASSES not set. Test cannot execute. Failed."
- exit 1
-fi
-
-
-JAVAC="$TESTJAVA/bin/javac"
-
-# Create our little Java tests on the fly
-( printf "public class GetDataModel {"
- printf " public static void main(String argv[]) {"
- printf " System.out.println(System.getProperty(\"sun.arch.data.model\", \"none\"));"
- printf " }"
- printf "}"
-) > GetDataModel.java
-
-$JAVAC GetDataModel.java
-
-( printf "public class GetLdLibraryPath {"
- printf " public static void main(String argv[]) {"
- printf " System.out.println(System.getProperty(\"java.library.path\"));"
- printf " }"
- printf "}"
-) > GetLdLibraryPath.java
-
-$JAVAC GetLdLibraryPath.java
-
-
-
-# All preconditions are met; run the tests
-
-
-# Construct path to 32-bit Java executable
-JAVA="$TESTJAVA/bin/java -classpath $TESTCLASSES${PATHSEP}."
-
-
-# Construct path to 64-bit Java executable, might not exist
-JAVA64="$TESTJAVA/bin/sparcv9/java -classpath $TESTCLASSES${PATHSEP}."
-JAVA64FILE="$TESTJAVA/bin/sparcv9/java"
-
-
-# java -d32 tests
-
-LD_LIBRARY_PATH=""
-export LD_LIBRARY_PATH
-
-DM=`$JAVA -d32 GetDataModel`
-case "$DM" in
- 32 )
- ;;
-
- * )
- echo "The combination \"java -d32\" failed."
- echo $DM
- exit 1
-esac
-
-# Rerun test with LD_LIBRARY_PATH preset
-LD_LIBRARY_PATH=`$JAVA GetLdLibraryPath`;
-DM=`$JAVA -d32 GetDataModel`
-case "$DM" in
- 32 )
- ;;
-
- * )
- echo "The combination \"java -d32\" failed with preset LD_LIBRARY_PATH."
- echo $DM
- exit 1
-esac
-
-# Reset LD_LIBRARY_PATH
-LD_LIBRARY_PATH=
-
-
-# Test for 64-bit executable
-
-if [ -f $JAVA64FILE ]; then
-
- DM=`$JAVA -d64 GetDataModel`
- case "$DM" in
- 64 )
- ;;
-
- * )
- echo "The combination \"java -d64\" failed."
- exit 1
- esac
-
- DM=`$JAVA64 -d32 GetDataModel`
- case "$DM" in
- 32 )
- ;;
-
- * )
- echo "The combination \"sparcv9/java -d32\" failed."
- exit 1
- esac
-
- DM=`$JAVA64 -d64 GetDataModel`
- case "$DM" in
- 64 )
- ;;
-
- * )
- echo "The combination \"sparcv9/java -d64\" failed."
- exit 1
- esac
-
- # Rerun tests with LD_LIBRARY_PATH preset
- LD_LIBRARY_PATH=`$JAVA GetLdLibraryPath`;
- echo "Presetting LD_LIBRARY_PATH"
-
- DM=`$JAVA -d64 GetDataModel`
- case "$DM" in
- 64 )
- ;;
-
- * )
- echo "The combination \"java -d64\" failed with preset LD_LIBRARY_PATH."
- exit 1
- esac
-
- DM=`$JAVA64 -d32 GetDataModel`
- case "$DM" in
- 32 )
- ;;
-
- * )
- echo "The combination \"sparcv9/java -d32\" failed with preset LD_LIBRARY_PATH."
- exit 1
- esac
-
- DM=`$JAVA64 -d64 GetDataModel`
- case "$DM" in
- 64 )
- ;;
-
- * )
- echo "The combination \"sparcv9/java -d64\" failed with preset LD_LIBRARY_PATH."
- exit 1
- esac
-
-else
- echo "Warning: no 64-bit components found; only java -d32 tests have been run."
-fi
-exit 0;
diff --git a/test/tools/launcher/SolarisRunpath.sh b/test/tools/launcher/SolarisRunpath.sh
deleted file mode 100644
index 26dd964f6548709bc267b13977865ceebfd722f4..0000000000000000000000000000000000000000
--- a/test/tools/launcher/SolarisRunpath.sh
+++ /dev/null
@@ -1,221 +0,0 @@
-# Copyright 2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
-# CA 95054 USA or visit www.sun.com if you need additional information or
-# have any questions.
-
-
-# @test
-# @bug 4731671
-# @build libraryCaller
-# @run shell SolarisRunpath.sh
-# @summary Verify that Solaris LD_LIBRARY_PATH rules are followed
-# @author Joseph D. Darcy
-
-# The launcher has been updated to properly take account of Solaris
-# LD_LIBRARY_PATH rules when constructing the runpath for the Java
-# executable. That is, data model dependent LD_LIBRARY_PATH variables
-# are tested for and override LD_LIBRARY_PATH if present. The current
-# launcher design relies on LD_LIBRARY_PATH settings to ensure the
-# proper jre/jdk libraries are opening during program execution. In
-# the future, this dependence might be removed by having the vm
-# explicitly dlopen the needed files. If that change occurs, this
-# test will be harmless but no long relevant.
-
-# A more robust test for Solaris SPARC would set the different
-# LD_LIBRARY_PATH variables while also varying the -d[32|64] options
-# to make sure the LD_LIBRARY_PATH of the *target* data model were
-# being respected. That is "java -d64" should use the 64-bit
-# LD_LIBRARY_PATH while "java -d32" should use the 32-bit
-# LD_LIBRARY_PATH regardless of the data model of the "java" binary.
-# However, by default builds do not contain both 32 and 64 bit
-# components so such a test would often not be applicable.
-
-
-# If the test is not being run on a Solaris box, SPARC or x86, the
-# test succeeds immediately.
-
-OS=`uname -s`;
-
-case "$OS" in
- SunOS )
- PATHSEP=":"
- ;;
-
- * )
- echo "Not a Solaris environment; test vacuously succeeds."
- exit 0;
- ;;
-esac
-
-# Verify directory context variables are set
-if [ "${TESTJAVA}" = "" ]
-then
- echo "TESTJAVA not set. Test cannot execute. Failed."
- exit 1
-fi
-
-if [ "${TESTSRC}" = "" ]
-then
- echo "TESTSRC not set. Test cannot execute. Failed."
- exit 1
-fi
-
-
-if [ "${TESTCLASSES}" = "" ]
-then
- echo "TESTCLASSES not set. Test cannot execute. Failed."
- exit 1
-fi
-
-# Construct paths to default Java executables
-JAVAC="$TESTJAVA/bin/javac"
-
-
-# Create our little Java test on the fly
-( printf "public class GetDataModel {"
- printf " public static void main(String argv[]) {"
- printf " System.out.println(System.getProperty(\"sun.arch.data.model\", \"none\"));"
- printf " }"
- printf "}"
-) > GetDataModel.java
-
-$JAVAC GetDataModel.java
-
-
-# ARCH should be sparc or i386
-ARCH=`uname -p`
-case "$ARCH" in
- sparc | i386 )
- ;;
-
- * )
- echo "Unrecognized architecture; test fails."
- exit 1
-esac
-
-# The following construction may not work as desired in a
-# 64-bit build.
-JAVA="$TESTJAVA/bin/java -classpath $TESTCLASSES${PATHSEP}."
-
-# Determine data model
-DM=`$JAVA GetDataModel`
-
-# verify DM is 32 or 64
-case "$DM" in
- 32 )
- ODM=64;
- ;;
-
- 64 )
- ODM=32;
- ;;
-
- * )
- echo "Unknown data model \"$DM\"; test fails."
- exit 1
-esac
-
-# -------------------- Test 1 --------------------
-
-LD_LIBRARY_PATH=$TESTSRC/lib/$ARCH/lib$DM
-export LD_LIBRARY_PATH
-unset LD_LIBRARY_PATH_32
-unset LD_LIBRARY_PATH_64
-
-# With plain LD_LIBRARY_PATH, result should always be 0
-RESULT=`$JAVA libraryCaller`
-if [ "${RESULT}" != "0" ];
-then
- echo "Not using LD_LIBRARY_PATH; test fails."
- exit 1
-fi
-
-# The following two tests sets both data model dependent
-# LD_LIBRARY_PATH variables individually.
-
-# -------------------- Test 2 --------------------
-
-# Set opposite data model variable; should return same result
-# as plain LD_LIBRARY_PATH.
-
-if [ "${DM}" = "32" ]; then
- LD_LIBRARY_PATH_64=$TESTSRC/lib/$ARCH/lib$DM/lib$DM
- export LD_LIBRARY_PATH_64
-else
- LD_LIBRARY_PATH_32=$TESTSRC/lib/$ARCH/lib$DM/lib$DM
- export LD_LIBRARY_PATH_32
-fi
-
-RESULT=`$JAVA libraryCaller`
-if [ "${RESULT}" != "0" ];
-then
- echo "Using LD_LIBRARY_PATH_$ODM for $DM binary;"
- echo "test fails."
- exit 1
-fi
-
-unset LD_LIBRARY_PATH_32
-unset LD_LIBRARY_PATH_64
-
-# -------------------- Test 3 --------------------
-
-# Set appropriate data model variable; result should match
-# data model.
-if [ "${DM}" = "32" ]; then
- LD_LIBRARY_PATH_32=$TESTSRC/lib/$ARCH/lib$DM/lib$DM
- export LD_LIBRARY_PATH_32
-else
- LD_LIBRARY_PATH_64=$TESTSRC/lib/$ARCH/lib$DM/lib$DM
- export LD_LIBRARY_PATH_64
-fi
-
-RESULT=`$JAVA libraryCaller`
-if [ "${RESULT}" != "$DM" ];
-then
- echo "Data model dependent LD_LIBRARY_PATH_$DM"
- echo "not overriding LD_LIBRARY_PATH; test fails."
- exit 1
-fi
-
-unset LD_LIBRARY_PATH
-unset LD_LIBRARY_PATH_32
-unset LD_LIBRARY_PATH_64
-
-# -------------------- Test 4 --------------------
-
-# Have only data model dependent LD_LIBRARY_PATH set; result
-# should match data model.
-
-if [ "${DM}" = "32" ]; then
- LD_LIBRARY_PATH_32=$TESTSRC/lib/$ARCH/lib$DM/lib$DM
- export LD_LIBRARY_PATH_32
-else
- LD_LIBRARY_PATH_64=$TESTSRC/lib/$ARCH/lib$DM/lib$DM
- export LD_LIBRARY_PATH_64
-fi
-
-RESULT=`$JAVA libraryCaller`
-if [ "${RESULT}" != "$DM" ];
-then
- echo "Not using data-model dependent LD_LIBRARY_PATH; test fails."
- exit 1
-fi
-
-# All tests have passed
-exit 0
diff --git a/test/tools/launcher/TestHelper.java b/test/tools/launcher/TestHelper.java
index fb63114b6d582864263766e257506e0b139fcdf3..da7b084dfd7c48e02d9e635ed125e63a391dd6a3 100644
--- a/test/tools/launcher/TestHelper.java
+++ b/test/tools/launcher/TestHelper.java
@@ -39,18 +39,36 @@ import javax.tools.JavaCompiler;
*/
public enum TestHelper {
INSTANCE;
- static final String JAVAHOME = System.getProperty("java.home", ".");
+ static final String JAVAHOME = System.getProperty("java.home");
static final boolean isSDK = JAVAHOME.endsWith("jre");
static final String javaCmd;
+ static final String java64Cmd;
static final String javacCmd;
static final JavaCompiler compiler;
- static final boolean debug = Boolean.getBoolean("Arrrghs.Debug");
+ static final boolean debug = Boolean.getBoolean("TestHelper.Debug");
static final boolean isWindows =
System.getProperty("os.name", "unknown").startsWith("Windows");
+ static final boolean is64Bit =
+ System.getProperty("sun.arch.data.model").equals("64");
+ static final boolean is32Bit =
+ System.getProperty("sun.arch.data.model").equals("32");
+ static final boolean isSolaris =
+ System.getProperty("os.name", "unknown").startsWith("SunOS");
+ static final boolean isLinux =
+ System.getProperty("os.name", "unknown").startsWith("Linux");
+ static final boolean isDualMode = isSolaris;
+ static final boolean isSparc = System.getProperty("os.arch").startsWith("sparc");
+
static int testExitValue = 0;
static {
+ if (is64Bit && is32Bit) {
+ throw new RuntimeException("arch model cannot be both 32 and 64 bit");
+ }
+ if (!is64Bit && !is32Bit) {
+ throw new RuntimeException("arch model is not 32 or 64 bit ?");
+ }
compiler = ToolProvider.getSystemJavaCompiler();
File binDir = (isSDK) ? new File((new File(JAVAHOME)).getParentFile(), "bin")
: new File(JAVAHOME, "bin");
@@ -69,6 +87,33 @@ public enum TestHelper {
if (!javacCmdFile.canExecute()) {
throw new RuntimeException("java <" + javacCmd + "> must exist");
}
+ if (isSolaris) {
+ File sparc64BinDir = new File(binDir,isSparc ? "sparcv9" : "amd64");
+ File java64CmdFile= new File(sparc64BinDir, "java");
+ if (java64CmdFile.exists() && java64CmdFile.canExecute()) {
+ java64Cmd = java64CmdFile.getAbsolutePath();
+ } else {
+ java64Cmd = null;
+ }
+ } else {
+ java64Cmd = null;
+ }
+ }
+
+ /*
+ * usually the jre/lib/arch-name is the same as os.arch, except for x86.
+ */
+ static String getJreArch() {
+ String arch = System.getProperty("os.arch");
+ return arch.equals("x86") ? "i386" : arch;
+ }
+
+ /*
+ * A convenience method to create a jar with jar file name and defs
+ */
+ static void createJar(File jarName, String... mainDefs)
+ throws FileNotFoundException{
+ createJar(null, jarName, new File("Foo"), mainDefs);
}
/*
@@ -123,16 +168,23 @@ public enum TestHelper {
}
}
+ static TestResult doExec(String...cmds) {
+ return doExec(null, cmds);
+ }
+
/*
* A method which executes a java cmd and returns the results in a container
*/
- static TestResult doExec(String...cmds) {
+ static TestResult doExec(Map envToSet, String...cmds) {
String cmdStr = "";
for (String x : cmds) {
cmdStr = cmdStr.concat(x + " ");
}
ProcessBuilder pb = new ProcessBuilder(cmds);
Map env = pb.environment();
+ if (envToSet != null) {
+ env.putAll(envToSet);
+ }
BufferedReader rdr = null;
try {
List outputList = new ArrayList();
@@ -163,21 +215,25 @@ public enum TestHelper {
List testOutput;
public TestResult(String str, int rv, List oList) {
- status = new StringBuilder(str);
+ status = new StringBuilder("Executed command: " + str + "\n");
exitValue = rv;
testOutput = oList;
}
+ void appendStatus(String x) {
+ status = status.append(" " + x + "\n");
+ }
+
void checkNegative() {
if (exitValue == 0) {
- status = status.append(" Error: test must not return 0 exit value");
+ appendStatus("Error: test must not return 0 exit value");
testExitValue++;
}
}
void checkPositive() {
if (exitValue != 0) {
- status = status.append(" Error: test did not return 0 exit value");
+ appendStatus("Error: test did not return 0 exit value");
testExitValue++;
}
}
@@ -188,7 +244,7 @@ public enum TestHelper {
boolean isZeroOutput() {
if (!testOutput.isEmpty()) {
- status = status.append(" Error: No message from cmd please");
+ appendStatus("Error: No message from cmd please");
testExitValue++;
return false;
}
@@ -197,19 +253,20 @@ public enum TestHelper {
boolean isNotZeroOutput() {
if (testOutput.isEmpty()) {
- status = status.append(" Error: Missing message");
+ appendStatus("Error: Missing message");
testExitValue++;
return false;
}
return true;
}
+ @Override
public String toString() {
- if (debug) {
- for (String x : testOutput) {
- status = status.append(x + "\n");
- }
+ status = status.append("++++Test Output Begin++++\n");
+ for (String x : testOutput) {
+ appendStatus(x);
}
+ status = status.append("++++Test Output End++++\n");
return status.toString();
}
@@ -219,7 +276,18 @@ public enum TestHelper {
return true;
}
}
- status = status.append(" Error: string <" + str + "> not found ");
+ appendStatus("Error: string <" + str + "> not found");
+ testExitValue++;
+ return false;
+ }
+
+ boolean matches(String stringToMatch) {
+ for (String x : testOutput) {
+ if (x.matches(stringToMatch)) {
+ return true;
+ }
+ }
+ appendStatus("Error: string <" + stringToMatch + "> not found");
testExitValue++;
return false;
}