From ef34d898410f90252274df515f7e003e2d9a92f3 Mon Sep 17 00:00:00 2001 From: Yuka Kamiya Date: Thu, 2 Oct 2008 15:54:59 +0900 Subject: [PATCH 01/44] 6645263: (cal) Calendar throw java.lang.IllegalArgumentException: WEEK_OF_MONTH Reviewed-by: okutsu --- jdk/src/share/classes/java/util/Calendar.java | 4 +- jdk/test/java/util/Calendar/Bug6645263.java | 47 +++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 jdk/test/java/util/Calendar/Bug6645263.java diff --git a/jdk/src/share/classes/java/util/Calendar.java b/jdk/src/share/classes/java/util/Calendar.java index e1f65e6a885..7fa8296433c 100644 --- a/jdk/src/share/classes/java/util/Calendar.java +++ b/jdk/src/share/classes/java/util/Calendar.java @@ -1190,7 +1190,9 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable Date: Fri, 3 Oct 2008 15:54:41 +0900 Subject: [PATCH 02/44] 6683975: [fmt-da] Regression: Java 6 returns English DateFormatPatterns for Thai locale Reviewed-by: okutsu --- .../sun/text/resources/FormatData_th.java | 29 +++-- .../text/Format/DateFormat/Bug6683975.java | 114 ++++++++++++++++++ 2 files changed, 131 insertions(+), 12 deletions(-) create mode 100644 jdk/test/java/text/Format/DateFormat/Bug6683975.java diff --git a/jdk/src/share/classes/sun/text/resources/FormatData_th.java b/jdk/src/share/classes/sun/text/resources/FormatData_th.java index 18e1da8ffbb..e1fe418f597 100644 --- a/jdk/src/share/classes/sun/text/resources/FormatData_th.java +++ b/jdk/src/share/classes/sun/text/resources/FormatData_th.java @@ -47,6 +47,19 @@ public class FormatData_th extends ListResourceBundle { * Overrides ListResourceBundle */ protected final Object[][] getContents() { + String[] dateTimePatterns = new String[] { + "H' \u0e19\u0e32\u0e2c\u0e34\u0e01\u0e32 'm' \u0e19\u0e32\u0e17\u0e35 'ss' \u0e27\u0e34\u0e19\u0e32\u0e17\u0e35'", // full time pattern + "H' \u0e19\u0e32\u0e2c\u0e34\u0e01\u0e32 'm' \u0e19\u0e32\u0e17\u0e35'", // long time pattern + "H:mm:ss", // medium time pattern + "H:mm' \u0e19.'", // short time pattern (modified) -- add ' \u0e19.' + // (it means something like "o'clock" in english) + "EEEE'\u0e17\u0e35\u0e48 'd MMMM G yyyy", // full date pattern + "d MMMM yyyy", // long date pattern + "d MMM yyyy", // medium date pattern + "d/M/yyyy", // short date pattern + "{1}, {0}" // date-time pattern + }; + return new Object[][] { { "MonthNames", new String[] { @@ -129,18 +142,10 @@ public class FormatData_th extends ListResourceBundle { } }, { "sun.util.BuddhistCalendar.DateTimePatterns", - new String[] { - "H' \u0e19\u0e32\u0e2c\u0e34\u0e01\u0e32 'm' \u0e19\u0e32\u0e17\u0e35 'ss' \u0e27\u0e34\u0e19\u0e32\u0e17\u0e35'", // full time pattern - "H' \u0e19\u0e32\u0e2c\u0e34\u0e01\u0e32 'm' \u0e19\u0e32\u0e17\u0e35'", // long time pattern - "H:mm:ss", // medium time pattern - "H:mm' \u0e19.'", // short time pattern (modified) -- add ' \u0e19.' - // (it means something like "o'clock" in english) - "EEEE'\u0e17\u0e35\u0e48 'd MMMM G yyyy", // full date pattern - "d MMMM yyyy", // long date pattern - "d MMM yyyy", // medium date pattern - "d/M/yyyy", // short date pattern - "{1}, {0}" // date-time pattern - } + dateTimePatterns + }, + { "DateTimePatterns", + dateTimePatterns }, { "DateTimePatternChars", "GanjkHmsSEDFwWxhKzZ" }, }; diff --git a/jdk/test/java/text/Format/DateFormat/Bug6683975.java b/jdk/test/java/text/Format/DateFormat/Bug6683975.java new file mode 100644 index 00000000000..1f497881a29 --- /dev/null +++ b/jdk/test/java/text/Format/DateFormat/Bug6683975.java @@ -0,0 +1,114 @@ +/* + * Copyright 2008 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 6683975 + * @summary Make sure that date is formatted correctlyin th locale. + */ +import java.text.*; +import java.util.*; + +public class Bug6683975 { + + private static boolean err = false; + + private static Locale th = new Locale("th", ""); + private static Locale th_TH = new Locale("th", "TH"); + private static Date date = new Date(2008-1900, Calendar.OCTOBER, 1, 0, 0, 0); + private static String expected_th[] = { + "\u0e27\u0e31\u0e19\u0e2d\u0e31\u0e07\u0e04\u0e32\u0e23\u0e17\u0e35\u0e48 30 \u0e01\u0e31\u0e19\u0e22\u0e32\u0e22\u0e19 \u0e04.\u0e28. 2008, 8 \u0e19\u0e32\u0e2c\u0e34\u0e01\u0e32 0 \u0e19\u0e32\u0e17\u0e35 00 \u0e27\u0e34\u0e19\u0e32\u0e17\u0e35", // 0: FULL + "30 \u0e01\u0e31\u0e19\u0e22\u0e32\u0e22\u0e19 2008, 8 \u0e19\u0e32\u0e2c\u0e34\u0e01\u0e32 0 \u0e19\u0e32\u0e17\u0e35", // 1: LONG + "30 \u0e01.\u0e22. 2008, 8:00:00", // 2: MEDIUM + "30/9/2008, 8:00 \u0e19.", // 3: SHORT + }; + private static String expected_th_TH[] = { + "\u0e27\u0e31\u0e19\u0e2d\u0e31\u0e07\u0e04\u0e32\u0e23\u0e17\u0e35\u0e48 30 \u0e01\u0e31\u0e19\u0e22\u0e32\u0e22\u0e19 \u0e1e.\u0e28. 2551, 8 \u0e19\u0e32\u0e2c\u0e34\u0e01\u0e32 0 \u0e19\u0e32\u0e17\u0e35 00 \u0e27\u0e34\u0e19\u0e32\u0e17\u0e35", // 0: FULL + "30 \u0e01\u0e31\u0e19\u0e22\u0e32\u0e22\u0e19 2551, 8 \u0e19\u0e32\u0e2c\u0e34\u0e01\u0e32 0 \u0e19\u0e32\u0e17\u0e35", // 1: LONG + "30 \u0e01.\u0e22. 2551, 8:00:00", // 2: MEDIUM + "30/9/2551, 8:00 \u0e19." // 3: SHORT + }; + private static String stylePattern[] = { + "FULL", "LONG", "MEDIUM", "SHORT" + }; + + private static void test(int style) { + DateFormat df_th = DateFormat.getDateTimeInstance(style, style, th); + DateFormat df_th_TH = DateFormat.getDateTimeInstance(style, style, th_TH); + + String str_th = ((SimpleDateFormat)df_th).toPattern(); + String str_th_TH = ((SimpleDateFormat)df_th_TH).toPattern(); + if (!str_th.equals(str_th_TH)) { + err = true; + System.err.println("Error: Pattern for th locale should be the same as pattern for th_TH locale. (" + stylePattern[style] + ")"); + System.err.println("\tth: " + str_th); + System.err.println("\tth_TH: " + str_th_TH); + } + + str_th = df_th.format(date); + if (!expected_th[style].equals(str_th)) { + err = true; + System.err.println("Error: Formatted date in th locale is incorrect in " + stylePattern[style] + " pattern."); + System.err.println("\tExpected: " + expected_th[style]); + System.err.println("\tGot: " + str_th); + } + + str_th_TH = df_th_TH.format(date); + if (!expected_th_TH[style].equals(str_th_TH)) { + err = true; + System.err.println("Error: Formatted date in th_TH locale is incorrect in " + stylePattern[style] + " pattern."); + System.err.println("\tExpected: " + expected_th_TH[style]); + System.err.println("\tGot: " + str_th_TH); + } + } + + public static void main(String[] args) { + TimeZone timezone = TimeZone.getDefault(); + Locale locale = Locale.getDefault(); + + TimeZone.setDefault(TimeZone.getTimeZone("US/Pacific")); + Locale.setDefault(Locale.US); + + try { + test(DateFormat.FULL); + test(DateFormat.LONG); + test(DateFormat.MEDIUM); + test(DateFormat.SHORT); + } + catch (Exception e) { + err = true; + System.err.println("Unexpected exception was thrown: " + e); + } + finally { + TimeZone.setDefault(timezone); + Locale.setDefault(locale); + + if (err) { + throw new RuntimeException("Failed."); + } else { + System.out.println("Passed."); + } + } + } + +} From c7f7759bdd7718ca83586e1bc868e814a7337f86 Mon Sep 17 00:00:00 2001 From: Naoto Sato Date: Mon, 6 Oct 2008 17:16:06 -0700 Subject: [PATCH 03/44] 6706382: jdk/test/java/util/Locale/data/deflocale.sol10 has incorrect legal notice Reviewed-by: okutsu --- jdk/test/java/util/Locale/data/deflocale.sol10 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jdk/test/java/util/Locale/data/deflocale.sol10 b/jdk/test/java/util/Locale/data/deflocale.sol10 index f79d413663d..712a1e159ec 100644 --- a/jdk/test/java/util/Locale/data/deflocale.sol10 +++ b/jdk/test/java/util/Locale/data/deflocale.sol10 @@ -1,7 +1,7 @@ Solaris 10 3/05 s10_74L2a SPARC - Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. - Use is subject to license terms. - Assembled 22 January 2005 + + (copyright from `uname -a` goes here) + SunOS deltas4 5.10 Generic_118833-03 sun4u sparc SUNW,Sun-Blade-2500 OS Locale: C From 671a2de6c7b6f8022815e0c612803e95f3c4d839 Mon Sep 17 00:00:00 2001 From: Yuka Kamiya Date: Tue, 7 Oct 2008 18:25:59 +0900 Subject: [PATCH 04/44] 6756569: (tz) Support tzdata2008g Reviewed-by: okutsu --- jdk/make/sun/javazic/tzdata/VERSION | 2 +- jdk/make/sun/javazic/tzdata/africa | 38 +++++++++++- jdk/make/sun/javazic/tzdata/asia | 35 ++++++++++- jdk/make/sun/javazic/tzdata/europe | 21 +++++++ jdk/make/sun/javazic/tzdata/southamerica | 75 ++++++++++++++++++++++-- 5 files changed, 160 insertions(+), 11 deletions(-) diff --git a/jdk/make/sun/javazic/tzdata/VERSION b/jdk/make/sun/javazic/tzdata/VERSION index 2f4f9df808f..6aef31bbb8e 100644 --- a/jdk/make/sun/javazic/tzdata/VERSION +++ b/jdk/make/sun/javazic/tzdata/VERSION @@ -21,4 +21,4 @@ # CA 95054 USA or visit www.sun.com if you need additional information or # have any questions. # -tzdata2008e +tzdata2008g diff --git a/jdk/make/sun/javazic/tzdata/africa b/jdk/make/sun/javazic/tzdata/africa index 8141f080997..bc673bdd93b 100644 --- a/jdk/make/sun/javazic/tzdata/africa +++ b/jdk/make/sun/javazic/tzdata/africa @@ -458,11 +458,28 @@ Zone Africa/Nouakchott -1:03:48 - LMT 1912 # http://www.worldtimezone.com/dst_news/dst_news_mauritius02.html # +# From Riad M. Hossen Ally (2008-08-03): +# The Government of Mauritius weblink +# +# http://www.gov.mu/portal/site/pmosite/menuitem.4ca0efdee47462e7440a600248a521ca/?content_id=3D4728ca68b2a5b110VgnVCM1000000a04a8c0RCRD +# +# Cabinet Decision of July 18th, 2008 states as follows: +# +# 4. ...Cabinet has agreed to the introduction into the National Assembly +# of the Time Bill which provides for the introduction of summer time in +# Mauritius. The summer time period which will be of one hour ahead of +# the standard time, will be aligned with that in Europe and the United +# States of America. It will start at two o'clock in the morning on the +# last Sunday of October and will end at two o'clock in the morning on +# the last Sunday of March the following year. The summer time for the +# year 2008 - 2009 will, therefore, be effective as from 26 October 2008 +# and end on 29 March 2009. + # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule Mauritius 1982 only - Oct 10 0:00 1:00 S Rule Mauritius 1983 only - Mar 21 0:00 0 - -Rule Mauritius 2008 only - Oct 26 2:00s 1:00 S -Rule Mauritius 2009 only - Mar 27 2:00s 0 - +Rule Mauritius 2008 max - Oct lastSun 2:00 1:00 S +Rule Mauritius 2009 max - Mar lastSun 2:00 0 - # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Indian/Mauritius 3:50:00 - LMT 1907 # Port Louis 4:00 Mauritius MU%sT # Mauritius Time @@ -547,7 +564,22 @@ Zone Indian/Mayotte 3:00:56 - LMT 1911 Jul # Mamoutzou # From Arthur David Olson (2008-05-09): # XXX--guess that it is only Morocco for now; guess only 2008 for now. +# From Steffen Thorsen (2008-08-27): +# Morocco will change the clocks back on the midnight between August 31 +# and September 1. They originally planned to observe DST to near the end +# of September: +# +# One article about it (in French): +# +# http://www.menara.ma/fr/Actualites/Maroc/Societe/ci.retour_a_l_heure_gmt_a_partir_du_dimanche_31_aout_a_minuit_officiel_.default +# +# +# We have some further details posted here: +# +# http://www.timeanddate.com/news/time/morocco-ends-dst-early-2008.html +# # RULE NAME FROM TO TYPE IN ON AT SAVE LETTER/S + Rule Morocco 1939 only - Sep 12 0:00 1:00 S Rule Morocco 1939 only - Nov 19 0:00 0 - Rule Morocco 1940 only - Feb 25 0:00 1:00 S @@ -564,7 +596,7 @@ Rule Morocco 1977 only - Sep 28 0:00 0 - Rule Morocco 1978 only - Jun 1 0:00 1:00 S Rule Morocco 1978 only - Aug 4 0:00 0 - Rule Morocco 2008 only - Jun 1 0:00 1:00 S -Rule Morocco 2008 only - Sep 28 0:00 0 - +Rule Morocco 2008 only - Sep 1 0:00 0 - # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Africa/Casablanca -0:30:20 - LMT 1913 Oct 26 0:00 Morocco WE%sT 1984 Mar 16 diff --git a/jdk/make/sun/javazic/tzdata/asia b/jdk/make/sun/javazic/tzdata/asia index be581970001..5e77028dafa 100644 --- a/jdk/make/sun/javazic/tzdata/asia +++ b/jdk/make/sun/javazic/tzdata/asia @@ -1563,11 +1563,24 @@ Zone Asia/Muscat 3:54:20 - LMT 1920 # From Arthur David Olson (2008-05-19): # XXX--midnight transitions is a guess; 2008 only is a guess. +# From Alexander Krivenyshev (2008-08-28): +# Pakistan government has decided to keep the watches one-hour advanced +# for another 2 months--plan to return to Standard Time on October 31 +# instead of August 31. +# +# +# http://www.worldtimezone.com/dst_news/dst_news_pakistan02.html +# +# OR +# +# http://dailymailnews.com/200808/28/news/dmbrn03.html +# + # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule Pakistan 2002 only - Apr Sun>=2 0:01 1:00 S Rule Pakistan 2002 only - Oct Sun>=2 0:01 0 - Rule Pakistan 2008 only - Jun 1 0:00 1:00 S -Rule Pakistan 2008 only - Sep 1 0:00 0 - +Rule Pakistan 2008 only - Nov 1 0:00 0 - # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Asia/Karachi 4:28:12 - LMT 1907 5:30 - IST 1942 Sep @@ -1687,6 +1700,23 @@ Zone Asia/Karachi 4:28:12 - LMT 1907 # For lack of better information, predict that future changes will be # the 2nd Thursday of September at 02:00. +# From Alexander Krivenyshev (2008-08-28): +# Here is an article, that Mideast running on different clocks at Ramadan. +# +# Gaza Strip (as Egypt) ended DST at midnight Thursday (Aug 28, 2008), while +# the West Bank will end Daylight Saving Time at midnight Sunday (Aug 31, 2008). +# +# +# http://www.guardian.co.uk/world/feedarticle/7759001 +# +# +# http://www.abcnews.go.com/International/wireStory?id=5676087 +# +# or +# +# http://www.worldtimezone.com/dst_news/dst_news_gazastrip01.html +# + # The rules for Egypt are stolen from the `africa' file. # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule EgyptAsia 1957 only - May 10 0:00 1:00 S @@ -1702,7 +1732,8 @@ Rule Palestine 2004 only - Oct 1 1:00 0 - Rule Palestine 2005 only - Oct 4 2:00 0 - Rule Palestine 2006 max - Apr 1 0:00 1:00 S Rule Palestine 2006 only - Sep 22 0:00 0 - -Rule Palestine 2007 max - Sep Thu>=8 2:00 0 - +Rule Palestine 2007 only - Sep Thu>=8 2:00 0 - +Rule Palestine 2008 max - Aug lastThu 2:00 0 - # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Asia/Gaza 2:17:52 - LMT 1900 Oct diff --git a/jdk/make/sun/javazic/tzdata/europe b/jdk/make/sun/javazic/tzdata/europe index 30724328383..27f198649ba 100644 --- a/jdk/make/sun/javazic/tzdata/europe +++ b/jdk/make/sun/javazic/tzdata/europe @@ -2375,6 +2375,27 @@ Zone Europe/Zurich 0:34:08 - LMT 1848 Sep 12 # (on a non-government server though) describing dates between 2002 and 2006: # http://www.alomaliye.com/bkk_2002_3769.htm +# From Sue Williams (2008-08-11): +# I spotted this news article about a potential change in Turkey. +# +# +# http://www.hurriyet.com.tr/english/domestic/9626174.asp?scr=1 +# + +# From Sue Williams (2008-08-20): +# This article says that around the end of March 2011, Turkey wants to +# adjust the clocks forward by 1/2 hour and stay that way permanently. +# The article indicates that this is a change in timezone offset in addition +# to stopping observance of DST. +# This proposal has not yet been approved. +# +# Read more here... +# +# Turkey to abandon daylight saving time in 2011 +# +# http://www.turkishdailynews.com.tr/article.php?enewsid=112989 +# + # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule Turkey 1916 only - May 1 0:00 1:00 S Rule Turkey 1916 only - Oct 1 0:00 0 - diff --git a/jdk/make/sun/javazic/tzdata/southamerica b/jdk/make/sun/javazic/tzdata/southamerica index 06a8d130e39..ab558df75b9 100644 --- a/jdk/make/sun/javazic/tzdata/southamerica +++ b/jdk/make/sun/javazic/tzdata/southamerica @@ -186,9 +186,22 @@ Rule Arg 2000 only - Mar 3 0:00 0 - # From Paul Eggert (2007-12-22): # For dates after mid-2008, the following rules are my guesses and # are quite possibly wrong, but are more likely than no DST at all. + +# From Alexander Krivenyshev (2008-09-05): +# As per message from Carlos Alberto Fonseca Arauz (Nicaragua), +# Argentina will start DST on Sunday October 19, 2008. +# +# +# http://www.worldtimezone.com/dst_news/dst_news_argentina03.html +# +# OR +# +# http://www.impulsobaires.com.ar/nota.php?id=57832 (in spanish) +# + Rule Arg 2007 only - Dec 30 0:00 1:00 S Rule Arg 2008 max - Mar Sun>=15 0:00 0 - -Rule Arg 2008 max - Oct Sun>=1 0:00 1:00 S +Rule Arg 2008 max - Oct Sun>=15 0:00 1:00 S # From Mariano Absatz (2004-05-21): # Today it was officially published that the Province of Mendoza is changing @@ -613,6 +626,36 @@ Zone America/La_Paz -4:32:36 - LMT 1890 # Decretos sobre o Horario de Verao no Brasil # . +# From Steffen Thorsen (2008-08-29): +# As announced by the government and many newspapers in Brazil late +# yesterday, Brazil will start DST on 2008-10-19 (need to change rule) and +# it will end on 2009-02-15 (current rule for Brazil is fine). Based on +# past years experience with the elections, there was a good chance that +# the start was postponed to November, but it did not happen this year. +# +# It has not yet been posted to http://pcdsh01.on.br/DecHV.html +# +# An official page about it: +# +# http://www.mme.gov.br/site/news/detail.do?newsId=16722 +# +# Note that this link does not always work directly, but must be accessed +# by going to +# +# http://www.mme.gov.br/first +# +# +# One example link that works directly: +# +# http://jornale.com.br/index.php?option=com_content&task=view&id=13530&Itemid=54 +# (Portuguese) +# +# +# We have a written a short article about it as well: +# +# http://www.timeanddate.com/news/time/brazil-dst-2008-2009.html +# + # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S # Decree 20,466 (1931-10-01) # Decree 21,896 (1932-01-10) @@ -746,12 +789,34 @@ Rule Brazil 2006 only - Nov 5 0:00 1:00 S Rule Brazil 2007 only - Feb 25 0:00 0 - # Decree 6,212 (2007-09-26), # adopted by the same states as before. -Rule Brazil 2007 max - Oct Sun>=8 0:00 1:00 S -Rule Brazil 2008 max - Feb Sun>=15 0:00 0 - +Rule Brazil 2007 only - Oct Sun>=8 0:00 1:00 S +# From Frederico A. C. Neves (2008-09-10): +# Acording to this decree +# +# http://www.planalto.gov.br/ccivil_03/_Ato2007-2010/2008/Decreto/D6558.htm +# +# [t]he DST period in Brazil now on will be from the 3rd Oct Sunday to the +# 3rd Feb Sunday. There is an exception on the return date when this is +# the Carnival Sunday then the return date will be the next Sunday... +Rule Brazil 2008 max - Oct Sun>=15 0:00 1:00 S +Rule Brazil 2008 2011 - Feb Sun>=15 0:00 0 - +Rule Brazil 2012 only - Feb Sun>=22 0:00 0 - +Rule Brazil 2013 2014 - Feb Sun>=15 0:00 0 - +Rule Brazil 2015 only - Feb Sun>=22 0:00 0 - +Rule Brazil 2016 2022 - Feb Sun>=15 0:00 0 - +Rule Brazil 2023 only - Feb Sun>=22 0:00 0 - +Rule Brazil 2024 2025 - Feb Sun>=15 0:00 0 - +Rule Brazil 2026 only - Feb Sun>=22 0:00 0 - +Rule Brazil 2027 2033 - Feb Sun>=15 0:00 0 - +Rule Brazil 2034 only - Feb Sun>=22 0:00 0 - +Rule Brazil 2035 2036 - Feb Sun>=15 0:00 0 - +Rule Brazil 2037 only - Feb Sun>=22 0:00 0 - +# From Arthur David Olson (2008-09-29): +# The next is wrong in some years but is better than nothing. +Rule Brazil 2038 max - Feb Sun>=15 0:00 0 - + # The latest ruleset listed above says that the following states observe DST: # DF, ES, GO, MG, MS, MT, PR, RJ, RS, SC, SP. -# For dates after mid-2008, the above rules with TO="max" are guesses -# and are quite possibly wrong, but are more likely than no DST at all. # Zone NAME GMTOFF RULES FORMAT [UNTIL] # From 5c08fa0e797d5dac5eb7389d94ec98733a1b35cd Mon Sep 17 00:00:00 2001 From: Roman Kennke Date: Wed, 15 Oct 2008 15:55:19 +0200 Subject: [PATCH 05/44] 6759311: RepaintManager casts Tookit to SunToolkit without instanceof check Check type of Toolkit before casting. Reviewed-by: alexp --- .../classes/javax/swing/RepaintManager.java | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/jdk/src/share/classes/javax/swing/RepaintManager.java b/jdk/src/share/classes/javax/swing/RepaintManager.java index b0e6c048f62..981ea1fe8d5 100644 --- a/jdk/src/share/classes/javax/swing/RepaintManager.java +++ b/jdk/src/share/classes/javax/swing/RepaintManager.java @@ -1305,9 +1305,12 @@ public class RepaintManager if (doubleBufferingEnabled && !nativeDoubleBuffering) { switch (bufferStrategyType) { case BUFFER_STRATEGY_NOT_SPECIFIED: - if (((SunToolkit)Toolkit.getDefaultToolkit()). - useBufferPerWindow()) { - paintManager = new BufferStrategyPaintManager(); + Toolkit tk = Toolkit.getDefaultToolkit(); + if (tk instanceof SunToolkit) { + SunToolkit stk = (SunToolkit) tk; + if (stk.useBufferPerWindow()) { + paintManager = new BufferStrategyPaintManager(); + } } break; case BUFFER_STRATEGY_SPECIFIED_ON: @@ -1329,9 +1332,16 @@ public class RepaintManager private void scheduleProcessingRunnable(AppContext context) { if (processingRunnable.markPending()) { - SunToolkit.getSystemEventQueueImplPP(context). - postEvent(new InvocationEvent(Toolkit.getDefaultToolkit(), - processingRunnable)); + Toolkit tk = Toolkit.getDefaultToolkit(); + if (tk instanceof SunToolkit) { + SunToolkit.getSystemEventQueueImplPP(context). + postEvent(new InvocationEvent(Toolkit.getDefaultToolkit(), + processingRunnable)); + } else { + Toolkit.getDefaultToolkit().getSystemEventQueue(). + postEvent(new InvocationEvent(Toolkit.getDefaultToolkit(), + processingRunnable)); + } } } From 7fb9ea225e61249e84b155ebc3e8918638547472 Mon Sep 17 00:00:00 2001 From: Yuka Kamiya Date: Thu, 16 Oct 2008 14:00:58 +0900 Subject: [PATCH 06/44] 6758988: (tz) Support tzdata2008h Reviewed-by: okutsu --- jdk/make/sun/javazic/tzdata/VERSION | 2 +- jdk/make/sun/javazic/tzdata/africa | 12 ++++++++++-- jdk/make/sun/javazic/tzdata/asia | 14 +++++++++++++- jdk/make/sun/javazic/tzdata/southamerica | 16 ++++++++++++++++ jdk/make/sun/javazic/tzdata/zone.tab | 2 +- 5 files changed, 41 insertions(+), 5 deletions(-) diff --git a/jdk/make/sun/javazic/tzdata/VERSION b/jdk/make/sun/javazic/tzdata/VERSION index 6aef31bbb8e..0d71d62ab79 100644 --- a/jdk/make/sun/javazic/tzdata/VERSION +++ b/jdk/make/sun/javazic/tzdata/VERSION @@ -21,4 +21,4 @@ # CA 95054 USA or visit www.sun.com if you need additional information or # have any questions. # -tzdata2008g +tzdata2008h diff --git a/jdk/make/sun/javazic/tzdata/africa b/jdk/make/sun/javazic/tzdata/africa index bc673bdd93b..52289f12054 100644 --- a/jdk/make/sun/javazic/tzdata/africa +++ b/jdk/make/sun/javazic/tzdata/africa @@ -475,11 +475,19 @@ Zone Africa/Nouakchott -1:03:48 - LMT 1912 # year 2008 - 2009 will, therefore, be effective as from 26 October 2008 # and end on 29 March 2009. +# From Ed Maste (2008-10-07): +# THE TIME BILL (No. XXVII of 2008) Explanatory Memorandum states the +# beginning / ending of summer time is 2 o'clock standard time in the +# morning of the last Sunday of October / last Sunday of March. +# +# http://www.gov.mu/portal/goc/assemblysite/file/bill2708.pdf +# + # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule Mauritius 1982 only - Oct 10 0:00 1:00 S Rule Mauritius 1983 only - Mar 21 0:00 0 - -Rule Mauritius 2008 max - Oct lastSun 2:00 1:00 S -Rule Mauritius 2009 max - Mar lastSun 2:00 0 - +Rule Mauritius 2008 max - Oct lastSun 2:00s 1:00 S +Rule Mauritius 2009 max - Mar lastSun 2:00s 0 - # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Indian/Mauritius 3:50:00 - LMT 1907 # Port Louis 4:00 Mauritius MU%sT # Mauritius Time diff --git a/jdk/make/sun/javazic/tzdata/asia b/jdk/make/sun/javazic/tzdata/asia index 5e77028dafa..b763d0d97d8 100644 --- a/jdk/make/sun/javazic/tzdata/asia +++ b/jdk/make/sun/javazic/tzdata/asia @@ -1979,8 +1979,20 @@ Rule Syria 2007 only - Nov Fri>=1 0:00 0 - # compilers can't handle or having multiple Rules (a la Israel). # For now, use "Apr Fri>=1", and go with IATA on a uniform Sep 30 end. +# From Steffen Thorsen (2008-10-07): +# Syria has now officially decided to end DST on 2008-11-01 this year, +# according to the following article in the Syrian Arab News Agency (SANA). +# +# The article is in Arabic, and seems to tell that they will go back to +# winter time on 2008-11-01 at 00:00 local daylight time (delaying/setting +# clocks back 60 minutes). +# +# +# http://sana.sy/ara/2/2008/10/07/195459.htm +# + Rule Syria 2008 max - Apr Fri>=1 0:00 1:00 S -Rule Syria 2008 max - Oct 1 0:00 0 - +Rule Syria 2008 max - Nov 1 0:00 0 - # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Asia/Damascus 2:25:12 - LMT 1920 # Dimashq diff --git a/jdk/make/sun/javazic/tzdata/southamerica b/jdk/make/sun/javazic/tzdata/southamerica index ab558df75b9..3d37b9deb62 100644 --- a/jdk/make/sun/javazic/tzdata/southamerica +++ b/jdk/make/sun/javazic/tzdata/southamerica @@ -199,6 +199,22 @@ Rule Arg 2000 only - Mar 3 0:00 0 - # http://www.impulsobaires.com.ar/nota.php?id=57832 (in spanish) # +# From Rodrigo Severo (2008-10-06): +# Here is some info available at a Gentoo bug related to TZ on Argentina's DST: +# ... +# ------- Comment #1 from [jmdocile] 2008-10-06 16:28 0000 ------- +# Hi, there is a problem with timezone-data-2008e and maybe with +# timezone-data-2008f +# Argentinian law [Number] 25.155 is no longer valid. +# +# http://www.infoleg.gov.ar/infolegInternet/anexos/60000-64999/60036/norma.htm +# +# The new one is law [Number] 26.350 +# +# http://www.infoleg.gov.ar/infolegInternet/anexos/135000-139999/136191/norma.htm +# +# So there is no summer time in Argentina for now. + Rule Arg 2007 only - Dec 30 0:00 1:00 S Rule Arg 2008 max - Mar Sun>=15 0:00 0 - Rule Arg 2008 max - Oct Sun>=15 0:00 1:00 S diff --git a/jdk/make/sun/javazic/tzdata/zone.tab b/jdk/make/sun/javazic/tzdata/zone.tab index a9c686227ec..a06a008ee3b 100644 --- a/jdk/make/sun/javazic/tzdata/zone.tab +++ b/jdk/make/sun/javazic/tzdata/zone.tab @@ -315,7 +315,7 @@ NL +5222+00454 Europe/Amsterdam NO +5955+01045 Europe/Oslo NP +2743+08519 Asia/Katmandu NR -0031+16655 Pacific/Nauru -NU -1901+16955 Pacific/Niue +NU -1901-16955 Pacific/Niue NZ -3652+17446 Pacific/Auckland most locations NZ -4357-17633 Pacific/Chatham Chatham Islands OM +2336+05835 Asia/Muscat From 3b082d1d69938f1b44fa16b6b4fc97a33c5d78fb Mon Sep 17 00:00:00 2001 From: Yuka Kamiya Date: Fri, 17 Oct 2008 13:34:03 +0900 Subject: [PATCH 07/44] 6759521: Move Bidi test programs from closed to open Reviewed-by: okutsu --- jdk/test/java/text/Bidi/BidiBug.java | 41 ++++++ .../java/text/Bidi/BidiEmbeddingTest.java | 132 ++++++++++++++++++ .../java/text/Bidi/BidiSurrogateTest.java | 103 ++++++++++++++ 3 files changed, 276 insertions(+) create mode 100644 jdk/test/java/text/Bidi/BidiBug.java create mode 100644 jdk/test/java/text/Bidi/BidiEmbeddingTest.java create mode 100644 jdk/test/java/text/Bidi/BidiSurrogateTest.java diff --git a/jdk/test/java/text/Bidi/BidiBug.java b/jdk/test/java/text/Bidi/BidiBug.java new file mode 100644 index 00000000000..36ffcd7e440 --- /dev/null +++ b/jdk/test/java/text/Bidi/BidiBug.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2008 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 4827312 + * @summary verify that argument validity check is not fooled by overflow + */ +public class BidiBug { + public static void main(String[] args) { + try { + byte buff[] = new byte[3000]; + java.text.Bidi bidi = new java.text.Bidi(new char[20],10,buff,Integer.MAX_VALUE-3,4,1); + } + catch (IllegalArgumentException e) { + System.out.println(e); + return; // success + } + throw new RuntimeException("didn't throw error, though we didn't crash either"); + } +} diff --git a/jdk/test/java/text/Bidi/BidiEmbeddingTest.java b/jdk/test/java/text/Bidi/BidiEmbeddingTest.java new file mode 100644 index 00000000000..3e967be351d --- /dev/null +++ b/jdk/test/java/text/Bidi/BidiEmbeddingTest.java @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2008 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 4396492 4396496 4778510 + * @summary verify that the embedding values processed by the bidi code use negative values to + * indicate overrides, rather than using bit 7. Also tests Bidi without loading awt classes to + * confirm that Bidi can be used without awt. Verify that embedding level 0 is properly mapped + * to the base embedding level. + */ + +import java.awt.Color; +import java.awt.Frame; +import java.awt.font.TextAttribute; +import java.text.AttributedString; +import java.text.Bidi; + +public class BidiEmbeddingTest { + public static void main(String[] args) { + // to regress embedding test against old fix, call with an arg. A window will pop + // up causing awt lib to be loaded so the vm won't die with the unsatisfied link error. + if (args.length > 0) { + Frame f = new Frame(); + f.setSize(300, 300); + f.setBackground(Color.white); + f.show(); + } + + test1(); + test2(); + } + + static void test1() { + String target = "BACK WARDS"; + String str = "If this text is >" + target + "< the test passed."; + int start = str.indexOf(target); + int limit = start + target.length(); + + System.out.println("start: " + start + " limit: " + limit); + + AttributedString astr = new AttributedString(str); + astr.addAttribute(TextAttribute.BIDI_EMBEDDING, + new Integer(-1), + start, + limit); + + Bidi bidi = new Bidi(astr.getIterator()); + + for (int i = 0; i < bidi.getRunCount(); ++i) { + System.out.println("run " + i + + " from " + bidi.getRunStart(i) + + " to " + bidi.getRunLimit(i) + + " at level " + bidi.getRunLevel(i)); + } + + System.out.println(bidi); + + byte[] embs = new byte[str.length() + 3]; + for (int i = start + 1; i < limit + 1; ++i) { + embs[i] = -1; + } + + Bidi bidi2 = new Bidi(str.toCharArray(), 0, embs, 1, str.length(), Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT); + for (int i = 0; i < bidi2.getRunCount(); ++i) { + System.out.println("run " + i + + " from " + bidi2.getRunStart(i) + + " to " + bidi2.getRunLimit(i) + + " at level " + bidi2.getRunLevel(i)); + } + + System.out.println(bidi2); + + if (bidi.getRunCount() != 3 || bidi2.getRunCount() != 3) { + throw new Error("Bidi run count incorrect"); + } + } + + // make sure BIDI_EMBEDDING values of 0 are mapped to base run direction, instead of flagging an error. + static void test2() { + String target = "BACK WARDS"; + String str = "If this text is >" + target + "< the test passed."; + int length = str.length(); + int start = str.indexOf(target); + int limit = start + target.length(); + + System.out.println("start: " + start + " limit: " + limit); + + AttributedString astr = new AttributedString(str); + astr.addAttribute(TextAttribute.RUN_DIRECTION, TextAttribute.RUN_DIRECTION_RTL); + + astr.addAttribute(TextAttribute.BIDI_EMBEDDING, + new Integer(-3), + start, + limit); + + Bidi bidi = new Bidi(astr.getIterator()); + + for (int i = 0; i < bidi.getRunCount(); ++i) { + System.out.println("run " + i + + " from " + bidi.getRunStart(i) + + " to " + bidi.getRunLimit(i) + + " at level " + bidi.getRunLevel(i)); + } + + System.out.println(bidi); + + if (bidi.getRunCount() != 6) { // runs of spaces and angles at embedding bound,s and final period, each get level 1 + throw new Error("Bidi embedding processing failed"); + } + } +} diff --git a/jdk/test/java/text/Bidi/BidiSurrogateTest.java b/jdk/test/java/text/Bidi/BidiSurrogateTest.java new file mode 100644 index 00000000000..b24e1a1123f --- /dev/null +++ b/jdk/test/java/text/Bidi/BidiSurrogateTest.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2008 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 4888843 + * @summary verify that surrogate pairs representing codepoints with R or AL directionality + * and correctly recognized and reordered. + */ + +import java.text.Bidi; + +public class BidiSurrogateTest { + private static final String RTLS = new String(Character.toChars(0x10800)); // surrogate code point with R directionality + private static final String LTRS = new String(Character.toChars(0x107ff)); // surrogate code point with L directionality + private static final String LRE = "\u202a"; + private static final String RLE = "\u202b"; + private static final String PDF = "\u202c"; + + + public static void main(String[] args) { + new BidiSurrogateTest().test(); + } + + void test() { + test0(); + test1(); + } + + void test0() { + // test unpaired surrogates - should have L directionality + testRequiresBidi("\ud800", false); // unpaired lead surrogate + testRequiresBidi("\udc00", false); // unpaired trail surrogate + testRequiresBidi("\udc00\ud800", false); // out of order surrogates + testRequiresBidi("a\udc00b\ud800c", false); // out of order surrogates split + testRequiresBidi(LTRS, false); // supplementary with L + testRequiresBidi(RTLS, true); // supplementary with R + testRequiresBidi("a" + RTLS + "b", true); // R supplementary in LTR text + testRequiresBidi(LTRS + RTLS, true); // R supplementary in LTR supplementary text + testRequiresBidi(LRE, false); // LRE lone embedding + testRequiresBidi(RLE, true); // RLE lone embedding + testRequiresBidi(PDF, false); // PDF lone pop embedding + } + + void testRequiresBidi(String string, boolean requiresBidi) { + char[] text = string.toCharArray(); + if (Bidi.requiresBidi(text, 0, text.length) != requiresBidi) { + throw new RuntimeException("testRequiresBidi failed with '" + string + "', " + requiresBidi); + } + } + + void test1() { + // test that strings with surrogate runs process surrogate directionality ok + testBidi("This is a string with " + LTRS + " in it.", false); + testBidi("This is a string with \ud800 in it.", false); + testBidi("This is a string with \u0640 in it.", 22, 1); + testBidi(RTLS, true); + testBidi("This is a string with " + RTLS + RTLS + RTLS + " in it.", 22, 6); + } + + void testBidi(String string, boolean directionIsRTL) { + Bidi bidi = new Bidi(string, Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT); + if (bidi.isMixed()) { + throw new RuntimeException("bidi is mixed"); + } + if (bidi.isRightToLeft() != directionIsRTL) { + throw new RuntimeException("bidi is not " + (directionIsRTL ? "rtl" : "ltr")); + } + } + + void testBidi(String string, int rtlstart, int rtllength) { + Bidi bidi = new Bidi(string, Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT); + for (int i = 0; i < bidi.getRunCount(); ++i) { + if ((bidi.getRunLevel(i) & 1) != 0) { + if (bidi.getRunStart(i) != rtlstart || + bidi.getRunLimit(i) != rtlstart + rtllength) { + throw new RuntimeException("first rtl run didn't match " + rtlstart + ", " + rtllength); + } + break; + } + } + } +} From 1bff9286d7d745513040c17bcfc19a406d75525d Mon Sep 17 00:00:00 2001 From: Yuka Kamiya Date: Thu, 30 Oct 2008 13:12:54 +0900 Subject: [PATCH 08/44] 6764308: (tz) Support tzdata2008i Reviewed-by: okutsu --- jdk/make/sun/javazic/tzdata/VERSION | 2 +- jdk/make/sun/javazic/tzdata/southamerica | 58 +++++++++++++++---- jdk/make/sun/javazic/tzdata/zone.tab | 9 +-- .../sun/util/resources/TimeZoneNames.java | 1 + .../sun/util/resources/TimeZoneNames_de.java | 1 + .../sun/util/resources/TimeZoneNames_es.java | 1 + .../sun/util/resources/TimeZoneNames_fr.java | 1 + .../sun/util/resources/TimeZoneNames_it.java | 1 + .../sun/util/resources/TimeZoneNames_ja.java | 1 + .../sun/util/resources/TimeZoneNames_ko.java | 1 + .../sun/util/resources/TimeZoneNames_sv.java | 1 + .../util/resources/TimeZoneNames_zh_CN.java | 1 + .../util/resources/TimeZoneNames_zh_TW.java | 1 + 13 files changed, 64 insertions(+), 15 deletions(-) diff --git a/jdk/make/sun/javazic/tzdata/VERSION b/jdk/make/sun/javazic/tzdata/VERSION index 0d71d62ab79..d242b2d1da9 100644 --- a/jdk/make/sun/javazic/tzdata/VERSION +++ b/jdk/make/sun/javazic/tzdata/VERSION @@ -21,4 +21,4 @@ # CA 95054 USA or visit www.sun.com if you need additional information or # have any questions. # -tzdata2008h +tzdata2008i diff --git a/jdk/make/sun/javazic/tzdata/southamerica b/jdk/make/sun/javazic/tzdata/southamerica index 3d37b9deb62..6c82a557a70 100644 --- a/jdk/make/sun/javazic/tzdata/southamerica +++ b/jdk/make/sun/javazic/tzdata/southamerica @@ -215,6 +215,26 @@ Rule Arg 2000 only - Mar 3 0:00 0 - # # So there is no summer time in Argentina for now. +# From Mariano Absatz (2008-10-20): +# Decree 1693/2008 applies Law 26.350 for the summer 2008/2009 establishing DST in Argentina +# From 2008-10-19 until 2009-03-15 +# +# http://www.boletinoficial.gov.ar/Bora.Portal/CustomControls/PdfContent.aspx?fp=16102008&pi=3&pf=4&s=0&sec=01 +# +# +# Decree 1705/2008 excepting 12 Provinces from applying DST in the summer 2008/2009: +# Catamarca, La Rioja, Mendoza, Salta, San Juan, San Luis, La Pampa, Neuquen, Rio Negro, Chubut, Santa Cruz +# and Tierra del Fuego +# +# http://www.boletinoficial.gov.ar/Bora.Portal/CustomControls/PdfContent.aspx?fp=17102008&pi=1&pf=1&s=0&sec=01 +# +# +# Press release 235 dated Saturday October 18th, from the Government of the Province of Jujuy saying +# it will not apply DST either (even when it was not included in Decree 1705/2008) +# +# http://www.jujuy.gov.ar/index2/partes_prensa/18_10_08/235-181008.doc +# + Rule Arg 2007 only - Dec 30 0:00 1:00 S Rule Arg 2008 max - Mar Sun>=15 0:00 0 - Rule Arg 2008 max - Oct Sun>=15 0:00 1:00 S @@ -365,9 +385,8 @@ Zone America/Argentina/Buenos_Aires -3:53:48 - LMT 1894 Oct 31 -4:00 Arg AR%sT 2000 Mar 3 -3:00 Arg AR%sT # -# Santa Fe (SF), Entre Rios (ER), Corrientes (CN), Misiones (MN), Chaco (CC), -# Formosa (FM), Salta (SA), Santiago del Estero (SE), Cordoba (CB), -# La Pampa (LP), Neuquen (NQ), Rio Negro (RN) +# Cordoba (CB), Santa Fe (SF), Entre Rios (ER), Corrientes (CN), Misiones (MN), +# Chaco (CC), Formosa (FM), Santiago del Estero (SE) # # Shanks & Pottenger also make the following claims, which we haven't verified: # - Formosa switched to -3:00 on 1991-01-07. @@ -386,6 +405,18 @@ Zone America/Argentina/Cordoba -4:16:48 - LMT 1894 Oct 31 -4:00 Arg AR%sT 2000 Mar 3 -3:00 Arg AR%sT # +# Salta (SA), La Pampa (LP), Neuquen (NQ), Rio Negro (RN) +Zone America/Argentina/Salta -4:21:40 - LMT 1894 Oct 31 + -4:16:48 - CMT 1920 May + -4:00 - ART 1930 Dec + -4:00 Arg AR%sT 1969 Oct 5 + -3:00 Arg AR%sT 1991 Mar 3 + -4:00 - WART 1991 Oct 20 + -3:00 Arg AR%sT 1999 Oct 3 + -4:00 Arg AR%sT 2000 Mar 3 + -3:00 Arg AR%sT 2008 Oct 18 + -3:00 - ART +# # Tucuman (TM) Zone America/Argentina/Tucuman -4:20:52 - LMT 1894 Oct 31 -4:16:48 - CMT 1920 May @@ -410,7 +441,8 @@ Zone America/Argentina/La_Rioja -4:27:24 - LMT 1894 Oct 31 -4:00 Arg AR%sT 2000 Mar 3 -3:00 - ART 2004 Jun 1 -4:00 - WART 2004 Jun 20 - -3:00 Arg AR%sT + -3:00 Arg AR%sT 2008 Oct 18 + -3:00 - ART # # San Juan (SJ) Zone America/Argentina/San_Juan -4:34:04 - LMT 1894 Oct 31 @@ -423,7 +455,8 @@ Zone America/Argentina/San_Juan -4:34:04 - LMT 1894 Oct 31 -4:00 Arg AR%sT 2000 Mar 3 -3:00 - ART 2004 May 31 -4:00 - WART 2004 Jul 25 - -3:00 Arg AR%sT + -3:00 Arg AR%sT 2008 Oct 18 + -3:00 - ART # # Jujuy (JY) Zone America/Argentina/Jujuy -4:21:12 - LMT 1894 Oct 31 @@ -437,7 +470,8 @@ Zone America/Argentina/Jujuy -4:21:12 - LMT 1894 Oct 31 -3:00 1:00 ARST 1992 -3:00 Arg AR%sT 1999 Oct 3 -4:00 Arg AR%sT 2000 Mar 3 - -3:00 Arg AR%sT + -3:00 Arg AR%sT 2008 Oct 18 + -3:00 - ART # # Catamarca (CT), Chubut (CH) Zone America/Argentina/Catamarca -4:23:08 - LMT 1894 Oct 31 @@ -450,7 +484,8 @@ Zone America/Argentina/Catamarca -4:23:08 - LMT 1894 Oct 31 -4:00 Arg AR%sT 2000 Mar 3 -3:00 - ART 2004 Jun 1 -4:00 - WART 2004 Jun 20 - -3:00 Arg AR%sT + -3:00 Arg AR%sT 2008 Oct 18 + -3:00 - ART # # Mendoza (MZ) Zone America/Argentina/Mendoza -4:35:16 - LMT 1894 Oct 31 @@ -467,7 +502,8 @@ Zone America/Argentina/Mendoza -4:35:16 - LMT 1894 Oct 31 -4:00 Arg AR%sT 2000 Mar 3 -3:00 - ART 2004 May 23 -4:00 - WART 2004 Sep 26 - -3:00 Arg AR%sT + -3:00 Arg AR%sT 2008 Oct 18 + -3:00 - ART # # San Luis (SL) Zone America/Argentina/San_Luis -4:25:24 - LMT 1894 Oct 31 @@ -495,7 +531,8 @@ Zone America/Argentina/Rio_Gallegos -4:36:52 - LMT 1894 Oct 31 -4:00 Arg AR%sT 2000 Mar 3 -3:00 - ART 2004 Jun 1 -4:00 - WART 2004 Jun 20 - -3:00 Arg AR%sT + -3:00 Arg AR%sT 2008 Oct 18 + -3:00 - ART # # Tierra del Fuego, Antartida e Islas del Atlantico Sur (TF) Zone America/Argentina/Ushuaia -4:33:12 - LMT 1894 Oct 31 @@ -506,7 +543,8 @@ Zone America/Argentina/Ushuaia -4:33:12 - LMT 1894 Oct 31 -4:00 Arg AR%sT 2000 Mar 3 -3:00 - ART 2004 May 30 -4:00 - WART 2004 Jun 20 - -3:00 Arg AR%sT + -3:00 Arg AR%sT 2008 Oct 18 + -3:00 - ART # Aruba # Zone NAME GMTOFF RULES FORMAT [UNTIL] diff --git a/jdk/make/sun/javazic/tzdata/zone.tab b/jdk/make/sun/javazic/tzdata/zone.tab index a06a008ee3b..305da58d372 100644 --- a/jdk/make/sun/javazic/tzdata/zone.tab +++ b/jdk/make/sun/javazic/tzdata/zone.tab @@ -64,14 +64,15 @@ AQ -7824+10654 Antarctica/Vostok Vostok Station, S Magnetic Pole AQ -6640+14001 Antarctica/DumontDUrville Dumont-d'Urville Station, Terre Adelie AQ -690022+0393524 Antarctica/Syowa Syowa Station, E Ongul I AR -3436-05827 America/Argentina/Buenos_Aires Buenos Aires (BA, CF) -AR -3124-06411 America/Argentina/Cordoba most locations (CB, CC, CN, ER, FM, LP, MN, NQ, RN, SA, SE, SF) -AR -3319-06621 America/Argentina/San_Luis San Luis (SL) +AR -3124-06411 America/Argentina/Cordoba most locations (CB, CC, CN, ER, FM, MN, SE, SF) +AR -2447-06525 America/Argentina/Salta (SA, LP, NQ, RN) AR -2411-06518 America/Argentina/Jujuy Jujuy (JY) AR -2649-06513 America/Argentina/Tucuman Tucuman (TM) AR -2828-06547 America/Argentina/Catamarca Catamarca (CT), Chubut (CH) AR -2926-06651 America/Argentina/La_Rioja La Rioja (LR) AR -3132-06831 America/Argentina/San_Juan San Juan (SJ) AR -3253-06849 America/Argentina/Mendoza Mendoza (MZ) +AR -3319-06621 America/Argentina/San_Luis San Luis (SL) AR -5138-06913 America/Argentina/Rio_Gallegos Santa Cruz (SC) AR -5448-06818 America/Argentina/Ushuaia Tierra del Fuego (TF) AS -1416-17042 Pacific/Pago_Pago @@ -406,13 +407,13 @@ US +381515-0854534 America/Kentucky/Louisville Eastern Time - Kentucky - Louisvi US +364947-0845057 America/Kentucky/Monticello Eastern Time - Kentucky - Wayne County US +394606-0860929 America/Indiana/Indianapolis Eastern Time - Indiana - most locations US +384038-0873143 America/Indiana/Vincennes Eastern Time - Indiana - Daviess, Dubois, Knox & Martin Counties -US +411745-0863730 America/Indiana/Knox Eastern Time - Indiana - Starke County US +410305-0863611 America/Indiana/Winamac Eastern Time - Indiana - Pulaski County US +382232-0862041 America/Indiana/Marengo Eastern Time - Indiana - Crawford County +US +382931-0871643 America/Indiana/Petersburg Eastern Time - Indiana - Pike County US +384452-0850402 America/Indiana/Vevay Eastern Time - Indiana - Switzerland County US +415100-0873900 America/Chicago Central Time US +375711-0864541 America/Indiana/Tell_City Central Time - Indiana - Perry County -US +382931-0871643 America/Indiana/Petersburg Central Time - Indiana - Pike County +US +411745-0863730 America/Indiana/Knox Central Time - Indiana - Starke County US +450628-0873651 America/Menominee Central Time - Michigan - Dickinson, Gogebic, Iron & Menominee Counties US +470659-1011757 America/North_Dakota/Center Central Time - North Dakota - Oliver County US +465042-1012439 America/North_Dakota/New_Salem Central Time - North Dakota - Morton County (except Mandan area) diff --git a/jdk/src/share/classes/sun/util/resources/TimeZoneNames.java b/jdk/src/share/classes/sun/util/resources/TimeZoneNames.java index 6925ba12d5b..458fc79ed0c 100644 --- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames.java +++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames.java @@ -290,6 +290,7 @@ public final class TimeZoneNames extends TimeZoneNamesBundle { {"America/Argentina/La_Rioja", AGT}, {"America/Argentina/Mendoza", AGT}, {"America/Argentina/Rio_Gallegos", AGT}, + {"America/Argentina/Salta", AGT}, {"America/Argentina/San_Juan", AGT}, {"America/Argentina/San_Luis", AGT}, {"America/Argentina/Tucuman", AGT}, diff --git a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_de.java b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_de.java index eed4bbfb37d..88c0cff348f 100644 --- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_de.java +++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_de.java @@ -290,6 +290,7 @@ public final class TimeZoneNames_de extends TimeZoneNamesBundle { {"America/Argentina/La_Rioja", AGT}, {"America/Argentina/Mendoza", AGT}, {"America/Argentina/Rio_Gallegos", AGT}, + {"America/Argentina/Salta", AGT}, {"America/Argentina/San_Juan", AGT}, {"America/Argentina/San_Luis", AGT}, {"America/Argentina/Tucuman", AGT}, diff --git a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_es.java b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_es.java index 27bf6533143..c05ed9317f5 100644 --- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_es.java +++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_es.java @@ -290,6 +290,7 @@ public final class TimeZoneNames_es extends TimeZoneNamesBundle { {"America/Argentina/La_Rioja", AGT}, {"America/Argentina/Mendoza", AGT}, {"America/Argentina/Rio_Gallegos", AGT}, + {"America/Argentina/Salta", AGT}, {"America/Argentina/San_Juan", AGT}, {"America/Argentina/San_Luis", AGT}, {"America/Argentina/Tucuman", AGT}, diff --git a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_fr.java b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_fr.java index e9a3811d1b7..4ce66327638 100644 --- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_fr.java +++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_fr.java @@ -290,6 +290,7 @@ public final class TimeZoneNames_fr extends TimeZoneNamesBundle { {"America/Argentina/La_Rioja", AGT}, {"America/Argentina/Mendoza", AGT}, {"America/Argentina/Rio_Gallegos", AGT}, + {"America/Argentina/Salta", AGT}, {"America/Argentina/San_Juan", AGT}, {"America/Argentina/San_Luis", AGT}, {"America/Argentina/Tucuman", AGT}, diff --git a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_it.java b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_it.java index 8012c36f7e6..3793c135147 100644 --- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_it.java +++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_it.java @@ -290,6 +290,7 @@ public final class TimeZoneNames_it extends TimeZoneNamesBundle { {"America/Argentina/La_Rioja", AGT}, {"America/Argentina/Mendoza", AGT}, {"America/Argentina/Rio_Gallegos", AGT}, + {"America/Argentina/Salta", AGT}, {"America/Argentina/San_Juan", AGT}, {"America/Argentina/San_Luis", AGT}, {"America/Argentina/Tucuman", AGT}, diff --git a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_ja.java b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_ja.java index 33a1913bd52..53b4f394f92 100644 --- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_ja.java +++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_ja.java @@ -290,6 +290,7 @@ public final class TimeZoneNames_ja extends TimeZoneNamesBundle { {"America/Argentina/La_Rioja", AGT}, {"America/Argentina/Mendoza", AGT}, {"America/Argentina/Rio_Gallegos", AGT}, + {"America/Argentina/Salta", AGT}, {"America/Argentina/San_Juan", AGT}, {"America/Argentina/San_Luis", AGT}, {"America/Argentina/Tucuman", AGT}, diff --git a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_ko.java b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_ko.java index 8068237976f..8e3a4ff5232 100644 --- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_ko.java +++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_ko.java @@ -290,6 +290,7 @@ public final class TimeZoneNames_ko extends TimeZoneNamesBundle { {"America/Argentina/La_Rioja", AGT}, {"America/Argentina/Mendoza", AGT}, {"America/Argentina/Rio_Gallegos", AGT}, + {"America/Argentina/Salta", AGT}, {"America/Argentina/San_Juan", AGT}, {"America/Argentina/San_Luis", AGT}, {"America/Argentina/Tucuman", AGT}, diff --git a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_sv.java b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_sv.java index cc872089fe1..253f506417d 100644 --- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_sv.java +++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_sv.java @@ -290,6 +290,7 @@ public final class TimeZoneNames_sv extends TimeZoneNamesBundle { {"America/Argentina/La_Rioja", AGT}, {"America/Argentina/Mendoza", AGT}, {"America/Argentina/Rio_Gallegos", AGT}, + {"America/Argentina/Salta", AGT}, {"America/Argentina/San_Juan", AGT}, {"America/Argentina/San_Luis", AGT}, {"America/Argentina/Tucuman", AGT}, diff --git a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_zh_CN.java b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_zh_CN.java index 62304e98586..d6e9eeaecf3 100644 --- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_zh_CN.java +++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_zh_CN.java @@ -290,6 +290,7 @@ public final class TimeZoneNames_zh_CN extends TimeZoneNamesBundle { {"America/Argentina/La_Rioja", AGT}, {"America/Argentina/Mendoza", AGT}, {"America/Argentina/Rio_Gallegos", AGT}, + {"America/Argentina/Salta", AGT}, {"America/Argentina/San_Juan", AGT}, {"America/Argentina/San_Luis", AGT}, {"America/Argentina/Tucuman", AGT}, diff --git a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_zh_TW.java b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_zh_TW.java index 77f539fe990..97afacdbc73 100644 --- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_zh_TW.java +++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_zh_TW.java @@ -290,6 +290,7 @@ public final class TimeZoneNames_zh_TW extends TimeZoneNamesBundle { {"America/Argentina/La_Rioja", AGT}, {"America/Argentina/Mendoza", AGT}, {"America/Argentina/Rio_Gallegos", AGT}, + {"America/Argentina/Salta", AGT}, {"America/Argentina/San_Juan", AGT}, {"America/Argentina/San_Luis", AGT}, {"America/Argentina/Tucuman", AGT}, From 9487cedae1a415182c11525d90a6a5de4a1a515f Mon Sep 17 00:00:00 2001 From: Pavel Porvatov Date: Mon, 17 Nov 2008 17:36:27 +0300 Subject: [PATCH 09/44] 6771030: Code improvement and warnings removing from the com.sun.java.swing.plaf.gtk package Removed unnecessary castings and other warnings Reviewed-by: malenkov --- .../swing/plaf/gtk/GTKColorChooserPanel.java | 22 ++++++++-------- .../sun/java/swing/plaf/gtk/GTKEngine.java | 4 +-- .../java/swing/plaf/gtk/GTKFileChooserUI.java | 25 +++++++++---------- .../sun/java/swing/plaf/gtk/GTKPainter.java | 2 +- .../com/sun/java/swing/plaf/gtk/Metacity.java | 20 +++++++-------- 5 files changed, 36 insertions(+), 37 deletions(-) diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKColorChooserPanel.java b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKColorChooserPanel.java index c70d889f453..d54839f7e3c 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKColorChooserPanel.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKColorChooserPanel.java @@ -799,9 +799,9 @@ class GTKColorChooserPanel extends AbstractColorChooserPanel implements Graphics g = triangleImage.getGraphics(); g.setColor(new Color(0, 0, 0, 0)); g.fillRect(0, 0, a, a); - g.translate((int)(a / 2), 0); + g.translate(a / 2, 0); paintTriangle(g, triangleSize, getColor()); - g.translate((int)(-a / 2), 0); + g.translate(-a / 2, 0); g.dispose(); g = wheelImage.getGraphics(); @@ -897,7 +897,7 @@ class GTKColorChooserPanel extends AbstractColorChooserPanel implements return false; } // Rotate to origin and and verify x is valid. - int triangleSize = (int)innerR * 3 / 2; + int triangleSize = innerR * 3 / 2; double x1 = Math.cos(angle) * x - Math.sin(angle) * y; double y1 = Math.sin(angle) * x + Math.cos(angle) * y; if (x1 < -(innerR / 2)) { @@ -960,7 +960,7 @@ class GTKColorChooserPanel extends AbstractColorChooserPanel implements */ private void setSaturationAndBrightness(float s, float b) { int innerR = getTriangleCircumscribedRadius(); - int triangleSize = (int)innerR * 3 / 2; + int triangleSize = innerR * 3 / 2; double x = b * triangleSize; double maxY = x * Math.tan(Math.toRadians(30.0)); double y = 2 * maxY * s - maxY; @@ -1156,7 +1156,7 @@ class GTKColorChooserPanel extends AbstractColorChooserPanel implements * @param x X location to get color for * @param y Y location to get color for * @param rad Radius from center of color wheel - * @param integer with red, green and blue components + * @return integer with red, green and blue components */ private int colorWheelLocationToRGB(int x, int y, double rad) { double angle = Math.acos((double)x / rad); @@ -1165,12 +1165,12 @@ class GTKColorChooserPanel extends AbstractColorChooserPanel implements if (angle < PI_3) { if (y < 0) { // FFFF00 - FF0000 - rgb = 0xFF0000 | (int)Math.min(255, + rgb = 0xFF0000 | Math.min(255, (int)(255 * angle / PI_3)) << 8; } else { // FF0000 - FF00FF - rgb = 0xFF0000 | (int)Math.min(255, + rgb = 0xFF0000 | Math.min(255, (int)(255 * angle / PI_3)); } } @@ -1178,12 +1178,12 @@ class GTKColorChooserPanel extends AbstractColorChooserPanel implements angle -= PI_3; if (y < 0) { // 00FF00 - FFFF00 - rgb = 0x00FF00 | (int)Math.max(0, 255 - + rgb = 0x00FF00 | Math.max(0, 255 - (int)(255 * angle / PI_3)) << 16; } else { // FF00FF - 0000FF - rgb = 0x0000FF | (int)Math.max(0, 255 - + rgb = 0x0000FF | Math.max(0, 255 - (int)(255 * angle / PI_3)) << 16; } } @@ -1191,12 +1191,12 @@ class GTKColorChooserPanel extends AbstractColorChooserPanel implements angle -= 2 * PI_3; if (y < 0) { // 00FFFF - 00FF00 - rgb = 0x00FF00 | (int)Math.min(255, + rgb = 0x00FF00 | Math.min(255, (int)(255 * angle / PI_3)); } else { // 0000FF - 00FFFF - rgb = 0x0000FF | (int)Math.min(255, + rgb = 0x0000FF | Math.min(255, (int)(255 * angle / PI_3)) << 8; } } diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKEngine.java b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKEngine.java index 95bf090b645..737e20c2243 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKEngine.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKEngine.java @@ -112,7 +112,7 @@ class GTKEngine { } - private static HashMap regionToWidgetTypeMap; + private static HashMap regionToWidgetTypeMap; private ImageCache cache = new ImageCache(CACHE_SIZE); private int x0, y0, w0, h0; private Graphics graphics; @@ -178,7 +178,7 @@ class GTKEngine { Toolkit.getDefaultToolkit(); // Initialize regionToWidgetTypeMap - regionToWidgetTypeMap = new HashMap(50); + regionToWidgetTypeMap = new HashMap(50); regionToWidgetTypeMap.put(Region.ARROW_BUTTON, new WidgetType[] { WidgetType.SPINNER_ARROW_BUTTON, WidgetType.COMBO_BOX_ARROW_BUTTON, diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKFileChooserUI.java b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKFileChooserUI.java index 8b786da73fb..9ca8fa52b61 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKFileChooserUI.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKFileChooserUI.java @@ -148,7 +148,7 @@ class GTKFileChooserUI extends SynthFileChooserUI { directoryList : fileList; Object[] files = list.getSelectedValues(); int len = files.length; - Vector result = new Vector(len + 1); + Vector result = new Vector(len + 1); // we return all selected file names for (int i = 0; i < len; i++) { @@ -425,16 +425,16 @@ class GTKFileChooserUI extends SynthFileChooserUI { setDirectorySelected(true); setDirectory(((File)objects[0])); } else { - ArrayList fList = new ArrayList(objects.length); - for (int i = 0; i < objects.length; i++) { - File f = (File)objects[i]; + ArrayList fList = new ArrayList(objects.length); + for (Object object : objects) { + File f = (File) object; if ((chooser.isFileSelectionEnabled() && f.isFile()) || (chooser.isDirectorySelectionEnabled() && f.isDirectory())) { fList.add(f); } } if (fList.size() > 0) { - files = (File[])fList.toArray(new File[fList.size()]); + files = fList.toArray(new File[fList.size()]); } setDirectorySelected(false); } @@ -671,9 +671,9 @@ class GTKFileChooserUI extends SynthFileChooserUI { pathFieldLabel.setLabelFor(fileNameTextField); - Set forwardTraversalKeys = fileNameTextField.getFocusTraversalKeys( + Set forwardTraversalKeys = fileNameTextField.getFocusTraversalKeys( KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS); - forwardTraversalKeys = new HashSet(forwardTraversalKeys); + forwardTraversalKeys = new HashSet(forwardTraversalKeys); forwardTraversalKeys.remove(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0)); fileNameTextField.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, forwardTraversalKeys); @@ -895,10 +895,9 @@ class GTKFileChooserUI extends SynthFileChooserUI { private class GTKDirectoryModel extends BasicDirectoryModel { FileSystemView fsv; - private Comparator fileComparator = new Comparator() { - public int compare(Object o, Object o1) { - return fsv.getSystemDisplayName((File) o).compareTo - (fsv.getSystemDisplayName((File) o1)); + private Comparator fileComparator = new Comparator() { + public int compare(File o, File o1) { + return fsv.getSystemDisplayName(o).compareTo(fsv.getSystemDisplayName(o1)); } }; @@ -1352,8 +1351,8 @@ class GTKFileChooserUI extends SynthFileChooserUI { FileFilter currentFilter = getFileChooser().getFileFilter(); boolean found = false; if (currentFilter != null) { - for (int i = 0; i < filters.length; i++) { - if (filters[i] == currentFilter) { + for (FileFilter filter : filters) { + if (filter == currentFilter) { found = true; } } diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKPainter.java b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKPainter.java index 780b01cf6d4..58d61dc909a 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKPainter.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKPainter.java @@ -299,7 +299,7 @@ class GTKPainter extends SynthPainter { // Paint the default indicator GTKStyle style = (GTKStyle)context.getStyle(); if (defaultCapable && !toolButton) { - Insets defaultInsets = (Insets)style.getClassSpecificInsetsValue( + Insets defaultInsets = style.getClassSpecificInsetsValue( context, "default-border", GTKStyle.BUTTON_DEFAULT_BORDER_INSETS); diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/Metacity.java b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/Metacity.java index a3eada90d84..d432bb088ba 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/Metacity.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/Metacity.java @@ -124,7 +124,7 @@ class Metacity implements SynthConstants { } // Initialize constants - variables = new HashMap(); + variables = new HashMap(); NodeList nodes = xmlDoc.getElementsByTagName("constant"); int n = nodes.getLength(); for (int i = 0; i < n; i++) { @@ -144,14 +144,14 @@ class Metacity implements SynthConstants { } // Cache frame geometries - frameGeometries = new HashMap(); + frameGeometries = new HashMap>(); nodes = xmlDoc.getElementsByTagName("frame_geometry"); n = nodes.getLength(); for (int i = 0; i < n; i++) { Node node = nodes.item(i); String name = getStringAttr(node, "name"); if (name != null) { - HashMap gm = new HashMap(); + HashMap gm = new HashMap(); frameGeometries.put(name, gm); String parentGM = getStringAttr(node, "parent"); @@ -458,7 +458,7 @@ class Metacity implements SynthConstants { - private static class Privileged implements PrivilegedAction { + private static class Privileged implements PrivilegedAction { private static int GET_THEME_DIR = 0; private static int GET_USER_THEME = 1; private static int GET_IMAGE = 2; @@ -598,7 +598,7 @@ class Metacity implements SynthConstants { g2.setComposite(oldComp); } - private HashMap images = new HashMap(); + private HashMap images = new HashMap(); protected Image getImage(String key, Color c) { Image image = images.get(key+"-"+c.getRGB()); @@ -1530,8 +1530,8 @@ class Metacity implements SynthConstants { DocumentBuilderFactory.newInstance().newDocumentBuilder(); } InputStream inputStream = - (InputStream)AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged(new PrivilegedAction() { + public InputStream run() { try { return new BufferedInputStream(xmlFile.openStream()); } catch (IOException ex) { @@ -1551,7 +1551,7 @@ class Metacity implements SynthConstants { protected Node[] getNodesByName(Node parent, String name) { NodeList nodes = parent.getChildNodes(); // ElementNode int n = nodes.getLength(); - ArrayList list = new ArrayList(); + ArrayList list = new ArrayList(); for (int i=0; i < n; i++) { Node node = nodes.item(i); if (name.equals(node.getNodeName())) { @@ -1603,7 +1603,7 @@ class Metacity implements SynthConstants { String aValue = attrs[a * 2 + 1]; Node attr = nodeAttrs.getNamedItem(aName); if (attr == null || - aValue != null && !aValue.equals((String)attr.getNodeValue())) { + aValue != null && !aValue.equals(attr.getNodeValue())) { matches = false; break; } @@ -1642,7 +1642,7 @@ class Metacity implements SynthConstants { protected String getStringAttr(NamedNodeMap attrs, String name) { Node item = attrs.getNamedItem(name); - return (item != null) ? (String)item.getNodeValue() : null; + return (item != null) ? item.getNodeValue() : null; } protected boolean getBooleanAttr(Node node, String name, boolean fallback) { From 36134f31f5bd7705043a88c081ffefc85695b8cd Mon Sep 17 00:00:00 2001 From: Yuka Kamiya Date: Tue, 18 Nov 2008 13:58:43 +0900 Subject: [PATCH 10/44] 6769873: Regression test java/text/Date/DateFormat/Bug6683975.java started failing after DST ended Reviewed-by: okutsu --- jdk/test/java/text/Format/DateFormat/Bug6683975.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/test/java/text/Format/DateFormat/Bug6683975.java b/jdk/test/java/text/Format/DateFormat/Bug6683975.java index 1f497881a29..0638c557158 100644 --- a/jdk/test/java/text/Format/DateFormat/Bug6683975.java +++ b/jdk/test/java/text/Format/DateFormat/Bug6683975.java @@ -35,7 +35,6 @@ public class Bug6683975 { private static Locale th = new Locale("th", ""); private static Locale th_TH = new Locale("th", "TH"); - private static Date date = new Date(2008-1900, Calendar.OCTOBER, 1, 0, 0, 0); private static String expected_th[] = { "\u0e27\u0e31\u0e19\u0e2d\u0e31\u0e07\u0e04\u0e32\u0e23\u0e17\u0e35\u0e48 30 \u0e01\u0e31\u0e19\u0e22\u0e32\u0e22\u0e19 \u0e04.\u0e28. 2008, 8 \u0e19\u0e32\u0e2c\u0e34\u0e01\u0e32 0 \u0e19\u0e32\u0e17\u0e35 00 \u0e27\u0e34\u0e19\u0e32\u0e17\u0e35", // 0: FULL "30 \u0e01\u0e31\u0e19\u0e22\u0e32\u0e22\u0e19 2008, 8 \u0e19\u0e32\u0e2c\u0e34\u0e01\u0e32 0 \u0e19\u0e32\u0e17\u0e35", // 1: LONG @@ -65,6 +64,7 @@ public class Bug6683975 { System.err.println("\tth_TH: " + str_th_TH); } + Date date = new Date(2008-1900, Calendar.SEPTEMBER, 30, 8, 0, 0); str_th = df_th.format(date); if (!expected_th[style].equals(str_th)) { err = true; From 59b2212c9dd77c3b03601811f7ca2499e33cd603 Mon Sep 17 00:00:00 2001 From: Yuka Kamiya Date: Tue, 18 Nov 2008 15:59:36 +0900 Subject: [PATCH 11/44] 6772646: Regression test java/text/Date/DateFormat/Bug4823811.java started failing after DST ended Reviewed-by: okutsu --- jdk/test/java/text/Format/DateFormat/Bug4823811.java | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/test/java/text/Format/DateFormat/Bug4823811.java b/jdk/test/java/text/Format/DateFormat/Bug4823811.java index 65b4aa26349..6aa0787bfc2 100644 --- a/jdk/test/java/text/Format/DateFormat/Bug4823811.java +++ b/jdk/test/java/text/Format/DateFormat/Bug4823811.java @@ -25,6 +25,7 @@ * @test * @bug 4823811 * @summary Confirm that text which includes numbers with a trailing minus sign is parsed correctly. + * @run main/othervm -Duser.timezone=GMT+09:00 Bug4823811 */ import java.text.*; From 466eda6ee48797919f7c34016b1fb56402161463 Mon Sep 17 00:00:00 2001 From: Pavel Porvatov Date: Tue, 25 Nov 2008 16:42:10 +0300 Subject: [PATCH 12/44] 6698013: JFileChooser can no longer navigate non-local file systems ShellFolder is used only if possible Reviewed-by: peterz --- .../swing/plaf/basic/BasicFileChooserUI.java | 2 +- jdk/src/share/classes/sun/swing/FilePane.java | 10 + .../JFileChooser/6698013/bug6698013.html | 8 + .../JFileChooser/6698013/bug6698013.java | 174 ++++++++++++++++++ 4 files changed, 193 insertions(+), 1 deletion(-) create mode 100644 jdk/test/javax/swing/JFileChooser/6698013/bug6698013.html create mode 100644 jdk/test/javax/swing/JFileChooser/6698013/bug6698013.java diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicFileChooserUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicFileChooserUI.java index 13d13cdcefe..9b696868095 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicFileChooserUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicFileChooserUI.java @@ -1132,7 +1132,7 @@ public class BasicFileChooserUI extends FileChooserUI { private void changeDirectory(File dir) { JFileChooser fc = getFileChooser(); // Traverse shortcuts on Windows - if (dir != null && File.separatorChar == '\\' && dir.getPath().endsWith(".lnk")) { + if (dir != null && FilePane.usesShellFolder(fc)) { try { File linkedTo = ShellFolder.getShellFolder(dir).getLinkLocation(); if (linkedTo != null && fc.isTraversable(linkedTo)) { diff --git a/jdk/src/share/classes/sun/swing/FilePane.java b/jdk/src/share/classes/sun/swing/FilePane.java index 298fd42b146..2f80184c741 100644 --- a/jdk/src/share/classes/sun/swing/FilePane.java +++ b/jdk/src/share/classes/sun/swing/FilePane.java @@ -1961,6 +1961,16 @@ public class FilePane extends JPanel implements PropertyChangeListener { } } + /** + * Returns true if specified FileChooser should use ShellFolder + */ + public static boolean usesShellFolder(JFileChooser chooser) { + Boolean prop = (Boolean) chooser.getClientProperty("FileChooser.useShellFolder"); + + return prop == null ? chooser.getFileSystemView().equals(FileSystemView.getFileSystemView()) + : prop.booleanValue(); + } + // This interface is used to access methods in the FileChooserUI // that are not public. public interface FileChooserUIAccessor { diff --git a/jdk/test/javax/swing/JFileChooser/6698013/bug6698013.html b/jdk/test/javax/swing/JFileChooser/6698013/bug6698013.html new file mode 100644 index 00000000000..8de6fdd0792 --- /dev/null +++ b/jdk/test/javax/swing/JFileChooser/6698013/bug6698013.html @@ -0,0 +1,8 @@ + + + +1. Go into 'subdir' folder via double click +2. Return to parent directory +3. Go into 'subdir' folder: select 'subdir' folder and press the 'Open' button + + diff --git a/jdk/test/javax/swing/JFileChooser/6698013/bug6698013.java b/jdk/test/javax/swing/JFileChooser/6698013/bug6698013.java new file mode 100644 index 00000000000..ede1533746d --- /dev/null +++ b/jdk/test/javax/swing/JFileChooser/6698013/bug6698013.java @@ -0,0 +1,174 @@ +/* @test %W% %E% + @bug 6698013 + @summary JFileChooser can no longer navigate non-local file systems. + @author Pavel Porvatov + @run applet/manual=done bug6698013.html +*/ + +import javax.swing.*; +import javax.swing.filechooser.FileSystemView; +import java.io.File; + +public class bug6698013 extends JApplet { + + final static VirtualFile root = new VirtualFile("testdir", true); + + final static VirtualFile rootFile = new VirtualFile("testdir/test.txt", false); + + final static VirtualFile subdir = new VirtualFile("testdir/subdir", true); + + final static VirtualFile subdirFile = new VirtualFile("testdir/subdir/subtest.txt", false); + + public static void main(String[] args) { + JFileChooser chooser = new JFileChooser(new VirtualFileSystemView()); + chooser.setCurrentDirectory(root); + chooser.showSaveDialog(null); + } + + public void init() { + JFileChooser chooser = new JFileChooser(new VirtualFileSystemView()); + chooser.setCurrentDirectory(root); + chooser.showSaveDialog(null); + } +} + +class VirtualFileSystemView extends FileSystemView { + + public boolean isRoot(File dir) { + return bug6698013.root.equals(dir); + } + + public File createNewFolder(File dir) { + return null; + } + + public File[] getRoots() { + return new File[]{bug6698013.root}; + } + + public boolean isDrive(File dir) { + return false; + } + + public boolean isFloppyDrive(File dir) { + return false; + } + + public File getParentDirectory(File dir) { + if (dir == null) { + return null; + } + + return new VirtualFile(dir.getPath(), true).getParentFile(); + } + + public File[] getFiles(File dir, boolean hide_hidden) { + if (dir.equals(bug6698013.root)) { + return new File[]{bug6698013.rootFile, bug6698013.subdir}; + } + + if (dir.equals(bug6698013.subdir)) { + return new File[]{bug6698013.subdirFile}; + } + + return null; + } + + public File getHomeDirectory() { + return bug6698013.root; + } + + public File getDefaultDirectory() { + return getHomeDirectory(); + } + + public String getSystemDisplayName(File file) { + return file.getName(); + } + + public Boolean isTraversable(File file) { + return Boolean.valueOf(file.isDirectory()); + } +} + +/** + * A Virtual File. Contains a path and a directory flag that + * represents the location of a virtual file to be contained in the + * Virtual FileSystemView. + */ +class VirtualFile extends File { + + private static final long serialVersionUID = 0L; + + private String path; + + private boolean directory; + + public VirtualFile(String path, boolean directory) { + super(path); + this.path = path; + this.directory = directory; + } + + public File getParentFile() { + int index = path.lastIndexOf('/'); + + if (index == -1) { + return null; + } + + return new VirtualFile(path.substring(0, index), true); + } + + public File getCanonicalFile() { + return this; + } + + public String getParent() { + File parent_file = getParentFile(); + + return parent_file == null ? null : parent_file.getPath(); + } + + public String getName() { + int index = path.lastIndexOf('/'); + + return index == -1 ? path : path.substring(index + 1); + } + + public String getPath() { + return path; + } + + public String getAbsolutePath() { + return path; + } + + public String getCanonicalPath() { + return path; + } + + public String toString() { + return path; + } + + public boolean equals(Object obj) { + return obj instanceof VirtualFile && path.equals(obj.toString()); + } + + public int hashCode() { + return path.hashCode(); + } + + public boolean canWrite() { + return true; + } + + public boolean isDirectory() { + return directory; + } + + public boolean exists() { + return true; + } +} From e7c2dc0b7ad6b1facf05d7bae13802ef9757636a Mon Sep 17 00:00:00 2001 From: Pavel Porvatov Date: Wed, 26 Nov 2008 19:08:41 +0300 Subject: [PATCH 13/44] 6560349: REGRESSION :folder having ".lnk" in the name can not be opened by 5.0 and later versions Reviewed-by: alexp --- .../swing/plaf/basic/BasicFileChooserUI.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicFileChooserUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicFileChooserUI.java index 9b696868095..44f99d6d3e3 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicFileChooserUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicFileChooserUI.java @@ -1134,11 +1134,16 @@ public class BasicFileChooserUI extends FileChooserUI { // Traverse shortcuts on Windows if (dir != null && FilePane.usesShellFolder(fc)) { try { - File linkedTo = ShellFolder.getShellFolder(dir).getLinkLocation(); - if (linkedTo != null && fc.isTraversable(linkedTo)) { - dir = linkedTo; - } else { - return; + ShellFolder shellFolder = ShellFolder.getShellFolder(dir); + + if (shellFolder.isLink()) { + File linkedTo = shellFolder.getLinkLocation(); + + if (linkedTo != null && fc.isTraversable(linkedTo)) { + dir = linkedTo; + } else { + return; + } } } catch (FileNotFoundException ex) { return; From 5a8c6c3bf7b2101bca5d1a0bb601ce887f885ccc Mon Sep 17 00:00:00 2001 From: Pavel Porvatov Date: Wed, 26 Nov 2008 19:38:46 +0300 Subject: [PATCH 14/44] 6776856: Code with useShellFolder field shuold be simplify Reviewed-by: peterz --- .../plaf/windows/WindowsFileChooserUI.java | 16 +++---------- .../swing/plaf/metal/MetalFileChooserUI.java | 24 ++----------------- jdk/src/share/classes/sun/swing/FilePane.java | 5 ++-- .../plaf/synth/SynthFileChooserUIImpl.java | 24 ++----------------- 4 files changed, 9 insertions(+), 60 deletions(-) diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java index e0fb203e0d3..6f75220d4e7 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java @@ -70,7 +70,6 @@ public class WindowsFileChooserUI extends BasicFileChooserUI { private JTextField filenameTextField; private FilePane filePane; private WindowsPlacesBar placesBar; - private boolean useShellFolder; private JButton approveButton; private JButton cancelButton; @@ -210,10 +209,6 @@ public class WindowsFileChooserUI extends BasicFileChooserUI { public ListSelectionListener createListSelectionListener() { return WindowsFileChooserUI.this.createListSelectionListener(getFileChooser()); } - - public boolean usesShellFolder() { - return useShellFolder; - } } public void installComponents(JFileChooser fc) { @@ -625,15 +620,8 @@ public class WindowsFileChooserUI extends BasicFileChooserUI { // Decide whether to use the ShellFolder class to populate shortcut // panel and combobox. JFileChooser fc = getFileChooser(); - Boolean prop = - (Boolean)fc.getClientProperty("FileChooser.useShellFolder"); - if (prop != null) { - useShellFolder = prop.booleanValue(); - } else { - useShellFolder = fc.getFileSystemView().equals(FileSystemView.getFileSystemView()); - } if (OS_VERSION.compareTo(OSInfo.WINDOWS_ME) >= 0) { - if (useShellFolder) { + if (FilePane.usesShellFolder(fc)) { if (placesBar == null && !UIManager.getBoolean("FileChooser.noPlacesBar")) { placesBar = new WindowsPlacesBar(fc, XPStyle.getXP() != null); fc.add(placesBar, BorderLayout.BEFORE_LINE_BEGINS); @@ -1149,6 +1137,8 @@ public class WindowsFileChooserUI extends BasicFileChooserUI { return; } + boolean useShellFolder = FilePane.usesShellFolder(chooser); + directories.clear(); File[] baseFolders; diff --git a/jdk/src/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java b/jdk/src/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java index fd837b9abf2..f1864614d90 100644 --- a/jdk/src/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java @@ -68,8 +68,6 @@ public class MetalFileChooserUI extends BasicFileChooserUI { private JToggleButton listViewButton; private JToggleButton detailsViewButton; - private boolean useShellFolder; - private JButton approveButton; private JButton cancelButton; @@ -204,10 +202,6 @@ public class MetalFileChooserUI extends BasicFileChooserUI { public ListSelectionListener createListSelectionListener() { return MetalFileChooserUI.this.createListSelectionListener(getFileChooser()); } - - public boolean usesShellFolder() { - return useShellFolder; - } } public void installComponents(JFileChooser fc) { @@ -219,8 +213,6 @@ public class MetalFileChooserUI extends BasicFileChooserUI { filePane = new FilePane(new MetalFileChooserUIAccessor()); fc.addPropertyChangeListener(filePane); - updateUseShellFolder(); - // ********************************* // // **** Construct the top panel **** // // ********************************* // @@ -448,19 +440,6 @@ public class MetalFileChooserUI extends BasicFileChooserUI { groupLabels(new AlignedLabel[] { fileNameLabel, filesOfTypeLabel }); } - private void updateUseShellFolder() { - // Decide whether to use the ShellFolder class to populate shortcut - // panel and combobox. - JFileChooser fc = getFileChooser(); - Boolean prop = - (Boolean)fc.getClientProperty("FileChooser.useShellFolder"); - if (prop != null) { - useShellFolder = prop.booleanValue(); - } else { - useShellFolder = fc.getFileSystemView().equals(FileSystemView.getFileSystemView()); - } - } - protected JPanel getButtonPanel() { if (buttonPanel == null) { buttonPanel = new JPanel(); @@ -786,7 +765,6 @@ public class MetalFileChooserUI extends BasicFileChooserUI { cc.applyComponentOrientation(o); } } else if (s == "FileChooser.useShellFolder") { - updateUseShellFolder(); doDirectoryChanged(e); } else if (s.equals("ancestor")) { if (e.getOldValue() == null && e.getNewValue() != null) { @@ -953,6 +931,8 @@ public class MetalFileChooserUI extends BasicFileChooserUI { return; } + boolean useShellFolder = FilePane.usesShellFolder(chooser); + directories.clear(); File[] baseFolders; diff --git a/jdk/src/share/classes/sun/swing/FilePane.java b/jdk/src/share/classes/sun/swing/FilePane.java index 2f80184c741..de5ad7c4831 100644 --- a/jdk/src/share/classes/sun/swing/FilePane.java +++ b/jdk/src/share/classes/sun/swing/FilePane.java @@ -689,7 +689,7 @@ public class FilePane extends JPanel implements PropertyChangeListener { void updateColumnInfo() { File dir = chooser.getCurrentDirectory(); - if (dir != null && fileChooserUIAccessor.usesShellFolder()) { + if (dir != null && usesShellFolder(chooser)) { try { dir = ShellFolder.getShellFolder(dir); } catch (FileNotFoundException e) { @@ -1947,7 +1947,7 @@ public class FilePane extends JPanel implements PropertyChangeListener { if (f instanceof ShellFolder) { return ((ShellFolder) f).isFileSystem(); } else { - if (fileChooserUIAccessor.usesShellFolder()) { + if (usesShellFolder(getFileChooser())) { try { return ShellFolder.getShellFolder(f).isFileSystem(); } catch (FileNotFoundException ex) { @@ -1985,6 +1985,5 @@ public class FilePane extends JPanel implements PropertyChangeListener { public Action getNewFolderAction(); public MouseListener createDoubleClickListener(JList list); public ListSelectionListener createListSelectionListener(); - public boolean usesShellFolder(); } } diff --git a/jdk/src/share/classes/sun/swing/plaf/synth/SynthFileChooserUIImpl.java b/jdk/src/share/classes/sun/swing/plaf/synth/SynthFileChooserUIImpl.java index 2721764d1d7..a107ccca88d 100644 --- a/jdk/src/share/classes/sun/swing/plaf/synth/SynthFileChooserUIImpl.java +++ b/jdk/src/share/classes/sun/swing/plaf/synth/SynthFileChooserUIImpl.java @@ -71,8 +71,6 @@ public class SynthFileChooserUIImpl extends SynthFileChooserUI { private JToggleButton listViewButton; private JToggleButton detailsViewButton; - private boolean useShellFolder; - private boolean readOnly; private JPanel buttonPanel; @@ -185,10 +183,6 @@ public class SynthFileChooserUIImpl extends SynthFileChooserUI { public ListSelectionListener createListSelectionListener() { return SynthFileChooserUIImpl.this.createListSelectionListener(getFileChooser()); } - - public boolean usesShellFolder() { - return useShellFolder; - } } protected void installDefaults(JFileChooser fc) { @@ -201,8 +195,6 @@ public class SynthFileChooserUIImpl extends SynthFileChooserUI { SynthContext context = getContext(fc, ENABLED); - updateUseShellFolder(); - fc.setLayout(new BorderLayout(0, 11)); // ********************************* // @@ -432,20 +424,6 @@ public class SynthFileChooserUIImpl extends SynthFileChooserUI { super.uninstallListeners(fc); } - private void updateUseShellFolder() { - // Decide whether to use the ShellFolder class to populate shortcut - // panel and combobox. - JFileChooser fc = getFileChooser(); - Boolean prop = - (Boolean)fc.getClientProperty("FileChooser.useShellFolder"); - if (prop != null) { - useShellFolder = prop.booleanValue(); - } else { - useShellFolder = fc.getFileSystemView().equals(FileSystemView.getFileSystemView()); - } - } - - private String fileNameString(File file) { if (file == null) { return null; @@ -761,6 +739,8 @@ public class SynthFileChooserUIImpl extends SynthFileChooserUI { return; } + boolean useShellFolder = FilePane.usesShellFolder(chooser); + int oldSize = directories.size(); directories.clear(); if (oldSize > 0) { From 8242c2b3b60c69868c78e7d40fe04e0b295fe78c Mon Sep 17 00:00:00 2001 From: Florian Brunner Date: Thu, 27 Nov 2008 17:55:36 +0300 Subject: [PATCH 15/44] 6776095: Code improvement and warnings removing from swing packages Reviewed-by: malenkov --- .../java/swing/plaf/gtk/GTKFileChooserUI.java | 8 +++---- .../java/swing/plaf/gtk/GTKLookAndFeel.java | 8 +++---- .../share/classes/javax/swing/ImageIcon.java | 2 +- .../classes/javax/swing/ProgressMonitor.java | 13 +++++------- .../classes/javax/swing/SwingWorker.java | 4 ++-- .../DefaultColorSelectionModel.java | 3 +-- .../swing/table/DefaultTableColumnModel.java | 7 +++---- .../swing/tree/DefaultMutableTreeNode.java | 21 ++++++++----------- .../javax/swing/undo/CompoundEdit.java | 6 +++--- 9 files changed, 32 insertions(+), 40 deletions(-) diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKFileChooserUI.java b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKFileChooserUI.java index 9ca8fa52b61..acb944dfa56 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKFileChooserUI.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKFileChooserUI.java @@ -263,13 +263,13 @@ class GTKFileChooserUI extends SynthFileChooserUI { ListSelectionModel sm = directoryList.getSelectionModel(); if (sm instanceof DefaultListSelectionModel) { ((DefaultListSelectionModel)sm).moveLeadSelectionIndex(0); - ((DefaultListSelectionModel)sm).setAnchorSelectionIndex(0); + sm.setAnchorSelectionIndex(0); } fileList.clearSelection(); sm = fileList.getSelectionModel(); if (sm instanceof DefaultListSelectionModel) { ((DefaultListSelectionModel)sm).moveLeadSelectionIndex(0); - ((DefaultListSelectionModel)sm).setAnchorSelectionIndex(0); + sm.setAnchorSelectionIndex(0); } File currentDirectory = getFileChooser().getCurrentDirectory(); @@ -1073,7 +1073,7 @@ class GTKFileChooserUI extends SynthFileChooserUI { * Data model for a type-face selection combo-box. */ protected class DirectoryComboBoxModel extends AbstractListModel implements ComboBoxModel { - Vector directories = new Vector(); + Vector directories = new Vector(); File selectedDirectory = null; JFileChooser chooser = getFileChooser(); FileSystemView fsv = chooser.getFileSystemView(); @@ -1215,7 +1215,7 @@ class GTKFileChooserUI extends SynthFileChooserUI { ListSelectionModel sm = fileList.getSelectionModel(); if (sm instanceof DefaultListSelectionModel) { ((DefaultListSelectionModel)sm).moveLeadSelectionIndex(0); - ((DefaultListSelectionModel)sm).setAnchorSelectionIndex(0); + sm.setAnchorSelectionIndex(0); } rescanCurrentDirectory(getFileChooser()); return; diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java index 6934aa213d1..23e4ee2eee5 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java @@ -1470,7 +1470,7 @@ public class GTKLookAndFeel extends SynthLookAndFeel { aaTextInfo = SwingUtilities2.AATextInfo.getAATextInfo(gtkAAFontSettingsCond); } - static ReferenceQueue queue = new ReferenceQueue(); + static ReferenceQueue queue = new ReferenceQueue(); private static void flushUnreferenced() { WeakPCL pcl; @@ -1480,12 +1480,12 @@ public class GTKLookAndFeel extends SynthLookAndFeel { } } - static class WeakPCL extends WeakReference implements + static class WeakPCL extends WeakReference implements PropertyChangeListener { private Toolkit kit; private String key; - WeakPCL(Object target, Toolkit kit, String key) { + WeakPCL(GTKLookAndFeel target, Toolkit kit, String key) { super(target, queue); this.kit = kit; this.key = key; @@ -1494,7 +1494,7 @@ public class GTKLookAndFeel extends SynthLookAndFeel { public String getKey() { return key; } public void propertyChange(final PropertyChangeEvent pce) { - final GTKLookAndFeel lnf = (GTKLookAndFeel)get(); + final GTKLookAndFeel lnf = get(); if (lnf == null || UIManager.getLookAndFeel() != lnf) { // The property was GC'ed, we're no longer interested in diff --git a/jdk/src/share/classes/javax/swing/ImageIcon.java b/jdk/src/share/classes/javax/swing/ImageIcon.java index 74788f1a803..7f1fd02e003 100644 --- a/jdk/src/share/classes/javax/swing/ImageIcon.java +++ b/jdk/src/share/classes/javax/swing/ImageIcon.java @@ -86,7 +86,7 @@ public class ImageIcon implements Icon, Serializable, Accessible { static { component = new Component() {}; - AccessController.doPrivileged(new PrivilegedAction() { + AccessController.doPrivileged(new PrivilegedAction() { public Object run() { try { // 6482575 - clear the appContext field so as not to leak it diff --git a/jdk/src/share/classes/javax/swing/ProgressMonitor.java b/jdk/src/share/classes/javax/swing/ProgressMonitor.java index 36366df170c..73a2b656b0d 100644 --- a/jdk/src/share/classes/javax/swing/ProgressMonitor.java +++ b/jdk/src/share/classes/javax/swing/ProgressMonitor.java @@ -78,7 +78,7 @@ import javax.swing.text.*; * @author James Gosling * @author Lynn Monsanto (accessibility) */ -public class ProgressMonitor extends Object implements Accessible +public class ProgressMonitor implements Accessible { private ProgressMonitor root; private JDialog dialog; @@ -186,7 +186,7 @@ public class ProgressMonitor extends Object implements Accessible } if (window instanceof SwingUtilities.SharedOwnerFrame) { WindowListener ownerShutdownListener = - (WindowListener)SwingUtilities.getSharedOwnerFrameShutdownListener(); + SwingUtilities.getSharedOwnerFrameShutdownListener(); dialog.addWindowListener(ownerShutdownListener); } Container contentPane = dialog.getContentPane(); @@ -273,7 +273,7 @@ public class ProgressMonitor extends Object implements Accessible if (dT >= millisToDecideToPopup) { int predictedCompletionTime; if (nv > min) { - predictedCompletionTime = (int)((long)dT * + predictedCompletionTime = (int)(dT * (max - min) / (nv - min)); } @@ -691,10 +691,7 @@ public class ProgressMonitor extends Object implements Accessible * object does not have an Accessible parent */ public Accessible getAccessibleParent() { - if (dialog != null) { - return (Accessible)dialog; - } - return null; + return dialog; } /* @@ -768,7 +765,7 @@ public class ProgressMonitor extends Object implements Accessible if (myBar != null) { Component c = myBar.getParent(); if (c instanceof Accessible) { - return ((Accessible)c).getAccessibleContext(); + return c.getAccessibleContext(); } } return null; diff --git a/jdk/src/share/classes/javax/swing/SwingWorker.java b/jdk/src/share/classes/javax/swing/SwingWorker.java index de00ddc381d..9eca7d535f6 100644 --- a/jdk/src/share/classes/javax/swing/SwingWorker.java +++ b/jdk/src/share/classes/javax/swing/SwingWorker.java @@ -282,7 +282,7 @@ public abstract class SwingWorker implements RunnableFuture { * is finished. */ DONE - }; + } /** * Constructs this {@code SwingWorker}. @@ -825,7 +825,7 @@ public abstract class SwingWorker implements RunnableFuture { } private static class DoSubmitAccumulativeRunnable extends AccumulativeRunnable implements ActionListener { - private final static int DELAY = (int) (1000 / 30); + private final static int DELAY = 1000 / 30; @Override protected void run(List args) { for (Runnable runnable : args) { diff --git a/jdk/src/share/classes/javax/swing/colorchooser/DefaultColorSelectionModel.java b/jdk/src/share/classes/javax/swing/colorchooser/DefaultColorSelectionModel.java index e3cf261bd02..e437dd96dd3 100644 --- a/jdk/src/share/classes/javax/swing/colorchooser/DefaultColorSelectionModel.java +++ b/jdk/src/share/classes/javax/swing/colorchooser/DefaultColorSelectionModel.java @@ -128,8 +128,7 @@ public class DefaultColorSelectionModel implements ColorSelectionModel, Serializ * @since 1.4 */ public ChangeListener[] getChangeListeners() { - return (ChangeListener[])listenerList.getListeners( - ChangeListener.class); + return listenerList.getListeners(ChangeListener.class); } /** diff --git a/jdk/src/share/classes/javax/swing/table/DefaultTableColumnModel.java b/jdk/src/share/classes/javax/swing/table/DefaultTableColumnModel.java index 846001b35b1..d3ae8cdd63f 100644 --- a/jdk/src/share/classes/javax/swing/table/DefaultTableColumnModel.java +++ b/jdk/src/share/classes/javax/swing/table/DefaultTableColumnModel.java @@ -190,7 +190,7 @@ public class DefaultTableColumnModel implements TableColumnModel, fireColumnMoved(new TableColumnModelEvent(this, columnIndex, newIndex)); return; } - aColumn = (TableColumn)tableColumns.elementAt(columnIndex); + aColumn = tableColumns.elementAt(columnIndex); tableColumns.removeElementAt(columnIndex); boolean selected = selectionModel.isSelectedIndex(columnIndex); @@ -291,7 +291,7 @@ public class DefaultTableColumnModel implements TableColumnModel, * at columnIndex */ public TableColumn getColumn(int columnIndex) { - return (TableColumn)tableColumns.elementAt(columnIndex); + return tableColumns.elementAt(columnIndex); } /** @@ -504,8 +504,7 @@ public class DefaultTableColumnModel implements TableColumnModel, * @since 1.4 */ public TableColumnModelListener[] getColumnModelListeners() { - return (TableColumnModelListener[])listenerList.getListeners( - TableColumnModelListener.class); + return listenerList.getListeners(TableColumnModelListener.class); } // diff --git a/jdk/src/share/classes/javax/swing/tree/DefaultMutableTreeNode.java b/jdk/src/share/classes/javax/swing/tree/DefaultMutableTreeNode.java index 11ed3bdd582..34c36ba8957 100644 --- a/jdk/src/share/classes/javax/swing/tree/DefaultMutableTreeNode.java +++ b/jdk/src/share/classes/javax/swing/tree/DefaultMutableTreeNode.java @@ -84,7 +84,7 @@ import java.util.*; * * @author Rob Davis */ -public class DefaultMutableTreeNode extends Object implements Cloneable, +public class DefaultMutableTreeNode implements Cloneable, MutableTreeNode, Serializable { private static final long serialVersionUID = -4298474751201349152L; @@ -1251,7 +1251,7 @@ public class DefaultMutableTreeNode extends Object implements Cloneable, * @return a copy of this node */ public Object clone() { - DefaultMutableTreeNode newNode = null; + DefaultMutableTreeNode newNode; try { newNode = (DefaultMutableTreeNode)super.clone(); @@ -1297,24 +1297,22 @@ public class DefaultMutableTreeNode extends Object implements Cloneable, userObject = tValues[1]; } - final class PreorderEnumeration implements Enumeration { - protected Stack stack; + private final class PreorderEnumeration implements Enumeration { + private final Stack stack = new Stack(); public PreorderEnumeration(TreeNode rootNode) { super(); - Vector v = new Vector(1); + Vector v = new Vector(1); v.addElement(rootNode); // PENDING: don't really need a vector - stack = new Stack(); stack.push(v.elements()); } public boolean hasMoreElements() { - return (!stack.empty() && - ((Enumeration)stack.peek()).hasMoreElements()); + return (!stack.empty() && stack.peek().hasMoreElements()); } public TreeNode nextElement() { - Enumeration enumer = (Enumeration)stack.peek(); + Enumeration enumer = stack.peek(); TreeNode node = (TreeNode)enumer.nextElement(); Enumeration children = node.children(); @@ -1353,8 +1351,7 @@ public class DefaultMutableTreeNode extends Object implements Cloneable, if (subtree.hasMoreElements()) { retval = subtree.nextElement(); } else if (children.hasMoreElements()) { - subtree = new PostorderEnumeration( - (TreeNode)children.nextElement()); + subtree = new PostorderEnumeration(children.nextElement()); retval = subtree.nextElement(); } else { retval = root; @@ -1373,7 +1370,7 @@ public class DefaultMutableTreeNode extends Object implements Cloneable, public BreadthFirstEnumeration(TreeNode rootNode) { super(); - Vector v = new Vector(1); + Vector v = new Vector(1); v.addElement(rootNode); // PENDING: don't really need a vector queue = new Queue(); queue.enqueue(v.elements()); diff --git a/jdk/src/share/classes/javax/swing/undo/CompoundEdit.java b/jdk/src/share/classes/javax/swing/undo/CompoundEdit.java index 6bc66156029..7aa21d3af8d 100644 --- a/jdk/src/share/classes/javax/swing/undo/CompoundEdit.java +++ b/jdk/src/share/classes/javax/swing/undo/CompoundEdit.java @@ -59,7 +59,7 @@ public class CompoundEdit extends AbstractUndoableEdit { super.undo(); int i = edits.size(); while (i-- > 0) { - UndoableEdit e = (UndoableEdit)edits.elementAt(i); + UndoableEdit e = edits.elementAt(i); e.undo(); } } @@ -85,7 +85,7 @@ public class CompoundEdit extends AbstractUndoableEdit { protected UndoableEdit lastEdit() { int count = edits.size(); if (count > 0) - return (UndoableEdit)edits.elementAt(count-1); + return edits.elementAt(count-1); else return null; } @@ -98,7 +98,7 @@ public class CompoundEdit extends AbstractUndoableEdit { int size = edits.size(); for (int i = size-1; i >= 0; i--) { - UndoableEdit e = (UndoableEdit)edits.elementAt(i); + UndoableEdit e = edits.elementAt(i); // System.out.println("CompoundEdit(" + i + "): Discarding " + // e.getUndoPresentationName()); e.die(); From 9330abadeaef38e2ed74c6f97f7c933250ae2edc Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Mon, 22 Dec 2008 17:42:49 +0300 Subject: [PATCH 16/44] 4864117: RFE: Make XMLDecoder API more reusable Reviewed-by: peterz, loneid --- .../classes/com/sun/beans/ObjectHandler.java | 479 ------------------ .../beans/decoder/AccessorElementHandler.java | 105 ++++ .../beans/decoder/ArrayElementHandler.java | 133 +++++ .../beans/decoder/BooleanElementHandler.java | 69 +++ .../sun/beans/decoder/ByteElementHandler.java | 63 +++ .../sun/beans/decoder/CharElementHandler.java | 92 ++++ .../beans/decoder/ClassElementHandler.java | 62 +++ .../sun/beans/decoder/DocumentHandler.java | 389 ++++++++++++++ .../beans/decoder/DoubleElementHandler.java | 63 +++ .../com/sun/beans/decoder/ElementHandler.java | 224 ++++++++ .../beans/decoder/FalseElementHandler.java | 56 ++ .../beans/decoder/FieldElementHandler.java | 189 +++++++ .../beans/decoder/FloatElementHandler.java | 63 +++ .../sun/beans/decoder/IntElementHandler.java | 63 +++ .../sun/beans/decoder/JavaElementHandler.java | 151 ++++++ .../sun/beans/decoder/LongElementHandler.java | 63 +++ .../beans/decoder/MethodElementHandler.java | 109 ++++ .../sun/beans/decoder/NewElementHandler.java | 205 ++++++++ .../sun/beans/decoder/NullElementHandler.java | 76 +++ .../beans/decoder/ObjectElementHandler.java | 168 ++++++ .../beans/decoder/PropertyElementHandler.java | 287 +++++++++++ .../beans/decoder/ShortElementHandler.java | 63 +++ .../beans/decoder/StringElementHandler.java | 116 +++++ .../sun/beans/decoder/TrueElementHandler.java | 56 ++ .../com/sun/beans/decoder/ValueObject.java | 50 ++ .../sun/beans/decoder/ValueObjectImpl.java | 88 ++++ .../sun/beans/decoder/VarElementHandler.java | 82 +++ .../sun/beans/decoder/VoidElementHandler.java | 68 +++ .../com/sun/beans/finder/AbstractFinder.java | 213 ++++++++ .../com/sun/beans/finder/ClassFinder.java | 99 ++-- .../sun/beans/finder/ConstructorFinder.java | 127 +++++ .../com/sun/beans/finder/FieldFinder.java | 106 ++++ .../com/sun/beans/finder/MethodFinder.java | 205 ++++++++ .../sun/beans/finder/PrimitiveTypeMap.java | 29 +- .../sun/beans/finder/PrimitiveWrapperMap.java | 86 ++++ .../com/sun/beans/finder/Signature.java | 169 ++++++ .../share/classes/java/beans/MetaData.java | 4 +- .../classes/java/beans/ReflectionUtils.java | 13 +- .../share/classes/java/beans/XMLDecoder.java | 153 +++--- .../javax/swing/plaf/synth/SynthParser.java | 107 ++-- .../java/beans/XMLDecoder/Test4864117.java | 146 ++++++ .../java/beans/XMLDecoder/Test6341798.java | 4 +- .../beans/XMLDecoder/spec/AbstractTest.java | 76 +++ .../java/beans/XMLDecoder/spec/TestArray.java | 86 ++++ .../beans/XMLDecoder/spec/TestBoolean.java | 52 ++ .../java/beans/XMLDecoder/spec/TestByte.java | 56 ++ .../java/beans/XMLDecoder/spec/TestChar.java | 52 ++ .../java/beans/XMLDecoder/spec/TestClass.java | 61 +++ .../beans/XMLDecoder/spec/TestDouble.java | 58 +++ .../java/beans/XMLDecoder/spec/TestFalse.java | 48 ++ .../java/beans/XMLDecoder/spec/TestField.java | 74 +++ .../java/beans/XMLDecoder/spec/TestFloat.java | 58 +++ .../java/beans/XMLDecoder/spec/TestInt.java | 64 +++ .../java/beans/XMLDecoder/spec/TestJava.java | 63 +++ .../java/beans/XMLDecoder/spec/TestLong.java | 68 +++ .../beans/XMLDecoder/spec/TestMethod.java | 178 +++++++ .../java/beans/XMLDecoder/spec/TestNew.java | 90 ++++ .../java/beans/XMLDecoder/spec/TestNull.java | 48 ++ .../beans/XMLDecoder/spec/TestObject.java | 84 +++ .../beans/XMLDecoder/spec/TestProperty.java | 88 ++++ .../java/beans/XMLDecoder/spec/TestShort.java | 60 +++ .../beans/XMLDecoder/spec/TestString.java | 60 +++ .../java/beans/XMLDecoder/spec/TestTrue.java | 48 ++ .../java/beans/XMLDecoder/spec/TestVar.java | 54 ++ 64 files changed, 5946 insertions(+), 673 deletions(-) delete mode 100644 jdk/src/share/classes/com/sun/beans/ObjectHandler.java create mode 100644 jdk/src/share/classes/com/sun/beans/decoder/AccessorElementHandler.java create mode 100644 jdk/src/share/classes/com/sun/beans/decoder/ArrayElementHandler.java create mode 100644 jdk/src/share/classes/com/sun/beans/decoder/BooleanElementHandler.java create mode 100644 jdk/src/share/classes/com/sun/beans/decoder/ByteElementHandler.java create mode 100644 jdk/src/share/classes/com/sun/beans/decoder/CharElementHandler.java create mode 100644 jdk/src/share/classes/com/sun/beans/decoder/ClassElementHandler.java create mode 100644 jdk/src/share/classes/com/sun/beans/decoder/DocumentHandler.java create mode 100644 jdk/src/share/classes/com/sun/beans/decoder/DoubleElementHandler.java create mode 100644 jdk/src/share/classes/com/sun/beans/decoder/ElementHandler.java create mode 100644 jdk/src/share/classes/com/sun/beans/decoder/FalseElementHandler.java create mode 100644 jdk/src/share/classes/com/sun/beans/decoder/FieldElementHandler.java create mode 100644 jdk/src/share/classes/com/sun/beans/decoder/FloatElementHandler.java create mode 100644 jdk/src/share/classes/com/sun/beans/decoder/IntElementHandler.java create mode 100644 jdk/src/share/classes/com/sun/beans/decoder/JavaElementHandler.java create mode 100644 jdk/src/share/classes/com/sun/beans/decoder/LongElementHandler.java create mode 100644 jdk/src/share/classes/com/sun/beans/decoder/MethodElementHandler.java create mode 100644 jdk/src/share/classes/com/sun/beans/decoder/NewElementHandler.java create mode 100644 jdk/src/share/classes/com/sun/beans/decoder/NullElementHandler.java create mode 100644 jdk/src/share/classes/com/sun/beans/decoder/ObjectElementHandler.java create mode 100644 jdk/src/share/classes/com/sun/beans/decoder/PropertyElementHandler.java create mode 100644 jdk/src/share/classes/com/sun/beans/decoder/ShortElementHandler.java create mode 100644 jdk/src/share/classes/com/sun/beans/decoder/StringElementHandler.java create mode 100644 jdk/src/share/classes/com/sun/beans/decoder/TrueElementHandler.java create mode 100644 jdk/src/share/classes/com/sun/beans/decoder/ValueObject.java create mode 100644 jdk/src/share/classes/com/sun/beans/decoder/ValueObjectImpl.java create mode 100644 jdk/src/share/classes/com/sun/beans/decoder/VarElementHandler.java create mode 100644 jdk/src/share/classes/com/sun/beans/decoder/VoidElementHandler.java create mode 100644 jdk/src/share/classes/com/sun/beans/finder/AbstractFinder.java create mode 100644 jdk/src/share/classes/com/sun/beans/finder/ConstructorFinder.java create mode 100644 jdk/src/share/classes/com/sun/beans/finder/FieldFinder.java create mode 100644 jdk/src/share/classes/com/sun/beans/finder/MethodFinder.java create mode 100644 jdk/src/share/classes/com/sun/beans/finder/PrimitiveWrapperMap.java create mode 100644 jdk/src/share/classes/com/sun/beans/finder/Signature.java create mode 100644 jdk/test/java/beans/XMLDecoder/Test4864117.java create mode 100644 jdk/test/java/beans/XMLDecoder/spec/AbstractTest.java create mode 100644 jdk/test/java/beans/XMLDecoder/spec/TestArray.java create mode 100644 jdk/test/java/beans/XMLDecoder/spec/TestBoolean.java create mode 100644 jdk/test/java/beans/XMLDecoder/spec/TestByte.java create mode 100644 jdk/test/java/beans/XMLDecoder/spec/TestChar.java create mode 100644 jdk/test/java/beans/XMLDecoder/spec/TestClass.java create mode 100644 jdk/test/java/beans/XMLDecoder/spec/TestDouble.java create mode 100644 jdk/test/java/beans/XMLDecoder/spec/TestFalse.java create mode 100644 jdk/test/java/beans/XMLDecoder/spec/TestField.java create mode 100644 jdk/test/java/beans/XMLDecoder/spec/TestFloat.java create mode 100644 jdk/test/java/beans/XMLDecoder/spec/TestInt.java create mode 100644 jdk/test/java/beans/XMLDecoder/spec/TestJava.java create mode 100644 jdk/test/java/beans/XMLDecoder/spec/TestLong.java create mode 100644 jdk/test/java/beans/XMLDecoder/spec/TestMethod.java create mode 100644 jdk/test/java/beans/XMLDecoder/spec/TestNew.java create mode 100644 jdk/test/java/beans/XMLDecoder/spec/TestNull.java create mode 100644 jdk/test/java/beans/XMLDecoder/spec/TestObject.java create mode 100644 jdk/test/java/beans/XMLDecoder/spec/TestProperty.java create mode 100644 jdk/test/java/beans/XMLDecoder/spec/TestShort.java create mode 100644 jdk/test/java/beans/XMLDecoder/spec/TestString.java create mode 100644 jdk/test/java/beans/XMLDecoder/spec/TestTrue.java create mode 100644 jdk/test/java/beans/XMLDecoder/spec/TestVar.java diff --git a/jdk/src/share/classes/com/sun/beans/ObjectHandler.java b/jdk/src/share/classes/com/sun/beans/ObjectHandler.java deleted file mode 100644 index 6daeab953a2..00000000000 --- a/jdk/src/share/classes/com/sun/beans/ObjectHandler.java +++ /dev/null @@ -1,479 +0,0 @@ -/* - * Copyright 2003-2006 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. 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 - * 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. - */ - -package com.sun.beans; - -import com.sun.beans.finder.ClassFinder; - -import java.beans.*; -import java.util.*; - -import org.xml.sax.*; - -import static java.util.Locale.ENGLISH; - -/** - * WARNING: This class is an implementation detail and only meant - * for use within the core platform. You should NOT depend upon it! This - * API may change drastically between dot dot release, and it may even be - * removed. - * - * @see java.beans.XMLEncoder - * @see java.io.ObjectInputStream - * - * @since 1.4 - * - * @author Philip Milne - */ -public class ObjectHandler extends HandlerBase { - - public static Class typeNameToClass(String typeName) { - typeName = typeName.intern(); - if (typeName == "boolean") return Boolean.class; - if (typeName == "byte") return Byte.class; - if (typeName == "char") return Character.class; - if (typeName == "short") return Short.class; - if (typeName == "int") return Integer.class; - if (typeName == "long") return Long.class; - if (typeName == "float") return Float.class; - if (typeName == "double") return Double.class; - if (typeName == "void") return Void.class; - return null; - } - - public static Class typeNameToPrimitiveClass(String typeName) { - typeName = typeName.intern(); - if (typeName == "boolean") return boolean.class; - if (typeName == "byte") return byte.class; - if (typeName == "char") return char.class; - if (typeName == "short") return short.class; - if (typeName == "int") return int.class; - if (typeName == "long") return long.class; - if (typeName == "float") return float.class; - if (typeName == "double") return double.class; - if (typeName == "void") return void.class; - return null; - } - - /** - * Returns the Class object associated with - * the class or interface with the given string name, - * using the default class loader. - * - * @param name fully qualified name of the desired class - * @param cl class loader from which the class must be loaded - * @return class object representing the desired class - * - * @exception ClassNotFoundException if the class cannot be located - * by the specified class loader - * - * @deprecated As of JDK version 7, replaced by - * {@link ClassFinder#resolveClass(String)}. - */ - @Deprecated - public static Class classForName(String name) throws ClassNotFoundException { - return ClassFinder.resolveClass(name); - } - - /** - * Returns the Class object associated with - * the class or interface with the given string name, - * using the given class loader. - * - * @param name fully qualified name of the desired class - * @param cl class loader from which the class must be loaded - * @return class object representing the desired class - * - * @exception ClassNotFoundException if the class cannot be located - * by the specified class loader - * - * @deprecated As of JDK version 7, replaced by - * {@link ClassFinder#resolveClass(String,ClassLoader)}. - */ - @Deprecated - public static Class classForName(String name, ClassLoader cl) - throws ClassNotFoundException { - return ClassFinder.resolveClass(name, cl); - } - - private Hashtable environment; - private Vector expStack; - private StringBuffer chars; - private XMLDecoder is; - private ClassLoader ldr; - private int itemsRead = 0; - private boolean isString; - - public ObjectHandler() { - environment = new Hashtable(); - expStack = new Vector(); - chars = new StringBuffer(); - } - - public ObjectHandler(XMLDecoder is) { - this(); - this.is = is; - } - - /* loader can be null */ - public ObjectHandler(XMLDecoder is, ClassLoader loader) { - this(is); - this.ldr = loader; - } - - - public void reset() { - expStack.clear(); - chars.setLength(0); - MutableExpression e = new MutableExpression(); - e.setTarget(classForName2("java.lang.Object")); - e.setMethodName("null"); - expStack.add(e); - } - - private Object getValue(Expression exp) { - try { - return exp.getValue(); - } - catch (Exception e) { - if (is != null) { - is.getExceptionListener().exceptionThrown(e); - } - return null; - } - } - - private void addArg(Object arg) { - lastExp().addArg(arg); - } - - private Object pop(Vector v) { - int last = v.size()-1; - Object result = v.get(last); - v.remove(last); - return result; - } - - private Object eval() { - return getValue(lastExp()); - } - - private MutableExpression lastExp() { - return (MutableExpression)expStack.lastElement(); - } - - public Object dequeueResult() { - Object[] results = lastExp().getArguments(); - return results[itemsRead++]; - } - - private boolean isPrimitive(String name) { - return name != "void" && typeNameToClass(name) != null; - } - - private void simulateException(String message) { - Exception e = new Exception(message); - e.fillInStackTrace(); - if (is != null) { - is.getExceptionListener().exceptionThrown(e); - } - } - - private Class classForName2(String name) { - try { - return ClassFinder.resolveClass(name, this.ldr); - } - catch (ClassNotFoundException e) { - if (is != null) { - is.getExceptionListener().exceptionThrown(e); - } - } - return null; - } - - private HashMap getAttributes(AttributeList attrs) { - HashMap attributes = new HashMap(); - if (attrs != null && attrs.getLength() > 0) { - for(int i = 0; i < attrs.getLength(); i++) { - attributes.put(attrs.getName(i), attrs.getValue(i)); - } - } - return attributes; - } - - public void startElement(String name, AttributeList attrs) throws SAXException { - name = name.intern(); // Xerces parser does not supply unique tag names. - if (this.isString) { - parseCharCode(name, getAttributes(attrs)); - return; - } - chars.setLength(0); - - HashMap attributes = getAttributes(attrs); - MutableExpression e = new MutableExpression(); - - // Target - String className = (String)attributes.get("class"); - if (className != null) { - e.setTarget(classForName2(className)); - } - - // Property - Object property = attributes.get("property"); - String index = (String)attributes.get("index"); - if (index != null) { - property = new Integer(index); - e.addArg(property); - } - e.setProperty(property); - - // Method - String methodName = (String)attributes.get("method"); - if (methodName == null && property == null) { - methodName = "new"; - } - e.setMethodName(methodName); - - // Tags - if (name == "string") { - e.setTarget(String.class); - e.setMethodName("new"); - this.isString = true; - } - else if (isPrimitive(name)){ - Class wrapper = typeNameToClass(name); - e.setTarget(wrapper); - e.setMethodName("new"); - parseCharCode(name, attributes); - } - else if (name == "class") { - e.setTarget(Class.class); - e.setMethodName("forName"); - } - else if (name == "null") { - // Create an arbitrary expression that has a value of null - for - // consistency. - e.setTarget(Object.class); - e.setMethodName("getSuperclass"); - e.setValue(null); - } - else if (name == "void") { - if (e.getTarget() == null) { // this check is for "void class="foo" method= ..." - e.setTarget(eval()); - } - } - else if (name == "array") { - // The class attribute means sub-type for arrays. - String subtypeName = (String)attributes.get("class"); - Class subtype = (subtypeName == null) ? Object.class : classForName2(subtypeName); - String length = (String)attributes.get("length"); - if (length != null) { - e.setTarget(java.lang.reflect.Array.class); - e.addArg(subtype); - e.addArg(new Integer(length)); - } - else { - Class arrayClass = java.lang.reflect.Array.newInstance(subtype, 0).getClass(); - e.setTarget(arrayClass); - } - } - else if (name == "java") { - e.setValue(is); // The outermost scope is the stream itself. - } - else if (name == "object") { - } - else { - simulateException("Unrecognized opening tag: " + name + " " + attrsToString(attrs)); - return; - } - - // ids - String idName = (String)attributes.get("id"); - if (idName != null) { - environment.put(idName, e); - } - - // idrefs - String idrefName = (String)attributes.get("idref"); - if (idrefName != null) { - e.setValue(lookup(idrefName)); - } - - // fields - String fieldName = (String)attributes.get("field"); - if (fieldName != null) { - e.setValue(getFieldValue(e.getTarget(), fieldName)); - } - expStack.add(e); - } - - private Object getFieldValue(Object target, String fieldName) { - try { - Class type = target.getClass(); - if (type == Class.class) { - type = (Class)target; - } - java.lang.reflect.Field f = sun.reflect.misc.FieldUtil.getField(type, fieldName); - return f.get(target); - } - catch (Exception e) { - if (is != null) { - is.getExceptionListener().exceptionThrown(e); - } - return null; - } - } - - private String attrsToString(AttributeList attrs) { - StringBuffer b = new StringBuffer(); - for (int i = 0; i < attrs.getLength (); i++) { - b.append(attrs.getName(i)+"=\""+attrs.getValue(i)+"\" "); - } - return b.toString(); - } - - public void characters(char buf [], int offset, int len) throws SAXException { - chars.append(new String(buf, offset, len)); - } - - private void parseCharCode(String name, Map map) { - if (name == "char") { - String value = (String) map.get("code"); - if (value != null) { - int code = Integer.decode(value); - for (char ch : Character.toChars(code)) { - this.chars.append(ch); - } - } - } - } - - public Object lookup(String s) { - Expression e = (Expression)environment.get(s); - if (e == null) { - simulateException("Unbound variable: " + s); - } - return getValue(e); - } - - public void register(String id, Object value) { - Expression e = new MutableExpression(); - e.setValue(value); - environment.put(id, e); - } - - public void endElement(String name) throws SAXException { - name = name.intern(); // Xerces parser does not supply unique tag names. - if (name == "string") { - this.isString = false; - } else if (this.isString) { - return; - } - if (name == "java") { - return; - } - if (isPrimitive(name) || name == "string" || name == "class") { - addArg(chars.toString()); - } - if (name == "object" || name == "array" || name == "void" || - isPrimitive(name) || name == "string" || name == "class" || - name == "null") { - Expression e = (Expression)pop(expStack); - Object value = getValue(e); - if (name != "void") { - addArg(value); - } - } - else { - simulateException("Unrecognized closing tag: " + name); - } - } -} - - -class MutableExpression extends Expression { - private Object target; - private String methodName; - - private Object property; - private Vector argV = new Vector(); - - private String capitalize(String propertyName) { - if (propertyName.length() == 0) { - return propertyName; - } - return propertyName.substring(0, 1).toUpperCase(ENGLISH) + propertyName.substring(1); - } - - public MutableExpression() { - super(null, null, null); - } - - public Object[] getArguments() { - return argV.toArray(); - } - - public String getMethodName() { - if (property == null) { - return methodName; - } - int setterArgs = (property instanceof String) ? 1 : 2; - String methodName = (argV.size() == setterArgs) ? "set" : "get"; - if (property instanceof String) { - return methodName + capitalize((String)property); - } - else { - return methodName; - } - } - - public void addArg(Object arg) { - argV.add(arg); - } - - public void setTarget(Object target) { - this.target = target; - } - - public Object getTarget() { - return target; - } - - public void setMethodName(String methodName) { - this.methodName = methodName; - } - - public void setProperty(Object property) { - this.property = property; - } - - public void setValue(Object value) { - super.setValue(value); - } - - public Object getValue() throws Exception { - return super.getValue(); - } -} diff --git a/jdk/src/share/classes/com/sun/beans/decoder/AccessorElementHandler.java b/jdk/src/share/classes/com/sun/beans/decoder/AccessorElementHandler.java new file mode 100644 index 00000000000..d34fce45635 --- /dev/null +++ b/jdk/src/share/classes/com/sun/beans/decoder/AccessorElementHandler.java @@ -0,0 +1,105 @@ +/* + * Copyright 2008 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. 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 + * 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. + */ +package com.sun.beans.decoder; + +/** + * This is base class that simplifies access to entities (fields or properties). + * The {@code name} attribute specifies the name of the accessible entity. + * The element defines getter if it contains no argument + * or setter if it contains one argument. + * + * @since 1.7 + * + * @author Sergey A. Malenkov + */ +abstract class AccessorElementHandler extends ElementHandler { + private String name; + private ValueObject value; + + /** + * Parses attributes of the element. + * The following atributes are supported: + *
+ *
name + *
the name of the accessible entity + *
id + *
the identifier of the variable that is intended to store the result + *
+ * + * @param name the attribute name + * @param value the attribute value + */ + @Override + public void addAttribute(String name, String value) { + if (name.equals("name")) { // NON-NLS: the attribute name + this.name = value; + } else { + super.addAttribute(name, value); + } + } + + /** + * Adds the argument that is used to set the value of this element. + * + * @param argument the value of the element that contained in this one + */ + @Override + protected final void addArgument(Object argument) { + if (this.value != null) { + throw new IllegalStateException("Could not add argument to evaluated element"); + } + setValue(this.name, argument); + this.value = ValueObjectImpl.VOID; + } + + /** + * Returns the value of this element. + * + * @return the value of this element + */ + @Override + protected final ValueObject getValueObject() { + if (this.value == null) { + this.value = ValueObjectImpl.create(getValue(this.name)); + } + return this.value; + } + + /** + * Returns the value of the entity with specified {@code name}. + * + * @param name the name of the accessible entity + * @return the value of the specified entity + */ + protected abstract Object getValue(String name); + + /** + * Sets the new value for the entity with specified {@code name}. + * + * @param name the name of the accessible entity + * @param value the new value for the specified entity + */ + protected abstract void setValue(String name, Object value); +} diff --git a/jdk/src/share/classes/com/sun/beans/decoder/ArrayElementHandler.java b/jdk/src/share/classes/com/sun/beans/decoder/ArrayElementHandler.java new file mode 100644 index 00000000000..0bfcec6e46a --- /dev/null +++ b/jdk/src/share/classes/com/sun/beans/decoder/ArrayElementHandler.java @@ -0,0 +1,133 @@ +/* + * Copyright 2008 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. 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 + * 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. + */ +package com.sun.beans.decoder; + +import java.lang.reflect.Array; + +/** + * This class is intended to handle <array> element, + * that is used to array creation. + * The {@code length} attribute specifies the length of the array. + * The {@code class} attribute specifies the elements type. + * The {@link Object} type is used by default. + * For example:
+ * <array length="10"/>
+ * is equivalent to {@code new Component[10]} in Java code. + * The {@code set} and {@code get} methods, + * as defined in the {@link java.util.List} interface, + * can be used as if they could be applied to array instances. + * The {@code index} attribute can thus be used with arrays. + * For example:
+ * <array length="3" class="java.lang.String">
+ *     <void index="1">
+ *         <string>Hello, world</string>
+ *     </void>
+ * </array>
+ * is equivalent to the following Java code:
+ * String[] s = new String[3];
+ * s[1] = "Hello, world";
+ * It is possible to omit the {@code length} attribute and + * specify the values directly, without using {@code void} tags. + * The length of the array is equal to the number of values specified. + * For example:
+ * <array id="array" class="int">
+ *     <int>123</int>
+ *     <int>456</int>
+ * </array>
+ * is equivalent to {@code int[] array = {123, 456}} in Java code. + *

The following atributes are supported: + *

+ *
length + *
the array length + *
class + *
the type of object for instantiation + *
id + *
the identifier of the variable that is intended to store the result + *
+ * + * @since 1.7 + * + * @author Sergey A. Malenkov + */ +final class ArrayElementHandler extends NewElementHandler { + private Integer length; + + /** + * Parses attributes of the element. + * The following atributes are supported: + *
+ *
length + *
the array length + *
class + *
the type of object for instantiation + *
id + *
the identifier of the variable that is intended to store the result + *
+ * + * @param name the attribute name + * @param value the attribute value + */ + @Override + public void addAttribute(String name, String value) { + if (name.equals("length")) { // NON-NLS: the attribute name + this.length = Integer.valueOf(value); + } else { + super.addAttribute(name, value); + } + } + + /** + * Calculates the value of this element + * if the lentgh attribute is set. + */ + @Override + public void startElement() { + if (this.length != null) { + getValueObject(); + } + } + + /** + * Creates an instance of the array. + * + * @param type the base class + * @param args the array of arguments + * @return the value of this element + */ + @Override + protected ValueObject getValueObject(Class type, Object[] args) { + if (type == null) { + type = Object.class; + } + if (this.length != null) { + return ValueObjectImpl.create(Array.newInstance(type, this.length)); + } + Object array = Array.newInstance(type, args.length); + for (int i = 0; i < args.length; i++) { + Array.set(array, i, args[i]); + } + return ValueObjectImpl.create(array); + } +} diff --git a/jdk/src/share/classes/com/sun/beans/decoder/BooleanElementHandler.java b/jdk/src/share/classes/com/sun/beans/decoder/BooleanElementHandler.java new file mode 100644 index 00000000000..a5f401b5f49 --- /dev/null +++ b/jdk/src/share/classes/com/sun/beans/decoder/BooleanElementHandler.java @@ -0,0 +1,69 @@ +/* + * Copyright 2008 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. 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 + * 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. + */ +package com.sun.beans.decoder; + +/** + * This class is intended to handle <boolean> element. + * This element specifies {@code boolean} values. + * The class {@link Boolean} is used as wrapper for these values. + * The result value is created from text of the body of this element. + * The body parsing is described in the class {@link StringElementHandler}. + * For example:
+ * <boolean>true</boolean>
+ * is shortcut to
+ * <method name="valueOf" class="java.lang.Boolean">
+ *     <string>true</string>
+ * </method>
+ * which is equivalent to {@code Boolean.valueOf("true")} in Java code. + *

The following atribute is supported: + *

+ *
id + *
the identifier of the variable that is intended to store the result + *
+ * + * @since 1.7 + * + * @author Sergey A. Malenkov + */ +final class BooleanElementHandler extends StringElementHandler { + + /** + * Creates {@code boolean} value from + * the text of the body of this element. + * + * @param argument the text of the body + * @return evaluated {@code boolean} value + */ + @Override + public Object getValue(String argument) { + if (Boolean.TRUE.toString().equalsIgnoreCase(argument)) { + return Boolean.TRUE; + } + if (Boolean.FALSE.toString().equalsIgnoreCase(argument)) { + return Boolean.FALSE; + } + throw new IllegalArgumentException("Unsupported boolean argument: " + argument); + } +} diff --git a/jdk/src/share/classes/com/sun/beans/decoder/ByteElementHandler.java b/jdk/src/share/classes/com/sun/beans/decoder/ByteElementHandler.java new file mode 100644 index 00000000000..d7d458f0104 --- /dev/null +++ b/jdk/src/share/classes/com/sun/beans/decoder/ByteElementHandler.java @@ -0,0 +1,63 @@ +/* + * Copyright 2008 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. 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 + * 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. + */ +package com.sun.beans.decoder; + +/** + * This class is intended to handle <byte> element. + * This element specifies {@code byte} values. + * The class {@link Byte} is used as wrapper for these values. + * The result value is created from text of the body of this element. + * The body parsing is described in the class {@link StringElementHandler}. + * For example:
+ * <byte>127</byte>
+ * is shortcut to
+ * <method name="decode" class="java.lang.Byte">
+ *     <string>127</string>
+ * </method>
+ * which is equivalent to {@code Byte.decode("127")} in Java code. + *

The following atribute is supported: + *

+ *
id + *
the identifier of the variable that is intended to store the result + *
+ * + * @since 1.7 + * + * @author Sergey A. Malenkov + */ +final class ByteElementHandler extends StringElementHandler { + + /** + * Creates {@code byte} value from + * the text of the body of this element. + * + * @param argument the text of the body + * @return evaluated {@code byte} value + */ + @Override + public Object getValue(String argument) { + return Byte.decode(argument); + } +} diff --git a/jdk/src/share/classes/com/sun/beans/decoder/CharElementHandler.java b/jdk/src/share/classes/com/sun/beans/decoder/CharElementHandler.java new file mode 100644 index 00000000000..910b5a63f70 --- /dev/null +++ b/jdk/src/share/classes/com/sun/beans/decoder/CharElementHandler.java @@ -0,0 +1,92 @@ +/* + * Copyright 2008 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. 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 + * 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. + */ +package com.sun.beans.decoder; + +/** + * This class is intended to handle <char> element. + * This element specifies {@code char} values. + * The class {@link Character} is used as wrapper for these values. + * The result value is created from text of the body of this element. + * The body parsing is described in the class {@link StringElementHandler}. + * For example:
+ * <char>X</char>
+ * which is equivalent to {@code Character.valueOf('X')} in Java code. + *

The following atributes are supported: + *

+ *
code + *
this attribute specifies character code + *
id + *
the identifier of the variable that is intended to store the result + *
+ * The {@code code} attribute can be used for characters + * that are illegal in XML document, for example:
+ * <char code="0"/>
+ * + * @since 1.7 + * + * @author Sergey A. Malenkov + */ +final class CharElementHandler extends StringElementHandler { + + /** + * Parses attributes of the element. + * The following atributes are supported: + *
+ *
code + *
this attribute specifies character code + *
id + *
the identifier of the variable that is intended to store the result + *
+ * + * @param name the attribute name + * @param value the attribute value + */ + @Override + public void addAttribute(String name, String value) { + if (name.equals("code")) { // NON-NLS: the attribute name + int code = Integer.decode(value); + for (char ch : Character.toChars(code)) { + addCharacter(ch); + } + } else { + super.addAttribute(name, value); + } + } + + /** + * Creates {@code char} value from + * the text of the body of this element. + * + * @param argument the text of the body + * @return evaluated {@code char} value + */ + @Override + public Object getValue(String argument) { + if (argument.length() != 1) { + throw new IllegalArgumentException("Wrong characters count"); + } + return Character.valueOf(argument.charAt(0)); + } +} diff --git a/jdk/src/share/classes/com/sun/beans/decoder/ClassElementHandler.java b/jdk/src/share/classes/com/sun/beans/decoder/ClassElementHandler.java new file mode 100644 index 00000000000..c6ca9856416 --- /dev/null +++ b/jdk/src/share/classes/com/sun/beans/decoder/ClassElementHandler.java @@ -0,0 +1,62 @@ +/* + * Copyright 2008 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. 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 + * 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. + */ +package com.sun.beans.decoder; + +/** + * This class is intended to handle <class> element. + * This element specifies {@link Class} values. + * The result value is created from text of the body of this element. + * The body parsing is described in the class {@link StringElementHandler}. + * For example:
+ * <class>java.lang.Class</class>
+ * is shortcut to
+ * <method name="forName" class="java.lang.Class">
+ *     <string>java.lang.Class</string>
+ * </method>
+ * which is equivalent to {@code Class.forName("java.lang.Class")} in Java code. + *

The following atribute is supported: + *

+ *
id + *
the identifier of the variable that is intended to store the result + *
+ * + * @since 1.7 + * + * @author Sergey A. Malenkov + */ +final class ClassElementHandler extends StringElementHandler { + + /** + * Creates class by the name from + * the text of the body of this element. + * + * @param argument the text of the body + * @return evaluated {@code Class} value + */ + @Override + public Object getValue(String argument) { + return getOwner().findClass(argument); + } +} diff --git a/jdk/src/share/classes/com/sun/beans/decoder/DocumentHandler.java b/jdk/src/share/classes/com/sun/beans/decoder/DocumentHandler.java new file mode 100644 index 00000000000..4c409a12a9b --- /dev/null +++ b/jdk/src/share/classes/com/sun/beans/decoder/DocumentHandler.java @@ -0,0 +1,389 @@ +/* + * Copyright 2008 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. 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 + * 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. + */ +package com.sun.beans.decoder; + +import com.sun.beans.finder.ClassFinder; + +import java.beans.ExceptionListener; + +import java.io.IOException; + +import java.lang.ref.Reference; +import java.lang.ref.WeakReference; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParserFactory; + +import org.xml.sax.Attributes; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +/** + * The main class to parse JavaBeans XML archive. + * + * @since 1.7 + * + * @author Sergey A. Malenkov + * + * @see ElementHandler + */ +public final class DocumentHandler extends DefaultHandler { + private final Map> handlers = new HashMap>(); + + private final Map environment = new HashMap(); + + private final List objects = new ArrayList(); + + private Reference loader; + private ExceptionListener listener; + private Object owner; + + private ElementHandler handler; + + /** + * Creates new instance of document handler. + */ + public DocumentHandler() { + setElementHandler("java", JavaElementHandler.class); // NON-NLS: the element name + setElementHandler("null", NullElementHandler.class); // NON-NLS: the element name + setElementHandler("array", ArrayElementHandler.class); // NON-NLS: the element name + setElementHandler("class", ClassElementHandler.class); // NON-NLS: the element name + setElementHandler("string", StringElementHandler.class); // NON-NLS: the element name + setElementHandler("object", ObjectElementHandler.class); // NON-NLS: the element name + + setElementHandler("void", VoidElementHandler.class); // NON-NLS: the element name + setElementHandler("char", CharElementHandler.class); // NON-NLS: the element name + setElementHandler("byte", ByteElementHandler.class); // NON-NLS: the element name + setElementHandler("short", ShortElementHandler.class); // NON-NLS: the element name + setElementHandler("int", IntElementHandler.class); // NON-NLS: the element name + setElementHandler("long", LongElementHandler.class); // NON-NLS: the element name + setElementHandler("float", FloatElementHandler.class); // NON-NLS: the element name + setElementHandler("double", DoubleElementHandler.class); // NON-NLS: the element name + setElementHandler("boolean", BooleanElementHandler.class); // NON-NLS: the element name + + // some handlers for new elements + setElementHandler("new", NewElementHandler.class); // NON-NLS: the element name + setElementHandler("var", VarElementHandler.class); // NON-NLS: the element name + setElementHandler("true", TrueElementHandler.class); // NON-NLS: the element name + setElementHandler("false", FalseElementHandler.class); // NON-NLS: the element name + setElementHandler("field", FieldElementHandler.class); // NON-NLS: the element name + setElementHandler("method", MethodElementHandler.class); // NON-NLS: the element name + setElementHandler("property", PropertyElementHandler.class); // NON-NLS: the element name + } + + /** + * Returns the class loader used to instantiate objects. + * If the class loader has not been explicitly set + * then {@code null} is returned. + * + * @return the class loader used to instantiate objects + */ + public ClassLoader getClassLoader() { + return (this.loader != null) + ? this.loader.get() + : null; + } + + /** + * Sets the class loader used to instantiate objects. + * If the class loader is not set + * then default class loader will be used. + * + * @param loader a classloader to use + */ + public void setClassLoader(ClassLoader loader) { + this.loader = new WeakReference(loader); + } + + /** + * Returns the exception listener for parsing. + * The exception listener is notified + * when handler catches recoverable exceptions. + * If the exception listener has not been explicitly set + * then default exception listener is returned. + * + * @return the exception listener for parsing + */ + public ExceptionListener getExceptionListener() { + return this.listener; + } + + /** + * Sets the exception listener for parsing. + * The exception listener is notified + * when handler catches recoverable exceptions. + * + * @param listener the exception listener for parsing + */ + public void setExceptionListener(ExceptionListener listener) { + this.listener = listener; + } + + /** + * Returns the owner of this document handler. + * + * @return the owner of this document handler + */ + public Object getOwner() { + return this.owner; + } + + /** + * Sets the owner of this document handler. + * + * @param owner the owner of this document handler + */ + public void setOwner(Object owner) { + this.owner = owner; + } + + /** + * Returns the handler for the element with specified name. + * + * @param name the name of the element + * @return the corresponding element handler + */ + public Class getElementHandler(String name) { + Class type = this.handlers.get(name); + if (type == null) { + throw new IllegalArgumentException("Unsupported element: " + name); + } + return type; + } + + /** + * Sets the handler for the element with specified name. + * + * @param name the name of the element + * @param handler the corresponding element handler + */ + public void setElementHandler(String name, Class handler) { + this.handlers.put(name, handler); + } + + /** + * Indicates whether the variable with specified identifier is defined. + * + * @param id the identifier + * @return @{code true} if the variable is defined; + * @{code false} otherwise + */ + public boolean hasVariable(String id) { + return this.environment.containsKey(id); + } + + /** + * Returns the value of the variable with specified identifier. + * + * @param id the identifier + * @return the value of the variable + */ + public Object getVariable(String id) { + if (!this.environment.containsKey(id)) { + throw new IllegalArgumentException("Unbound variable: " + id); + } + return this.environment.get(id); + } + + /** + * Sets new value of the variable with specified identifier. + * + * @param id the identifier + * @param value new value of the variable + */ + public void setVariable(String id, Object value) { + this.environment.put(id, value); + } + + /** + * Returns the array of readed objects. + * + * @return the array of readed objects + */ + public Object[] getObjects() { + return this.objects.toArray(); + } + + /** + * Adds the object to the list of readed objects. + * + * @param object the object that is readed from XML document + */ + void addObject(Object object) { + this.objects.add(object); + } + + /** + * Prepares this handler to read objects from XML document. + */ + @Override + public void startDocument() { + this.objects.clear(); + this.handler = null; + } + + /** + * Parses opening tag of XML element + * using corresponding element handler. + * + * @param uri the namespace URI, or the empty string + * if the element has no namespace URI or + * if namespace processing is not being performed + * @param localName the local name (without prefix), or the empty string + * if namespace processing is not being performed + * @param qName the qualified name (with prefix), or the empty string + * if qualified names are not available + * @param attributes the attributes attached to the element + */ + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { + ElementHandler parent = this.handler; + try { + this.handler = getElementHandler(qName).newInstance(); + this.handler.setOwner(this); + this.handler.setParent(parent); + } + catch (Exception exception) { + throw new SAXException(exception); + } + for (int i = 0; i < attributes.getLength(); i++) + try { + String name = attributes.getQName(i); + String value = attributes.getValue(i); + this.handler.addAttribute(name, value); + } + catch (RuntimeException exception) { + handleException(exception); + } + + this.handler.startElement(); + } + + /** + * Parses closing tag of XML element + * using corresponding element handler. + * + * @param uri the namespace URI, or the empty string + * if the element has no namespace URI or + * if namespace processing is not being performed + * @param localName the local name (without prefix), or the empty string + * if namespace processing is not being performed + * @param qName the qualified name (with prefix), or the empty string + * if qualified names are not available + */ + @Override + public void endElement(String uri, String localName, String qName) { + try { + this.handler.endElement(); + } + catch (RuntimeException exception) { + handleException(exception); + } + finally { + this.handler = this.handler.getParent(); + } + } + + /** + * Parses character data inside XML element. + * + * @param chars the array of characters + * @param start the start position in the character array + * @param length the number of characters to use + */ + @Override + public void characters(char[] chars, int start, int length) { + if (this.handler != null) { + try { + while (0 < length--) { + this.handler.addCharacter(chars[start++]); + } + } + catch (RuntimeException exception) { + handleException(exception); + } + } + } + + /** + * Handles an exception using current exception listener. + * + * @param exception an exception to handle + * @see #setExceptionListener + */ + public void handleException(Exception exception) { + if (this.listener == null) { + throw new IllegalStateException(exception); + } + this.listener.exceptionThrown(exception); + } + + /** + * Starts parsing of the specified input source. + * + * @param input the input source to parse + */ + public void parse(InputSource input) { + try { + SAXParserFactory.newInstance().newSAXParser().parse(input, this); + } + catch (ParserConfigurationException exception) { + handleException(exception); + } + catch (SAXException wrapper) { + Exception exception = wrapper.getException(); + if (exception == null) { + exception = wrapper; + } + handleException(exception); + } + catch (IOException exception) { + handleException(exception); + } + } + + /** + * Resolves class by name using current class loader. + * This method handles exception using current exception listener. + * + * @param name the name of the class + * @return the object that represents the class + */ + public Class findClass(String name) { + try { + return ClassFinder.resolveClass(name, getClassLoader()); + } + catch (ClassNotFoundException exception) { + handleException(exception); + return null; + } + } +} diff --git a/jdk/src/share/classes/com/sun/beans/decoder/DoubleElementHandler.java b/jdk/src/share/classes/com/sun/beans/decoder/DoubleElementHandler.java new file mode 100644 index 00000000000..e0f58677627 --- /dev/null +++ b/jdk/src/share/classes/com/sun/beans/decoder/DoubleElementHandler.java @@ -0,0 +1,63 @@ +/* + * Copyright 2008 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. 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 + * 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. + */ +package com.sun.beans.decoder; + +/** + * This class is intended to handle <double> element. + * This element specifies {@code double} values. + * The class {@link Double} is used as wrapper for these values. + * The result value is created from text of the body of this element. + * The body parsing is described in the class {@link StringElementHandler}. + * For example:
+ * <double>1.23e45</double>
+ * is shortcut to
+ * <method name="valueOf" class="java.lang.Double">
+ *     <string>1.23e45</string>
+ * </method>
+ * which is equivalent to {@code Double.valueOf("1.23e45")} in Java code. + *

The following atribute is supported: + *

+ *
id + *
the identifier of the variable that is intended to store the result + *
+ * + * @since 1.7 + * + * @author Sergey A. Malenkov + */ +final class DoubleElementHandler extends StringElementHandler { + + /** + * Creates {@code double} value from + * the text of the body of this element. + * + * @param argument the text of the body + * @return evaluated {@code double} value + */ + @Override + public Object getValue(String argument) { + return Double.valueOf(argument); + } +} diff --git a/jdk/src/share/classes/com/sun/beans/decoder/ElementHandler.java b/jdk/src/share/classes/com/sun/beans/decoder/ElementHandler.java new file mode 100644 index 00000000000..ca85cd6ed08 --- /dev/null +++ b/jdk/src/share/classes/com/sun/beans/decoder/ElementHandler.java @@ -0,0 +1,224 @@ +/* + * Copyright 2008 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. 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 + * 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. + */ +package com.sun.beans.decoder; + +/** + * The base class for element handlers. + * + * @since 1.7 + * + * @author Sergey A. Malenkov + * + * @see DocumentHandler + */ +public abstract class ElementHandler { + private DocumentHandler owner; + private ElementHandler parent; + + private String id; + + /** + * Returns the document handler that creates this element handler. + * + * @return the owner document handler + */ + public final DocumentHandler getOwner() { + return this.owner; + } + + /** + * Sets the document handler that creates this element handler. + * The owner document handler should be set after instantiation. + * Such approach is used to simplify the extensibility. + * + * @param owner the owner document handler + * @see DocumentHandler#startElement + */ + final void setOwner(DocumentHandler owner) { + if (owner == null) { + throw new IllegalArgumentException("Every element should have owner"); + } + this.owner = owner; + } + + /** + * Returns the element handler that contains this one. + * + * @return the parent element handler + */ + public final ElementHandler getParent() { + return this.parent; + } + + /** + * Sets the element handler that contains this one. + * The parent element handler should be set after instantiation. + * Such approach is used to simplify the extensibility. + * + * @param parent the parent element handler + * @see DocumentHandler#startElement + */ + final void setParent(ElementHandler parent) { + this.parent = parent; + } + + /** + * Returns the value of the variable with specified identifier. + * + * @param id the identifier + * @return the value of the variable + */ + protected final Object getVariable(String id) { + if (id.equals(this.id)) { + ValueObject value = getValueObject(); + if (value.isVoid()) { + throw new IllegalStateException("The element does not return value"); + } + return value.getValue(); + } + return (this.parent != null) + ? this.parent.getVariable(id) + : this.owner.getVariable(id); + } + + /** + * Returns the value of the parent element. + * + * @return the value of the parent element + */ + protected Object getContextBean() { + if (this.parent != null) { + ValueObject value = this.parent.getValueObject(); + if (!value.isVoid()) { + return value.getValue(); + } + throw new IllegalStateException("The outer element does not return value"); + } else { + Object value = this.owner.getOwner(); + if (value != null) { + return value; + } + throw new IllegalStateException("The topmost element does not have context"); + } + } + + /** + * Parses attributes of the element. + * By default, the following atribute is supported: + *
+ *
id + *
the identifier of the variable that is intended to store the result + *
+ * + * @param name the attribute name + * @param value the attribute value + */ + public void addAttribute(String name, String value) { + if (name.equals("id")) { // NON-NLS: the attribute name + this.id = value; + } else { + throw new IllegalArgumentException("Unsupported attribute: " + name); + } + } + + /** + * This method is called before parsing of the element's body. + * All attributes are parsed at this point. + * By default, do nothing. + */ + public void startElement() { + } + + /** + * This method is called after parsing of the element's body. + * By default, it calculates the value of this element. + * The following tasks are executing for any non-void value: + *
    + *
  1. If the {@code id} attribute is set + * the value of the variable with the specified identifier + * is set to the value of this element.
  2. + *
  3. This element is used as an argument of parent element if it is possible.
  4. + *
+ * + * @see #isArgument + */ + public void endElement() { + // do nothing if no value returned + ValueObject value = getValueObject(); + if (!value.isVoid()) { + if (this.id != null) { + this.owner.setVariable(this.id, value.getValue()); + } + if (isArgument()) { + if (this.parent != null) { + this.parent.addArgument(value.getValue()); + } else { + this.owner.addObject(value.getValue()); + } + } + } + } + + /** + * Adds the character that contained in this element. + * By default, only whitespaces are acceptable. + * + * @param ch the character + */ + public void addCharacter(char ch) { + if ((ch != ' ') && (ch != '\n') && (ch != '\t') && (ch != '\r')) { + throw new IllegalStateException("Illegal character with code " + (int) ch); + } + } + + /** + * Adds the argument that is used to calculate the value of this element. + * By default, no arguments are acceptable. + * + * @param argument the value of the element that contained in this one + */ + protected void addArgument(Object argument) { + throw new IllegalStateException("Could not add argument to simple element"); + } + + /** + * Tests whether the value of this element can be used + * as an argument of the element that contained in this one. + * + * @return {@code true} if the value of this element can be used + * as an argument of the element that contained in this one, + * {@code false} otherwise + */ + protected boolean isArgument() { + return this.id == null; + } + + /** + * Returns the value of this element. + * + * @return the value of this element + */ + protected abstract ValueObject getValueObject(); +} diff --git a/jdk/src/share/classes/com/sun/beans/decoder/FalseElementHandler.java b/jdk/src/share/classes/com/sun/beans/decoder/FalseElementHandler.java new file mode 100644 index 00000000000..6e8d786aa14 --- /dev/null +++ b/jdk/src/share/classes/com/sun/beans/decoder/FalseElementHandler.java @@ -0,0 +1,56 @@ +/* + * Copyright 2008 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. 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 + * 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. + */ +package com.sun.beans.decoder; + +/** + * This class is intended to handle <false> element. + * This element specifies {@code false} value. + * It should not contain body or inner elements. + * For example:
+ * <false/>
+ * is equivalent to {@code false} in Java code. + *

The following atribute is supported: + *

+ *
id + *
the identifier of the variable that is intended to store the result + *
+ * + * @since 1.7 + * + * @author Sergey A. Malenkov + */ +final class FalseElementHandler extends NullElementHandler { + + /** + * Returns {@code Boolean.FALSE} + * as a value of <false> element. + * + * @return {@code Boolean.FALSE} by default + */ + @Override + public Object getValue() { + return Boolean.FALSE; + } +} diff --git a/jdk/src/share/classes/com/sun/beans/decoder/FieldElementHandler.java b/jdk/src/share/classes/com/sun/beans/decoder/FieldElementHandler.java new file mode 100644 index 00000000000..ac255dde7fd --- /dev/null +++ b/jdk/src/share/classes/com/sun/beans/decoder/FieldElementHandler.java @@ -0,0 +1,189 @@ +/* + * Copyright 2008 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. 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 + * 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. + */ +package com.sun.beans.decoder; + +import com.sun.beans.finder.FieldFinder; + +import java.lang.reflect.Field; + +/** + * This class is intended to handle <field> element. + * This element simplifies access to the fields. + * If the {@code class} attribute is specified + * this element accesses static field of specified class. + * This element defines getter if it contains no argument. + * It returns the value of the field in this case. + * For example:
+ * <field name="TYPE" class="java.lang.Long"/>
+ * is equivalent to {@code Long.TYPE} in Java code. + * This element defines setter if it contains one argument. + * It does not return the value of the field in this case. + * For example:
+ * <field name="id"><int>0</int></field>
+ * is equivalent to {@code id = 0} in Java code. + *

The following atributes are supported: + *

+ *
name + *
the field name + *
class + *
the type is used for static fields only + *
id + *
the identifier of the variable that is intended to store the result + *
+ * + * @since 1.7 + * + * @author Sergey A. Malenkov + */ +final class FieldElementHandler extends AccessorElementHandler { + private Class type; + + /** + * Parses attributes of the element. + * The following atributes are supported: + *
+ *
name + *
the field name + *
class + *
the type is used for static fields only + *
id + *
the identifier of the variable that is intended to store the result + *
+ * + * @param name the attribute name + * @param value the attribute value + */ + @Override + public void addAttribute(String name, String value) { + if (name.equals("class")) { // NON-NLS: the attribute name + this.type = getOwner().findClass(value); + } else { + super.addAttribute(name, value); + } + } + + /** + * Tests whether the value of this element can be used + * as an argument of the element that contained in this one. + * + * @return {@code true} if the value of this element should be used + * as an argument of the element that contained in this one, + * {@code false} otherwise + */ + @Override + protected boolean isArgument() { + return super.isArgument() && (this.type != null); // only static accessor can be used an argument + } + + /** + * Returns the context of the field. + * The context of the static field is the class object. + * The context of the non-static field is the value of the parent element. + * + * @return the context of the field + */ + @Override + protected Object getContextBean() { + return (this.type != null) + ? this.type + : super.getContextBean(); + } + + /** + * Returns the value of the field with specified {@code name}. + * + * @param name the name of the field + * @return the value of the specified field + */ + @Override + protected Object getValue(String name) { + try { + return getFieldValue(getContextBean(), name); + } + catch (Exception exception) { + getOwner().handleException(exception); + } + return null; + } + + /** + * Sets the new value for the field with specified {@code name}. + * + * @param name the name of the field + * @param value the new value for the specified field + */ + @Override + protected void setValue(String name, Object value) { + try { + setFieldValue(getContextBean(), name, value); + } + catch (Exception exception) { + getOwner().handleException(exception); + } + } + + /** + * Performs the search of the field with specified {@code name} + * in specified context and returns its value. + * + * @param bean the context bean that contains field + * @param name the name of the field + * @return the value of the field + * @throws IllegalAccessException if the field is not accesible + * @throws NoSuchFieldException if the field is not found + */ + static Object getFieldValue(Object bean, String name) throws IllegalAccessException, NoSuchFieldException { + return findField(bean, name).get(bean); + } + + /** + * Performs the search of the field with specified {@code name} + * in specified context and updates its value. + * + * @param bean the context bean that contains field + * @param name the name of the field + * @param value the new value for the field + * @throws IllegalAccessException if the field is not accesible + * @throws NoSuchFieldException if the field is not found + */ + private static void setFieldValue(Object bean, String name, Object value) throws IllegalAccessException, NoSuchFieldException { + findField(bean, name).set(bean, value); + } + + /** + * Performs the search of the field + * with specified {@code name} in specified context. + * + * @param bean the context bean that contains field + * @param name the name of the field + * @return field object that represents found field + * @throws NoSuchFieldException if the field is not found + */ + private static Field findField(Object bean, String name) throws NoSuchFieldException { + return (bean instanceof Class) + ? FieldFinder.findStaticField((Class) bean, name) + : FieldFinder.findField(bean.getClass(), name); + } +} diff --git a/jdk/src/share/classes/com/sun/beans/decoder/FloatElementHandler.java b/jdk/src/share/classes/com/sun/beans/decoder/FloatElementHandler.java new file mode 100644 index 00000000000..08311b49f29 --- /dev/null +++ b/jdk/src/share/classes/com/sun/beans/decoder/FloatElementHandler.java @@ -0,0 +1,63 @@ +/* + * Copyright 2008 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. 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 + * 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. + */ +package com.sun.beans.decoder; + +/** + * This class is intended to handle <float> element. + * This element specifies {@code float} values. + * The class {@link Float} is used as wrapper for these values. + * The result value is created from text of the body of this element. + * The body parsing is described in the class {@link StringElementHandler}. + * For example:
+ * <float>-1.23</float>
+ * is shortcut to
+ * <method name="valueOf" class="java.lang.Float">
+ *     <string>-1.23</string>
+ * </method>
+ * which is equivalent to {@code Float.valueOf("-1.23")} in Java code. + *

The following atribute is supported: + *

+ *
id + *
the identifier of the variable that is intended to store the result + *
+ * + * @since 1.7 + * + * @author Sergey A. Malenkov + */ +final class FloatElementHandler extends StringElementHandler { + + /** + * Creates {@code float} value from + * the text of the body of this element. + * + * @param argument the text of the body + * @return evaluated {@code float} value + */ + @Override + public Object getValue(String argument) { + return Float.valueOf(argument); + } +} diff --git a/jdk/src/share/classes/com/sun/beans/decoder/IntElementHandler.java b/jdk/src/share/classes/com/sun/beans/decoder/IntElementHandler.java new file mode 100644 index 00000000000..ec5063fcd8e --- /dev/null +++ b/jdk/src/share/classes/com/sun/beans/decoder/IntElementHandler.java @@ -0,0 +1,63 @@ +/* + * Copyright 2008 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. 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 + * 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. + */ +package com.sun.beans.decoder; + +/** + * This class is intended to handle <int> element. + * This element specifies {@code int} values. + * The class {@link Integer} is used as wrapper for these values. + * The result value is created from text of the body of this element. + * The body parsing is described in the class {@link StringElementHandler}. + * For example:
+ * <int>-1</int>
+ * is shortcut to
+ * <method name="decode" class="java.lang.Integer">
+ *     <string>-1</string>
+ * </method>
+ * which is equivalent to {@code Integer.decode("-1")} in Java code. + *

The following atribute is supported: + *

+ *
id + *
the identifier of the variable that is intended to store the result + *
+ * + * @since 1.7 + * + * @author Sergey A. Malenkov + */ +final class IntElementHandler extends StringElementHandler { + + /** + * Creates {@code int} value from + * the text of the body of this element. + * + * @param argument the text of the body + * @return evaluated {@code int} value + */ + @Override + public Object getValue(String argument) { + return Integer.decode(argument); + } +} diff --git a/jdk/src/share/classes/com/sun/beans/decoder/JavaElementHandler.java b/jdk/src/share/classes/com/sun/beans/decoder/JavaElementHandler.java new file mode 100644 index 00000000000..2d416a139fb --- /dev/null +++ b/jdk/src/share/classes/com/sun/beans/decoder/JavaElementHandler.java @@ -0,0 +1,151 @@ +/* + * Copyright 2008 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. 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 + * 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. + */ +package com.sun.beans.decoder; + +import java.beans.XMLDecoder; + +/** + * This class is intended to handle <java> element. + * Each element that appears in the body of this element + * is evaluated in the context of the decoder itself. + * Typically this outer context is used to retrieve the owner of the decoder, + * which can be set before reading the archive. + *

The following atributes are supported: + *

+ *
version + *
the Java version (not supported) + *
class + *
the type of preferable parser (not supported) + *
id + *
the identifier of the variable that is intended to store the result + *
+ * + * @see DocumentHandler#getOwner + * @see DocumentHandler#setOwner + * @since 1.7 + * + * @author Sergey A. Malenkov + */ +final class JavaElementHandler extends ElementHandler { + private Class type; + private ValueObject value; + + /** + * Parses attributes of the element. + * The following atributes are supported: + *
+ *
version + *
the Java version (not supported) + *
class + *
the type of preferable parser (not supported) + *
id + *
the identifier of the variable that is intended to store the result + *
+ * + * @param name the attribute name + * @param value the attribute value + */ + @Override + public void addAttribute(String name, String value) { + if (name.equals("version")) { // NON-NLS: the attribute name + // unsupported attribute + } else if (name.equals("class")) { // NON-NLS: the attribute name + // check class for owner + this.type = getOwner().findClass(value); + } else { + super.addAttribute(name, value); + } + } + + /** + * Adds the argument to the list of readed objects. + * + * @param argument the value of the element that contained in this one + */ + @Override + protected void addArgument(Object argument) { + getOwner().addObject(argument); + } + + /** + * Tests whether the value of this element can be used + * as an argument of the element that contained in this one. + * + * @return {@code true} if the value of this element should be used + * as an argument of the element that contained in this one, + * {@code false} otherwise + */ + @Override + protected boolean isArgument() { + return false; // do not use owner as object + } + + /** + * Returns the value of this element. + * + * @return the value of this element + */ + @Override + protected ValueObject getValueObject() { + if (this.value == null) { + this.value = ValueObjectImpl.create(getValue()); + } + return this.value; + } + + /** + * Returns the owner of the owner document handler + * as a value of <java> element. + * + * @return the owner of the owner document handler + */ + private Object getValue() { + Object owner = getOwner().getOwner(); + if ((this.type == null) || isValid(owner)) { + return owner; + } + if (owner instanceof XMLDecoder) { + XMLDecoder decoder = (XMLDecoder) owner; + owner = decoder.getOwner(); + if (isValid(owner)) { + return owner; + } + } + throw new IllegalStateException("Unexpected owner class: " + owner.getClass().getName()); + } + + /** + * Validates the owner of the <java> element. + * The owner is valid if it is {@code null} or an instance + * of the class specified by the {@code class} attribute. + * + * @param owner the owner of the <java> element + * @return {@code true} if the {@code owner} is valid; + * {@code false} otherwise + */ + private boolean isValid(Object owner) { + return (owner == null) || this.type.isInstance(owner); + } +} diff --git a/jdk/src/share/classes/com/sun/beans/decoder/LongElementHandler.java b/jdk/src/share/classes/com/sun/beans/decoder/LongElementHandler.java new file mode 100644 index 00000000000..a26f2f57fb6 --- /dev/null +++ b/jdk/src/share/classes/com/sun/beans/decoder/LongElementHandler.java @@ -0,0 +1,63 @@ +/* + * Copyright 2008 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. 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 + * 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. + */ +package com.sun.beans.decoder; + +/** + * This class is intended to handle <long> element. + * This element specifies {@code long} values. + * The class {@link Long} is used as wrapper for these values. + * The result value is created from text of the body of this element. + * The body parsing is described in the class {@link StringElementHandler}. + * For example:
+ * <long>0xFFFF</long>
+ * is shortcut to
+ * <method name="decode" class="java.lang.Long">
+ *     <string>0xFFFF</string>
+ * </method>
+ * which is equivalent to {@code Long.decode("0xFFFF")} in Java code. + *

The following atribute is supported: + *

+ *
id + *
the identifier of the variable that is intended to store the result + *
+ * + * @since 1.7 + * + * @author Sergey A. Malenkov + */ +final class LongElementHandler extends StringElementHandler { + + /** + * Creates {@code long} value from + * the text of the body of this element. + * + * @param argument the text of the body + * @return evaluated {@code long} value + */ + @Override + public Object getValue(String argument) { + return Long.decode(argument); + } +} diff --git a/jdk/src/share/classes/com/sun/beans/decoder/MethodElementHandler.java b/jdk/src/share/classes/com/sun/beans/decoder/MethodElementHandler.java new file mode 100644 index 00000000000..34d030c90b3 --- /dev/null +++ b/jdk/src/share/classes/com/sun/beans/decoder/MethodElementHandler.java @@ -0,0 +1,109 @@ +/* + * Copyright 2008 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. 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 + * 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. + */ +package com.sun.beans.decoder; + +import com.sun.beans.finder.MethodFinder; + +import java.lang.reflect.Method; + +/** + * This class is intended to handle <method> element. + * It describes invocation of the method. + * The {@code name} attribute denotes + * the name of the method to invoke. + * If the {@code class} attribute is specified + * this element invokes static method of specified class. + * The inner elements specifies the arguments of the method. + * For example:
+ * <method name="valueOf" class="java.lang.Long">
+ *     <string>10</string>
+ * </method>
+ * is equivalent to {@code Long.valueOf("10")} in Java code. + *

The following atributes are supported: + *

+ *
name + *
the method name + *
class + *
the type of object for instantiation + *
id + *
the identifier of the variable that is intended to store the result + *
+ * + * @since 1.7 + * + * @author Sergey A. Malenkov + */ +final class MethodElementHandler extends NewElementHandler { + private String name; + + /** + * Parses attributes of the element. + * The following atributes are supported: + *
+ *
name + *
the method name + *
class + *
the type of object for instantiation + *
id + *
the identifier of the variable that is intended to store the result + *
+ * + * @param name the attribute name + * @param value the attribute value + */ + @Override + public void addAttribute(String name, String value) { + if (name.equals("name")) { // NON-NLS: the attribute name + this.name = value; + } else { + super.addAttribute(name, value); + } + } + + /** + * Returns the result of method execution. + * + * @param type the base class + * @param args the array of arguments + * @return the value of this element + * @throws Exception if calculation is failed + */ + @Override + protected ValueObject getValueObject(Class type, Object[] args) throws Exception { + Object bean = getContextBean(); + Class[] types = getArgumentTypes(args); + Method method = (type != null) + ? MethodFinder.findStaticMethod(type, this.name, types) + : MethodFinder.findMethod(bean.getClass(), this.name, types); + + if (method.isVarArgs()) { + args = getArguments(args, method.getParameterTypes()); + } + Object value = method.invoke(bean, args); + return method.getReturnType().equals(void.class) + ? ValueObjectImpl.VOID + : ValueObjectImpl.create(value); + } +} diff --git a/jdk/src/share/classes/com/sun/beans/decoder/NewElementHandler.java b/jdk/src/share/classes/com/sun/beans/decoder/NewElementHandler.java new file mode 100644 index 00000000000..fc7debfc500 --- /dev/null +++ b/jdk/src/share/classes/com/sun/beans/decoder/NewElementHandler.java @@ -0,0 +1,205 @@ +/* + * Copyright 2008 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. 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 + * 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. + */ +package com.sun.beans.decoder; + +import com.sun.beans.finder.ConstructorFinder; + +import java.lang.reflect.Array; +import java.lang.reflect.Constructor; + +import java.util.ArrayList; +import java.util.List; + +/** + * This class is intended to handle <new> element. + * It describes instantiation of the object. + * The {@code class} attribute denotes + * the name of the class to instantiate. + * The inner elements specifies the arguments of the constructor. + * For example:
+ * <new class="java.lang.Long">
+ *     <string>10</string>
+ * </new>
+ * is equivalent to {@code new Long("10")} in Java code. + *

The following atributes are supported: + *

+ *
class + *
the type of object for instantiation + *
id + *
the identifier of the variable that is intended to store the result + *
+ * + * @since 1.7 + * + * @author Sergey A. Malenkov + */ +class NewElementHandler extends ElementHandler { + private List arguments = new ArrayList(); + private ValueObject value = ValueObjectImpl.VOID; + + private Class type; + + /** + * Parses attributes of the element. + * The following atributes are supported: + *
+ *
class + *
the type of object for instantiation + *
id + *
the identifier of the variable that is intended to store the result + *
+ * + * @param name the attribute name + * @param value the attribute value + */ + @Override + public void addAttribute(String name, String value) { + if (name.equals("class")) { // NON-NLS: the attribute name + this.type = getOwner().findClass(value); + } else { + super.addAttribute(name, value); + } + } + + /** + * Adds the argument to the list of arguments + * that is used to calculate the value of this element. + * + * @param argument the value of the element that contained in this one + */ + @Override + protected final void addArgument(Object argument) { + if (this.arguments == null) { + throw new IllegalStateException("Could not add argument to evaluated element"); + } + this.arguments.add(argument); + } + + /** + * Returns the context of the method. + * The context of the static method is the class object. + * The context of the non-static method is the value of the parent element. + * + * @return the context of the method + */ + @Override + protected final Object getContextBean() { + return (this.type != null) + ? this.type + : super.getContextBean(); + } + + /** + * Returns the value of this element. + * + * @return the value of this element + */ + @Override + protected final ValueObject getValueObject() { + if (this.arguments != null) { + try { + this.value = getValueObject(this.type, this.arguments.toArray()); + } + catch (Exception exception) { + getOwner().handleException(exception); + } + finally { + this.arguments = null; + } + } + return this.value; + } + + /** + * Calculates the value of this element + * using the base class and the array of arguments. + * By default, it creates an instance of the base class. + * This method should be overridden in those handlers + * that extend behavior of this element. + * + * @param type the base class + * @param args the array of arguments + * @return the value of this element + * @throws Exception if calculation is failed + */ + ValueObject getValueObject(Class type, Object[] args) throws Exception { + if (type == null) { + throw new IllegalArgumentException("Class name is not set"); + } + Class[] types = getArgumentTypes(args); + Constructor constructor = ConstructorFinder.findConstructor(type, types); + if (constructor.isVarArgs()) { + args = getArguments(args, constructor.getParameterTypes()); + } + return ValueObjectImpl.create(constructor.newInstance(args)); + } + + /** + * Converts the array of arguments to the array of corresponding classes. + * If argument is {@code null} the class is {@code null} too. + * + * @param arguments the array of arguments + * @return the array of corresponding classes + */ + static Class[] getArgumentTypes(Object[] arguments) { + Class[] types = new Class[arguments.length]; + for (int i = 0; i < arguments.length; i++) { + if (arguments[i] != null) { + types[i] = arguments[i].getClass(); + } + } + return types; + } + + /** + * Resolves variable arguments. + * + * @param arguments the array of arguments + * @param types the array of parameter types + * @return the resolved array of arguments + */ + static Object[] getArguments(Object[] arguments, Class[] types) { + int index = types.length - 1; + if (types.length == arguments.length) { + Object argument = arguments[index]; + if (argument == null) { + return arguments; + } + Class type = types[index]; + if (type.isAssignableFrom(argument.getClass())) { + return arguments; + } + } + int length = arguments.length - index; + Class type = types[index].getComponentType(); + Object array = Array.newInstance(type, length); + System.arraycopy(arguments, index, array, 0, length); + + Object[] args = new Object[types.length]; + System.arraycopy(arguments, 0, args, 0, index); + args[index] = array; + return args; + } +} diff --git a/jdk/src/share/classes/com/sun/beans/decoder/NullElementHandler.java b/jdk/src/share/classes/com/sun/beans/decoder/NullElementHandler.java new file mode 100644 index 00000000000..a3e2d699c39 --- /dev/null +++ b/jdk/src/share/classes/com/sun/beans/decoder/NullElementHandler.java @@ -0,0 +1,76 @@ +/* + * Copyright 2008 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. 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 + * 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. + */ +package com.sun.beans.decoder; + +/** + * This class is intended to handle <null> element. + * This element specifies {@code null} value. + * It should not contain body or inner elements. + * For example:
+ * <null/>
+ * is equivalent to {@code null} in Java code. + *

The following atribute is supported: + *

+ *
id + *
the identifier of the variable that is intended to store the result + *
+ * + * @since 1.7 + * + * @author Sergey A. Malenkov + */ +class NullElementHandler extends ElementHandler implements ValueObject { + + /** + * Returns the value of this element. + * + * @return the value of this element + */ + @Override + protected final ValueObject getValueObject() { + return this; + } + + /** + * Returns {@code null} + * as a value of <null> element. + * This method should be overridden in those handlers + * that extend behavior of this element. + * + * @return {@code null} by default + */ + public Object getValue() { + return null; + } + + /** + * Returns {@code void} state of this value object. + * + * @return {@code false} always + */ + public final boolean isVoid() { + return false; + } +} diff --git a/jdk/src/share/classes/com/sun/beans/decoder/ObjectElementHandler.java b/jdk/src/share/classes/com/sun/beans/decoder/ObjectElementHandler.java new file mode 100644 index 00000000000..3ab5ddca942 --- /dev/null +++ b/jdk/src/share/classes/com/sun/beans/decoder/ObjectElementHandler.java @@ -0,0 +1,168 @@ +/* + * Copyright 2008 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. 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 + * 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. + */ +package com.sun.beans.decoder; + +import java.beans.Expression; + +import static java.util.Locale.ENGLISH; + +/** + * This class is intended to handle <object> element. + * This element looks like <void> element, + * but its value is always used as an argument for element + * that contains this one. + *

The following atributes are supported: + *

+ *
class + *
the type is used for static methods and fields + *
method + *
the method name + *
property + *
the property name + *
index + *
the property index + *
field + *
the field name + *
idref + *
the identifier to refer to the variable + *
id + *
the identifier of the variable that is intended to store the result + *
+ * + * @since 1.7 + * + * @author Sergey A. Malenkov + */ +class ObjectElementHandler extends NewElementHandler { + private String idref; + private String field; + private Integer index; + private String property; + private String method; + + /** + * Parses attributes of the element. + * The following atributes are supported: + *
+ *
class + *
the type is used for static methods and fields + *
method + *
the method name + *
property + *
the property name + *
index + *
the property index + *
field + *
the field name + *
idref + *
the identifier to refer to the variable + *
id + *
the identifier of the variable that is intended to store the result + *
+ * + * @param name the attribute name + * @param value the attribute value + */ + @Override + public final void addAttribute(String name, String value) { + if (name.equals("idref")) { // NON-NLS: the attribute name + this.idref = value; + } else if (name.equals("field")) { // NON-NLS: the attribute name + this.field = value; + } else if (name.equals("index")) { // NON-NLS: the attribute name + this.index = Integer.valueOf(value); + addArgument(this.index); // hack for compatibility + } else if (name.equals("property")) { // NON-NLS: the attribute name + this.property = value; + } else if (name.equals("method")) { // NON-NLS: the attribute name + this.method = value; + } else { + super.addAttribute(name, value); + } + } + + /** + * Calculates the value of this element + * if the field attribute or the idref attribute is set. + */ + @Override + public final void startElement() { + if ((this.field != null) || (this.idref != null)) { + getValueObject(); + } + } + + /** + * Tests whether the value of this element can be used + * as an argument of the element that contained in this one. + * + * @return {@code true} if the value of this element can be used + * as an argument of the element that contained in this one, + * {@code false} otherwise + */ + @Override + protected boolean isArgument() { + return true; // hack for compatibility + } + + /** + * Creates the value of this element. + * + * @param type the base class + * @param args the array of arguments + * @return the value of this element + * @throws Exception if calculation is failed + */ + @Override + protected final ValueObject getValueObject(Class type, Object[] args) throws Exception { + if (this.field != null) { + return ValueObjectImpl.create(FieldElementHandler.getFieldValue(getContextBean(), this.field)); + } + if (this.idref != null) { + return ValueObjectImpl.create(getVariable(this.idref)); + } + Object bean = getContextBean(); + String name; + if (this.index != null) { + name = (args.length == 2) + ? PropertyElementHandler.SETTER + : PropertyElementHandler.GETTER; + } else if (this.property != null) { + name = (args.length == 1) + ? PropertyElementHandler.SETTER + : PropertyElementHandler.GETTER; + + if (0 < this.property.length()) { + name += this.property.substring(0, 1).toUpperCase(ENGLISH) + this.property.substring(1); + } + } else { + name = (this.method != null) && (0 < this.method.length()) + ? this.method + : "new"; // NON-NLS: the constructor marker + } + Expression expression = new Expression(bean, name, args); + return ValueObjectImpl.create(expression.getValue()); + } +} diff --git a/jdk/src/share/classes/com/sun/beans/decoder/PropertyElementHandler.java b/jdk/src/share/classes/com/sun/beans/decoder/PropertyElementHandler.java new file mode 100644 index 00000000000..dcc55062945 --- /dev/null +++ b/jdk/src/share/classes/com/sun/beans/decoder/PropertyElementHandler.java @@ -0,0 +1,287 @@ +/* + * Copyright 2008 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. 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 + * 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. + */ +package com.sun.beans.decoder; + +import com.sun.beans.finder.MethodFinder; + +import java.beans.IndexedPropertyDescriptor; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; + +import java.lang.reflect.Array; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * This class is intended to handle <property> element. + * This element simplifies access to the properties. + * If the {@code index} attribute is specified + * this element uses additional {@code int} parameter. + * If the {@code name} attribute is not specified + * this element uses method "get" as getter + * and method "set" as setter. + * This element defines getter if it contains no argument. + * It returns the value of the property in this case. + * For example:
+ * <property name="object" index="10"/>
+ * is shortcut to
+ * <method name="getObject">
+ *     <int>10</int>
+ * </method>
+ * which is equivalent to {@code getObject(10)} in Java code. + * This element defines setter if it contains one argument. + * It does not return the value of the property in this case. + * For example:
+ * <property><int>0</int></property>
+ * is shortcut to
+ * <method name="set">
+ *     <int>0</int>
+ * </method>
+ * which is equivalent to {@code set(0)} in Java code. + *

The following atributes are supported: + *

+ *
name + *
the property name + *
index + *
the property index + *
id + *
the identifier of the variable that is intended to store the result + *
+ * + * @since 1.7 + * + * @author Sergey A. Malenkov + */ +final class PropertyElementHandler extends AccessorElementHandler { + static final String GETTER = "get"; // NON-NLS: the getter prefix + static final String SETTER = "set"; // NON-NLS: the setter prefix + + private Integer index; + + /** + * Parses attributes of the element. + * The following atributes are supported: + *
+ *
name + *
the property name + *
index + *
the property index + *
id + *
the identifier of the variable that is intended to store the result + *
+ * + * @param name the attribute name + * @param value the attribute value + */ + @Override + public void addAttribute(String name, String value) { + if (name.equals("index")) { // NON-NLS: the attribute name + this.index = Integer.valueOf(value); + } else { + super.addAttribute(name, value); + } + } + + /** + * Tests whether the value of this element can be used + * as an argument of the element that contained in this one. + * + * @return {@code true} if the value of this element should be used + * as an argument of the element that contained in this one, + * {@code false} otherwise + */ + @Override + protected boolean isArgument() { + return false; // non-static accessor cannot be used an argument + } + + /** + * Returns the value of the property with specified {@code name}. + * + * @param name the name of the property + * @return the value of the specified property + */ + @Override + protected Object getValue(String name) { + try { + return getPropertyValue(getContextBean(), name, this.index); + } + catch (Exception exception) { + getOwner().handleException(exception); + } + return null; + } + + /** + * Sets the new value for the property with specified {@code name}. + * + * @param name the name of the property + * @param value the new value for the specified property + */ + @Override + protected void setValue(String name, Object value) { + try { + setPropertyValue(getContextBean(), name, this.index, value); + } + catch (Exception exception) { + getOwner().handleException(exception); + } + } + + /** + * Performs the search of the getter for the property + * with specified {@code name} in specified class + * and returns value of the property. + * + * @param bean the context bean that contains property + * @param name the name of the property + * @param index the index of the indexed property + * @return the value of the property + * @throws IllegalAccessException if the property is not accesible + * @throws IntrospectionException if the bean introspection is failed + * @throws InvocationTargetException if the getter cannot be invoked + * @throws NoSuchMethodException if the getter is not found + */ + private static Object getPropertyValue(Object bean, String name, Integer index) throws IllegalAccessException, IntrospectionException, InvocationTargetException, NoSuchMethodException { + Class type = bean.getClass(); + if (index == null) { + return findGetter(type, name).invoke(bean); + } else if (type.isArray() && (name == null)) { + return Array.get(bean, index); + } else { + return findGetter(type, name, int.class).invoke(bean, index); + } + } + + /** + * Performs the search of the setter for the property + * with specified {@code name} in specified class + * and updates value of the property. + * + * @param bean the context bean that contains property + * @param name the name of the property + * @param index the index of the indexed property + * @param value the new value for the property + * @throws IllegalAccessException if the property is not accesible + * @throws IntrospectionException if the bean introspection is failed + * @throws InvocationTargetException if the setter cannot be invoked + * @throws NoSuchMethodException if the setter is not found + */ + private static void setPropertyValue(Object bean, String name, Integer index, Object value) throws IllegalAccessException, IntrospectionException, InvocationTargetException, NoSuchMethodException { + Class type = bean.getClass(); + Class param = (value != null) + ? value.getClass() + : null; + + if (index == null) { + findSetter(type, name, param).invoke(bean, value); + } else if (type.isArray() && (name == null)) { + Array.set(bean, index, value); + } else { + findSetter(type, name, int.class, param).invoke(bean, index, value); + } + } + + /** + * Performs the search of the getter for the property + * with specified {@code name} in specified class. + * + * @param type the class that contains method + * @param name the name of the property + * @param args the method arguments + * @return method object that represents found getter + * @throws IntrospectionException if the bean introspection is failed + * @throws NoSuchMethodException if method is not found + */ + private static Method findGetter(Class type, String name, Class...args) throws IntrospectionException, NoSuchMethodException { + if (name == null) { + return MethodFinder.findInstanceMethod(type, GETTER, args); + } + PropertyDescriptor pd = getProperty(type, name); + if (args.length == 0) { + Method method = pd.getReadMethod(); + if (method != null) { + return method; + } + } else if (pd instanceof IndexedPropertyDescriptor) { + IndexedPropertyDescriptor ipd = (IndexedPropertyDescriptor) pd; + Method method = ipd.getIndexedReadMethod(); + if (method != null) { + return method; + } + } + throw new IntrospectionException("Could not find getter for the " + name + " property"); + } + + /** + * Performs the search of the setter for the property + * with specified {@code name} in specified class. + * + * @param type the class that contains method + * @param name the name of the property + * @param args the method arguments + * @return method object that represents found setter + * @throws IntrospectionException if the bean introspection is failed + * @throws NoSuchMethodException if method is not found + */ + private static Method findSetter(Class type, String name, Class...args) throws IntrospectionException, NoSuchMethodException { + if (name == null) { + return MethodFinder.findInstanceMethod(type, SETTER, args); + } + PropertyDescriptor pd = getProperty(type, name); + if (args.length == 1) { + Method method = pd.getWriteMethod(); + if (method != null) { + return method; + } + } else if (pd instanceof IndexedPropertyDescriptor) { + IndexedPropertyDescriptor ipd = (IndexedPropertyDescriptor) pd; + Method method = ipd.getIndexedWriteMethod(); + if (method != null) { + return method; + } + } + throw new IntrospectionException("Could not find setter for the " + name + " property"); + } + + /** + * Performs the search of the descriptor for the property + * with specified {@code name} in specified class. + * + * @param type the class to introspect + * @param name the property name + * @return descriptor for the named property + * @throws IntrospectionException if property descriptor is not found + */ + private static PropertyDescriptor getProperty(Class type, String name) throws IntrospectionException { + for (PropertyDescriptor pd : Introspector.getBeanInfo(type).getPropertyDescriptors()) { + if (name.equals(pd.getName())) { + return pd; + } + } + throw new IntrospectionException("Could not find the " + name + " property descriptor"); + } +} diff --git a/jdk/src/share/classes/com/sun/beans/decoder/ShortElementHandler.java b/jdk/src/share/classes/com/sun/beans/decoder/ShortElementHandler.java new file mode 100644 index 00000000000..5f91e254424 --- /dev/null +++ b/jdk/src/share/classes/com/sun/beans/decoder/ShortElementHandler.java @@ -0,0 +1,63 @@ +/* + * Copyright 2008 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. 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 + * 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. + */ +package com.sun.beans.decoder; + +/** + * This class is intended to handle <short> element. + * This element specifies {@code short} values. + * The class {@link Short} is used as wrapper for these values. + * The result value is created from text of the body of this element. + * The body parsing is described in the class {@link StringElementHandler}. + * For example:
+ * <short>200</short>
+ * is shortcut to
+ * <method name="decode" class="java.lang.Short">
+ *     <string>200</string>
+ * </method>
+ * which is equivalent to {@code Short.decode("200")} in Java code. + *

The following atribute is supported: + *

+ *
id + *
the identifier of the variable that is intended to store the result + *
+ * + * @since 1.7 + * + * @author Sergey A. Malenkov + */ +final class ShortElementHandler extends StringElementHandler { + + /** + * Creates {@code short} value from + * the text of the body of this element. + * + * @param argument the text of the body + * @return evaluated {@code short} value + */ + @Override + public Object getValue(String argument) { + return Short.decode(argument); + } +} diff --git a/jdk/src/share/classes/com/sun/beans/decoder/StringElementHandler.java b/jdk/src/share/classes/com/sun/beans/decoder/StringElementHandler.java new file mode 100644 index 00000000000..6075f436aa0 --- /dev/null +++ b/jdk/src/share/classes/com/sun/beans/decoder/StringElementHandler.java @@ -0,0 +1,116 @@ +/* + * Copyright 2008 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. 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 + * 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. + */ +package com.sun.beans.decoder; + +/** + * This class is intended to handle <string> element. + * This element specifies {@link String} values. + * The result value is created from text of the body of this element. + * For example:
+ * <string>description</string>
+ * is equivalent to {@code "description"} in Java code. + * The value of inner element is calculated + * before adding to the string using {@link String#valueOf(Object)}. + * Note that all characters are used including whitespaces (' ', '\t', '\n', '\r'). + * So the value of the element
+ * <string><true></string>
+ * is not equal to the value of the element
+ * <string>
+ *     <true>
+ * </string>
+ *

The following atribute is supported: + *

+ *
id + *
the identifier of the variable that is intended to store the result + *
+ * + * @since 1.7 + * + * @author Sergey A. Malenkov + */ +public class StringElementHandler extends ElementHandler { + private StringBuilder sb = new StringBuilder(); + private ValueObject value = ValueObjectImpl.NULL; + + /** + * Adds the character that contained in this element. + * + * @param ch the character + */ + @Override + public final void addCharacter(char ch) { + if (this.sb == null) { + throw new IllegalStateException("Could not add chararcter to evaluated string element"); + } + this.sb.append(ch); + } + + /** + * Adds the string value of the argument to the string value of this element. + * + * @param argument the value of the element that contained in this one + */ + @Override + protected final void addArgument(Object argument) { + if (this.sb == null) { + throw new IllegalStateException("Could not add argument to evaluated string element"); + } + this.sb.append(argument); + } + + /** + * Returns the value of this element. + * + * @return the value of this element + */ + @Override + protected final ValueObject getValueObject() { + if (this.sb != null) { + try { + this.value = ValueObjectImpl.create(getValue(this.sb.toString())); + } + catch (RuntimeException exception) { + getOwner().handleException(exception); + } + finally { + this.sb = null; + } + } + return this.value; + } + + /** + * Returns the text of the body of this element. + * This method evaluates value from text of the body, + * and should be overridden in those handlers + * that extend behavior of this element. + * + * @param argument the text of the body + * @return evaluated value + */ + protected Object getValue(String argument) { + return argument; + } +} diff --git a/jdk/src/share/classes/com/sun/beans/decoder/TrueElementHandler.java b/jdk/src/share/classes/com/sun/beans/decoder/TrueElementHandler.java new file mode 100644 index 00000000000..faf8904d4d0 --- /dev/null +++ b/jdk/src/share/classes/com/sun/beans/decoder/TrueElementHandler.java @@ -0,0 +1,56 @@ +/* + * Copyright 2008 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. 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 + * 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. + */ +package com.sun.beans.decoder; + +/** + * This class is intended to handle <true> element. + * This element specifies {@code true} value. + * It should not contain body or inner elements. + * For example:
+ * <true/>
+ * is equivalent to {@code true} in Java code. + *

The following atribute is supported: + *

+ *
id + *
the identifier of the variable that is intended to store the result + *
+ * + * @since 1.7 + * + * @author Sergey A. Malenkov + */ +final class TrueElementHandler extends NullElementHandler { + + /** + * Returns {@code Boolean.TRUE} + * as a value of <true> element. + * + * @return {@code Boolean.TRUE} by default + */ + @Override + public Object getValue() { + return Boolean.TRUE; + } +} diff --git a/jdk/src/share/classes/com/sun/beans/decoder/ValueObject.java b/jdk/src/share/classes/com/sun/beans/decoder/ValueObject.java new file mode 100644 index 00000000000..04f28278e34 --- /dev/null +++ b/jdk/src/share/classes/com/sun/beans/decoder/ValueObject.java @@ -0,0 +1,50 @@ +/* + * Copyright 2008 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. 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 + * 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. + */ +package com.sun.beans.decoder; + +/** + * This interface represents the result of method execution. + * + * @since 1.7 + * + * @author Sergey A. Malenkov + */ +public interface ValueObject { + + /** + * Returns the result of method execution. + * + * @return the result of method execution + */ + Object getValue(); + + /** + * Returns {@code void} state of this value object. + * + * @return {@code true} if value can be ignored, + * {@code false} otherwise + */ + boolean isVoid(); +} diff --git a/jdk/src/share/classes/com/sun/beans/decoder/ValueObjectImpl.java b/jdk/src/share/classes/com/sun/beans/decoder/ValueObjectImpl.java new file mode 100644 index 00000000000..cb891fe6c61 --- /dev/null +++ b/jdk/src/share/classes/com/sun/beans/decoder/ValueObjectImpl.java @@ -0,0 +1,88 @@ +/* + * Copyright 2008 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. 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 + * 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. + */ +package com.sun.beans.decoder; + +/** + * This utility class provides {@code static} method + * to create the object that contains the result of method execution. + * + * @since 1.7 + * + * @author Sergey A. Malenkov + */ +final class ValueObjectImpl implements ValueObject { + static final ValueObject NULL = new ValueObjectImpl(null); + static final ValueObject VOID = new ValueObjectImpl(); + + /** + * Returns the object that describes returning value. + * + * @param value the result of method execution + * @return the object that describes value + */ + static ValueObject create(Object value) { + return (value != null) + ? new ValueObjectImpl(value) + : NULL; + } + + private Object value; + private boolean isVoid; + + /** + * Creates the object that describes returning void value. + */ + private ValueObjectImpl() { + this.isVoid = true; + } + + /** + * Creates the object that describes returning non-void value. + * + * @param value the result of method execution + */ + private ValueObjectImpl(Object value) { + this.value = value; + } + + /** + * Returns the result of method execution. + * + * @return the result of method execution + */ + public Object getValue() { + return this.value; + } + + /** + * Returns {@code void} state of this value object. + * + * @return {@code true} if value should be ignored, + * {@code false} otherwise + */ + public boolean isVoid() { + return this.isVoid; + } +} diff --git a/jdk/src/share/classes/com/sun/beans/decoder/VarElementHandler.java b/jdk/src/share/classes/com/sun/beans/decoder/VarElementHandler.java new file mode 100644 index 00000000000..d948c18e538 --- /dev/null +++ b/jdk/src/share/classes/com/sun/beans/decoder/VarElementHandler.java @@ -0,0 +1,82 @@ +/* + * Copyright 2008 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. 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 + * 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. + */ +package com.sun.beans.decoder; + +/** + * This class is intended to handle <var> element. + * This element retrieves the value of specified variable. + * For example:
+ * <var id="id1" idref="id2"/>
+ * is equivalent to {@code id1 = id2} in Java code. + *

The following atributes are supported: + *

+ *
idref + *
the identifier to refer to the variable + *
id + *
the identifier of the variable that is intended to store the result + *
+ * + * @since 1.7 + * + * @author Sergey A. Malenkov + */ +final class VarElementHandler extends ElementHandler { + private ValueObject value; + + /** + * Parses attributes of the element. + * The following atributes are supported: + *
+ *
idref + *
the identifier to refer to the variable + *
id + *
the identifier of the variable that is intended to store the result + *
+ * + * @param name the attribute name + * @param value the attribute value + */ + @Override + public void addAttribute(String name, String value) { + if (name.equals("idref")) { // NON-NLS: the attribute name + this.value = ValueObjectImpl.create(getVariable(value)); + } else { + super.addAttribute(name, value); + } + } + + /** + * Returns the value of this element. + * + * @return the value of this element + */ + @Override + protected ValueObject getValueObject() { + if (this.value == null) { + throw new IllegalArgumentException("Variable name is not set"); + } + return this.value; + } +} diff --git a/jdk/src/share/classes/com/sun/beans/decoder/VoidElementHandler.java b/jdk/src/share/classes/com/sun/beans/decoder/VoidElementHandler.java new file mode 100644 index 00000000000..44726a0f7a1 --- /dev/null +++ b/jdk/src/share/classes/com/sun/beans/decoder/VoidElementHandler.java @@ -0,0 +1,68 @@ +/* + * Copyright 2008 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. 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 + * 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. + */ +package com.sun.beans.decoder; + +/** + * This class is intended to handle <void> element. + * This element looks like <object> element, + * but its value is not used as an argument for element + * that contains this one. + *

The following atributes are supported: + *

+ *
class + *
the type is used for static methods and fields + *
method + *
the method name + *
property + *
the property name + *
index + *
the property index + *
field + *
the field name + *
idref + *
the identifier to refer to the variable + *
id + *
the identifier of the variable that is intended to store the result + *
+ * + * @since 1.7 + * + * @author Sergey A. Malenkov + */ +final class VoidElementHandler extends ObjectElementHandler { + + /** + * Tests whether the value of this element can be used + * as an argument of the element that contained in this one. + * + * @return {@code true} if the value of this element should be used + * as an argument of the element that contained in this one, + * {@code false} otherwise + */ + @Override + protected boolean isArgument() { + return false; // hack for compatibility + } +} diff --git a/jdk/src/share/classes/com/sun/beans/finder/AbstractFinder.java b/jdk/src/share/classes/com/sun/beans/finder/AbstractFinder.java new file mode 100644 index 00000000000..396d6cbf8f8 --- /dev/null +++ b/jdk/src/share/classes/com/sun/beans/finder/AbstractFinder.java @@ -0,0 +1,213 @@ +/* + * Copyright 2008 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. 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 + * 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. + */ +package com.sun.beans.finder; + +import java.util.HashMap; +import java.util.Map; + +/** + * This abstract class provides functionality + * to find a public method or constructor + * with specified parameter types. + * It supports a variable number of parameters. + * + * @since 1.7 + * + * @author Sergey A. Malenkov + */ +abstract class AbstractFinder { + private final Class[] args; + + /** + * Creates finder for array of classes of arguments. + * If a particular element of array equals {@code null}, + * than the appropriate pair of classes + * does not take into consideration. + * + * @param args array of classes of arguments + */ + protected AbstractFinder(Class[] args) { + this.args = args; + } + + /** + * Returns an array of {@code Class} objects + * that represent the formal parameter types of the method + * Returns an empty array if the method takes no parameters. + * + * @param method the object that represents method + * @return the parameter types of the method + */ + protected abstract Class[] getParameters(T method); + + /** + * Returns {@code true} if and only if the method + * was declared to take a variable number of arguments. + * + * @param method the object that represents method + * @return {@code true} if the method was declared + * to take a variable number of arguments; + * {@code false} otherwise + */ + protected abstract boolean isVarArgs(T method); + + /** + * Checks validness of the method. + * At least the valid method should be public. + * + * @param method the object that represents method + * @return {@code true} if the method is valid, + * {@code false} otherwise + */ + protected abstract boolean isValid(T method); + + /** + * Performs a search in the {@code methods} array. + * The one method is selected from the array of the valid methods. + * The list of parameters of the selected method shows + * the best correlation with the list of arguments + * specified at class initialization. + * If more than one method is both accessible and applicable + * to a method invocation, it is necessary to choose one + * to provide the descriptor for the run-time method dispatch. + * The most specific method should be chosen. + * + * @param methods the array of methods to search within + * @return the object that represents found method + * @throws NoSuchMethodException if no method was found or several + * methods meet the search criteria + * @see #isAssignable + */ + final T find(T[] methods) throws NoSuchMethodException { + Map[]> map = new HashMap[]>(); + + T oldMethod = null; + Class[] oldParams = null; + boolean ambiguous = false; + + for (T newMethod : methods) { + if (isValid(newMethod)) { + Class[] newParams = getParameters(newMethod); + if (newParams.length == this.args.length) { + PrimitiveWrapperMap.replacePrimitivesWithWrappers(newParams); + if (isAssignable(newParams, this.args)) { + if (oldMethod == null) { + oldMethod = newMethod; + oldParams = newParams; + } else { + boolean useNew = isAssignable(oldParams, newParams); + boolean useOld = isAssignable(newParams, oldParams); + + if (useOld == useNew) { + ambiguous = true; + } else if (useNew) { + oldMethod = newMethod; + oldParams = newParams; + ambiguous = false; + } + } + } + } + if (isVarArgs(newMethod)) { + int length = newParams.length - 1; + if (length <= this.args.length) { + Class[] array = new Class[this.args.length]; + System.arraycopy(newParams, 0, array, 0, length); + if (length < this.args.length) { + Class type = newParams[length].getComponentType(); + if (type.isPrimitive()) { + type = PrimitiveWrapperMap.getType(type.getName()); + } + for (int i = length; i < this.args.length; i++) { + array[i] = type; + } + } + map.put(newMethod, array); + } + } + } + } + for (T newMethod : methods) { + Class[] newParams = map.get(newMethod); + if (newParams != null) { + if (isAssignable(newParams, this.args)) { + if (oldMethod == null) { + oldMethod = newMethod; + oldParams = newParams; + } else { + boolean useNew = isAssignable(oldParams, newParams); + boolean useOld = isAssignable(newParams, oldParams); + + if (useOld == useNew) { + if (oldParams == map.get(oldMethod)) { + ambiguous = true; + } + } else if (useNew) { + oldMethod = newMethod; + oldParams = newParams; + ambiguous = false; + } + } + } + } + } + + if (ambiguous) { + throw new NoSuchMethodException("Ambiguous methods are found"); + } + if (oldMethod == null) { + throw new NoSuchMethodException("Method is not found"); + } + return oldMethod; + } + + /** + * Determines if every class in {@code min} array is either the same as, + * or is a superclass of, the corresponding class in {@code max} array. + * The length of every array must equal the number of arguments. + * This comparison is performed in the {@link #find} method + * before the first call of the isAssignable method. + * If an argument equals {@code null} + * the appropriate pair of classes does not take into consideration. + * + * @param min the array of classes to be checked + * @param max the array of classes that is used to check + * @return {@code true} if all classes in {@code min} array + * are assignable from corresponding classes in {@code max} array, + * {@code false} otherwise + * + * @see Class#isAssignableFrom + */ + private boolean isAssignable(Class[] min, Class[] max) { + for (int i = 0; i < this.args.length; i++) { + if (null != this.args[i]) { + if (!min[i].isAssignableFrom(max[i])) { + return false; + } + } + } + return true; + } +} diff --git a/jdk/src/share/classes/com/sun/beans/finder/ClassFinder.java b/jdk/src/share/classes/com/sun/beans/finder/ClassFinder.java index 79b77415653..01a72fa5809 100644 --- a/jdk/src/share/classes/com/sun/beans/finder/ClassFinder.java +++ b/jdk/src/share/classes/com/sun/beans/finder/ClassFinder.java @@ -1,5 +1,5 @@ /* - * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2006-2008 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 @@ -25,7 +25,7 @@ package com.sun.beans.finder; /** - * This is utility class that provides static methods + * This is utility class that provides {@code static} methods * to find a class with the specified name using the specified class loader. * * @since 1.7 @@ -33,137 +33,138 @@ package com.sun.beans.finder; * @author Sergey A. Malenkov */ public final class ClassFinder { + /** - * Returns the Class object associated + * Returns the {@code Class} object associated * with the class or interface with the given string name, * using the default class loader. *

- * The name can denote an array class + * The {@code name} can denote an array class * (see {@link Class#getName} for details). * * @param name fully qualified name of the desired class * @return class object representing the desired class * - * @exception ClassNotFoundException if the class cannot be located - * by the specified class loader + * @throws ClassNotFoundException if the class cannot be located + * by the specified class loader * * @see Class#forName(String) * @see Class#forName(String,boolean,ClassLoader) * @see ClassLoader#getSystemClassLoader() * @see Thread#getContextClassLoader() */ - public static Class findClass( String name ) throws ClassNotFoundException { + public static Class findClass(String name) throws ClassNotFoundException { try { ClassLoader loader = Thread.currentThread().getContextClassLoader(); - if ( loader == null ) { + if (loader == null) { // can be null in IE (see 6204697) loader = ClassLoader.getSystemClassLoader(); } - if ( loader != null ) { - return Class.forName( name, false, loader ); + if (loader != null) { + return Class.forName(name, false, loader); } - } catch ( ClassNotFoundException exception ) { + } catch (ClassNotFoundException exception) { // use current class loader instead - } catch ( SecurityException exception ) { + } catch (SecurityException exception) { // use current class loader instead } - return Class.forName( name ); + return Class.forName(name); } /** - * Returns the Class object associated with + * Returns the {@code Class} object associated with * the class or interface with the given string name, * using the given class loader. *

- * The name can denote an array class + * The {@code name} can denote an array class * (see {@link Class#getName} for details). *

- * If the parameter loader is null, + * If the parameter {@code loader} is null, * the class is loaded through the default class loader. * * @param name fully qualified name of the desired class * @param loader class loader from which the class must be loaded * @return class object representing the desired class * - * @exception ClassNotFoundException if the class cannot be located - * by the specified class loader + * @throws ClassNotFoundException if the class cannot be located + * by the specified class loader * * @see #findClass(String,ClassLoader) * @see Class#forName(String,boolean,ClassLoader) */ - public static Class findClass( String name, ClassLoader loader ) throws ClassNotFoundException { - if ( loader != null ) { + public static Class findClass(String name, ClassLoader loader) throws ClassNotFoundException { + if (loader != null) { try { - return Class.forName( name, false, loader ); - } catch ( ClassNotFoundException exception ) { + return Class.forName(name, false, loader); + } catch (ClassNotFoundException exception) { // use default class loader instead - } catch ( SecurityException exception ) { + } catch (SecurityException exception) { // use default class loader instead } } - return findClass( name ); + return findClass(name); } /** - * Returns the Class object associated + * Returns the {@code Class} object associated * with the class or interface with the given string name, * using the default class loader. *

- * The name can denote an array class + * The {@code name} can denote an array class * (see {@link Class#getName} for details). *

* This method can be used to obtain - * any of the Class objects - * representing void or primitive Java types: - * char, byte, short, - * int, long, float, - * double and boolean. + * any of the {@code Class} objects + * representing {@code void} or primitive Java types: + * {@code char}, {@code byte}, {@code short}, + * {@code int}, {@code long}, {@code float}, + * {@code double} and {@code boolean}. * * @param name fully qualified name of the desired class * @return class object representing the desired class * - * @exception ClassNotFoundException if the class cannot be located - * by the specified class loader + * @throws ClassNotFoundException if the class cannot be located + * by the specified class loader * * @see #resolveClass(String,ClassLoader) */ - public static Class resolveClass( String name ) throws ClassNotFoundException { - return resolveClass( name, null ); + public static Class resolveClass(String name) throws ClassNotFoundException { + return resolveClass(name, null); } /** - * Returns the Class object associated with + * Returns the {@code Class} object associated with * the class or interface with the given string name, * using the given class loader. *

- * The name can denote an array class + * The {@code name} can denote an array class * (see {@link Class#getName} for details). *

- * If the parameter loader is null, + * If the parameter {@code loader} is null, * the class is loaded through the default class loader. *

* This method can be used to obtain - * any of the Class objects - * representing void or primitive Java types: - * char, byte, short, - * int, long, float, - * double and boolean. + * any of the {@code Class} objects + * representing {@code void} or primitive Java types: + * {@code char}, {@code byte}, {@code short}, + * {@code int}, {@code long}, {@code float}, + * {@code double} and {@code boolean}. * * @param name fully qualified name of the desired class * @param loader class loader from which the class must be loaded * @return class object representing the desired class * - * @exception ClassNotFoundException if the class cannot be located - * by the specified class loader + * @throws ClassNotFoundException if the class cannot be located + * by the specified class loader * * @see #findClass(String,ClassLoader) * @see PrimitiveTypeMap#getType(String) */ - public static Class resolveClass( String name, ClassLoader loader ) throws ClassNotFoundException { - Class type = PrimitiveTypeMap.getType( name ); - return ( type == null ) - ? findClass( name, loader ) + public static Class resolveClass(String name, ClassLoader loader) throws ClassNotFoundException { + Class type = PrimitiveTypeMap.getType(name); + return (type == null) + ? findClass(name, loader) : type; } diff --git a/jdk/src/share/classes/com/sun/beans/finder/ConstructorFinder.java b/jdk/src/share/classes/com/sun/beans/finder/ConstructorFinder.java new file mode 100644 index 00000000000..e7bb33421fe --- /dev/null +++ b/jdk/src/share/classes/com/sun/beans/finder/ConstructorFinder.java @@ -0,0 +1,127 @@ +/* + * Copyright 2008 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. 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 + * 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. + */ +package com.sun.beans.finder; + +import com.sun.beans.WeakCache; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Modifier; + +/** + * This utility class provides {@code static} methods + * to find a public constructor with specified parameter types + * in specified class. + * + * @since 1.7 + * + * @author Sergey A. Malenkov + */ +public final class ConstructorFinder extends AbstractFinder> { + private static final WeakCache> CACHE = new WeakCache>(); + + /** + * Finds public constructor + * that is declared in public class. + * + * @param type the class that can have constructor + * @param args parameter types that is used to find constructor + * @return object that represents found constructor + * @throws NoSuchMethodException if constructor could not be found + * or some constructors are found + */ + public static Constructor findConstructor(Class type, Class...args) throws NoSuchMethodException { + if (type.isPrimitive()) { + throw new NoSuchMethodException("Primitive wrapper does not contain constructors"); + } + if (type.isInterface()) { + throw new NoSuchMethodException("Interface does not contain constructors"); + } + if (Modifier.isAbstract(type.getModifiers())) { + throw new NoSuchMethodException("Abstract class cannot be instantiated"); + } + if (!Modifier.isPublic(type.getModifiers())) { + throw new NoSuchMethodException("Class is not accessible"); + } + PrimitiveWrapperMap.replacePrimitivesWithWrappers(args); + Signature signature = new Signature(type, args); + + Constructor constructor = CACHE.get(signature); + if (constructor != null) { + return constructor; + } + constructor = new ConstructorFinder(args).find(type.getConstructors()); + CACHE.put(signature, constructor); + return constructor; + } + + /** + * Creates constructor finder with specified array of parameter types. + * + * @param args the array of parameter types + */ + private ConstructorFinder(Class[] args) { + super(args); + } + + /** + * Returns an array of {@code Class} objects + * that represent the formal parameter types of the constructor + * Returns an empty array if the constructor takes no parameters. + * + * @param constructor the object that represents constructor + * @return the parameter types of the constructor + */ + @Override + protected Class[] getParameters(Constructor constructor) { + return constructor.getParameterTypes(); + } + + /** + * Returns {@code true} if and only if the constructor + * was declared to take a variable number of arguments. + * + * @param constructor the object that represents constructor + * @return {@code true} if the constructor was declared + * to take a variable number of arguments; + * {@code false} otherwise + */ + @Override + protected boolean isVarArgs(Constructor constructor) { + return constructor.isVarArgs(); + } + + /** + * Checks validness of the constructor. + * The valid constructor should be public. + * + * @param constructor the object that represents constructor + * @return {@code true} if the constructor is valid, + * {@code false} otherwise + */ + @Override + protected boolean isValid(Constructor constructor) { + return Modifier.isPublic(constructor.getModifiers()); + } +} diff --git a/jdk/src/share/classes/com/sun/beans/finder/FieldFinder.java b/jdk/src/share/classes/com/sun/beans/finder/FieldFinder.java new file mode 100644 index 00000000000..cb17d02417d --- /dev/null +++ b/jdk/src/share/classes/com/sun/beans/finder/FieldFinder.java @@ -0,0 +1,106 @@ +/* + * Copyright 2008 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. 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 + * 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. + */ +package com.sun.beans.finder; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; + +/** + * This utility class provides {@code static} methods + * to find a public field with specified name + * in specified class. + * + * @since 1.7 + * + * @author Sergey A. Malenkov + */ +public final class FieldFinder { + + /** + * Finds public field (static or non-static) + * that is declared in public class. + * + * @param type the class that can have field + * @param name the name of field to find + * @return object that represents found field + * @throws NoSuchFieldException if field is not found + * @see Class#getField + */ + public static Field findField(Class type, String name) throws NoSuchFieldException { + if (name == null) { + throw new IllegalArgumentException("Field name is not set"); + } + Field field = type.getField(name); + if (!Modifier.isPublic(field.getModifiers())) { + throw new NoSuchFieldException("Field '" + name + "' is not public"); + } + if (!Modifier.isPublic(field.getDeclaringClass().getModifiers())) { + throw new NoSuchFieldException("Field '" + name + "' is not accessible"); + } + return field; + } + + /** + * Finds public non-static field + * that is declared in public class. + * + * @param type the class that can have field + * @param name the name of field to find + * @return object that represents found field + * @throws NoSuchFieldException if field is not found + * @see Class#getField + */ + public static Field findInstanceField(Class type, String name) throws NoSuchFieldException { + Field field = findField(type, name); + if (Modifier.isStatic(field.getModifiers())) { + throw new NoSuchFieldException("Field '" + name + "' is static"); + } + return field; + } + + /** + * Finds public static field + * that is declared in public class. + * + * @param type the class that can have field + * @param name the name of field to find + * @return object that represents found field + * @throws NoSuchFieldException if field is not found + * @see Class#getField + */ + public static Field findStaticField(Class type, String name) throws NoSuchFieldException { + Field field = findField(type, name); + if (!Modifier.isStatic(field.getModifiers())) { + throw new NoSuchFieldException("Field '" + name + "' is not static"); + } + return field; + } + + /** + * Disable instantiation. + */ + private FieldFinder() { + } +} diff --git a/jdk/src/share/classes/com/sun/beans/finder/MethodFinder.java b/jdk/src/share/classes/com/sun/beans/finder/MethodFinder.java new file mode 100644 index 00000000000..d4aa0844ad3 --- /dev/null +++ b/jdk/src/share/classes/com/sun/beans/finder/MethodFinder.java @@ -0,0 +1,205 @@ +/* + * Copyright 2008 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. 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 + * 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. + */ +package com.sun.beans.finder; + +import com.sun.beans.WeakCache; + +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +/** + * This utility class provides {@code static} methods + * to find a public method with specified name and parameter types + * in specified class. + * + * @since 1.7 + * + * @author Sergey A. Malenkov + */ +public final class MethodFinder extends AbstractFinder { + private static final WeakCache CACHE = new WeakCache(); + + /** + * Finds public method (static or non-static) + * that is accessible from public class. + * + * @param type the class that can have method + * @param name the name of method to find + * @param args parameter types that is used to find method + * @return object that represents found method + * @throws NoSuchMethodException if method could not be found + * or some methods are found + */ + public static Method findMethod(Class type, String name, Class...args) throws NoSuchMethodException { + if (name == null) { + throw new IllegalArgumentException("Method name is not set"); + } + PrimitiveWrapperMap.replacePrimitivesWithWrappers(args); + Signature signature = new Signature(type, name, args); + + Method method = CACHE.get(signature); + if (method != null) { + return method; + } + method = findAccessibleMethod(new MethodFinder(name, args).find(type.getMethods())); + CACHE.put(signature, method); + return method; + } + + /** + * Finds public non-static method + * that is accessible from public class. + * + * @param type the class that can have method + * @param name the name of method to find + * @param args parameter types that is used to find method + * @return object that represents found method + * @throws NoSuchMethodException if method could not be found + * or some methods are found + */ + public static Method findInstanceMethod(Class type, String name, Class... args) throws NoSuchMethodException { + Method method = findMethod(type, name, args); + if (Modifier.isStatic(method.getModifiers())) { + throw new NoSuchMethodException("Method '" + name + "' is static"); + } + return method; + } + + /** + * Finds public static method + * that is accessible from public class. + * + * @param type the class that can have method + * @param name the name of method to find + * @param args parameter types that is used to find method + * @return object that represents found method + * @throws NoSuchMethodException if method could not be found + * or some methods are found + */ + public static Method findStaticMethod(Class type, String name, Class...args) throws NoSuchMethodException { + Method method = findMethod(type, name, args); + if (!Modifier.isStatic(method.getModifiers())) { + throw new NoSuchMethodException("Method '" + name + "' is not static"); + } + return method; + } + + /** + * Finds method that is accessible from public class or interface through class hierarchy. + * + * @param method object that represents found method + * @return object that represents accessible method + * @throws NoSuchMethodException if method is not accessible or is not found + * in specified superclass or interface + */ + private static Method findAccessibleMethod(Method method) throws NoSuchMethodException { + Class type = method.getDeclaringClass(); + if (Modifier.isPublic(type.getModifiers())) { + return method; + } + if (Modifier.isStatic(method.getModifiers())) { + throw new NoSuchMethodException("Method '" + method.getName() + "' is not accessible"); + } + for (Class face : type.getInterfaces()) { + try { + return findAccessibleMethod(method, face); + } + catch (NoSuchMethodException exception) { + // try to find in superclass or another interface + } + } + return findAccessibleMethod(method, type.getSuperclass()); + } + + /** + * Finds method that accessible from specified class. + * + * @param method object that represents found method + * @param type class that is used to find accessible method + * @return object that represents accessible method + * @throws NoSuchMethodException if method is not accessible or is not found + * in specified superclass or interface + */ + private static Method findAccessibleMethod(Method method, Class type) throws NoSuchMethodException { + String name = method.getName(); + Class[] params = method.getParameterTypes(); + return findAccessibleMethod(type.getMethod(name, params)); + } + + + private final String name; + + /** + * Creates method finder with specified array of parameter types. + * + * @param name the name of method to find + * @param args the array of parameter types + */ + private MethodFinder(String name, Class[] args) { + super(args); + this.name = name; + } + + /** + * Returns an array of {@code Class} objects + * that represent the formal parameter types of the method + * Returns an empty array if the method takes no parameters. + * + * @param method the object that represents method + * @return the parameter types of the method + */ + @Override + protected Class[] getParameters(Method method) { + return method.getParameterTypes(); + } + + /** + * Returns {@code true} if and only if the method + * was declared to take a variable number of arguments. + * + * @param method the object that represents method + * @return {@code true} if the method was declared + * to take a variable number of arguments; + * {@code false} otherwise + */ + @Override + protected boolean isVarArgs(Method method) { + return method.isVarArgs(); + } + + /** + * Checks validness of the method. + * The valid method should be public and + * should have the specified name. + * + * @param method the object that represents method + * @return {@code true} if the method is valid, + * {@code false} otherwise + */ + @Override + protected boolean isValid(Method method) { + return Modifier.isPublic(method.getModifiers()) && method.getName().equals(this.name); + } +} diff --git a/jdk/src/share/classes/com/sun/beans/finder/PrimitiveTypeMap.java b/jdk/src/share/classes/com/sun/beans/finder/PrimitiveTypeMap.java index 0bdb09e5be1..36a552b906c 100644 --- a/jdk/src/share/classes/com/sun/beans/finder/PrimitiveTypeMap.java +++ b/jdk/src/share/classes/com/sun/beans/finder/PrimitiveTypeMap.java @@ -1,5 +1,5 @@ /* - * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2006-2008 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 @@ -36,29 +36,30 @@ import java.util.Map; * @author Sergey A. Malenkov */ final class PrimitiveTypeMap { + /** * Returns primitive type class by its name. * * @param name the name of primitive type * @return found primitive type class, - * or null if not found + * or {@code null} if not found */ - static Class getType( String name ) { - return map.get( name ); + static Class getType(String name) { + return map.get(name); } - private static final Map map = new HashMap( 9 ); + private static final Map> map = new HashMap>(9); static { - map.put( boolean.class.getName(), boolean.class ); - map.put( char.class.getName(), char.class ); - map.put( byte.class.getName(), byte.class ); - map.put( short.class.getName(), short.class ); - map.put( int.class.getName(), int.class ); - map.put( long.class.getName(), long.class ); - map.put( float.class.getName(), float.class ); - map.put( double.class.getName(), double.class ); - map.put( void.class.getName(), void.class ); + map.put(boolean.class.getName(), boolean.class); + map.put(char.class.getName(), char.class); + map.put(byte.class.getName(), byte.class); + map.put(short.class.getName(), short.class); + map.put(int.class.getName(), int.class); + map.put(long.class.getName(), long.class); + map.put(float.class.getName(), float.class); + map.put(double.class.getName(), double.class); + map.put(void.class.getName(), void.class); } /** diff --git a/jdk/src/share/classes/com/sun/beans/finder/PrimitiveWrapperMap.java b/jdk/src/share/classes/com/sun/beans/finder/PrimitiveWrapperMap.java new file mode 100644 index 00000000000..f39b3ea3df0 --- /dev/null +++ b/jdk/src/share/classes/com/sun/beans/finder/PrimitiveWrapperMap.java @@ -0,0 +1,86 @@ +/* + * Copyright 2008 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. 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 + * 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. + */ +package com.sun.beans.finder; + +import java.util.HashMap; +import java.util.Map; + +/** + * This utility class associates + * name of primitive type with appropriate wrapper. + * + * @since 1.7 + * + * @author Sergey A. Malenkov + */ +public final class PrimitiveWrapperMap { + + /** + * Replaces all primitive types in specified array with wrappers. + * + * @param types array of classes where all primitive types + * will be replaced by appropriate wrappers + */ + static void replacePrimitivesWithWrappers(Class[] types) { + for (int i = 0; i < types.length; i++) { + if (types[i] != null) { + if (types[i].isPrimitive()) { + types[i] = getType(types[i].getName()); + } + } + } + } + + /** + * Returns wrapper for primitive type by its name. + * + * @param name the name of primitive type + * @return found wrapper for primitive type, + * or {@code null} if not found + */ + public static Class getType(String name) { + return map.get(name); + } + + private static final Map> map = new HashMap>(9); + + static { + map.put(Boolean.TYPE.getName(), Boolean.class); + map.put(Character.TYPE.getName(), Character.class); + map.put(Byte.TYPE.getName(), Byte.class); + map.put(Short.TYPE.getName(), Short.class); + map.put(Integer.TYPE.getName(), Integer.class); + map.put(Long.TYPE.getName(), Long.class); + map.put(Float.TYPE.getName(), Float.class); + map.put(Double.TYPE.getName(), Double.class); + map.put(Void.TYPE.getName(), Void.class); + } + + /** + * Disable instantiation. + */ + private PrimitiveWrapperMap() { + } +} diff --git a/jdk/src/share/classes/com/sun/beans/finder/Signature.java b/jdk/src/share/classes/com/sun/beans/finder/Signature.java new file mode 100644 index 00000000000..8c09e11f4b4 --- /dev/null +++ b/jdk/src/share/classes/com/sun/beans/finder/Signature.java @@ -0,0 +1,169 @@ +/* + * Copyright 2008 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. 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 + * 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. + */ +package com.sun.beans.finder; + +/** + * This class is designed to be a key of a cache + * of constructors or methods. + * + * @since 1.7 + * + * @author Sergey A. Malenkov + */ +final class Signature { + private final Class type; + private final String name; + private final Class[] args; + + private volatile int code; + + /** + * Constructs signature for constructor. + * + * @param type the class that contains constructor + * @param args the types of constructor's parameters + */ + Signature(Class type, Class[] args) { + this(type, null, args); + } + + /** + * Constructs signature for method. + * + * @param type the class that contains method + * @param name the name of the method + * @param args the types of method's parameters + */ + Signature(Class type, String name, Class[] args) { + this.type = type; + this.name = name; + this.args = args; + } + + /** + * Indicates whether some other object is "equal to" this one. + * + * @param object the reference object with which to compare + * @return {@code true} if this object is the same as the + * {@code object} argument, {@code false} otherwise + * @see #hashCode() + */ + @Override + public boolean equals(Object object) { + if (this == object) { + return true; + } + if (object instanceof Signature) { + Signature signature = (Signature) object; + return isEqual(signature.type, this.type) + && isEqual(signature.name, this.name) + && isEqual(signature.args, this.args); + } + return false; + } + + /** + * Indicates whether some object is "equal to" another one. + * This method supports {@code null} values. + * + * @param obj1 the first reference object that will compared + * @param obj2 the second reference object that will compared + * @return {@code true} if first object is the same as the second object, + * {@code false} otherwise + */ + private static boolean isEqual(Object obj1, Object obj2) { + return (obj1 == null) + ? obj2 == null + : obj1.equals(obj2); + } + + /** + * Indicates whether some array is "equal to" another one. + * This method supports {@code null} values. + * + * @param args1 the first reference array that will compared + * @param args2 the second reference array that will compared + * @return {@code true} if first array is the same as the second array, + * {@code false} otherwise + */ + private static boolean isEqual(Class[] args1, Class[] args2) { + if ((args1 == null) || (args2 == null)) { + return args1 == args2; + } + if (args1.length != args2.length) { + return false; + } + for (int i = 0; i < args1.length; i++) { + if (!isEqual(args1[i], args2[i])) { + return false; + } + } + return true; + } + + /** + * Returns a hash code value for the object. + * This method is supported for the benefit of hashtables + * such as {@link java.util.HashMap} or {@link java.util.HashSet}. + * Hash code computed using algorithm + * suggested in Effective Java, Item 8. + * + * @return a hash code value for this object + * @see #equals(Object) + */ + @Override + public int hashCode() { + if (this.code == 0) { + int code = 17; + code = addHashCode(code, this.type); + code = addHashCode(code, this.name); + + if (this.args != null) { + for (Class arg : this.args) { + code = addHashCode(code, arg); + } + } + this.code = code; + } + return this.code; + } + + /** + * Adds hash code value if specified object. + * This is a part of the algorithm + * suggested in Effective Java, Item 8. + * + * @param code current hash code value + * @param object object that updates hash code value + * @return updated hash code value + * @see #hashCode() + */ + private static int addHashCode(int code, Object object) { + code *= 37; + return (object != null) + ? code + object.hashCode() + : code; + } +} diff --git a/jdk/src/share/classes/java/beans/MetaData.java b/jdk/src/share/classes/java/beans/MetaData.java index 5d8fd697918..defd196457e 100644 --- a/jdk/src/share/classes/java/beans/MetaData.java +++ b/jdk/src/share/classes/java/beans/MetaData.java @@ -24,6 +24,8 @@ */ package java.beans; +import com.sun.beans.finder.PrimitiveWrapperMap; + import java.awt.AWTKeyStroke; import java.awt.BorderLayout; import java.awt.Dimension; @@ -204,7 +206,7 @@ class java_lang_Class_PersistenceDelegate extends PersistenceDelegate { if (c.isPrimitive()) { Field field = null; try { - field = ReflectionUtils.typeToClass(c).getDeclaredField("TYPE"); + field = PrimitiveWrapperMap.getType(c.getName()).getDeclaredField("TYPE"); } catch (NoSuchFieldException ex) { System.err.println("Unknown primitive type: " + c); } diff --git a/jdk/src/share/classes/java/beans/ReflectionUtils.java b/jdk/src/share/classes/java/beans/ReflectionUtils.java index 167b02995f0..c2553fd4176 100644 --- a/jdk/src/share/classes/java/beans/ReflectionUtils.java +++ b/jdk/src/share/classes/java/beans/ReflectionUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 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 @@ -24,6 +24,8 @@ */ package java.beans; +import com.sun.beans.finder.PrimitiveWrapperMap; + import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; @@ -34,7 +36,6 @@ import java.lang.ref.SoftReference; import java.util.*; -import com.sun.beans.ObjectHandler; import sun.reflect.misc.MethodUtil; import sun.reflect.misc.ConstructorUtil; import sun.reflect.misc.ReflectUtil; @@ -47,10 +48,6 @@ class ReflectionUtils { private static Reference methodCacheRef; - public static Class typeToClass(Class type) { - return type.isPrimitive() ? ObjectHandler.typeNameToClass(type.getName()) : type; - } - public static boolean isPrimitive(Class type) { return primitiveTypeFor(type) != null; } @@ -99,7 +96,7 @@ class ReflectionUtils { for(int j = 0; j < argClasses.length && match; j++) { Class argType = argTypes[j]; if (argType.isPrimitive()) { - argType = typeToClass(argType); + argType = PrimitiveWrapperMap.getType(argType.getName()); } if (explicit) { // Test each element for equality @@ -210,7 +207,7 @@ class ReflectionUtils { for (int i = 0; i < args.length; i++) { Class mArg = mArgs[i]; if (mArg.isPrimitive()) { - mArg = typeToClass(mArg); + mArg = PrimitiveWrapperMap.getType(mArg.getName()); } if (args[i] == mArg) { matches++; diff --git a/jdk/src/share/classes/java/beans/XMLDecoder.java b/jdk/src/share/classes/java/beans/XMLDecoder.java index 688edfae406..5e0327d65f5 100644 --- a/jdk/src/share/classes/java/beans/XMLDecoder.java +++ b/jdk/src/share/classes/java/beans/XMLDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2008 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 @@ -24,19 +24,14 @@ */ package java.beans; -import com.sun.beans.ObjectHandler; +import com.sun.beans.decoder.DocumentHandler; +import java.io.Closeable; import java.io.InputStream; import java.io.IOException; -import java.lang.ref.Reference; -import java.lang.ref.WeakReference; - -import org.xml.sax.SAXException; - -import javax.xml.parsers.SAXParserFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParser; +import org.xml.sax.InputSource; +import org.xml.sax.helpers.DefaultHandler; /** * The XMLDecoder class is used to read XML documents @@ -66,11 +61,11 @@ import javax.xml.parsers.SAXParser; * @author Philip Milne */ public class XMLDecoder { - private InputStream in; + private final DocumentHandler handler = new DocumentHandler(); + private final InputSource input; private Object owner; - private ExceptionListener exceptionListener; - private ObjectHandler handler; - private Reference clref; + private Object[] array; + private int index; /** * Creates a new input stream for reading archives @@ -126,36 +121,45 @@ public class XMLDecoder { */ public XMLDecoder(InputStream in, Object owner, ExceptionListener exceptionListener, ClassLoader cl) { - this.in = in; - setOwner(owner); - setExceptionListener(exceptionListener); - setClassLoader(cl); + this(new InputSource(in), owner, exceptionListener, cl); } /** - * Set the class loader used to instantiate objects for this stream. + * Creates a new decoder to parse XML archives + * created by the {@code XMLEncoder} class. + * If the input source {@code is} is {@code null}, + * no exception is thrown and no parsing is performed. + * This behavior is similar to behavior of other constructors + * that use {@code InputStream} as a parameter. * - * @param cl a classloader to use; if null then the default class loader - * will be used + * @param is the input source to parse + * + * @since 1.7 */ - private void setClassLoader(ClassLoader cl) { - if (cl != null) { - this.clref = new WeakReference(cl); - } + public XMLDecoder(InputSource is) { + this(is, null, null, null); } /** - * Return the class loader used to instantiate objects. If the class loader - * has not been explicitly set then null is returned. + * Creates a new decoder to parse XML archives + * created by the {@code XMLEncoder} class. * - * @return the class loader used to instantiate objects + * @param is the input source to parse + * @param owner the owner of this decoder + * @param el the exception handler for the parser, + * or {@code null} to use the default exception handler + * @param cl the class loader used for instantiating objects, + * or {@code null} to use the default class loader + * + * @since 1.7 */ - private ClassLoader getClassLoader() { - if (clref != null) { - return (ClassLoader)clref.get(); - } - return null; + private XMLDecoder(InputSource is, Object owner, ExceptionListener el, ClassLoader cl) { + this.input = is; + this.owner = owner; + setExceptionListener(el); + this.handler.setClassLoader(cl); + this.handler.setOwner(this); } /** @@ -163,8 +167,14 @@ public class XMLDecoder { * with this stream. */ public void close() { + if (parsingComplete()) { + close(this.input.getCharacterStream()); + close(this.input.getByteStream()); + } + } + + private void close(Closeable in) { if (in != null) { - getHandler(); try { in.close(); } @@ -174,6 +184,17 @@ public class XMLDecoder { } } + private boolean parsingComplete() { + if (this.input == null) { + return false; + } + if (this.array == null) { + this.handler.parse(this.input); + this.array = this.handler.getObjects(); + } + return true; + } + /** * Sets the exception handler for this stream to exceptionListener. * The exception handler is notified when this stream catches recoverable @@ -185,7 +206,10 @@ public class XMLDecoder { * @see #getExceptionListener */ public void setExceptionListener(ExceptionListener exceptionListener) { - this.exceptionListener = exceptionListener; + if (exceptionListener == null) { + exceptionListener = Statement.defaultExceptionListener; + } + this.handler.setExceptionListener(exceptionListener); } /** @@ -197,8 +221,7 @@ public class XMLDecoder { * @see #setExceptionListener */ public ExceptionListener getExceptionListener() { - return (exceptionListener != null) ? exceptionListener : - Statement.defaultExceptionListener; + return this.handler.getExceptionListener(); } /** @@ -212,10 +235,9 @@ public class XMLDecoder { * @see XMLEncoder#writeObject */ public Object readObject() { - if (in == null) { - return null; - } - return getHandler().dequeueResult(); + return (parsingComplete()) + ? this.array[this.index++] + : null; } /** @@ -241,33 +263,32 @@ public class XMLDecoder { } /** - * Returns the object handler for input stream. - * The object handler is created if necessary. + * Creates a new handler for SAX parser + * that can be used to parse embedded XML archives + * created by the {@code XMLEncoder} class. * - * @return the object handler + * The {@code owner} should be used if parsed XML document contains + * the method call within context of the <java> element. + * The {@code null} value may cause illegal parsing in such case. + * The same problem may occur, if the {@code owner} class + * does not contain expected method to call. See details here. + * + * @param owner the owner of the default handler + * that can be used as a value of <java> element + * @param el the exception handler for the parser, + * or {@code null} to use the default exception handler + * @param cl the class loader used for instantiating objects, + * or {@code null} to use the default class loader + * @return an instance of {@code DefaultHandler} for SAX parser + * + * @since 1.7 */ - private ObjectHandler getHandler() { - if ( handler == null ) { - SAXParserFactory factory = SAXParserFactory.newInstance(); - try { - SAXParser parser = factory.newSAXParser(); - handler = new ObjectHandler( this, getClassLoader() ); - parser.parse( in, handler ); - } - catch ( ParserConfigurationException e ) { - getExceptionListener().exceptionThrown( e ); - } - catch ( SAXException se ) { - Exception e = se.getException(); - if ( e == null ) { - e = se; - } - getExceptionListener().exceptionThrown( e ); - } - catch ( IOException ioe ) { - getExceptionListener().exceptionThrown( ioe ); - } - } + public static DefaultHandler createHandler(Object owner, ExceptionListener el, ClassLoader cl) { + DocumentHandler handler = new DocumentHandler(); + handler.setOwner(owner); + handler.setExceptionListener(el); + handler.setClassLoader(cl); return handler; } } diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthParser.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthParser.java index 5f7a9b6c282..7fe2278fd20 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthParser.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 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 @@ -59,16 +59,16 @@ import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; -import org.xml.sax.AttributeList; -import org.xml.sax.HandlerBase; +import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.Locator; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; +import org.xml.sax.helpers.DefaultHandler; -import com.sun.beans.ObjectHandler; +import com.sun.beans.decoder.DocumentHandler; -class SynthParser extends HandlerBase { +class SynthParser extends DefaultHandler { // // Known element names // @@ -119,7 +119,7 @@ class SynthParser extends HandlerBase { /** * Lazily created, used for anything we don't understand. */ - private ObjectHandler _handler; + private DocumentHandler _handler; /** * Indicates the depth of how many elements we've encountered but don't @@ -292,8 +292,9 @@ class SynthParser extends HandlerBase { /** * Handles beans persistance. */ - private ObjectHandler getHandler() { + private DocumentHandler getHandler() { if (_handler == null) { + _handler = new DocumentHandler(); if (_urlResourceBase != null) { // getHandler() is never called before parse() so it is safe // to create a URLClassLoader with _resourceBase. @@ -304,14 +305,13 @@ class SynthParser extends HandlerBase { URL[] urls = new URL[] { getResource(".") }; ClassLoader parent = Thread.currentThread().getContextClassLoader(); ClassLoader urlLoader = new URLClassLoader(urls, parent); - _handler = new ObjectHandler(null, urlLoader); + _handler.setClassLoader(urlLoader); } else { - _handler = new ObjectHandler(null, - _classResourceBase.getClassLoader()); + _handler.setClassLoader(_classResourceBase.getClassLoader()); } for (String key : _mapping.keySet()) { - _handler.register(key, _mapping.get(key)); + _handler.setVariable(key, _mapping.get(key)); } } return _handler; @@ -336,8 +336,8 @@ class SynthParser extends HandlerBase { private Object lookup(String key, Class type) throws SAXException { Object value; if (_handler != null) { - if ((value = _handler.lookup(key)) != null) { - return checkCast(value, type); + if (_handler.hasVariable(key)) { + return checkCast(_handler.getVariable(key), type); } } value = _mapping.get(key); @@ -354,11 +354,11 @@ class SynthParser extends HandlerBase { private void register(String key, Object value) throws SAXException { if (key != null) { if (_mapping.get(key) != null || - (_handler != null && _handler.lookup(key) != null)) { + (_handler != null && _handler.hasVariable(key))) { throw new SAXException("ID " + key + " is already defined"); } if (_handler != null) { - _handler.register(key, value); + _handler.setVariable(key, value); } else { _mapping.put(key, value); @@ -400,12 +400,12 @@ class SynthParser extends HandlerBase { // The following methods are invoked from startElement/stopElement // - private void startStyle(AttributeList attributes) throws SAXException { + private void startStyle(Attributes attributes) throws SAXException { String id = null; _style = null; for(int i = attributes.getLength() - 1; i >= 0; i--) { - String key = attributes.getName(i); + String key = attributes.getQName(i); if (key.equals(ATTRIBUTE_CLONE)) { _style = (ParsedSynthStyle)((ParsedSynthStyle)lookup( attributes.getValue(i), ParsedSynthStyle.class)). @@ -421,7 +421,7 @@ class SynthParser extends HandlerBase { register(id, _style); } - private void endStyle() throws SAXException { + private void endStyle() { int size = _stylePainters.size(); if (size > 0) { _style.setPainters(_stylePainters.toArray(new ParsedSynthStyle.PainterInfo[size])); @@ -435,14 +435,14 @@ class SynthParser extends HandlerBase { _style = null; } - private void startState(AttributeList attributes) throws SAXException { + private void startState(Attributes attributes) throws SAXException { ParsedSynthStyle.StateInfo stateInfo = null; int state = 0; String id = null; _stateInfo = null; for(int i = attributes.getLength() - 1; i >= 0; i--) { - String key = attributes.getName(i); + String key = attributes.getQName(i); if (key.equals(ATTRIBUTE_ID)) { id = attributes.getValue(i); } @@ -496,7 +496,7 @@ class SynthParser extends HandlerBase { _stateInfos.add(_stateInfo); } - private void endState() throws SAXException { + private void endState() { int size = _statePainters.size(); if (size > 0) { _stateInfo.setPainters(_statePainters.toArray(new ParsedSynthStyle.PainterInfo[size])); @@ -505,7 +505,7 @@ class SynthParser extends HandlerBase { _stateInfo = null; } - private void startFont(AttributeList attributes) throws SAXException { + private void startFont(Attributes attributes) throws SAXException { Font font = null; int style = Font.PLAIN; int size = 0; @@ -513,7 +513,7 @@ class SynthParser extends HandlerBase { String name = null; for(int i = attributes.getLength() - 1; i >= 0; i--) { - String key = attributes.getName(i); + String key = attributes.getQName(i); if (key.equals(ATTRIBUTE_ID)) { id = attributes.getValue(i); } @@ -568,13 +568,13 @@ class SynthParser extends HandlerBase { } } - private void startColor(AttributeList attributes) throws SAXException { + private void startColor(Attributes attributes) throws SAXException { Color color = null; String id = null; _colorTypes.clear(); for(int i = attributes.getLength() - 1; i >= 0; i--) { - String key = attributes.getName(i); + String key = attributes.getQName(i); if (key.equals(ATTRIBUTE_ID)) { id = attributes.getValue(i); } @@ -697,7 +697,7 @@ class SynthParser extends HandlerBase { } } - private void startProperty(AttributeList attributes, + private void startProperty(Attributes attributes, Object property) throws SAXException { Object value = null; String key = null; @@ -707,7 +707,7 @@ class SynthParser extends HandlerBase { String aValue = null; for(int i = attributes.getLength() - 1; i >= 0; i--) { - String aName = attributes.getName(i); + String aName = attributes.getQName(i); if (aName.equals(ATTRIBUTE_TYPE)) { String type = attributes.getValue(i).toUpperCase(); if (type.equals("IDREF")) { @@ -795,11 +795,11 @@ class SynthParser extends HandlerBase { } } - private void startGraphics(AttributeList attributes) throws SAXException { + private void startGraphics(Attributes attributes) throws SAXException { SynthGraphicsUtils graphics = null; for(int i = attributes.getLength() - 1; i >= 0; i--) { - String key = attributes.getName(i); + String key = attributes.getQName(i); if (key.equals(ATTRIBUTE_IDREF)) { graphics = (SynthGraphicsUtils)lookup(attributes.getValue(i), SynthGraphicsUtils.class); @@ -813,7 +813,7 @@ class SynthParser extends HandlerBase { } } - private void startInsets(AttributeList attributes) throws SAXException { + private void startInsets(Attributes attributes) throws SAXException { int top = 0; int bottom = 0; int left = 0; @@ -822,7 +822,7 @@ class SynthParser extends HandlerBase { String id = null; for(int i = attributes.getLength() - 1; i >= 0; i--) { - String key = attributes.getName(i); + String key = attributes.getQName(i); try { if (key.equals(ATTRIBUTE_IDREF)) { @@ -858,13 +858,13 @@ class SynthParser extends HandlerBase { } } - private void startBind(AttributeList attributes) throws SAXException { + private void startBind(Attributes attributes) throws SAXException { ParsedSynthStyle style = null; String path = null; int type = -1; for(int i = attributes.getLength() - 1; i >= 0; i--) { - String key = attributes.getName(i); + String key = attributes.getQName(i); if (key.equals(ATTRIBUTE_STYLE)) { style = (ParsedSynthStyle)lookup(attributes.getValue(i), @@ -899,7 +899,7 @@ class SynthParser extends HandlerBase { } } - private void startPainter(AttributeList attributes, String type) throws SAXException { + private void startPainter(Attributes attributes, String type) throws SAXException { Insets sourceInsets = null; Insets destInsets = null; String path = null; @@ -915,7 +915,7 @@ class SynthParser extends HandlerBase { boolean paintCenterSpecified = false; for(int i = attributes.getLength() - 1; i >= 0; i--) { - String key = attributes.getName(i); + String key = attributes.getQName(i); String value = attributes.getValue(i); if (key.equals(ATTRIBUTE_ID)) { @@ -1042,12 +1042,12 @@ class SynthParser extends HandlerBase { painters.add(painterInfo); } - private void startImageIcon(AttributeList attributes) throws SAXException { + private void startImageIcon(Attributes attributes) throws SAXException { String path = null; String id = null; for(int i = attributes.getLength() - 1; i >= 0; i--) { - String key = attributes.getName(i); + String key = attributes.getQName(i); if (key.equals(ATTRIBUTE_ID)) { id = attributes.getValue(i); @@ -1062,12 +1062,11 @@ class SynthParser extends HandlerBase { register(id, new LazyImageIcon(getResource(path))); } - private void startOpaque(AttributeList attributes) throws - SAXException { + private void startOpaque(Attributes attributes) { if (_style != null) { _style.setOpaque(true); for(int i = attributes.getLength() - 1; i >= 0; i--) { - String key = attributes.getName(i); + String key = attributes.getQName(i); if (key.equals(ATTRIBUTE_VALUE)) { _style.setOpaque("true".equals(attributes.getValue(i). @@ -1077,12 +1076,12 @@ class SynthParser extends HandlerBase { } } - private void startInputMap(AttributeList attributes) throws SAXException { + private void startInputMap(Attributes attributes) throws SAXException { _inputMapBindings.clear(); _inputMapID = null; if (_style != null) { for(int i = attributes.getLength() - 1; i >= 0; i--) { - String key = attributes.getName(i); + String key = attributes.getQName(i); if (key.equals(ATTRIBUTE_ID)) { _inputMapID = attributes.getValue(i); @@ -1101,7 +1100,7 @@ class SynthParser extends HandlerBase { _inputMapID = null; } - private void startBindKey(AttributeList attributes) throws SAXException { + private void startBindKey(Attributes attributes) throws SAXException { if (_inputMapID == null) { // Not in an inputmap, bail. return; @@ -1110,7 +1109,7 @@ class SynthParser extends HandlerBase { String key = null; String value = null; for(int i = attributes.getLength() - 1; i >= 0; i--) { - String aKey = attributes.getName(i); + String aKey = attributes.getQName(i); if (aKey.equals(ATTRIBUTE_KEY)) { key = attributes.getValue(i); @@ -1129,26 +1128,26 @@ class SynthParser extends HandlerBase { } // - // SAX methods, these forward to the ObjectHandler if we don't know + // SAX methods, these forward to the DocumentHandler if we don't know // the element name. // public InputSource resolveEntity(String publicId, String systemId) - throws SAXException { + throws IOException, SAXException { if (isForwarding()) { return getHandler().resolveEntity(publicId, systemId); } return null; } - public void notationDecl(String name, String publicId, String systemId) { + public void notationDecl(String name, String publicId, String systemId) throws SAXException { if (isForwarding()) { getHandler().notationDecl(name, publicId, systemId); } } public void unparsedEntityDecl(String name, String publicId, - String systemId, String notationName) { + String systemId, String notationName) throws SAXException { if (isForwarding()) { getHandler().unparsedEntityDecl(name, publicId, systemId, notationName); @@ -1173,7 +1172,7 @@ class SynthParser extends HandlerBase { } } - public void startElement(String name, AttributeList attributes) + public void startElement(String uri, String local, String name, Attributes attributes) throws SAXException { name = name.intern(); if (name == ELEMENT_STYLE) { @@ -1223,18 +1222,18 @@ class SynthParser extends HandlerBase { } else if (name != ELEMENT_SYNTH) { if (_depth++ == 0) { - getHandler().reset(); + getHandler().startDocument(); } - getHandler().startElement(name, attributes); + getHandler().startElement(uri, local, name, attributes); } } - public void endElement(String name) throws SAXException { + public void endElement(String uri, String local, String name) throws SAXException { if (isForwarding()) { - getHandler().endElement(name); + getHandler().endElement(uri, local, name); _depth--; if (!isForwarding()) { - getHandler().reset(); + getHandler().startDocument(); } } else { diff --git a/jdk/test/java/beans/XMLDecoder/Test4864117.java b/jdk/test/java/beans/XMLDecoder/Test4864117.java new file mode 100644 index 00000000000..a3459f918c6 --- /dev/null +++ b/jdk/test/java/beans/XMLDecoder/Test4864117.java @@ -0,0 +1,146 @@ +/* + * Copyright 2008 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 4864117 + * @summary Tests XMLDecoder within another DefaultHandler for SAX parser + * @author Sergey Malenkov + */ + +import java.beans.XMLDecoder; +import java.beans.ExceptionListener; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.io.IOException; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParserFactory; + +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +public final class Test4864117 extends DefaultHandler implements ExceptionListener { + private static final String TEST = "test"; + private static final String DATA + = "\n" + + " \n" + + " Hello, world!\n" + + " \n" + + ""; + + public static void main(String[] args) { + Test4864117 test = new Test4864117(); + InputStream input = new ByteArrayInputStream(DATA.getBytes()); + Exception error = null; + try { + SAXParserFactory.newInstance().newSAXParser().parse(input, test); + } + catch (ParserConfigurationException exception) { + error = exception; + } + catch (SAXException exception) { + error = exception.getException(); + if (error == null) { + error = exception; + } + } + catch (IOException exception) { + error = exception; + } + if (error != null) { + throw new Error("unexpected error", error); + } + test.print('?', test.getMessage()); + } + + private String message; + + public String getMessage() { + if (this.message == null) { + throw new Error("owner's method is not called"); + } + return this.message; + } + + public void setMessage(String message) { + this.message = message; + print(':', this.message); + } + + // DefaultHandler implementation + + private DefaultHandler handler; + private int depth; + + @Override + public void startDocument() throws SAXException { + this.handler = XMLDecoder.createHandler(this, this, null); + this.handler.startDocument(); + } + + @Override + public void endDocument() { + this.handler = null; + } + + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { + print('>', qName); + if (this.depth > 0) { + this.handler.startElement(uri, localName, qName, attributes); + } else if (!TEST.equals(qName)) { + throw new SAXException("unexpected element name: " + qName); + } + this.depth++; + } + + @Override + public void endElement(String uri, String localName, String qName) throws SAXException { + this.depth--; + print('<', qName); + if (this.depth > 0) { + this.handler.endElement(uri, localName, qName); + } else if (!TEST.equals(qName)) { + throw new SAXException("unexpected element name: " + qName); + } + } + + @Override + public void characters(char[] ch, int start, int length) throws SAXException { + this.handler.characters(ch, start, length); + } + + public void exceptionThrown(Exception exception) { + throw new Error("unexpected exception", exception); + } + + private void print(char ch, String name) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < this.depth; i++) sb.append(' '); + sb.append(ch).append(' ').append(name); + System.out.println(sb.toString()); + } +} diff --git a/jdk/test/java/beans/XMLDecoder/Test6341798.java b/jdk/test/java/beans/XMLDecoder/Test6341798.java index 2bc43e87565..677ff842352 100644 --- a/jdk/test/java/beans/XMLDecoder/Test6341798.java +++ b/jdk/test/java/beans/XMLDecoder/Test6341798.java @@ -1,5 +1,5 @@ /* - * Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2008 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,7 +39,7 @@ public class Test6341798 { private static final String DATA = "\n" - + " \n" + + " \n" + " \n" + " true\n" + " \n" diff --git a/jdk/test/java/beans/XMLDecoder/spec/AbstractTest.java b/jdk/test/java/beans/XMLDecoder/spec/AbstractTest.java new file mode 100644 index 00000000000..2b8abb2af9e --- /dev/null +++ b/jdk/test/java/beans/XMLDecoder/spec/AbstractTest.java @@ -0,0 +1,76 @@ +/* + * Copyright 2008 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 java.beans.ExceptionListener; +import java.beans.XMLDecoder; + +import java.io.ByteArrayInputStream; + +abstract class AbstractTest implements ExceptionListener { + public void exceptionThrown(Exception exception) { + throw new Error("unexpected exception", exception); + } + + /** + * Validates the XML decoder for XML archive + * that defined in the public field of the subclass. + * + * @param decoder the initialized XML decoder + * @throws Error if validation failed + */ + protected abstract void validate(XMLDecoder decoder); + + /** + * This is entry point to start testing. + * + * @param security use {@code true} to start + * second pass in secure context + */ + final void test(boolean security) { + byte[] array = getFieldValue("XML").getBytes(); // NON-NLS: the field name + ByteArrayInputStream input = new ByteArrayInputStream(array); + XMLDecoder decoder = new XMLDecoder(input); + decoder.setExceptionListener(this); + validate(decoder); + try { + throw new Error("unexpected object" + decoder.readObject()); + } catch (ArrayIndexOutOfBoundsException exception) { + // expected exception + } + decoder.close(); + if (security) { + System.setSecurityManager(new SecurityManager()); + test(false); + } + } + + private String getFieldValue(String field) { + try { + return getClass().getField(field).get(this).toString(); + } catch (NoSuchFieldException exception) { + throw new Error("unexpected exception", exception); + } catch (IllegalAccessException exception) { + throw new Error("unexpected exception", exception); + } + } +} diff --git a/jdk/test/java/beans/XMLDecoder/spec/TestArray.java b/jdk/test/java/beans/XMLDecoder/spec/TestArray.java new file mode 100644 index 00000000000..7ae34a148e5 --- /dev/null +++ b/jdk/test/java/beans/XMLDecoder/spec/TestArray.java @@ -0,0 +1,86 @@ +/* + * Copyright 2008 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 + * @summary Tests element + * @author Sergey Malenkov + */ + +import java.beans.XMLDecoder; +import java.lang.reflect.Array; + +public final class TestArray extends AbstractTest { + public static final String XML + = "\n" + + " \n" + + " -111\n" + + " 1111\n" + + " \n" + + " \n" + + " \n" + + " Hello, world!\n" + + " \n" + + " \n" + + ""; + + public static void main(String[] args) { + new TestArray().test(true); + } + + @Override + protected void validate(XMLDecoder decoder) { + Number[] numbers = getArray(Number.class, 2, decoder.readObject()); + if (!numbers[0].equals(Byte.valueOf("-111"))) { // NON-NLS: hardcoded in XML + throw new Error("unexpected byte value"); + } + if (!numbers[1].equals(Long.valueOf("1111"))) { // NON-NLS: hardcoded in XML + throw new Error("unexpected long value"); + } + + Object[] objects = getArray(Object.class, 3, decoder.readObject()); + if (objects[0] != null) { + throw new Error("unexpected first value"); + } + if (!objects[1].equals("Hello, world!")) { // NON-NLS: hardcoded in XML + throw new Error("unexpected string value"); + } + if (objects[2] != null) { + throw new Error("unexpected last value"); + } + } + + private static T[] getArray(Class component, int length, Object object) { + Class type = object.getClass(); + if (!type.isArray()) { + throw new Error("array expected"); + } + if (!type.getComponentType().equals(component)) { + throw new Error("unexpected component type"); + } + if (length != Array.getLength(object)) { + throw new Error("unexpected array length"); + } + return (T[]) object; + } +} diff --git a/jdk/test/java/beans/XMLDecoder/spec/TestBoolean.java b/jdk/test/java/beans/XMLDecoder/spec/TestBoolean.java new file mode 100644 index 00000000000..e24d1fb4f72 --- /dev/null +++ b/jdk/test/java/beans/XMLDecoder/spec/TestBoolean.java @@ -0,0 +1,52 @@ +/* + * Copyright 2008 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 + * @summary Tests element + * @author Sergey Malenkov + */ + +import java.beans.XMLDecoder; + +public final class TestBoolean extends AbstractTest { + public static final String XML + = "\n" + + " true\n" + + " false\n" + + ""; + + public static void main(String[] args) { + new TestBoolean().test(true); + } + + @Override + protected void validate(XMLDecoder decoder) { + if (!Boolean.TRUE.equals(decoder.readObject())) { + throw new Error("true expected"); + } + if (!Boolean.FALSE.equals(decoder.readObject())) { + throw new Error("false expected"); + } + } +} diff --git a/jdk/test/java/beans/XMLDecoder/spec/TestByte.java b/jdk/test/java/beans/XMLDecoder/spec/TestByte.java new file mode 100644 index 00000000000..46693d94c0b --- /dev/null +++ b/jdk/test/java/beans/XMLDecoder/spec/TestByte.java @@ -0,0 +1,56 @@ +/* + * Copyright 2008 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 + * @summary Tests element + * @author Sergey Malenkov + */ + +import java.beans.XMLDecoder; + +public final class TestByte extends AbstractTest { + public static final String XML + = "\n" + + " 0\n" + + " 127\n" + + " -128\n" + + ""; + + public static void main(String[] args) { + new TestByte().test(true); + } + + @Override + protected void validate(XMLDecoder decoder) { + validate((byte) 0, decoder.readObject()); + validate(Byte.MAX_VALUE, decoder.readObject()); + validate(Byte.MIN_VALUE, decoder.readObject()); + } + + private static void validate(byte value, Object object) { + if (!object.equals(Byte.valueOf(value))) { + throw new Error("byte " + value + " expected"); + } + } +} diff --git a/jdk/test/java/beans/XMLDecoder/spec/TestChar.java b/jdk/test/java/beans/XMLDecoder/spec/TestChar.java new file mode 100644 index 00000000000..cb29b713bce --- /dev/null +++ b/jdk/test/java/beans/XMLDecoder/spec/TestChar.java @@ -0,0 +1,52 @@ +/* + * Copyright 2008 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 + * @summary Tests element + * @author Sergey Malenkov + */ + +import java.beans.XMLDecoder; + +public final class TestChar extends AbstractTest { + public static final String XML + = "\n" + + " X\n" + + " \n" + + ""; + + public static void main(String[] args) { + new TestChar().test(true); + } + + @Override + protected void validate(XMLDecoder decoder) { + if (!decoder.readObject().equals(Character.valueOf('X'))) { + throw new Error("unexpected character"); + } + if (!decoder.readObject().equals(Character.valueOf((char) 0x20))) { + throw new Error("unexpected character code"); + } + } +} diff --git a/jdk/test/java/beans/XMLDecoder/spec/TestClass.java b/jdk/test/java/beans/XMLDecoder/spec/TestClass.java new file mode 100644 index 00000000000..2c16ba75f3c --- /dev/null +++ b/jdk/test/java/beans/XMLDecoder/spec/TestClass.java @@ -0,0 +1,61 @@ +/* + * Copyright 2008 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 + * @summary Tests element + * @author Sergey Malenkov + */ + +import java.beans.XMLDecoder; + +public final class TestClass extends AbstractTest { + public static final String PREFIX = "javax.swing.colorchooser."; + public static final String INTERFACE = "ColorSelectionModel"; + public static final String PUBLIC_CLASS = "DefaultColorSelectionModel"; + public static final String PRIVATE_CLASS = "DiagramComponent"; + public static final String XML + = "\n" + + " " + PREFIX + INTERFACE + "\n" + + " " + PREFIX + PUBLIC_CLASS + "\n" + + " " + PREFIX + PRIVATE_CLASS + "\n" + + ""; + + public static void main(String[] args) { + new TestClass().test(true); + } + + @Override + protected void validate(XMLDecoder decoder) { + validate(PREFIX + INTERFACE, decoder.readObject()); + validate(PREFIX + PUBLIC_CLASS, decoder.readObject()); + validate(PREFIX + PRIVATE_CLASS, decoder.readObject()); + } + + private static void validate(String name, Object object) { + Class type = (Class) object; + if (!type.getName().equals(name)) { + throw new Error(name + " expected"); + } + } +} diff --git a/jdk/test/java/beans/XMLDecoder/spec/TestDouble.java b/jdk/test/java/beans/XMLDecoder/spec/TestDouble.java new file mode 100644 index 00000000000..8e3d918c886 --- /dev/null +++ b/jdk/test/java/beans/XMLDecoder/spec/TestDouble.java @@ -0,0 +1,58 @@ +/* + * Copyright 2008 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 + * @summary Tests element + * @author Sergey Malenkov + */ + +import java.beans.XMLDecoder; + +public final class TestDouble extends AbstractTest { + public static final String XML + = "\n" + + " 0\n" + + " 1000\n" + + " -1.1e15\n" + + " 10.11e-123\n" + + ""; + + public static void main(String[] args) { + new TestDouble().test(true); + } + + @Override + protected void validate(XMLDecoder decoder) { + validate(0.0, decoder.readObject()); + validate(1000.0, decoder.readObject()); + validate(-1.1e15, decoder.readObject()); + validate(10.11e-123, decoder.readObject()); + } + + private static void validate(double value, Object object) { + if (!object.equals(Double.valueOf(value))) { + throw new Error("double " + value + " expected"); + } + } +} diff --git a/jdk/test/java/beans/XMLDecoder/spec/TestFalse.java b/jdk/test/java/beans/XMLDecoder/spec/TestFalse.java new file mode 100644 index 00000000000..57a81b87740 --- /dev/null +++ b/jdk/test/java/beans/XMLDecoder/spec/TestFalse.java @@ -0,0 +1,48 @@ +/* + * Copyright 2008 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 + * @summary Tests element + * @author Sergey Malenkov + */ + +import java.beans.XMLDecoder; + +public final class TestFalse extends AbstractTest { + public static final String XML + = "\n" + + " \n" + + ""; + + public static void main(String[] args) { + new TestFalse().test(true); + } + + @Override + protected void validate(XMLDecoder decoder) { + if (!Boolean.FALSE.equals(decoder.readObject())) { + throw new Error("false expected"); + } + } +} diff --git a/jdk/test/java/beans/XMLDecoder/spec/TestField.java b/jdk/test/java/beans/XMLDecoder/spec/TestField.java new file mode 100644 index 00000000000..aa84408814e --- /dev/null +++ b/jdk/test/java/beans/XMLDecoder/spec/TestField.java @@ -0,0 +1,74 @@ +/* + * Copyright 2008 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 + * @summary Tests element + * @author Sergey Malenkov + */ + +import java.beans.XMLDecoder; + +public final class TestField extends AbstractTest { + public static final String XML + = "\n" + + " \n" + + " \n" + + " static postfix\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " postfix\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + public static void main(String[] args) { + new TestField().test(true); + } + + public static String FIELD; + public String field; + + @Override + protected void validate(XMLDecoder decoder) { + FIELD = "static prefix"; + field = "prefix"; + decoder.setOwner(this); + validate(decoder, "static prefix"); + validate(decoder, "static postfix"); + validate(decoder, "prefix"); + validate(decoder, "postfix"); + } + + private static void validate(XMLDecoder decoder, String name) { + if (!decoder.readObject().equals(name)) { + throw new Error(name + " expected"); + } + } +} diff --git a/jdk/test/java/beans/XMLDecoder/spec/TestFloat.java b/jdk/test/java/beans/XMLDecoder/spec/TestFloat.java new file mode 100644 index 00000000000..bb1287f8804 --- /dev/null +++ b/jdk/test/java/beans/XMLDecoder/spec/TestFloat.java @@ -0,0 +1,58 @@ +/* + * Copyright 2008 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 + * @summary Tests element + * @author Sergey Malenkov + */ + +import java.beans.XMLDecoder; + +public final class TestFloat extends AbstractTest { + public static final String XML + = "\n" + + " 0\n" + + " 100\n" + + " -1e15\n" + + " 100e-20\n" + + ""; + + public static void main(String[] args) { + new TestFloat().test(true); + } + + @Override + protected void validate(XMLDecoder decoder) { + validate(0.0f, decoder.readObject()); + validate(100.0f, decoder.readObject()); + validate(-1e15f, decoder.readObject()); + validate(100e-20f, decoder.readObject()); + } + + private static void validate(float value, Object object) { + if (!object.equals(Float.valueOf(value))) { + throw new Error("float " + value + " expected"); + } + } +} diff --git a/jdk/test/java/beans/XMLDecoder/spec/TestInt.java b/jdk/test/java/beans/XMLDecoder/spec/TestInt.java new file mode 100644 index 00000000000..531c9447b64 --- /dev/null +++ b/jdk/test/java/beans/XMLDecoder/spec/TestInt.java @@ -0,0 +1,64 @@ +/* + * Copyright 2008 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 + * @summary Tests element + * @author Sergey Malenkov + */ + +import java.beans.XMLDecoder; + +public final class TestInt extends AbstractTest { + public static final String XML + = "\n" + + " 0\n" + + " 127\n" + + " -128\n" + + " 32767\n" + + " -32768\n" + + " 2147483647\n" + + " -2147483648\n" + + ""; + + public static void main(String[] args) { + new TestInt().test(true); + } + + @Override + protected void validate(XMLDecoder decoder) { + validate(0, decoder.readObject()); + validate((int) Byte.MAX_VALUE, decoder.readObject()); + validate((int) Byte.MIN_VALUE, decoder.readObject()); + validate((int) Short.MAX_VALUE, decoder.readObject()); + validate((int) Short.MIN_VALUE, decoder.readObject()); + validate(Integer.MAX_VALUE, decoder.readObject()); + validate(Integer.MIN_VALUE, decoder.readObject()); + } + + private static void validate(int value, Object object) { + if (!object.equals(Integer.valueOf(value))) { + throw new Error("int " + value + " expected"); + } + } +} diff --git a/jdk/test/java/beans/XMLDecoder/spec/TestJava.java b/jdk/test/java/beans/XMLDecoder/spec/TestJava.java new file mode 100644 index 00000000000..5786195aaa0 --- /dev/null +++ b/jdk/test/java/beans/XMLDecoder/spec/TestJava.java @@ -0,0 +1,63 @@ +/* + * Copyright 2008 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 + * @summary Tests element + * @author Sergey Malenkov + */ + +import java.beans.XMLDecoder; + +public final class TestJava extends AbstractTest { + public static final String XML + = "\n" + + " \n" + + " \n" + + " Hello, world!\n" + + " \n" + + " \n" + + " \n" + + ""; + + public static void main(String[] args) { + new TestJava().test(true); + } + + private String message; + + public void init(String message) { + this.message = message; + } + + @Override + protected void validate(XMLDecoder decoder) { + decoder.setOwner(this); + if (this != decoder.readObject()) { + throw new Error("owner should be the same"); + } + if (this.message == null) { + throw new Error("owner's method is not called"); + } + } +} diff --git a/jdk/test/java/beans/XMLDecoder/spec/TestLong.java b/jdk/test/java/beans/XMLDecoder/spec/TestLong.java new file mode 100644 index 00000000000..16a7e324014 --- /dev/null +++ b/jdk/test/java/beans/XMLDecoder/spec/TestLong.java @@ -0,0 +1,68 @@ +/* + * Copyright 2008 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 + * @summary Tests element + * @author Sergey Malenkov + */ + +import java.beans.XMLDecoder; + +public final class TestLong extends AbstractTest { + public static final String XML + = "\n" + + " 0\n" + + " 127\n" + + " -128\n" + + " 32767\n" + + " -32768\n" + + " 2147483647\n" + + " -2147483648\n" + + " 9223372036854775807\n" + + " -9223372036854775808\n" + + ""; + + public static void main(String[] args) { + new TestLong().test(true); + } + + @Override + protected void validate(XMLDecoder decoder) { + validate(0L, decoder.readObject()); + validate((long) Byte.MAX_VALUE, decoder.readObject()); + validate((long) Byte.MIN_VALUE, decoder.readObject()); + validate((long) Short.MAX_VALUE, decoder.readObject()); + validate((long) Short.MIN_VALUE, decoder.readObject()); + validate((long) Integer.MAX_VALUE, decoder.readObject()); + validate((long) Integer.MIN_VALUE, decoder.readObject()); + validate(Long.MAX_VALUE, decoder.readObject()); + validate(Long.MIN_VALUE, decoder.readObject()); + } + + private static void validate(long value, Object object) { + if (!object.equals(Long.valueOf(value))) { + throw new Error("long " + value + " expected"); + } + } +} diff --git a/jdk/test/java/beans/XMLDecoder/spec/TestMethod.java b/jdk/test/java/beans/XMLDecoder/spec/TestMethod.java new file mode 100644 index 00000000000..01ee5e1cf95 --- /dev/null +++ b/jdk/test/java/beans/XMLDecoder/spec/TestMethod.java @@ -0,0 +1,178 @@ +/* + * Copyright 2008 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 + * @summary Tests element + * @author Sergey Malenkov + */ + +import java.beans.XMLDecoder; + +public final class TestMethod extends AbstractTest { + public static final String XML + = "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + public static void main(String[] args) { + new TestMethod().test(true); + } + + private NoSuchMethodException exception; + + @Override + public void exceptionThrown(Exception exception) { + if (this.exception != null) { + // only one exception allowed + super.exceptionThrown(exception); + } else if (exception instanceof NoSuchMethodException) { + // expected exception: ambiguous methods are found + this.exception = (NoSuchMethodException) exception; + } else { + super.exceptionThrown(exception); + } + } + + @Override + protected void validate(XMLDecoder decoder) { + this.exception = null; + validate(decoder, A.class); + validate(decoder, B.class); + validate(decoder, C.class); + validate(decoder, D.class); + validate(decoder, E.class); + if (this.exception == null) { + throw new Error("NoSuchMethodException expected"); + } + } + + private static void validate(XMLDecoder decoder, Class type) { + if (!type.equals(decoder.readObject().getClass())) { + throw new Error("unexpected class"); + } + } + + /** + * All ambiguous method declarations should fail. + */ + public static class A { + public void m(X x1, X x2) { + throw new Error("A.m(X,X) should not be called"); + } + + public void m(X x1, Y y2) { + throw new Error("A.m(X,Y) should not be called"); + } + + public void m(Y y1, X x2) { + throw new Error("A.m(Y,X) should not be called"); + } + } + + /** + * The most specific method in this case would be the second declaration. + */ + public static class B { + public void m(X x1, X x2) { + throw new Error("B.m(X,X) should not be called"); + } + + public void m(X x1, Y y2) { + // expected: B.m(X,Y) should be called + } + } + + /** + * The most specific method in this case would be the first declaration. + */ + public static class C { + public void m(Y y1, Y y2) { + // expected: C.m(Y,Y) should be called + } + + public void m(X x1, X x2) { + throw new Error("C.m(X,X) should not be called"); + } + } + + /** + * Same as the previous case but flip methods. + */ + public static class D { + public void m(X x1, X x2) { + throw new Error("D.m(X,X) should not be called"); + } + + public void m(Y y1, Y y2) { + // expected: D.m(Y,Y) should be called + } + } + + /** + * The method should be called with (Z,Z). + */ + public static class E { + public void m(X x1, X x2) { + // expected: E.m(X,X) should be called + } + } + + public static class X { + } + + public static class Y extends X { + } + + public static class Z extends Y { + } +} diff --git a/jdk/test/java/beans/XMLDecoder/spec/TestNew.java b/jdk/test/java/beans/XMLDecoder/spec/TestNew.java new file mode 100644 index 00000000000..3e1e86d9951 --- /dev/null +++ b/jdk/test/java/beans/XMLDecoder/spec/TestNew.java @@ -0,0 +1,90 @@ +/* + * Copyright 2008 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 + * @summary Tests element + * @author Sergey Malenkov + */ + +import java.beans.XMLDecoder; +import java.util.ArrayList; +import java.util.List; + +public final class TestNew extends AbstractTest { + public static final String XML + = "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " single\n" + + " \n" + + " \n" + + " first\n" + + " second\n" + + " third\n" + + " \n" + + ""; + + public static void main(String[] args) { + new TestNew().test(true); + } + + private List list; + + public TestNew(String...messages) { + if (messages != null) { + this.list = new ArrayList(); + for (String message : messages) { + this.list.add(message); + } + } + } + + @Override + public boolean equals(Object object) { + if (object instanceof TestNew) { + TestNew test = (TestNew) object; + return (test.list == null) + ? this.list == null + : test.list.equals(this.list); + } + return false; + } + + @Override + protected void validate(XMLDecoder decoder) { + validate(decoder.readObject()); + validate(decoder.readObject(), null); + validate(decoder.readObject(), "single"); + validate(decoder.readObject(), "first", "second", "third"); + } + + private static void validate(Object object, String...messages) { + if (!object.equals(new TestNew(messages))) { + throw new Error("expected object"); + } + } +} diff --git a/jdk/test/java/beans/XMLDecoder/spec/TestNull.java b/jdk/test/java/beans/XMLDecoder/spec/TestNull.java new file mode 100644 index 00000000000..e14bf951e58 --- /dev/null +++ b/jdk/test/java/beans/XMLDecoder/spec/TestNull.java @@ -0,0 +1,48 @@ +/* + * Copyright 2008 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 + * @summary Tests element + * @author Sergey Malenkov + */ + +import java.beans.XMLDecoder; + +public final class TestNull extends AbstractTest { + public static final String XML + = "\n" + + " \n" + + ""; + + public static void main(String[] args) { + new TestNull().test(true); + } + + @Override + protected void validate(XMLDecoder decoder) { + if (null != decoder.readObject()) { + throw new Error("null value expected"); + } + } +} diff --git a/jdk/test/java/beans/XMLDecoder/spec/TestObject.java b/jdk/test/java/beans/XMLDecoder/spec/TestObject.java new file mode 100644 index 00000000000..d9531b3d646 --- /dev/null +++ b/jdk/test/java/beans/XMLDecoder/spec/TestObject.java @@ -0,0 +1,84 @@ +/* + * Copyright 2008 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 + * @summary Tests element + * @author Sergey Malenkov + */ + +import java.beans.XMLDecoder; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.SwingConstants; + +public final class TestObject extends AbstractTest { + public static final String XML // TODO + = "\n" + + " \n" + + " \n" + + " \n" + + " button\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " label\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + public static void main(String[] args) { + new TestObject().test(true); + } + + @Override + protected void validate(XMLDecoder decoder) { + JPanel panel = (JPanel) decoder.readObject(); + if (2 != panel.getComponents().length) { + throw new Error("unexpected component count"); + } + JButton button = (JButton) panel.getComponents()[0]; + if (!button.getText().equals("button")) { // NON-NLS: hardcoded in XML + throw new Error("unexpected button text"); + } + if (SwingConstants.CENTER != button.getVerticalAlignment()) { + throw new Error("unexpected vertical alignment"); + } + JLabel label = (JLabel) panel.getComponents()[1]; + if (!label.getText().equals("label")) { // NON-NLS: hardcoded in XML + throw new Error("unexpected label text"); + } + if (button != label.getLabelFor()) { + throw new Error("unexpected component"); + } + } +} diff --git a/jdk/test/java/beans/XMLDecoder/spec/TestProperty.java b/jdk/test/java/beans/XMLDecoder/spec/TestProperty.java new file mode 100644 index 00000000000..e1f9c77e445 --- /dev/null +++ b/jdk/test/java/beans/XMLDecoder/spec/TestProperty.java @@ -0,0 +1,88 @@ +/* + * Copyright 2008 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 + * @summary Tests element + * @author Sergey Malenkov + */ + +import java.beans.XMLDecoder; + +public final class TestProperty extends AbstractTest { + public static final String XML + = "\n" + + " \n" + + " \n" + + " message\n" + + " \n" + + " \n" + + " \n" + + " indexed\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + public static void main(String[] args) { + new TestProperty().test(true); + } + + private int index; + private String message; + + public String getMessage() { + return this.message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getIndexed(int index) { + if (this.index != index) { + throw new Error("unexpected index"); + } + return this.message; + } + + public void setIndexed(int index, String message) { + this.index = index; + this.message = message; + } + + @Override + protected void validate(XMLDecoder decoder) { + decoder.setOwner(this); + validate(decoder, "message"); + validate(decoder, "indexed"); + } + + private static void validate(XMLDecoder decoder, String name) { + if (!decoder.readObject().equals(name)) { + throw new Error(name + " expected"); + } + } +} diff --git a/jdk/test/java/beans/XMLDecoder/spec/TestShort.java b/jdk/test/java/beans/XMLDecoder/spec/TestShort.java new file mode 100644 index 00000000000..99a0c57d357 --- /dev/null +++ b/jdk/test/java/beans/XMLDecoder/spec/TestShort.java @@ -0,0 +1,60 @@ +/* + * Copyright 2008 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 + * @summary Tests element + * @author Sergey Malenkov + */ + +import java.beans.XMLDecoder; + +public final class TestShort extends AbstractTest { + public static final String XML + = "\n" + + " 0\n" + + " 127\n" + + " -128\n" + + " 32767\n" + + " -32768\n" + + ""; + + public static void main(String[] args) { + new TestShort().test(true); + } + + @Override + protected void validate(XMLDecoder decoder) { + validate((short) 0, decoder.readObject()); + validate((short) Byte.MAX_VALUE, decoder.readObject()); + validate((short) Byte.MIN_VALUE, decoder.readObject()); + validate(Short.MAX_VALUE, decoder.readObject()); + validate(Short.MIN_VALUE, decoder.readObject()); + } + + private static void validate(short value, Object object) { + if (!object.equals(Short.valueOf(value))) { + throw new Error("short " + value + " expected"); + } + } +} diff --git a/jdk/test/java/beans/XMLDecoder/spec/TestString.java b/jdk/test/java/beans/XMLDecoder/spec/TestString.java new file mode 100644 index 00000000000..d41b1bbce38 --- /dev/null +++ b/jdk/test/java/beans/XMLDecoder/spec/TestString.java @@ -0,0 +1,60 @@ +/* + * Copyright 2008 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 + * @summary Tests element + * @author Sergey Malenkov + */ + +import java.beans.XMLDecoder; + +public final class TestString extends AbstractTest { + public static final String PREFIX = " prefix "; + public static final String POSTFIX = " postfix "; + public static final String XML + = "\n" + + " " + PREFIX + "\n" + + " " + POSTFIX + "\n" + + " " + PREFIX + POSTFIX + "\n" + + " " + PREFIX + "" + POSTFIX + "\n" + + ""; + + public static void main(String[] args) { + new TestString().test(true); + } + + @Override + protected void validate(XMLDecoder decoder) { + validate(PREFIX, decoder.readObject()); + validate(POSTFIX, decoder.readObject()); + validate(PREFIX + POSTFIX, decoder.readObject()); + validate(PREFIX + '\u0000' + POSTFIX, decoder.readObject()); + } + + private static void validate(String name, Object object) { + if (!object.equals(name)) { + throw new Error(name + " expected"); + } + } +} diff --git a/jdk/test/java/beans/XMLDecoder/spec/TestTrue.java b/jdk/test/java/beans/XMLDecoder/spec/TestTrue.java new file mode 100644 index 00000000000..934d28e4f63 --- /dev/null +++ b/jdk/test/java/beans/XMLDecoder/spec/TestTrue.java @@ -0,0 +1,48 @@ +/* + * Copyright 2008 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 + * @summary Tests element + * @author Sergey Malenkov + */ + +import java.beans.XMLDecoder; + +public final class TestTrue extends AbstractTest { + public static final String XML + = "\n" + + " \n" + + ""; + + public static void main(String[] args) { + new TestTrue().test(true); + } + + @Override + protected void validate(XMLDecoder decoder) { + if (!Boolean.TRUE.equals(decoder.readObject())) { + throw new Error("true expected"); + } + } +} diff --git a/jdk/test/java/beans/XMLDecoder/spec/TestVar.java b/jdk/test/java/beans/XMLDecoder/spec/TestVar.java new file mode 100644 index 00000000000..701edad79a8 --- /dev/null +++ b/jdk/test/java/beans/XMLDecoder/spec/TestVar.java @@ -0,0 +1,54 @@ +/* + * Copyright 2008 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 + * @summary Tests element + * @author Sergey Malenkov + */ + +import java.beans.XMLDecoder; + +public final class TestVar extends AbstractTest { + public static final String XML + = "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + public static void main(String[] args) { + new TestVar().test(true); + } + + @Override + protected void validate(XMLDecoder decoder) { + for (int i = 0; i < 3; i++) { + if (decoder != decoder.readObject()) { + throw new Error("decoder instance expected"); + } + } + } +} From aa3da7789a0dfaa0b95a7b8e31382bf11fdcb765 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Thu, 25 Dec 2008 20:43:44 +0300 Subject: [PATCH 17/44] 6736248: EnumEditor bug. Class check incorrect Reviewed-by: rupashka, alexp --- .../classes/sun/beans/editors/EnumEditor.java | 2 +- .../PropertyEditor/TestEnumSubclass.java | 50 +++++++++++++++++ .../PropertyEditor/TestEnumSubclassJava.java | 49 +++++++++++++++++ .../PropertyEditor/TestEnumSubclassNull.java | 49 +++++++++++++++++ .../PropertyEditor/TestEnumSubclassValue.java | 53 +++++++++++++++++++ 5 files changed, 202 insertions(+), 1 deletion(-) create mode 100644 jdk/test/java/beans/PropertyEditor/TestEnumSubclass.java create mode 100644 jdk/test/java/beans/PropertyEditor/TestEnumSubclassJava.java create mode 100644 jdk/test/java/beans/PropertyEditor/TestEnumSubclassNull.java create mode 100644 jdk/test/java/beans/PropertyEditor/TestEnumSubclassValue.java diff --git a/jdk/src/share/classes/sun/beans/editors/EnumEditor.java b/jdk/src/share/classes/sun/beans/editors/EnumEditor.java index 6a465785c17..201c6f24b81 100644 --- a/jdk/src/share/classes/sun/beans/editors/EnumEditor.java +++ b/jdk/src/share/classes/sun/beans/editors/EnumEditor.java @@ -67,7 +67,7 @@ public final class EnumEditor implements PropertyEditor { } public void setValue( Object value ) { - if ( ( value != null ) && ( this.type != value.getClass() ) ) { + if ( ( value != null ) && !this.type.isInstance( value ) ) { throw new IllegalArgumentException( "Unsupported value: " + value ); } Object oldValue; diff --git a/jdk/test/java/beans/PropertyEditor/TestEnumSubclass.java b/jdk/test/java/beans/PropertyEditor/TestEnumSubclass.java new file mode 100644 index 00000000000..f1d5f78c5d2 --- /dev/null +++ b/jdk/test/java/beans/PropertyEditor/TestEnumSubclass.java @@ -0,0 +1,50 @@ +/* + * Copyright 2008 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 6736248 + * @summary Tests PropertyEditor for value of subtype Enum with security manager + * @author Sergey Malenkov + */ + +public class TestEnumSubclass { + public static void main(String[] args) { + System.setSecurityManager(new SecurityManager()); + new TestEditor(Operation.class); + } + + public enum Operation { + PLUS { + public int run(int i, int j) { + return i + j; + } + }, + MINUS { + public int run(int i, int j) { + return i - j; + } + }; + public abstract int run(int i, int j); + } +} diff --git a/jdk/test/java/beans/PropertyEditor/TestEnumSubclassJava.java b/jdk/test/java/beans/PropertyEditor/TestEnumSubclassJava.java new file mode 100644 index 00000000000..296d1f31d1c --- /dev/null +++ b/jdk/test/java/beans/PropertyEditor/TestEnumSubclassJava.java @@ -0,0 +1,49 @@ +/* + * Copyright 2008 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 6736248 + * @summary Tests PropertyEditor for value of subtype Enum + * @author Sergey Malenkov + */ + +public class TestEnumSubclassJava { + public static void main(String[] args) { + new TestEditor(Operation.class).testJava(Operation.PLUS); + } + + public enum Operation { + PLUS { + public int run(int i, int j) { + return i + j; + } + }, + MINUS { + public int run(int i, int j) { + return i - j; + } + }; + public abstract int run(int i, int j); + } +} diff --git a/jdk/test/java/beans/PropertyEditor/TestEnumSubclassNull.java b/jdk/test/java/beans/PropertyEditor/TestEnumSubclassNull.java new file mode 100644 index 00000000000..2a407bf9998 --- /dev/null +++ b/jdk/test/java/beans/PropertyEditor/TestEnumSubclassNull.java @@ -0,0 +1,49 @@ +/* + * Copyright 2008 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 6736248 + * @summary Tests PropertyEditor for null value of subtype Enum + * @author Sergey Malenkov + */ + +public class TestEnumSubclassNull { + public static void main(String[] args) { + new TestEditor(Operation.class).testJava(null); + } + + public enum Operation { + PLUS { + public int run(int i, int j) { + return i + j; + } + }, + MINUS { + public int run(int i, int j) { + return i - j; + } + }; + public abstract int run(int i, int j); + } +} diff --git a/jdk/test/java/beans/PropertyEditor/TestEnumSubclassValue.java b/jdk/test/java/beans/PropertyEditor/TestEnumSubclassValue.java new file mode 100644 index 00000000000..5c0e970f569 --- /dev/null +++ b/jdk/test/java/beans/PropertyEditor/TestEnumSubclassValue.java @@ -0,0 +1,53 @@ +/* + * Copyright 2008 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 6736248 + * @summary Tests PropertyEditor for value of subtype Enum + * @author Sergey Malenkov + */ + +public class TestEnumSubclassValue { + public static void main(String[] args) { + TestEditor test = new TestEditor(Operation.class); + test.testValue(Operation.PLUS, "PLUS"); + test.testValue(null, null); + test.testText("MINUS", Operation.MINUS); + test.testText(null, null); + } + + public enum Operation { + PLUS { + public int run(int i, int j) { + return i + j; + } + }, + MINUS { + public int run(int i, int j) { + return i - j; + } + }; + public abstract int run(int i, int j); + } +} From de73102ff40beb27f2897bcf475bad4b15b40ab9 Mon Sep 17 00:00:00 2001 From: Bhavesh Patel Date: Thu, 15 Jan 2009 17:21:11 -0800 Subject: [PATCH 18/44] 6786682: Javadoc HTML WCAG 2.0 accessibility issues in standard doclet - HTML tag should have lang attribute Reviewed-by: jjg --- .../formats/html/ConfigurationImpl.java | 10 ++ .../formats/html/markup/HtmlWriter.java | 2 +- .../internal/toolkit/Configuration.java | 5 + .../toolkit/util/SourceToHTMLConverter.java | 7 +- .../com/sun/tools/javadoc/RootDocImpl.java | 8 ++ .../sun/javadoc/testHtmlTag/TestHtmlTag.java | 93 +++++++++++++++++++ .../com/sun/javadoc/testHtmlTag/pkg1/C1.java | 33 +++++++ .../com/sun/javadoc/testHtmlTag/pkg2/C2.java | 31 +++++++ 8 files changed, 185 insertions(+), 4 deletions(-) create mode 100644 langtools/test/com/sun/javadoc/testHtmlTag/TestHtmlTag.java create mode 100644 langtools/test/com/sun/javadoc/testHtmlTag/pkg1/C1.java create mode 100644 langtools/test/com/sun/javadoc/testHtmlTag/pkg2/C2.java diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java index 524bd2472a3..70d487da2ba 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java @@ -493,4 +493,14 @@ public class ConfigurationImpl extends Configuration { public Comparator getMemberComparator() { return null; } + + /** + * {@inheritDoc} + */ + public Locale getLocale() { + if (root instanceof com.sun.tools.javadoc.RootDocImpl) + return ((com.sun.tools.javadoc.RootDocImpl)root).getLocale(); + else + return Locale.getDefault(); + } } diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java index 21fb7e642b0..cdafe1be907 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java @@ -85,7 +85,7 @@ public class HtmlWriter extends PrintWriter { * Print <HTML> tag. Add a newline character at the end. */ public void html() { - println(""); + println(""); } /** diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java index 11b37b34498..eb8960f4c65 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java @@ -706,6 +706,11 @@ public abstract class Configuration { new FileInputStream(new File(builderXMLPath)); } + /** + * Return the Locale for this document. + */ + public abstract Locale getLocale(); + /** * Return the comparator that will be used to sort member documentation. * To no do any sorting, return null. diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/SourceToHTMLConverter.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/SourceToHTMLConverter.java index 67a82e8a3b3..8f98dfcfd25 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/SourceToHTMLConverter.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/SourceToHTMLConverter.java @@ -142,7 +142,7 @@ public class SourceToHTMLConverter { reader.close(); } output = addLineNumbers(output.toString()); - output.insert(0, getHeader()); + output.insert(0, getHeader(configuration)); output.append(getFooter()); writeToFile(output.toString(), outputdir, cd.name(), configuration); } catch (Exception e){ @@ -192,10 +192,11 @@ public class SourceToHTMLConverter { /** * Get the header. + * @param configuration the Doclet configuration * @return the header to the output file */ - protected static String getHeader() { - StringBuffer result = new StringBuffer("" + DocletConstants.NL); + protected static String getHeader(Configuration configuration) { + StringBuffer result = new StringBuffer("" + DocletConstants.NL); result.append("" + DocletConstants.NL); result.append("
" + DocletConstants.NL);
         return result.toString();
diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/RootDocImpl.java b/langtools/src/share/classes/com/sun/tools/javadoc/RootDocImpl.java
index 8595151cc32..4c7cd5fa2e8 100644
--- a/langtools/src/share/classes/com/sun/tools/javadoc/RootDocImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/RootDocImpl.java
@@ -36,6 +36,7 @@ import com.sun.tools.javac.code.Symbol;
 import com.sun.tools.javac.util.List;
 import com.sun.tools.javac.util.ListBuffer;
 import com.sun.tools.javac.util.Position;
+import java.util.Locale;
 
 /**
  * This class holds the information from one run of javadoc.
@@ -351,4 +352,11 @@ public class RootDocImpl extends DocImpl implements RootDoc {
             null :
             SourcePositionImpl.make(path, Position.NOPOS, null);
     }
+
+    /**
+     * Return the locale provided by the user or the default locale value.
+     */
+    public Locale getLocale() {
+        return env.doclocale.locale;
+    }
 }
diff --git a/langtools/test/com/sun/javadoc/testHtmlTag/TestHtmlTag.java b/langtools/test/com/sun/javadoc/testHtmlTag/TestHtmlTag.java
new file mode 100644
index 00000000000..4588d070b7e
--- /dev/null
+++ b/langtools/test/com/sun/javadoc/testHtmlTag/TestHtmlTag.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.  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
+ * 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 6786682
+ * @summary This test verifies the use of lang attribute by .
+ * @author Bhavesh Patel
+ * @library ../lib/
+ * @build JavadocTester
+ * @build TestHtmlTag
+ * @run main TestHtmlTag
+ */
+
+import java.util.Locale;
+
+public class TestHtmlTag extends JavadocTester {
+
+    private static final String BUG_ID = "6786682";
+    private static final String[][] TEST1 = {
+        {BUG_ID + FS + "pkg1" + FS + "C1.html", ""},
+        {BUG_ID + FS + "pkg1" + FS + "package-summary.html", ""}};
+    private static final String[][] NEGATED_TEST1 = {
+        {BUG_ID + FS + "pkg1" + FS + "C1.html", ""}};
+    private static final String[][] TEST2 = {
+        {BUG_ID + FS + "pkg2" + FS + "C2.html", ""},
+        {BUG_ID + FS + "pkg2" + FS + "package-summary.html", ""}};
+    private static final String[][] NEGATED_TEST2 = {
+        {BUG_ID + FS + "pkg2" + FS + "C2.html", ""}};
+    private static final String[][] TEST3 = {
+        {BUG_ID + FS + "pkg1" + FS + "C1.html", ""},
+        {BUG_ID + FS + "pkg1" + FS + "package-summary.html", ""}};
+    private static final String[][] NEGATED_TEST3 = {
+        {BUG_ID + FS + "pkg1" + FS + "C1.html", ""}};
+
+    private static final String[] ARGS1 =
+        new String[] {
+            "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg1"};
+    private static final String[] ARGS2 =
+        new String[] {
+            "-locale", "ja", "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg2"};
+    private static final String[] ARGS3 =
+        new String[] {
+            "-locale", "en_US", "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg1"};
+
+    /**
+     * The entry point of the test.
+     * @param args the array of command line arguments.
+     */
+    public static void main(String[] args) {
+        TestHtmlTag tester = new TestHtmlTag();
+        run(tester, ARGS1, TEST1, NEGATED_TEST1);
+        run(tester, ARGS2, TEST2, NEGATED_TEST2);
+        run(tester, ARGS3, TEST3, NEGATED_TEST3);
+        tester.printSummary();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getBugId() {
+        return BUG_ID;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getBugName() {
+        return getClass().getName();
+    }
+}
diff --git a/langtools/test/com/sun/javadoc/testHtmlTag/pkg1/C1.java b/langtools/test/com/sun/javadoc/testHtmlTag/pkg1/C1.java
new file mode 100644
index 00000000000..5fb4bc8a30e
--- /dev/null
+++ b/langtools/test/com/sun/javadoc/testHtmlTag/pkg1/C1.java
@@ -0,0 +1,33 @@
+/*
+ * 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.  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
+ * 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.
+ */
+
+package pkg1;
+
+public class C1 {
+
+    public void method(int param1, int param2) {
+
+    }
+}
diff --git a/langtools/test/com/sun/javadoc/testHtmlTag/pkg2/C2.java b/langtools/test/com/sun/javadoc/testHtmlTag/pkg2/C2.java
new file mode 100644
index 00000000000..2bd9d323be8
--- /dev/null
+++ b/langtools/test/com/sun/javadoc/testHtmlTag/pkg2/C2.java
@@ -0,0 +1,31 @@
+/*
+ * 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.  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
+ * 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.
+ */
+
+package pkg2;
+
+/**
+ * Comments: Class 2
+ */
+public class C2 {}

From b4747d31883141ae46230597b0173b82cec13c50 Mon Sep 17 00:00:00 2001
From: Jonathan Gibbons 
Date: Thu, 15 Jan 2009 18:06:36 -0800
Subject: [PATCH 19/44] 6794520: MessageRetriever should be upgraded to use
 varargs Object..

Reviewed-by: bpatel
---
 .../toolkit/util/MessageRetriever.java        | 274 ++----------------
 .../doclets/internal/toolkit/util/Util.java   |   1 -
 2 files changed, 21 insertions(+), 254 deletions(-)

diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/MessageRetriever.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/MessageRetriever.java
index 4055b914822..9f0b6417d6c 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/MessageRetriever.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/MessageRetriever.java
@@ -80,47 +80,15 @@ public class MessageRetriever {
         this.resourcelocation = resourcelocation;
     }
 
-    /**
-     * get and format message string from resource
-     *
-     * @param key selects message from resource
-     */
-    public String getText(String key) {
-        return getText(key, (String)null);
-    }
-
     /**
      * Get and format message string from resource
      *
      * @param key selects message from resource
-     * @param a1 Argument, to be repalced in the message.
-     */
-    public String getText(String key, String a1) {
-        return getText(key, a1, null);
-    }
-
-    /**
-     * Get and format message string from resource
-     *
-     * @param key selects message from resource
-     * @param a1 first argument to be replaced in the message.
-     * @param a2 second argument to be replaced in the message.
-     */
-    public String getText(String key, String a1, String a2) {
-        return getText(key, a1, a2, null);
-    }
-
-    /**
-     * Get and format message string from resource
-     *
-     * @param key selects message from resource
-     * @param a1 first argument to be replaced in the message.
-     * @param a2 second argument to be replaced in the message.
-     * @param a3 third argument to be replaced in the message.
+     * @param args arguments to be replaced in the message.
      * @throws MissingResourceException when the key does not
      * exist in the properties file.
      */
-    public String getText(String key, String a1, String a2, String a3) throws MissingResourceException {
+    public String getText(String key, Object... args) throws MissingResourceException {
         if (messageRB == null) {
             try {
                 messageRB = ResourceBundle.getBundle(resourcelocation);
@@ -130,7 +98,7 @@ public class MessageRetriever {
             }
         }
         String message = messageRB.getString(key);
-        return MessageFormat.format(message, a1, a2, a3);
+        return MessageFormat.format(message, args);
     }
 
     /**
@@ -195,87 +163,20 @@ public class MessageRetriever {
      *
      * @param pos the position of the source
      * @param key selects message from resource
+     * @param args arguments to be replaced in the message.
      */
-    public void error(SourcePosition pos, String key) {
-        printError(pos, getText(key));
+    public void error(SourcePosition pos, String key, Object... args) {
+        printError(pos, getText(key, args));
     }
 
     /**
      * Print error message, increment error count.
      *
      * @param key selects message from resource
+     * @param args arguments to be replaced in the message.
      */
-    public void error(String key) {
-        printError(getText(key));
-    }
-
-    /**
-     * Print error message, increment error count.
-     *
-     * @param pos the position of the source
-     * @param key selects message from resource
-     * @param a1 first argument to be replaced in the message.
-     */
-    public void error(SourcePosition pos, String key, String a1) {
-        printError(pos, getText(key, a1));
-    }
-
-    /**
-     * Print error message, increment error count.
-     *
-     * @param key selects message from resource
-     * @param a1 first argument to be replaced in the message.
-     */
-    public void error(String key, String a1) {
-        printError(getText(key, a1));
-    }
-
-    /**
-     * Print error message, increment error count.
-     *
-     * @param pos the position of the source
-     * @param key selects message from resource
-     * @param a1 first argument to be replaced in the message.
-     * @param a2 second argument to be replaced in the message.
-     */
-    public void error(SourcePosition pos, String key, String a1, String a2) {
-        printError(pos, getText(key, a1, a2));
-    }
-
-    /**
-     * Print error message, increment error count.
-     *
-     * @param key selects message from resource
-     * @param a1 first argument to be replaced in the message.
-     * @param a2 second argument to be replaced in the message.
-     */
-    public void error(String key, String a1, String a2) {
-        printError(getText(key, a1, a2));
-    }
-
-    /**
-     * Print error message, increment error count.
-     *
-     * @param pos the position of the source
-     * @param key selects message from resource
-     * @param a1 first argument to be replaced in the message.
-     * @param a2 second argument to be replaced in the message.
-     * @param a3 third argument to be replaced in the message.
-     */
-    public void error(SourcePosition pos, String key, String a1, String a2, String a3) {
-        printError(pos, getText(key, a1, a2, a3));
-    }
-
-    /**
-     * Print error message, increment error count.
-     *
-     * @param key selects message from resource
-     * @param a1 first argument to be replaced in the message.
-     * @param a2 second argument to be replaced in the message.
-     * @param a3 third argument to be replaced in the message.
-     */
-    public void error(String key, String a1, String a2, String a3) {
-        printError(getText(key, a1, a2, a3));
+    public void error(String key, Object... args) {
+        printError(getText(key, args));
     }
 
     /**
@@ -283,87 +184,20 @@ public class MessageRetriever {
      *
      * @param pos the position of the source
      * @param key selects message from resource
+     * @param args arguments to be replaced in the message.
      */
-    public void warning(SourcePosition pos, String key) {
-        printWarning(pos, getText(key));
+    public void warning(SourcePosition pos, String key, Object... args) {
+        printWarning(pos, getText(key, args));
     }
 
     /**
      * Print warning message, increment warning count.
      *
      * @param key selects message from resource
+     * @param args arguments to be replaced in the message.
      */
-    public void warning(String key) {
-        printWarning(getText(key));
-    }
-
-    /**
-     * Print warning message, increment warning count.
-     *
-     * @param pos the position of the source
-     * @param key selects message from resource
-     * @param a1 first argument to be replaced in the message.
-     */
-    public void warning(SourcePosition pos, String key, String a1) {
-        printWarning(pos, getText(key, a1));
-    }
-
-    /**
-     * Print warning message, increment warning count.
-     *
-     * @param key selects message from resource
-     * @param a1 first argument to be replaced in the message.
-     */
-    public void warning(String key, String a1) {
-        printWarning(getText(key, a1));
-    }
-
-    /**
-     * Print warning message, increment warning count.
-     *
-     * @param pos the position of the source
-     * @param key selects message from resource
-     * @param a1 first argument to be replaced in the message.
-     * @param a2 second argument to be replaced in the message.
-     */
-    public void warning(SourcePosition pos, String key, String a1, String a2) {
-        printWarning(pos, getText(key, a1, a2));
-    }
-
-    /**
-     * Print warning message, increment warning count.
-     *
-     * @param key selects message from resource
-     * @param a1 first argument to be replaced in the message.
-     * @param a2 second argument to be replaced in the message.
-     */
-    public void warning(String key, String a1, String a2) {
-        printWarning(getText(key, a1, a2));
-    }
-
-    /**
-     * Print warning message, increment warning count.
-     *
-     * @param pos the position of the source
-     * @param key selects message from resource
-     * @param a1 first argument to be replaced in the message.
-     * @param a2 second argument to be replaced in the message.
-     * @param a3 third argument to be replaced in the message.
-     */
-    public void warning(SourcePosition pos, String key, String a1, String a2, String a3) {
-        printWarning(pos, getText(key, a1, a2, a3));
-    }
-
-    /**
-     * Print warning message, increment warning count.
-     *
-     * @param key selects message from resource
-     * @param a1 first argument to be replaced in the message.
-     * @param a2 second argument to be replaced in the message.
-     * @param a3 third argument to be replaced in the message.
-     */
-    public void warning(String key, String a1, String a2, String a3) {
-        printWarning(getText(key, a1, a2, a3));
+    public void warning(String key, Object... args) {
+        printWarning(getText(key, args));
     }
 
     /**
@@ -371,85 +205,19 @@ public class MessageRetriever {
      *
      * @param pos the position of the source
      * @param key selects message from resource
+     * @param args arguments to be replaced in the message.
      */
-    public void notice(SourcePosition pos, String key) {
-        printNotice(pos, getText(key));
+    public void notice(SourcePosition pos, String key, Object... args) {
+        printNotice(pos, getText(key, args));
     }
 
     /**
      * Print a message.
      *
      * @param key selects message from resource
+     * @param args arguments to be replaced in the message.
      */
-    public void notice(String key) {
-        printNotice(getText(key));
-    }
-
-    /**
-     * Print a message.
-     * @param pos the position of the source
-     * @param key selects message from resource
-     * @param a1 first argument to be replaced in the message.
-     */
-    public void notice(SourcePosition pos, String key, String a1) {
-        printNotice(pos, getText(key, a1));
-    }
-
-    /**
-     * Print a message.
-     *
-     * @param key selects message from resource
-     * @param a1 first argument to be replaced in the message.
-     */
-    public void notice(String key, String a1) {
-        printNotice(getText(key, a1));
-    }
-
-    /**
-     * Print a message.
-     *
-     * @param pos the position of the source
-     * @param key selects message from resource
-     * @param a1 first argument to be replaced in the message.
-     * @param a2 second argument to be replaced in the message.
-     */
-    public void notice(SourcePosition pos, String key, String a1, String a2) {
-        printNotice(pos, getText(key, a1, a2));
-    }
-
-    /**
-     * Print a message.
-     *
-     * @param key selects message from resource
-     * @param a1 first argument to be replaced in the message.
-     * @param a2 second argument to be replaced in the message.
-     */
-    public void notice(String key, String a1, String a2) {
-        printNotice(getText(key, a1, a2));
-    }
-
-    /**
-     * Print a message.
-     *
-     * @param pos the position of the source
-     * @param key selects message from resource
-     * @param a1 first argument to be replaced in the message.
-     * @param a2 second argument to be replaced in the message.
-     * @param a3 third argument to be replaced in the message.
-     */
-    public void notice(SourcePosition pos, String key, String a1, String a2, String a3) {
-        printNotice(pos, getText(key, a1, a2, a3));
-    }
-
-    /**
-     * Print a message.
-     *
-     * @param key selects message from resource
-     * @param a1 first argument to be replaced in the message.
-     * @param a2 second argument to be replaced in the message.
-     * @param a3 third argument to be replaced in the message.
-     */
-    public void notice(String key, String a1, String a2, String a3) {
-        printNotice(getText(key, a1, a2, a3));
+    public void notice(String key, Object... args) {
+        printNotice(getText(key, args));
     }
 }
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java
index 9b7b668b6c0..ef6ab80892b 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java
@@ -599,7 +599,6 @@ public class Util {
         }
         if (docencoding == null) {
             OutputStreamWriter oswriter = new OutputStreamWriter(fos);
-            docencoding = oswriter.getEncoding();
             return oswriter;
         } else {
             return new OutputStreamWriter(fos, docencoding);

From 66443965435433de5cac7514dd0b444665ef11a2 Mon Sep 17 00:00:00 2001
From: Joe Darcy 
Date: Fri, 16 Jan 2009 14:05:55 -0800
Subject: [PATCH 20/44] 6583626: Improve serialization support in
 javax.lang.model.type exception classes

Reviewed-by: jjg
---
 .../model/type/MirroredTypeException.java     | 14 ++++++++++--
 .../model/type/MirroredTypesException.java    | 22 ++++++++++++++-----
 2 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/langtools/src/share/classes/javax/lang/model/type/MirroredTypeException.java b/langtools/src/share/classes/javax/lang/model/type/MirroredTypeException.java
index bf5904b8a61..db729c59550 100644
--- a/langtools/src/share/classes/javax/lang/model/type/MirroredTypeException.java
+++ b/langtools/src/share/classes/javax/lang/model/type/MirroredTypeException.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2005-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
@@ -25,7 +25,8 @@
 
 package javax.lang.model.type;
 
-
+import java.io.ObjectInputStream;
+import java.io.IOException;
 import java.lang.annotation.Annotation;
 import javax.lang.model.element.Element;
 
@@ -67,4 +68,13 @@ public class MirroredTypeException extends RuntimeException {
     public TypeMirror getTypeMirror() {
         return type;
     }
+
+    /**
+     * Explicitly set all transient fields.
+     */
+    private void readObject(ObjectInputStream s)
+        throws IOException, ClassNotFoundException {
+        s.defaultReadObject();
+        type = null;
+    }
 }
diff --git a/langtools/src/share/classes/javax/lang/model/type/MirroredTypesException.java b/langtools/src/share/classes/javax/lang/model/type/MirroredTypesException.java
index 4ed0383d5ea..54efe41a7c9 100644
--- a/langtools/src/share/classes/javax/lang/model/type/MirroredTypesException.java
+++ b/langtools/src/share/classes/javax/lang/model/type/MirroredTypesException.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2005-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
@@ -25,12 +25,12 @@
 
 package javax.lang.model.type;
 
-
 import java.lang.annotation.Annotation;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Collections;
-
+import java.io.ObjectInputStream;
+import java.io.IOException;
 import javax.lang.model.element.Element;
 
 
@@ -49,8 +49,7 @@ public class MirroredTypesException extends RuntimeException {
 
     private static final long serialVersionUID = 269;
 
-    // Should this be non-final for a custum readObject method?
-    private final transient List types;   // cannot be serialized
+    private transient List types; // cannot be serialized
 
     /**
      * Constructs a new MirroredTypesException for the specified types.
@@ -58,7 +57,9 @@ public class MirroredTypesException extends RuntimeException {
      * @param types  the types being accessed
      */
     public MirroredTypesException(List types) {
-        super("Attempt to access Class objects for TypeMirrors " + types);
+        super("Attempt to access Class objects for TypeMirrors " +
+              (types = // defensive copy
+               new ArrayList(types)).toString() );
         this.types = Collections.unmodifiableList(types);
     }
 
@@ -72,4 +73,13 @@ public class MirroredTypesException extends RuntimeException {
     public List getTypeMirrors() {
         return types;
     }
+
+    /**
+     * Explicitly set all transient fields.
+     */
+    private void readObject(ObjectInputStream s)
+        throws IOException, ClassNotFoundException {
+        s.defaultReadObject();
+        types = null;
+    }
 }

From e3d66c641499640a5e7c0b6a1a3df7170fbc5299 Mon Sep 17 00:00:00 2001
From: Alex Menkov 
Date: Mon, 19 Jan 2009 20:11:58 +0300
Subject: [PATCH 21/44] 6702956: OpenJDK: replace encumbered code (software
 synthesizer) 6717691: Update Gervill with post 1.0 fixes 6740210: Update
 Gervill with more post 1.0 fixes 6748247: Further update Gervill with still
 more post 1.0 fixes 6748251: Apply IcedTea midi sound patch 6758986: Gervill:
 Turn SoftJitterCorrector, SoftAudioPusher threads into a daemon threads

Reviewed-by: ohair, darcy
---
 jdk/make/common/Release.gmk                   |    8 -
 jdk/make/common/internal/BinaryPlugs.gmk      |   91 +-
 jdk/make/javax/sound/Makefile                 |   21 +-
 jdk/make/javax/sound/jsoundhs/FILES.gmk       |   91 -
 jdk/make/javax/sound/jsoundhs/Makefile        |  100 -
 jdk/make/javax/sound/jsoundhs/mapfile-vers    |  153 -
 .../sun/media/sound/AbstractMidiDevice.java   |   29 +-
 .../media/sound/AudioFileSoundbankReader.java |  131 +
 .../sun/media/sound/AudioFloatConverter.java  | 1058 +++++++
 .../sound/AudioFloatFormatConverter.java      |  617 ++++
 .../media/sound/AudioFloatInputStream.java    |  281 ++
 .../com/sun/media/sound/AudioSynthesizer.java |  128 +
 .../sound/AudioSynthesizerPropertyInfo.java   |   76 +
 .../classes/com/sun/media/sound/DLSInfo.java  |  109 +
 .../com/sun/media/sound/DLSInstrument.java    |  448 +++
 .../com/sun/media/sound/DLSModulator.java     |  351 +++
 .../com/sun/media/sound/DLSRegion.java        |  150 +
 .../com/sun/media/sound/DLSSample.java        |  122 +
 .../com/sun/media/sound/DLSSampleLoop.java    |   63 +
 .../com/sun/media/sound/DLSSampleOptions.java |   80 +
 .../com/sun/media/sound/DLSSoundbank.java     | 1287 ++++++++
 .../sun/media/sound/DLSSoundbankReader.java   |   74 +
 .../sun/media/sound/DirectAudioDevice.java    |  108 +-
 .../sun/media/sound/EmergencySoundbank.java   | 2695 +++++++++++++++++
 .../classes/com/sun/media/sound/FFT.java      |  748 +++++
 .../sun/media/sound/InvalidDataException.java |   45 +
 .../media/sound/InvalidFormatException.java   |   44 +
 .../sun/media/sound/JARSoundbankReader.java   |  120 +
 .../sound/ModelAbstractChannelMixer.java      |  126 +
 .../media/sound/ModelAbstractOscillator.java  |  200 ++
 .../com/sun/media/sound/ModelByteBuffer.java  |  329 ++
 .../media/sound/ModelByteBufferWavetable.java |  281 ++
 .../sun/media/sound/ModelChannelMixer.java    |   50 +
 .../sun/media/sound/ModelConnectionBlock.java |  135 +
 .../com/sun/media/sound/ModelDestination.java |  117 +
 .../sun/media/sound/ModelDirectedPlayer.java  |   36 +
 .../com/sun/media/sound/ModelDirector.java    |   46 +
 .../com/sun/media/sound/ModelIdentifier.java  |  169 ++
 .../com/sun/media/sound/ModelInstrument.java  |  136 +
 .../sound/ModelInstrumentComparator.java      |   52 +
 .../media/sound/ModelMappedInstrument.java    |   62 +
 .../com/sun/media/sound/ModelOscillator.java  |   44 +
 .../media/sound/ModelOscillatorStream.java    |   48 +
 .../com/sun/media/sound/ModelPatch.java       |   52 +
 .../com/sun/media/sound/ModelPerformer.java   |  143 +
 .../com/sun/media/sound/ModelSource.java      |  109 +
 .../media/sound/ModelStandardDirector.java    |   86 +
 .../media/sound/ModelStandardTransform.java   |  139 +
 .../com/sun/media/sound/ModelTransform.java   |   35 +
 .../com/sun/media/sound/ModelWavetable.java   |   49 +
 .../classes/com/sun/media/sound/Platform.java |    5 +-
 .../media/sound/RIFFInvalidDataException.java |   43 +
 .../sound/RIFFInvalidFormatException.java     |   44 +
 .../com/sun/media/sound/RIFFReader.java       |  332 ++
 .../com/sun/media/sound/RIFFWriter.java       |  365 +++
 .../sun/media/sound/RealTimeSequencer.java    |  337 ---
 .../com/sun/media/sound/SF2GlobalRegion.java  |   33 +
 .../com/sun/media/sound/SF2Instrument.java    |  911 ++++++
 .../sun/media/sound/SF2InstrumentRegion.java  |   43 +
 .../classes/com/sun/media/sound/SF2Layer.java |   78 +
 .../com/sun/media/sound/SF2LayerRegion.java   |   43 +
 .../com/sun/media/sound/SF2Modulator.java     |   97 +
 .../com/sun/media/sound/SF2Region.java        |  167 +
 .../com/sun/media/sound/SF2Sample.java        |  216 ++
 .../com/sun/media/sound/SF2Soundbank.java     |  973 ++++++
 .../sun/media/sound/SF2SoundbankReader.java   |   73 +
 .../com/sun/media/sound/SimpleInstrument.java |  196 ++
 .../com/sun/media/sound/SimpleSoundbank.java  |  145 +
 .../media/sound/SoftAbstractResampler.java    |  390 +++
 .../com/sun/media/sound/SoftAudioBuffer.java  |  104 +
 .../sun/media/sound/SoftAudioProcessor.java   |   48 +
 .../com/sun/media/sound/SoftAudioPusher.java  |   91 +
 .../com/sun/media/sound/SoftChannel.java      | 1548 ++++++++++
 .../com/sun/media/sound/SoftChannelProxy.java |  202 ++
 .../com/sun/media/sound/SoftChorus.java       |  341 +++
 .../com/sun/media/sound/SoftControl.java      |   36 +
 .../sun/media/sound/SoftCubicResampler.java   |   87 +
 .../media/sound/SoftEnvelopeGenerator.java    |  298 ++
 .../com/sun/media/sound/SoftFilter.java       |  614 ++++
 .../com/sun/media/sound/SoftInstrument.java   |   82 +
 .../sun/media/sound/SoftJitterCorrector.java  |  276 ++
 .../sun/media/sound/SoftLanczosResampler.java |  118 +
 .../com/sun/media/sound/SoftLimiter.java      |  191 ++
 .../sun/media/sound/SoftLinearResampler.java  |   70 +
 .../sun/media/sound/SoftLinearResampler2.java |  108 +
 .../sound/SoftLowFrequencyOscillator.java     |  122 +
 .../com/sun/media/sound/SoftMainMixer.java    |  982 ++++++
 .../media/sound/SoftMidiAudioFileReader.java  |  214 ++
 .../com/sun/media/sound/SoftMixingClip.java   |  539 ++++
 .../sun/media/sound/SoftMixingDataLine.java   |  522 ++++
 .../sun/media/sound/SoftMixingMainMixer.java  |  259 ++
 .../com/sun/media/sound/SoftMixingMixer.java  |  529 ++++
 .../media/sound/SoftMixingMixerProvider.java  |   66 +
 .../media/sound/SoftMixingSourceDataLine.java |  519 ++++
 .../com/sun/media/sound/SoftPerformer.java    |  775 +++++
 .../sun/media/sound/SoftPointResampler.java   |   63 +
 .../com/sun/media/sound/SoftProcess.java      |   41 +
 .../com/sun/media/sound/SoftProvider.java     |   51 +
 .../com/sun/media/sound/SoftReceiver.java     |   83 +
 .../com/sun/media/sound/SoftResampler.java    |   35 +
 .../media/sound/SoftResamplerStreamer.java    |   38 +
 .../com/sun/media/sound/SoftReverb.java       |  515 ++++
 .../com/sun/media/sound/SoftShortMessage.java |   58 +
 .../sun/media/sound/SoftSincResampler.java    |  139 +
 .../com/sun/media/sound/SoftSynthesizer.java  | 1179 +++++++
 .../com/sun/media/sound/SoftTuning.java       |  256 ++
 .../com/sun/media/sound/SoftVoice.java        |  841 +++++
 .../media/sound/WaveExtensibleFileReader.java |  339 +++
 .../sun/media/sound/WaveFloatFileReader.java  |  166 +
 .../sun/media/sound/WaveFloatFileWriter.java  |  147 +
 .../javax.sound.midi.spi.MidiDeviceProvider   |    2 +-
 .../javax.sound.midi.spi.MidiFileReader       |    1 -
 .../javax.sound.midi.spi.SoundbankReader      |    5 +-
 .../javax.sound.sampled.spi.AudioFileReader   |    2 +
 ...sound.sampled.spi.FormatConversionProvider |    1 +
 .../javax.sound.sampled.spi.MixerProvider     |    2 -
 jdk/src/share/lib/audio/soundbank.gm          |  Bin 493589 -> 0 bytes
 .../AudioFloatConverter/GetFormat.java        |   41 +
 .../AudioFloatConverter/ToFloatArray.java     |  160 +
 .../AudioFloatInputStream/Available.java      |   81 +
 .../Gervill/AudioFloatInputStream/Close.java  |   72 +
 .../AudioFloatInputStream/GetFormat.java      |   74 +
 .../AudioFloatInputStream/GetFrameLength.java |   74 +
 .../AudioFloatInputStream/MarkSupported.java  |   74 +
 .../Gervill/AudioFloatInputStream/Read.java   |   83 +
 .../AudioFloatInputStream/ReadFloatArray.java |   81 +
 .../ReadFloatArrayIntInt.java                 |   83 +
 .../Gervill/AudioFloatInputStream/Reset.java  |   87 +
 .../Gervill/AudioFloatInputStream/Skip.java   |   83 +
 .../TestGetSoundbankFile.java                 |   52 +
 .../TestGetSoundbankInputStream.java          |   63 +
 .../TestGetSoundbankInputStream2.java         |  119 +
 .../TestGetSoundbankUrl.java                  |   54 +
 .../midi/Gervill/DLSSoundbankReader/ding.dls  |  Bin 0 -> 72554 bytes
 .../TestCreateSoundbank.java                  |   59 +
 .../ModelByteBuffer/GetInputStream.java       |   91 +
 .../midi/Gervill/ModelByteBuffer/GetRoot.java |   82 +
 .../midi/Gervill/ModelByteBuffer/Load.java    |   89 +
 .../midi/Gervill/ModelByteBuffer/LoadAll.java |   93 +
 .../NewModelByteBufferByteArray.java          |   84 +
 .../NewModelByteBufferByteArrayIntInt.java    |   86 +
 .../NewModelByteBufferFile.java               |   88 +
 .../NewModelByteBufferFileLongLong.java       |   88 +
 .../RandomFileInputStream/Available.java      |  107 +
 .../RandomFileInputStream/Close.java          |  104 +
 .../RandomFileInputStream/MarkReset.java      |  129 +
 .../RandomFileInputStream/MarkSupported.java  |  106 +
 .../RandomFileInputStream/Read.java           |  117 +
 .../RandomFileInputStream/ReadByte.java       |  118 +
 .../RandomFileInputStream/ReadByteIntInt.java |  118 +
 .../RandomFileInputStream/Skip.java           |  131 +
 .../ModelByteBuffer/SubbufferLong.java        |   92 +
 .../ModelByteBuffer/SubbufferLongLong.java    |   92 +
 .../SubbufferLongLongBoolean.java             |   98 +
 .../midi/Gervill/ModelByteBuffer/Unload.java  |   83 +
 .../midi/Gervill/ModelByteBuffer/WriteTo.java |   92 +
 .../GetAttenuation.java                       |   97 +
 .../ModelByteBufferWavetable/GetChannels.java |   97 +
 .../GetLoopLength.java                        |   96 +
 .../GetLoopStart.java                         |   96 +
 .../GetPitchCorrection.java                   |   97 +
 ...delByteBufferWavetableModelByteBuffer.java |   94 +
 ...erWavetableModelByteBufferAudioFormat.java |   94 +
 ...etableModelByteBufferAudioFormatFloat.java |   94 +
 ...teBufferWavetableModelByteBufferFloat.java |   96 +
 .../ModelByteBufferWavetable/Open.java        |   92 +
 .../Set8BitExtensionBuffer.java               |  119 +
 .../ModelByteBufferWavetable/SetLoopType.java |   96 +
 .../ModelDestination/NewModelDestination.java |   46 +
 .../NewModelDestinationModelIdentifier.java   |   46 +
 .../ModelDestination/SetIdentifier.java       |   45 +
 .../ModelDestination/SetTransform.java        |   46 +
 .../Gervill/ModelIdentifier/EqualsObject.java |   54 +
 .../NewModelIdentifierString.java             |   48 +
 .../NewModelIdentifierStringInt.java          |   48 +
 .../NewModelIdentifierStringString.java       |   48 +
 .../NewModelIdentifierStringStringInt.java    |   48 +
 .../Gervill/ModelIdentifier/SetInstance.java  |   45 +
 .../Gervill/ModelIdentifier/SetObject.java    |   45 +
 .../Gervill/ModelIdentifier/SetVariable.java  |   45 +
 .../ModelPerformer/GetOscillators.java        |   44 +
 .../ModelPerformer/SetConnectionBlocks.java   |   48 +
 .../SetDefaultConnectionsEnabled.java         |   49 +
 .../ModelPerformer/SetExclusiveClass.java     |   45 +
 .../Gervill/ModelPerformer/SetKeyFrom.java    |   45 +
 .../midi/Gervill/ModelPerformer/SetKeyTo.java |   45 +
 .../midi/Gervill/ModelPerformer/SetName.java  |   45 +
 .../ModelPerformer/SetSelfNonExclusive.java   |   48 +
 .../Gervill/ModelPerformer/SetVelFrom.java    |   45 +
 .../midi/Gervill/ModelPerformer/SetVelTo.java |   45 +
 .../Gervill/ModelSource/NewModelSource.java   |   48 +
 .../NewModelSourceModelIdentifier.java        |   46 +
 .../NewModelSourceModelIdentifierBoolean.java |   49 +
 ...elSourceModelIdentifierBooleanBoolean.java |   51 +
 ...ourceModelIdentifierBooleanBooleanInt.java |   56 +
 ...elSourceModelIdentifierModelTransform.java |   47 +
 .../Gervill/ModelSource/SetIdentifier.java    |   45 +
 .../Gervill/ModelSource/SetTransform.java     |   46 +
 .../NewModelStandardTransform.java            |   48 +
 .../NewModelStandardTransformBoolean.java     |   48 +
 ...wModelStandardTransformBooleanBoolean.java |   50 +
 ...delStandardTransformBooleanBooleanInt.java |   51 +
 .../ModelStandardTransform/SetDirection.java  |   45 +
 .../ModelStandardTransform/SetPolarity.java   |   45 +
 .../ModelStandardTransform/SetTransform.java  |   74 +
 .../TransformAbsolute.java                    |   73 +
 .../TransformConcave.java                     |   98 +
 .../TransformConvex.java                      |   98 +
 .../TransformLinear.java                      |   90 +
 .../TransformSwitch.java                      |   63 +
 .../Gervill/RiffReaderWriter/Available.java   |   78 +
 .../midi/Gervill/RiffReaderWriter/Close.java  |   72 +
 .../RiffReaderWriter/GetFilePointer.java      |   78 +
 .../Gervill/RiffReaderWriter/GetSize.java     |   77 +
 .../RiffReaderWriter/HasNextChunk.java        |   85 +
 .../midi/Gervill/RiffReaderWriter/Read.java   |   79 +
 .../Gervill/RiffReaderWriter/ReadByte.java    |   79 +
 .../RiffReaderWriter/ReadByteArrayIntInt.java |   81 +
 .../Gervill/RiffReaderWriter/ReadInt.java     |   79 +
 .../Gervill/RiffReaderWriter/ReadLong.java    |   79 +
 .../Gervill/RiffReaderWriter/ReadShort.java   |   79 +
 .../Gervill/RiffReaderWriter/ReadString.java  |   79 +
 .../RiffReaderWriter/ReadUnsignedByte.java    |   79 +
 .../RiffReaderWriter/ReadUnsignedInt.java     |   79 +
 .../RiffReaderWriter/ReadUnsignedShort.java   |   79 +
 .../midi/Gervill/RiffReaderWriter/Skip.java   |   78 +
 .../RiffReaderWriter/WriteOutputStream.java   |   81 +
 .../TestGetSoundbankFile.java                 |   52 +
 .../TestGetSoundbankInputStream.java          |   63 +
 .../TestGetSoundbankInputStream2.java         |  119 +
 .../TestGetSoundbankUrl.java                  |   54 +
 .../midi/Gervill/SF2SoundbankReader/ding.sf2  |  Bin 0 -> 72618 bytes
 .../SimpleInstrument/AddModelInstrument.java  |   86 +
 .../AddModelInstrumentIntInt.java             |   91 +
 .../AddModelInstrumentIntIntIntInt.java       |   97 +
 .../AddModelInstrumentIntIntIntIntInt.java    |   97 +
 .../SimpleInstrument/AddModelPerformer.java   |   83 +
 .../AddModelPerformerArray.java               |   83 +
 .../AddModelPerformerArrayIntInt.java         |   89 +
 .../AddModelPerformerArrayIntIntIntInt.java   |   95 +
 ...AddModelPerformerArrayIntIntIntIntInt.java |   95 +
 .../AddModelPerformerIntInt.java              |   89 +
 .../AddModelPerformerIntIntIntInt.java        |   95 +
 .../AddModelPerformerIntIntIntIntInt.java     |   95 +
 .../midi/Gervill/SimpleInstrument/Clear.java  |   73 +
 .../Gervill/SimpleInstrument/SetName.java     |   72 +
 .../Gervill/SimpleInstrument/SetPatch.java    |   75 +
 .../SimpleSoundbank/AddInstrument.java        |   51 +
 .../Gervill/SimpleSoundbank/AddResource.java  |   52 +
 .../SimpleSoundbank/GetInstrument.java        |   50 +
 .../SimpleSoundbank/RemoveInstrument.java     |   58 +
 .../SimpleSoundbank/SetDescription.java       |   47 +
 .../midi/Gervill/SimpleSoundbank/SetName.java |   47 +
 .../Gervill/SimpleSoundbank/SetVendor.java    |   47 +
 .../Gervill/SimpleSoundbank/SetVersion.java   |   47 +
 .../midi/Gervill/SoftAudioBuffer/Array.java   |   54 +
 .../midi/Gervill/SoftAudioBuffer/Clear.java   |   56 +
 .../midi/Gervill/SoftAudioBuffer/Get.java     |   68 +
 .../SoftAudioBuffer/NewSoftAudioBuffer.java   |   55 +
 .../DummySourceDataLine.java                  |  232 ++
 .../SoftAudioSynthesizer/GetFormat.java       |   61 +
 .../SoftAudioSynthesizer/GetPropertyInfo.java |   53 +
 .../Gervill/SoftAudioSynthesizer/Open.java    |   54 +
 .../SoftAudioSynthesizer/OpenStream.java      |   54 +
 .../midi/Gervill/SoftChannel/AllNotesOff.java |   64 +
 .../midi/Gervill/SoftChannel/AllSoundOff.java |   64 +
 .../Gervill/SoftChannel/ChannelPressure.java  |   59 +
 .../midi/Gervill/SoftChannel/Controller.java  |   62 +
 .../Gervill/SoftChannel/LocalControl.java     |   60 +
 .../sound/midi/Gervill/SoftChannel/Mono.java  |   59 +
 .../sound/midi/Gervill/SoftChannel/Mute.java  |   59 +
 .../midi/Gervill/SoftChannel/NoteOff.java     |   64 +
 .../midi/Gervill/SoftChannel/NoteOff2.java    |   64 +
 .../midi/Gervill/SoftChannel/NoteOn.java      |   64 +
 .../sound/midi/Gervill/SoftChannel/Omni.java  |   61 +
 .../midi/Gervill/SoftChannel/PitchBend.java   |   59 +
 .../Gervill/SoftChannel/PolyPressure.java     |   61 +
 .../Gervill/SoftChannel/ProgramChange.java    |   59 +
 .../SoftChannel/ResetAllControllers.java      |  132 +
 .../Gervill/SoftChannel/SoftTestUtils.java    |  111 +
 .../sound/midi/Gervill/SoftChannel/Solo.java  |   59 +
 .../SoftCubicResampler/Interpolate.java       |  113 +
 .../SoftLanczosResampler/Interpolate.java     |  113 +
 .../SoftLimiter/ProcessAudio_replace_mix.java |   96 +
 .../ProcessAudio_replace_mix_mono.java        |   83 +
 ...ocessAudio_replace_mix_mono_overdrive.java |   84 +
 .../ProcessAudio_replace_mix_overdrive.java   |   95 +
 .../ProcessAudio_replace_normal.java          |   95 +
 .../ProcessAudio_replace_normal_mono.java     |   83 +
 .../ProcessAudio_replace_overdrive.java       |   95 +
 .../ProcessAudio_replace_overdrive_mono.java  |   83 +
 .../SoftLinearResampler/Interpolate.java      |  113 +
 .../SoftLinearResampler2/Interpolate.java     |  113 +
 .../SoftPointResampler/Interpolate.java       |  113 +
 .../midi/Gervill/SoftProvider/GetDevice.java  |   70 +
 .../midi/Gervill/SoftReceiver/Close.java      |   59 +
 .../SoftReceiver/Send_ActiveSense.java        |   82 +
 .../SoftReceiver/Send_AllNotesOff.java        |   64 +
 .../SoftReceiver/Send_AllSoundOff.java        |   64 +
 .../SoftReceiver/Send_ChannelPressure.java    |   63 +
 .../Gervill/SoftReceiver/Send_Controller.java |   66 +
 .../midi/Gervill/SoftReceiver/Send_Mono.java  |   75 +
 .../Gervill/SoftReceiver/Send_NoteOff.java    |   65 +
 .../Gervill/SoftReceiver/Send_NoteOn.java     |   65 +
 .../SoftReceiver/Send_NoteOn_AllChannels.java |   71 +
 .../SoftReceiver/Send_NoteOn_Delayed.java     |   67 +
 .../SoftReceiver/Send_NoteOn_Multiple.java    |   76 +
 .../midi/Gervill/SoftReceiver/Send_Omni.java  |   74 +
 .../Gervill/SoftReceiver/Send_PitchBend.java  |   63 +
 .../SoftReceiver/Send_PolyPressure.java       |   65 +
 .../SoftReceiver/Send_ProgramChange.java      |   63 +
 .../Send_ResetAllControllers.java             |  136 +
 .../Gervill/SoftReceiver/SoftTestUtils.java   |  111 +
 .../SoftSincResampler/Interpolate.java        |  113 +
 .../midi/Gervill/SoftSynthesizer/Close.java   |   58 +
 .../SoftSynthesizer/DummySourceDataLine.java  |  232 ++
 .../GetAvailableInstruments.java              |   63 +
 .../Gervill/SoftSynthesizer/GetChannels.java  |   64 +
 .../SoftSynthesizer/GetDefaultSoundbank.java  |   58 +
 .../SoftSynthesizer/GetDeviceInfo.java        |   56 +
 .../Gervill/SoftSynthesizer/GetLatency.java   |   58 +
 .../SoftSynthesizer/GetLoadedInstruments.java |   65 +
 .../SoftSynthesizer/GetMaxPolyphony.java      |   58 +
 .../SoftSynthesizer/GetMaxReceivers.java      |   56 +
 .../SoftSynthesizer/GetMaxTransmitters.java   |   56 +
 .../GetMicrosecondPosition.java               |   64 +
 .../Gervill/SoftSynthesizer/GetReceiver.java  |   63 +
 .../Gervill/SoftSynthesizer/GetReceiver2.java |   62 +
 .../Gervill/SoftSynthesizer/GetReceivers.java |   63 +
 .../SoftSynthesizer/GetTransmitter.java       |   63 +
 .../SoftSynthesizer/GetTransmitters.java      |   58 +
 .../SoftSynthesizer/GetVoiceStatus.java       |   61 +
 .../SoftSynthesizer/ImplicitOpenClose.java    |  105 +
 .../midi/Gervill/SoftSynthesizer/IsOpen.java  |   59 +
 .../SoftSynthesizer/IsSoundbankSupported.java |   95 +
 .../SoftSynthesizer/LoadAllInstruments.java   |   73 +
 .../SoftSynthesizer/LoadInstrument.java       |   73 +
 .../SoftSynthesizer/LoadInstruments.java      |   73 +
 .../midi/Gervill/SoftSynthesizer/Open.java    |   64 +
 .../Gervill/SoftSynthesizer/OpenStream.java   |   58 +
 .../SoftSynthesizer/RemapInstrument.java      |   76 +
 .../Gervill/SoftSynthesizer/TestRender1.java  |  214 ++
 .../SoftSynthesizer/UnloadAllInstruments.java |   69 +
 .../SoftSynthesizer/UnloadInstrument.java     |   75 +
 .../SoftSynthesizer/UnloadInstruments.java    |   75 +
 .../midi/Gervill/SoftSynthesizer/ding.sf2     |  Bin 0 -> 72618 bytes
 .../midi/Gervill/SoftSynthesizer/expresso.mid |  Bin 0 -> 17449 bytes
 .../midi/Gervill/SoftTuning/GetName.java      |   54 +
 .../midi/Gervill/SoftTuning/GetTuning.java    |   56 +
 .../midi/Gervill/SoftTuning/GetTuningInt.java |   53 +
 .../sound/midi/Gervill/SoftTuning/Load1.java  |  101 +
 .../sound/midi/Gervill/SoftTuning/Load2.java  |   71 +
 .../sound/midi/Gervill/SoftTuning/Load4.java  |  104 +
 .../sound/midi/Gervill/SoftTuning/Load5.java  |   87 +
 .../sound/midi/Gervill/SoftTuning/Load6.java  |   91 +
 .../sound/midi/Gervill/SoftTuning/Load7.java  |   72 +
 .../sound/midi/Gervill/SoftTuning/Load8.java  |   65 +
 .../sound/midi/Gervill/SoftTuning/Load9.java  |   69 +
 .../Gervill/SoftTuning/NewSoftTuning.java     |   56 +
 .../SoftTuning/NewSoftTuningByteArray.java    |   63 +
 .../SoftTuning/NewSoftTuningPatch.java        |   54 +
 .../NewSoftTuningPatchByteArray.java          |   65 +
 362 files changed, 46203 insertions(+), 865 deletions(-)
 delete mode 100644 jdk/make/javax/sound/jsoundhs/FILES.gmk
 delete mode 100644 jdk/make/javax/sound/jsoundhs/Makefile
 delete mode 100644 jdk/make/javax/sound/jsoundhs/mapfile-vers
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/AudioFileSoundbankReader.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/AudioFloatConverter.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/AudioFloatFormatConverter.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/AudioFloatInputStream.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/AudioSynthesizer.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/AudioSynthesizerPropertyInfo.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/DLSInfo.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/DLSInstrument.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/DLSModulator.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/DLSRegion.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/DLSSample.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/DLSSampleLoop.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/DLSSampleOptions.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/DLSSoundbank.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/DLSSoundbankReader.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/EmergencySoundbank.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/FFT.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/InvalidDataException.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/InvalidFormatException.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/JARSoundbankReader.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/ModelAbstractChannelMixer.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/ModelAbstractOscillator.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/ModelByteBuffer.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/ModelByteBufferWavetable.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/ModelChannelMixer.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/ModelConnectionBlock.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/ModelDestination.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/ModelDirectedPlayer.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/ModelDirector.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/ModelIdentifier.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/ModelInstrument.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/ModelInstrumentComparator.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/ModelMappedInstrument.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/ModelOscillator.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/ModelOscillatorStream.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/ModelPatch.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/ModelPerformer.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/ModelSource.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/ModelStandardDirector.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/ModelStandardTransform.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/ModelTransform.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/ModelWavetable.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/RIFFInvalidDataException.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/RIFFInvalidFormatException.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/RIFFReader.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/RIFFWriter.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SF2GlobalRegion.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SF2Instrument.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SF2InstrumentRegion.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SF2Layer.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SF2LayerRegion.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SF2Modulator.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SF2Region.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SF2Sample.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SF2Soundbank.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SF2SoundbankReader.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SimpleInstrument.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SimpleSoundbank.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SoftAbstractResampler.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SoftAudioBuffer.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SoftAudioProcessor.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SoftAudioPusher.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SoftChannel.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SoftChannelProxy.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SoftChorus.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SoftControl.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SoftCubicResampler.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SoftEnvelopeGenerator.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SoftFilter.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SoftInstrument.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SoftJitterCorrector.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SoftLanczosResampler.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SoftLimiter.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SoftLinearResampler.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SoftLinearResampler2.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SoftLowFrequencyOscillator.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SoftMainMixer.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SoftMidiAudioFileReader.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SoftMixingClip.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SoftMixingDataLine.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SoftMixingMainMixer.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SoftMixingMixer.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SoftMixingMixerProvider.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SoftMixingSourceDataLine.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SoftPerformer.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SoftPointResampler.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SoftProcess.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SoftProvider.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SoftReceiver.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SoftResampler.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SoftResamplerStreamer.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SoftReverb.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SoftShortMessage.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SoftSincResampler.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SoftSynthesizer.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SoftTuning.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/SoftVoice.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/WaveExtensibleFileReader.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/WaveFloatFileReader.java
 create mode 100644 jdk/src/share/classes/com/sun/media/sound/WaveFloatFileWriter.java
 delete mode 100644 jdk/src/share/lib/audio/soundbank.gm
 create mode 100644 jdk/test/javax/sound/midi/Gervill/AudioFloatConverter/GetFormat.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/AudioFloatConverter/ToFloatArray.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/AudioFloatInputStream/Available.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/AudioFloatInputStream/Close.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/AudioFloatInputStream/GetFormat.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/AudioFloatInputStream/GetFrameLength.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/AudioFloatInputStream/MarkSupported.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/AudioFloatInputStream/Read.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/AudioFloatInputStream/ReadFloatArray.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/AudioFloatInputStream/ReadFloatArrayIntInt.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/AudioFloatInputStream/Reset.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/AudioFloatInputStream/Skip.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/DLSSoundbankReader/TestGetSoundbankFile.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/DLSSoundbankReader/TestGetSoundbankInputStream.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/DLSSoundbankReader/TestGetSoundbankInputStream2.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/DLSSoundbankReader/TestGetSoundbankUrl.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/DLSSoundbankReader/ding.dls
 create mode 100644 jdk/test/javax/sound/midi/Gervill/EmergencySoundbank/TestCreateSoundbank.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelByteBuffer/GetInputStream.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelByteBuffer/GetRoot.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelByteBuffer/Load.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelByteBuffer/LoadAll.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelByteBuffer/NewModelByteBufferByteArray.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelByteBuffer/NewModelByteBufferByteArrayIntInt.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelByteBuffer/NewModelByteBufferFile.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelByteBuffer/NewModelByteBufferFileLongLong.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelByteBuffer/RandomFileInputStream/Available.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelByteBuffer/RandomFileInputStream/Close.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelByteBuffer/RandomFileInputStream/MarkReset.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelByteBuffer/RandomFileInputStream/MarkSupported.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelByteBuffer/RandomFileInputStream/Read.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelByteBuffer/RandomFileInputStream/ReadByte.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelByteBuffer/RandomFileInputStream/ReadByteIntInt.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelByteBuffer/RandomFileInputStream/Skip.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelByteBuffer/SubbufferLong.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelByteBuffer/SubbufferLongLong.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelByteBuffer/SubbufferLongLongBoolean.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelByteBuffer/Unload.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelByteBuffer/WriteTo.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelByteBufferWavetable/GetAttenuation.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelByteBufferWavetable/GetChannels.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelByteBufferWavetable/GetLoopLength.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelByteBufferWavetable/GetLoopStart.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelByteBufferWavetable/GetPitchCorrection.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelByteBufferWavetable/NewModelByteBufferWavetableModelByteBuffer.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelByteBufferWavetable/NewModelByteBufferWavetableModelByteBufferAudioFormat.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelByteBufferWavetable/NewModelByteBufferWavetableModelByteBufferAudioFormatFloat.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelByteBufferWavetable/NewModelByteBufferWavetableModelByteBufferFloat.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelByteBufferWavetable/Open.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelByteBufferWavetable/Set8BitExtensionBuffer.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelByteBufferWavetable/SetLoopType.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelDestination/NewModelDestination.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelDestination/NewModelDestinationModelIdentifier.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelDestination/SetIdentifier.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelDestination/SetTransform.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelIdentifier/EqualsObject.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelIdentifier/NewModelIdentifierString.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelIdentifier/NewModelIdentifierStringInt.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelIdentifier/NewModelIdentifierStringString.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelIdentifier/NewModelIdentifierStringStringInt.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelIdentifier/SetInstance.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelIdentifier/SetObject.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelIdentifier/SetVariable.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelPerformer/GetOscillators.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelPerformer/SetConnectionBlocks.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelPerformer/SetDefaultConnectionsEnabled.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelPerformer/SetExclusiveClass.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelPerformer/SetKeyFrom.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelPerformer/SetKeyTo.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelPerformer/SetName.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelPerformer/SetSelfNonExclusive.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelPerformer/SetVelFrom.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelPerformer/SetVelTo.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelSource/NewModelSource.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelSource/NewModelSourceModelIdentifier.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelSource/NewModelSourceModelIdentifierBoolean.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelSource/NewModelSourceModelIdentifierBooleanBoolean.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelSource/NewModelSourceModelIdentifierBooleanBooleanInt.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelSource/NewModelSourceModelIdentifierModelTransform.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelSource/SetIdentifier.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelSource/SetTransform.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelStandardTransform/NewModelStandardTransform.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelStandardTransform/NewModelStandardTransformBoolean.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelStandardTransform/NewModelStandardTransformBooleanBoolean.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelStandardTransform/NewModelStandardTransformBooleanBooleanInt.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelStandardTransform/SetDirection.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelStandardTransform/SetPolarity.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelStandardTransform/SetTransform.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelStandardTransform/TransformAbsolute.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelStandardTransform/TransformConcave.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelStandardTransform/TransformConvex.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelStandardTransform/TransformLinear.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/ModelStandardTransform/TransformSwitch.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/RiffReaderWriter/Available.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/RiffReaderWriter/Close.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/RiffReaderWriter/GetFilePointer.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/RiffReaderWriter/GetSize.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/RiffReaderWriter/HasNextChunk.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/RiffReaderWriter/Read.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/RiffReaderWriter/ReadByte.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/RiffReaderWriter/ReadByteArrayIntInt.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/RiffReaderWriter/ReadInt.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/RiffReaderWriter/ReadLong.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/RiffReaderWriter/ReadShort.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/RiffReaderWriter/ReadString.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/RiffReaderWriter/ReadUnsignedByte.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/RiffReaderWriter/ReadUnsignedInt.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/RiffReaderWriter/ReadUnsignedShort.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/RiffReaderWriter/Skip.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/RiffReaderWriter/WriteOutputStream.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SF2SoundbankReader/TestGetSoundbankFile.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SF2SoundbankReader/TestGetSoundbankInputStream.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SF2SoundbankReader/TestGetSoundbankInputStream2.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SF2SoundbankReader/TestGetSoundbankUrl.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SF2SoundbankReader/ding.sf2
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SimpleInstrument/AddModelInstrument.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SimpleInstrument/AddModelInstrumentIntInt.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SimpleInstrument/AddModelInstrumentIntIntIntInt.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SimpleInstrument/AddModelInstrumentIntIntIntIntInt.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SimpleInstrument/AddModelPerformer.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SimpleInstrument/AddModelPerformerArray.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SimpleInstrument/AddModelPerformerArrayIntInt.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SimpleInstrument/AddModelPerformerArrayIntIntIntInt.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SimpleInstrument/AddModelPerformerArrayIntIntIntIntInt.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SimpleInstrument/AddModelPerformerIntInt.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SimpleInstrument/AddModelPerformerIntIntIntInt.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SimpleInstrument/AddModelPerformerIntIntIntIntInt.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SimpleInstrument/Clear.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SimpleInstrument/SetName.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SimpleInstrument/SetPatch.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SimpleSoundbank/AddInstrument.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SimpleSoundbank/AddResource.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SimpleSoundbank/GetInstrument.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SimpleSoundbank/RemoveInstrument.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SimpleSoundbank/SetDescription.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SimpleSoundbank/SetName.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SimpleSoundbank/SetVendor.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SimpleSoundbank/SetVersion.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftAudioBuffer/Array.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftAudioBuffer/Clear.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftAudioBuffer/Get.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftAudioBuffer/NewSoftAudioBuffer.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftAudioSynthesizer/DummySourceDataLine.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftAudioSynthesizer/GetFormat.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftAudioSynthesizer/GetPropertyInfo.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftAudioSynthesizer/Open.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftAudioSynthesizer/OpenStream.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftChannel/AllNotesOff.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftChannel/AllSoundOff.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftChannel/ChannelPressure.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftChannel/Controller.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftChannel/LocalControl.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftChannel/Mono.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftChannel/Mute.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftChannel/NoteOff.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftChannel/NoteOff2.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftChannel/NoteOn.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftChannel/Omni.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftChannel/PitchBend.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftChannel/PolyPressure.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftChannel/ProgramChange.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftChannel/ResetAllControllers.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftChannel/SoftTestUtils.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftChannel/Solo.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftCubicResampler/Interpolate.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftLanczosResampler/Interpolate.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftLimiter/ProcessAudio_replace_mix.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftLimiter/ProcessAudio_replace_mix_mono.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftLimiter/ProcessAudio_replace_mix_mono_overdrive.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftLimiter/ProcessAudio_replace_mix_overdrive.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftLimiter/ProcessAudio_replace_normal.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftLimiter/ProcessAudio_replace_normal_mono.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftLimiter/ProcessAudio_replace_overdrive.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftLimiter/ProcessAudio_replace_overdrive_mono.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftLinearResampler/Interpolate.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftLinearResampler2/Interpolate.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftPointResampler/Interpolate.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftProvider/GetDevice.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftReceiver/Close.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftReceiver/Send_ActiveSense.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftReceiver/Send_AllNotesOff.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftReceiver/Send_AllSoundOff.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftReceiver/Send_ChannelPressure.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftReceiver/Send_Controller.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftReceiver/Send_Mono.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftReceiver/Send_NoteOff.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftReceiver/Send_NoteOn.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftReceiver/Send_NoteOn_AllChannels.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftReceiver/Send_NoteOn_Delayed.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftReceiver/Send_NoteOn_Multiple.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftReceiver/Send_Omni.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftReceiver/Send_PitchBend.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftReceiver/Send_PolyPressure.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftReceiver/Send_ProgramChange.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftReceiver/Send_ResetAllControllers.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftReceiver/SoftTestUtils.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftSincResampler/Interpolate.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/Close.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/DummySourceDataLine.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/GetAvailableInstruments.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/GetChannels.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/GetDefaultSoundbank.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/GetDeviceInfo.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/GetLatency.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/GetLoadedInstruments.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/GetMaxPolyphony.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/GetMaxReceivers.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/GetMaxTransmitters.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/GetMicrosecondPosition.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/GetReceiver.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/GetReceiver2.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/GetReceivers.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/GetTransmitter.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/GetTransmitters.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/GetVoiceStatus.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/ImplicitOpenClose.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/IsOpen.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/IsSoundbankSupported.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/LoadAllInstruments.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/LoadInstrument.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/LoadInstruments.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/Open.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/OpenStream.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/RemapInstrument.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/TestRender1.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/UnloadAllInstruments.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/UnloadInstrument.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/UnloadInstruments.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/ding.sf2
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/expresso.mid
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftTuning/GetName.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftTuning/GetTuning.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftTuning/GetTuningInt.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftTuning/Load1.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftTuning/Load2.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftTuning/Load4.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftTuning/Load5.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftTuning/Load6.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftTuning/Load7.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftTuning/Load8.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftTuning/Load9.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftTuning/NewSoftTuning.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftTuning/NewSoftTuningByteArray.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftTuning/NewSoftTuningPatch.java
 create mode 100644 jdk/test/javax/sound/midi/Gervill/SoftTuning/NewSoftTuningPatchByteArray.java

diff --git a/jdk/make/common/Release.gmk b/jdk/make/common/Release.gmk
index 76a1bc466f2..4bee467967d 100644
--- a/jdk/make/common/Release.gmk
+++ b/jdk/make/common/Release.gmk
@@ -911,14 +911,6 @@ initial-image-jdk:: initial-image-jdk-setup \
 	    fi; \
 	done
   ifeq ($(PLATFORM), windows)
-	@#
-	@# Audio soundbank - Bug# 4236400
-	@# Windows only: adding audio files to JDK's jre/lib directory.
-	@#
-	($(CD) $(LIBDIR) && $(TAR) cf - \
-	    `$(FIND) audio -depth -print`) | \
-	    ($(CD) $(JDK_IMAGE_DIR)/jre/lib && $(TAR) xf -)
-	@#
 	@#
 	@# lib/
 	@#
diff --git a/jdk/make/common/internal/BinaryPlugs.gmk b/jdk/make/common/internal/BinaryPlugs.gmk
index bb2d64262ed..a77044af43c 100644
--- a/jdk/make/common/internal/BinaryPlugs.gmk
+++ b/jdk/make/common/internal/BinaryPlugs.gmk
@@ -29,9 +29,7 @@
 
 # Names of native shared libraries
 
-PLUG_JSOUND_LIBRARY=$(LIB_PREFIX)jsoundhs.$(LIBRARY_SUFFIX)
-PLUG_LIBRARY_NAMES = \
-    $(PLUG_JSOUND_LIBRARY)
+PLUG_LIBRARY_NAMES=
 
 # Sub-directory where native shared libraries are located (e.g. jre/bin or...)
 
@@ -74,62 +72,10 @@ com/sun/jmx/snmp/daemon/SnmpSocket.class \
 com/sun/jmx/snmp/daemon/SnmpTimerServer.class \
 com/sun/jmx/snmp/daemon/WaitQ.class
 
-PLUG_SOUND_CLASS_NAMES = \
-com/sun/media/sound/AbstractPlayer.class \
-com/sun/media/sound/CircularBuffer.class \
-com/sun/media/sound/HeadspaceInstrument.class \
-com/sun/media/sound/HeadspaceMixer\$$1.class \
-com/sun/media/sound/HeadspaceMixer\$$MidiLine.class \
-com/sun/media/sound/HeadspaceMixer\$$MidiLineInfo.class \
-com/sun/media/sound/HeadspaceMixer\$$MixerInfo.class \
-com/sun/media/sound/HeadspaceMixer\$$MixerReverbControl\$$MixerReverbType.class \
-com/sun/media/sound/HeadspaceMixer\$$MixerReverbControl.class \
-com/sun/media/sound/HeadspaceMixer.class \
-com/sun/media/sound/HeadspaceMixerProvider.class \
-com/sun/media/sound/HeadspaceSample.class \
-com/sun/media/sound/HeadspaceSoundbank.class \
-com/sun/media/sound/HsbParser.class \
-com/sun/media/sound/MixerClip\$$1.class \
-com/sun/media/sound/MixerClip\$$MixerClipApplyReverbControl.class \
-com/sun/media/sound/MixerClip\$$MixerClipGainControl.class \
-com/sun/media/sound/MixerClip\$$MixerClipMuteControl.class \
-com/sun/media/sound/MixerClip\$$MixerClipPanControl.class \
-com/sun/media/sound/MixerClip\$$MixerClipSampleRateControl.class \
-com/sun/media/sound/MixerClip.class \
-com/sun/media/sound/MixerMidiChannel.class \
-com/sun/media/sound/MixerSequencer\$$1.class \
-com/sun/media/sound/MixerSequencer\$$ControllerVectorElement.class \
-com/sun/media/sound/MixerSequencer\$$MixerSequencerInfo.class \
-com/sun/media/sound/MixerSequencer\$$RecordingTrack.class \
-com/sun/media/sound/MixerSequencer.class \
-com/sun/media/sound/MixerSequencerProvider.class \
-com/sun/media/sound/MixerSourceLine\$$1.class \
-com/sun/media/sound/MixerSourceLine\$$MixerSourceLineApplyReverbControl.class \
-com/sun/media/sound/MixerSourceLine\$$MixerSourceLineGainControl.class \
-com/sun/media/sound/MixerSourceLine\$$MixerSourceLineMuteControl.class \
-com/sun/media/sound/MixerSourceLine\$$MixerSourceLinePanControl.class \
-com/sun/media/sound/MixerSourceLine\$$MixerSourceLineSampleRateControl.class \
-com/sun/media/sound/MixerSourceLine.class \
-com/sun/media/sound/MixerSynth\$$1.class \
-com/sun/media/sound/MixerSynth\$$MixerSynthInfo.class \
-com/sun/media/sound/MixerSynth\$$SynthReceiver.class \
-com/sun/media/sound/MixerSynth.class \
-com/sun/media/sound/MixerSynthProvider.class \
-com/sun/media/sound/MixerThread.class \
-com/sun/media/sound/RmfFileReader.class \
-com/sun/media/sound/SimpleInputDevice\$$1.class \
-com/sun/media/sound/SimpleInputDevice\$$InputDeviceDataLine.class \
-com/sun/media/sound/SimpleInputDevice\$$InputDevicePort.class \
-com/sun/media/sound/SimpleInputDevice\$$InputDevicePortInfo.class \
-com/sun/media/sound/SimpleInputDevice.class \
-com/sun/media/sound/SimpleInputDeviceProvider\$$1.class \
-com/sun/media/sound/SimpleInputDeviceProvider\$$InputDeviceInfo.class \
-com/sun/media/sound/SimpleInputDeviceProvider.class
-
 # Class list temp files (used by both import and export of plugs)
 
 PLUG_TEMPDIR=$(ABS_TEMPDIR)/plugs
-PLUG_CLASS_AREAS = jmf sound
+PLUG_CLASS_AREAS = jmf
 PLUG_CLISTS = $(PLUG_CLASS_AREAS:%=$(PLUG_TEMPDIR)/%.clist)
 
 # Create jargs file command
@@ -147,18 +93,11 @@ $(PLUG_TEMPDIR)/jmf.clist:
 	@for i in $(PLUG_JMF_CLASS_NAMES) ; do \
 	  $(ECHO) "$$i" >> $@; \
 	done
-$(PLUG_TEMPDIR)/sound.clist:
-	@$(prep-target)
-	@for i in $(PLUG_SOUND_CLASS_NAMES) ; do \
-	  $(ECHO) "$$i" >> $@ ; \
-	done
 $(PLUG_TEMPDIR)/all.clist: $(PLUG_CLISTS)
 	@$(prep-target)
 	$(CAT) $(PLUG_CLISTS) > $@
 $(PLUG_TEMPDIR)/jmf.jargs: $(PLUG_TEMPDIR)/jmf.clist
 	$(plug-create-jargs)
-$(PLUG_TEMPDIR)/sound.jargs: $(PLUG_TEMPDIR)/sound.clist
-	$(plug-create-jargs)
 $(PLUG_TEMPDIR)/all.jargs: $(PLUG_TEMPDIR)/all.clist
 	$(plug-create-jargs)
 
@@ -193,25 +132,11 @@ endef # import-binary-plug-classes
 
 import-binary-plug-jmf-classes: $(PLUG_IMPORT_JARFILE) $(PLUG_TEMPDIR)/jmf.clist
 	$(call import-binary-plug-classes,$(PLUG_TEMPDIR)/jmf.clist)
-import-binary-plug-sound-classes: $(PLUG_IMPORT_JARFILE) $(PLUG_TEMPDIR)/sound.clist
-	$(call import-binary-plug-classes,$(PLUG_TEMPDIR)/sound.clist)
 
 # Import all classes from the jar file
 
 import-binary-plug-jar: \
-	     import-binary-plug-jmf-classes \
-	     import-binary-plug-sound-classes
-
-# Import native libraries
-
-$(LIB_LOCATION)/$(PLUG_JSOUND_LIBRARY): \
-    $(PLUG_IMPORT_DIR)/$(PLUG_LOCATION_SUBDIR)/$(PLUG_JSOUND_LIBRARY)
-	$(import-binary-plug-file)
-
-# Rules only used by lower level makefiles
-
-import-binary-plug-jsound-library: \
-    $(LIB_LOCATION)/$(PLUG_JSOUND_LIBRARY)
+	     import-binary-plug-jmf-classes
 
 # Binary plug start/complete messages
 
@@ -241,9 +166,7 @@ import-binary-plugs: \
 	import-binary-plugs-libs \
 	import-binary-plugs \
 	import-binary-plug-jar \
-        import-binary-plug-jmf-classes \
-        import-binary-plug-sound-classes \
-        import-binary-plug-jsound-library
+	import-binary-plug-jmf-classes
 
 else # !OPENJDK
 
@@ -280,12 +203,6 @@ $(PLUG_EXPORT_JARFILE): $(PLUG_TEMPDIR)/all.clist $(PLUG_TEMPDIR)/all.jargs
 	@$(java-vm-cleanup)
 export-binary-plugs-jar: $(PLUG_EXPORT_JARFILE)
 
-# Export native libraries
-
-$(PLUG_EXPORT_DIR)/$(PLUG_LOCATION_SUBDIR)/$(PLUG_JSOUND_LIBRARY): \
-    $(LIB_LOCATION)/$(PLUG_JSOUND_LIBRARY)
-	$(export-binary-plug-file)
-
 # Export binary plug start/complete messages
 
 export-binary-plugs-started:
diff --git a/jdk/make/javax/sound/Makefile b/jdk/make/javax/sound/Makefile
index 9b5346003d1..c3e0524fd46 100644
--- a/jdk/make/javax/sound/Makefile
+++ b/jdk/make/javax/sound/Makefile
@@ -53,18 +53,6 @@ include FILES_c.gmk
 # add java files
 AUTO_FILES_JAVA_DIRS = javax/sound com/sun/media/sound
 
-#
-# Specific to OpenJDK building
-#
-ifdef OPENJDK
-
-# copy closed .class files
-build: import-binary-plug-sound-classes 
-
-include $(BUILDDIR)/common/internal/BinaryPlugs.gmk
-
-endif # OPENJDK
-
 #
 # Files that just need cp.
 #
@@ -79,13 +67,11 @@ FILES_copy = \
 	$(SERVICEDIR)/javax.sound.sampled.spi.AudioFileReader \
 	$(SERVICEDIR)/javax.sound.sampled.spi.FormatConversionProvider \
 	$(SERVICEDIR)/javax.sound.sampled.spi.MixerProvider \
-	$(LIBDIR)/audio/soundbank.gm \
 	$(LIBDIR)/sound.properties
 
 FILES_mkdirs = \
 	$(CLASSBINDIR)/META-INF \
-	$(CLASSBINDIR)/META-INF/services \
-	$(LIBDIR)/audio
+	$(CLASSBINDIR)/META-INF/services
 
 FILES_copydirs = \
 	$(CLASSBINDIR) \
@@ -95,11 +81,6 @@ FILES_copydirs = \
 FILES_c += $(FILES_$(PLATFORM))
 
 
-#
-# add "closed" library
-#
-SUBDIRS += jsoundhs
-
 #
 # system dependent flags
 #
diff --git a/jdk/make/javax/sound/jsoundhs/FILES.gmk b/jdk/make/javax/sound/jsoundhs/FILES.gmk
deleted file mode 100644
index 6bc7a57da83..00000000000
--- a/jdk/make/javax/sound/jsoundhs/FILES.gmk
+++ /dev/null
@@ -1,91 +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.  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
-# 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.
-#
-
-FILES_c = \
-	Utilities.c \
-	MixerThread.c \
-	HeadspaceMixer.c \
-	MixerClip.c \
-	MixerSourceLine.c \
-	SimpleInputDevice.c \
-	SimpleInputDeviceProvider.c \
-	HeadspaceSoundbank.c \
-	MixerMidiChannel.c \
-	AbstractPlayer.c \
-	MixerSequencer.c \
-	MixerSynth.c
-
-FILES_engine = \
-	DriverTools.c \
-	GenAudioCaptureStreams.c \
-	GenAudioStreams.c \
-	GenOutput.c \
-	GenPatch.c \
-	GenReverb.c \
-	GenSample.c \
-	GenSeq.c \
-	GenSetup.c \
-	GenSong.c \
-	GenSynth.c \
-	GenSynthFilters.c \
-	GenSynthInterp2.c \
-	GenSynthResample.c \
-	NewNewLZSS.c \
-	SampleTools.c \
-	SMOD_Volume_Scaler.c \
-	X_API.c \
-	X_Decompress.c \
-	X_IMA.c \
-	GenFiltersReverb.c \
-	GenInterp2Reverb.c \
-	GenSoundFiles.c \
-	SincResample.c
-
-FILES_solaris = \
-	HAE_API_SolarisOS.c \
-	HAE_API_SolarisOS_Capture.c
-
-FILES_linux = \
-	HAE_API_LinuxOS.c \
-	HAE_API_LinuxOS_Capture.c
-
-FILES_windows = \
-	HAE_API_WinOS.c \
-	HAE_API_WinOS_Capture.c \
-	HAE_API_WinOS_Synth.c
-
-FILES_export = \
-	com/sun/media/sound/AbstractPlayer.java \
-	com/sun/media/sound/HeadspaceMixer.java \
-	com/sun/media/sound/HeadspaceSoundbank.java \
-	com/sun/media/sound/MixerClip.java \
-	com/sun/media/sound/MixerMidiChannel.java \
-	com/sun/media/sound/MixerSequencer.java \
-	com/sun/media/sound/MixerSourceLine.java \
-	com/sun/media/sound/MixerSynth.java \
-	com/sun/media/sound/MixerThread.java \
-	com/sun/media/sound/SimpleInputDevice.java \
-	com/sun/media/sound/SimpleInputDeviceProvider.java
-
diff --git a/jdk/make/javax/sound/jsoundhs/Makefile b/jdk/make/javax/sound/jsoundhs/Makefile
deleted file mode 100644
index 6a4952c6522..00000000000
--- a/jdk/make/javax/sound/jsoundhs/Makefile
+++ /dev/null
@@ -1,100 +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.  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
-# 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.
-#
-
-BUILDDIR = ../../..
-PACKAGE = javax.sound
-LIBRARY = jsoundhs
-PRODUCT = sun
-CPLUSPLUSLIBRARY = true
-include $(BUILDDIR)/common/Defs.gmk
-
-# this Makefile compiles "closed" JavaSound library
-
-ifdef OPENJDK
-
-# precompiled lib will be copied by the rules in Library.gmk instead of compiling.
-USE_BINARY_PLUG_LIBRARY=true
-
-build: import-binary-plug-jsound-library
-
-include $(BUILDDIR)/common/internal/BinaryPlugs.gmk
-
-else # OPENJDK
-
-# include defines for sound
-include ../SoundDefs.gmk
-
-#
-# Add use of mapfile
-#
-FILES_m = mapfile-vers
-include $(BUILDDIR)/common/Mapfile-vers.gmk
-
-#
-# Files
-#
-include FILES.gmk
-
-FILES_c += $(FILES_engine) $(FILES_$(PLATFORM))
-
-#
-# Extra cc/linker flags.
-#
-# flags needed for all platforms
-CPPFLAGS += \
-	-DJAVA_SOUND -DJAVA_THREAD \
-	-I$(CLOSED_SHARE_SRC)/native/com/sun/media/sound \
-	-I$(CLOSED_SHARE_SRC)/native/com/sun/media/sound/engine
-
-# system dependent flags
-ifeq ($(PLATFORM), windows)
-  CPPFLAGS += 	-DUSE_DIRECTSOUND=0 \
-		-DUSE_EXTERNAL_SYNTH=TRUE
-  LDLIBS += winmm.lib
-endif # PLATFORM windows
-
-ifeq ($(PLATFORM), linux)
-endif # PLATFORM linux
-
-ifeq ($(PLATFORM), solaris)
-endif # PLATFORM solaris
-
-
-#
-# Add to the ambient VPATH.
-#
-vpath %.c $(CLOSED_SHARE_SRC)/native/com/sun/media/sound
-vpath %.c $(CLOSED_SHARE_SRC)/native/com/sun/media/sound/engine
-vpath %.c $(CLOSED_PLATFORM_SRC)/native/com/sun/media/sound/engine
-
-
-endif # OPENJDK
-
-
-#
-# Include rules
-#
-include $(BUILDDIR)/common/Library.gmk
-
diff --git a/jdk/make/javax/sound/jsoundhs/mapfile-vers b/jdk/make/javax/sound/jsoundhs/mapfile-vers
deleted file mode 100644
index 7961825600c..00000000000
--- a/jdk/make/javax/sound/jsoundhs/mapfile-vers
+++ /dev/null
@@ -1,153 +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.  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
-# 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.
-#
-
-# Define library interface.
-
-SUNWprivate_1.1 {
-	global:
-            Java_com_sun_media_sound_AbstractPlayer_nAddReceiver;
-            Java_com_sun_media_sound_AbstractPlayer_nClose;
-            Java_com_sun_media_sound_AbstractPlayer_nLoadInstrument;
-            Java_com_sun_media_sound_AbstractPlayer_nRemapInstrument;
-            Java_com_sun_media_sound_AbstractPlayer_nRemoveReceiver;
-            Java_com_sun_media_sound_AbstractPlayer_nUnloadInstrument;
-            Java_com_sun_media_sound_HeadspaceMixer_nAllocateVoices;
-            Java_com_sun_media_sound_HeadspaceMixer_nCloseMixer;
-            Java_com_sun_media_sound_HeadspaceMixer_nCreateLinkedStreams;
-            Java_com_sun_media_sound_HeadspaceMixer_nDrain;
-            Java_com_sun_media_sound_HeadspaceMixer_nFlush;
-            Java_com_sun_media_sound_HeadspaceMixer_nGetCpuLoad;
-            Java_com_sun_media_sound_HeadspaceMixer_nGetDefaultBufferSize;
-            Java_com_sun_media_sound_HeadspaceMixer_nGetLevel;
-            Java_com_sun_media_sound_HeadspaceMixer_nGetPosition;
-            Java_com_sun_media_sound_HeadspaceMixer_nGetTotalVoices;
-            Java_com_sun_media_sound_HeadspaceMixer_nOpenMixer;
-            Java_com_sun_media_sound_HeadspaceMixer_nPause;
-            Java_com_sun_media_sound_HeadspaceMixer_nResume;
-            Java_com_sun_media_sound_HeadspaceMixer_nSetInterpolation;
-            Java_com_sun_media_sound_HeadspaceMixer_nSetMixerFormat;
-            Java_com_sun_media_sound_HeadspaceMixer_nSetMixLevel;
-            Java_com_sun_media_sound_HeadspaceMixer_nSetReverb;
-            Java_com_sun_media_sound_HeadspaceMixer_nStartLinkedStreams;
-            Java_com_sun_media_sound_HeadspaceMixer_nStopLinkedStreams;
-            Java_com_sun_media_sound_HeadspaceSoundbank_nCloseResource;
-            Java_com_sun_media_sound_HeadspaceSoundbank_nGetInstruments;
-            Java_com_sun_media_sound_HeadspaceSoundbank_nGetName;
-            Java_com_sun_media_sound_HeadspaceSoundbank_nGetSamples;
-            Java_com_sun_media_sound_HeadspaceSoundbank_nGetVersionMajor;
-            Java_com_sun_media_sound_HeadspaceSoundbank_nGetVersionMinor;
-            Java_com_sun_media_sound_HeadspaceSoundbank_nGetVersionSubMinor;
-            Java_com_sun_media_sound_HeadspaceSoundbank_nOpenResource;
-            Java_com_sun_media_sound_HeadspaceSoundbank_nOpenResourceFromByteArray;
-            Java_com_sun_media_sound_MixerClip_nClose;
-            Java_com_sun_media_sound_MixerClip_nDrain;
-            Java_com_sun_media_sound_MixerClip_nFlush;
-            Java_com_sun_media_sound_MixerClip_nGetPosition;
-            Java_com_sun_media_sound_MixerClip_nOpen;
-            Java_com_sun_media_sound_MixerClip_nSetLinearGain;
-            Java_com_sun_media_sound_MixerClip_nSetPan;
-            Java_com_sun_media_sound_MixerClip_nSetSampleRate;
-            Java_com_sun_media_sound_MixerClip_nSetup;
-            Java_com_sun_media_sound_MixerClip_nStart;
-            Java_com_sun_media_sound_MixerClip_nStop;
-            Java_com_sun_media_sound_MixerMidiChannel_nAllNotesOff;
-            Java_com_sun_media_sound_MixerMidiChannel_nControlChange;
-            Java_com_sun_media_sound_MixerMidiChannel_nGetController;
-            Java_com_sun_media_sound_MixerMidiChannel_nGetPitchBend;
-            Java_com_sun_media_sound_MixerMidiChannel_nGetSolo;
-            Java_com_sun_media_sound_MixerMidiChannel_nNoteOff;
-            Java_com_sun_media_sound_MixerMidiChannel_nNoteOn;
-            Java_com_sun_media_sound_MixerMidiChannel_nProgramChange__JIIIJ;
-            Java_com_sun_media_sound_MixerMidiChannel_nProgramChange__JIIJ;
-            Java_com_sun_media_sound_MixerMidiChannel_nResetAllControllers;
-            Java_com_sun_media_sound_MixerMidiChannel_nSetMute;
-            Java_com_sun_media_sound_MixerMidiChannel_nSetPitchBend;
-            Java_com_sun_media_sound_MixerMidiChannel_nSetSolo;
-            Java_com_sun_media_sound_MixerSequencer_nAddControllerEventCallback;
-            Java_com_sun_media_sound_MixerSequencer_nGetMasterTempo;
-            Java_com_sun_media_sound_MixerSequencer_nGetSequenceMicrosecondLength;
-            Java_com_sun_media_sound_MixerSequencer_nGetSequencerMicrosecondPosition;
-            Java_com_sun_media_sound_MixerSequencer_nGetSequencerTickPosition;
-            Java_com_sun_media_sound_MixerSequencer_nGetSequenceTickLength;
-            Java_com_sun_media_sound_MixerSequencer_nGetTempoInBPM;
-            Java_com_sun_media_sound_MixerSequencer_nGetTempoInMPQ;
-            Java_com_sun_media_sound_MixerSequencer_nGetTrackMute;
-            Java_com_sun_media_sound_MixerSequencer_nGetTrackSolo;
-            Java_com_sun_media_sound_MixerSequencer_nOpenMidiSequencer;
-            Java_com_sun_media_sound_MixerSequencer_nOpenRmfSequencer;
-            Java_com_sun_media_sound_MixerSequencer_nPauseSequencer;
-            Java_com_sun_media_sound_MixerSequencer_nResumeSequencer;
-            Java_com_sun_media_sound_MixerSequencer_nSetMasterTempo;
-            Java_com_sun_media_sound_MixerSequencer_nSetSequencerMicrosecondPosition;
-            Java_com_sun_media_sound_MixerSequencer_nSetSequencerTickPosition;
-            Java_com_sun_media_sound_MixerSequencer_nSetTempoInBPM;
-            Java_com_sun_media_sound_MixerSequencer_nSetTempoInMPQ;
-            Java_com_sun_media_sound_MixerSequencer_nSetTrackMute;
-            Java_com_sun_media_sound_MixerSequencer_nSetTrackSolo;
-            Java_com_sun_media_sound_MixerSequencer_nStartSequencer;
-            Java_com_sun_media_sound_MixerSourceLine_nClose;
-            Java_com_sun_media_sound_MixerSourceLine_nDrain;
-            Java_com_sun_media_sound_MixerSourceLine_nFlush;
-            Java_com_sun_media_sound_MixerSourceLine_nGetLevel;
-            Java_com_sun_media_sound_MixerSourceLine_nGetPosition;
-            Java_com_sun_media_sound_MixerSourceLine_nOpen;
-            Java_com_sun_media_sound_MixerSourceLine_nPause;
-            Java_com_sun_media_sound_MixerSourceLine_nResume;
-            Java_com_sun_media_sound_MixerSourceLine_nSetLinearGain;
-            Java_com_sun_media_sound_MixerSourceLine_nSetPan;
-            Java_com_sun_media_sound_MixerSourceLine_nSetSampleRate;
-            Java_com_sun_media_sound_MixerSourceLine_nStart;
-            Java_com_sun_media_sound_MixerSynth_nCreateSynthesizer;
-            Java_com_sun_media_sound_MixerSynth_nDestroySynthesizer;
-            Java_com_sun_media_sound_MixerSynth_nGetLatency;
-            Java_com_sun_media_sound_MixerSynth_nLoadInstrument;
-            Java_com_sun_media_sound_MixerSynth_nRemapInstrument;
-            Java_com_sun_media_sound_MixerSynth_nStartSynthesizer;
-            Java_com_sun_media_sound_MixerSynth_nUnloadInstrument;
-            Java_com_sun_media_sound_MixerThread_runNative;
-            Java_com_sun_media_sound_SimpleInputDevice_nClose;
-            Java_com_sun_media_sound_SimpleInputDevice_nDrain;
-            Java_com_sun_media_sound_SimpleInputDevice_nFlush;
-            Java_com_sun_media_sound_SimpleInputDevice_nGetBufferSizeInFrames;
-            Java_com_sun_media_sound_SimpleInputDevice_nGetFormats;
-            Java_com_sun_media_sound_SimpleInputDevice_nGetNumPorts;
-            Java_com_sun_media_sound_SimpleInputDevice_nGetPortName;
-            Java_com_sun_media_sound_SimpleInputDevice_nGetPosition;
-            Java_com_sun_media_sound_SimpleInputDevice_nOpen;
-            Java_com_sun_media_sound_SimpleInputDevice_nPause;
-            Java_com_sun_media_sound_SimpleInputDevice_nResume;
-            Java_com_sun_media_sound_SimpleInputDevice_nStart;
-            Java_com_sun_media_sound_SimpleInputDevice_nStop;
-            Java_com_sun_media_sound_SimpleInputDevice_nSupportsChannels;
-            Java_com_sun_media_sound_SimpleInputDevice_nSupportsSampleRate;
-            Java_com_sun_media_sound_SimpleInputDevice_nSupportsSampleSizeInBits;
-            Java_com_sun_media_sound_SimpleInputDeviceProvider_nGetDescription;
-            Java_com_sun_media_sound_SimpleInputDeviceProvider_nGetName;
-            Java_com_sun_media_sound_SimpleInputDeviceProvider_nGetNumDevices;
-            Java_com_sun_media_sound_SimpleInputDeviceProvider_nGetVendor;
-            Java_com_sun_media_sound_SimpleInputDeviceProvider_nGetVersion;
-	local:
-	    *;
-};
diff --git a/jdk/src/share/classes/com/sun/media/sound/AbstractMidiDevice.java b/jdk/src/share/classes/com/sun/media/sound/AbstractMidiDevice.java
index 5409ab0567b..70cb15e0a40 100644
--- a/jdk/src/share/classes/com/sun/media/sound/AbstractMidiDevice.java
+++ b/jdk/src/share/classes/com/sun/media/sound/AbstractMidiDevice.java
@@ -75,13 +75,6 @@ abstract class AbstractMidiDevice implements MidiDevice, ReferenceCountingDevice
     /**
      * This is the device handle returned from native code
      */
-    /*
-     * $$rratta Solaris 64 bit holds pointer must be long
-     *
-     * $$mp 2003-08-07:
-     * 'id' is a really bad name. The variable should
-     * be called nativePointer or something similar.
-     */
     protected long id                   = 0;
 
 
@@ -586,7 +579,6 @@ abstract class AbstractMidiDevice implements MidiDevice, ReferenceCountingDevice
 
         private ArrayList transmitters = new ArrayList();
         private MidiOutDevice.MidiOutReceiver midiOutReceiver;
-        private MixerSynth.SynthReceiver mixerSynthReceiver;
 
         // how many transmitters must be present for optimized
         // handling
@@ -621,22 +613,14 @@ abstract class AbstractMidiDevice implements MidiDevice, ReferenceCountingDevice
                 if (midiOutReceiver == oldR) {
                     midiOutReceiver = null;
                 }
-                if (mixerSynthReceiver == oldR) {
-                    mixerSynthReceiver = null;
-                }
                 if (newR != null) {
                     if ((newR instanceof MidiOutDevice.MidiOutReceiver)
                         && (midiOutReceiver == null)) {
                         midiOutReceiver = ((MidiOutDevice.MidiOutReceiver) newR);
                     }
-                    if ((newR instanceof MixerSynth.SynthReceiver)
-                        && (mixerSynthReceiver == null)) {
-                        mixerSynthReceiver = ((MixerSynth.SynthReceiver) newR);
-                    }
                 }
                 optimizedReceiverCount =
-                      ((midiOutReceiver!=null)?1:0)
-                    + ((mixerSynthReceiver!=null)?1:0);
+                      ((midiOutReceiver!=null)?1:0);
             }
             // more potential for optimization here
         }
@@ -670,10 +654,6 @@ abstract class AbstractMidiDevice implements MidiDevice, ReferenceCountingDevice
                             if (TRACE_TRANSMITTER) Printer.println("Sending packed message to MidiOutReceiver");
                             midiOutReceiver.sendPackedMidiMessage(packedMessage, timeStamp);
                         }
-                        if (mixerSynthReceiver != null) {
-                            if (TRACE_TRANSMITTER) Printer.println("Sending packed message to MixerSynthReceiver");
-                            mixerSynthReceiver.sendPackedMidiMessage(packedMessage, timeStamp);
-                        }
                     } else {
                         if (TRACE_TRANSMITTER) Printer.println("Sending packed message to "+size+" transmitter's receivers");
                         for (int i = 0; i < size; i++) {
@@ -682,9 +662,6 @@ abstract class AbstractMidiDevice implements MidiDevice, ReferenceCountingDevice
                                 if (optimizedReceiverCount > 0) {
                                     if (receiver instanceof MidiOutDevice.MidiOutReceiver) {
                                         ((MidiOutDevice.MidiOutReceiver) receiver).sendPackedMidiMessage(packedMessage, timeStamp);
-                                    }
-                                    else if (receiver instanceof MixerSynth.SynthReceiver) {
-                                        ((MixerSynth.SynthReceiver) receiver).sendPackedMidiMessage(packedMessage, timeStamp);
                                     } else {
                                         receiver.send(new FastShortMessage(packedMessage), timeStamp);
                                     }
@@ -739,10 +716,6 @@ abstract class AbstractMidiDevice implements MidiDevice, ReferenceCountingDevice
                         if (TRACE_TRANSMITTER) Printer.println("Sending MIDI message to MidiOutReceiver");
                         midiOutReceiver.send(message, timeStamp);
                     }
-                    if (mixerSynthReceiver != null) {
-                        if (TRACE_TRANSMITTER) Printer.println("Sending MIDI message to MixerSynthReceiver");
-                        mixerSynthReceiver.send(message, timeStamp);
-                    }
                 } else {
                     if (TRACE_TRANSMITTER) Printer.println("Sending MIDI message to "+size+" transmitter's receivers");
                     for (int i = 0; i < size; i++) {
diff --git a/jdk/src/share/classes/com/sun/media/sound/AudioFileSoundbankReader.java b/jdk/src/share/classes/com/sun/media/sound/AudioFileSoundbankReader.java
new file mode 100644
index 00000000000..7f4090d8d3e
--- /dev/null
+++ b/jdk/src/share/classes/com/sun/media/sound/AudioFileSoundbankReader.java
@@ -0,0 +1,131 @@
+/*
+ * 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.  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
+ * 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.
+ */
+package com.sun.media.sound;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import javax.sound.midi.InvalidMidiDataException;
+import javax.sound.midi.Soundbank;
+import javax.sound.midi.spi.SoundbankReader;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.UnsupportedAudioFileException;
+
+/**
+ * Soundbank reader that uses audio files as soundbanks.
+ *
+ * @author Karl Helgason
+ */
+public class AudioFileSoundbankReader extends SoundbankReader {
+
+    public Soundbank getSoundbank(URL url)
+            throws InvalidMidiDataException, IOException {
+        try {
+            AudioInputStream ais = AudioSystem.getAudioInputStream(url);
+            Soundbank sbk = getSoundbank(ais);
+            ais.close();
+            return sbk;
+        } catch (UnsupportedAudioFileException e) {
+            return null;
+        } catch (IOException e) {
+            return null;
+        }
+    }
+
+    public Soundbank getSoundbank(InputStream stream)
+            throws InvalidMidiDataException, IOException {
+        stream.mark(512);
+        try {
+            AudioInputStream ais = AudioSystem.getAudioInputStream(stream);
+            Soundbank sbk = getSoundbank(ais);
+            if (sbk != null)
+                return sbk;
+        } catch (UnsupportedAudioFileException e) {
+        } catch (IOException e) {
+        }
+        stream.reset();
+        return null;
+    }
+
+    public Soundbank getSoundbank(AudioInputStream ais)
+            throws InvalidMidiDataException, IOException {
+        try {
+            byte[] buffer;
+            if (ais.getFrameLength() == -1) {
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                byte[] buff = new byte[1024
+                        - (1024 % ais.getFormat().getFrameSize())];
+                int ret;
+                while ((ret = ais.read(buff)) != -1) {
+                    baos.write(buff, 0, ret);
+                }
+                ais.close();
+                buffer = baos.toByteArray();
+            } else {
+                buffer = new byte[(int) (ais.getFrameLength()
+                                    * ais.getFormat().getFrameSize())];
+                new DataInputStream(ais).readFully(buffer);
+            }
+            ModelByteBufferWavetable osc = new ModelByteBufferWavetable(
+                    new ModelByteBuffer(buffer), ais.getFormat(), -4800);
+            ModelPerformer performer = new ModelPerformer();
+            performer.getOscillators().add(osc);
+
+            SimpleSoundbank sbk = new SimpleSoundbank();
+            SimpleInstrument ins = new SimpleInstrument();
+            ins.add(performer);
+            sbk.addInstrument(ins);
+            return sbk;
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    public Soundbank getSoundbank(File file)
+            throws InvalidMidiDataException, IOException {
+        try {
+            AudioInputStream ais = AudioSystem.getAudioInputStream(file);
+            ais.close();
+            ModelByteBufferWavetable osc = new ModelByteBufferWavetable(
+                    new ModelByteBuffer(file, 0, file.length()), -4800);
+            ModelPerformer performer = new ModelPerformer();
+            performer.getOscillators().add(osc);
+            SimpleSoundbank sbk = new SimpleSoundbank();
+            SimpleInstrument ins = new SimpleInstrument();
+            ins.add(performer);
+            sbk.addInstrument(ins);
+            return sbk;
+        } catch (UnsupportedAudioFileException e1) {
+            return null;
+        } catch (IOException e) {
+            return null;
+        }
+    }
+}
diff --git a/jdk/src/share/classes/com/sun/media/sound/AudioFloatConverter.java b/jdk/src/share/classes/com/sun/media/sound/AudioFloatConverter.java
new file mode 100644
index 00000000000..e8d9dbeb14d
--- /dev/null
+++ b/jdk/src/share/classes/com/sun/media/sound/AudioFloatConverter.java
@@ -0,0 +1,1058 @@
+/*
+ * 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.  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
+ * 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.
+ */
+package com.sun.media.sound;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.DoubleBuffer;
+import java.nio.FloatBuffer;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioFormat.Encoding;
+
+/**
+ * This class is used to convert between 8,16,24,32,32+ bit signed/unsigned
+ * big/litle endian fixed/floating point byte buffers and float buffers.
+ *
+ * @author Karl Helgason
+ */
+public abstract class AudioFloatConverter {
+
+    public static final Encoding PCM_FLOAT = new Encoding("PCM_FLOAT");
+
+    /***************************************************************************
+     *
+     * LSB Filter, used filter least significant byte in samples arrays.
+     *
+     * Is used filter out data in lsb byte when SampleSizeInBits is not
+     * dividable by 8.
+     *
+     **************************************************************************/
+
+    private static class AudioFloatLSBFilter extends AudioFloatConverter {
+
+        private AudioFloatConverter converter;
+
+        final private int offset;
+
+        final private int stepsize;
+
+        final private byte mask;
+
+        private byte[] mask_buffer;
+
+        public AudioFloatLSBFilter(AudioFloatConverter converter,
+                AudioFormat format) {
+            int bits = format.getSampleSizeInBits();
+            boolean bigEndian = format.isBigEndian();
+            this.converter = converter;
+            stepsize = (bits + 7) / 8;
+            offset = bigEndian ? (stepsize - 1) : 0;
+            int lsb_bits = bits % 8;
+            if (lsb_bits == 0)
+                mask = (byte) 0x00;
+            else if (lsb_bits == 1)
+                mask = (byte) 0x80;
+            else if (lsb_bits == 2)
+                mask = (byte) 0xC0;
+            else if (lsb_bits == 3)
+                mask = (byte) 0xE0;
+            else if (lsb_bits == 4)
+                mask = (byte) 0xF0;
+            else if (lsb_bits == 5)
+                mask = (byte) 0xF8;
+            else if (lsb_bits == 6)
+                mask = (byte) 0xFC;
+            else if (lsb_bits == 7)
+                mask = (byte) 0xFE;
+            else
+                mask = (byte) 0xFF;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            byte[] ret = converter.toByteArray(in_buff, in_offset, in_len,
+                    out_buff, out_offset);
+
+            int out_offset_end = in_len * stepsize;
+            for (int i = out_offset + offset; i < out_offset_end; i += stepsize) {
+                out_buff[i] = (byte) (out_buff[i] & mask);
+            }
+
+            return ret;
+        }
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            if (mask_buffer == null || mask_buffer.length < in_buff.length)
+                mask_buffer = new byte[in_buff.length];
+            System.arraycopy(in_buff, 0, mask_buffer, 0, in_buff.length);
+            int in_offset_end = out_len * stepsize;
+            for (int i = in_offset + offset; i < in_offset_end; i += stepsize) {
+                mask_buffer[i] = (byte) (mask_buffer[i] & mask);
+            }
+            float[] ret = converter.toFloatArray(mask_buffer, in_offset,
+                    out_buff, out_offset, out_len);
+            return ret;
+        }
+
+    }
+
+    /***************************************************************************
+     *
+     * 64 bit float, little/big-endian
+     *
+     **************************************************************************/
+
+    // PCM 64 bit float, little-endian
+    private static class AudioFloatConversion64L extends AudioFloatConverter {
+        ByteBuffer bytebuffer = null;
+
+        DoubleBuffer floatbuffer = null;
+
+        double[] double_buff = null;
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int in_len = out_len * 8;
+            if (bytebuffer == null || bytebuffer.capacity() < in_len) {
+                bytebuffer = ByteBuffer.allocate(in_len).order(
+                        ByteOrder.LITTLE_ENDIAN);
+                floatbuffer = bytebuffer.asDoubleBuffer();
+            }
+            bytebuffer.position(0);
+            floatbuffer.position(0);
+            bytebuffer.put(in_buff, in_offset, in_len);
+            if (double_buff == null
+                    || double_buff.length < out_len + out_offset)
+                double_buff = new double[out_len + out_offset];
+            floatbuffer.get(double_buff, out_offset, out_len);
+            int out_offset_end = out_offset + out_len;
+            for (int i = out_offset; i < out_offset_end; i++) {
+                out_buff[i] = (float) double_buff[i];
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int out_len = in_len * 8;
+            if (bytebuffer == null || bytebuffer.capacity() < out_len) {
+                bytebuffer = ByteBuffer.allocate(out_len).order(
+                        ByteOrder.LITTLE_ENDIAN);
+                floatbuffer = bytebuffer.asDoubleBuffer();
+            }
+            floatbuffer.position(0);
+            bytebuffer.position(0);
+            if (double_buff == null || double_buff.length < in_offset + in_len)
+                double_buff = new double[in_offset + in_len];
+            int in_offset_end = in_offset + in_len;
+            for (int i = in_offset; i < in_offset_end; i++) {
+                double_buff[i] = in_buff[i];
+            }
+            floatbuffer.put(double_buff, in_offset, in_len);
+            bytebuffer.get(out_buff, out_offset, out_len);
+            return out_buff;
+        }
+    }
+
+    // PCM 64 bit float, big-endian
+    private static class AudioFloatConversion64B extends AudioFloatConverter {
+        ByteBuffer bytebuffer = null;
+
+        DoubleBuffer floatbuffer = null;
+
+        double[] double_buff = null;
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int in_len = out_len * 8;
+            if (bytebuffer == null || bytebuffer.capacity() < in_len) {
+                bytebuffer = ByteBuffer.allocate(in_len).order(
+                        ByteOrder.BIG_ENDIAN);
+                floatbuffer = bytebuffer.asDoubleBuffer();
+            }
+            bytebuffer.position(0);
+            floatbuffer.position(0);
+            bytebuffer.put(in_buff, in_offset, in_len);
+            if (double_buff == null
+                    || double_buff.length < out_len + out_offset)
+                double_buff = new double[out_len + out_offset];
+            floatbuffer.get(double_buff, out_offset, out_len);
+            int out_offset_end = out_offset + out_len;
+            for (int i = out_offset; i < out_offset_end; i++) {
+                out_buff[i] = (float) double_buff[i];
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int out_len = in_len * 8;
+            if (bytebuffer == null || bytebuffer.capacity() < out_len) {
+                bytebuffer = ByteBuffer.allocate(out_len).order(
+                        ByteOrder.BIG_ENDIAN);
+                floatbuffer = bytebuffer.asDoubleBuffer();
+            }
+            floatbuffer.position(0);
+            bytebuffer.position(0);
+            if (double_buff == null || double_buff.length < in_offset + in_len)
+                double_buff = new double[in_offset + in_len];
+            int in_offset_end = in_offset + in_len;
+            for (int i = in_offset; i < in_offset_end; i++) {
+                double_buff[i] = in_buff[i];
+            }
+            floatbuffer.put(double_buff, in_offset, in_len);
+            bytebuffer.get(out_buff, out_offset, out_len);
+            return out_buff;
+        }
+    }
+
+    /***************************************************************************
+     *
+     * 32 bit float, little/big-endian
+     *
+     **************************************************************************/
+
+    // PCM 32 bit float, little-endian
+    private static class AudioFloatConversion32L extends AudioFloatConverter {
+        ByteBuffer bytebuffer = null;
+
+        FloatBuffer floatbuffer = null;
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int in_len = out_len * 4;
+            if (bytebuffer == null || bytebuffer.capacity() < in_len) {
+                bytebuffer = ByteBuffer.allocate(in_len).order(
+                        ByteOrder.LITTLE_ENDIAN);
+                floatbuffer = bytebuffer.asFloatBuffer();
+            }
+            bytebuffer.position(0);
+            floatbuffer.position(0);
+            bytebuffer.put(in_buff, in_offset, in_len);
+            floatbuffer.get(out_buff, out_offset, out_len);
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int out_len = in_len * 4;
+            if (bytebuffer == null || bytebuffer.capacity() < out_len) {
+                bytebuffer = ByteBuffer.allocate(out_len).order(
+                        ByteOrder.LITTLE_ENDIAN);
+                floatbuffer = bytebuffer.asFloatBuffer();
+            }
+            floatbuffer.position(0);
+            bytebuffer.position(0);
+            floatbuffer.put(in_buff, in_offset, in_len);
+            bytebuffer.get(out_buff, out_offset, out_len);
+            return out_buff;
+        }
+    }
+
+    // PCM 32 bit float, big-endian
+    private static class AudioFloatConversion32B extends AudioFloatConverter {
+        ByteBuffer bytebuffer = null;
+
+        FloatBuffer floatbuffer = null;
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int in_len = out_len * 4;
+            if (bytebuffer == null || bytebuffer.capacity() < in_len) {
+                bytebuffer = ByteBuffer.allocate(in_len).order(
+                        ByteOrder.BIG_ENDIAN);
+                floatbuffer = bytebuffer.asFloatBuffer();
+            }
+            bytebuffer.position(0);
+            floatbuffer.position(0);
+            bytebuffer.put(in_buff, in_offset, in_len);
+            floatbuffer.get(out_buff, out_offset, out_len);
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int out_len = in_len * 4;
+            if (bytebuffer == null || bytebuffer.capacity() < out_len) {
+                bytebuffer = ByteBuffer.allocate(out_len).order(
+                        ByteOrder.BIG_ENDIAN);
+                floatbuffer = bytebuffer.asFloatBuffer();
+            }
+            floatbuffer.position(0);
+            bytebuffer.position(0);
+            floatbuffer.put(in_buff, in_offset, in_len);
+            bytebuffer.get(out_buff, out_offset, out_len);
+            return out_buff;
+        }
+    }
+
+    /***************************************************************************
+     *
+     * 8 bit signed/unsigned
+     *
+     **************************************************************************/
+
+    // PCM 8 bit, signed
+    private static class AudioFloatConversion8S extends AudioFloatConverter {
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++)
+                out_buff[ox++] = in_buff[ix++] * (1.0f / 127.0f);
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++)
+                out_buff[ox++] = (byte) (in_buff[ix++] * 127.0f);
+            return out_buff;
+        }
+    }
+
+    // PCM 8 bit, unsigned
+    private static class AudioFloatConversion8U extends AudioFloatConverter {
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++)
+                out_buff[ox++] = ((in_buff[ix++] & 0xFF) - 127)
+                        * (1.0f / 127.0f);
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++)
+                out_buff[ox++] = (byte) (127 + in_buff[ix++] * 127.0f);
+            return out_buff;
+        }
+    }
+
+    /***************************************************************************
+     *
+     * 16 bit signed/unsigned, little/big-endian
+     *
+     **************************************************************************/
+
+    // PCM 16 bit, signed, little-endian
+    private static class AudioFloatConversion16SL extends AudioFloatConverter {
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int len = out_offset + out_len;
+            for (int ox = out_offset; ox < len; ox++) {
+                out_buff[ox] = ((short) ((in_buff[ix++] & 0xFF) |
+                           (in_buff[ix++] << 8))) * (1.0f / 32767.0f);
+            }
+
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ox = out_offset;
+            int len = in_offset + in_len;
+            for (int ix = in_offset; ix < len; ix++) {
+                int x = (int) (in_buff[ix] * 32767.0);
+                out_buff[ox++] = (byte) x;
+                out_buff[ox++] = (byte) (x >>> 8);
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 16 bit, signed, big-endian
+    private static class AudioFloatConversion16SB extends AudioFloatConverter {
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                out_buff[ox++] = ((short) ((in_buff[ix++] << 8) |
+                        (in_buff[ix++] & 0xFF))) * (1.0f / 32767.0f);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int) (in_buff[ix++] * 32767.0);
+                out_buff[ox++] = (byte) (x >>> 8);
+                out_buff[ox++] = (byte) x;
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 16 bit, unsigned, little-endian
+    private static class AudioFloatConversion16UL extends AudioFloatConverter {
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8);
+                out_buff[ox++] = (x - 32767) * (1.0f / 32767.0f);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = 32767 + (int) (in_buff[ix++] * 32767.0);
+                out_buff[ox++] = (byte) x;
+                out_buff[ox++] = (byte) (x >>> 8);
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 16 bit, unsigned, big-endian
+    private static class AudioFloatConversion16UB extends AudioFloatConverter {
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
+                out_buff[ox++] = (x - 32767) * (1.0f / 32767.0f);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = 32767 + (int) (in_buff[ix++] * 32767.0);
+                out_buff[ox++] = (byte) (x >>> 8);
+                out_buff[ox++] = (byte) x;
+            }
+            return out_buff;
+        }
+    }
+
+    /***************************************************************************
+     *
+     * 24 bit signed/unsigned, little/big-endian
+     *
+     **************************************************************************/
+
+    // PCM 24 bit, signed, little-endian
+    private static class AudioFloatConversion24SL extends AudioFloatConverter {
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8)
+                        | ((in_buff[ix++] & 0xFF) << 16);
+                if (x > 0x7FFFFF)
+                    x -= 0x1000000;
+                out_buff[ox++] = x * (1.0f / (float)0x7FFFFF);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int) (in_buff[ix++] * (float)0x7FFFFF);
+                if (x < 0)
+                    x += 0x1000000;
+                out_buff[ox++] = (byte) x;
+                out_buff[ox++] = (byte) (x >>> 8);
+                out_buff[ox++] = (byte) (x >>> 16);
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 24 bit, signed, big-endian
+    private static class AudioFloatConversion24SB extends AudioFloatConverter {
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = ((in_buff[ix++] & 0xFF) << 16)
+                        | ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
+                if (x > 0x7FFFFF)
+                    x -= 0x1000000;
+                out_buff[ox++] = x * (1.0f / (float)0x7FFFFF);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int) (in_buff[ix++] * (float)0x7FFFFF);
+                if (x < 0)
+                    x += 0x1000000;
+                out_buff[ox++] = (byte) (x >>> 16);
+                out_buff[ox++] = (byte) (x >>> 8);
+                out_buff[ox++] = (byte) x;
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 24 bit, unsigned, little-endian
+    private static class AudioFloatConversion24UL extends AudioFloatConverter {
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8)
+                        | ((in_buff[ix++] & 0xFF) << 16);
+                x -= 0x7FFFFF;
+                out_buff[ox++] = x * (1.0f / (float)0x7FFFFF);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int) (in_buff[ix++] * (float)0x7FFFFF);
+                x += 0x7FFFFF;
+                out_buff[ox++] = (byte) x;
+                out_buff[ox++] = (byte) (x >>> 8);
+                out_buff[ox++] = (byte) (x >>> 16);
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 24 bit, unsigned, big-endian
+    private static class AudioFloatConversion24UB extends AudioFloatConverter {
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = ((in_buff[ix++] & 0xFF) << 16)
+                        | ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
+                x -= 0x7FFFFF;
+                out_buff[ox++] = x * (1.0f / (float)0x7FFFFF);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int) (in_buff[ix++] * (float)0x7FFFFF);
+                x += 0x7FFFFF;
+                out_buff[ox++] = (byte) (x >>> 16);
+                out_buff[ox++] = (byte) (x >>> 8);
+                out_buff[ox++] = (byte) x;
+            }
+            return out_buff;
+        }
+    }
+
+    /***************************************************************************
+     *
+     * 32 bit signed/unsigned, little/big-endian
+     *
+     **************************************************************************/
+
+    // PCM 32 bit, signed, little-endian
+    private static class AudioFloatConversion32SL extends AudioFloatConverter {
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8) |
+                        ((in_buff[ix++] & 0xFF) << 16) |
+                        ((in_buff[ix++] & 0xFF) << 24);
+                out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF);
+                out_buff[ox++] = (byte) x;
+                out_buff[ox++] = (byte) (x >>> 8);
+                out_buff[ox++] = (byte) (x >>> 16);
+                out_buff[ox++] = (byte) (x >>> 24);
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 32 bit, signed, big-endian
+    private static class AudioFloatConversion32SB extends AudioFloatConverter {
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = ((in_buff[ix++] & 0xFF) << 24) |
+                        ((in_buff[ix++] & 0xFF) << 16) |
+                        ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
+                out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF);
+                out_buff[ox++] = (byte) (x >>> 24);
+                out_buff[ox++] = (byte) (x >>> 16);
+                out_buff[ox++] = (byte) (x >>> 8);
+                out_buff[ox++] = (byte) x;
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 32 bit, unsigned, little-endian
+    private static class AudioFloatConversion32UL extends AudioFloatConverter {
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8) |
+                        ((in_buff[ix++] & 0xFF) << 16) |
+                        ((in_buff[ix++] & 0xFF) << 24);
+                x -= 0x7FFFFFFF;
+                out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF);
+                x += 0x7FFFFFFF;
+                out_buff[ox++] = (byte) x;
+                out_buff[ox++] = (byte) (x >>> 8);
+                out_buff[ox++] = (byte) (x >>> 16);
+                out_buff[ox++] = (byte) (x >>> 24);
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 32 bit, unsigned, big-endian
+    private static class AudioFloatConversion32UB extends AudioFloatConverter {
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = ((in_buff[ix++] & 0xFF) << 24) |
+                        ((in_buff[ix++] & 0xFF) << 16) |
+                        ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
+                x -= 0x7FFFFFFF;
+                out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF);
+                x += 0x7FFFFFFF;
+                out_buff[ox++] = (byte) (x >>> 24);
+                out_buff[ox++] = (byte) (x >>> 16);
+                out_buff[ox++] = (byte) (x >>> 8);
+                out_buff[ox++] = (byte) x;
+            }
+            return out_buff;
+        }
+    }
+
+    /***************************************************************************
+     *
+     * 32+ bit signed/unsigned, little/big-endian
+     *
+     **************************************************************************/
+
+    // PCM 32+ bit, signed, little-endian
+    private static class AudioFloatConversion32xSL extends AudioFloatConverter {
+
+        final int xbytes;
+
+        public AudioFloatConversion32xSL(int xbytes) {
+            this.xbytes = xbytes;
+        }
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                ix += xbytes;
+                int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8)
+                        | ((in_buff[ix++] & 0xFF) << 16)
+                        | ((in_buff[ix++] & 0xFF) << 24);
+                out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF);
+                for (int j = 0; j < xbytes; j++) {
+                    out_buff[ox++] = 0;
+                }
+                out_buff[ox++] = (byte) x;
+                out_buff[ox++] = (byte) (x >>> 8);
+                out_buff[ox++] = (byte) (x >>> 16);
+                out_buff[ox++] = (byte) (x >>> 24);
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 32+ bit, signed, big-endian
+    private static class AudioFloatConversion32xSB extends AudioFloatConverter {
+
+        final int xbytes;
+
+        public AudioFloatConversion32xSB(int xbytes) {
+            this.xbytes = xbytes;
+        }
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = ((in_buff[ix++] & 0xFF) << 24)
+                        | ((in_buff[ix++] & 0xFF) << 16)
+                        | ((in_buff[ix++] & 0xFF) << 8)
+                        | (in_buff[ix++] & 0xFF);
+                ix += xbytes;
+                out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF);
+                out_buff[ox++] = (byte) (x >>> 24);
+                out_buff[ox++] = (byte) (x >>> 16);
+                out_buff[ox++] = (byte) (x >>> 8);
+                out_buff[ox++] = (byte) x;
+                for (int j = 0; j < xbytes; j++) {
+                    out_buff[ox++] = 0;
+                }
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 32+ bit, unsigned, little-endian
+    private static class AudioFloatConversion32xUL extends AudioFloatConverter {
+
+        final int xbytes;
+
+        public AudioFloatConversion32xUL(int xbytes) {
+            this.xbytes = xbytes;
+        }
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                ix += xbytes;
+                int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8)
+                        | ((in_buff[ix++] & 0xFF) << 16)
+                        | ((in_buff[ix++] & 0xFF) << 24);
+                x -= 0x7FFFFFFF;
+                out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF);
+                x += 0x7FFFFFFF;
+                for (int j = 0; j < xbytes; j++) {
+                    out_buff[ox++] = 0;
+                }
+                out_buff[ox++] = (byte) x;
+                out_buff[ox++] = (byte) (x >>> 8);
+                out_buff[ox++] = (byte) (x >>> 16);
+                out_buff[ox++] = (byte) (x >>> 24);
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 32+ bit, unsigned, big-endian
+    private static class AudioFloatConversion32xUB extends AudioFloatConverter {
+
+        final int xbytes;
+
+        public AudioFloatConversion32xUB(int xbytes) {
+            this.xbytes = xbytes;
+        }
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = ((in_buff[ix++] & 0xFF) << 24) |
+                        ((in_buff[ix++] & 0xFF) << 16) |
+                        ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
+                ix += xbytes;
+                x -= 2147483647;
+                out_buff[ox++] = x * (1.0f / 2147483647.0f);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int) (in_buff[ix++] * 2147483647.0);
+                x += 2147483647;
+                out_buff[ox++] = (byte) (x >>> 24);
+                out_buff[ox++] = (byte) (x >>> 16);
+                out_buff[ox++] = (byte) (x >>> 8);
+                out_buff[ox++] = (byte) x;
+                for (int j = 0; j < xbytes; j++) {
+                    out_buff[ox++] = 0;
+                }
+            }
+            return out_buff;
+        }
+    }
+
+    public static AudioFloatConverter getConverter(AudioFormat format) {
+        AudioFloatConverter conv = null;
+        if (format.getFrameSize() == 0)
+            return null;
+        if (format.getFrameSize() !=
+                ((format.getSampleSizeInBits() + 7) / 8) * format.getChannels()) {
+            return null;
+        }
+        if (format.getEncoding().equals(Encoding.PCM_SIGNED)) {
+            if (format.isBigEndian()) {
+                if (format.getSampleSizeInBits() <= 8) {
+                    conv = new AudioFloatConversion8S();
+                } else if (format.getSampleSizeInBits() > 8 &&
+                      format.getSampleSizeInBits() <= 16) {
+                    conv = new AudioFloatConversion16SB();
+                } else if (format.getSampleSizeInBits() > 16 &&
+                      format.getSampleSizeInBits() <= 24) {
+                    conv = new AudioFloatConversion24SB();
+                } else if (format.getSampleSizeInBits() > 24 &&
+                      format.getSampleSizeInBits() <= 32) {
+                    conv = new AudioFloatConversion32SB();
+                } else if (format.getSampleSizeInBits() > 32) {
+                    conv = new AudioFloatConversion32xSB(((format
+                            .getSampleSizeInBits() + 7) / 8) - 4);
+                }
+            } else {
+                if (format.getSampleSizeInBits() <= 8) {
+                    conv = new AudioFloatConversion8S();
+                } else if (format.getSampleSizeInBits() > 8 &&
+                         format.getSampleSizeInBits() <= 16) {
+                    conv = new AudioFloatConversion16SL();
+                } else if (format.getSampleSizeInBits() > 16 &&
+                         format.getSampleSizeInBits() <= 24) {
+                    conv = new AudioFloatConversion24SL();
+                } else if (format.getSampleSizeInBits() > 24 &&
+                         format.getSampleSizeInBits() <= 32) {
+                    conv = new AudioFloatConversion32SL();
+                } else if (format.getSampleSizeInBits() > 32) {
+                    conv = new AudioFloatConversion32xSL(((format
+                            .getSampleSizeInBits() + 7) / 8) - 4);
+                }
+            }
+        } else if (format.getEncoding().equals(Encoding.PCM_UNSIGNED)) {
+            if (format.isBigEndian()) {
+                if (format.getSampleSizeInBits() <= 8) {
+                    conv = new AudioFloatConversion8U();
+                } else if (format.getSampleSizeInBits() > 8 &&
+                        format.getSampleSizeInBits() <= 16) {
+                    conv = new AudioFloatConversion16UB();
+                } else if (format.getSampleSizeInBits() > 16 &&
+                        format.getSampleSizeInBits() <= 24) {
+                    conv = new AudioFloatConversion24UB();
+                } else if (format.getSampleSizeInBits() > 24 &&
+                        format.getSampleSizeInBits() <= 32) {
+                    conv = new AudioFloatConversion32UB();
+                } else if (format.getSampleSizeInBits() > 32) {
+                    conv = new AudioFloatConversion32xUB(((
+                            format.getSampleSizeInBits() + 7) / 8) - 4);
+                }
+            } else {
+                if (format.getSampleSizeInBits() <= 8) {
+                    conv = new AudioFloatConversion8U();
+                } else if (format.getSampleSizeInBits() > 8 &&
+                        format.getSampleSizeInBits() <= 16) {
+                    conv = new AudioFloatConversion16UL();
+                } else if (format.getSampleSizeInBits() > 16 &&
+                        format.getSampleSizeInBits() <= 24) {
+                    conv = new AudioFloatConversion24UL();
+                } else if (format.getSampleSizeInBits() > 24 &&
+                        format.getSampleSizeInBits() <= 32) {
+                    conv = new AudioFloatConversion32UL();
+                } else if (format.getSampleSizeInBits() > 32) {
+                    conv = new AudioFloatConversion32xUL(((
+                            format.getSampleSizeInBits() + 7) / 8) - 4);
+                }
+            }
+        } else if (format.getEncoding().equals(PCM_FLOAT)) {
+            if (format.getSampleSizeInBits() == 32) {
+                if (format.isBigEndian())
+                    conv = new AudioFloatConversion32B();
+                else
+                    conv = new AudioFloatConversion32L();
+            } else if (format.getSampleSizeInBits() == 64) {
+                if (format.isBigEndian())
+                    conv = new AudioFloatConversion64B();
+                else
+                    conv = new AudioFloatConversion64L();
+            }
+
+        }
+
+        if ((format.getEncoding().equals(Encoding.PCM_SIGNED) ||
+                format.getEncoding().equals(Encoding.PCM_UNSIGNED)) &&
+                (format.getSampleSizeInBits() % 8 != 0)) {
+            conv = new AudioFloatLSBFilter(conv, format);
+        }
+
+        if (conv != null)
+            conv.format = format;
+        return conv;
+    }
+
+    private AudioFormat format;
+
+    public AudioFormat getFormat() {
+        return format;
+    }
+
+    public abstract float[] toFloatArray(byte[] in_buff, int in_offset,
+            float[] out_buff, int out_offset, int out_len);
+
+    public float[] toFloatArray(byte[] in_buff, float[] out_buff,
+            int out_offset, int out_len) {
+        return toFloatArray(in_buff, 0, out_buff, out_offset, out_len);
+    }
+
+    public float[] toFloatArray(byte[] in_buff, int in_offset,
+            float[] out_buff, int out_len) {
+        return toFloatArray(in_buff, in_offset, out_buff, 0, out_len);
+    }
+
+    public float[] toFloatArray(byte[] in_buff, float[] out_buff, int out_len) {
+        return toFloatArray(in_buff, 0, out_buff, 0, out_len);
+    }
+
+    public float[] toFloatArray(byte[] in_buff, float[] out_buff) {
+        return toFloatArray(in_buff, 0, out_buff, 0, out_buff.length);
+    }
+
+    public abstract byte[] toByteArray(float[] in_buff, int in_offset,
+            int in_len, byte[] out_buff, int out_offset);
+
+    public byte[] toByteArray(float[] in_buff, int in_len, byte[] out_buff,
+            int out_offset) {
+        return toByteArray(in_buff, 0, in_len, out_buff, out_offset);
+    }
+
+    public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+            byte[] out_buff) {
+        return toByteArray(in_buff, in_offset, in_len, out_buff, 0);
+    }
+
+    public byte[] toByteArray(float[] in_buff, int in_len, byte[] out_buff) {
+        return toByteArray(in_buff, 0, in_len, out_buff, 0);
+    }
+
+    public byte[] toByteArray(float[] in_buff, byte[] out_buff) {
+        return toByteArray(in_buff, 0, in_buff.length, out_buff, 0);
+    }
+}
diff --git a/jdk/src/share/classes/com/sun/media/sound/AudioFloatFormatConverter.java b/jdk/src/share/classes/com/sun/media/sound/AudioFloatFormatConverter.java
new file mode 100644
index 00000000000..4e835f4c192
--- /dev/null
+++ b/jdk/src/share/classes/com/sun/media/sound/AudioFloatFormatConverter.java
@@ -0,0 +1,617 @@
+/*
+ * Copyright 2008 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.  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
+ * 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.
+ */
+package com.sun.media.sound;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.AudioFormat.Encoding;
+import javax.sound.sampled.spi.FormatConversionProvider;
+
+/**
+ * This class is used to convert between 8,16,24,32 bit signed/unsigned
+ * big/litle endian fixed/floating stereo/mono/multi-channel audio streams and
+ * perform sample-rate conversion if needed.
+ *
+ * @author Karl Helgason
+ */
+public class AudioFloatFormatConverter extends FormatConversionProvider {
+
+    private static class AudioFloatFormatConverterInputStream extends
+            InputStream {
+        private AudioFloatConverter converter;
+
+        private AudioFloatInputStream stream;
+
+        private float[] readfloatbuffer;
+
+        private int fsize = 0;
+
+        public AudioFloatFormatConverterInputStream(AudioFormat targetFormat,
+                AudioFloatInputStream stream) {
+            this.stream = stream;
+            converter = AudioFloatConverter.getConverter(targetFormat);
+            fsize = ((targetFormat.getSampleSizeInBits() + 7) / 8);
+        }
+
+        public int read() throws IOException {
+            byte[] b = new byte[1];
+            int ret = read(b);
+            if (ret < 0)
+                return ret;
+            return b[0] & 0xFF;
+        }
+
+        public int read(byte[] b, int off, int len) throws IOException {
+
+            int flen = len / fsize;
+            if (readfloatbuffer == null || readfloatbuffer.length < flen)
+                readfloatbuffer = new float[flen];
+            int ret = stream.read(readfloatbuffer, 0, flen);
+            if (ret < 0)
+                return ret;
+            converter.toByteArray(readfloatbuffer, 0, ret, b, off);
+            return ret * fsize;
+        }
+
+        public int available() throws IOException {
+            int ret = stream.available();
+            if (ret < 0)
+                return ret;
+            return ret * fsize;
+        }
+
+        public void close() throws IOException {
+            stream.close();
+        }
+
+        public synchronized void mark(int readlimit) {
+            stream.mark(readlimit * fsize);
+        }
+
+        public boolean markSupported() {
+            return stream.markSupported();
+        }
+
+        public synchronized void reset() throws IOException {
+            stream.reset();
+        }
+
+        public long skip(long n) throws IOException {
+            long ret = stream.skip(n / fsize);
+            if (ret < 0)
+                return ret;
+            return ret * fsize;
+        }
+
+    }
+
+    private static class AudioFloatInputStreamChannelMixer extends
+            AudioFloatInputStream {
+
+        private int targetChannels;
+
+        private int sourceChannels;
+
+        private AudioFloatInputStream ais;
+
+        private AudioFormat targetFormat;
+
+        private float[] conversion_buffer;
+
+        public AudioFloatInputStreamChannelMixer(AudioFloatInputStream ais,
+                int targetChannels) {
+            this.sourceChannels = ais.getFormat().getChannels();
+            this.targetChannels = targetChannels;
+            this.ais = ais;
+            AudioFormat format = ais.getFormat();
+            targetFormat = new AudioFormat(format.getEncoding(), format
+                    .getSampleRate(), format.getSampleSizeInBits(),
+                    targetChannels, (format.getFrameSize() / sourceChannels)
+                            * targetChannels, format.getFrameRate(), format
+                            .isBigEndian());
+        }
+
+        public int available() throws IOException {
+            return (ais.available() / sourceChannels) * targetChannels;
+        }
+
+        public void close() throws IOException {
+            ais.close();
+        }
+
+        public AudioFormat getFormat() {
+            return targetFormat;
+        }
+
+        public long getFrameLength() {
+            return ais.getFrameLength();
+        }
+
+        public void mark(int readlimit) {
+            ais.mark((readlimit / targetChannels) * sourceChannels);
+        }
+
+        public boolean markSupported() {
+            return ais.markSupported();
+        }
+
+        public int read(float[] b, int off, int len) throws IOException {
+            int len2 = (len / targetChannels) * sourceChannels;
+            if (conversion_buffer == null || conversion_buffer.length < len2)
+                conversion_buffer = new float[len2];
+            int ret = ais.read(conversion_buffer, 0, len2);
+            if (ret < 0)
+                return ret;
+            if (sourceChannels == 1) {
+                int cs = targetChannels;
+                for (int c = 0; c < targetChannels; c++) {
+                    for (int i = 0, ix = off + c; i < len2; i++, ix += cs) {
+                        b[ix] = conversion_buffer[i];
+                        ;
+                    }
+                }
+            } else if (targetChannels == 1) {
+                int cs = sourceChannels;
+                for (int i = 0, ix = off; i < len2; i += cs, ix++) {
+                    b[ix] = conversion_buffer[i];
+                }
+                for (int c = 1; c < sourceChannels; c++) {
+                    for (int i = c, ix = off; i < len2; i += cs, ix++) {
+                        b[ix] += conversion_buffer[i];
+                        ;
+                    }
+                }
+                float vol = 1f / ((float) sourceChannels);
+                for (int i = 0, ix = off; i < len2; i += cs, ix++) {
+                    b[ix] *= vol;
+                }
+            } else {
+                int minChannels = Math.min(sourceChannels, targetChannels);
+                int off_len = off + len;
+                int ct = targetChannels;
+                int cs = sourceChannels;
+                for (int c = 0; c < minChannels; c++) {
+                    for (int i = off + c, ix = c; i < off_len; i += ct, ix += cs) {
+                        b[i] = conversion_buffer[ix];
+                    }
+                }
+                for (int c = minChannels; c < targetChannels; c++) {
+                    for (int i = off + c; i < off_len; i += ct) {
+                        b[i] = 0;
+                    }
+                }
+            }
+            return (ret / sourceChannels) * targetChannels;
+        }
+
+        public void reset() throws IOException {
+            ais.reset();
+        }
+
+        public long skip(long len) throws IOException {
+            long ret = ais.skip((len / targetChannels) * sourceChannels);
+            if (ret < 0)
+                return ret;
+            return (ret / sourceChannels) * targetChannels;
+        }
+
+    }
+
+    private static class AudioFloatInputStreamResampler extends
+            AudioFloatInputStream {
+
+        private AudioFloatInputStream ais;
+
+        private AudioFormat targetFormat;
+
+        private float[] skipbuffer;
+
+        private SoftAbstractResampler resampler;
+
+        private float[] pitch = new float[1];
+
+        private float[] ibuffer2;
+
+        private float[][] ibuffer;
+
+        private float ibuffer_index = 0;
+
+        private int ibuffer_len = 0;
+
+        private int nrofchannels = 0;
+
+        private float[][] cbuffer;
+
+        private int buffer_len = 512;
+
+        private int pad;
+
+        private int pad2;
+
+        private float[] ix = new float[1];
+
+        private int[] ox = new int[1];
+
+        private float[][] mark_ibuffer = null;
+
+        private float mark_ibuffer_index = 0;
+
+        private int mark_ibuffer_len = 0;
+
+        public AudioFloatInputStreamResampler(AudioFloatInputStream ais,
+                AudioFormat format) {
+            this.ais = ais;
+            AudioFormat sourceFormat = ais.getFormat();
+            targetFormat = new AudioFormat(sourceFormat.getEncoding(), format
+                    .getSampleRate(), sourceFormat.getSampleSizeInBits(),
+                    sourceFormat.getChannels(), sourceFormat.getFrameSize(),
+                    format.getSampleRate(), sourceFormat.isBigEndian());
+            nrofchannels = targetFormat.getChannels();
+            Object interpolation = format.getProperty("interpolation");
+            if (interpolation != null && (interpolation instanceof String)) {
+                String resamplerType = (String) interpolation;
+                if (resamplerType.equalsIgnoreCase("point"))
+                    this.resampler = new SoftPointResampler();
+                if (resamplerType.equalsIgnoreCase("linear"))
+                    this.resampler = new SoftLinearResampler2();
+                if (resamplerType.equalsIgnoreCase("linear1"))
+                    this.resampler = new SoftLinearResampler();
+                if (resamplerType.equalsIgnoreCase("linear2"))
+                    this.resampler = new SoftLinearResampler2();
+                if (resamplerType.equalsIgnoreCase("cubic"))
+                    this.resampler = new SoftCubicResampler();
+                if (resamplerType.equalsIgnoreCase("lanczos"))
+                    this.resampler = new SoftLanczosResampler();
+                if (resamplerType.equalsIgnoreCase("sinc"))
+                    this.resampler = new SoftSincResampler();
+            }
+            if (resampler == null)
+                resampler = new SoftLinearResampler2(); // new
+                                                        // SoftLinearResampler2();
+            pitch[0] = sourceFormat.getSampleRate() / format.getSampleRate();
+            pad = resampler.getPadding();
+            pad2 = pad * 2;
+            ibuffer = new float[nrofchannels][buffer_len + pad2];
+            ibuffer2 = new float[nrofchannels * buffer_len];
+            ibuffer_index = buffer_len + pad;
+            ibuffer_len = buffer_len;
+        }
+
+        public int available() throws IOException {
+            return 0;
+        }
+
+        public void close() throws IOException {
+            ais.close();
+        }
+
+        public AudioFormat getFormat() {
+            return targetFormat;
+        }
+
+        public long getFrameLength() {
+            return AudioSystem.NOT_SPECIFIED; // ais.getFrameLength();
+        }
+
+        public void mark(int readlimit) {
+            ais.mark((int) (readlimit * pitch[0]));
+            mark_ibuffer_index = ibuffer_index;
+            mark_ibuffer_len = ibuffer_len;
+            if (mark_ibuffer == null) {
+                mark_ibuffer = new float[ibuffer.length][ibuffer[0].length];
+            }
+            for (int c = 0; c < ibuffer.length; c++) {
+                float[] from = ibuffer[c];
+                float[] to = mark_ibuffer[c];
+                for (int i = 0; i < to.length; i++) {
+                    to[i] = from[i];
+                }
+            }
+        }
+
+        public boolean markSupported() {
+            return ais.markSupported();
+        }
+
+        private void readNextBuffer() throws IOException {
+
+            if (ibuffer_len == -1)
+                return;
+
+            for (int c = 0; c < nrofchannels; c++) {
+                float[] buff = ibuffer[c];
+                int buffer_len_pad = ibuffer_len + pad2;
+                for (int i = ibuffer_len, ix = 0; i < buffer_len_pad; i++, ix++) {
+                    buff[ix] = buff[i];
+                }
+            }
+
+            ibuffer_index -= (ibuffer_len);
+
+            ibuffer_len = ais.read(ibuffer2);
+            if (ibuffer_len >= 0) {
+                while (ibuffer_len < ibuffer2.length) {
+                    int ret = ais.read(ibuffer2, ibuffer_len, ibuffer2.length
+                            - ibuffer_len);
+                    if (ret == -1)
+                        break;
+                    ibuffer_len += ret;
+                }
+                Arrays.fill(ibuffer2, ibuffer_len, ibuffer2.length, 0);
+                ibuffer_len /= nrofchannels;
+            } else {
+                Arrays.fill(ibuffer2, 0, ibuffer2.length, 0);
+            }
+
+            int ibuffer2_len = ibuffer2.length;
+            for (int c = 0; c < nrofchannels; c++) {
+                float[] buff = ibuffer[c];
+                for (int i = c, ix = pad2; i < ibuffer2_len; i += nrofchannels, ix++) {
+                    buff[ix] = ibuffer2[i];
+                }
+            }
+
+        }
+
+        public int read(float[] b, int off, int len) throws IOException {
+
+            if (cbuffer == null || cbuffer[0].length < len / nrofchannels) {
+                cbuffer = new float[nrofchannels][len / nrofchannels];
+            }
+            if (ibuffer_len == -1)
+                return -1;
+            if (len < 0)
+                return 0;
+            int remain = len / nrofchannels;
+            int destPos = 0;
+            int in_end = ibuffer_len;
+            while (remain > 0) {
+                if (ibuffer_len >= 0) {
+                    if (ibuffer_index >= (ibuffer_len + pad))
+                        readNextBuffer();
+                    in_end = ibuffer_len + pad;
+                }
+
+                if (ibuffer_len < 0) {
+                    in_end = pad2;
+                    if (ibuffer_index >= in_end)
+                        break;
+                }
+
+                if (ibuffer_index < 0)
+                    break;
+                int preDestPos = destPos;
+                for (int c = 0; c < nrofchannels; c++) {
+                    ix[0] = ibuffer_index;
+                    ox[0] = destPos;
+                    float[] buff = ibuffer[c];
+                    resampler.interpolate(buff, ix, in_end, pitch, 0,
+                            cbuffer[c], ox, len / nrofchannels);
+                }
+                ibuffer_index = ix[0];
+                destPos = ox[0];
+                remain -= destPos - preDestPos;
+            }
+            for (int c = 0; c < nrofchannels; c++) {
+                int ix = 0;
+                float[] buff = cbuffer[c];
+                for (int i = c; i < b.length; i += nrofchannels) {
+                    b[i] = buff[ix++];
+                }
+            }
+            return len - remain * nrofchannels;
+        }
+
+        public void reset() throws IOException {
+            ais.reset();
+            if (mark_ibuffer == null)
+                return;
+            ibuffer_index = mark_ibuffer_index;
+            ibuffer_len = mark_ibuffer_len;
+            for (int c = 0; c < ibuffer.length; c++) {
+                float[] from = mark_ibuffer[c];
+                float[] to = ibuffer[c];
+                for (int i = 0; i < to.length; i++) {
+                    to[i] = from[i];
+                }
+            }
+
+        }
+
+        public long skip(long len) throws IOException {
+            if (len > 0)
+                return 0;
+            if (skipbuffer == null)
+                skipbuffer = new float[1024 * targetFormat.getFrameSize()];
+            float[] l_skipbuffer = skipbuffer;
+            long remain = len;
+            while (remain > 0) {
+                int ret = read(l_skipbuffer, 0, (int) Math.min(remain,
+                        skipbuffer.length));
+                if (ret < 0) {
+                    if (remain == len)
+                        return ret;
+                    break;
+                }
+                remain -= ret;
+            }
+            return len - remain;
+
+        }
+
+    }
+
+    private Encoding[] formats = { Encoding.PCM_SIGNED, Encoding.PCM_UNSIGNED,
+            AudioFloatConverter.PCM_FLOAT };
+
+    public AudioInputStream getAudioInputStream(Encoding targetEncoding,
+            AudioInputStream sourceStream) {
+        if (sourceStream.getFormat().getEncoding().equals(targetEncoding))
+            return sourceStream;
+        AudioFormat format = sourceStream.getFormat();
+        int channels = format.getChannels();
+        Encoding encoding = targetEncoding;
+        float samplerate = format.getSampleRate();
+        int bits = format.getSampleSizeInBits();
+        boolean bigendian = format.isBigEndian();
+        if (targetEncoding.equals(AudioFloatConverter.PCM_FLOAT))
+            bits = 32;
+        AudioFormat targetFormat = new AudioFormat(encoding, samplerate, bits,
+                channels, channels * bits / 8, samplerate, bigendian);
+        return getAudioInputStream(targetFormat, sourceStream);
+    }
+
+    public AudioInputStream getAudioInputStream(AudioFormat targetFormat,
+            AudioInputStream sourceStream) {
+        if (!isConversionSupported(targetFormat, sourceStream.getFormat()))
+            throw new IllegalArgumentException("Unsupported conversion: "
+                    + sourceStream.getFormat().toString() + " to "
+                    + targetFormat.toString());
+        return getAudioInputStream(targetFormat, AudioFloatInputStream
+                .getInputStream(sourceStream));
+    }
+
+    public AudioInputStream getAudioInputStream(AudioFormat targetFormat,
+            AudioFloatInputStream sourceStream) {
+
+        if (!isConversionSupported(targetFormat, sourceStream.getFormat()))
+            throw new IllegalArgumentException("Unsupported conversion: "
+                    + sourceStream.getFormat().toString() + " to "
+                    + targetFormat.toString());
+        if (targetFormat.getChannels() != sourceStream.getFormat()
+                .getChannels())
+            sourceStream = new AudioFloatInputStreamChannelMixer(sourceStream,
+                    targetFormat.getChannels());
+        if (Math.abs(targetFormat.getSampleRate()
+                - sourceStream.getFormat().getSampleRate()) > 0.000001)
+            sourceStream = new AudioFloatInputStreamResampler(sourceStream,
+                    targetFormat);
+        return new AudioInputStream(new AudioFloatFormatConverterInputStream(
+                targetFormat, sourceStream), targetFormat, sourceStream
+                .getFrameLength());
+    }
+
+    public Encoding[] getSourceEncodings() {
+        return new Encoding[] { Encoding.PCM_SIGNED, Encoding.PCM_UNSIGNED,
+                AudioFloatConverter.PCM_FLOAT };
+    }
+
+    public Encoding[] getTargetEncodings() {
+        return new Encoding[] { Encoding.PCM_SIGNED, Encoding.PCM_UNSIGNED,
+                AudioFloatConverter.PCM_FLOAT };
+    }
+
+    public Encoding[] getTargetEncodings(AudioFormat sourceFormat) {
+        if (AudioFloatConverter.getConverter(sourceFormat) == null)
+            return new Encoding[0];
+        return new Encoding[] { Encoding.PCM_SIGNED, Encoding.PCM_UNSIGNED,
+                AudioFloatConverter.PCM_FLOAT };
+    }
+
+    public AudioFormat[] getTargetFormats(Encoding targetEncoding,
+            AudioFormat sourceFormat) {
+        if (AudioFloatConverter.getConverter(sourceFormat) == null)
+            return new AudioFormat[0];
+        int channels = sourceFormat.getChannels();
+
+        ArrayList formats = new ArrayList();
+
+        if (targetEncoding.equals(Encoding.PCM_SIGNED))
+            formats.add(new AudioFormat(Encoding.PCM_SIGNED,
+                    AudioSystem.NOT_SPECIFIED, 8, channels, channels,
+                    AudioSystem.NOT_SPECIFIED, false));
+        if (targetEncoding.equals(Encoding.PCM_UNSIGNED))
+            formats.add(new AudioFormat(Encoding.PCM_UNSIGNED,
+                    AudioSystem.NOT_SPECIFIED, 8, channels, channels,
+                    AudioSystem.NOT_SPECIFIED, false));
+
+        for (int bits = 16; bits < 32; bits += 8) {
+            if (targetEncoding.equals(Encoding.PCM_SIGNED)) {
+                formats.add(new AudioFormat(Encoding.PCM_SIGNED,
+                        AudioSystem.NOT_SPECIFIED, bits, channels, channels
+                                * bits / 8, AudioSystem.NOT_SPECIFIED, false));
+                formats.add(new AudioFormat(Encoding.PCM_SIGNED,
+                        AudioSystem.NOT_SPECIFIED, bits, channels, channels
+                                * bits / 8, AudioSystem.NOT_SPECIFIED, true));
+            }
+            if (targetEncoding.equals(Encoding.PCM_UNSIGNED)) {
+                formats.add(new AudioFormat(Encoding.PCM_UNSIGNED,
+                        AudioSystem.NOT_SPECIFIED, bits, channels, channels
+                                * bits / 8, AudioSystem.NOT_SPECIFIED, true));
+                formats.add(new AudioFormat(Encoding.PCM_UNSIGNED,
+                        AudioSystem.NOT_SPECIFIED, bits, channels, channels
+                                * bits / 8, AudioSystem.NOT_SPECIFIED, false));
+            }
+        }
+
+        if (targetEncoding.equals(AudioFloatConverter.PCM_FLOAT)) {
+            formats.add(new AudioFormat(AudioFloatConverter.PCM_FLOAT,
+                    AudioSystem.NOT_SPECIFIED, 32, channels, channels * 4,
+                    AudioSystem.NOT_SPECIFIED, false));
+            formats.add(new AudioFormat(AudioFloatConverter.PCM_FLOAT,
+                    AudioSystem.NOT_SPECIFIED, 32, channels, channels * 4,
+                    AudioSystem.NOT_SPECIFIED, true));
+            formats.add(new AudioFormat(AudioFloatConverter.PCM_FLOAT,
+                    AudioSystem.NOT_SPECIFIED, 64, channels, channels * 8,
+                    AudioSystem.NOT_SPECIFIED, false));
+            formats.add(new AudioFormat(AudioFloatConverter.PCM_FLOAT,
+                    AudioSystem.NOT_SPECIFIED, 64, channels, channels * 8,
+                    AudioSystem.NOT_SPECIFIED, true));
+        }
+
+        return formats.toArray(new AudioFormat[formats.size()]);
+    }
+
+    public boolean isConversionSupported(AudioFormat targetFormat,
+            AudioFormat sourceFormat) {
+        if (AudioFloatConverter.getConverter(sourceFormat) == null)
+            return false;
+        if (AudioFloatConverter.getConverter(targetFormat) == null)
+            return false;
+        if (sourceFormat.getChannels() <= 0)
+            return false;
+        if (targetFormat.getChannels() <= 0)
+            return false;
+        return true;
+    }
+
+    public boolean isConversionSupported(Encoding targetEncoding,
+            AudioFormat sourceFormat) {
+        if (AudioFloatConverter.getConverter(sourceFormat) == null)
+            return false;
+        for (int i = 0; i < formats.length; i++) {
+            if (targetEncoding.equals(formats[i]))
+                return true;
+        }
+        return false;
+    }
+
+}
diff --git a/jdk/src/share/classes/com/sun/media/sound/AudioFloatInputStream.java b/jdk/src/share/classes/com/sun/media/sound/AudioFloatInputStream.java
new file mode 100644
index 00000000000..9c3673721c3
--- /dev/null
+++ b/jdk/src/share/classes/com/sun/media/sound/AudioFloatInputStream.java
@@ -0,0 +1,281 @@
+/*
+ * 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.  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
+ * 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.
+ */
+package com.sun.media.sound;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.UnsupportedAudioFileException;
+
+/**
+ * This class is used to create AudioFloatInputStream from AudioInputStream and
+ * byte buffers.
+ *
+ * @author Karl Helgason
+ */
+public abstract class AudioFloatInputStream {
+
+    private static class BytaArrayAudioFloatInputStream
+            extends AudioFloatInputStream {
+
+        private int pos = 0;
+        private int markpos = 0;
+        private AudioFloatConverter converter;
+        private AudioFormat format;
+        private byte[] buffer;
+        private int buffer_offset;
+        private int buffer_len;
+        private int framesize_pc;
+
+        public BytaArrayAudioFloatInputStream(AudioFloatConverter converter,
+                byte[] buffer, int offset, int len) {
+            this.converter = converter;
+            this.format = converter.getFormat();
+            this.buffer = buffer;
+            this.buffer_offset = offset;
+            framesize_pc = format.getFrameSize() / format.getChannels();
+            this.buffer_len = len / framesize_pc;
+
+        }
+
+        public AudioFormat getFormat() {
+            return format;
+        }
+
+        public long getFrameLength() {
+            return buffer_len;// / format.getFrameSize();
+        }
+
+        public int read(float[] b, int off, int len) throws IOException {
+            if (b == null)
+                throw new NullPointerException();
+            if (off < 0 || len < 0 || len > b.length - off)
+                throw new IndexOutOfBoundsException();
+            if (pos >= buffer_len)
+                return -1;
+            if (len == 0)
+                return 0;
+            if (pos + len > buffer_len)
+                len = buffer_len - pos;
+            converter.toFloatArray(buffer, buffer_offset + pos * framesize_pc,
+                    b, off, len);
+            pos += len;
+            return len;
+        }
+
+        public long skip(long len) throws IOException {
+            if (pos >= buffer_len)
+                return -1;
+            if (len <= 0)
+                return 0;
+            if (pos + len > buffer_len)
+                len = buffer_len - pos;
+            pos += len;
+            return len;
+        }
+
+        public int available() throws IOException {
+            return buffer_len - pos;
+        }
+
+        public void close() throws IOException {
+        }
+
+        public void mark(int readlimit) {
+            markpos = pos;
+        }
+
+        public boolean markSupported() {
+            return true;
+        }
+
+        public void reset() throws IOException {
+            pos = markpos;
+        }
+    }
+
+    private static class DirectAudioFloatInputStream
+            extends AudioFloatInputStream {
+
+        private AudioInputStream stream;
+        private AudioFloatConverter converter;
+        private int framesize_pc; // framesize / channels
+        private byte[] buffer;
+
+        public DirectAudioFloatInputStream(AudioInputStream stream) {
+            converter = AudioFloatConverter.getConverter(stream.getFormat());
+            if (converter == null) {
+                AudioFormat format = stream.getFormat();
+                AudioFormat newformat;
+
+                AudioFormat[] formats = AudioSystem.getTargetFormats(
+                        AudioFormat.Encoding.PCM_SIGNED, format);
+                if (formats.length != 0) {
+                    newformat = formats[0];
+                } else {
+                    float samplerate = format.getSampleRate();
+                    int samplesizeinbits = format.getSampleSizeInBits();
+                    int framesize = format.getFrameSize();
+                    float framerate = format.getFrameRate();
+                    samplesizeinbits = 16;
+                    framesize = format.getChannels() * (samplesizeinbits / 8);
+                    framerate = samplerate;
+
+                    newformat = new AudioFormat(
+                            AudioFormat.Encoding.PCM_SIGNED, samplerate,
+                            samplesizeinbits, format.getChannels(), framesize,
+                            framerate, false);
+                }
+
+                stream = AudioSystem.getAudioInputStream(newformat, stream);
+                converter = AudioFloatConverter.getConverter(stream.getFormat());
+            }
+            framesize_pc = stream.getFormat().getFrameSize()
+                    / stream.getFormat().getChannels();
+            this.stream = stream;
+        }
+
+        public AudioFormat getFormat() {
+            return stream.getFormat();
+        }
+
+        public long getFrameLength() {
+            return stream.getFrameLength();
+        }
+
+        public int read(float[] b, int off, int len) throws IOException {
+            int b_len = len * framesize_pc;
+            if (buffer == null || buffer.length < b_len)
+                buffer = new byte[b_len];
+            int ret = stream.read(buffer, 0, b_len);
+            if (ret == -1)
+                return -1;
+            converter.toFloatArray(buffer, b, off, ret / framesize_pc);
+            return ret / framesize_pc;
+        }
+
+        public long skip(long len) throws IOException {
+            long b_len = len * framesize_pc;
+            long ret = stream.skip(b_len);
+            if (ret == -1)
+                return -1;
+            return ret / framesize_pc;
+        }
+
+        public int available() throws IOException {
+            return stream.available() / framesize_pc;
+        }
+
+        public void close() throws IOException {
+            stream.close();
+        }
+
+        public void mark(int readlimit) {
+            stream.mark(readlimit * framesize_pc);
+        }
+
+        public boolean markSupported() {
+            return stream.markSupported();
+        }
+
+        public void reset() throws IOException {
+            stream.reset();
+        }
+    }
+
+    public static AudioFloatInputStream getInputStream(URL url)
+            throws UnsupportedAudioFileException, IOException {
+        return new DirectAudioFloatInputStream(AudioSystem
+                .getAudioInputStream(url));
+    }
+
+    public static AudioFloatInputStream getInputStream(File file)
+            throws UnsupportedAudioFileException, IOException {
+        return new DirectAudioFloatInputStream(AudioSystem
+                .getAudioInputStream(file));
+    }
+
+    public static AudioFloatInputStream getInputStream(InputStream stream)
+            throws UnsupportedAudioFileException, IOException {
+        return new DirectAudioFloatInputStream(AudioSystem
+                .getAudioInputStream(stream));
+    }
+
+    public static AudioFloatInputStream getInputStream(
+            AudioInputStream stream) {
+        return new DirectAudioFloatInputStream(stream);
+    }
+
+    public static AudioFloatInputStream getInputStream(AudioFormat format,
+            byte[] buffer, int offset, int len) {
+        AudioFloatConverter converter = AudioFloatConverter
+                .getConverter(format);
+        if (converter != null)
+            return new BytaArrayAudioFloatInputStream(converter, buffer,
+                    offset, len);
+
+        InputStream stream = new ByteArrayInputStream(buffer, offset, len);
+        long aLen = format.getFrameSize() == AudioSystem.NOT_SPECIFIED
+                ? AudioSystem.NOT_SPECIFIED : len / format.getFrameSize();
+        AudioInputStream astream = new AudioInputStream(stream, format, aLen);
+        return getInputStream(astream);
+    }
+
+    public abstract AudioFormat getFormat();
+
+    public abstract long getFrameLength();
+
+    public abstract int read(float[] b, int off, int len) throws IOException;
+
+    public int read(float[] b) throws IOException {
+        return read(b, 0, b.length);
+    }
+
+    public float read() throws IOException {
+        float[] b = new float[1];
+        int ret = read(b, 0, 1);
+        if (ret == -1 || ret == 0)
+            return 0;
+        return b[0];
+    }
+
+    public abstract long skip(long len) throws IOException;
+
+    public abstract int available() throws IOException;
+
+    public abstract void close() throws IOException;
+
+    public abstract void mark(int readlimit);
+
+    public abstract boolean markSupported();
+
+    public abstract void reset() throws IOException;
+}
diff --git a/jdk/src/share/classes/com/sun/media/sound/AudioSynthesizer.java b/jdk/src/share/classes/com/sun/media/sound/AudioSynthesizer.java
new file mode 100644
index 00000000000..247e03f04ab
--- /dev/null
+++ b/jdk/src/share/classes/com/sun/media/sound/AudioSynthesizer.java
@@ -0,0 +1,128 @@
+/*
+ * 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.  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
+ * 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.
+ */
+package com.sun.media.sound;
+
+import java.util.Map;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Synthesizer;
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.SourceDataLine;
+
+/**
+ * AudioSynthesizer is a Synthesizer
+ * which renders it's output audio into SourceDataLine
+ * or AudioInputStream.
+ *
+ * @see MidiSystem#getSynthesizer
+ * @see Synthesizer
+ *
+ * @author Karl Helgason
+ */
+public interface AudioSynthesizer extends Synthesizer {
+
+    /**
+     * Obtains the current format (encoding, sample rate, number of channels,
+     * etc.) of the synthesizer audio data.
+     *
+     * 

If the synthesizer is not open and has never been opened, it returns + * the default format. + * + * @return current audio data format + * @see AudioFormat + */ + public AudioFormat getFormat(); + + /** + * Gets information about the possible properties for the synthesizer. + * + * @param info a proposed list of tag/value pairs that will be sent on open. + * @return an array of AudioSynthesizerPropertyInfo objects + * describing possible properties. This array may be an empty array if + * no properties are required. + */ + public AudioSynthesizerPropertyInfo[] getPropertyInfo( + Map info); + + /** + * Opens the synthesizer and starts rendering audio into + * SourceDataLine. + * + *

An application opening a synthesizer explicitly with this call + * has to close the synthesizer by calling {@link #close}. This is + * necessary to release system resources and allow applications to + * exit cleanly. + * + *

Note that some synthesizers, once closed, cannot be reopened. + * Attempts to reopen such a synthesizer will always result in + * a MidiUnavailableException. + * + * @param line which AudioSynthesizer writes output audio into. + * If line is null, then line from system default mixer is used. + * @param info a Map object containing + * properties for additional configuration supported by synthesizer. + * If info is null then default settings are used. + * + * @throws MidiUnavailableException thrown if the synthesizer cannot be + * opened due to resource restrictions. + * @throws SecurityException thrown if the synthesizer cannot be + * opened due to security restrictions. + * + * @see #close + * @see #isOpen + */ + public void open(SourceDataLine line, Map info) + throws MidiUnavailableException; + + /** + * Opens the synthesizer and renders audio into returned + * AudioInputStream. + * + *

An application opening a synthesizer explicitly with this call + * has to close the synthesizer by calling {@link #close}. This is + * necessary to release system resources and allow applications to + * exit cleanly. + * + *

Note that some synthesizers, once closed, cannot be reopened. + * Attempts to reopen such a synthesizer will always result in + * a MidiUnavailableException. + * + * @param targetFormat specifies the AudioFormat + * used in returned AudioInputStream. + * @param info a Map object containing + * properties for additional configuration supported by synthesizer. + * If info is null then default settings are used. + * + * @throws MidiUnavailableException thrown if the synthesizer cannot be + * opened due to resource restrictions. + * @throws SecurityException thrown if the synthesizer cannot be + * opened due to security restrictions. + * + * @see #close + * @see #isOpen + */ + public AudioInputStream openStream(AudioFormat targetFormat, + Map info) throws MidiUnavailableException; +} diff --git a/jdk/src/share/classes/com/sun/media/sound/AudioSynthesizerPropertyInfo.java b/jdk/src/share/classes/com/sun/media/sound/AudioSynthesizerPropertyInfo.java new file mode 100644 index 00000000000..cf40dda256a --- /dev/null +++ b/jdk/src/share/classes/com/sun/media/sound/AudioSynthesizerPropertyInfo.java @@ -0,0 +1,76 @@ +/* + * 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. 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 + * 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. + */ +package com.sun.media.sound; + +/** + * Information about property used in opening AudioSynthesizer. + * + * @author Karl Helgason + */ +public class AudioSynthesizerPropertyInfo { + + /** + * Constructs a AudioSynthesizerPropertyInfo object with a given + * name and value. The description and choices + * are intialized by null values. + * + * @param name the name of the property + * @param value the current value or class used for values. + * + */ + public AudioSynthesizerPropertyInfo(String name, Object value) { + this.name = name; + this.value = value; + if (value instanceof Class) + valueClass = (Class)value; + else if (value != null) + valueClass = value.getClass(); + } + /** + * The name of the property. + */ + public String name; + /** + * A brief description of the property, which may be null. + */ + public String description = null; + /** + * The value field specifies the current value of + * the property. + */ + public Object value = null; + /** + * The valueClass field specifies class + * used in value field. + */ + public Class valueClass = null; + /** + * An array of possible values if the value for the field + * AudioSynthesizerPropertyInfo.value may be selected + * from a particular set of values; otherwise null. + */ + public Object[] choices = null; + +} diff --git a/jdk/src/share/classes/com/sun/media/sound/DLSInfo.java b/jdk/src/share/classes/com/sun/media/sound/DLSInfo.java new file mode 100644 index 00000000000..4e904216138 --- /dev/null +++ b/jdk/src/share/classes/com/sun/media/sound/DLSInfo.java @@ -0,0 +1,109 @@ +/* + * 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. 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 + * 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. + */ +package com.sun.media.sound; + +/** + * This class is used to store information to describe soundbanks, instruments + * and samples. It is stored inside a "INFO" List Chunk inside DLS files. + * + * @author Karl Helgason + */ +public class DLSInfo { + + /** + * (INAM) Title or subject. + */ + public String name = "untitled"; + /** + * (ICRD) Date of creation, the format is: YYYY-MM-DD. + * For example 2007-01-01 for 1. january of year 2007. + */ + public String creationDate = null; + /** + * (IENG) Name of engineer who created the object. + */ + public String engineers = null; + /** + * (IPRD) Name of the product which the object is intended for. + */ + public String product = null; + /** + * (ICOP) Copyright information. + */ + public String copyright = null; + /** + * (ICMT) General comments. Doesn't contain newline characters. + */ + public String comments = null; + /** + * (ISFT) Name of software package used to create the file. + */ + public String tools = null; + /** + * (IARL) Where content is archived. + */ + public String archival_location = null; + /** + * (IART) Artists of original content. + */ + public String artist = null; + /** + * (ICMS) Names of persons or orginizations who commissioned the file. + */ + public String commissioned = null; + /** + * (IGNR) Genre of the work. + * Example: jazz, classical, rock, etc. + */ + public String genre = null; + /** + * (IKEY) List of keyword that describe the content. + * Examples: FX, bird, piano, etc. + */ + public String keywords = null; + /** + * (IMED) Describes original medium of the data. + * For example: record, CD, etc. + */ + public String medium = null; + /** + * (ISBJ) Description of the content. + */ + public String subject = null; + /** + * (ISRC) Name of person or orginization who supplied + * orginal material for the file. + */ + public String source = null; + /** + * (ISRF) Source media for sample data is from. + * For example: CD, TV, etc. + */ + public String source_form = null; + /** + * (ITCH) Technician who sample the file/object. + */ + public String technician = null; +} diff --git a/jdk/src/share/classes/com/sun/media/sound/DLSInstrument.java b/jdk/src/share/classes/com/sun/media/sound/DLSInstrument.java new file mode 100644 index 00000000000..c4912314abb --- /dev/null +++ b/jdk/src/share/classes/com/sun/media/sound/DLSInstrument.java @@ -0,0 +1,448 @@ +/* + * 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. 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 + * 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. + */ +package com.sun.media.sound; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.sound.midi.Patch; + +/** + * This class is used to store information to describe instrument. + * It contains list of regions and modulators. + * It is stored inside a "ins " List Chunk inside DLS files. + * In the DLS documentation a modulator is called articulator. + * + * @author Karl Helgason + */ +public class DLSInstrument extends ModelInstrument { + + protected int preset = 0; + protected int bank = 0; + protected boolean druminstrument = false; + protected byte[] guid = null; + protected DLSInfo info = new DLSInfo(); + protected List regions = new ArrayList(); + protected List modulators = new ArrayList(); + + public DLSInstrument() { + super(null, null, null, null); + } + + public DLSInstrument(DLSSoundbank soundbank) { + super(soundbank, null, null, null); + } + + public DLSInfo getInfo() { + return info; + } + + public String getName() { + return info.name; + } + + public void setName(String name) { + info.name = name; + } + + public ModelPatch getPatch() { + return new ModelPatch(bank, preset, druminstrument); + } + + public void setPatch(Patch patch) { + if (patch instanceof ModelPatch && ((ModelPatch)patch).isPercussion()) { + druminstrument = true; + bank = patch.getBank(); + preset = patch.getProgram(); + } else { + druminstrument = false; + bank = patch.getBank(); + preset = patch.getProgram(); + } + } + + public Object getData() { + return null; + } + + public List getRegions() { + return regions; + } + + public List getModulators() { + return modulators; + } + + public String toString() { + if (druminstrument) + return "Drumkit: " + info.name + + " bank #" + bank + " preset #" + preset; + else + return "Instrument: " + info.name + + " bank #" + bank + " preset #" + preset; + } + + private ModelIdentifier convertToModelDest(int dest) { + if (dest == DLSModulator.CONN_DST_NONE) + return null; + if (dest == DLSModulator.CONN_DST_GAIN) + return ModelDestination.DESTINATION_GAIN; + if (dest == DLSModulator.CONN_DST_PITCH) + return ModelDestination.DESTINATION_PITCH; + if (dest == DLSModulator.CONN_DST_PAN) + return ModelDestination.DESTINATION_PAN; + + if (dest == DLSModulator.CONN_DST_LFO_FREQUENCY) + return ModelDestination.DESTINATION_LFO1_FREQ; + if (dest == DLSModulator.CONN_DST_LFO_STARTDELAY) + return ModelDestination.DESTINATION_LFO1_DELAY; + + if (dest == DLSModulator.CONN_DST_EG1_ATTACKTIME) + return ModelDestination.DESTINATION_EG1_ATTACK; + if (dest == DLSModulator.CONN_DST_EG1_DECAYTIME) + return ModelDestination.DESTINATION_EG1_DECAY; + if (dest == DLSModulator.CONN_DST_EG1_RELEASETIME) + return ModelDestination.DESTINATION_EG1_RELEASE; + if (dest == DLSModulator.CONN_DST_EG1_SUSTAINLEVEL) + return ModelDestination.DESTINATION_EG1_SUSTAIN; + + if (dest == DLSModulator.CONN_DST_EG2_ATTACKTIME) + return ModelDestination.DESTINATION_EG2_ATTACK; + if (dest == DLSModulator.CONN_DST_EG2_DECAYTIME) + return ModelDestination.DESTINATION_EG2_DECAY; + if (dest == DLSModulator.CONN_DST_EG2_RELEASETIME) + return ModelDestination.DESTINATION_EG2_RELEASE; + if (dest == DLSModulator.CONN_DST_EG2_SUSTAINLEVEL) + return ModelDestination.DESTINATION_EG2_SUSTAIN; + + // DLS2 Destinations + if (dest == DLSModulator.CONN_DST_KEYNUMBER) + return ModelDestination.DESTINATION_KEYNUMBER; + + if (dest == DLSModulator.CONN_DST_CHORUS) + return ModelDestination.DESTINATION_CHORUS; + if (dest == DLSModulator.CONN_DST_REVERB) + return ModelDestination.DESTINATION_REVERB; + + if (dest == DLSModulator.CONN_DST_VIB_FREQUENCY) + return ModelDestination.DESTINATION_LFO2_FREQ; + if (dest == DLSModulator.CONN_DST_VIB_STARTDELAY) + return ModelDestination.DESTINATION_LFO2_DELAY; + + if (dest == DLSModulator.CONN_DST_EG1_DELAYTIME) + return ModelDestination.DESTINATION_EG1_DELAY; + if (dest == DLSModulator.CONN_DST_EG1_HOLDTIME) + return ModelDestination.DESTINATION_EG1_HOLD; + if (dest == DLSModulator.CONN_DST_EG1_SHUTDOWNTIME) + return ModelDestination.DESTINATION_EG1_SHUTDOWN; + + if (dest == DLSModulator.CONN_DST_EG2_DELAYTIME) + return ModelDestination.DESTINATION_EG2_DELAY; + if (dest == DLSModulator.CONN_DST_EG2_HOLDTIME) + return ModelDestination.DESTINATION_EG2_HOLD; + + if (dest == DLSModulator.CONN_DST_FILTER_CUTOFF) + return ModelDestination.DESTINATION_FILTER_FREQ; + if (dest == DLSModulator.CONN_DST_FILTER_Q) + return ModelDestination.DESTINATION_FILTER_Q; + + return null; + } + + private ModelIdentifier convertToModelSrc(int src) { + if (src == DLSModulator.CONN_SRC_NONE) + return null; + + if (src == DLSModulator.CONN_SRC_LFO) + return ModelSource.SOURCE_LFO1; + if (src == DLSModulator.CONN_SRC_KEYONVELOCITY) + return ModelSource.SOURCE_NOTEON_VELOCITY; + if (src == DLSModulator.CONN_SRC_KEYNUMBER) + return ModelSource.SOURCE_NOTEON_KEYNUMBER; + if (src == DLSModulator.CONN_SRC_EG1) + return ModelSource.SOURCE_EG1; + if (src == DLSModulator.CONN_SRC_EG2) + return ModelSource.SOURCE_EG2; + if (src == DLSModulator.CONN_SRC_PITCHWHEEL) + return ModelSource.SOURCE_MIDI_PITCH; + if (src == DLSModulator.CONN_SRC_CC1) + return new ModelIdentifier("midi_cc", "1", 0); + if (src == DLSModulator.CONN_SRC_CC7) + return new ModelIdentifier("midi_cc", "7", 0); + if (src == DLSModulator.CONN_SRC_CC10) + return new ModelIdentifier("midi_cc", "10", 0); + if (src == DLSModulator.CONN_SRC_CC11) + return new ModelIdentifier("midi_cc", "11", 0); + if (src == DLSModulator.CONN_SRC_RPN0) + return new ModelIdentifier("midi_rpn", "0", 0); + if (src == DLSModulator.CONN_SRC_RPN1) + return new ModelIdentifier("midi_rpn", "1", 0); + + if (src == DLSModulator.CONN_SRC_POLYPRESSURE) + return ModelSource.SOURCE_MIDI_POLY_PRESSURE; + if (src == DLSModulator.CONN_SRC_CHANNELPRESSURE) + return ModelSource.SOURCE_MIDI_CHANNEL_PRESSURE; + if (src == DLSModulator.CONN_SRC_VIBRATO) + return ModelSource.SOURCE_LFO2; + if (src == DLSModulator.CONN_SRC_MONOPRESSURE) + return ModelSource.SOURCE_MIDI_CHANNEL_PRESSURE; + + if (src == DLSModulator.CONN_SRC_CC91) + return new ModelIdentifier("midi_cc", "91", 0); + if (src == DLSModulator.CONN_SRC_CC93) + return new ModelIdentifier("midi_cc", "93", 0); + + return null; + } + + private ModelConnectionBlock convertToModel(DLSModulator mod) { + ModelIdentifier source = convertToModelSrc(mod.getSource()); + ModelIdentifier control = convertToModelSrc(mod.getControl()); + ModelIdentifier destination_id = + convertToModelDest(mod.getDestination()); + + int scale = mod.getScale(); + double f_scale; + if (scale == Integer.MIN_VALUE) + f_scale = Double.NEGATIVE_INFINITY; + else + f_scale = scale / 65536.0; + + if (destination_id != null) { + ModelSource src = null; + ModelSource ctrl = null; + ModelConnectionBlock block = new ModelConnectionBlock(); + if (control != null) { + ModelSource s = new ModelSource(); + if (control == ModelSource.SOURCE_MIDI_PITCH) { + ((ModelStandardTransform)s.getTransform()).setPolarity( + ModelStandardTransform.POLARITY_BIPOLAR); + } else if (control == ModelSource.SOURCE_LFO1 + || control == ModelSource.SOURCE_LFO2) { + ((ModelStandardTransform)s.getTransform()).setPolarity( + ModelStandardTransform.POLARITY_BIPOLAR); + } + s.setIdentifier(control); + block.addSource(s); + ctrl = s; + } + if (source != null) { + ModelSource s = new ModelSource(); + if (source == ModelSource.SOURCE_MIDI_PITCH) { + ((ModelStandardTransform)s.getTransform()).setPolarity( + ModelStandardTransform.POLARITY_BIPOLAR); + } else if (source == ModelSource.SOURCE_LFO1 + || source == ModelSource.SOURCE_LFO2) { + ((ModelStandardTransform)s.getTransform()).setPolarity( + ModelStandardTransform.POLARITY_BIPOLAR); + } + s.setIdentifier(source); + block.addSource(s); + src = s; + } + ModelDestination destination = new ModelDestination(); + destination.setIdentifier(destination_id); + block.setDestination(destination); + + if (mod.getVersion() == 1) { + //if (mod.getTransform() == DLSModulator.CONN_TRN_CONCAVE) { + // ((ModelStandardTransform)destination.getTransform()) + // .setTransform( + // ModelStandardTransform.TRANSFORM_CONCAVE); + //} + if (mod.getTransform() == DLSModulator.CONN_TRN_CONCAVE) { + if (src != null) { + ((ModelStandardTransform)src.getTransform()) + .setTransform( + ModelStandardTransform.TRANSFORM_CONCAVE); + ((ModelStandardTransform)src.getTransform()) + .setDirection( + ModelStandardTransform.DIRECTION_MAX2MIN); + } + if (ctrl != null) { + ((ModelStandardTransform)ctrl.getTransform()) + .setTransform( + ModelStandardTransform.TRANSFORM_CONCAVE); + ((ModelStandardTransform)ctrl.getTransform()) + .setDirection( + ModelStandardTransform.DIRECTION_MAX2MIN); + } + } + + } else if (mod.getVersion() == 2) { + int transform = mod.getTransform(); + int src_transform_invert = (transform >> 15) & 1; + int src_transform_bipolar = (transform >> 14) & 1; + int src_transform = (transform >> 10) & 8; + int ctr_transform_invert = (transform >> 9) & 1; + int ctr_transform_bipolar = (transform >> 8) & 1; + int ctr_transform = (transform >> 4) & 8; + + + if (src != null) { + int trans = ModelStandardTransform.TRANSFORM_LINEAR; + if (src_transform == DLSModulator.CONN_TRN_SWITCH) + trans = ModelStandardTransform.TRANSFORM_SWITCH; + if (src_transform == DLSModulator.CONN_TRN_CONCAVE) + trans = ModelStandardTransform.TRANSFORM_CONCAVE; + if (src_transform == DLSModulator.CONN_TRN_CONVEX) + trans = ModelStandardTransform.TRANSFORM_CONVEX; + ((ModelStandardTransform)src.getTransform()) + .setTransform(trans); + ((ModelStandardTransform)src.getTransform()) + .setPolarity(src_transform_bipolar == 1); + ((ModelStandardTransform)src.getTransform()) + .setDirection(src_transform_invert == 1); + + } + + if (ctrl != null) { + int trans = ModelStandardTransform.TRANSFORM_LINEAR; + if (ctr_transform == DLSModulator.CONN_TRN_SWITCH) + trans = ModelStandardTransform.TRANSFORM_SWITCH; + if (ctr_transform == DLSModulator.CONN_TRN_CONCAVE) + trans = ModelStandardTransform.TRANSFORM_CONCAVE; + if (ctr_transform == DLSModulator.CONN_TRN_CONVEX) + trans = ModelStandardTransform.TRANSFORM_CONVEX; + ((ModelStandardTransform)ctrl.getTransform()) + .setTransform(trans); + ((ModelStandardTransform)ctrl.getTransform()) + .setPolarity(ctr_transform_bipolar == 1); + ((ModelStandardTransform)ctrl.getTransform()) + .setDirection(ctr_transform_invert == 1); + } + + /* No output transforms are defined the DLS Level 2 + int out_transform = transform % 8; + int trans = ModelStandardTransform.TRANSFORM_LINEAR; + if (out_transform == DLSModulator.CONN_TRN_SWITCH) + trans = ModelStandardTransform.TRANSFORM_SWITCH; + if (out_transform == DLSModulator.CONN_TRN_CONCAVE) + trans = ModelStandardTransform.TRANSFORM_CONCAVE; + if (out_transform == DLSModulator.CONN_TRN_CONVEX) + trans = ModelStandardTransform.TRANSFORM_CONVEX; + if (ctrl != null) { + ((ModelStandardTransform)destination.getTransform()) + .setTransform(trans); + } + */ + + } + + block.setScale(f_scale); + + return block; + } + + return null; + } + + public ModelPerformer[] getPerformers() { + List performers = new ArrayList(); + + Map modmap = new HashMap(); + for (DLSModulator mod: getModulators()) { + modmap.put(mod.getSource() + "x" + mod.getControl() + "=" + + mod.getDestination(), mod); + } + + Map insmodmap = + new HashMap(); + + for (DLSRegion zone: regions) { + ModelPerformer performer = new ModelPerformer(); + performer.setName(zone.getSample().getName()); + performer.setSelfNonExclusive((zone.getFusoptions() & + DLSRegion.OPTION_SELFNONEXCLUSIVE) != 0); + performer.setExclusiveClass(zone.getExclusiveClass()); + performer.setKeyFrom(zone.getKeyfrom()); + performer.setKeyTo(zone.getKeyto()); + performer.setVelFrom(zone.getVelfrom()); + performer.setVelTo(zone.getVelto()); + + insmodmap.clear(); + insmodmap.putAll(modmap); + for (DLSModulator mod: zone.getModulators()) { + insmodmap.put(mod.getSource() + "x" + mod.getControl() + "=" + + mod.getDestination(), mod); + } + + List blocks = performer.getConnectionBlocks(); + for (DLSModulator mod: insmodmap.values()) { + ModelConnectionBlock p = convertToModel(mod); + if (p != null) + blocks.add(p); + } + + + DLSSample sample = zone.getSample(); + DLSSampleOptions sampleopt = zone.getSampleoptions(); + if (sampleopt == null) + sampleopt = sample.getSampleoptions(); + + ModelByteBuffer buff = sample.getDataBuffer(); + + float pitchcorrection = (-sampleopt.unitynote * 100) + + sampleopt.finetune; + + ModelByteBufferWavetable osc = new ModelByteBufferWavetable(buff, + sample.getFormat(), pitchcorrection); + osc.setAttenuation(osc.getAttenuation() / 65536f); + if (sampleopt.getLoops().size() != 0) { + DLSSampleLoop loop = sampleopt.getLoops().get(0); + osc.setLoopStart((int)loop.getStart()); + osc.setLoopLength((int)loop.getLength()); + if (loop.getType() == DLSSampleLoop.LOOP_TYPE_FORWARD) + osc.setLoopType(ModelWavetable.LOOP_TYPE_FORWARD); + if (loop.getType() == DLSSampleLoop.LOOP_TYPE_RELEASE) + osc.setLoopType(ModelWavetable.LOOP_TYPE_RELEASE); + else + osc.setLoopType(ModelWavetable.LOOP_TYPE_FORWARD); + } + + performer.getConnectionBlocks().add( + new ModelConnectionBlock(SoftFilter.FILTERTYPE_LP12, + new ModelDestination( + new ModelIdentifier("filter", "type", 1)))); + + performer.getOscillators().add(osc); + + performers.add(performer); + + } + + return performers.toArray(new ModelPerformer[performers.size()]); + } + + public byte[] getGuid() { + return guid; + } + + public void setGuid(byte[] guid) { + this.guid = guid; + } +} diff --git a/jdk/src/share/classes/com/sun/media/sound/DLSModulator.java b/jdk/src/share/classes/com/sun/media/sound/DLSModulator.java new file mode 100644 index 00000000000..082454ea980 --- /dev/null +++ b/jdk/src/share/classes/com/sun/media/sound/DLSModulator.java @@ -0,0 +1,351 @@ +/* + * 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. 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 + * 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. + */ +package com.sun.media.sound; + +/** + * This class is used to store modulator/artiuclation data. + * A modulator connects one synthesizer source to + * a destination. For example a note on velocity + * can be mapped to the gain of the synthesized voice. + * It is stored as a "art1" or "art2" chunk inside DLS files. + * + * @author Karl Helgason + */ +public class DLSModulator { + + // DLS1 Destinations + public static final int CONN_DST_NONE = 0x000; // 0 + public static final int CONN_DST_GAIN = 0x001; // cB + public static final int CONN_DST_PITCH = 0x003; // cent + public static final int CONN_DST_PAN = 0x004; // 0.1% + public static final int CONN_DST_LFO_FREQUENCY = 0x104; // cent (default 5 Hz) + public static final int CONN_DST_LFO_STARTDELAY = 0x105; // timecent + public static final int CONN_DST_EG1_ATTACKTIME = 0x206; // timecent + public static final int CONN_DST_EG1_DECAYTIME = 0x207; // timecent + public static final int CONN_DST_EG1_RELEASETIME = 0x209; // timecent + public static final int CONN_DST_EG1_SUSTAINLEVEL = 0x20A; // 0.1% + public static final int CONN_DST_EG2_ATTACKTIME = 0x30A; // timecent + public static final int CONN_DST_EG2_DECAYTIME = 0x30B; // timecent + public static final int CONN_DST_EG2_RELEASETIME = 0x30D; // timecent + public static final int CONN_DST_EG2_SUSTAINLEVEL = 0x30E; // 0.1% + // DLS2 Destinations + public static final int CONN_DST_KEYNUMBER = 0x005; + public static final int CONN_DST_LEFT = 0x010; // 0.1% + public static final int CONN_DST_RIGHT = 0x011; // 0.1% + public static final int CONN_DST_CENTER = 0x012; // 0.1% + public static final int CONN_DST_LEFTREAR = 0x013; // 0.1% + public static final int CONN_DST_RIGHTREAR = 0x014; // 0.1% + public static final int CONN_DST_LFE_CHANNEL = 0x015; // 0.1% + public static final int CONN_DST_CHORUS = 0x080; // 0.1% + public static final int CONN_DST_REVERB = 0x081; // 0.1% + public static final int CONN_DST_VIB_FREQUENCY = 0x114; // cent + public static final int CONN_DST_VIB_STARTDELAY = 0x115; // dB + public static final int CONN_DST_EG1_DELAYTIME = 0x20B; // timecent + public static final int CONN_DST_EG1_HOLDTIME = 0x20C; // timecent + public static final int CONN_DST_EG1_SHUTDOWNTIME = 0x20D; // timecent + public static final int CONN_DST_EG2_DELAYTIME = 0x30F; // timecent + public static final int CONN_DST_EG2_HOLDTIME = 0x310; // timecent + public static final int CONN_DST_FILTER_CUTOFF = 0x500; // cent + public static final int CONN_DST_FILTER_Q = 0x501; // dB + + // DLS1 Sources + public static final int CONN_SRC_NONE = 0x000; // 1 + public static final int CONN_SRC_LFO = 0x001; // linear (sine wave) + public static final int CONN_SRC_KEYONVELOCITY = 0x002; // ??db or velocity?? + public static final int CONN_SRC_KEYNUMBER = 0x003; // ??cent or keynumber?? + public static final int CONN_SRC_EG1 = 0x004; // linear direct from eg + public static final int CONN_SRC_EG2 = 0x005; // linear direct from eg + public static final int CONN_SRC_PITCHWHEEL = 0x006; // linear -1..1 + public static final int CONN_SRC_CC1 = 0x081; // linear 0..1 + public static final int CONN_SRC_CC7 = 0x087; // linear 0..1 + public static final int CONN_SRC_CC10 = 0x08A; // linear 0..1 + public static final int CONN_SRC_CC11 = 0x08B; // linear 0..1 + public static final int CONN_SRC_RPN0 = 0x100; // ?? // Pitch Bend Range + public static final int CONN_SRC_RPN1 = 0x101; // ?? // Fine Tune + public static final int CONN_SRC_RPN2 = 0x102; // ?? // Course Tune + // DLS2 Sources + public static final int CONN_SRC_POLYPRESSURE = 0x007; // linear 0..1 + public static final int CONN_SRC_CHANNELPRESSURE = 0x008; // linear 0..1 + public static final int CONN_SRC_VIBRATO = 0x009; // linear 0..1 + public static final int CONN_SRC_MONOPRESSURE = 0x00A; // linear 0..1 + public static final int CONN_SRC_CC91 = 0x0DB; // linear 0..1 + public static final int CONN_SRC_CC93 = 0x0DD; // linear 0..1 + // DLS1 Transforms + public static final int CONN_TRN_NONE = 0x000; + public static final int CONN_TRN_CONCAVE = 0x001; + // DLS2 Transforms + public static final int CONN_TRN_CONVEX = 0x002; + public static final int CONN_TRN_SWITCH = 0x003; + public static final int DST_FORMAT_CB = 1; + public static final int DST_FORMAT_CENT = 1; + public static final int DST_FORMAT_TIMECENT = 2; + public static final int DST_FORMAT_PERCENT = 3; + protected int source; + protected int control; + protected int destination; + protected int transform; + protected int scale; + protected int version = 1; + + public int getControl() { + return control; + } + + public void setControl(int control) { + this.control = control; + } + + public static int getDestinationFormat(int destination) { + + if (destination == CONN_DST_GAIN) + return DST_FORMAT_CB; + if (destination == CONN_DST_PITCH) + return DST_FORMAT_CENT; + if (destination == CONN_DST_PAN) + return DST_FORMAT_PERCENT; + + if (destination == CONN_DST_LFO_FREQUENCY) + return DST_FORMAT_CENT; + if (destination == CONN_DST_LFO_STARTDELAY) + return DST_FORMAT_TIMECENT; + + if (destination == CONN_DST_EG1_ATTACKTIME) + return DST_FORMAT_TIMECENT; + if (destination == CONN_DST_EG1_DECAYTIME) + return DST_FORMAT_TIMECENT; + if (destination == CONN_DST_EG1_RELEASETIME) + return DST_FORMAT_TIMECENT; + if (destination == CONN_DST_EG1_SUSTAINLEVEL) + return DST_FORMAT_PERCENT; + + if (destination == CONN_DST_EG2_ATTACKTIME) + return DST_FORMAT_TIMECENT; + if (destination == CONN_DST_EG2_DECAYTIME) + return DST_FORMAT_TIMECENT; + if (destination == CONN_DST_EG2_RELEASETIME) + return DST_FORMAT_TIMECENT; + if (destination == CONN_DST_EG2_SUSTAINLEVEL) + return DST_FORMAT_PERCENT; + + if (destination == CONN_DST_KEYNUMBER) + return DST_FORMAT_CENT; // NOT SURE WITHOUT DLS 2 SPEC + if (destination == CONN_DST_LEFT) + return DST_FORMAT_CB; + if (destination == CONN_DST_RIGHT) + return DST_FORMAT_CB; + if (destination == CONN_DST_CENTER) + return DST_FORMAT_CB; + if (destination == CONN_DST_LEFTREAR) + return DST_FORMAT_CB; + if (destination == CONN_DST_RIGHTREAR) + return DST_FORMAT_CB; + if (destination == CONN_DST_LFE_CHANNEL) + return DST_FORMAT_CB; + if (destination == CONN_DST_CHORUS) + return DST_FORMAT_PERCENT; + if (destination == CONN_DST_REVERB) + return DST_FORMAT_PERCENT; + + if (destination == CONN_DST_VIB_FREQUENCY) + return DST_FORMAT_CENT; + if (destination == CONN_DST_VIB_STARTDELAY) + return DST_FORMAT_TIMECENT; + + if (destination == CONN_DST_EG1_DELAYTIME) + return DST_FORMAT_TIMECENT; + if (destination == CONN_DST_EG1_HOLDTIME) + return DST_FORMAT_TIMECENT; + if (destination == CONN_DST_EG1_SHUTDOWNTIME) + return DST_FORMAT_TIMECENT; + + if (destination == CONN_DST_EG2_DELAYTIME) + return DST_FORMAT_TIMECENT; + if (destination == CONN_DST_EG2_HOLDTIME) + return DST_FORMAT_TIMECENT; + + if (destination == CONN_DST_FILTER_CUTOFF) + return DST_FORMAT_CENT; + if (destination == CONN_DST_FILTER_Q) + return DST_FORMAT_CB; + + return -1; + } + + public static String getDestinationName(int destination) { + + if (destination == CONN_DST_GAIN) + return "gain"; + if (destination == CONN_DST_PITCH) + return "pitch"; + if (destination == CONN_DST_PAN) + return "pan"; + + if (destination == CONN_DST_LFO_FREQUENCY) + return "lfo1.freq"; + if (destination == CONN_DST_LFO_STARTDELAY) + return "lfo1.delay"; + + if (destination == CONN_DST_EG1_ATTACKTIME) + return "eg1.attack"; + if (destination == CONN_DST_EG1_DECAYTIME) + return "eg1.decay"; + if (destination == CONN_DST_EG1_RELEASETIME) + return "eg1.release"; + if (destination == CONN_DST_EG1_SUSTAINLEVEL) + return "eg1.sustain"; + + if (destination == CONN_DST_EG2_ATTACKTIME) + return "eg2.attack"; + if (destination == CONN_DST_EG2_DECAYTIME) + return "eg2.decay"; + if (destination == CONN_DST_EG2_RELEASETIME) + return "eg2.release"; + if (destination == CONN_DST_EG2_SUSTAINLEVEL) + return "eg2.sustain"; + + if (destination == CONN_DST_KEYNUMBER) + return "keynumber"; + if (destination == CONN_DST_LEFT) + return "left"; + if (destination == CONN_DST_RIGHT) + return "right"; + if (destination == CONN_DST_CENTER) + return "center"; + if (destination == CONN_DST_LEFTREAR) + return "leftrear"; + if (destination == CONN_DST_RIGHTREAR) + return "rightrear"; + if (destination == CONN_DST_LFE_CHANNEL) + return "lfe_channel"; + if (destination == CONN_DST_CHORUS) + return "chorus"; + if (destination == CONN_DST_REVERB) + return "reverb"; + + if (destination == CONN_DST_VIB_FREQUENCY) + return "vib.freq"; + if (destination == CONN_DST_VIB_STARTDELAY) + return "vib.delay"; + + if (destination == CONN_DST_EG1_DELAYTIME) + return "eg1.delay"; + if (destination == CONN_DST_EG1_HOLDTIME) + return "eg1.hold"; + if (destination == CONN_DST_EG1_SHUTDOWNTIME) + return "eg1.shutdown"; + + if (destination == CONN_DST_EG2_DELAYTIME) + return "eg2.delay"; + if (destination == CONN_DST_EG2_HOLDTIME) + return "eg.2hold"; + + if (destination == CONN_DST_FILTER_CUTOFF) + return "filter.cutoff"; // NOT SURE WITHOUT DLS 2 SPEC + if (destination == CONN_DST_FILTER_Q) + return "filter.q"; // NOT SURE WITHOUT DLS 2 SPEC + + return null; + } + + public static String getSourceName(int source) { + + if (source == CONN_SRC_NONE) + return "none"; + if (source == CONN_SRC_LFO) + return "lfo"; + if (source == CONN_SRC_KEYONVELOCITY) + return "keyonvelocity"; + if (source == CONN_SRC_KEYNUMBER) + return "keynumber"; + if (source == CONN_SRC_EG1) + return "eg1"; + if (source == CONN_SRC_EG2) + return "eg2"; + if (source == CONN_SRC_PITCHWHEEL) + return "pitchweel"; + if (source == CONN_SRC_CC1) + return "cc1"; + if (source == CONN_SRC_CC7) + return "cc7"; + if (source == CONN_SRC_CC10) + return "c10"; + if (source == CONN_SRC_CC11) + return "cc11"; + + if (source == CONN_SRC_POLYPRESSURE) + return "polypressure"; + if (source == CONN_SRC_CHANNELPRESSURE) + return "channelpressure"; + if (source == CONN_SRC_VIBRATO) + return "vibrato"; + if (source == CONN_SRC_MONOPRESSURE) + return "monopressure"; + if (source == CONN_SRC_CC91) + return "cc91"; + if (source == CONN_SRC_CC93) + return "cc93"; + return null; + } + + public int getDestination() { + return destination; + } + + public void setDestination(int destination) { + this.destination = destination; + } + + public int getScale() { + return scale; + } + + public void setScale(int scale) { + this.scale = scale; + } + + public int getSource() { + return source; + } + + public void setSource(int source) { + this.source = source; + } + + public int getVersion() { + return version; + } + + public void setVersion(int version) { + this.version = version; + } + + public int getTransform() { + return transform; + } + + public void setTransform(int transform) { + this.transform = transform; + } +} diff --git a/jdk/src/share/classes/com/sun/media/sound/DLSRegion.java b/jdk/src/share/classes/com/sun/media/sound/DLSRegion.java new file mode 100644 index 00000000000..17e57a3b3cf --- /dev/null +++ b/jdk/src/share/classes/com/sun/media/sound/DLSRegion.java @@ -0,0 +1,150 @@ +/* + * 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. 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 + * 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. + */ +package com.sun.media.sound; + +import java.util.ArrayList; +import java.util.List; + +/** + * This class is used to store region parts for instrument. + * A region has a velocity and key range which it response to. + * And it has a list of modulators/articulators which + * is used how to synthesize a single voice. + * It is stored inside a "rgn " List Chunk inside DLS files. + * + * @author Karl Helgason + */ +public class DLSRegion { + + public final static int OPTION_SELFNONEXCLUSIVE = 0x0001; + protected List modulators = new ArrayList(); + protected int keyfrom; + protected int keyto; + protected int velfrom; + protected int velto; + protected int options; + protected int exclusiveClass; + protected int fusoptions; + protected int phasegroup; + protected long channel; + protected DLSSample sample = null; + protected DLSSampleOptions sampleoptions; + + public List getModulators() { + return modulators; + } + + public long getChannel() { + return channel; + } + + public void setChannel(long channel) { + this.channel = channel; + } + + public int getExclusiveClass() { + return exclusiveClass; + } + + public void setExclusiveClass(int exclusiveClass) { + this.exclusiveClass = exclusiveClass; + } + + public int getFusoptions() { + return fusoptions; + } + + public void setFusoptions(int fusoptions) { + this.fusoptions = fusoptions; + } + + public int getKeyfrom() { + return keyfrom; + } + + public void setKeyfrom(int keyfrom) { + this.keyfrom = keyfrom; + } + + public int getKeyto() { + return keyto; + } + + public void setKeyto(int keyto) { + this.keyto = keyto; + } + + public int getOptions() { + return options; + } + + public void setOptions(int options) { + this.options = options; + } + + public int getPhasegroup() { + return phasegroup; + } + + public void setPhasegroup(int phasegroup) { + this.phasegroup = phasegroup; + } + + public DLSSample getSample() { + return sample; + } + + public void setSample(DLSSample sample) { + this.sample = sample; + } + + public int getVelfrom() { + return velfrom; + } + + public void setVelfrom(int velfrom) { + this.velfrom = velfrom; + } + + public int getVelto() { + return velto; + } + + public void setVelto(int velto) { + this.velto = velto; + } + + public void setModulators(List modulators) { + this.modulators = modulators; + } + + public DLSSampleOptions getSampleoptions() { + return sampleoptions; + } + + public void setSampleoptions(DLSSampleOptions sampleOptions) { + this.sampleoptions = sampleOptions; + } +} diff --git a/jdk/src/share/classes/com/sun/media/sound/DLSSample.java b/jdk/src/share/classes/com/sun/media/sound/DLSSample.java new file mode 100644 index 00000000000..b75b2a9a94c --- /dev/null +++ b/jdk/src/share/classes/com/sun/media/sound/DLSSample.java @@ -0,0 +1,122 @@ +/* + * 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. 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 + * 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. + */ +package com.sun.media.sound; + +import java.io.InputStream; +import javax.sound.midi.Soundbank; +import javax.sound.midi.SoundbankResource; +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; + +/** + * This class is used to store the sample data itself. + * A sample is encoded as PCM audio stream + * and in DLS Level 1 files it is always a mono 8/16 bit stream. + * They are stored just like RIFF WAVE files are stored. + * It is stored inside a "wave" List Chunk inside DLS files. + * + * @author Karl Helgason + */ +public class DLSSample extends SoundbankResource { + + protected byte[] guid = null; + protected DLSInfo info = new DLSInfo(); + protected DLSSampleOptions sampleoptions; + protected ModelByteBuffer data; + protected AudioFormat format; + + public DLSSample(Soundbank soundBank) { + super(soundBank, null, AudioInputStream.class); + } + + public DLSSample() { + super(null, null, AudioInputStream.class); + } + + public DLSInfo getInfo() { + return info; + } + + public Object getData() { + AudioFormat format = getFormat(); + + InputStream is = data.getInputStream(); + if (is == null) + return null; + return new AudioInputStream(is, format, data.capacity()); + } + + public ModelByteBuffer getDataBuffer() { + return data; + } + + public AudioFormat getFormat() { + return format; + } + + public void setFormat(AudioFormat format) { + this.format = format; + } + + public void setData(ModelByteBuffer data) { + this.data = data; + } + + public void setData(byte[] data) { + this.data = new ModelByteBuffer(data); + } + + public void setData(byte[] data, int offset, int length) { + this.data = new ModelByteBuffer(data, offset, length); + } + + public String getName() { + return info.name; + } + + public void setName(String name) { + info.name = name; + } + + public DLSSampleOptions getSampleoptions() { + return sampleoptions; + } + + public void setSampleoptions(DLSSampleOptions sampleOptions) { + this.sampleoptions = sampleOptions; + } + + public String toString() { + return "Sample: " + info.name; + } + + public byte[] getGuid() { + return guid; + } + + public void setGuid(byte[] guid) { + this.guid = guid; + } +} diff --git a/jdk/src/share/classes/com/sun/media/sound/DLSSampleLoop.java b/jdk/src/share/classes/com/sun/media/sound/DLSSampleLoop.java new file mode 100644 index 00000000000..ee78d64fce0 --- /dev/null +++ b/jdk/src/share/classes/com/sun/media/sound/DLSSampleLoop.java @@ -0,0 +1,63 @@ +/* + * 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. 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 + * 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. + */ +package com.sun.media.sound; + +/** + * This class is used to store loop points inside DLSSampleOptions class. + * + * @author Karl Helgason + */ +public class DLSSampleLoop { + + public final static int LOOP_TYPE_FORWARD = 0; + public final static int LOOP_TYPE_RELEASE = 1; + protected long type; + protected long start; + protected long length; + + public long getLength() { + return length; + } + + public void setLength(long length) { + this.length = length; + } + + public long getStart() { + return start; + } + + public void setStart(long start) { + this.start = start; + } + + public long getType() { + return type; + } + + public void setType(long type) { + this.type = type; + } +} diff --git a/jdk/src/share/classes/com/sun/media/sound/DLSSampleOptions.java b/jdk/src/share/classes/com/sun/media/sound/DLSSampleOptions.java new file mode 100644 index 00000000000..849644b6cc7 --- /dev/null +++ b/jdk/src/share/classes/com/sun/media/sound/DLSSampleOptions.java @@ -0,0 +1,80 @@ +/* + * 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. 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 + * 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. + */ +package com.sun.media.sound; + +import java.util.ArrayList; +import java.util.List; + +/** + * This class stores options how to playback sampled data like pitch/tuning, + * attenuation and loops. + * It is stored as a "wsmp" chunk inside DLS files. + * + * @author Karl Helgason + */ +public class DLSSampleOptions { + + protected int unitynote; + protected short finetune; + protected int attenuation; + protected long options; + protected List loops = new ArrayList(); + + public int getAttenuation() { + return attenuation; + } + + public void setAttenuation(int attenuation) { + this.attenuation = attenuation; + } + + public short getFinetune() { + return finetune; + } + + public void setFinetune(short finetune) { + this.finetune = finetune; + } + + public List getLoops() { + return loops; + } + + public long getOptions() { + return options; + } + + public void setOptions(long options) { + this.options = options; + } + + public int getUnitynote() { + return unitynote; + } + + public void setUnitynote(int unitynote) { + this.unitynote = unitynote; + } +} diff --git a/jdk/src/share/classes/com/sun/media/sound/DLSSoundbank.java b/jdk/src/share/classes/com/sun/media/sound/DLSSoundbank.java new file mode 100644 index 00000000000..027fa75b472 --- /dev/null +++ b/jdk/src/share/classes/com/sun/media/sound/DLSSoundbank.java @@ -0,0 +1,1287 @@ +/* + * 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. 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 + * 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. + */ +package com.sun.media.sound; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Stack; + +import javax.sound.midi.Instrument; +import javax.sound.midi.Patch; +import javax.sound.midi.Soundbank; +import javax.sound.midi.SoundbankResource; +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.AudioFormat.Encoding; + +/** + * A DLS Level 1 and Level 2 soundbank reader (from files/url/streams). + * + * @author Karl Helgason + */ +public class DLSSoundbank implements Soundbank { + + static private class DLSID { + long i1; + int s1; + int s2; + int x1; + int x2; + int x3; + int x4; + int x5; + int x6; + int x7; + int x8; + + private DLSID() { + } + + public DLSID(long i1, int s1, int s2, int x1, int x2, int x3, int x4, + int x5, int x6, int x7, int x8) { + this.i1 = i1; + this.s1 = s1; + this.s2 = s2; + this.x1 = x1; + this.x2 = x2; + this.x3 = x3; + this.x4 = x4; + this.x5 = x5; + this.x6 = x6; + this.x7 = x7; + this.x8 = x8; + } + + public static DLSID read(RIFFReader riff) throws IOException { + DLSID d = new DLSID(); + d.i1 = riff.readUnsignedInt(); + d.s1 = riff.readUnsignedShort(); + d.s2 = riff.readUnsignedShort(); + d.x1 = riff.readUnsignedByte(); + d.x2 = riff.readUnsignedByte(); + d.x3 = riff.readUnsignedByte(); + d.x4 = riff.readUnsignedByte(); + d.x5 = riff.readUnsignedByte(); + d.x6 = riff.readUnsignedByte(); + d.x7 = riff.readUnsignedByte(); + d.x8 = riff.readUnsignedByte(); + return d; + } + + public int hashCode() { + return (int)i1; + } + + public boolean equals(Object obj) { + if (!(obj instanceof DLSID)) { + return false; + } + DLSID t = (DLSID) obj; + return i1 == t.i1 && s1 == t.s1 && s2 == t.s2 + && x1 == t.x1 && x2 == t.x2 && x3 == t.x3 && x4 == t.x4 + && x5 == t.x5 && x6 == t.x6 && x7 == t.x7 && x8 == t.x8; + } + } + + /** X = X & Y */ + private static final int DLS_CDL_AND = 0x0001; + /** X = X | Y */ + private static final int DLS_CDL_OR = 0x0002; + /** X = X ^ Y */ + private static final int DLS_CDL_XOR = 0x0003; + /** X = X + Y */ + private static final int DLS_CDL_ADD = 0x0004; + /** X = X - Y */ + private static final int DLS_CDL_SUBTRACT = 0x0005; + /** X = X * Y */ + private static final int DLS_CDL_MULTIPLY = 0x0006; + /** X = X / Y */ + private static final int DLS_CDL_DIVIDE = 0x0007; + /** X = X && Y */ + private static final int DLS_CDL_LOGICAL_AND = 0x0008; + /** X = X || Y */ + private static final int DLS_CDL_LOGICAL_OR = 0x0009; + /** X = (X < Y) */ + private static final int DLS_CDL_LT = 0x000A; + /** X = (X <= Y) */ + private static final int DLS_CDL_LE = 0x000B; + /** X = (X > Y) */ + private static final int DLS_CDL_GT = 0x000C; + /** X = (X >= Y) */ + private static final int DLS_CDL_GE = 0x000D; + /** X = (X == Y) */ + private static final int DLS_CDL_EQ = 0x000E; + /** X = !X */ + private static final int DLS_CDL_NOT = 0x000F; + /** 32-bit constant */ + private static final int DLS_CDL_CONST = 0x0010; + /** 32-bit value returned from query */ + private static final int DLS_CDL_QUERY = 0x0011; + /** 32-bit value returned from query */ + private static final int DLS_CDL_QUERYSUPPORTED = 0x0012; + + private static final DLSID DLSID_GMInHardware = new DLSID(0x178f2f24, + 0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12); + private static final DLSID DLSID_GSInHardware = new DLSID(0x178f2f25, + 0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12); + private static final DLSID DLSID_XGInHardware = new DLSID(0x178f2f26, + 0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12); + private static final DLSID DLSID_SupportsDLS1 = new DLSID(0x178f2f27, + 0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12); + private static final DLSID DLSID_SupportsDLS2 = new DLSID(0xf14599e5, + 0x4689, 0x11d2, 0xaf, 0xa6, 0x0, 0xaa, 0x0, 0x24, 0xd8, 0xb6); + private static final DLSID DLSID_SampleMemorySize = new DLSID(0x178f2f28, + 0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12); + private static final DLSID DLSID_ManufacturersID = new DLSID(0xb03e1181, + 0x8095, 0x11d2, 0xa1, 0xef, 0x0, 0x60, 0x8, 0x33, 0xdb, 0xd8); + private static final DLSID DLSID_ProductID = new DLSID(0xb03e1182, + 0x8095, 0x11d2, 0xa1, 0xef, 0x0, 0x60, 0x8, 0x33, 0xdb, 0xd8); + private static final DLSID DLSID_SamplePlaybackRate = new DLSID(0x2a91f713, + 0xa4bf, 0x11d2, 0xbb, 0xdf, 0x0, 0x60, 0x8, 0x33, 0xdb, 0xd8); + + private long major = -1; + private long minor = -1; + + private DLSInfo info = new DLSInfo(); + + private List instruments = new ArrayList(); + private List samples = new ArrayList(); + + private boolean largeFormat = false; + private File sampleFile; + + public DLSSoundbank() { + } + + public DLSSoundbank(URL url) throws IOException { + InputStream is = url.openStream(); + try { + readSoundbank(is); + } finally { + is.close(); + } + } + + public DLSSoundbank(File file) throws IOException { + largeFormat = true; + sampleFile = file; + InputStream is = new FileInputStream(file); + try { + readSoundbank(is); + } finally { + is.close(); + } + } + + public DLSSoundbank(InputStream inputstream) throws IOException { + readSoundbank(inputstream); + } + + private void readSoundbank(InputStream inputstream) throws IOException { + RIFFReader riff = new RIFFReader(inputstream); + if (!riff.getFormat().equals("RIFF")) { + throw new RIFFInvalidFormatException( + "Input stream is not a valid RIFF stream!"); + } + if (!riff.getType().equals("DLS ")) { + throw new RIFFInvalidFormatException( + "Input stream is not a valid DLS soundbank!"); + } + while (riff.hasNextChunk()) { + RIFFReader chunk = riff.nextChunk(); + if (chunk.getFormat().equals("LIST")) { + if (chunk.getType().equals("INFO")) + readInfoChunk(chunk); + if (chunk.getType().equals("lins")) + readLinsChunk(chunk); + if (chunk.getType().equals("wvpl")) + readWvplChunk(chunk); + } else { + if (chunk.getFormat().equals("cdl ")) { + if (!readCdlChunk(chunk)) { + throw new RIFFInvalidFormatException( + "DLS file isn't supported!"); + } + } + if (chunk.getFormat().equals("colh")) { + // skipped because we will load the entire bank into memory + // long instrumentcount = chunk.readUnsignedInt(); + // System.out.println("instrumentcount = "+ instrumentcount); + } + if (chunk.getFormat().equals("ptbl")) { + // Pool Table Chunk + // skipped because we will load the entire bank into memory + } + if (chunk.getFormat().equals("vers")) { + major = chunk.readUnsignedInt(); + minor = chunk.readUnsignedInt(); + } + } + } + + for (Map.Entry entry : temp_rgnassign.entrySet()) { + entry.getKey().sample = samples.get((int)entry.getValue().longValue()); + } + + temp_rgnassign = null; + } + + private boolean cdlIsQuerySupported(DLSID uuid) { + return uuid.equals(DLSID_GMInHardware) + || uuid.equals(DLSID_GSInHardware) + || uuid.equals(DLSID_XGInHardware) + || uuid.equals(DLSID_SupportsDLS1) + || uuid.equals(DLSID_SupportsDLS2) + || uuid.equals(DLSID_SampleMemorySize) + || uuid.equals(DLSID_ManufacturersID) + || uuid.equals(DLSID_ProductID) + || uuid.equals(DLSID_SamplePlaybackRate); + } + + private long cdlQuery(DLSID uuid) { + if (uuid.equals(DLSID_GMInHardware)) + return 1; + if (uuid.equals(DLSID_GSInHardware)) + return 0; + if (uuid.equals(DLSID_XGInHardware)) + return 0; + if (uuid.equals(DLSID_SupportsDLS1)) + return 1; + if (uuid.equals(DLSID_SupportsDLS2)) + return 1; + if (uuid.equals(DLSID_SampleMemorySize)) + return Runtime.getRuntime().totalMemory(); + if (uuid.equals(DLSID_ManufacturersID)) + return 0; + if (uuid.equals(DLSID_ProductID)) + return 0; + if (uuid.equals(DLSID_SamplePlaybackRate)) + return 44100; + return 0; + } + + + // Reading cdl-ck Chunk + // "cdl " chunk can only appear inside : DLS,lart,lar2,rgn,rgn2 + private boolean readCdlChunk(RIFFReader riff) throws IOException { + + DLSID uuid; + long x; + long y; + Stack stack = new Stack(); + + while (riff.available() != 0) { + int opcode = riff.readUnsignedShort(); + switch (opcode) { + case DLS_CDL_AND: + x = stack.pop(); + y = stack.pop(); + stack.push(Long.valueOf(((x != 0) && (y != 0)) ? 1 : 0)); + break; + case DLS_CDL_OR: + x = stack.pop(); + y = stack.pop(); + stack.push(Long.valueOf(((x != 0) || (y != 0)) ? 1 : 0)); + break; + case DLS_CDL_XOR: + x = stack.pop(); + y = stack.pop(); + stack.push(Long.valueOf(((x != 0) ^ (y != 0)) ? 1 : 0)); + break; + case DLS_CDL_ADD: + x = stack.pop(); + y = stack.pop(); + stack.push(Long.valueOf(x + y)); + break; + case DLS_CDL_SUBTRACT: + x = stack.pop(); + y = stack.pop(); + stack.push(Long.valueOf(x - y)); + break; + case DLS_CDL_MULTIPLY: + x = stack.pop(); + y = stack.pop(); + stack.push(Long.valueOf(x * y)); + break; + case DLS_CDL_DIVIDE: + x = stack.pop(); + y = stack.pop(); + stack.push(Long.valueOf(x / y)); + break; + case DLS_CDL_LOGICAL_AND: + x = stack.pop(); + y = stack.pop(); + stack.push(Long.valueOf(((x != 0) && (y != 0)) ? 1 : 0)); + break; + case DLS_CDL_LOGICAL_OR: + x = stack.pop(); + y = stack.pop(); + stack.push(Long.valueOf(((x != 0) || (y != 0)) ? 1 : 0)); + break; + case DLS_CDL_LT: + x = stack.pop(); + y = stack.pop(); + stack.push(Long.valueOf((x < y) ? 1 : 0)); + break; + case DLS_CDL_LE: + x = stack.pop(); + y = stack.pop(); + stack.push(Long.valueOf((x <= y) ? 1 : 0)); + break; + case DLS_CDL_GT: + x = stack.pop(); + y = stack.pop(); + stack.push(Long.valueOf((x > y) ? 1 : 0)); + break; + case DLS_CDL_GE: + x = stack.pop(); + y = stack.pop(); + stack.push(Long.valueOf((x >= y) ? 1 : 0)); + break; + case DLS_CDL_EQ: + x = stack.pop(); + y = stack.pop(); + stack.push(Long.valueOf((x == y) ? 1 : 0)); + break; + case DLS_CDL_NOT: + x = stack.pop(); + y = stack.pop(); + stack.push(Long.valueOf((x == 0) ? 1 : 0)); + break; + case DLS_CDL_CONST: + stack.push(Long.valueOf(riff.readUnsignedInt())); + break; + case DLS_CDL_QUERY: + uuid = DLSID.read(riff); + stack.push(cdlQuery(uuid)); + break; + case DLS_CDL_QUERYSUPPORTED: + uuid = DLSID.read(riff); + stack.push(Long.valueOf(cdlIsQuerySupported(uuid) ? 1 : 0)); + break; + default: + break; + } + } + if (stack.isEmpty()) + return false; + + return stack.pop() == 1; + } + + private void readInfoChunk(RIFFReader riff) throws IOException { + info.name = null; + while (riff.hasNextChunk()) { + RIFFReader chunk = riff.nextChunk(); + String format = chunk.getFormat(); + if (format.equals("INAM")) + info.name = chunk.readString(chunk.available()); + else if (format.equals("ICRD")) + info.creationDate = chunk.readString(chunk.available()); + else if (format.equals("IENG")) + info.engineers = chunk.readString(chunk.available()); + else if (format.equals("IPRD")) + info.product = chunk.readString(chunk.available()); + else if (format.equals("ICOP")) + info.copyright = chunk.readString(chunk.available()); + else if (format.equals("ICMT")) + info.comments = chunk.readString(chunk.available()); + else if (format.equals("ISFT")) + info.tools = chunk.readString(chunk.available()); + else if (format.equals("IARL")) + info.archival_location = chunk.readString(chunk.available()); + else if (format.equals("IART")) + info.artist = chunk.readString(chunk.available()); + else if (format.equals("ICMS")) + info.commissioned = chunk.readString(chunk.available()); + else if (format.equals("IGNR")) + info.genre = chunk.readString(chunk.available()); + else if (format.equals("IKEY")) + info.keywords = chunk.readString(chunk.available()); + else if (format.equals("IMED")) + info.medium = chunk.readString(chunk.available()); + else if (format.equals("ISBJ")) + info.subject = chunk.readString(chunk.available()); + else if (format.equals("ISRC")) + info.source = chunk.readString(chunk.available()); + else if (format.equals("ISRF")) + info.source_form = chunk.readString(chunk.available()); + else if (format.equals("ITCH")) + info.technician = chunk.readString(chunk.available()); + } + } + + private void readLinsChunk(RIFFReader riff) throws IOException { + while (riff.hasNextChunk()) { + RIFFReader chunk = riff.nextChunk(); + if (chunk.getFormat().equals("LIST")) { + if (chunk.getType().equals("ins ")) + readInsChunk(chunk); + } + } + } + + private void readInsChunk(RIFFReader riff) throws IOException { + DLSInstrument instrument = new DLSInstrument(this); + + while (riff.hasNextChunk()) { + RIFFReader chunk = riff.nextChunk(); + String format = chunk.getFormat(); + if (format.equals("LIST")) { + if (chunk.getType().equals("INFO")) { + readInsInfoChunk(instrument, chunk); + } + if (chunk.getType().equals("lrgn")) { + while (chunk.hasNextChunk()) { + RIFFReader subchunk = chunk.nextChunk(); + if (subchunk.getFormat().equals("LIST")) { + if (subchunk.getType().equals("rgn ")) { + DLSRegion split = new DLSRegion(); + if (readRgnChunk(split, subchunk)) + instrument.getRegions().add(split); + } + if (subchunk.getType().equals("rgn2")) { + // support for DLS level 2 regions + DLSRegion split = new DLSRegion(); + if (readRgnChunk(split, subchunk)) + instrument.getRegions().add(split); + } + } + } + } + if (chunk.getType().equals("lart")) { + List modlist = new ArrayList(); + while (chunk.hasNextChunk()) { + RIFFReader subchunk = chunk.nextChunk(); + if (chunk.getFormat().equals("cdl ")) { + if (!readCdlChunk(chunk)) { + modlist.clear(); + break; + } + } + if (subchunk.getFormat().equals("art1")) + readArt1Chunk(modlist, subchunk); + } + instrument.getModulators().addAll(modlist); + } + if (chunk.getType().equals("lar2")) { + // support for DLS level 2 ART + List modlist = new ArrayList(); + while (chunk.hasNextChunk()) { + RIFFReader subchunk = chunk.nextChunk(); + if (chunk.getFormat().equals("cdl ")) { + if (!readCdlChunk(chunk)) { + modlist.clear(); + break; + } + } + if (subchunk.getFormat().equals("art2")) + readArt2Chunk(modlist, subchunk); + } + instrument.getModulators().addAll(modlist); + } + } else { + if (format.equals("dlid")) { + instrument.guid = new byte[16]; + chunk.readFully(instrument.guid); + } + if (format.equals("insh")) { + chunk.readUnsignedInt(); // Read Region Count - ignored + + int bank = chunk.read(); // LSB + bank += (chunk.read() & 127) << 7; // MSB + chunk.read(); // Read Reserved byte + int drumins = chunk.read(); // Drum Instrument + + int id = chunk.read() & 127; // Read only first 7 bits + chunk.read(); // Read Reserved byte + chunk.read(); // Read Reserved byte + chunk.read(); // Read Reserved byte + + instrument.bank = bank; + instrument.preset = (int) id; + instrument.druminstrument = (drumins & 128) > 0; + //System.out.println("bank="+bank+" drumkit="+drumkit + // +" id="+id); + } + + } + } + instruments.add(instrument); + } + + private void readArt1Chunk(List modulators, RIFFReader riff) + throws IOException { + long size = riff.readUnsignedInt(); + long count = riff.readUnsignedInt(); + + if (size - 8 != 0) + riff.skipBytes(size - 8); + + for (int i = 0; i < count; i++) { + DLSModulator modulator = new DLSModulator(); + modulator.version = 1; + modulator.source = riff.readUnsignedShort(); + modulator.control = riff.readUnsignedShort(); + modulator.destination = riff.readUnsignedShort(); + modulator.transform = riff.readUnsignedShort(); + modulator.scale = riff.readInt(); + modulators.add(modulator); + } + } + + private void readArt2Chunk(List modulators, RIFFReader riff) + throws IOException { + long size = riff.readUnsignedInt(); + long count = riff.readUnsignedInt(); + + if (size - 8 != 0) + riff.skipBytes(size - 8); + + for (int i = 0; i < count; i++) { + DLSModulator modulator = new DLSModulator(); + modulator.version = 2; + modulator.source = riff.readUnsignedShort(); + modulator.control = riff.readUnsignedShort(); + modulator.destination = riff.readUnsignedShort(); + modulator.transform = riff.readUnsignedShort(); + modulator.scale = riff.readInt(); + modulators.add(modulator); + } + } + + private Map temp_rgnassign = new HashMap(); + + private boolean readRgnChunk(DLSRegion split, RIFFReader riff) + throws IOException { + while (riff.hasNextChunk()) { + RIFFReader chunk = riff.nextChunk(); + String format = chunk.getFormat(); + if (format.equals("LIST")) { + if (chunk.getType().equals("lart")) { + List modlist = new ArrayList(); + while (chunk.hasNextChunk()) { + RIFFReader subchunk = chunk.nextChunk(); + if (chunk.getFormat().equals("cdl ")) { + if (!readCdlChunk(chunk)) { + modlist.clear(); + break; + } + } + if (subchunk.getFormat().equals("art1")) + readArt1Chunk(modlist, subchunk); + } + split.getModulators().addAll(modlist); + } + if (chunk.getType().equals("lar2")) { + // support for DLS level 2 ART + List modlist = new ArrayList(); + while (chunk.hasNextChunk()) { + RIFFReader subchunk = chunk.nextChunk(); + if (chunk.getFormat().equals("cdl ")) { + if (!readCdlChunk(chunk)) { + modlist.clear(); + break; + } + } + if (subchunk.getFormat().equals("art2")) + readArt2Chunk(modlist, subchunk); + } + split.getModulators().addAll(modlist); + } + } else { + + if (format.equals("cdl ")) { + if (!readCdlChunk(chunk)) + return false; + } + if (format.equals("rgnh")) { + split.keyfrom = chunk.readUnsignedShort(); + split.keyto = chunk.readUnsignedShort(); + split.velfrom = chunk.readUnsignedShort(); + split.velto = chunk.readUnsignedShort(); + split.options = chunk.readUnsignedShort(); + split.exclusiveClass = chunk.readUnsignedShort(); + } + if (format.equals("wlnk")) { + split.fusoptions = chunk.readUnsignedShort(); + split.phasegroup = chunk.readUnsignedShort(); + split.channel = chunk.readUnsignedInt(); + long sampleid = chunk.readUnsignedInt(); + temp_rgnassign.put(split, sampleid); + } + if (format.equals("wsmp")) { + split.sampleoptions = new DLSSampleOptions(); + readWsmpChunk(split.sampleoptions, chunk); + } + } + } + return true; + } + + private void readWsmpChunk(DLSSampleOptions sampleOptions, RIFFReader riff) + throws IOException { + long size = riff.readUnsignedInt(); + sampleOptions.unitynote = riff.readUnsignedShort(); + sampleOptions.finetune = riff.readShort(); + sampleOptions.attenuation = riff.readInt(); + sampleOptions.options = riff.readUnsignedInt(); + long loops = riff.readInt(); + + if (size > 20) + riff.skipBytes(size - 20); + + for (int i = 0; i < loops; i++) { + DLSSampleLoop loop = new DLSSampleLoop(); + long size2 = riff.readUnsignedInt(); + loop.type = riff.readUnsignedInt(); + loop.start = riff.readUnsignedInt(); + loop.length = riff.readUnsignedInt(); + sampleOptions.loops.add(loop); + if (size2 > 16) + riff.skipBytes(size2 - 16); + } + } + + private void readInsInfoChunk(DLSInstrument dlsinstrument, RIFFReader riff) + throws IOException { + dlsinstrument.info.name = null; + while (riff.hasNextChunk()) { + RIFFReader chunk = riff.nextChunk(); + String format = chunk.getFormat(); + if (format.equals("INAM")) { + dlsinstrument.info.name = chunk.readString(chunk.available()); + } else if (format.equals("ICRD")) { + dlsinstrument.info.creationDate = + chunk.readString(chunk.available()); + } else if (format.equals("IENG")) { + dlsinstrument.info.engineers = + chunk.readString(chunk.available()); + } else if (format.equals("IPRD")) { + dlsinstrument.info.product = chunk.readString(chunk.available()); + } else if (format.equals("ICOP")) { + dlsinstrument.info.copyright = + chunk.readString(chunk.available()); + } else if (format.equals("ICMT")) { + dlsinstrument.info.comments = + chunk.readString(chunk.available()); + } else if (format.equals("ISFT")) { + dlsinstrument.info.tools = chunk.readString(chunk.available()); + } else if (format.equals("IARL")) { + dlsinstrument.info.archival_location = + chunk.readString(chunk.available()); + } else if (format.equals("IART")) { + dlsinstrument.info.artist = chunk.readString(chunk.available()); + } else if (format.equals("ICMS")) { + dlsinstrument.info.commissioned = + chunk.readString(chunk.available()); + } else if (format.equals("IGNR")) { + dlsinstrument.info.genre = chunk.readString(chunk.available()); + } else if (format.equals("IKEY")) { + dlsinstrument.info.keywords = + chunk.readString(chunk.available()); + } else if (format.equals("IMED")) { + dlsinstrument.info.medium = chunk.readString(chunk.available()); + } else if (format.equals("ISBJ")) { + dlsinstrument.info.subject = chunk.readString(chunk.available()); + } else if (format.equals("ISRC")) { + dlsinstrument.info.source = chunk.readString(chunk.available()); + } else if (format.equals("ISRF")) { + dlsinstrument.info.source_form = + chunk.readString(chunk.available()); + } else if (format.equals("ITCH")) { + dlsinstrument.info.technician = + chunk.readString(chunk.available()); + } + } + } + + private void readWvplChunk(RIFFReader riff) throws IOException { + while (riff.hasNextChunk()) { + RIFFReader chunk = riff.nextChunk(); + if (chunk.getFormat().equals("LIST")) { + if (chunk.getType().equals("wave")) + readWaveChunk(chunk); + } + } + } + + private void readWaveChunk(RIFFReader riff) throws IOException { + DLSSample sample = new DLSSample(this); + + while (riff.hasNextChunk()) { + RIFFReader chunk = riff.nextChunk(); + String format = chunk.getFormat(); + if (format.equals("LIST")) { + if (chunk.getType().equals("INFO")) { + readWaveInfoChunk(sample, chunk); + } + } else { + if (format.equals("dlid")) { + sample.guid = new byte[16]; + chunk.readFully(sample.guid); + } + + if (format.equals("fmt ")) { + int sampleformat = chunk.readUnsignedShort(); + if (sampleformat != 1 && sampleformat != 3) { + throw new RIFFInvalidDataException( + "Only PCM samples are supported!"); + } + int channels = chunk.readUnsignedShort(); + long samplerate = chunk.readUnsignedInt(); + // bytes per sec + /* long framerate = */ chunk.readUnsignedInt(); + // block align, framesize + int framesize = chunk.readUnsignedShort(); + int bits = chunk.readUnsignedShort(); + AudioFormat audioformat = null; + if (sampleformat == 1) { + if (bits == 8) { + audioformat = new AudioFormat( + Encoding.PCM_UNSIGNED, samplerate, bits, + channels, framesize, samplerate, false); + } else { + audioformat = new AudioFormat( + Encoding.PCM_SIGNED, samplerate, bits, + channels, framesize, samplerate, false); + } + } + if (sampleformat == 3) { + audioformat = new AudioFormat( + AudioFloatConverter.PCM_FLOAT, samplerate, bits, + channels, framesize, samplerate, false); + } + + sample.format = audioformat; + } + + if (format.equals("data")) { + if (largeFormat) { + sample.setData(new ModelByteBuffer(sampleFile, + chunk.getFilePointer(), chunk.available())); + } else { + byte[] buffer = new byte[chunk.available()]; + // chunk.read(buffer); + sample.setData(buffer); + + int read = 0; + int avail = chunk.available(); + while (read != avail) { + if (avail - read > 65536) { + chunk.readFully(buffer, read, 65536); + read += 65536; + } else { + chunk.readFully(buffer, read, avail - read); + read = avail; + } + } + } + } + + if (format.equals("wsmp")) { + sample.sampleoptions = new DLSSampleOptions(); + readWsmpChunk(sample.sampleoptions, chunk); + } + } + } + + samples.add(sample); + + } + + private void readWaveInfoChunk(DLSSample dlssample, RIFFReader riff) + throws IOException { + dlssample.info.name = null; + while (riff.hasNextChunk()) { + RIFFReader chunk = riff.nextChunk(); + String format = chunk.getFormat(); + if (format.equals("INAM")) { + dlssample.info.name = chunk.readString(chunk.available()); + } else if (format.equals("ICRD")) { + dlssample.info.creationDate = + chunk.readString(chunk.available()); + } else if (format.equals("IENG")) { + dlssample.info.engineers = chunk.readString(chunk.available()); + } else if (format.equals("IPRD")) { + dlssample.info.product = chunk.readString(chunk.available()); + } else if (format.equals("ICOP")) { + dlssample.info.copyright = chunk.readString(chunk.available()); + } else if (format.equals("ICMT")) { + dlssample.info.comments = chunk.readString(chunk.available()); + } else if (format.equals("ISFT")) { + dlssample.info.tools = chunk.readString(chunk.available()); + } else if (format.equals("IARL")) { + dlssample.info.archival_location = + chunk.readString(chunk.available()); + } else if (format.equals("IART")) { + dlssample.info.artist = chunk.readString(chunk.available()); + } else if (format.equals("ICMS")) { + dlssample.info.commissioned = + chunk.readString(chunk.available()); + } else if (format.equals("IGNR")) { + dlssample.info.genre = chunk.readString(chunk.available()); + } else if (format.equals("IKEY")) { + dlssample.info.keywords = chunk.readString(chunk.available()); + } else if (format.equals("IMED")) { + dlssample.info.medium = chunk.readString(chunk.available()); + } else if (format.equals("ISBJ")) { + dlssample.info.subject = chunk.readString(chunk.available()); + } else if (format.equals("ISRC")) { + dlssample.info.source = chunk.readString(chunk.available()); + } else if (format.equals("ISRF")) { + dlssample.info.source_form = chunk.readString(chunk.available()); + } else if (format.equals("ITCH")) { + dlssample.info.technician = chunk.readString(chunk.available()); + } + } + } + + public void save(String name) throws IOException { + writeSoundbank(new RIFFWriter(name, "DLS ")); + } + + public void save(File file) throws IOException { + writeSoundbank(new RIFFWriter(file, "DLS ")); + } + + public void save(OutputStream out) throws IOException { + writeSoundbank(new RIFFWriter(out, "DLS ")); + } + + private void writeSoundbank(RIFFWriter writer) throws IOException { + RIFFWriter colh_chunk = writer.writeChunk("colh"); + colh_chunk.writeUnsignedInt(instruments.size()); + + if (major != -1 && minor != -1) { + RIFFWriter vers_chunk = writer.writeChunk("vers"); + vers_chunk.writeUnsignedInt(major); + vers_chunk.writeUnsignedInt(minor); + } + + writeInstruments(writer.writeList("lins")); + + RIFFWriter ptbl = writer.writeChunk("ptbl"); + ptbl.writeUnsignedInt(8); + ptbl.writeUnsignedInt(samples.size()); + long ptbl_offset = writer.getFilePointer(); + for (int i = 0; i < samples.size(); i++) + ptbl.writeUnsignedInt(0); + + RIFFWriter wvpl = writer.writeList("wvpl"); + long off = wvpl.getFilePointer(); + List offsettable = new ArrayList(); + for (DLSSample sample : samples) { + offsettable.add(Long.valueOf(wvpl.getFilePointer() - off)); + writeSample(wvpl.writeList("wave"), sample); + } + + // small cheat, we are going to rewrite data back in wvpl + long bak = writer.getFilePointer(); + writer.seek(ptbl_offset); + writer.setWriteOverride(true); + for (Long offset : offsettable) + writer.writeUnsignedInt(offset.longValue()); + writer.setWriteOverride(false); + writer.seek(bak); + + writeInfo(writer.writeList("INFO"), info); + + writer.close(); + } + + private void writeSample(RIFFWriter writer, DLSSample sample) + throws IOException { + + AudioFormat audioformat = sample.getFormat(); + + Encoding encoding = audioformat.getEncoding(); + float sampleRate = audioformat.getSampleRate(); + int sampleSizeInBits = audioformat.getSampleSizeInBits(); + int channels = audioformat.getChannels(); + int frameSize = audioformat.getFrameSize(); + float frameRate = audioformat.getFrameRate(); + boolean bigEndian = audioformat.isBigEndian(); + + boolean convert_needed = false; + + if (audioformat.getSampleSizeInBits() == 8) { + if (!encoding.equals(Encoding.PCM_UNSIGNED)) { + encoding = Encoding.PCM_UNSIGNED; + convert_needed = true; + } + } else { + if (!encoding.equals(Encoding.PCM_SIGNED)) { + encoding = Encoding.PCM_SIGNED; + convert_needed = true; + } + if (bigEndian) { + bigEndian = false; + convert_needed = true; + } + } + + if (convert_needed) { + audioformat = new AudioFormat(encoding, sampleRate, + sampleSizeInBits, channels, frameSize, frameRate, bigEndian); + } + + // fmt + RIFFWriter fmt_chunk = writer.writeChunk("fmt "); + int sampleformat = 0; + if (audioformat.getEncoding().equals(Encoding.PCM_UNSIGNED)) + sampleformat = 1; + else if (audioformat.getEncoding().equals(Encoding.PCM_SIGNED)) + sampleformat = 1; + else if (audioformat.getEncoding().equals(AudioFloatConverter.PCM_FLOAT)) + sampleformat = 3; + + fmt_chunk.writeUnsignedShort(sampleformat); + fmt_chunk.writeUnsignedShort(audioformat.getChannels()); + fmt_chunk.writeUnsignedInt((long) audioformat.getSampleRate()); + long srate = ((long)audioformat.getFrameRate())*audioformat.getFrameSize(); + fmt_chunk.writeUnsignedInt(srate); + fmt_chunk.writeUnsignedShort(audioformat.getFrameSize()); + fmt_chunk.writeUnsignedShort(audioformat.getSampleSizeInBits()); + fmt_chunk.write(0); + fmt_chunk.write(0); + + writeSampleOptions(writer.writeChunk("wsmp"), sample.sampleoptions); + + if (convert_needed) { + RIFFWriter data_chunk = writer.writeChunk("data"); + AudioInputStream stream = AudioSystem.getAudioInputStream( + audioformat, (AudioInputStream)sample.getData()); + byte[] buff = new byte[1024]; + int ret; + while ((ret = stream.read(buff)) != -1) { + data_chunk.write(buff, 0, ret); + } + } else { + RIFFWriter data_chunk = writer.writeChunk("data"); + ModelByteBuffer databuff = sample.getDataBuffer(); + databuff.writeTo(data_chunk); + /* + data_chunk.write(databuff.array(), + databuff.arrayOffset(), + databuff.capacity()); + */ + } + + writeInfo(writer.writeList("INFO"), sample.info); + } + + private void writeInstruments(RIFFWriter writer) throws IOException { + for (DLSInstrument instrument : instruments) { + writeInstrument(writer.writeList("ins "), instrument); + } + } + + private void writeInstrument(RIFFWriter writer, DLSInstrument instrument) + throws IOException { + + int art1_count = 0; + int art2_count = 0; + for (DLSModulator modulator : instrument.getModulators()) { + if (modulator.version == 1) + art1_count++; + if (modulator.version == 2) + art2_count++; + } + for (DLSRegion region : instrument.regions) { + for (DLSModulator modulator : region.getModulators()) { + if (modulator.version == 1) + art1_count++; + if (modulator.version == 2) + art2_count++; + } + } + + int version = 1; + if (art2_count > 0) + version = 2; + + RIFFWriter insh_chunk = writer.writeChunk("insh"); + insh_chunk.writeUnsignedInt(instrument.getRegions().size()); + insh_chunk.writeUnsignedInt(instrument.bank + + (instrument.druminstrument ? 2147483648L : 0)); + insh_chunk.writeUnsignedInt(instrument.preset); + + RIFFWriter lrgn = writer.writeList("lrgn"); + for (DLSRegion region: instrument.regions) + writeRegion(lrgn, region, version); + + writeArticulators(writer, instrument.getModulators()); + + writeInfo(writer.writeList("INFO"), instrument.info); + + } + + private void writeArticulators(RIFFWriter writer, + List modulators) throws IOException { + int art1_count = 0; + int art2_count = 0; + for (DLSModulator modulator : modulators) { + if (modulator.version == 1) + art1_count++; + if (modulator.version == 2) + art2_count++; + } + if (art1_count > 0) { + RIFFWriter lar1 = writer.writeList("lart"); + RIFFWriter art1 = lar1.writeChunk("art1"); + art1.writeUnsignedInt(8); + art1.writeUnsignedInt(art1_count); + for (DLSModulator modulator : modulators) { + if (modulator.version == 1) { + art1.writeUnsignedShort(modulator.source); + art1.writeUnsignedShort(modulator.control); + art1.writeUnsignedShort(modulator.destination); + art1.writeUnsignedShort(modulator.transform); + art1.writeInt(modulator.scale); + } + } + } + if (art2_count > 0) { + RIFFWriter lar2 = writer.writeList("lar2"); + RIFFWriter art2 = lar2.writeChunk("art2"); + art2.writeUnsignedInt(8); + art2.writeUnsignedInt(art2_count); + for (DLSModulator modulator : modulators) { + if (modulator.version == 2) { + art2.writeUnsignedShort(modulator.source); + art2.writeUnsignedShort(modulator.control); + art2.writeUnsignedShort(modulator.destination); + art2.writeUnsignedShort(modulator.transform); + art2.writeInt(modulator.scale); + } + } + } + } + + private void writeRegion(RIFFWriter writer, DLSRegion region, int version) + throws IOException { + RIFFWriter rgns = null; + if (version == 1) + rgns = writer.writeList("rgn "); + if (version == 2) + rgns = writer.writeList("rgn2"); + if (rgns == null) + return; + + RIFFWriter rgnh = rgns.writeChunk("rgnh"); + rgnh.writeUnsignedShort(region.keyfrom); + rgnh.writeUnsignedShort(region.keyto); + rgnh.writeUnsignedShort(region.velfrom); + rgnh.writeUnsignedShort(region.velto); + rgnh.writeUnsignedShort(region.options); + rgnh.writeUnsignedShort(region.exclusiveClass); + + if (region.sampleoptions != null) + writeSampleOptions(rgns.writeChunk("wsmp"), region.sampleoptions); + + if (region.sample != null) { + if (samples.indexOf(region.sample) != -1) { + RIFFWriter wlnk = rgns.writeChunk("wlnk"); + wlnk.writeUnsignedShort(region.fusoptions); + wlnk.writeUnsignedShort(region.phasegroup); + wlnk.writeUnsignedInt(region.channel); + wlnk.writeUnsignedInt(samples.indexOf(region.sample)); + } + } + writeArticulators(rgns, region.getModulators()); + rgns.close(); + } + + private void writeSampleOptions(RIFFWriter wsmp, + DLSSampleOptions sampleoptions) throws IOException { + wsmp.writeUnsignedInt(20); + wsmp.writeUnsignedShort(sampleoptions.unitynote); + wsmp.writeShort(sampleoptions.finetune); + wsmp.writeInt(sampleoptions.attenuation); + wsmp.writeUnsignedInt(sampleoptions.options); + wsmp.writeInt(sampleoptions.loops.size()); + + for (DLSSampleLoop loop : sampleoptions.loops) { + wsmp.writeUnsignedInt(16); + wsmp.writeUnsignedInt(loop.type); + wsmp.writeUnsignedInt(loop.start); + wsmp.writeUnsignedInt(loop.length); + } + } + + private void writeInfoStringChunk(RIFFWriter writer, + String name, String value) throws IOException { + if (value == null) + return; + RIFFWriter chunk = writer.writeChunk(name); + chunk.writeString(value); + int len = value.getBytes("ascii").length; + chunk.write(0); + len++; + if (len % 2 != 0) + chunk.write(0); + } + + private void writeInfo(RIFFWriter writer, DLSInfo info) throws IOException { + writeInfoStringChunk(writer, "INAM", info.name); + writeInfoStringChunk(writer, "ICRD", info.creationDate); + writeInfoStringChunk(writer, "IENG", info.engineers); + writeInfoStringChunk(writer, "IPRD", info.product); + writeInfoStringChunk(writer, "ICOP", info.copyright); + writeInfoStringChunk(writer, "ICMT", info.comments); + writeInfoStringChunk(writer, "ISFT", info.tools); + writeInfoStringChunk(writer, "IARL", info.archival_location); + writeInfoStringChunk(writer, "IART", info.artist); + writeInfoStringChunk(writer, "ICMS", info.commissioned); + writeInfoStringChunk(writer, "IGNR", info.genre); + writeInfoStringChunk(writer, "IKEY", info.keywords); + writeInfoStringChunk(writer, "IMED", info.medium); + writeInfoStringChunk(writer, "ISBJ", info.subject); + writeInfoStringChunk(writer, "ISRC", info.source); + writeInfoStringChunk(writer, "ISRF", info.source_form); + writeInfoStringChunk(writer, "ITCH", info.technician); + } + + public DLSInfo getInfo() { + return info; + } + + public String getName() { + return info.name; + } + + public String getVersion() { + return major + "." + minor; + } + + public String getVendor() { + return info.engineers; + } + + public String getDescription() { + return info.comments; + } + + public void setName(String s) { + info.name = s; + } + + public void setVendor(String s) { + info.engineers = s; + } + + public void setDescription(String s) { + info.comments = s; + } + + public SoundbankResource[] getResources() { + SoundbankResource[] resources = new SoundbankResource[samples.size()]; + int j = 0; + for (int i = 0; i < samples.size(); i++) + resources[j++] = samples.get(i); + return resources; + } + + public DLSInstrument[] getInstruments() { + DLSInstrument[] inslist_array = + instruments.toArray(new DLSInstrument[instruments.size()]); + Arrays.sort(inslist_array, new ModelInstrumentComparator()); + return inslist_array; + } + + public DLSSample[] getSamples() { + return samples.toArray(new DLSSample[samples.size()]); + } + + public Instrument getInstrument(Patch patch) { + int program = patch.getProgram(); + int bank = patch.getBank(); + boolean percussion = false; + if (patch instanceof ModelPatch) + percussion = ((ModelPatch) patch).isPercussion(); + for (Instrument instrument : instruments) { + Patch patch2 = instrument.getPatch(); + int program2 = patch2.getProgram(); + int bank2 = patch2.getBank(); + if (program == program2 && bank == bank2) { + boolean percussion2 = false; + if (patch2 instanceof ModelPatch) + percussion2 = ((ModelPatch) patch2).isPercussion(); + if (percussion == percussion2) + return instrument; + } + } + return null; + } + + public void addResource(SoundbankResource resource) { + if (resource instanceof DLSInstrument) + instruments.add((DLSInstrument) resource); + if (resource instanceof DLSSample) + samples.add((DLSSample) resource); + } + + public void removeResource(SoundbankResource resource) { + if (resource instanceof DLSInstrument) + instruments.remove((DLSInstrument) resource); + if (resource instanceof DLSSample) + samples.remove((DLSSample) resource); + } + + public void addInstrument(DLSInstrument resource) { + instruments.add(resource); + } + + public void removeInstrument(DLSInstrument resource) { + instruments.remove(resource); + } + + public long getMajor() { + return major; + } + + public void setMajor(long major) { + this.major = major; + } + + public long getMinor() { + return minor; + } + + public void setMinor(long minor) { + this.minor = minor; + } +} diff --git a/jdk/src/share/classes/com/sun/media/sound/DLSSoundbankReader.java b/jdk/src/share/classes/com/sun/media/sound/DLSSoundbankReader.java new file mode 100644 index 00000000000..294384976af --- /dev/null +++ b/jdk/src/share/classes/com/sun/media/sound/DLSSoundbankReader.java @@ -0,0 +1,74 @@ +/* + * 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. 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 + * 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. + */ + +package com.sun.media.sound; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import javax.sound.midi.InvalidMidiDataException; +import javax.sound.midi.Soundbank; +import javax.sound.midi.spi.SoundbankReader; + +/** + * This class is used to connect the DLSSoundBank class + * to the SoundbankReader SPI interface. + * + * @author Karl Helgason + */ +public class DLSSoundbankReader extends SoundbankReader { + + public Soundbank getSoundbank(URL url) + throws InvalidMidiDataException, IOException { + try { + return new DLSSoundbank(url); + } catch (RIFFInvalidFormatException e) { + return null; + } catch(IOException ioe) { + return null; + } + } + + public Soundbank getSoundbank(InputStream stream) + throws InvalidMidiDataException, IOException { + try { + stream.mark(512); + return new DLSSoundbank(stream); + } catch (RIFFInvalidFormatException e) { + stream.reset(); + return null; + } + } + + public Soundbank getSoundbank(File file) + throws InvalidMidiDataException, IOException { + try { + return new DLSSoundbank(file); + } catch (RIFFInvalidFormatException e) { + return null; + } + } +} diff --git a/jdk/src/share/classes/com/sun/media/sound/DirectAudioDevice.java b/jdk/src/share/classes/com/sun/media/sound/DirectAudioDevice.java index 754aebf6a44..7a4289b1a30 100644 --- a/jdk/src/share/classes/com/sun/media/sound/DirectAudioDevice.java +++ b/jdk/src/share/classes/com/sun/media/sound/DirectAudioDevice.java @@ -394,7 +394,12 @@ class DirectAudioDevice extends AbstractMixer { private float leftGain, rightGain; protected volatile boolean noService = false; // do not run the nService method + // Guards all native calls. protected Object lockNative = new Object(); + // Guards the lastOpened static variable in implOpen and implClose. + protected static Object lockLast = new Object(); + // Keeps track of last opened line, see implOpen "trick". + protected static DirectDL lastOpened; // CONSTRUCTOR protected DirectDL(DataLine.Info info, @@ -496,20 +501,50 @@ class DirectAudioDevice extends AbstractMixer { // align buffer to full frames bufferSize = ((int) bufferSize / format.getFrameSize()) * format.getFrameSize(); - id = nOpen(mixerIndex, deviceID, isSource, - encoding, - hardwareFormat.getSampleRate(), - hardwareFormat.getSampleSizeInBits(), - hardwareFormat.getFrameSize(), - hardwareFormat.getChannels(), - hardwareFormat.getEncoding().equals(AudioFormat.Encoding.PCM_SIGNED), - hardwareFormat.isBigEndian(), - bufferSize); + synchronized(lockLast) { + id = nOpen(mixerIndex, deviceID, isSource, + encoding, + hardwareFormat.getSampleRate(), + hardwareFormat.getSampleSizeInBits(), + hardwareFormat.getFrameSize(), + hardwareFormat.getChannels(), + hardwareFormat.getEncoding().equals( + AudioFormat.Encoding.PCM_SIGNED), + hardwareFormat.isBigEndian(), + bufferSize); - if (id == 0) { - // TODO: nicer error messages... - throw new LineUnavailableException("line with format "+format+" not supported."); + if (id == 0) { + // Bah... Dirty trick. The most likely cause is an application + // already having a line open for this particular hardware + // format and forgetting about it. If so, silently close that + // implementation and try again. Unfortuantely we can only + // open one line per hardware format currently. + if (lastOpened != null + && hardwareFormat.matches(lastOpened.hardwareFormat)) { + lastOpened.implClose(); + lastOpened = null; + + id = nOpen(mixerIndex, deviceID, isSource, + encoding, + hardwareFormat.getSampleRate(), + hardwareFormat.getSampleSizeInBits(), + hardwareFormat.getFrameSize(), + hardwareFormat.getChannels(), + hardwareFormat.getEncoding().equals( + AudioFormat.Encoding.PCM_SIGNED), + hardwareFormat.isBigEndian(), + bufferSize); + } + + if (id == 0) { + // TODO: nicer error messages... + throw new LineUnavailableException( + "line with format "+format+" not supported."); + } + } + lastOpened = this; } + this.bufferSize = nGetBufferSize(id, isSource); if (this.bufferSize < 1) { // this is an error! @@ -580,12 +615,12 @@ class DirectAudioDevice extends AbstractMixer { } synchronized (lockNative) { nStop(id, isSource); - } - // need to set doIO to false before notifying the - // read/write thread, that's why isStartedRunning() - // cannot be used - doIO = false; + // need to set doIO to false before notifying the + // read/write thread, that's why isStartedRunning() + // cannot be used + doIO = false; + } // wake up any waiting threads synchronized(lock) { lock.notifyAll(); @@ -614,8 +649,12 @@ class DirectAudioDevice extends AbstractMixer { doIO = false; long oldID = id; id = 0; - synchronized (lockNative) { - nClose(oldID, isSource); + synchronized (lockLast) { + synchronized (lockNative) { + nClose(oldID, isSource); + if (lastOpened == this) + lastOpened = null; + } } bytePosition = 0; softwareConversionSize = 0; @@ -630,7 +669,8 @@ class DirectAudioDevice extends AbstractMixer { } int a = 0; synchronized (lockNative) { - a = nAvailable(id, isSource); + if (doIO) + a = nAvailable(id, isSource); } return a; } @@ -644,9 +684,9 @@ class DirectAudioDevice extends AbstractMixer { int counter = 0; long startPos = getLongFramePosition(); boolean posChanged = false; - while (!drained && doIO) { + while (!drained) { synchronized (lockNative) { - if ((id == 0) || !nIsStillDraining(id, isSource)) + if ((id == 0) || (!doIO) || !nIsStillDraining(id, isSource)) break; } // check every now and then for a new position @@ -686,7 +726,7 @@ class DirectAudioDevice extends AbstractMixer { lock.notifyAll(); } synchronized (lockNative) { - if (id != 0) { + if (id != 0 && doIO) { // then flush native buffers nFlush(id, isSource); } @@ -697,9 +737,10 @@ class DirectAudioDevice extends AbstractMixer { // replacement for getFramePosition (see AbstractDataLine) public long getLongFramePosition() { - long pos; + long pos = 0; synchronized (lockNative) { - pos = nGetBytePosition(id, isSource, bytePosition); + if (doIO) + pos = nGetBytePosition(id, isSource, bytePosition); } // hack because ALSA sometimes reports wrong framepos if (pos < 0) { @@ -745,11 +786,12 @@ class DirectAudioDevice extends AbstractMixer { } int written = 0; while (!flushing) { - int thisWritten; + int thisWritten = 0; synchronized (lockNative) { - thisWritten = nWrite(id, b, off, len, - softwareConversionSize, - leftGain, rightGain); + if (doIO) + thisWritten = nWrite(id, b, off, len, + softwareConversionSize, + leftGain, rightGain); if (thisWritten < 0) { // error in native layer break; @@ -972,9 +1014,10 @@ class DirectAudioDevice extends AbstractMixer { } int read = 0; while (doIO && !flushing) { - int thisRead; + int thisRead = 0; synchronized (lockNative) { - thisRead = nRead(id, b, off, len, softwareConversionSize); + if (doIO) + thisRead = nRead(id, b, off, len, softwareConversionSize); if (thisRead < 0) { // error in native layer break; @@ -1209,7 +1252,8 @@ class DirectAudioDevice extends AbstractMixer { // set new native position (if necessary) // this must come after the flush! synchronized (lockNative) { - nSetBytePosition(id, isSource, frames * frameSize); + if (doIO) + nSetBytePosition(id, isSource, frames * frameSize); } if (Printer.debug) Printer.debug(" DirectClip.setFramePosition: " diff --git a/jdk/src/share/classes/com/sun/media/sound/EmergencySoundbank.java b/jdk/src/share/classes/com/sun/media/sound/EmergencySoundbank.java new file mode 100644 index 00000000000..9e248641c05 --- /dev/null +++ b/jdk/src/share/classes/com/sun/media/sound/EmergencySoundbank.java @@ -0,0 +1,2695 @@ +/* + * 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. 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 + * 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. + */ +package com.sun.media.sound; + +import java.util.Random; + +import javax.sound.midi.Patch; +import javax.sound.sampled.AudioFormat; + +/** + * Emergency Soundbank generator. + * Used when no other default soundbank can be found. + * + * @author Karl Helgason + */ +public class EmergencySoundbank { + + private final static String[] general_midi_instruments = { + "Acoustic Grand Piano", + "Bright Acoustic Piano", + "Electric Grand Piano", + "Honky-tonk Piano", + "Electric Piano 1", + "Electric Piano 2", + "Harpsichord", + "Clavi", + "Celesta", + "Glockenspiel", + "Music Box", + "Vibraphone", + "Marimba", + "Xylophone", + "Tubular Bells", + "Dulcimer", + "Drawbar Organ", + "Percussive Organ", + "Rock Organ", + "Church Organ", + "Reed Organ", + "Accordion", + "Harmonica", + "Tango Accordion", + "Acoustic Guitar (nylon)", + "Acoustic Guitar (steel)", + "Electric Guitar (jazz)", + "Electric Guitar (clean)", + "Electric Guitar (muted)", + "Overdriven Guitar", + "Distortion Guitar", + "Guitar harmonics", + "Acoustic Bass", + "Electric Bass (finger)", + "Electric Bass (pick)", + "Fretless Bass", + "Slap Bass 1", + "Slap Bass 2", + "Synth Bass 1", + "Synth Bass 2", + "Violin", + "Viola", + "Cello", + "Contrabass", + "Tremolo Strings", + "Pizzicato Strings", + "Orchestral Harp", + "Timpani", + "String Ensemble 1", + "String Ensemble 2", + "SynthStrings 1", + "SynthStrings 2", + "Choir Aahs", + "Voice Oohs", + "Synth Voice", + "Orchestra Hit", + "Trumpet", + "Trombone", + "Tuba", + "Muted Trumpet", + "French Horn", + "Brass Section", + "SynthBrass 1", + "SynthBrass 2", + "Soprano Sax", + "Alto Sax", + "Tenor Sax", + "Baritone Sax", + "Oboe", + "English Horn", + "Bassoon", + "Clarinet", + "Piccolo", + "Flute", + "Recorder", + "Pan Flute", + "Blown Bottle", + "Shakuhachi", + "Whistle", + "Ocarina", + "Lead 1 (square)", + "Lead 2 (sawtooth)", + "Lead 3 (calliope)", + "Lead 4 (chiff)", + "Lead 5 (charang)", + "Lead 6 (voice)", + "Lead 7 (fifths)", + "Lead 8 (bass + lead)", + "Pad 1 (new age)", + "Pad 2 (warm)", + "Pad 3 (polysynth)", + "Pad 4 (choir)", + "Pad 5 (bowed)", + "Pad 6 (metallic)", + "Pad 7 (halo)", + "Pad 8 (sweep)", + "FX 1 (rain)", + "FX 2 (soundtrack)", + "FX 3 (crystal)", + "FX 4 (atmosphere)", + "FX 5 (brightness)", + "FX 6 (goblins)", + "FX 7 (echoes)", + "FX 8 (sci-fi)", + "Sitar", + "Banjo", + "Shamisen", + "Koto", + "Kalimba", + "Bag pipe", + "Fiddle", + "Shanai", + "Tinkle Bell", + "Agogo", + "Steel Drums", + "Woodblock", + "Taiko Drum", + "Melodic Tom", + "Synth Drum", + "Reverse Cymbal", + "Guitar Fret Noise", + "Breath Noise", + "Seashore", + "Bird Tweet", + "Telephone Ring", + "Helicopter", + "Applause", + "Gunshot" + }; + + public static SF2Soundbank createSoundbank() throws Exception { + SF2Soundbank sf2 = new SF2Soundbank(); + sf2.setName("Emergency GM sound set"); + sf2.setVendor("Generated"); + sf2.setDescription("Emergency generated soundbank"); + + /* + * percussion instruments + */ + + SF2Layer bass_drum = new_bass_drum(sf2); + SF2Layer snare_drum = new_snare_drum(sf2); + SF2Layer tom = new_tom(sf2); + SF2Layer open_hihat = new_open_hihat(sf2); + SF2Layer closed_hihat = new_closed_hihat(sf2); + SF2Layer crash_cymbal = new_crash_cymbal(sf2); + SF2Layer side_stick = new_side_stick(sf2); + + SF2Layer[] drums = new SF2Layer[128]; + drums[35] = bass_drum; + drums[36] = bass_drum; + drums[38] = snare_drum; + drums[40] = snare_drum; + drums[41] = tom; + drums[43] = tom; + drums[45] = tom; + drums[47] = tom; + drums[48] = tom; + drums[50] = tom; + drums[42] = closed_hihat; + drums[44] = closed_hihat; + drums[46] = open_hihat; + drums[49] = crash_cymbal; + drums[51] = crash_cymbal; + drums[52] = crash_cymbal; + drums[55] = crash_cymbal; + drums[57] = crash_cymbal; + drums[59] = crash_cymbal; + + // Use side_stick for missing drums: + drums[37] = side_stick; + drums[39] = side_stick; + drums[53] = side_stick; + drums[54] = side_stick; + drums[56] = side_stick; + drums[58] = side_stick; + drums[69] = side_stick; + drums[70] = side_stick; + drums[75] = side_stick; + drums[60] = side_stick; + drums[61] = side_stick; + drums[62] = side_stick; + drums[63] = side_stick; + drums[64] = side_stick; + drums[65] = side_stick; + drums[66] = side_stick; + drums[67] = side_stick; + drums[68] = side_stick; + drums[71] = side_stick; + drums[72] = side_stick; + drums[73] = side_stick; + drums[74] = side_stick; + drums[76] = side_stick; + drums[77] = side_stick; + drums[78] = side_stick; + drums[79] = side_stick; + drums[80] = side_stick; + drums[81] = side_stick; + + + SF2Instrument drum_instrument = new SF2Instrument(sf2); + drum_instrument.setName("Standard Kit"); + drum_instrument.setPatch(new ModelPatch(0, 0, true)); + sf2.addInstrument(drum_instrument); + for (int i = 0; i < drums.length; i++) { + if (drums[i] != null) { + SF2InstrumentRegion region = new SF2InstrumentRegion(); + region.setLayer(drums[i]); + region.putBytes(SF2InstrumentRegion.GENERATOR_KEYRANGE, + new byte[]{(byte) i, (byte) i}); + drum_instrument.getRegions().add(region); + } + } + + + /* + * melodic instruments + */ + + SF2Layer gpiano = new_gpiano(sf2); + SF2Layer gpiano2 = new_gpiano2(sf2); + SF2Layer gpiano_hammer = new_piano_hammer(sf2); + SF2Layer piano1 = new_piano1(sf2); + SF2Layer epiano1 = new_epiano1(sf2); + SF2Layer epiano2 = new_epiano2(sf2); + + SF2Layer guitar = new_guitar1(sf2); + SF2Layer guitar_pick = new_guitar_pick(sf2); + SF2Layer guitar_dist = new_guitar_dist(sf2); + SF2Layer bass1 = new_bass1(sf2); + SF2Layer bass2 = new_bass2(sf2); + SF2Layer synthbass = new_synthbass(sf2); + SF2Layer string2 = new_string2(sf2); + SF2Layer orchhit = new_orchhit(sf2); + SF2Layer choir = new_choir(sf2); + SF2Layer solostring = new_solostring(sf2); + SF2Layer organ = new_organ(sf2); + SF2Layer ch_organ = new_ch_organ(sf2); + SF2Layer bell = new_bell(sf2); + SF2Layer flute = new_flute(sf2); + + SF2Layer timpani = new_timpani(sf2); + SF2Layer melodic_toms = new_melodic_toms(sf2); + SF2Layer trumpet = new_trumpet(sf2); + SF2Layer trombone = new_trombone(sf2); + SF2Layer brass_section = new_brass_section(sf2); + SF2Layer horn = new_horn(sf2); + SF2Layer sax = new_sax(sf2); + SF2Layer oboe = new_oboe(sf2); + SF2Layer bassoon = new_bassoon(sf2); + SF2Layer clarinet = new_clarinet(sf2); + SF2Layer reverse_cymbal = new_reverse_cymbal(sf2); + + SF2Layer defaultsound = piano1; + + newInstrument(sf2, "Piano", new Patch(0, 0), gpiano, gpiano_hammer); + newInstrument(sf2, "Piano", new Patch(0, 1), gpiano2, gpiano_hammer); + newInstrument(sf2, "Piano", new Patch(0, 2), piano1); + { + SF2Instrument ins = newInstrument(sf2, "Honky-tonk Piano", + new Patch(0, 3), piano1, piano1); + SF2InstrumentRegion region = ins.getRegions().get(0); + region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 80); + region.putInteger(SF2Region.GENERATOR_FINETUNE, 30); + region = ins.getRegions().get(1); + region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 30); + } + newInstrument(sf2, "Rhodes", new Patch(0, 4), epiano2); + newInstrument(sf2, "Rhodes", new Patch(0, 5), epiano2); + newInstrument(sf2, "Clavinet", new Patch(0, 6), epiano1); + newInstrument(sf2, "Clavinet", new Patch(0, 7), epiano1); + newInstrument(sf2, "Rhodes", new Patch(0, 8), epiano2); + newInstrument(sf2, "Bell", new Patch(0, 9), bell); + newInstrument(sf2, "Bell", new Patch(0, 10), bell); + newInstrument(sf2, "Vibraphone", new Patch(0, 11), bell); + newInstrument(sf2, "Marimba", new Patch(0, 12), bell); + newInstrument(sf2, "Marimba", new Patch(0, 13), bell); + newInstrument(sf2, "Bell", new Patch(0, 14), bell); + newInstrument(sf2, "Rock Organ", new Patch(0, 15), organ); + newInstrument(sf2, "Rock Organ", new Patch(0, 16), organ); + newInstrument(sf2, "Perc Organ", new Patch(0, 17), organ); + newInstrument(sf2, "Rock Organ", new Patch(0, 18), organ); + newInstrument(sf2, "Church Organ", new Patch(0, 19), ch_organ); + newInstrument(sf2, "Accordion", new Patch(0, 20), organ); + newInstrument(sf2, "Accordion", new Patch(0, 21), organ); + newInstrument(sf2, "Accordion", new Patch(0, 22), organ); + newInstrument(sf2, "Accordion", new Patch(0, 23), organ); + newInstrument(sf2, "Guitar", new Patch(0, 24), guitar, guitar_pick); + newInstrument(sf2, "Guitar", new Patch(0, 25), guitar, guitar_pick); + newInstrument(sf2, "Guitar", new Patch(0, 26), guitar, guitar_pick); + newInstrument(sf2, "Guitar", new Patch(0, 27), guitar, guitar_pick); + newInstrument(sf2, "Guitar", new Patch(0, 28), guitar, guitar_pick); + newInstrument(sf2, "Distorted Guitar", new Patch(0, 29), guitar_dist); + newInstrument(sf2, "Distorted Guitar", new Patch(0, 30), guitar_dist); + newInstrument(sf2, "Guitar", new Patch(0, 31), guitar, guitar_pick); + newInstrument(sf2, "Finger Bass", new Patch(0, 32), bass1); + newInstrument(sf2, "Finger Bass", new Patch(0, 33), bass1); + newInstrument(sf2, "Finger Bass", new Patch(0, 34), bass1); + newInstrument(sf2, "Frettless Bass", new Patch(0, 35), bass2); + newInstrument(sf2, "Frettless Bass", new Patch(0, 36), bass2); + newInstrument(sf2, "Frettless Bass", new Patch(0, 37), bass2); + newInstrument(sf2, "Synth Bass1", new Patch(0, 38), synthbass); + newInstrument(sf2, "Synth Bass2", new Patch(0, 39), synthbass); + newInstrument(sf2, "Solo String", new Patch(0, 40), string2, solostring); + newInstrument(sf2, "Solo String", new Patch(0, 41), string2, solostring); + newInstrument(sf2, "Solo String", new Patch(0, 42), string2, solostring); + newInstrument(sf2, "Solo String", new Patch(0, 43), string2, solostring); + newInstrument(sf2, "Solo String", new Patch(0, 44), string2, solostring); + newInstrument(sf2, "Def", new Patch(0, 45), defaultsound); + newInstrument(sf2, "Harp", new Patch(0, 46), bell); + newInstrument(sf2, "Timpani", new Patch(0, 47), timpani); + newInstrument(sf2, "Strings", new Patch(0, 48), string2); + SF2Instrument slow_strings = + newInstrument(sf2, "Slow Strings", new Patch(0, 49), string2); + SF2InstrumentRegion region = slow_strings.getRegions().get(0); + region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, 2500); + region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 2000); + newInstrument(sf2, "Synth Strings", new Patch(0, 50), string2); + newInstrument(sf2, "Synth Strings", new Patch(0, 51), string2); + + + newInstrument(sf2, "Choir", new Patch(0, 52), choir); + newInstrument(sf2, "Choir", new Patch(0, 53), choir); + newInstrument(sf2, "Choir", new Patch(0, 54), choir); + { + SF2Instrument ins = newInstrument(sf2, "Orch Hit", + new Patch(0, 55), orchhit, orchhit, timpani); + region = ins.getRegions().get(0); + region.putInteger(SF2Region.GENERATOR_COARSETUNE, -12); + region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100); + } + newInstrument(sf2, "Trumpet", new Patch(0, 56), trumpet); + newInstrument(sf2, "Trombone", new Patch(0, 57), trombone); + newInstrument(sf2, "Trombone", new Patch(0, 58), trombone); + newInstrument(sf2, "Trumpet", new Patch(0, 59), trumpet); + newInstrument(sf2, "Horn", new Patch(0, 60), horn); + newInstrument(sf2, "Brass Section", new Patch(0, 61), brass_section); + newInstrument(sf2, "Brass Section", new Patch(0, 62), brass_section); + newInstrument(sf2, "Brass Section", new Patch(0, 63), brass_section); + newInstrument(sf2, "Sax", new Patch(0, 64), sax); + newInstrument(sf2, "Sax", new Patch(0, 65), sax); + newInstrument(sf2, "Sax", new Patch(0, 66), sax); + newInstrument(sf2, "Sax", new Patch(0, 67), sax); + newInstrument(sf2, "Oboe", new Patch(0, 68), oboe); + newInstrument(sf2, "Horn", new Patch(0, 69), horn); + newInstrument(sf2, "Bassoon", new Patch(0, 70), bassoon); + newInstrument(sf2, "Clarinet", new Patch(0, 71), clarinet); + newInstrument(sf2, "Flute", new Patch(0, 72), flute); + newInstrument(sf2, "Flute", new Patch(0, 73), flute); + newInstrument(sf2, "Flute", new Patch(0, 74), flute); + newInstrument(sf2, "Flute", new Patch(0, 75), flute); + newInstrument(sf2, "Flute", new Patch(0, 76), flute); + newInstrument(sf2, "Flute", new Patch(0, 77), flute); + newInstrument(sf2, "Flute", new Patch(0, 78), flute); + newInstrument(sf2, "Flute", new Patch(0, 79), flute); + newInstrument(sf2, "Organ", new Patch(0, 80), organ); + newInstrument(sf2, "Organ", new Patch(0, 81), organ); + newInstrument(sf2, "Flute", new Patch(0, 82), flute); + newInstrument(sf2, "Organ", new Patch(0, 83), organ); + newInstrument(sf2, "Organ", new Patch(0, 84), organ); + newInstrument(sf2, "Choir", new Patch(0, 85), choir); + newInstrument(sf2, "Organ", new Patch(0, 86), organ); + newInstrument(sf2, "Organ", new Patch(0, 87), organ); + newInstrument(sf2, "Synth Strings", new Patch(0, 88), string2); + newInstrument(sf2, "Organ", new Patch(0, 89), organ); + newInstrument(sf2, "Def", new Patch(0, 90), defaultsound); + newInstrument(sf2, "Choir", new Patch(0, 91), choir); + newInstrument(sf2, "Organ", new Patch(0, 92), organ); + newInstrument(sf2, "Organ", new Patch(0, 93), organ); + newInstrument(sf2, "Organ", new Patch(0, 94), organ); + newInstrument(sf2, "Organ", new Patch(0, 95), organ); + newInstrument(sf2, "Organ", new Patch(0, 96), organ); + newInstrument(sf2, "Organ", new Patch(0, 97), organ); + newInstrument(sf2, "Bell", new Patch(0, 98), bell); + newInstrument(sf2, "Organ", new Patch(0, 99), organ); + newInstrument(sf2, "Organ", new Patch(0, 100), organ); + newInstrument(sf2, "Organ", new Patch(0, 101), organ); + newInstrument(sf2, "Def", new Patch(0, 102), defaultsound); + newInstrument(sf2, "Synth Strings", new Patch(0, 103), string2); + newInstrument(sf2, "Def", new Patch(0, 104), defaultsound); + newInstrument(sf2, "Def", new Patch(0, 105), defaultsound); + newInstrument(sf2, "Def", new Patch(0, 106), defaultsound); + newInstrument(sf2, "Def", new Patch(0, 107), defaultsound); + newInstrument(sf2, "Marimba", new Patch(0, 108), bell); + newInstrument(sf2, "Sax", new Patch(0, 109), sax); + newInstrument(sf2, "Solo String", new Patch(0, 110), string2, solostring); + newInstrument(sf2, "Oboe", new Patch(0, 111), oboe); + newInstrument(sf2, "Bell", new Patch(0, 112), bell); + newInstrument(sf2, "Melodic Toms", new Patch(0, 113), melodic_toms); + newInstrument(sf2, "Marimba", new Patch(0, 114), bell); + newInstrument(sf2, "Melodic Toms", new Patch(0, 115), melodic_toms); + newInstrument(sf2, "Melodic Toms", new Patch(0, 116), melodic_toms); + newInstrument(sf2, "Melodic Toms", new Patch(0, 117), melodic_toms); + newInstrument(sf2, "Reverse Cymbal", new Patch(0, 118), reverse_cymbal); + newInstrument(sf2, "Reverse Cymbal", new Patch(0, 119), reverse_cymbal); + newInstrument(sf2, "Guitar", new Patch(0, 120), guitar); + newInstrument(sf2, "Def", new Patch(0, 121), defaultsound); + { + SF2Instrument ins = newInstrument(sf2, "Seashore/Reverse Cymbal", + new Patch(0, 122), reverse_cymbal); + region = ins.getRegions().get(0); + region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000); + region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 18500); + region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 4500); + region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, -4500); + } + { + SF2Instrument ins = newInstrument(sf2, "Bird/Flute", + new Patch(0, 123), flute); + region = ins.getRegions().get(0); + region.putInteger(SF2Region.GENERATOR_COARSETUNE, 24); + region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, -3000); + region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000); + } + newInstrument(sf2, "Def", new Patch(0, 124), side_stick); + { + SF2Instrument ins = newInstrument(sf2, "Seashore/Reverse Cymbal", + new Patch(0, 125), reverse_cymbal); + region = ins.getRegions().get(0); + region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000); + region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 18500); + region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 4500); + region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, -4500); + } + newInstrument(sf2, "Applause/crash_cymbal", + new Patch(0, 126), crash_cymbal); + newInstrument(sf2, "Gunshot/side_stick", new Patch(0, 127), side_stick); + + for (SF2Instrument instrument : sf2.getInstruments()) { + Patch patch = instrument.getPatch(); + if (patch instanceof ModelPatch) { + if (((ModelPatch) patch).isPercussion()) + continue; + } + instrument.setName(general_midi_instruments[patch.getProgram()]); + } + + return sf2; + + } + + public static SF2Layer new_bell(SF2Soundbank sf2) { + Random random = new Random(102030201); + int x = 8; + int fftsize = 4096 * x; + double[] data = new double[fftsize * 2]; + double base = x * 25; + double start_w = 0.01; + double end_w = 0.05; + double start_a = 0.2; + double end_a = 0.00001; + double a = start_a; + double a_step = Math.pow(end_a / start_a, 1.0 / 40.0); + for (int i = 0; i < 40; i++) { + double detune = 1 + (random.nextDouble() * 2 - 1) * 0.01; + double w = start_w + (end_w - start_w) * (i / 40.0); + complexGaussianDist(data, base * (i + 1) * detune, w, a); + a *= a_step; + } + SF2Sample sample = newSimpleFFTSample(sf2, "EPiano", data, base); + SF2Layer layer = newLayer(sf2, "EPiano", sample); + SF2Region region = layer.getRegions().get(0); + region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1); + region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -12000); + region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0); + region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000); + region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000); + region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, 1200); + region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000); + region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -9000); + region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 16000); + return layer; + } + + public static SF2Layer new_guitar1(SF2Soundbank sf2) { + + int x = 8; + int fftsize = 4096 * x; + double[] data = new double[fftsize * 2]; + double base = x * 25; + double start_w = 0.01; + double end_w = 0.01; + double start_a = 2; + double end_a = 0.01; + double a = start_a; + double a_step = Math.pow(end_a / start_a, 1.0 / 40.0); + + double[] aa = new double[40]; + for (int i = 0; i < 40; i++) { + aa[i] = a; + a *= a_step; + } + + aa[0] = 2; + aa[1] = 0.5; + aa[2] = 0.45; + aa[3] = 0.2; + aa[4] = 1; + aa[5] = 0.5; + aa[6] = 2; + aa[7] = 1; + aa[8] = 0.5; + aa[9] = 1; + aa[9] = 0.5; + aa[10] = 0.2; + aa[11] = 1; + aa[12] = 0.7; + aa[13] = 0.5; + aa[14] = 1; + + for (int i = 0; i < 40; i++) { + double w = start_w + (end_w - start_w) * (i / 40.0); + complexGaussianDist(data, base * (i + 1), w, aa[i]); + } + + SF2Sample sample = newSimpleFFTSample(sf2, "Guitar", data, base); + SF2Layer layer = newLayer(sf2, "Guitar", sample); + SF2Region region = layer.getRegions().get(0); + region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1); + region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -12000); + region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0); + region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 2400); + region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000); + + region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -100); + region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000); + region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -6000); + region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 16000); + region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -20); + return layer; + } + + public static SF2Layer new_guitar_dist(SF2Soundbank sf2) { + + int x = 8; + int fftsize = 4096 * x; + double[] data = new double[fftsize * 2]; + double base = x * 25; + double start_w = 0.01; + double end_w = 0.01; + double start_a = 2; + double end_a = 0.01; + double a = start_a; + double a_step = Math.pow(end_a / start_a, 1.0 / 40.0); + + double[] aa = new double[40]; + for (int i = 0; i < 40; i++) { + aa[i] = a; + a *= a_step; + } + + aa[0] = 5; + aa[1] = 2; + aa[2] = 0.45; + aa[3] = 0.2; + aa[4] = 1; + aa[5] = 0.5; + aa[6] = 2; + aa[7] = 1; + aa[8] = 0.5; + aa[9] = 1; + aa[9] = 0.5; + aa[10] = 0.2; + aa[11] = 1; + aa[12] = 0.7; + aa[13] = 0.5; + aa[14] = 1; + + for (int i = 0; i < 40; i++) { + double w = start_w + (end_w - start_w) * (i / 40.0); + complexGaussianDist(data, base * (i + 1), w, aa[i]); + } + + + SF2Sample sample = newSimpleFFTSample_dist(sf2, "Distorted Guitar", + data, base, 10000.0); + + + SF2Layer layer = newLayer(sf2, "Distorted Guitar", sample); + SF2Region region = layer.getRegions().get(0); + region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1); + region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -12000); + region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0); + //region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 2400); + //region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 200); + + //region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -100); + //region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000); + //region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -1000); + region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 8000); + //region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -20); + return layer; + } + + public static SF2Layer new_guitar_pick(SF2Soundbank sf2) { + + double datab[]; + + // Make treble part + { + int m = 2; + int fftlen = 4096 * m; + double[] data = new double[2 * fftlen]; + Random random = new Random(3049912); + for (int i = 0; i < data.length; i += 2) + data[i] = (2.0 * (random.nextDouble() - 0.5)); + fft(data); + // Remove all negative frequency + for (int i = fftlen / 2; i < data.length; i++) + data[i] = 0; + for (int i = 0; i < 2048 * m; i++) { + data[i] *= Math.exp(-Math.abs((i - 23) / ((double) m)) * 1.2) + + Math.exp(-Math.abs((i - 40) / ((double) m)) * 0.9); + } + randomPhase(data, new Random(3049912)); + ifft(data); + normalize(data, 0.8); + data = realPart(data); + double gain = 1.0; + for (int i = 0; i < data.length; i++) { + data[i] *= gain; + gain *= 0.9994; + } + datab = data; + + fadeUp(data, 80); + } + + SF2Sample sample = newSimpleDrumSample(sf2, "Guitar Noise", datab); + + SF2Layer layer = new SF2Layer(sf2); + layer.setName("Guitar Noise"); + + SF2GlobalRegion global = new SF2GlobalRegion(); + layer.setGlobalZone(global); + sf2.addResource(layer); + + SF2LayerRegion region = new SF2LayerRegion(); + region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 12000); + //region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0); +// region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100); +/* + region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, 0); + region.putInteger(SF2Region.GENERATOR_SUSTAINMODENV, 1000); + region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000); + region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -11000); + region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 12000); + */ + + region.setSample(sample); + layer.getRegions().add(region); + + return layer; + } + + public static SF2Layer new_gpiano(SF2Soundbank sf2) { + //Random random = new Random(302030201); + int x = 8; + int fftsize = 4096 * x; + double[] data = new double[fftsize * 2]; + double base = x * 25; + double start_a = 0.2; + double end_a = 0.001; + double a = start_a; + double a_step = Math.pow(end_a / start_a, 1.0 / 15.0); + + double[] aa = new double[30]; + for (int i = 0; i < 30; i++) { + aa[i] = a; + a *= a_step; + } + + aa[0] *= 2; + //aa[2] *= 0.1; + aa[4] *= 2; + + + aa[12] *= 0.9; + aa[13] *= 0.7; + for (int i = 14; i < 30; i++) { + aa[i] *= 0.5; + } + + + for (int i = 0; i < 30; i++) { + //double detune = 1 + (random.nextDouble()*2 - 1)*0.0001; + double w = 0.2; + double ai = aa[i]; + if (i > 10) { + w = 5; + ai *= 10; + } + int adjust = 0; + if (i > 5) { + adjust = (i - 5) * 7; + } + complexGaussianDist(data, base * (i + 1) + adjust, w, ai); + } + + SF2Sample sample = newSimpleFFTSample(sf2, "Grand Piano", data, base, 200); + SF2Layer layer = newLayer(sf2, "Grand Piano", sample); + SF2Region region = layer.getRegions().get(0); + region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1); + region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -7000); + region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0); + region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000); + region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000); + region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -6000); + region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000); + region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -5500); + region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 18000); + return layer; + } + + public static SF2Layer new_gpiano2(SF2Soundbank sf2) { + //Random random = new Random(302030201); + int x = 8; + int fftsize = 4096 * x; + double[] data = new double[fftsize * 2]; + double base = x * 25; + double start_a = 0.2; + double end_a = 0.001; + double a = start_a; + double a_step = Math.pow(end_a / start_a, 1.0 / 20.0); + + double[] aa = new double[30]; + for (int i = 0; i < 30; i++) { + aa[i] = a; + a *= a_step; + } + + aa[0] *= 1; + //aa[2] *= 0.1; + aa[4] *= 2; + + + aa[12] *= 0.9; + aa[13] *= 0.7; + for (int i = 14; i < 30; i++) { + aa[i] *= 0.5; + } + + + for (int i = 0; i < 30; i++) { + //double detune = 1 + (random.nextDouble()*2 - 1)*0.0001; + double w = 0.2; + double ai = aa[i]; + if (i > 10) { + w = 5; + ai *= 10; + } + int adjust = 0; + if (i > 5) { + adjust = (i - 5) * 7; + } + complexGaussianDist(data, base * (i + 1) + adjust, w, ai); + } + + SF2Sample sample = newSimpleFFTSample(sf2, "Grand Piano", data, base, 200); + SF2Layer layer = newLayer(sf2, "Grand Piano", sample); + SF2Region region = layer.getRegions().get(0); + region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1); + region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -7000); + region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0); + region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000); + region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000); + region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -6000); + region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000); + region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -5500); + region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 18000); + return layer; + } + + public static SF2Layer new_piano_hammer(SF2Soundbank sf2) { + + double datab[]; + + // Make treble part + { + int m = 2; + int fftlen = 4096 * m; + double[] data = new double[2 * fftlen]; + Random random = new Random(3049912); + for (int i = 0; i < data.length; i += 2) + data[i] = (2.0 * (random.nextDouble() - 0.5)); + fft(data); + // Remove all negative frequency + for (int i = fftlen / 2; i < data.length; i++) + data[i] = 0; + for (int i = 0; i < 2048 * m; i++) + data[i] *= Math.exp(-Math.abs((i - 37) / ((double) m)) * 0.05); + randomPhase(data, new Random(3049912)); + ifft(data); + normalize(data, 0.6); + data = realPart(data); + double gain = 1.0; + for (int i = 0; i < data.length; i++) { + data[i] *= gain; + gain *= 0.9997; + } + datab = data; + + fadeUp(data, 80); + } + + SF2Sample sample = newSimpleDrumSample(sf2, "Piano Hammer", datab); + + SF2Layer layer = new SF2Layer(sf2); + layer.setName("Piano Hammer"); + + SF2GlobalRegion global = new SF2GlobalRegion(); + layer.setGlobalZone(global); + sf2.addResource(layer); + + SF2LayerRegion region = new SF2LayerRegion(); + region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 12000); + //region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0); +/* + region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, 0); + region.putInteger(SF2Region.GENERATOR_SUSTAINMODENV, 1000); + region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000); + region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -11000); + region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 12000); + */ + + region.setSample(sample); + layer.getRegions().add(region); + + return layer; + } + + public static SF2Layer new_piano1(SF2Soundbank sf2) { + //Random random = new Random(302030201); + int x = 8; + int fftsize = 4096 * x; + double[] data = new double[fftsize * 2]; + double base = x * 25; + double start_a = 0.2; + double end_a = 0.0001; + double a = start_a; + double a_step = Math.pow(end_a / start_a, 1.0 / 40.0); + + double[] aa = new double[30]; + for (int i = 0; i < 30; i++) { + aa[i] = a; + a *= a_step; + } + + aa[0] *= 5; + aa[2] *= 0.1; + aa[7] *= 5; + + + for (int i = 0; i < 30; i++) { + //double detune = 1 + (random.nextDouble()*2 - 1)*0.0001; + double w = 0.2; + double ai = aa[i]; + if (i > 12) { + w = 5; + ai *= 10; + } + int adjust = 0; + if (i > 5) { + adjust = (i - 5) * 7; + } + complexGaussianDist(data, base * (i + 1) + adjust, w, ai); + } + + complexGaussianDist(data, base * (15.5), 1, 0.1); + complexGaussianDist(data, base * (17.5), 1, 0.01); + + SF2Sample sample = newSimpleFFTSample(sf2, "EPiano", data, base, 200); + SF2Layer layer = newLayer(sf2, "EPiano", sample); + SF2Region region = layer.getRegions().get(0); + region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1); + region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -12000); + region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0); + region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000); + region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000); + region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -1200); + region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000); + region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -5500); + region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 16000); + return layer; + } + + public static SF2Layer new_epiano1(SF2Soundbank sf2) { + Random random = new Random(302030201); + int x = 8; + int fftsize = 4096 * x; + double[] data = new double[fftsize * 2]; + double base = x * 25; + double start_w = 0.05; + double end_w = 0.05; + double start_a = 0.2; + double end_a = 0.0001; + double a = start_a; + double a_step = Math.pow(end_a / start_a, 1.0 / 40.0); + for (int i = 0; i < 40; i++) { + double detune = 1 + (random.nextDouble() * 2 - 1) * 0.0001; + double w = start_w + (end_w - start_w) * (i / 40.0); + complexGaussianDist(data, base * (i + 1) * detune, w, a); + a *= a_step; + } + + + + SF2Sample sample = newSimpleFFTSample(sf2, "EPiano", data, base); + SF2Layer layer = newLayer(sf2, "EPiano", sample); + SF2Region region = layer.getRegions().get(0); + region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1); + region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -12000); + region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0); + region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000); + region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000); + region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, 1200); + region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000); + region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -9000); + region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 16000); + return layer; + } + + public static SF2Layer new_epiano2(SF2Soundbank sf2) { + Random random = new Random(302030201); + int x = 8; + int fftsize = 4096 * x; + double[] data = new double[fftsize * 2]; + double base = x * 25; + double start_w = 0.01; + double end_w = 0.05; + double start_a = 0.2; + double end_a = 0.00001; + double a = start_a; + double a_step = Math.pow(end_a / start_a, 1.0 / 40.0); + for (int i = 0; i < 40; i++) { + double detune = 1 + (random.nextDouble() * 2 - 1) * 0.0001; + double w = start_w + (end_w - start_w) * (i / 40.0); + complexGaussianDist(data, base * (i + 1) * detune, w, a); + a *= a_step; + } + + SF2Sample sample = newSimpleFFTSample(sf2, "EPiano", data, base); + SF2Layer layer = newLayer(sf2, "EPiano", sample); + SF2Region region = layer.getRegions().get(0); + region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1); + region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -12000); + region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0); + region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 8000); + region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000); + region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, 2400); + region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000); + region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -9000); + region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 16000); + region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100); + return layer; + } + + public static SF2Layer new_bass1(SF2Soundbank sf2) { + int x = 8; + int fftsize = 4096 * x; + double[] data = new double[fftsize * 2]; + double base = x * 25; + double start_w = 0.05; + double end_w = 0.05; + double start_a = 0.2; + double end_a = 0.02; + double a = start_a; + double a_step = Math.pow(end_a / start_a, 1.0 / 25.0); + + double[] aa = new double[25]; + for (int i = 0; i < 25; i++) { + aa[i] = a; + a *= a_step; + } + + aa[0] *= 8; + aa[1] *= 4; + aa[3] *= 8; + aa[5] *= 8; + + for (int i = 0; i < 25; i++) { + double w = start_w + (end_w - start_w) * (i / 40.0); + complexGaussianDist(data, base * (i + 1), w, aa[i]); + } + + + SF2Sample sample = newSimpleFFTSample(sf2, "Bass", data, base); + SF2Layer layer = newLayer(sf2, "Bass", sample); + SF2Region region = layer.getRegions().get(0); + region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1); + region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -12000); + region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0); + region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000); + region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000); + region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -3000); + region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000); + region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -5000); + region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 11000); + region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100); + return layer; + } + + public static SF2Layer new_synthbass(SF2Soundbank sf2) { + int x = 8; + int fftsize = 4096 * x; + double[] data = new double[fftsize * 2]; + double base = x * 25; + double start_w = 0.05; + double end_w = 0.05; + double start_a = 0.2; + double end_a = 0.02; + double a = start_a; + double a_step = Math.pow(end_a / start_a, 1.0 / 25.0); + + double[] aa = new double[25]; + for (int i = 0; i < 25; i++) { + aa[i] = a; + a *= a_step; + } + + aa[0] *= 16; + aa[1] *= 4; + aa[3] *= 16; + aa[5] *= 8; + + for (int i = 0; i < 25; i++) { + double w = start_w + (end_w - start_w) * (i / 40.0); + complexGaussianDist(data, base * (i + 1), w, aa[i]); + } + + + SF2Sample sample = newSimpleFFTSample(sf2, "Bass", data, base); + SF2Layer layer = newLayer(sf2, "Bass", sample); + SF2Region region = layer.getRegions().get(0); + region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1); + region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -12000); + region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0); + region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000); + region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000); + region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -3000); + region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000); + region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -3000); + region.putInteger(SF2Region.GENERATOR_INITIALFILTERQ, 100); + region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 8000); + region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100); + return layer; + } + + public static SF2Layer new_bass2(SF2Soundbank sf2) { + int x = 8; + int fftsize = 4096 * x; + double[] data = new double[fftsize * 2]; + double base = x * 25; + double start_w = 0.05; + double end_w = 0.05; + double start_a = 0.2; + double end_a = 0.002; + double a = start_a; + double a_step = Math.pow(end_a / start_a, 1.0 / 25.0); + + double[] aa = new double[25]; + for (int i = 0; i < 25; i++) { + aa[i] = a; + a *= a_step; + } + + aa[0] *= 8; + aa[1] *= 4; + aa[3] *= 8; + aa[5] *= 8; + + for (int i = 0; i < 25; i++) { + double w = start_w + (end_w - start_w) * (i / 40.0); + complexGaussianDist(data, base * (i + 1), w, aa[i]); + } + + + SF2Sample sample = newSimpleFFTSample(sf2, "Bass2", data, base); + SF2Layer layer = newLayer(sf2, "Bass2", sample); + SF2Region region = layer.getRegions().get(0); + region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1); + region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -8000); + region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0); + region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000); + region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000); + region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -6000); + region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000); + region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 5000); + region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100); + return layer; + } + + public static SF2Layer new_solostring(SF2Soundbank sf2) { + int x = 8; + int fftsize = 4096 * x; + double[] data = new double[fftsize * 2]; + double base = x * 25; + double start_w = 2; + double end_w = 2; + double start_a = 0.2; + double end_a = 0.01; + + double[] aa = new double[18]; + double a = start_a; + double a_step = Math.pow(end_a / start_a, 1.0 / 40.0); + for (int i = 0; i < aa.length; i++) { + a *= a_step; + aa[i] = a; + } + + aa[0] *= 5; + aa[1] *= 5; + aa[2] *= 5; + aa[3] *= 4; + aa[4] *= 4; + aa[5] *= 3; + aa[6] *= 3; + aa[7] *= 2; + + for (int i = 0; i < aa.length; i++) { + double w = start_w + (end_w - start_w) * (i / 40.0); + complexGaussianDist(data, base * (i + 1), w, a); + } + SF2Sample sample = newSimpleFFTSample(sf2, "Strings", data, base); + SF2Layer layer = newLayer(sf2, "Strings", sample); + SF2Region region = layer.getRegions().get(0); + region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1); + region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -5000); + region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 1000); + region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000); + region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100); + region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500); + region.putInteger(SF2Region.GENERATOR_FREQVIBLFO, -1000); + region.putInteger(SF2Region.GENERATOR_VIBLFOTOPITCH, 15); + return layer; + + } + + public static SF2Layer new_orchhit(SF2Soundbank sf2) { + int x = 8; + int fftsize = 4096 * x; + double[] data = new double[fftsize * 2]; + double base = x * 25; + double start_w = 2; + double end_w = 80; + double start_a = 0.2; + double end_a = 0.001; + double a = start_a; + double a_step = Math.pow(end_a / start_a, 1.0 / 40.0); + for (int i = 0; i < 40; i++) { + double w = start_w + (end_w - start_w) * (i / 40.0); + complexGaussianDist(data, base * (i + 1), w, a); + a *= a_step; + } + complexGaussianDist(data, base * 4, 300, 1); + + + SF2Sample sample = newSimpleFFTSample(sf2, "Och Strings", data, base); + SF2Layer layer = newLayer(sf2, "Och Strings", sample); + SF2Region region = layer.getRegions().get(0); + region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1); + region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -5000); + region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 200); + region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 200); + region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000); + region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500); + return layer; + + } + + public static SF2Layer new_string2(SF2Soundbank sf2) { + int x = 8; + int fftsize = 4096 * x; + double[] data = new double[fftsize * 2]; + double base = x * 25; + double start_w = 2; + double end_w = 80; + double start_a = 0.2; + double end_a = 0.001; + double a = start_a; + double a_step = Math.pow(end_a / start_a, 1.0 / 40.0); + for (int i = 0; i < 40; i++) { + double w = start_w + (end_w - start_w) * (i / 40.0); + complexGaussianDist(data, base * (i + 1), w, a); + a *= a_step; + } + SF2Sample sample = newSimpleFFTSample(sf2, "Strings", data, base); + SF2Layer layer = newLayer(sf2, "Strings", sample); + SF2Region region = layer.getRegions().get(0); + region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1); + region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -5000); + region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 1000); + region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000); + region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100); + region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500); + return layer; + + } + + public static SF2Layer new_choir(SF2Soundbank sf2) { + int x = 8; + int fftsize = 4096 * x; + double[] data = new double[fftsize * 2]; + double base = x * 25; + double start_w = 2; + double end_w = 80; + double start_a = 0.2; + double end_a = 0.001; + double a = start_a; + double a_step = Math.pow(end_a / start_a, 1.0 / 40.0); + double[] aa = new double[40]; + for (int i = 0; i < aa.length; i++) { + a *= a_step; + aa[i] = a; + } + + aa[5] *= 0.1; + aa[6] *= 0.01; + aa[7] *= 0.1; + aa[8] *= 0.1; + + for (int i = 0; i < aa.length; i++) { + double w = start_w + (end_w - start_w) * (i / 40.0); + complexGaussianDist(data, base * (i + 1), w, aa[i]); + } + SF2Sample sample = newSimpleFFTSample(sf2, "Strings", data, base); + SF2Layer layer = newLayer(sf2, "Strings", sample); + SF2Region region = layer.getRegions().get(0); + region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1); + region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -5000); + region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 1000); + region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000); + region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100); + region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500); + return layer; + + } + + public static SF2Layer new_organ(SF2Soundbank sf2) { + Random random = new Random(102030201); + int x = 1; + int fftsize = 4096 * x; + double[] data = new double[fftsize * 2]; + double base = x * 15; + double start_w = 0.01; + double end_w = 0.01; + double start_a = 0.2; + double end_a = 0.001; + double a = start_a; + double a_step = Math.pow(end_a / start_a, 1.0 / 40.0); + + for (int i = 0; i < 12; i++) { + double w = start_w + (end_w - start_w) * (i / 40.0); + complexGaussianDist(data, base * (i + 1), w, + a * (0.5 + 3 * (random.nextDouble()))); + a *= a_step; + } + SF2Sample sample = newSimpleFFTSample(sf2, "Organ", data, base); + SF2Layer layer = newLayer(sf2, "Organ", sample); + SF2Region region = layer.getRegions().get(0); + region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1); + region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -6000); + region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000); + region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000); + region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100); + region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500); + return layer; + + } + + public static SF2Layer new_ch_organ(SF2Soundbank sf2) { + int x = 1; + int fftsize = 4096 * x; + double[] data = new double[fftsize * 2]; + double base = x * 15; + double start_w = 0.01; + double end_w = 0.01; + double start_a = 0.2; + double end_a = 0.001; + double a = start_a; + double a_step = Math.pow(end_a / start_a, 1.0 / 60.0); + + double[] aa = new double[60]; + for (int i = 0; i < aa.length; i++) { + a *= a_step; + aa[i] = a; + } + + aa[0] *= 5; + aa[1] *= 2; + aa[2] = 0; + aa[4] = 0; + aa[5] = 0; + aa[7] *= 7; + aa[9] = 0; + aa[10] = 0; + aa[12] = 0; + aa[15] *= 7; + aa[18] = 0; + aa[20] = 0; + aa[24] = 0; + aa[27] *= 5; + aa[29] = 0; + aa[30] = 0; + aa[33] = 0; + aa[36] *= 4; + aa[37] = 0; + aa[39] = 0; + aa[42] = 0; + aa[43] = 0; + aa[47] = 0; + aa[50] *= 4; + aa[52] = 0; + aa[55] = 0; + aa[57] = 0; + + + aa[10] *= 0.1; + aa[11] *= 0.1; + aa[12] *= 0.1; + aa[13] *= 0.1; + + aa[17] *= 0.1; + aa[18] *= 0.1; + aa[19] *= 0.1; + aa[20] *= 0.1; + + for (int i = 0; i < 60; i++) { + double w = start_w + (end_w - start_w) * (i / 40.0); + complexGaussianDist(data, base * (i + 1), w, aa[i]); + a *= a_step; + } + SF2Sample sample = newSimpleFFTSample(sf2, "Organ", data, base); + SF2Layer layer = newLayer(sf2, "Organ", sample); + SF2Region region = layer.getRegions().get(0); + region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1); + region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -10000); + region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000); + return layer; + + } + + public static SF2Layer new_flute(SF2Soundbank sf2) { + int x = 8; + int fftsize = 4096 * x; + double[] data = new double[fftsize * 2]; + double base = x * 15; + + complexGaussianDist(data, base * 1, 0.001, 0.5); + complexGaussianDist(data, base * 2, 0.001, 0.5); + complexGaussianDist(data, base * 3, 0.001, 0.5); + complexGaussianDist(data, base * 4, 0.01, 0.5); + + complexGaussianDist(data, base * 4, 100, 120); + complexGaussianDist(data, base * 6, 100, 40); + complexGaussianDist(data, base * 8, 100, 80); + + complexGaussianDist(data, base * 5, 0.001, 0.05); + complexGaussianDist(data, base * 6, 0.001, 0.06); + complexGaussianDist(data, base * 7, 0.001, 0.04); + complexGaussianDist(data, base * 8, 0.005, 0.06); + complexGaussianDist(data, base * 9, 0.005, 0.06); + complexGaussianDist(data, base * 10, 0.01, 0.1); + complexGaussianDist(data, base * 11, 0.08, 0.7); + complexGaussianDist(data, base * 12, 0.08, 0.6); + complexGaussianDist(data, base * 13, 0.08, 0.6); + complexGaussianDist(data, base * 14, 0.08, 0.6); + complexGaussianDist(data, base * 15, 0.08, 0.5); + complexGaussianDist(data, base * 16, 0.08, 0.5); + complexGaussianDist(data, base * 17, 0.08, 0.2); + + + complexGaussianDist(data, base * 1, 10, 8); + complexGaussianDist(data, base * 2, 10, 8); + complexGaussianDist(data, base * 3, 10, 8); + complexGaussianDist(data, base * 4, 10, 8); + complexGaussianDist(data, base * 5, 10, 8); + complexGaussianDist(data, base * 6, 20, 9); + complexGaussianDist(data, base * 7, 20, 9); + complexGaussianDist(data, base * 8, 20, 9); + complexGaussianDist(data, base * 9, 20, 8); + complexGaussianDist(data, base * 10, 30, 8); + complexGaussianDist(data, base * 11, 30, 9); + complexGaussianDist(data, base * 12, 30, 9); + complexGaussianDist(data, base * 13, 30, 8); + complexGaussianDist(data, base * 14, 30, 8); + complexGaussianDist(data, base * 15, 30, 7); + complexGaussianDist(data, base * 16, 30, 7); + complexGaussianDist(data, base * 17, 30, 6); + + SF2Sample sample = newSimpleFFTSample(sf2, "Flute", data, base); + SF2Layer layer = newLayer(sf2, "Flute", sample); + SF2Region region = layer.getRegions().get(0); + region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1); + region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -6000); + region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000); + region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000); + region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100); + region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500); + return layer; + + } + + public static SF2Layer new_horn(SF2Soundbank sf2) { + int x = 8; + int fftsize = 4096 * x; + double[] data = new double[fftsize * 2]; + double base = x * 15; + + double start_a = 0.5; + double end_a = 0.00000000001; + double a = start_a; + double a_step = Math.pow(end_a / start_a, 1.0 / 40.0); + for (int i = 0; i < 40; i++) { + if (i == 0) + complexGaussianDist(data, base * (i + 1), 0.1, a * 0.2); + else + complexGaussianDist(data, base * (i + 1), 0.1, a); + a *= a_step; + } + + complexGaussianDist(data, base * 2, 100, 1); + + + SF2Sample sample = newSimpleFFTSample(sf2, "Horn", data, base); + SF2Layer layer = newLayer(sf2, "Horn", sample); + SF2Region region = layer.getRegions().get(0); + region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1); + region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -6000); + region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000); + region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000); + region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100); + + region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -500); + region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000); + region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, 5000); + region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 4500); + return layer; + + } + + public static SF2Layer new_trumpet(SF2Soundbank sf2) { + int x = 8; + int fftsize = 4096 * x; + double[] data = new double[fftsize * 2]; + double base = x * 15; + + double start_a = 0.5; + double end_a = 0.00001; + double a = start_a; + double a_step = Math.pow(end_a / start_a, 1.0 / 80.0); + double[] aa = new double[80]; + for (int i = 0; i < 80; i++) { + aa[i] = a; + a *= a_step; + } + + aa[0] *= 0.05; + aa[1] *= 0.2; + aa[2] *= 0.5; + aa[3] *= 0.85; + + for (int i = 0; i < 80; i++) { + complexGaussianDist(data, base * (i + 1), 0.1, aa[i]); + } + + complexGaussianDist(data, base * 5, 300, 3); + + + SF2Sample sample = newSimpleFFTSample(sf2, "Trumpet", data, base); + SF2Layer layer = newLayer(sf2, "Trumpet", sample); + SF2Region region = layer.getRegions().get(0); + region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1); + region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -10000); + region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0); + region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000); + region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100); + + region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -4000); + region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, -2500); + region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, 5000); + region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 4500); + region.putInteger(SF2Region.GENERATOR_INITIALFILTERQ, 10); + return layer; + + } + + public static SF2Layer new_brass_section(SF2Soundbank sf2) { + int x = 8; + int fftsize = 4096 * x; + double[] data = new double[fftsize * 2]; + double base = x * 15; + + double start_a = 0.5; + double end_a = 0.005; + double a = start_a; + double a_step = Math.pow(end_a / start_a, 1.0 / 30.0); + double[] aa = new double[30]; + for (int i = 0; i < 30; i++) { + aa[i] = a; + a *= a_step; + } + + aa[0] *= 0.8; + aa[1] *= 0.9; + + double w = 5; + for (int i = 0; i < 30; i++) { + complexGaussianDist(data, base * (i + 1), 0.1 * w, aa[i] * w); + w += 6; //*= w_step; + } + + complexGaussianDist(data, base * 6, 300, 2); + + + SF2Sample sample = newSimpleFFTSample(sf2, "Brass Section", data, base); + SF2Layer layer = newLayer(sf2, "Brass Section", sample); + SF2Region region = layer.getRegions().get(0); + region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1); + region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -9200); + region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000); + region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000); + region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100); + + region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -3000); + region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000); + region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, 5000); + region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 4500); + return layer; + + } + + public static SF2Layer new_trombone(SF2Soundbank sf2) { + int x = 8; + int fftsize = 4096 * x; + double[] data = new double[fftsize * 2]; + double base = x * 15; + + double start_a = 0.5; + double end_a = 0.001; + double a = start_a; + double a_step = Math.pow(end_a / start_a, 1.0 / 80.0); + double[] aa = new double[80]; + for (int i = 0; i < 80; i++) { + aa[i] = a; + a *= a_step; + } + + aa[0] *= 0.3; + aa[1] *= 0.7; + + for (int i = 0; i < 80; i++) { + complexGaussianDist(data, base * (i + 1), 0.1, aa[i]); + } + + complexGaussianDist(data, base * 6, 300, 2); + + + SF2Sample sample = newSimpleFFTSample(sf2, "Trombone", data, base); + SF2Layer layer = newLayer(sf2, "Trombone", sample); + SF2Region region = layer.getRegions().get(0); + region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1); + region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -8000); + region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000); + region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000); + region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100); + + region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -2000); + region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000); + region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, 5000); + region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 4500); + region.putInteger(SF2Region.GENERATOR_INITIALFILTERQ, 10); + return layer; + + } + + public static SF2Layer new_sax(SF2Soundbank sf2) { + int x = 8; + int fftsize = 4096 * x; + double[] data = new double[fftsize * 2]; + double base = x * 15; + + double start_a = 0.5; + double end_a = 0.01; + double a = start_a; + double a_step = Math.pow(end_a / start_a, 1.0 / 40.0); + for (int i = 0; i < 40; i++) { + if (i == 0 || i == 2) + complexGaussianDist(data, base * (i + 1), 0.1, a * 4); + else + complexGaussianDist(data, base * (i + 1), 0.1, a); + a *= a_step; + } + + complexGaussianDist(data, base * 4, 200, 1); + + SF2Sample sample = newSimpleFFTSample(sf2, "Sax", data, base); + SF2Layer layer = newLayer(sf2, "Sax", sample); + SF2Region region = layer.getRegions().get(0); + region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1); + region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -6000); + region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000); + region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000); + region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100); + + region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -3000); + region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000); + region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, 5000); + region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 4500); + return layer; + + } + + public static SF2Layer new_oboe(SF2Soundbank sf2) { + int x = 8; + int fftsize = 4096 * x; + double[] data = new double[fftsize * 2]; + double base = x * 15; + + complexGaussianDist(data, base * 5, 100, 80); + + + complexGaussianDist(data, base * 1, 0.01, 0.53); + complexGaussianDist(data, base * 2, 0.01, 0.51); + complexGaussianDist(data, base * 3, 0.01, 0.48); + complexGaussianDist(data, base * 4, 0.01, 0.49); + complexGaussianDist(data, base * 5, 0.01, 5); + complexGaussianDist(data, base * 6, 0.01, 0.51); + complexGaussianDist(data, base * 7, 0.01, 0.50); + complexGaussianDist(data, base * 8, 0.01, 0.59); + complexGaussianDist(data, base * 9, 0.01, 0.61); + complexGaussianDist(data, base * 10, 0.01, 0.52); + complexGaussianDist(data, base * 11, 0.01, 0.49); + complexGaussianDist(data, base * 12, 0.01, 0.51); + complexGaussianDist(data, base * 13, 0.01, 0.48); + complexGaussianDist(data, base * 14, 0.01, 0.51); + complexGaussianDist(data, base * 15, 0.01, 0.46); + complexGaussianDist(data, base * 16, 0.01, 0.35); + complexGaussianDist(data, base * 17, 0.01, 0.20); + complexGaussianDist(data, base * 18, 0.01, 0.10); + complexGaussianDist(data, base * 19, 0.01, 0.5); + complexGaussianDist(data, base * 20, 0.01, 0.1); + + + SF2Sample sample = newSimpleFFTSample(sf2, "Oboe", data, base); + SF2Layer layer = newLayer(sf2, "Oboe", sample); + SF2Region region = layer.getRegions().get(0); + region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1); + region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -6000); + region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000); + region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000); + region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100); + region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500); + return layer; + + } + + public static SF2Layer new_bassoon(SF2Soundbank sf2) { + int x = 8; + int fftsize = 4096 * x; + double[] data = new double[fftsize * 2]; + double base = x * 15; + + complexGaussianDist(data, base * 2, 100, 40); + complexGaussianDist(data, base * 4, 100, 20); + + complexGaussianDist(data, base * 1, 0.01, 0.53); + complexGaussianDist(data, base * 2, 0.01, 5); + complexGaussianDist(data, base * 3, 0.01, 0.51); + complexGaussianDist(data, base * 4, 0.01, 0.48); + complexGaussianDist(data, base * 5, 0.01, 1.49); + complexGaussianDist(data, base * 6, 0.01, 0.51); + complexGaussianDist(data, base * 7, 0.01, 0.50); + complexGaussianDist(data, base * 8, 0.01, 0.59); + complexGaussianDist(data, base * 9, 0.01, 0.61); + complexGaussianDist(data, base * 10, 0.01, 0.52); + complexGaussianDist(data, base * 11, 0.01, 0.49); + complexGaussianDist(data, base * 12, 0.01, 0.51); + complexGaussianDist(data, base * 13, 0.01, 0.48); + complexGaussianDist(data, base * 14, 0.01, 0.51); + complexGaussianDist(data, base * 15, 0.01, 0.46); + complexGaussianDist(data, base * 16, 0.01, 0.35); + complexGaussianDist(data, base * 17, 0.01, 0.20); + complexGaussianDist(data, base * 18, 0.01, 0.10); + complexGaussianDist(data, base * 19, 0.01, 0.5); + complexGaussianDist(data, base * 20, 0.01, 0.1); + + + SF2Sample sample = newSimpleFFTSample(sf2, "Flute", data, base); + SF2Layer layer = newLayer(sf2, "Flute", sample); + SF2Region region = layer.getRegions().get(0); + region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1); + region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -6000); + region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000); + region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000); + region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100); + region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500); + return layer; + + } + + public static SF2Layer new_clarinet(SF2Soundbank sf2) { + int x = 8; + int fftsize = 4096 * x; + double[] data = new double[fftsize * 2]; + double base = x * 15; + + complexGaussianDist(data, base * 1, 0.001, 0.5); + complexGaussianDist(data, base * 2, 0.001, 0.02); + complexGaussianDist(data, base * 3, 0.001, 0.2); + complexGaussianDist(data, base * 4, 0.01, 0.1); + + complexGaussianDist(data, base * 4, 100, 60); + complexGaussianDist(data, base * 6, 100, 20); + complexGaussianDist(data, base * 8, 100, 20); + + complexGaussianDist(data, base * 5, 0.001, 0.1); + complexGaussianDist(data, base * 6, 0.001, 0.09); + complexGaussianDist(data, base * 7, 0.001, 0.02); + complexGaussianDist(data, base * 8, 0.005, 0.16); + complexGaussianDist(data, base * 9, 0.005, 0.96); + complexGaussianDist(data, base * 10, 0.01, 0.9); + complexGaussianDist(data, base * 11, 0.08, 1.2); + complexGaussianDist(data, base * 12, 0.08, 1.8); + complexGaussianDist(data, base * 13, 0.08, 1.6); + complexGaussianDist(data, base * 14, 0.08, 1.2); + complexGaussianDist(data, base * 15, 0.08, 0.9); + complexGaussianDist(data, base * 16, 0.08, 0.5); + complexGaussianDist(data, base * 17, 0.08, 0.2); + + + complexGaussianDist(data, base * 1, 10, 8); + complexGaussianDist(data, base * 2, 10, 8); + complexGaussianDist(data, base * 3, 10, 8); + complexGaussianDist(data, base * 4, 10, 8); + complexGaussianDist(data, base * 5, 10, 8); + complexGaussianDist(data, base * 6, 20, 9); + complexGaussianDist(data, base * 7, 20, 9); + complexGaussianDist(data, base * 8, 20, 9); + complexGaussianDist(data, base * 9, 20, 8); + complexGaussianDist(data, base * 10, 30, 8); + complexGaussianDist(data, base * 11, 30, 9); + complexGaussianDist(data, base * 12, 30, 9); + complexGaussianDist(data, base * 13, 30, 8); + complexGaussianDist(data, base * 14, 30, 8); + complexGaussianDist(data, base * 15, 30, 7); + complexGaussianDist(data, base * 16, 30, 7); + complexGaussianDist(data, base * 17, 30, 6); + + SF2Sample sample = newSimpleFFTSample(sf2, "Clarinet", data, base); + SF2Layer layer = newLayer(sf2, "Clarinet", sample); + SF2Region region = layer.getRegions().get(0); + region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1); + region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -6000); + region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000); + region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000); + region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100); + region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500); + return layer; + + } + + public static SF2Layer new_timpani(SF2Soundbank sf2) { + + double datab[]; + double datah[]; + + // Make Bass Part + { + int fftlen = 4096 * 8; + double[] data = new double[2 * fftlen]; + double base = 48; + complexGaussianDist(data, base * 2, 0.2, 1); + complexGaussianDist(data, base * 3, 0.2, 0.7); + complexGaussianDist(data, base * 5, 10, 1); + complexGaussianDist(data, base * 6, 9, 1); + complexGaussianDist(data, base * 8, 15, 1); + complexGaussianDist(data, base * 9, 18, 0.8); + complexGaussianDist(data, base * 11, 21, 0.5); + complexGaussianDist(data, base * 13, 28, 0.3); + complexGaussianDist(data, base * 14, 22, 0.1); + randomPhase(data, new Random(3049912)); + ifft(data); + normalize(data, 0.5); + data = realPart(data); + + double d_len = data.length; + for (int i = 0; i < data.length; i++) { + double g = (1.0 - (i / d_len)); + data[i] *= g * g; + } + fadeUp(data, 40); + datab = data; + } + + // Make treble part + { + int fftlen = 4096 * 4; + double[] data = new double[2 * fftlen]; + Random random = new Random(3049912); + for (int i = 0; i < data.length; i += 2) { + data[i] = (2.0 * (random.nextDouble() - 0.5)) * 0.1; + } + fft(data); + // Remove all negative frequency + for (int i = fftlen / 2; i < data.length; i++) + data[i] = 0; + for (int i = 1024 * 4; i < 2048 * 4; i++) + data[i] = 1.0 - (i - 4096) / 4096.0; + for (int i = 0; i < 300; i++) { + double g = (1.0 - (i / 300.0)); + data[i] *= 1.0 + 20 * g * g; + } + for (int i = 0; i < 24; i++) + data[i] = 0; + randomPhase(data, new Random(3049912)); + ifft(data); + normalize(data, 0.9); + data = realPart(data); + double gain = 1.0; + for (int i = 0; i < data.length; i++) { + data[i] *= gain; + gain *= 0.9998; + } + datah = data; + } + + for (int i = 0; i < datah.length; i++) + datab[i] += datah[i] * 0.02; + + normalize(datab, 0.9); + + SF2Sample sample = newSimpleDrumSample(sf2, "Timpani", datab); + + SF2Layer layer = new SF2Layer(sf2); + layer.setName("Timpani"); + + SF2GlobalRegion global = new SF2GlobalRegion(); + layer.setGlobalZone(global); + sf2.addResource(layer); + + SF2LayerRegion region = new SF2LayerRegion(); + region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 12000); + region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100); + region.setSample(sample); + layer.getRegions().add(region); + + return layer; + } + + public static SF2Layer new_melodic_toms(SF2Soundbank sf2) { + + double datab[]; + double datah[]; + + // Make Bass Part + { + int fftlen = 4096 * 4; + double[] data = new double[2 * fftlen]; + complexGaussianDist(data, 30, 0.5, 1); + randomPhase(data, new Random(3049912)); + ifft(data); + normalize(data, 0.8); + data = realPart(data); + + double d_len = data.length; + for (int i = 0; i < data.length; i++) + data[i] *= (1.0 - (i / d_len)); + datab = data; + } + + // Make treble part + { + int fftlen = 4096 * 4; + double[] data = new double[2 * fftlen]; + Random random = new Random(3049912); + for (int i = 0; i < data.length; i += 2) + data[i] = (2.0 * (random.nextDouble() - 0.5)) * 0.1; + fft(data); + // Remove all negative frequency + for (int i = fftlen / 2; i < data.length; i++) + data[i] = 0; + for (int i = 1024 * 4; i < 2048 * 4; i++) + data[i] = 1.0 - (i - 4096) / 4096.0; + for (int i = 0; i < 200; i++) { + double g = (1.0 - (i / 200.0)); + data[i] *= 1.0 + 20 * g * g; + } + for (int i = 0; i < 30; i++) + data[i] = 0; + randomPhase(data, new Random(3049912)); + ifft(data); + normalize(data, 0.9); + data = realPart(data); + double gain = 1.0; + for (int i = 0; i < data.length; i++) { + data[i] *= gain; + gain *= 0.9996; + } + datah = data; + } + + for (int i = 0; i < datah.length; i++) + datab[i] += datah[i] * 0.5; + for (int i = 0; i < 5; i++) + datab[i] *= i / 5.0; + + normalize(datab, 0.99); + + SF2Sample sample = newSimpleDrumSample(sf2, "Melodic Toms", datab); + sample.setOriginalPitch(63); + + SF2Layer layer = new SF2Layer(sf2); + layer.setName("Melodic Toms"); + + SF2GlobalRegion global = new SF2GlobalRegion(); + layer.setGlobalZone(global); + sf2.addResource(layer); + + SF2LayerRegion region = new SF2LayerRegion(); + region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 12000); + //region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0); + region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100); + region.setSample(sample); + layer.getRegions().add(region); + + return layer; + } + + public static SF2Layer new_reverse_cymbal(SF2Soundbank sf2) { + double datah[]; + { + int fftlen = 4096 * 4; + double[] data = new double[2 * fftlen]; + Random random = new Random(3049912); + for (int i = 0; i < data.length; i += 2) + data[i] = (2.0 * (random.nextDouble() - 0.5)); + for (int i = fftlen / 2; i < data.length; i++) + data[i] = 0; + for (int i = 0; i < 100; i++) + data[i] = 0; + + for (int i = 0; i < 512 * 2; i++) { + double gain = (i / (512.0 * 2.0)); + data[i] = 1 - gain; + } + datah = data; + } + + SF2Sample sample = newSimpleFFTSample(sf2, "Reverse Cymbal", + datah, 100, 20); + + SF2Layer layer = new SF2Layer(sf2); + layer.setName("Reverse Cymbal"); + + SF2GlobalRegion global = new SF2GlobalRegion(); + layer.setGlobalZone(global); + sf2.addResource(layer); + + SF2LayerRegion region = new SF2LayerRegion(); + region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -200); + region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, -12000); + region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1); + region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000); + region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000); + region.setSample(sample); + layer.getRegions().add(region); + + return layer; + } + + public static SF2Layer new_snare_drum(SF2Soundbank sf2) { + + double datab[]; + double datah[]; + + // Make Bass Part + { + int fftlen = 4096 * 4; + double[] data = new double[2 * fftlen]; + complexGaussianDist(data, 24, 0.5, 1); + randomPhase(data, new Random(3049912)); + ifft(data); + normalize(data, 0.5); + data = realPart(data); + + double d_len = data.length; + for (int i = 0; i < data.length; i++) + data[i] *= (1.0 - (i / d_len)); + datab = data; + } + + // Make treble part + { + int fftlen = 4096 * 4; + double[] data = new double[2 * fftlen]; + Random random = new Random(3049912); + for (int i = 0; i < data.length; i += 2) + data[i] = (2.0 * (random.nextDouble() - 0.5)) * 0.1; + fft(data); + // Remove all negative frequency + for (int i = fftlen / 2; i < data.length; i++) + data[i] = 0; + for (int i = 1024 * 4; i < 2048 * 4; i++) + data[i] = 1.0 - (i - 4096) / 4096.0; + for (int i = 0; i < 300; i++) { + double g = (1.0 - (i / 300.0)); + data[i] *= 1.0 + 20 * g * g; + } + for (int i = 0; i < 24; i++) + data[i] = 0; + randomPhase(data, new Random(3049912)); + ifft(data); + normalize(data, 0.9); + data = realPart(data); + double gain = 1.0; + for (int i = 0; i < data.length; i++) { + data[i] *= gain; + gain *= 0.9998; + } + datah = data; + } + + for (int i = 0; i < datah.length; i++) + datab[i] += datah[i]; + for (int i = 0; i < 5; i++) + datab[i] *= i / 5.0; + + SF2Sample sample = newSimpleDrumSample(sf2, "Snare Drum", datab); + + SF2Layer layer = new SF2Layer(sf2); + layer.setName("Snare Drum"); + + SF2GlobalRegion global = new SF2GlobalRegion(); + layer.setGlobalZone(global); + sf2.addResource(layer); + + SF2LayerRegion region = new SF2LayerRegion(); + region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 12000); + region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0); + region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100); + region.setSample(sample); + layer.getRegions().add(region); + + return layer; + } + + public static SF2Layer new_bass_drum(SF2Soundbank sf2) { + + double datab[]; + double datah[]; + + // Make Bass Part + { + int fftlen = 4096 * 4; + double[] data = new double[2 * fftlen]; + complexGaussianDist(data, 1.8 * 5 + 1, 2, 1); + complexGaussianDist(data, 1.8 * 9 + 1, 2, 1); + randomPhase(data, new Random(3049912)); + ifft(data); + normalize(data, 0.9); + data = realPart(data); + double d_len = data.length; + for (int i = 0; i < data.length; i++) + data[i] *= (1.0 - (i / d_len)); + datab = data; + } + + // Make treble part + { + int fftlen = 4096; + double[] data = new double[2 * fftlen]; + Random random = new Random(3049912); + for (int i = 0; i < data.length; i += 2) + data[i] = (2.0 * (random.nextDouble() - 0.5)) * 0.1; + fft(data); + // Remove all negative frequency + for (int i = fftlen / 2; i < data.length; i++) + data[i] = 0; + for (int i = 1024; i < 2048; i++) + data[i] = 1.0 - (i - 1024) / 1024.0; + for (int i = 0; i < 512; i++) + data[i] = 10 * i / 512.0; + for (int i = 0; i < 10; i++) + data[i] = 0; + randomPhase(data, new Random(3049912)); + ifft(data); + normalize(data, 0.9); + data = realPart(data); + double gain = 1.0; + for (int i = 0; i < data.length; i++) { + data[i] *= gain; + gain *= 0.999; + } + datah = data; + } + + for (int i = 0; i < datah.length; i++) + datab[i] += datah[i] * 0.5; + for (int i = 0; i < 5; i++) + datab[i] *= i / 5.0; + + SF2Sample sample = newSimpleDrumSample(sf2, "Bass Drum", datab); + + SF2Layer layer = new SF2Layer(sf2); + layer.setName("Bass Drum"); + + SF2GlobalRegion global = new SF2GlobalRegion(); + layer.setGlobalZone(global); + sf2.addResource(layer); + + SF2LayerRegion region = new SF2LayerRegion(); + region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 12000); + region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0); + region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100); + region.setSample(sample); + layer.getRegions().add(region); + + return layer; + } + + public static SF2Layer new_tom(SF2Soundbank sf2) { + + double datab[]; + double datah[]; + + // Make Bass Part + { + int fftlen = 4096 * 4; + double[] data = new double[2 * fftlen]; + complexGaussianDist(data, 30, 0.5, 1); + randomPhase(data, new Random(3049912)); + ifft(data); + normalize(data, 0.8); + data = realPart(data); + + double d_len = data.length; + for (int i = 0; i < data.length; i++) + data[i] *= (1.0 - (i / d_len)); + datab = data; + } + + // Make treble part + { + int fftlen = 4096 * 4; + double[] data = new double[2 * fftlen]; + Random random = new Random(3049912); + for (int i = 0; i < data.length; i += 2) + data[i] = (2.0 * (random.nextDouble() - 0.5)) * 0.1; + fft(data); + // Remove all negative frequency + for (int i = fftlen / 2; i < data.length; i++) + data[i] = 0; + for (int i = 1024 * 4; i < 2048 * 4; i++) + data[i] = 1.0 - (i - 4096) / 4096.0; + for (int i = 0; i < 200; i++) { + double g = (1.0 - (i / 200.0)); + data[i] *= 1.0 + 20 * g * g; + } + for (int i = 0; i < 30; i++) + data[i] = 0; + randomPhase(data, new Random(3049912)); + ifft(data); + normalize(data, 0.9); + data = realPart(data); + double gain = 1.0; + for (int i = 0; i < data.length; i++) { + data[i] *= gain; + gain *= 0.9996; + } + datah = data; + } + + for (int i = 0; i < datah.length; i++) + datab[i] += datah[i] * 0.5; + for (int i = 0; i < 5; i++) + datab[i] *= i / 5.0; + + normalize(datab, 0.99); + + SF2Sample sample = newSimpleDrumSample(sf2, "Tom", datab); + sample.setOriginalPitch(50); + + SF2Layer layer = new SF2Layer(sf2); + layer.setName("Tom"); + + SF2GlobalRegion global = new SF2GlobalRegion(); + layer.setGlobalZone(global); + sf2.addResource(layer); + + SF2LayerRegion region = new SF2LayerRegion(); + region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 12000); + //region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0); + region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100); + region.setSample(sample); + layer.getRegions().add(region); + + return layer; + } + + public static SF2Layer new_closed_hihat(SF2Soundbank sf2) { + double datah[]; + + // Make treble part + { + int fftlen = 4096 * 4; + double[] data = new double[2 * fftlen]; + Random random = new Random(3049912); + for (int i = 0; i < data.length; i += 2) + data[i] = (2.0 * (random.nextDouble() - 0.5)) * 0.1; + fft(data); + // Remove all negative frequency + for (int i = fftlen / 2; i < data.length; i++) + data[i] = 0; + for (int i = 1024 * 4; i < 2048 * 4; i++) + data[i] = 1.0 - (i - 4096) / 4096.0; + for (int i = 0; i < 2048; i++) + data[i] = 0.2 + 0.8 * (i / 2048.0); + randomPhase(data, new Random(3049912)); + ifft(data); + normalize(data, 0.9); + data = realPart(data); + double gain = 1.0; + for (int i = 0; i < data.length; i++) { + data[i] *= gain; + gain *= 0.9996; + } + datah = data; + } + + for (int i = 0; i < 5; i++) + datah[i] *= i / 5.0; + SF2Sample sample = newSimpleDrumSample(sf2, "Closed Hi-Hat", datah); + + SF2Layer layer = new SF2Layer(sf2); + layer.setName("Closed Hi-Hat"); + + SF2GlobalRegion global = new SF2GlobalRegion(); + layer.setGlobalZone(global); + sf2.addResource(layer); + + SF2LayerRegion region = new SF2LayerRegion(); + region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 12000); + region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0); + region.putInteger(SF2Region.GENERATOR_EXCLUSIVECLASS, 1); + region.setSample(sample); + layer.getRegions().add(region); + + return layer; + } + + public static SF2Layer new_open_hihat(SF2Soundbank sf2) { + double datah[]; + { + int fftlen = 4096 * 4; + double[] data = new double[2 * fftlen]; + Random random = new Random(3049912); + for (int i = 0; i < data.length; i += 2) + data[i] = (2.0 * (random.nextDouble() - 0.5)); + for (int i = fftlen / 2; i < data.length; i++) + data[i] = 0; + for (int i = 0; i < 200; i++) + data[i] = 0; + for (int i = 0; i < 2048 * 4; i++) { + double gain = (i / (2048.0 * 4.0)); + data[i] = gain; + } + datah = data; + } + + SF2Sample sample = newSimpleFFTSample(sf2, "Open Hi-Hat", datah, 1000, 5); + + SF2Layer layer = new SF2Layer(sf2); + layer.setName("Open Hi-Hat"); + + SF2GlobalRegion global = new SF2GlobalRegion(); + layer.setGlobalZone(global); + sf2.addResource(layer); + + SF2LayerRegion region = new SF2LayerRegion(); + region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 1500); + region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1); + region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 1500); + region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000); + region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0); + region.putInteger(SF2Region.GENERATOR_EXCLUSIVECLASS, 1); + region.setSample(sample); + layer.getRegions().add(region); + + return layer; + } + + public static SF2Layer new_crash_cymbal(SF2Soundbank sf2) { + double datah[]; + { + int fftlen = 4096 * 4; + double[] data = new double[2 * fftlen]; + Random random = new Random(3049912); + for (int i = 0; i < data.length; i += 2) + data[i] = (2.0 * (random.nextDouble() - 0.5)); + for (int i = fftlen / 2; i < data.length; i++) + data[i] = 0; + for (int i = 0; i < 100; i++) + data[i] = 0; + for (int i = 0; i < 512 * 2; i++) { + double gain = (i / (512.0 * 2.0)); + data[i] = gain; + } + datah = data; + } + + SF2Sample sample = newSimpleFFTSample(sf2, "Crash Cymbal", datah, 1000, 5); + + SF2Layer layer = new SF2Layer(sf2); + layer.setName("Crash Cymbal"); + + SF2GlobalRegion global = new SF2GlobalRegion(); + layer.setGlobalZone(global); + sf2.addResource(layer); + + SF2LayerRegion region = new SF2LayerRegion(); + region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 1800); + region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1); + region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 1800); + region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000); + region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0); + region.setSample(sample); + layer.getRegions().add(region); + + return layer; + } + + public static SF2Layer new_side_stick(SF2Soundbank sf2) { + double datab[]; + + // Make treble part + { + int fftlen = 4096 * 4; + double[] data = new double[2 * fftlen]; + Random random = new Random(3049912); + for (int i = 0; i < data.length; i += 2) + data[i] = (2.0 * (random.nextDouble() - 0.5)) * 0.1; + fft(data); + // Remove all negative frequency + for (int i = fftlen / 2; i < data.length; i++) + data[i] = 0; + for (int i = 1024 * 4; i < 2048 * 4; i++) + data[i] = 1.0 - (i - 4096) / 4096.0; + for (int i = 0; i < 200; i++) { + double g = (1.0 - (i / 200.0)); + data[i] *= 1.0 + 20 * g * g; + } + for (int i = 0; i < 30; i++) + data[i] = 0; + randomPhase(data, new Random(3049912)); + ifft(data); + normalize(data, 0.9); + data = realPart(data); + double gain = 1.0; + for (int i = 0; i < data.length; i++) { + data[i] *= gain; + gain *= 0.9996; + } + datab = data; + } + + for (int i = 0; i < 10; i++) + datab[i] *= i / 10.0; + + SF2Sample sample = newSimpleDrumSample(sf2, "Side Stick", datab); + + SF2Layer layer = new SF2Layer(sf2); + layer.setName("Side Stick"); + + SF2GlobalRegion global = new SF2GlobalRegion(); + layer.setGlobalZone(global); + sf2.addResource(layer); + + SF2LayerRegion region = new SF2LayerRegion(); + region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 12000); + region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0); + region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -50); + region.setSample(sample); + layer.getRegions().add(region); + + return layer; + + } + + public static SF2Sample newSimpleFFTSample(SF2Soundbank sf2, String name, + double[] data, double base) { + return newSimpleFFTSample(sf2, name, data, base, 10); + } + + public static SF2Sample newSimpleFFTSample(SF2Soundbank sf2, String name, + double[] data, double base, int fadeuptime) { + + int fftsize = data.length / 2; + AudioFormat format = new AudioFormat(44100, 16, 1, true, false); + double basefreq = (base / fftsize) * format.getSampleRate() * 0.5; + + randomPhase(data); + ifft(data); + data = realPart(data); + normalize(data, 0.9); + float[] fdata = toFloat(data); + fdata = loopExtend(fdata, fdata.length + 512); + fadeUp(fdata, fadeuptime); + byte[] bdata = toBytes(fdata, format); + + /* + * Create SoundFont2 sample. + */ + SF2Sample sample = new SF2Sample(sf2); + sample.setName(name); + sample.setData(bdata); + sample.setStartLoop(256); + sample.setEndLoop(fftsize + 256); + sample.setSampleRate((long) format.getSampleRate()); + double orgnote = (69 + 12) + + (12 * Math.log(basefreq / 440.0) / Math.log(2)); + sample.setOriginalPitch((int) orgnote); + sample.setPitchCorrection((byte) (-(orgnote - (int) orgnote) * 100.0)); + sf2.addResource(sample); + + return sample; + } + + public static SF2Sample newSimpleFFTSample_dist(SF2Soundbank sf2, + String name, double[] data, double base, double preamp) { + + int fftsize = data.length / 2; + AudioFormat format = new AudioFormat(44100, 16, 1, true, false); + double basefreq = (base / fftsize) * format.getSampleRate() * 0.5; + + randomPhase(data); + ifft(data); + data = realPart(data); + + for (int i = 0; i < data.length; i++) { + data[i] = (1 - Math.exp(-Math.abs(data[i] * preamp))) + * Math.signum(data[i]); + } + + normalize(data, 0.9); + float[] fdata = toFloat(data); + fdata = loopExtend(fdata, fdata.length + 512); + fadeUp(fdata, 80); + byte[] bdata = toBytes(fdata, format); + + /* + * Create SoundFont2 sample. + */ + SF2Sample sample = new SF2Sample(sf2); + sample.setName(name); + sample.setData(bdata); + sample.setStartLoop(256); + sample.setEndLoop(fftsize + 256); + sample.setSampleRate((long) format.getSampleRate()); + double orgnote = (69 + 12) + + (12 * Math.log(basefreq / 440.0) / Math.log(2)); + sample.setOriginalPitch((int) orgnote); + sample.setPitchCorrection((byte) (-(orgnote - (int) orgnote) * 100.0)); + sf2.addResource(sample); + + return sample; + } + + public static SF2Sample newSimpleDrumSample(SF2Soundbank sf2, String name, + double[] data) { + + int fftsize = data.length; + AudioFormat format = new AudioFormat(44100, 16, 1, true, false); + + byte[] bdata = toBytes(toFloat(realPart(data)), format); + + /* + * Create SoundFont2 sample. + */ + SF2Sample sample = new SF2Sample(sf2); + sample.setName(name); + sample.setData(bdata); + sample.setStartLoop(256); + sample.setEndLoop(fftsize + 256); + sample.setSampleRate((long) format.getSampleRate()); + sample.setOriginalPitch(60); + sf2.addResource(sample); + + return sample; + } + + public static SF2Layer newLayer(SF2Soundbank sf2, String name, SF2Sample sample) { + SF2LayerRegion region = new SF2LayerRegion(); + region.setSample(sample); + + SF2Layer layer = new SF2Layer(sf2); + layer.setName(name); + layer.getRegions().add(region); + sf2.addResource(layer); + + return layer; + } + + public static SF2Instrument newInstrument(SF2Soundbank sf2, String name, + Patch patch, SF2Layer... layers) { + + /* + * Create SoundFont2 instrument. + */ + SF2Instrument ins = new SF2Instrument(sf2); + ins.setPatch(patch); + ins.setName(name); + sf2.addInstrument(ins); + + /* + * Create region for instrument. + */ + for (int i = 0; i < layers.length; i++) { + SF2InstrumentRegion insregion = new SF2InstrumentRegion(); + insregion.setLayer(layers[i]); + ins.getRegions().add(insregion); + } + + return ins; + } + + static public void ifft(double[] data) { + new FFT(data.length / 2, 1).transform(data); + } + + static public void fft(double[] data) { + new FFT(data.length / 2, -1).transform(data); + } + + public static void complexGaussianDist(double[] cdata, double m, + double s, double v) { + for (int x = 0; x < cdata.length / 4; x++) { + cdata[x * 2] += v * (1.0 / (s * Math.sqrt(2 * Math.PI)) + * Math.exp((-1.0 / 2.0) * Math.pow((x - m) / s, 2.0))); + } + } + + static public void randomPhase(double[] data) { + for (int i = 0; i < data.length; i += 2) { + double phase = Math.random() * 2 * Math.PI; + double d = data[i]; + data[i] = Math.sin(phase) * d; + data[i + 1] = Math.cos(phase) * d; + } + } + + static public void randomPhase(double[] data, Random random) { + for (int i = 0; i < data.length; i += 2) { + double phase = random.nextDouble() * 2 * Math.PI; + double d = data[i]; + data[i] = Math.sin(phase) * d; + data[i + 1] = Math.cos(phase) * d; + } + } + + static public void normalize(double[] data, double target) { + double maxvalue = 0; + for (int i = 0; i < data.length; i++) { + if (data[i] > maxvalue) + maxvalue = data[i]; + if (-data[i] > maxvalue) + maxvalue = -data[i]; + } + if (maxvalue == 0) + return; + double gain = target / maxvalue; + for (int i = 0; i < data.length; i++) + data[i] *= gain; + } + + static public void normalize(float[] data, double target) { + double maxvalue = 0.5; + for (int i = 0; i < data.length; i++) { + if (data[i * 2] > maxvalue) + maxvalue = data[i * 2]; + if (-data[i * 2] > maxvalue) + maxvalue = -data[i * 2]; + } + double gain = target / maxvalue; + for (int i = 0; i < data.length; i++) + data[i * 2] *= gain; + } + + static public double[] realPart(double[] in) { + double[] out = new double[in.length / 2]; + for (int i = 0; i < out.length; i++) { + out[i] = in[i * 2]; + } + return out; + } + + static public double[] imgPart(double[] in) { + double[] out = new double[in.length / 2]; + for (int i = 0; i < out.length; i++) { + out[i] = in[i * 2]; + } + return out; + } + + static public float[] toFloat(double[] in) { + float[] out = new float[in.length]; + for (int i = 0; i < out.length; i++) { + out[i] = (float) in[i]; + } + return out; + } + + static public byte[] toBytes(float[] in, AudioFormat format) { + byte[] out = new byte[in.length * format.getFrameSize()]; + return AudioFloatConverter.getConverter(format).toByteArray(in, out); + } + + static public void fadeUp(double[] data, int samples) { + double dsamples = samples; + for (int i = 0; i < samples; i++) + data[i] *= i / dsamples; + } + + static public void fadeUp(float[] data, int samples) { + double dsamples = samples; + for (int i = 0; i < samples; i++) + data[i] *= i / dsamples; + } + + static public double[] loopExtend(double[] data, int newsize) { + double[] outdata = new double[newsize]; + int p_len = data.length; + int p_ps = 0; + for (int i = 0; i < outdata.length; i++) { + outdata[i] = data[p_ps]; + p_ps++; + if (p_ps == p_len) + p_ps = 0; + } + return outdata; + } + + static public float[] loopExtend(float[] data, int newsize) { + float[] outdata = new float[newsize]; + int p_len = data.length; + int p_ps = 0; + for (int i = 0; i < outdata.length; i++) { + outdata[i] = data[p_ps]; + p_ps++; + if (p_ps == p_len) + p_ps = 0; + } + return outdata; + } +} diff --git a/jdk/src/share/classes/com/sun/media/sound/FFT.java b/jdk/src/share/classes/com/sun/media/sound/FFT.java new file mode 100644 index 00000000000..2e297e127d7 --- /dev/null +++ b/jdk/src/share/classes/com/sun/media/sound/FFT.java @@ -0,0 +1,748 @@ +/* + * 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. 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 + * 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. + */ +package com.sun.media.sound; + +/** + * Fast Fourier Transformer. + * + * @author Karl Helgason + */ +public final class FFT { + + private double[] w; + private int fftFrameSize; + private int sign; + private int[] bitm_array; + private int fftFrameSize2; + + // Sign = -1 is FFT, 1 is IFFT (inverse FFT) + // Data = Interlaced double array to be transformed. + // The order is: real (sin), complex (cos) + // Framesize must be power of 2 + public FFT(int fftFrameSize, int sign) { + w = computeTwiddleFactors(fftFrameSize, sign); + + this.fftFrameSize = fftFrameSize; + this.sign = sign; + fftFrameSize2 = fftFrameSize << 1; + + // Pre-process Bit-Reversal + bitm_array = new int[fftFrameSize2]; + for (int i = 2; i < fftFrameSize2; i += 2) { + int j; + int bitm; + for (bitm = 2, j = 0; bitm < fftFrameSize2; bitm <<= 1) { + if ((i & bitm) != 0) + j++; + j <<= 1; + } + bitm_array[i] = j; + } + + } + + public void transform(double[] data) { + bitreversal(data); + calc(fftFrameSize, data, sign, w); + } + + private final static double[] computeTwiddleFactors(int fftFrameSize, + int sign) { + + int imax = (int) (Math.log(fftFrameSize) / Math.log(2.)); + + double[] warray = new double[(fftFrameSize - 1) * 4]; + int w_index = 0; + + for (int i = 0, nstep = 2; i < imax; i++) { + int jmax = nstep; + nstep <<= 1; + + double wr = 1.0; + double wi = 0.0; + + double arg = Math.PI / (jmax >> 1); + double wfr = Math.cos(arg); + double wfi = sign * Math.sin(arg); + + for (int j = 0; j < jmax; j += 2) { + warray[w_index++] = wr; + warray[w_index++] = wi; + + double tempr = wr; + wr = tempr * wfr - wi * wfi; + wi = tempr * wfi + wi * wfr; + } + } + + // PRECOMPUTATION of wwr1, wwi1 for factor 4 Decomposition (3 * complex + // operators and 8 +/- complex operators) + { + w_index = 0; + int w_index2 = warray.length >> 1; + for (int i = 0, nstep = 2; i < (imax - 1); i++) { + int jmax = nstep; + nstep *= 2; + + int ii = w_index + jmax; + for (int j = 0; j < jmax; j += 2) { + double wr = warray[w_index++]; + double wi = warray[w_index++]; + double wr1 = warray[ii++]; + double wi1 = warray[ii++]; + warray[w_index2++] = wr * wr1 - wi * wi1; + warray[w_index2++] = wr * wi1 + wi * wr1; + } + } + + } + + return warray; + } + + private final static void calc(int fftFrameSize, double[] data, int sign, + double[] w) { + + final int fftFrameSize2 = fftFrameSize << 1; + + int nstep = 2; + + if (nstep >= fftFrameSize2) + return; + int i = nstep - 2; + if (sign == -1) + calcF4F(fftFrameSize, data, i, nstep, w); + else + calcF4I(fftFrameSize, data, i, nstep, w); + + } + + private final static void calcF2E(int fftFrameSize, double[] data, int i, + int nstep, double[] w) { + int jmax = nstep; + for (int n = 0; n < jmax; n += 2) { + double wr = w[i++]; + double wi = w[i++]; + int m = n + jmax; + double datam_r = data[m]; + double datam_i = data[m + 1]; + double datan_r = data[n]; + double datan_i = data[n + 1]; + double tempr = datam_r * wr - datam_i * wi; + double tempi = datam_r * wi + datam_i * wr; + data[m] = datan_r - tempr; + data[m + 1] = datan_i - tempi; + data[n] = datan_r + tempr; + data[n + 1] = datan_i + tempi; + } + return; + + } + + // Perform Factor-4 Decomposition with 3 * complex operators and 8 +/- + // complex operators + private final static void calcF4F(int fftFrameSize, double[] data, int i, + int nstep, double[] w) { + final int fftFrameSize2 = fftFrameSize << 1; // 2*fftFrameSize; + // Factor-4 Decomposition + + int w_len = w.length >> 1; + while (nstep < fftFrameSize2) { + + if (nstep << 2 == fftFrameSize2) { + // Goto Factor-4 Final Decomposition + // calcF4E(data, i, nstep, -1, w); + calcF4FE(fftFrameSize, data, i, nstep, w); + return; + } + int jmax = nstep; + int nnstep = nstep << 1; + if (nnstep == fftFrameSize2) { + // Factor-4 Decomposition not possible + calcF2E(fftFrameSize, data, i, nstep, w); + return; + } + nstep <<= 2; + int ii = i + jmax; + int iii = i + w_len; + + { + i += 2; + ii += 2; + iii += 2; + + for (int n = 0; n < fftFrameSize2; n += nstep) { + int m = n + jmax; + + double datam1_r = data[m]; + double datam1_i = data[m + 1]; + double datan1_r = data[n]; + double datan1_i = data[n + 1]; + + n += nnstep; + m += nnstep; + double datam2_r = data[m]; + double datam2_i = data[m + 1]; + double datan2_r = data[n]; + double datan2_i = data[n + 1]; + + double tempr = datam1_r; + double tempi = datam1_i; + + datam1_r = datan1_r - tempr; + datam1_i = datan1_i - tempi; + datan1_r = datan1_r + tempr; + datan1_i = datan1_i + tempi; + + double n2w1r = datan2_r; + double n2w1i = datan2_i; + double m2ww1r = datam2_r; + double m2ww1i = datam2_i; + + tempr = m2ww1r - n2w1r; + tempi = m2ww1i - n2w1i; + + datam2_r = datam1_r + tempi; + datam2_i = datam1_i - tempr; + datam1_r = datam1_r - tempi; + datam1_i = datam1_i + tempr; + + tempr = n2w1r + m2ww1r; + tempi = n2w1i + m2ww1i; + + datan2_r = datan1_r - tempr; + datan2_i = datan1_i - tempi; + datan1_r = datan1_r + tempr; + datan1_i = datan1_i + tempi; + + data[m] = datam2_r; + data[m + 1] = datam2_i; + data[n] = datan2_r; + data[n + 1] = datan2_i; + + n -= nnstep; + m -= nnstep; + data[m] = datam1_r; + data[m + 1] = datam1_i; + data[n] = datan1_r; + data[n + 1] = datan1_i; + + } + } + + for (int j = 2; j < jmax; j += 2) { + double wr = w[i++]; + double wi = w[i++]; + double wr1 = w[ii++]; + double wi1 = w[ii++]; + double wwr1 = w[iii++]; + double wwi1 = w[iii++]; + // double wwr1 = wr * wr1 - wi * wi1; // these numbers can be + // precomputed!!! + // double wwi1 = wr * wi1 + wi * wr1; + + for (int n = j; n < fftFrameSize2; n += nstep) { + int m = n + jmax; + + double datam1_r = data[m]; + double datam1_i = data[m + 1]; + double datan1_r = data[n]; + double datan1_i = data[n + 1]; + + n += nnstep; + m += nnstep; + double datam2_r = data[m]; + double datam2_i = data[m + 1]; + double datan2_r = data[n]; + double datan2_i = data[n + 1]; + + double tempr = datam1_r * wr - datam1_i * wi; + double tempi = datam1_r * wi + datam1_i * wr; + + datam1_r = datan1_r - tempr; + datam1_i = datan1_i - tempi; + datan1_r = datan1_r + tempr; + datan1_i = datan1_i + tempi; + + double n2w1r = datan2_r * wr1 - datan2_i * wi1; + double n2w1i = datan2_r * wi1 + datan2_i * wr1; + double m2ww1r = datam2_r * wwr1 - datam2_i * wwi1; + double m2ww1i = datam2_r * wwi1 + datam2_i * wwr1; + + tempr = m2ww1r - n2w1r; + tempi = m2ww1i - n2w1i; + + datam2_r = datam1_r + tempi; + datam2_i = datam1_i - tempr; + datam1_r = datam1_r - tempi; + datam1_i = datam1_i + tempr; + + tempr = n2w1r + m2ww1r; + tempi = n2w1i + m2ww1i; + + datan2_r = datan1_r - tempr; + datan2_i = datan1_i - tempi; + datan1_r = datan1_r + tempr; + datan1_i = datan1_i + tempi; + + data[m] = datam2_r; + data[m + 1] = datam2_i; + data[n] = datan2_r; + data[n + 1] = datan2_i; + + n -= nnstep; + m -= nnstep; + data[m] = datam1_r; + data[m + 1] = datam1_i; + data[n] = datan1_r; + data[n + 1] = datan1_i; + } + } + + i += jmax << 1; + + } + + calcF2E(fftFrameSize, data, i, nstep, w); + + } + + // Perform Factor-4 Decomposition with 3 * complex operators and 8 +/- + // complex operators + private final static void calcF4I(int fftFrameSize, double[] data, int i, + int nstep, double[] w) { + final int fftFrameSize2 = fftFrameSize << 1; // 2*fftFrameSize; + // Factor-4 Decomposition + + int w_len = w.length >> 1; + while (nstep < fftFrameSize2) { + + if (nstep << 2 == fftFrameSize2) { + // Goto Factor-4 Final Decomposition + // calcF4E(data, i, nstep, 1, w); + calcF4IE(fftFrameSize, data, i, nstep, w); + return; + } + int jmax = nstep; + int nnstep = nstep << 1; + if (nnstep == fftFrameSize2) { + // Factor-4 Decomposition not possible + calcF2E(fftFrameSize, data, i, nstep, w); + return; + } + nstep <<= 2; + int ii = i + jmax; + int iii = i + w_len; + { + i += 2; + ii += 2; + iii += 2; + + for (int n = 0; n < fftFrameSize2; n += nstep) { + int m = n + jmax; + + double datam1_r = data[m]; + double datam1_i = data[m + 1]; + double datan1_r = data[n]; + double datan1_i = data[n + 1]; + + n += nnstep; + m += nnstep; + double datam2_r = data[m]; + double datam2_i = data[m + 1]; + double datan2_r = data[n]; + double datan2_i = data[n + 1]; + + double tempr = datam1_r; + double tempi = datam1_i; + + datam1_r = datan1_r - tempr; + datam1_i = datan1_i - tempi; + datan1_r = datan1_r + tempr; + datan1_i = datan1_i + tempi; + + double n2w1r = datan2_r; + double n2w1i = datan2_i; + double m2ww1r = datam2_r; + double m2ww1i = datam2_i; + + tempr = n2w1r - m2ww1r; + tempi = n2w1i - m2ww1i; + + datam2_r = datam1_r + tempi; + datam2_i = datam1_i - tempr; + datam1_r = datam1_r - tempi; + datam1_i = datam1_i + tempr; + + tempr = n2w1r + m2ww1r; + tempi = n2w1i + m2ww1i; + + datan2_r = datan1_r - tempr; + datan2_i = datan1_i - tempi; + datan1_r = datan1_r + tempr; + datan1_i = datan1_i + tempi; + + data[m] = datam2_r; + data[m + 1] = datam2_i; + data[n] = datan2_r; + data[n + 1] = datan2_i; + + n -= nnstep; + m -= nnstep; + data[m] = datam1_r; + data[m + 1] = datam1_i; + data[n] = datan1_r; + data[n + 1] = datan1_i; + + } + + } + for (int j = 2; j < jmax; j += 2) { + double wr = w[i++]; + double wi = w[i++]; + double wr1 = w[ii++]; + double wi1 = w[ii++]; + double wwr1 = w[iii++]; + double wwi1 = w[iii++]; + // double wwr1 = wr * wr1 - wi * wi1; // these numbers can be + // precomputed!!! + // double wwi1 = wr * wi1 + wi * wr1; + + for (int n = j; n < fftFrameSize2; n += nstep) { + int m = n + jmax; + + double datam1_r = data[m]; + double datam1_i = data[m + 1]; + double datan1_r = data[n]; + double datan1_i = data[n + 1]; + + n += nnstep; + m += nnstep; + double datam2_r = data[m]; + double datam2_i = data[m + 1]; + double datan2_r = data[n]; + double datan2_i = data[n + 1]; + + double tempr = datam1_r * wr - datam1_i * wi; + double tempi = datam1_r * wi + datam1_i * wr; + + datam1_r = datan1_r - tempr; + datam1_i = datan1_i - tempi; + datan1_r = datan1_r + tempr; + datan1_i = datan1_i + tempi; + + double n2w1r = datan2_r * wr1 - datan2_i * wi1; + double n2w1i = datan2_r * wi1 + datan2_i * wr1; + double m2ww1r = datam2_r * wwr1 - datam2_i * wwi1; + double m2ww1i = datam2_r * wwi1 + datam2_i * wwr1; + + tempr = n2w1r - m2ww1r; + tempi = n2w1i - m2ww1i; + + datam2_r = datam1_r + tempi; + datam2_i = datam1_i - tempr; + datam1_r = datam1_r - tempi; + datam1_i = datam1_i + tempr; + + tempr = n2w1r + m2ww1r; + tempi = n2w1i + m2ww1i; + + datan2_r = datan1_r - tempr; + datan2_i = datan1_i - tempi; + datan1_r = datan1_r + tempr; + datan1_i = datan1_i + tempi; + + data[m] = datam2_r; + data[m + 1] = datam2_i; + data[n] = datan2_r; + data[n + 1] = datan2_i; + + n -= nnstep; + m -= nnstep; + data[m] = datam1_r; + data[m + 1] = datam1_i; + data[n] = datan1_r; + data[n + 1] = datan1_i; + + } + } + + i += jmax << 1; + + } + + calcF2E(fftFrameSize, data, i, nstep, w); + + } + + // Perform Factor-4 Decomposition with 3 * complex operators and 8 +/- + // complex operators + private final static void calcF4FE(int fftFrameSize, double[] data, int i, + int nstep, double[] w) { + final int fftFrameSize2 = fftFrameSize << 1; // 2*fftFrameSize; + // Factor-4 Decomposition + + int w_len = w.length >> 1; + while (nstep < fftFrameSize2) { + + int jmax = nstep; + int nnstep = nstep << 1; + if (nnstep == fftFrameSize2) { + // Factor-4 Decomposition not possible + calcF2E(fftFrameSize, data, i, nstep, w); + return; + } + nstep <<= 2; + int ii = i + jmax; + int iii = i + w_len; + for (int n = 0; n < jmax; n += 2) { + double wr = w[i++]; + double wi = w[i++]; + double wr1 = w[ii++]; + double wi1 = w[ii++]; + double wwr1 = w[iii++]; + double wwi1 = w[iii++]; + // double wwr1 = wr * wr1 - wi * wi1; // these numbers can be + // precomputed!!! + // double wwi1 = wr * wi1 + wi * wr1; + + int m = n + jmax; + + double datam1_r = data[m]; + double datam1_i = data[m + 1]; + double datan1_r = data[n]; + double datan1_i = data[n + 1]; + + n += nnstep; + m += nnstep; + double datam2_r = data[m]; + double datam2_i = data[m + 1]; + double datan2_r = data[n]; + double datan2_i = data[n + 1]; + + double tempr = datam1_r * wr - datam1_i * wi; + double tempi = datam1_r * wi + datam1_i * wr; + + datam1_r = datan1_r - tempr; + datam1_i = datan1_i - tempi; + datan1_r = datan1_r + tempr; + datan1_i = datan1_i + tempi; + + double n2w1r = datan2_r * wr1 - datan2_i * wi1; + double n2w1i = datan2_r * wi1 + datan2_i * wr1; + double m2ww1r = datam2_r * wwr1 - datam2_i * wwi1; + double m2ww1i = datam2_r * wwi1 + datam2_i * wwr1; + + tempr = m2ww1r - n2w1r; + tempi = m2ww1i - n2w1i; + + datam2_r = datam1_r + tempi; + datam2_i = datam1_i - tempr; + datam1_r = datam1_r - tempi; + datam1_i = datam1_i + tempr; + + tempr = n2w1r + m2ww1r; + tempi = n2w1i + m2ww1i; + + datan2_r = datan1_r - tempr; + datan2_i = datan1_i - tempi; + datan1_r = datan1_r + tempr; + datan1_i = datan1_i + tempi; + + data[m] = datam2_r; + data[m + 1] = datam2_i; + data[n] = datan2_r; + data[n + 1] = datan2_i; + + n -= nnstep; + m -= nnstep; + data[m] = datam1_r; + data[m + 1] = datam1_i; + data[n] = datan1_r; + data[n + 1] = datan1_i; + + } + + i += jmax << 1; + + } + + } + + // Perform Factor-4 Decomposition with 3 * complex operators and 8 +/- + // complex operators + private final static void calcF4IE(int fftFrameSize, double[] data, int i, + int nstep, double[] w) { + final int fftFrameSize2 = fftFrameSize << 1; // 2*fftFrameSize; + // Factor-4 Decomposition + + int w_len = w.length >> 1; + while (nstep < fftFrameSize2) { + + int jmax = nstep; + int nnstep = nstep << 1; + if (nnstep == fftFrameSize2) { + // Factor-4 Decomposition not possible + calcF2E(fftFrameSize, data, i, nstep, w); + return; + } + nstep <<= 2; + int ii = i + jmax; + int iii = i + w_len; + for (int n = 0; n < jmax; n += 2) { + double wr = w[i++]; + double wi = w[i++]; + double wr1 = w[ii++]; + double wi1 = w[ii++]; + double wwr1 = w[iii++]; + double wwi1 = w[iii++]; + // double wwr1 = wr * wr1 - wi * wi1; // these numbers can be + // precomputed!!! + // double wwi1 = wr * wi1 + wi * wr1; + + int m = n + jmax; + + double datam1_r = data[m]; + double datam1_i = data[m + 1]; + double datan1_r = data[n]; + double datan1_i = data[n + 1]; + + n += nnstep; + m += nnstep; + double datam2_r = data[m]; + double datam2_i = data[m + 1]; + double datan2_r = data[n]; + double datan2_i = data[n + 1]; + + double tempr = datam1_r * wr - datam1_i * wi; + double tempi = datam1_r * wi + datam1_i * wr; + + datam1_r = datan1_r - tempr; + datam1_i = datan1_i - tempi; + datan1_r = datan1_r + tempr; + datan1_i = datan1_i + tempi; + + double n2w1r = datan2_r * wr1 - datan2_i * wi1; + double n2w1i = datan2_r * wi1 + datan2_i * wr1; + double m2ww1r = datam2_r * wwr1 - datam2_i * wwi1; + double m2ww1i = datam2_r * wwi1 + datam2_i * wwr1; + + tempr = n2w1r - m2ww1r; + tempi = n2w1i - m2ww1i; + + datam2_r = datam1_r + tempi; + datam2_i = datam1_i - tempr; + datam1_r = datam1_r - tempi; + datam1_i = datam1_i + tempr; + + tempr = n2w1r + m2ww1r; + tempi = n2w1i + m2ww1i; + + datan2_r = datan1_r - tempr; + datan2_i = datan1_i - tempi; + datan1_r = datan1_r + tempr; + datan1_i = datan1_i + tempi; + + data[m] = datam2_r; + data[m + 1] = datam2_i; + data[n] = datan2_r; + data[n + 1] = datan2_i; + + n -= nnstep; + m -= nnstep; + data[m] = datam1_r; + data[m + 1] = datam1_i; + data[n] = datan1_r; + data[n + 1] = datan1_i; + + } + + i += jmax << 1; + + } + + } + + private final void bitreversal(double[] data) { + if (fftFrameSize < 4) + return; + + int inverse = fftFrameSize2 - 2; + for (int i = 0; i < fftFrameSize; i += 4) { + int j = bitm_array[i]; + + // Performing Bit-Reversal, even v.s. even, O(2N) + if (i < j) { + + int n = i; + int m = j; + + // COMPLEX: SWAP(data[n], data[m]) + // Real Part + double tempr = data[n]; + data[n] = data[m]; + data[m] = tempr; + // Imagery Part + n++; + m++; + double tempi = data[n]; + data[n] = data[m]; + data[m] = tempi; + + n = inverse - i; + m = inverse - j; + + // COMPLEX: SWAP(data[n], data[m]) + // Real Part + tempr = data[n]; + data[n] = data[m]; + data[m] = tempr; + // Imagery Part + n++; + m++; + tempi = data[n]; + data[n] = data[m]; + data[m] = tempi; + } + + // Performing Bit-Reversal, odd v.s. even, O(N) + + int m = j + fftFrameSize; // bitm_array[i+2]; + // COMPLEX: SWAP(data[n], data[m]) + // Real Part + int n = i + 2; + double tempr = data[n]; + data[n] = data[m]; + data[m] = tempr; + // Imagery Part + n++; + m++; + double tempi = data[n]; + data[n] = data[m]; + data[m] = tempi; + } + + } +} diff --git a/jdk/src/share/classes/com/sun/media/sound/InvalidDataException.java b/jdk/src/share/classes/com/sun/media/sound/InvalidDataException.java new file mode 100644 index 00000000000..ab46ef370d5 --- /dev/null +++ b/jdk/src/share/classes/com/sun/media/sound/InvalidDataException.java @@ -0,0 +1,45 @@ +/* + * 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. 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 + * 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. + */ +package com.sun.media.sound; + +import java.io.IOException; + +/** + * This exception is used when a file contains illegal or unexpected data. + * + * @author Karl Helgason + */ +public class InvalidDataException extends IOException { + + private static final long serialVersionUID = 1L; + + public InvalidDataException() { + super("Invalid Data!"); + } + + public InvalidDataException(String s) { + super(s); + } +} diff --git a/jdk/src/share/classes/com/sun/media/sound/InvalidFormatException.java b/jdk/src/share/classes/com/sun/media/sound/InvalidFormatException.java new file mode 100644 index 00000000000..96aaa02250e --- /dev/null +++ b/jdk/src/share/classes/com/sun/media/sound/InvalidFormatException.java @@ -0,0 +1,44 @@ +/* + * 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. 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 + * 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. + */ +package com.sun.media.sound; + +/** + * This exception is used when a reader is used to read file of a format + * it doesn't unterstand or support. + * + * @author Karl Helgason + */ +public class InvalidFormatException extends InvalidDataException { + + private static final long serialVersionUID = 1L; + + public InvalidFormatException() { + super("Invalid format!"); + } + + public InvalidFormatException(String s) { + super(s); + } +} diff --git a/jdk/src/share/classes/com/sun/media/sound/JARSoundbankReader.java b/jdk/src/share/classes/com/sun/media/sound/JARSoundbankReader.java new file mode 100644 index 00000000000..442fe72c31a --- /dev/null +++ b/jdk/src/share/classes/com/sun/media/sound/JARSoundbankReader.java @@ -0,0 +1,120 @@ +/* + * 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. 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 + * 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. + */ +package com.sun.media.sound; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import javax.sound.midi.InvalidMidiDataException; +import javax.sound.midi.Soundbank; +import javax.sound.midi.spi.SoundbankReader; + +/** + * JarSoundbankReader is used to read sounbank object from jar files. + * + * @author Karl Helgason + */ +public class JARSoundbankReader extends SoundbankReader { + + public boolean isZIP(URL url) { + boolean ok = false; + try { + InputStream stream = url.openStream(); + try { + byte[] buff = new byte[4]; + ok = stream.read(buff) == 4; + if (ok) { + ok = (buff[0] == 0x50 + && buff[1] == 0x4b + && buff[2] == 0x03 + && buff[3] == 0x04); + } + } finally { + stream.close(); + } + } catch (IOException e) { + } + return ok; + } + + public Soundbank getSoundbank(URL url) + throws InvalidMidiDataException, IOException { + if (!isZIP(url)) + return null; + ArrayList soundbanks = new ArrayList(); + URLClassLoader ucl = URLClassLoader.newInstance(new URL[]{url}); + InputStream stream = ucl.getResourceAsStream( + "META-INF/services/javax.sound.midi.Soundbank"); + if (stream == null) + return null; + try + { + BufferedReader r = new BufferedReader(new InputStreamReader(stream)); + String line = r.readLine(); + while (line != null) { + if (!line.startsWith("#")) { + try { + Class c = Class.forName(line.trim(), true, ucl); + Object o = c.newInstance(); + if (o instanceof Soundbank) { + soundbanks.add((Soundbank) o); + } + } catch (ClassNotFoundException e) { + } catch (InstantiationException e) { + } catch (IllegalAccessException e) { + } + } + line = r.readLine(); + } + } + finally + { + stream.close(); + } + if (soundbanks.size() == 0) + return null; + if (soundbanks.size() == 1) + return soundbanks.get(0); + SimpleSoundbank sbk = new SimpleSoundbank(); + for (Soundbank soundbank : soundbanks) + sbk.addAllInstruments(soundbank); + return sbk; + } + + public Soundbank getSoundbank(InputStream stream) + throws InvalidMidiDataException, IOException { + return null; + } + + public Soundbank getSoundbank(File file) + throws InvalidMidiDataException, IOException { + return getSoundbank(file.toURI().toURL()); + } +} diff --git a/jdk/src/share/classes/com/sun/media/sound/ModelAbstractChannelMixer.java b/jdk/src/share/classes/com/sun/media/sound/ModelAbstractChannelMixer.java new file mode 100644 index 00000000000..37b14fe1a74 --- /dev/null +++ b/jdk/src/share/classes/com/sun/media/sound/ModelAbstractChannelMixer.java @@ -0,0 +1,126 @@ +/* + * 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. 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 + * 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. + */ +package com.sun.media.sound; + +/** + * ModelAbstractChannelMixer is ready for use class to implement + * ModelChannelMixer interface. + * + * @author Karl Helgason + */ +public abstract class ModelAbstractChannelMixer implements ModelChannelMixer { + + public abstract boolean process(float[][] buffer, int offset, int len); + + public abstract void stop(); + + public void allNotesOff() { + } + + public void allSoundOff() { + } + + public void controlChange(int controller, int value) { + } + + public int getChannelPressure() { + return 0; + } + + public int getController(int controller) { + return 0; + } + + public boolean getMono() { + return false; + } + + public boolean getMute() { + return false; + } + + public boolean getOmni() { + return false; + } + + public int getPitchBend() { + return 0; + } + + public int getPolyPressure(int noteNumber) { + return 0; + } + + public int getProgram() { + return 0; + } + + public boolean getSolo() { + return false; + } + + public boolean localControl(boolean on) { + return false; + } + + public void noteOff(int noteNumber) { + } + + public void noteOff(int noteNumber, int velocity) { + } + + public void noteOn(int noteNumber, int velocity) { + } + + public void programChange(int program) { + } + + public void programChange(int bank, int program) { + } + + public void resetAllControllers() { + } + + public void setChannelPressure(int pressure) { + } + + public void setMono(boolean on) { + } + + public void setMute(boolean mute) { + } + + public void setOmni(boolean on) { + } + + public void setPitchBend(int bend) { + } + + public void setPolyPressure(int noteNumber, int pressure) { + } + + public void setSolo(boolean soloState) { + } +} diff --git a/jdk/src/share/classes/com/sun/media/sound/ModelAbstractOscillator.java b/jdk/src/share/classes/com/sun/media/sound/ModelAbstractOscillator.java new file mode 100644 index 00000000000..5d5c7e937af --- /dev/null +++ b/jdk/src/share/classes/com/sun/media/sound/ModelAbstractOscillator.java @@ -0,0 +1,200 @@ +/* + * 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. 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 + * 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. + */ +package com.sun.media.sound; + +import java.io.IOException; +import javax.sound.midi.Instrument; +import javax.sound.midi.MidiChannel; +import javax.sound.midi.Patch; +import javax.sound.midi.Soundbank; +import javax.sound.midi.SoundbankResource; +import javax.sound.midi.VoiceStatus; + +/** + * A abstract class used to simplify creating custom ModelOscillator. + * + * @author Karl Helgason + */ +public abstract class ModelAbstractOscillator + implements ModelOscillator, ModelOscillatorStream, Soundbank { + + protected float pitch = 6000; + protected float samplerate; + protected MidiChannel channel; + protected VoiceStatus voice; + protected int noteNumber; + protected int velocity; + protected boolean on = false; + + public void init() { + } + + public void close() throws IOException { + } + + public void noteOff(int velocity) { + on = false; + } + + public void noteOn(MidiChannel channel, VoiceStatus voice, int noteNumber, + int velocity) { + this.channel = channel; + this.voice = voice; + this.noteNumber = noteNumber; + this.velocity = velocity; + on = true; + } + + public int read(float[][] buffer, int offset, int len) throws IOException { + return -1; + } + + public MidiChannel getChannel() { + return channel; + } + + public VoiceStatus getVoice() { + return voice; + } + + public int getNoteNumber() { + return noteNumber; + } + + public int getVelocity() { + return velocity; + } + + public boolean isOn() { + return on; + } + + public void setPitch(float pitch) { + this.pitch = pitch; + } + + public float getPitch() { + return pitch; + } + + public void setSampleRate(float samplerate) { + this.samplerate = samplerate; + } + + public float getSampleRate() { + return samplerate; + } + + public float getAttenuation() { + return 0; + } + + public int getChannels() { + return 1; + } + + public String getName() { + return getClass().getName(); + } + + public Patch getPatch() { + return new Patch(0, 0); + } + + public ModelOscillatorStream open(float samplerate) { + ModelAbstractOscillator oscs; + try { + oscs = this.getClass().newInstance(); + } catch (InstantiationException e) { + throw new IllegalArgumentException(e); + } catch (IllegalAccessException e) { + throw new IllegalArgumentException(e); + } + oscs.setSampleRate(samplerate); + oscs.init(); + return oscs; + } + + public ModelPerformer getPerformer() { + // Create performer for my custom oscillirator + ModelPerformer performer = new ModelPerformer(); + performer.getOscillators().add(this); + return performer; + + } + + public ModelInstrument getInstrument() { + // Create Instrument object around my performer + SimpleInstrument ins = new SimpleInstrument(); + ins.setName(getName()); + ins.add(getPerformer()); + ins.setPatch(getPatch()); + return ins; + + } + + public Soundbank getSoundBank() { + // Create Soundbank object around the instrument + SimpleSoundbank sbk = new SimpleSoundbank(); + sbk.addInstrument(getInstrument()); + return sbk; + } + + public String getDescription() { + return getName(); + } + + public Instrument getInstrument(Patch patch) { + Instrument ins = getInstrument(); + Patch p = ins.getPatch(); + if (p.getBank() != patch.getBank()) + return null; + if (p.getProgram() != patch.getProgram()) + return null; + if (p instanceof ModelPatch && patch instanceof ModelPatch) { + if (((ModelPatch)p).isPercussion() + != ((ModelPatch)patch).isPercussion()) { + return null; + } + } + return ins; + } + + public Instrument[] getInstruments() { + return new Instrument[]{getInstrument()}; + } + + public SoundbankResource[] getResources() { + return new SoundbankResource[0]; + } + + public String getVendor() { + return null; + } + + public String getVersion() { + return null; + } +} diff --git a/jdk/src/share/classes/com/sun/media/sound/ModelByteBuffer.java b/jdk/src/share/classes/com/sun/media/sound/ModelByteBuffer.java new file mode 100644 index 00000000000..16c1125fb61 --- /dev/null +++ b/jdk/src/share/classes/com/sun/media/sound/ModelByteBuffer.java @@ -0,0 +1,329 @@ +/* + * 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. 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 + * 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. + */ +package com.sun.media.sound; + +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.RandomAccessFile; +import java.util.Collection; + +/** + * This class is a pointer to a binary array either in memory or on disk. + * + * @author Karl Helgason + */ +public class ModelByteBuffer { + + private ModelByteBuffer root = this; + private File file; + private long fileoffset; + private byte[] buffer; + private long offset; + private final long len; + + private class RandomFileInputStream extends InputStream { + + private RandomAccessFile raf; + private long left; + private long mark = 0; + private long markleft = 0; + + public RandomFileInputStream() throws IOException { + raf = new RandomAccessFile(root.file, "r"); + raf.seek(root.fileoffset + arrayOffset()); + left = capacity(); + } + + public int available() throws IOException { + if (left > Integer.MAX_VALUE) + return Integer.MAX_VALUE; + return (int)left; + } + + public synchronized void mark(int readlimit) { + try { + mark = raf.getFilePointer(); + markleft = left; + } catch (IOException e) { + //e.printStackTrace(); + } + } + + public boolean markSupported() { + return true; + } + + public synchronized void reset() throws IOException { + raf.seek(mark); + left = markleft; + } + + public long skip(long n) throws IOException { + if( n < 0) + return 0; + if (n > left) + n = left; + long p = raf.getFilePointer(); + raf.seek(p + n); + left -= n; + return n; + } + + public int read(byte b[], int off, int len) throws IOException { + if (len > left) + len = (int)left; + if (left == 0) + return -1; + len = raf.read(b, off, len); + if (len == -1) + return -1; + left -= len; + return len; + } + + public int read(byte[] b) throws IOException { + int len = b.length; + if (len > left) + len = (int)left; + if (left == 0) + return -1; + len = raf.read(b, 0, len); + if (len == -1) + return -1; + left -= len; + return len; + } + + public int read() throws IOException { + if (left == 0) + return -1; + int b = raf.read(); + if (b == -1) + return -1; + left--; + return b; + } + + public void close() throws IOException { + raf.close(); + } + } + + private ModelByteBuffer(ModelByteBuffer parent, + long beginIndex, long endIndex, boolean independent) { + this.root = parent.root; + this.offset = 0; + long parent_len = parent.len; + if (beginIndex < 0) + beginIndex = 0; + if (beginIndex > parent_len) + beginIndex = parent_len; + if (endIndex < 0) + endIndex = 0; + if (endIndex > parent_len) + endIndex = parent_len; + if (beginIndex > endIndex) + beginIndex = endIndex; + offset = beginIndex; + len = endIndex - beginIndex; + if (independent) { + buffer = root.buffer; + if (root.file != null) { + file = root.file; + fileoffset = root.fileoffset + arrayOffset(); + offset = 0; + } else + offset = arrayOffset(); + root = this; + } + } + + public ModelByteBuffer(byte[] buffer) { + this.buffer = buffer; + this.offset = 0; + this.len = buffer.length; + } + + public ModelByteBuffer(byte[] buffer, int offset, int len) { + this.buffer = buffer; + this.offset = offset; + this.len = len; + } + + public ModelByteBuffer(File file) { + this.file = file; + this.fileoffset = 0; + this.len = file.length(); + } + + public ModelByteBuffer(File file, long offset, long len) { + this.file = file; + this.fileoffset = offset; + this.len = len; + } + + public void writeTo(OutputStream out) throws IOException { + if (root.file != null && root.buffer == null) { + InputStream is = getInputStream(); + byte[] buff = new byte[1024]; + int ret; + while ((ret = is.read(buff)) != -1) + out.write(buff, 0, ret); + } else + out.write(array(), (int) arrayOffset(), (int) capacity()); + } + + public InputStream getInputStream() { + if (root.file != null && root.buffer == null) { + try { + return new RandomFileInputStream(); + } catch (IOException e) { + //e.printStackTrace(); + return null; + } + } + return new ByteArrayInputStream(array(), + (int)arrayOffset(), (int)capacity()); + } + + public ModelByteBuffer subbuffer(long beginIndex) { + return subbuffer(beginIndex, capacity()); + } + + public ModelByteBuffer subbuffer(long beginIndex, long endIndex) { + return subbuffer(beginIndex, endIndex, false); + } + + public ModelByteBuffer subbuffer(long beginIndex, long endIndex, + boolean independent) { + return new ModelByteBuffer(this, beginIndex, endIndex, independent); + } + + public byte[] array() { + return root.buffer; + } + + public long arrayOffset() { + if (root != this) + return root.arrayOffset() + offset; + return offset; + } + + public long capacity() { + return len; + } + + public ModelByteBuffer getRoot() { + return root; + } + + public File getFile() { + return file; + } + + public long getFilePointer() { + return fileoffset; + } + + public static void loadAll(Collection col) + throws IOException { + File selfile = null; + RandomAccessFile raf = null; + try { + for (ModelByteBuffer mbuff : col) { + mbuff = mbuff.root; + if (mbuff.file == null) + continue; + if (mbuff.buffer != null) + continue; + if (selfile == null || !selfile.equals(mbuff.file)) { + if (raf != null) { + raf.close(); + raf = null; + } + selfile = mbuff.file; + raf = new RandomAccessFile(mbuff.file, "r"); + } + raf.seek(mbuff.fileoffset); + byte[] buffer = new byte[(int) mbuff.capacity()]; + + int read = 0; + int avail = buffer.length; + while (read != avail) { + if (avail - read > 65536) { + raf.readFully(buffer, read, 65536); + read += 65536; + } else { + raf.readFully(buffer, read, avail - read); + read = avail; + } + + } + + mbuff.buffer = buffer; + mbuff.offset = 0; + } + } finally { + if (raf != null) + raf.close(); + } + } + + public void load() throws IOException { + if (root != this) { + root.load(); + return; + } + if (buffer != null) + return; + if (file == null) { + throw new IllegalStateException( + "No file associated with this ByteBuffer!"); + } + + DataInputStream is = new DataInputStream(getInputStream()); + buffer = new byte[(int) capacity()]; + offset = 0; + is.readFully(buffer); + is.close(); + + } + + public void unload() { + if (root != this) { + root.unload(); + return; + } + if (file == null) { + throw new IllegalStateException( + "No file associated with this ByteBuffer!"); + } + root.buffer = null; + } +} diff --git a/jdk/src/share/classes/com/sun/media/sound/ModelByteBufferWavetable.java b/jdk/src/share/classes/com/sun/media/sound/ModelByteBufferWavetable.java new file mode 100644 index 00000000000..d7da52a7643 --- /dev/null +++ b/jdk/src/share/classes/com/sun/media/sound/ModelByteBufferWavetable.java @@ -0,0 +1,281 @@ +/* + * 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. 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 + * 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. + */ +package com.sun.media.sound; + +import java.io.IOException; +import java.io.InputStream; +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.AudioFormat.Encoding; + +/** + * Wavetable oscillator for pre-loaded data. + * + * @author Karl Helgason + */ +public class ModelByteBufferWavetable implements ModelWavetable { + + private class Buffer8PlusInputStream extends InputStream { + + private boolean bigendian; + private int framesize_pc; + int pos = 0; + int pos2 = 0; + int markpos = 0; + int markpos2 = 0; + + public Buffer8PlusInputStream() { + framesize_pc = format.getFrameSize() / format.getChannels(); + bigendian = format.isBigEndian(); + } + + public int read(byte[] b, int off, int len) throws IOException { + int avail = available(); + if (avail <= 0) + return -1; + if (len > avail) + len = avail; + byte[] buff1 = buffer.array(); + byte[] buff2 = buffer8.array(); + pos += buffer.arrayOffset(); + pos2 += buffer8.arrayOffset(); + if (bigendian) { + for (int i = 0; i < len; i += (framesize_pc + 1)) { + System.arraycopy(buff1, pos, b, i, framesize_pc); + System.arraycopy(buff2, pos2, b, i + framesize_pc, 1); + pos += framesize_pc; + pos2 += 1; + } + } else { + for (int i = 0; i < len; i += (framesize_pc + 1)) { + System.arraycopy(buff2, pos2, b, i, 1); + System.arraycopy(buff1, pos, b, i + 1, framesize_pc); + pos += framesize_pc; + pos2 += 1; + } + } + pos -= buffer.arrayOffset(); + pos2 -= buffer8.arrayOffset(); + return len; + } + + public long skip(long n) throws IOException { + int avail = available(); + if (avail <= 0) + return -1; + if (n > avail) + n = avail; + pos += (n / (framesize_pc + 1)) * (framesize_pc); + pos2 += n / (framesize_pc + 1); + return super.skip(n); + } + + public int read(byte[] b) throws IOException { + return read(b, 0, b.length); + } + + public int read() throws IOException { + byte[] b = new byte[1]; + int ret = read(b, 0, 1); + if (ret == -1) + return -1; + return 0 & 0xFF; + } + + public boolean markSupported() { + return true; + } + + public int available() throws IOException { + return (int)buffer.capacity() + (int)buffer8.capacity() - pos - pos2; + } + + public synchronized void mark(int readlimit) { + markpos = pos; + markpos2 = pos2; + } + + public synchronized void reset() throws IOException { + pos = markpos; + pos2 = markpos2; + + } + } + + private float loopStart = -1; + private float loopLength = -1; + private ModelByteBuffer buffer; + private ModelByteBuffer buffer8 = null; + private AudioFormat format = null; + private float pitchcorrection = 0; + private float attenuation = 0; + private int loopType = LOOP_TYPE_OFF; + + public ModelByteBufferWavetable(ModelByteBuffer buffer) { + this.buffer = buffer; + } + + public ModelByteBufferWavetable(ModelByteBuffer buffer, + float pitchcorrection) { + this.buffer = buffer; + this.pitchcorrection = pitchcorrection; + } + + public ModelByteBufferWavetable(ModelByteBuffer buffer, AudioFormat format) { + this.format = format; + this.buffer = buffer; + } + + public ModelByteBufferWavetable(ModelByteBuffer buffer, AudioFormat format, + float pitchcorrection) { + this.format = format; + this.buffer = buffer; + this.pitchcorrection = pitchcorrection; + } + + public void set8BitExtensionBuffer(ModelByteBuffer buffer) { + buffer8 = buffer; + } + + public ModelByteBuffer get8BitExtensionBuffer() { + return buffer8; + } + + public ModelByteBuffer getBuffer() { + return buffer; + } + + public AudioFormat getFormat() { + if (format == null) { + if (buffer == null) + return null; + InputStream is = buffer.getInputStream(); + AudioFormat format = null; + try { + format = AudioSystem.getAudioFileFormat(is).getFormat(); + } catch (Exception e) { + //e.printStackTrace(); + } + try { + is.close(); + } catch (IOException e) { + //e.printStackTrace(); + } + return format; + } + return format; + } + + public AudioFloatInputStream openStream() { + if (buffer == null) + return null; + if (format == null) { + InputStream is = buffer.getInputStream(); + AudioInputStream ais = null; + try { + ais = AudioSystem.getAudioInputStream(is); + } catch (Exception e) { + //e.printStackTrace(); + return null; + } + return AudioFloatInputStream.getInputStream(ais); + } + if (buffer.array() == null) { + return AudioFloatInputStream.getInputStream(new AudioInputStream( + buffer.getInputStream(), format, buffer.capacity())); + } + if (buffer8 != null) { + if (format.getEncoding().equals(Encoding.PCM_SIGNED) + || format.getEncoding().equals(Encoding.PCM_UNSIGNED)) { + InputStream is = new Buffer8PlusInputStream(); + AudioFormat format2 = new AudioFormat( + format.getEncoding(), + format.getSampleRate(), + format.getSampleSizeInBits() + 8, + format.getChannels(), + format.getFrameSize() + (1 * format.getChannels()), + format.getFrameRate(), + format.isBigEndian()); + + AudioInputStream ais = new AudioInputStream(is, format2, + buffer.capacity() / format.getFrameSize()); + return AudioFloatInputStream.getInputStream(ais); + } + } + return AudioFloatInputStream.getInputStream(format, buffer.array(), + (int)buffer.arrayOffset(), (int)buffer.capacity()); + } + + public int getChannels() { + return getFormat().getChannels(); + } + + public ModelOscillatorStream open(float samplerate) { + // ModelWavetableOscillator doesn't support ModelOscillatorStream + return null; + } + + // attenuation is in cB + public float getAttenuation() { + return attenuation; + } + // attenuation is in cB + public void setAttenuation(float attenuation) { + this.attenuation = attenuation; + } + + public float getLoopLength() { + return loopLength; + } + + public void setLoopLength(float loopLength) { + this.loopLength = loopLength; + } + + public float getLoopStart() { + return loopStart; + } + + public void setLoopStart(float loopStart) { + this.loopStart = loopStart; + } + + public void setLoopType(int loopType) { + this.loopType = loopType; + } + + public int getLoopType() { + return loopType; + } + + public float getPitchcorrection() { + return pitchcorrection; + } + + public void setPitchcorrection(float pitchcorrection) { + this.pitchcorrection = pitchcorrection; + } +} diff --git a/jdk/src/share/classes/com/sun/media/sound/ModelChannelMixer.java b/jdk/src/share/classes/com/sun/media/sound/ModelChannelMixer.java new file mode 100644 index 00000000000..1f6dfd6e97d --- /dev/null +++ b/jdk/src/share/classes/com/sun/media/sound/ModelChannelMixer.java @@ -0,0 +1,50 @@ +/* + * 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. 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 + * 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. + */ +package com.sun.media.sound; + +import javax.sound.midi.MidiChannel; + +/** + * ModelChannelMixer is used to process channel voice mix output before going + * to master output.
+ * It can be used to:
+ *