Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
ab9e1ef1
D
dragonwell8_jdk
项目概览
openanolis
/
dragonwell8_jdk
通知
4
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_jdk
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
ab9e1ef1
编写于
9月 28, 2012
作者:
P
peytoia
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
7069824: Support for BCP47 locale matching
Reviewed-by: naoto, okutsu
上级
05cd8405
变更
6
展开全部
隐藏空白更改
内联
并排
Showing
6 changed file
with
48575 addition
and
4 deletion
+48575
-4
src/share/classes/java/util/Locale.java
src/share/classes/java/util/Locale.java
+684
-4
src/share/classes/sun/util/locale/LocaleEquivalentMaps.java
src/share/classes/sun/util/locale/LocaleEquivalentMaps.java
+204
-0
src/share/classes/sun/util/locale/LocaleMatcher.java
src/share/classes/sun/util/locale/LocaleMatcher.java
+455
-0
test/java/util/Locale/Bug7069824.java
test/java/util/Locale/Bug7069824.java
+1006
-0
test/java/util/Locale/tools/EquivMapsGenerator.java
test/java/util/Locale/tools/EquivMapsGenerator.java
+251
-0
test/java/util/Locale/tools/language-subtag-registry.txt
test/java/util/Locale/tools/language-subtag-registry.txt
+45975
-0
未找到文件。
src/share/classes/java/util/Locale.java
浏览文件 @
ab9e1ef1
此差异已折叠。
点击以展开。
src/share/classes/sun/util/locale/LocaleEquivalentMaps.java
0 → 100644
浏览文件 @
ab9e1ef1
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package
sun.util.locale
;
import
java.util.HashMap
;
import
java.util.Map
;
/**
* Locale equivalent map for BCP47 Locale matching
*/
final
class
LocaleEquivalentMaps
{
static
final
Map
<
String
,
String
>
singleEquivMap
;
static
final
Map
<
String
,
String
[]>
multiEquivsMap
;
static
final
Map
<
String
,
String
>
regionVariantEquivMap
;
static
{
singleEquivMap
=
new
HashMap
<>();
multiEquivsMap
=
new
HashMap
<>();
regionVariantEquivMap
=
new
HashMap
<>();
// This is an auto-generated file and should not be manually edited.
// LSR Revision: 2012-09-04
singleEquivMap
.
put
(
"ami"
,
"i-ami"
);
singleEquivMap
.
put
(
"art-lojban"
,
"jbo"
);
singleEquivMap
.
put
(
"ase"
,
"sgn-us"
);
singleEquivMap
.
put
(
"ayx"
,
"nun"
);
singleEquivMap
.
put
(
"bfi"
,
"sgn-gb"
);
singleEquivMap
.
put
(
"bjd"
,
"drl"
);
singleEquivMap
.
put
(
"bnn"
,
"i-bnn"
);
singleEquivMap
.
put
(
"bzs"
,
"sgn-br"
);
singleEquivMap
.
put
(
"cjr"
,
"mom"
);
singleEquivMap
.
put
(
"cka"
,
"cmr"
);
singleEquivMap
.
put
(
"cmk"
,
"xch"
);
singleEquivMap
.
put
(
"cmn-hans"
,
"zh-cmn-hans"
);
singleEquivMap
.
put
(
"cmn-hant"
,
"zh-cmn-hant"
);
singleEquivMap
.
put
(
"cmr"
,
"cka"
);
singleEquivMap
.
put
(
"csn"
,
"sgn-co"
);
singleEquivMap
.
put
(
"dev"
,
"gav"
);
singleEquivMap
.
put
(
"drh"
,
"khk"
);
singleEquivMap
.
put
(
"drl"
,
"bjd"
);
singleEquivMap
.
put
(
"dse"
,
"sgn-nl"
);
singleEquivMap
.
put
(
"dsl"
,
"sgn-dk"
);
singleEquivMap
.
put
(
"fsl"
,
"sgn-fr"
);
singleEquivMap
.
put
(
"gan"
,
"zh-gan"
);
singleEquivMap
.
put
(
"gav"
,
"dev"
);
singleEquivMap
.
put
(
"gsg"
,
"sgn-de"
);
singleEquivMap
.
put
(
"gss"
,
"sgn-gr"
);
singleEquivMap
.
put
(
"he"
,
"iw"
);
singleEquivMap
.
put
(
"hle"
,
"sca"
);
singleEquivMap
.
put
(
"hrr"
,
"jal"
);
singleEquivMap
.
put
(
"hsn"
,
"zh-xiang"
);
singleEquivMap
.
put
(
"i-ami"
,
"ami"
);
singleEquivMap
.
put
(
"i-bnn"
,
"bnn"
);
singleEquivMap
.
put
(
"i-klingon"
,
"tlh"
);
singleEquivMap
.
put
(
"i-lux"
,
"lb"
);
singleEquivMap
.
put
(
"i-navajo"
,
"nv"
);
singleEquivMap
.
put
(
"i-pwn"
,
"pwn"
);
singleEquivMap
.
put
(
"i-tao"
,
"tao"
);
singleEquivMap
.
put
(
"i-tay"
,
"tay"
);
singleEquivMap
.
put
(
"i-tsu"
,
"tsu"
);
singleEquivMap
.
put
(
"ibi"
,
"opa"
);
singleEquivMap
.
put
(
"id"
,
"in"
);
singleEquivMap
.
put
(
"in"
,
"id"
);
singleEquivMap
.
put
(
"ise"
,
"sgn-it"
);
singleEquivMap
.
put
(
"isg"
,
"sgn-ie"
);
singleEquivMap
.
put
(
"iw"
,
"he"
);
singleEquivMap
.
put
(
"jal"
,
"hrr"
);
singleEquivMap
.
put
(
"jbo"
,
"art-lojban"
);
singleEquivMap
.
put
(
"ji"
,
"yi"
);
singleEquivMap
.
put
(
"jsl"
,
"sgn-jp"
);
singleEquivMap
.
put
(
"jv"
,
"jw"
);
singleEquivMap
.
put
(
"jw"
,
"jv"
);
singleEquivMap
.
put
(
"kgh"
,
"kml"
);
singleEquivMap
.
put
(
"khk"
,
"drh"
);
singleEquivMap
.
put
(
"kml"
,
"kgh"
);
singleEquivMap
.
put
(
"lb"
,
"i-lux"
);
singleEquivMap
.
put
(
"lcq"
,
"ppr"
);
singleEquivMap
.
put
(
"lrr"
,
"yma"
);
singleEquivMap
.
put
(
"mfs"
,
"sgn-mx"
);
singleEquivMap
.
put
(
"mo"
,
"ro"
);
singleEquivMap
.
put
(
"mom"
,
"cjr"
);
singleEquivMap
.
put
(
"nan"
,
"zh-min-nan"
);
singleEquivMap
.
put
(
"nb"
,
"no-bok"
);
singleEquivMap
.
put
(
"ncs"
,
"sgn-ni"
);
singleEquivMap
.
put
(
"nn"
,
"no-nyn"
);
singleEquivMap
.
put
(
"no-bok"
,
"nb"
);
singleEquivMap
.
put
(
"no-nyn"
,
"nn"
);
singleEquivMap
.
put
(
"nsl"
,
"sgn-no"
);
singleEquivMap
.
put
(
"nun"
,
"ayx"
);
singleEquivMap
.
put
(
"nv"
,
"i-navajo"
);
singleEquivMap
.
put
(
"opa"
,
"ibi"
);
singleEquivMap
.
put
(
"ppr"
,
"lcq"
);
singleEquivMap
.
put
(
"psr"
,
"sgn-pt"
);
singleEquivMap
.
put
(
"pwn"
,
"i-pwn"
);
singleEquivMap
.
put
(
"ras"
,
"tie"
);
singleEquivMap
.
put
(
"ro"
,
"mo"
);
singleEquivMap
.
put
(
"sca"
,
"hle"
);
singleEquivMap
.
put
(
"sfb"
,
"sgn-be-fr"
);
singleEquivMap
.
put
(
"sfs"
,
"sgn-za"
);
singleEquivMap
.
put
(
"sgg"
,
"sgn-ch-de"
);
singleEquivMap
.
put
(
"sgn-be-fr"
,
"sfb"
);
singleEquivMap
.
put
(
"sgn-be-nl"
,
"vgt"
);
singleEquivMap
.
put
(
"sgn-br"
,
"bzs"
);
singleEquivMap
.
put
(
"sgn-ch-de"
,
"sgg"
);
singleEquivMap
.
put
(
"sgn-co"
,
"csn"
);
singleEquivMap
.
put
(
"sgn-de"
,
"gsg"
);
singleEquivMap
.
put
(
"sgn-dk"
,
"dsl"
);
singleEquivMap
.
put
(
"sgn-es"
,
"ssp"
);
singleEquivMap
.
put
(
"sgn-fr"
,
"fsl"
);
singleEquivMap
.
put
(
"sgn-gb"
,
"bfi"
);
singleEquivMap
.
put
(
"sgn-gr"
,
"gss"
);
singleEquivMap
.
put
(
"sgn-ie"
,
"isg"
);
singleEquivMap
.
put
(
"sgn-it"
,
"ise"
);
singleEquivMap
.
put
(
"sgn-jp"
,
"jsl"
);
singleEquivMap
.
put
(
"sgn-mx"
,
"mfs"
);
singleEquivMap
.
put
(
"sgn-ni"
,
"ncs"
);
singleEquivMap
.
put
(
"sgn-nl"
,
"dse"
);
singleEquivMap
.
put
(
"sgn-no"
,
"nsl"
);
singleEquivMap
.
put
(
"sgn-pt"
,
"psr"
);
singleEquivMap
.
put
(
"sgn-se"
,
"swl"
);
singleEquivMap
.
put
(
"sgn-us"
,
"ase"
);
singleEquivMap
.
put
(
"sgn-za"
,
"sfs"
);
singleEquivMap
.
put
(
"ssp"
,
"sgn-es"
);
singleEquivMap
.
put
(
"swl"
,
"sgn-se"
);
singleEquivMap
.
put
(
"tao"
,
"i-tao"
);
singleEquivMap
.
put
(
"tay"
,
"i-tay"
);
singleEquivMap
.
put
(
"tie"
,
"ras"
);
singleEquivMap
.
put
(
"tkk"
,
"twm"
);
singleEquivMap
.
put
(
"tlh"
,
"i-klingon"
);
singleEquivMap
.
put
(
"tlw"
,
"weo"
);
singleEquivMap
.
put
(
"tsu"
,
"i-tsu"
);
singleEquivMap
.
put
(
"twm"
,
"tkk"
);
singleEquivMap
.
put
(
"vgt"
,
"sgn-be-nl"
);
singleEquivMap
.
put
(
"weo"
,
"tlw"
);
singleEquivMap
.
put
(
"wuu"
,
"zh-wuu"
);
singleEquivMap
.
put
(
"xch"
,
"cmk"
);
singleEquivMap
.
put
(
"yi"
,
"ji"
);
singleEquivMap
.
put
(
"yma"
,
"lrr"
);
singleEquivMap
.
put
(
"yue"
,
"zh-yue"
);
singleEquivMap
.
put
(
"zh-cmn-hans"
,
"cmn-hans"
);
singleEquivMap
.
put
(
"zh-cmn-hant"
,
"cmn-hant"
);
singleEquivMap
.
put
(
"zh-gan"
,
"gan"
);
singleEquivMap
.
put
(
"zh-min-nan"
,
"nan"
);
singleEquivMap
.
put
(
"zh-wuu"
,
"wuu"
);
singleEquivMap
.
put
(
"zh-xiang"
,
"hsn"
);
singleEquivMap
.
put
(
"zh-yue"
,
"yue"
);
multiEquivsMap
.
put
(
"ccq"
,
new
String
[]
{
"rki"
,
"ybd"
});
multiEquivsMap
.
put
(
"cmn"
,
new
String
[]
{
"zh-guoyu"
,
"zh-cmn"
});
multiEquivsMap
.
put
(
"drw"
,
new
String
[]
{
"prs"
,
"tnf"
});
multiEquivsMap
.
put
(
"hak"
,
new
String
[]
{
"i-hak"
,
"zh-hakka"
});
multiEquivsMap
.
put
(
"i-hak"
,
new
String
[]
{
"hak"
,
"zh-hakka"
});
multiEquivsMap
.
put
(
"mry"
,
new
String
[]
{
"mst"
,
"myt"
});
multiEquivsMap
.
put
(
"mst"
,
new
String
[]
{
"mry"
,
"myt"
});
multiEquivsMap
.
put
(
"myt"
,
new
String
[]
{
"mry"
,
"mst"
});
multiEquivsMap
.
put
(
"prs"
,
new
String
[]
{
"drw"
,
"tnf"
});
multiEquivsMap
.
put
(
"rki"
,
new
String
[]
{
"ccq"
,
"ybd"
});
multiEquivsMap
.
put
(
"tnf"
,
new
String
[]
{
"prs"
,
"drw"
});
multiEquivsMap
.
put
(
"ybd"
,
new
String
[]
{
"rki"
,
"ccq"
});
multiEquivsMap
.
put
(
"zh-cmn"
,
new
String
[]
{
"cmn"
,
"zh-guoyu"
});
multiEquivsMap
.
put
(
"zh-guoyu"
,
new
String
[]
{
"cmn"
,
"zh-cmn"
});
multiEquivsMap
.
put
(
"zh-hakka"
,
new
String
[]
{
"hak"
,
"i-hak"
});
regionVariantEquivMap
.
put
(
"-alalc97"
,
"-heploc"
);
regionVariantEquivMap
.
put
(
"-bu"
,
"-mm"
);
regionVariantEquivMap
.
put
(
"-cd"
,
"-zr"
);
regionVariantEquivMap
.
put
(
"-dd"
,
"-de"
);
regionVariantEquivMap
.
put
(
"-de"
,
"-dd"
);
regionVariantEquivMap
.
put
(
"-fr"
,
"-fx"
);
regionVariantEquivMap
.
put
(
"-fx"
,
"-fr"
);
regionVariantEquivMap
.
put
(
"-heploc"
,
"-alalc97"
);
regionVariantEquivMap
.
put
(
"-mm"
,
"-bu"
);
regionVariantEquivMap
.
put
(
"-tl"
,
"-tp"
);
regionVariantEquivMap
.
put
(
"-tp"
,
"-tl"
);
regionVariantEquivMap
.
put
(
"-yd"
,
"-ye"
);
regionVariantEquivMap
.
put
(
"-ye"
,
"-yd"
);
regionVariantEquivMap
.
put
(
"-zr"
,
"-cd"
);
}
}
src/share/classes/sun/util/locale/LocaleMatcher.java
0 → 100644
浏览文件 @
ab9e1ef1
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package
sun.util.locale
;
import
java.util.ArrayList
;
import
java.util.Collection
;
import
java.util.HashMap
;
import
java.util.Iterator
;
import
java.util.LinkedHashMap
;
import
java.util.LinkedList
;
import
java.util.List
;
import
java.util.Locale
;
import
java.util.Locale.*
;
import
static
java
.
util
.
Locale
.
FilteringMode
.*;
import
static
java
.
util
.
Locale
.
LanguageRange
.*;
import
java.util.Map
;
import
java.util.Set
;
/**
* Implementation for BCP47 Locale matching
*
*/
public
final
class
LocaleMatcher
{
public
static
List
<
Locale
>
filter
(
List
<
LanguageRange
>
priorityList
,
Collection
<
Locale
>
locales
,
FilteringMode
mode
)
{
if
(
priorityList
.
isEmpty
()
||
locales
.
isEmpty
())
{
return
new
ArrayList
<>();
// need to return a empty mutable List
}
// Create a list of language tags to be matched.
List
<
String
>
tags
=
new
ArrayList
<>();
for
(
Locale
locale
:
locales
)
{
tags
.
add
(
locale
.
toLanguageTag
());
}
// Filter language tags.
List
<
String
>
filteredTags
=
filterTags
(
priorityList
,
tags
,
mode
);
// Create a list of matching locales.
List
<
Locale
>
filteredLocales
=
new
ArrayList
<>(
filteredTags
.
size
());
for
(
String
tag
:
filteredTags
)
{
filteredLocales
.
add
(
Locale
.
forLanguageTag
(
tag
));
}
return
filteredLocales
;
}
public
static
List
<
String
>
filterTags
(
List
<
LanguageRange
>
priorityList
,
Collection
<
String
>
tags
,
FilteringMode
mode
)
{
if
(
priorityList
.
isEmpty
()
||
tags
.
isEmpty
())
{
return
new
ArrayList
<>();
// need to return a empty mutable List
}
ArrayList
<
LanguageRange
>
list
;
if
(
mode
==
EXTENDED_FILTERING
)
{
return
filterExtended
(
priorityList
,
tags
);
}
else
{
list
=
new
ArrayList
<>();
for
(
LanguageRange
lr
:
priorityList
)
{
String
range
=
lr
.
getRange
();
if
(
range
.
startsWith
(
"*-"
)
||
range
.
indexOf
(
"-*"
)
!=
-
1
)
{
// Extended range
if
(
mode
==
AUTOSELECT_FILTERING
)
{
return
filterExtended
(
priorityList
,
tags
);
}
else
if
(
mode
==
MAP_EXTENDED_RANGES
)
{
if
(
range
.
charAt
(
0
)
==
'*'
)
{
range
=
"*"
;
}
else
{
range
=
range
.
replaceAll
(
"-[*]"
,
""
);
}
list
.
add
(
new
LanguageRange
(
range
,
lr
.
getWeight
()));
}
else
if
(
mode
==
REJECT_EXTENDED_RANGES
)
{
throw
new
IllegalArgumentException
(
"An extended range \""
+
range
+
"\" found in REJECT_EXTENDED_RANGES mode."
);
}
}
else
{
// Basic range
list
.
add
(
lr
);
}
}
return
filterBasic
(
list
,
tags
);
}
}
private
static
List
<
String
>
filterBasic
(
List
<
LanguageRange
>
priorityList
,
Collection
<
String
>
tags
)
{
List
<
String
>
list
=
new
ArrayList
<>();
for
(
LanguageRange
lr
:
priorityList
)
{
String
range
=
lr
.
getRange
();
if
(
range
.
equals
(
"*"
))
{
return
new
ArrayList
<
String
>(
tags
);
}
else
{
for
(
String
tag
:
tags
)
{
tag
=
tag
.
toLowerCase
();
if
(
tag
.
startsWith
(
range
))
{
int
len
=
range
.
length
();
if
((
tag
.
length
()
==
len
||
tag
.
charAt
(
len
)
==
'-'
)
&&
!
list
.
contains
(
tag
))
{
list
.
add
(
tag
);
}
}
}
}
}
return
list
;
}
private
static
List
<
String
>
filterExtended
(
List
<
LanguageRange
>
priorityList
,
Collection
<
String
>
tags
)
{
List
<
String
>
list
=
new
ArrayList
<>();
for
(
LanguageRange
lr
:
priorityList
)
{
String
range
=
lr
.
getRange
();
if
(
range
.
equals
(
"*"
))
{
return
new
ArrayList
<
String
>(
tags
);
}
String
[]
rangeSubtags
=
range
.
split
(
"-"
);
for
(
String
tag
:
tags
)
{
tag
=
tag
.
toLowerCase
();
String
[]
tagSubtags
=
tag
.
split
(
"-"
);
if
(!
rangeSubtags
[
0
].
equals
(
tagSubtags
[
0
])
&&
!
rangeSubtags
[
0
].
equals
(
"*"
))
{
continue
;
}
int
rangeIndex
=
1
;
int
tagIndex
=
1
;
while
(
rangeIndex
<
rangeSubtags
.
length
&&
tagIndex
<
tagSubtags
.
length
)
{
if
(
rangeSubtags
[
rangeIndex
].
equals
(
"*"
))
{
rangeIndex
++;
}
else
if
(
rangeSubtags
[
rangeIndex
].
equals
(
tagSubtags
[
tagIndex
]))
{
rangeIndex
++;
tagIndex
++;
}
else
if
(
tagSubtags
[
tagIndex
].
length
()
==
1
&&
!
tagSubtags
[
tagIndex
].
equals
(
"*"
))
{
break
;
}
else
{
tagIndex
++;
}
}
if
(
rangeSubtags
.
length
==
rangeIndex
&&
!
list
.
contains
(
tag
))
{
list
.
add
(
tag
);
}
}
}
return
list
;
}
public
static
Locale
lookup
(
List
<
LanguageRange
>
priorityList
,
Collection
<
Locale
>
locales
)
{
if
(
priorityList
.
isEmpty
()
||
locales
.
isEmpty
())
{
return
null
;
}
// Create a list of language tags to be matched.
List
<
String
>
tags
=
new
ArrayList
<>();
for
(
Locale
locale
:
locales
)
{
tags
.
add
(
locale
.
toLanguageTag
());
}
// Look up a language tags.
String
lookedUpTag
=
lookupTag
(
priorityList
,
tags
);
if
(
lookedUpTag
==
null
)
{
return
null
;
}
else
{
return
Locale
.
forLanguageTag
(
lookedUpTag
);
}
}
public
static
String
lookupTag
(
List
<
LanguageRange
>
priorityList
,
Collection
<
String
>
tags
)
{
if
(
priorityList
.
isEmpty
()
||
tags
.
isEmpty
())
{
return
null
;
}
for
(
LanguageRange
lr
:
priorityList
)
{
String
range
=
lr
.
getRange
();
// Special language range ("*") is ignored in lookup.
if
(
range
.
equals
(
"*"
))
{
continue
;
}
String
rangeForRegex
=
range
.
replaceAll
(
"\\x2A"
,
"\\\\p{Alnum}*"
);
while
(
rangeForRegex
.
length
()
>
0
)
{
for
(
String
tag
:
tags
)
{
tag
=
tag
.
toLowerCase
();
if
(
tag
.
matches
(
rangeForRegex
))
{
return
tag
;
}
}
// Truncate from the end....
int
index
=
rangeForRegex
.
lastIndexOf
(
'-'
);
if
(
index
>=
0
)
{
rangeForRegex
=
rangeForRegex
.
substring
(
0
,
index
);
// if range ends with an extension key, truncate it.
if
(
rangeForRegex
.
lastIndexOf
(
'-'
)
==
rangeForRegex
.
length
()-
2
)
{
rangeForRegex
=
rangeForRegex
.
substring
(
0
,
rangeForRegex
.
length
()-
2
);
}
}
else
{
rangeForRegex
=
""
;
}
}
}
return
null
;
}
public
static
List
<
LanguageRange
>
parse
(
String
ranges
)
{
ranges
=
ranges
.
replaceAll
(
" "
,
""
).
toLowerCase
();
if
(
ranges
.
startsWith
(
"accept-language:"
))
{
ranges
=
ranges
.
substring
(
16
);
// delete unnecessary prefix
}
String
[]
langRanges
=
ranges
.
split
(
","
);
List
<
LanguageRange
>
list
=
new
ArrayList
<>(
langRanges
.
length
);
List
<
String
>
tempList
=
new
ArrayList
<>();
int
numOfRanges
=
0
;
for
(
String
range
:
langRanges
)
{
int
index
;
String
r
;
double
w
;
if
((
index
=
range
.
indexOf
(
";q="
))
==
-
1
)
{
r
=
range
;
w
=
MAX_WEIGHT
;
}
else
{
r
=
range
.
substring
(
0
,
index
);
index
+=
3
;
try
{
w
=
Double
.
parseDouble
(
range
.
substring
(
index
));
}
catch
(
Exception
e
)
{
throw
new
IllegalArgumentException
(
"weight=\""
+
range
.
substring
(
index
)
+
"\" for language range \""
+
r
+
"\""
);
}
if
(
w
<
MIN_WEIGHT
||
w
>
MAX_WEIGHT
)
{
throw
new
IllegalArgumentException
(
"weight="
+
w
+
" for language range \""
+
r
+
"\". It must be between "
+
MIN_WEIGHT
+
" and "
+
MAX_WEIGHT
+
"."
);
}
}
if
(!
tempList
.
contains
(
r
))
{
LanguageRange
lr
=
new
LanguageRange
(
r
,
w
);
index
=
numOfRanges
;
for
(
int
j
=
0
;
j
<
numOfRanges
;
j
++)
{
if
(
list
.
get
(
j
).
getWeight
()
<
w
)
{
index
=
j
;
break
;
}
}
list
.
add
(
index
,
lr
);
numOfRanges
++;
tempList
.
add
(
r
);
// Check if the range has an equivalent using IANA LSR data.
// If yes, add it to the User's Language Priority List as well.
// aa-XX -> aa-YY
String
equivalent
;
if
((
equivalent
=
getEquivalentForRegionAndVariant
(
r
))
!=
null
&&
!
tempList
.
contains
(
equivalent
))
{
list
.
add
(
index
+
1
,
new
LanguageRange
(
equivalent
,
w
));
numOfRanges
++;
tempList
.
add
(
equivalent
);
}
String
[]
equivalents
;
if
((
equivalents
=
getEquivalentsForLanguage
(
r
))
!=
null
)
{
for
(
String
equiv:
equivalents
)
{
// aa-XX -> bb-XX(, cc-XX)
if
(!
tempList
.
contains
(
equiv
))
{
list
.
add
(
index
+
1
,
new
LanguageRange
(
equiv
,
w
));
numOfRanges
++;
tempList
.
add
(
equiv
);
}
// bb-XX -> bb-YY(, cc-YY)
equivalent
=
getEquivalentForRegionAndVariant
(
equiv
);
if
(
equivalent
!=
null
&&
!
tempList
.
contains
(
equivalent
))
{
list
.
add
(
index
+
1
,
new
LanguageRange
(
equivalent
,
w
));
numOfRanges
++;
tempList
.
add
(
equivalent
);
}
}
}
}
}
return
list
;
}
private
static
String
[]
getEquivalentsForLanguage
(
String
range
)
{
String
r
=
range
;
while
(
r
.
length
()
>
0
)
{
if
(
LocaleEquivalentMaps
.
singleEquivMap
.
containsKey
(
r
))
{
String
equiv
=
LocaleEquivalentMaps
.
singleEquivMap
.
get
(
r
);
// Return immediately for performance if the first matching
// subtag is found.
return
new
String
[]
{
range
.
replaceFirst
(
r
,
equiv
)};
}
else
if
(
LocaleEquivalentMaps
.
multiEquivsMap
.
containsKey
(
r
))
{
String
[]
equivs
=
LocaleEquivalentMaps
.
multiEquivsMap
.
get
(
r
);
for
(
int
i
=
0
;
i
<
equivs
.
length
;
i
++)
{
equivs
[
i
]
=
range
.
replaceFirst
(
r
,
equivs
[
i
]);
}
return
equivs
;
}
// Truncate the last subtag simply.
int
index
=
r
.
lastIndexOf
(
'-'
);
if
(
index
==
-
1
)
{
break
;
}
r
=
r
.
substring
(
0
,
index
);
}
return
null
;
}
private
static
String
getEquivalentForRegionAndVariant
(
String
range
)
{
int
extensionKeyIndex
=
getExtentionKeyIndex
(
range
);
for
(
String
subtag
:
LocaleEquivalentMaps
.
regionVariantEquivMap
.
keySet
())
{
int
index
;
if
((
index
=
range
.
indexOf
(
subtag
))
!=
-
1
)
{
// Check if the matching text is a valid region or variant.
if
(
extensionKeyIndex
!=
Integer
.
MIN_VALUE
&&
index
>
extensionKeyIndex
)
{
continue
;
}
int
len
=
index
+
subtag
.
length
();
if
(
range
.
length
()
==
len
||
range
.
charAt
(
len
)
==
'-'
)
{
return
range
.
replaceFirst
(
subtag
,
LocaleEquivalentMaps
.
regionVariantEquivMap
.
get
(
subtag
));
}
}
}
return
null
;
}
private
static
int
getExtentionKeyIndex
(
String
s
)
{
char
[]
c
=
s
.
toCharArray
();
int
index
=
Integer
.
MIN_VALUE
;
for
(
int
i
=
1
;
i
<
c
.
length
;
i
++)
{
if
(
c
[
i
]
==
'-'
)
{
if
(
i
-
index
==
2
)
{
return
index
;
}
else
{
index
=
i
;
}
}
}
return
Integer
.
MIN_VALUE
;
}
public
static
List
<
LanguageRange
>
mapEquivalents
(
List
<
LanguageRange
>
priorityList
,
Map
<
String
,
List
<
String
>>
map
)
{
if
(
priorityList
.
isEmpty
())
{
return
new
ArrayList
<>();
// need to return a empty mutable List
}
if
(
map
==
null
||
map
.
isEmpty
())
{
return
new
ArrayList
<
LanguageRange
>(
priorityList
);
}
// Create a map, key=originalKey.toLowerCaes(), value=originalKey
Map
<
String
,
String
>
keyMap
=
new
HashMap
<>();
for
(
String
key
:
map
.
keySet
())
{
keyMap
.
put
(
key
.
toLowerCase
(),
key
);
}
List
<
LanguageRange
>
list
=
new
ArrayList
<>();
for
(
LanguageRange
lr
:
priorityList
)
{
String
range
=
lr
.
getRange
();
String
r
=
range
;
boolean
hasEquivalent
=
false
;
while
(
r
.
length
()
>
0
)
{
if
(
keyMap
.
containsKey
(
r
))
{
hasEquivalent
=
true
;
List
<
String
>
equivalents
=
map
.
get
(
keyMap
.
get
(
r
));
if
(
equivalents
!=
null
)
{
int
len
=
r
.
length
();
for
(
String
equivalent
:
equivalents
)
{
list
.
add
(
new
LanguageRange
(
equivalent
.
toLowerCase
()
+
range
.
substring
(
len
),
lr
.
getWeight
()));
}
}
// Return immediately if the first matching subtag is found.
break
;
}
// Truncate the last subtag simply.
int
index
=
r
.
lastIndexOf
(
'-'
);
if
(
index
==
-
1
)
{
break
;
}
r
=
r
.
substring
(
0
,
index
);
}
if
(!
hasEquivalent
)
{
list
.
add
(
lr
);
}
}
return
list
;
}
private
LocaleMatcher
()
{}
}
test/java/util/Locale/Bug7069824.java
0 → 100644
浏览文件 @
ab9e1ef1
此差异已折叠。
点击以展开。
test/java/util/Locale/tools/EquivMapsGenerator.java
0 → 100644
浏览文件 @
ab9e1ef1
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import
java.io.*
;
import
java.nio.charset.*
;
import
java.nio.file.*
;
import
java.util.*
;
public
class
EquivMapsGenerator
{
/*
* IANA Language Subtag Registry file downloaded from
* http://www.iana.org/assignments/language-subtag-registry
*/
private
static
final
String
DEFAULT_LSR_FILE
=
"language-subtag-registry.txt"
;
private
static
boolean
verbose
=
false
;
public
static
void
main
(
String
[]
args
)
throws
Exception
{
String
fileLSR
=
DEFAULT_LSR_FILE
;
for
(
int
i
=
0
;
i
<
args
.
length
;
i
++)
{
String
s
=
args
[
i
];
if
(
s
.
equals
(
"-lsr"
))
{
fileLSR
=
args
[++
i
];
}
else
if
(
s
.
equals
(
"-verbose"
))
{
verbose
=
true
;
}
}
readLSRfile
(
fileLSR
);
generateEquivalentMap
();
generateSourceCode
();
}
private
static
String
LSRrevisionDate
;
private
static
Map
<
String
,
StringBuilder
>
initialLanguageMap
=
new
TreeMap
<>();
private
static
Map
<
String
,
StringBuilder
>
initialRegionVariantMap
=
new
TreeMap
<>();
private
static
Map
<
String
,
String
>
sortedLanguageMap1
=
new
TreeMap
<>();
private
static
Map
<
String
,
String
[]>
sortedLanguageMap2
=
new
TreeMap
<>();
private
static
Map
<
String
,
String
>
sortedRegionVariantMap
=
new
TreeMap
<>();
private
static
void
readLSRfile
(
String
filename
)
throws
Exception
{
String
type
=
null
;
String
tag
=
null
;
String
preferred
=
null
;
int
mappingNum
=
0
;
for
(
String
line
:
Files
.
readAllLines
(
Paths
.
get
(
filename
),
Charset
.
forName
(
"UTF-8"
)))
{
line
=
line
.
toLowerCase
();
int
index
=
line
.
indexOf
(
' '
)+
1
;
if
(
line
.
startsWith
(
"file-date:"
))
{
LSRrevisionDate
=
line
.
substring
(
index
);
if
(
verbose
)
{
System
.
out
.
println
(
"LSR revision date="
+
LSRrevisionDate
);
}
}
else
if
(
line
.
startsWith
(
"type:"
))
{
type
=
line
.
substring
(
index
);
}
else
if
(
line
.
startsWith
(
"tag:"
)
||
line
.
startsWith
(
"subtag:"
))
{
tag
=
line
.
substring
(
index
);
}
else
if
(
line
.
startsWith
(
"preferred-value:"
)
&&
!
type
.
equals
(
"extlang"
))
{
preferred
=
line
.
substring
(
index
);
mappingNum
++;
processDeprecatedData
(
type
,
tag
,
preferred
);
}
else
if
(
line
.
equals
(
"%%"
))
{
type
=
null
;
tag
=
null
;
preferred
=
null
;
}
}
if
(
verbose
)
{
System
.
out
.
println
(
"readLSRfile("
+
filename
+
")"
);
System
.
out
.
println
(
" Total number of mapping="
+
mappingNum
);
System
.
out
.
println
(
"\n Map for language. Size="
+
initialLanguageMap
.
size
());
for
(
String
key
:
initialLanguageMap
.
keySet
())
{
System
.
out
.
println
(
" "
+
key
+
": \""
+
initialLanguageMap
.
get
(
key
)
+
"\""
);
}
System
.
out
.
println
(
"\n Map for region and variant. Size="
+
initialRegionVariantMap
.
size
());
for
(
String
key
:
initialRegionVariantMap
.
keySet
())
{
System
.
out
.
println
(
" "
+
key
+
": \""
+
initialRegionVariantMap
.
get
(
key
)
+
"\""
);
}
}
}
private
static
void
processDeprecatedData
(
String
type
,
String
tag
,
String
preferred
)
{
StringBuilder
sb
;
if
(
type
.
equals
(
"region"
)
||
type
.
equals
(
"variant"
))
{
if
(!
initialRegionVariantMap
.
containsKey
(
preferred
))
{
sb
=
new
StringBuilder
(
"-"
);
sb
.
append
(
preferred
);
sb
.
append
(
",-"
);
sb
.
append
(
tag
);
initialRegionVariantMap
.
put
(
"-"
+
preferred
,
sb
);
}
else
{
throw
new
RuntimeException
(
"New case, need implementation."
+
" A region/variant subtag \""
+
preferred
+
"\" is registered for more than one subtags."
);
}
}
else
{
// language, grandfahered, and redundant
if
(!
initialLanguageMap
.
containsKey
(
preferred
))
{
sb
=
new
StringBuilder
(
preferred
);
sb
.
append
(
','
);
sb
.
append
(
tag
);
initialLanguageMap
.
put
(
preferred
,
sb
);
}
else
{
sb
=
initialLanguageMap
.
get
(
preferred
);
sb
.
append
(
','
);
sb
.
append
(
tag
);
initialLanguageMap
.
put
(
preferred
,
sb
);
}
}
}
private
static
void
generateEquivalentMap
()
{
String
[]
subtags
;
for
(
String
preferred
:
initialLanguageMap
.
keySet
())
{
subtags
=
initialLanguageMap
.
get
(
preferred
).
toString
().
split
(
","
);
if
(
subtags
.
length
==
2
)
{
sortedLanguageMap1
.
put
(
subtags
[
0
],
subtags
[
1
]);
sortedLanguageMap1
.
put
(
subtags
[
1
],
subtags
[
0
]);
}
else
if
(
subtags
.
length
==
3
)
{
sortedLanguageMap2
.
put
(
subtags
[
0
],
new
String
[]{
subtags
[
1
],
subtags
[
2
]});
sortedLanguageMap2
.
put
(
subtags
[
1
],
new
String
[]{
subtags
[
0
],
subtags
[
2
]});
sortedLanguageMap2
.
put
(
subtags
[
2
],
new
String
[]{
subtags
[
0
],
subtags
[
1
]});
}
else
{
throw
new
RuntimeException
(
"New case, need implementation."
+
" A language subtag \""
+
preferred
+
"\" is registered for more than two subtags. "
);
}
}
for
(
String
preferred
:
initialRegionVariantMap
.
keySet
())
{
subtags
=
initialRegionVariantMap
.
get
(
preferred
).
toString
().
split
(
","
);
sortedRegionVariantMap
.
put
(
subtags
[
0
],
subtags
[
1
]);
sortedRegionVariantMap
.
put
(
subtags
[
1
],
subtags
[
0
]);
}
if
(
verbose
)
{
System
.
out
.
println
(
"generateEquivalentMap()"
);
System
.
out
.
println
(
" \nSorted map for language subtags which have only one equivalent. Size="
+
sortedLanguageMap1
.
size
());
for
(
String
key
:
sortedLanguageMap1
.
keySet
())
{
System
.
out
.
println
(
" "
+
key
+
": \""
+
sortedLanguageMap1
.
get
(
key
)
+
"\""
);
}
System
.
out
.
println
(
"\n Sorted map for language subtags which have multiple equivalents. Size="
+
sortedLanguageMap2
.
size
());
for
(
String
key
:
sortedLanguageMap2
.
keySet
())
{
String
[]
s
=
sortedLanguageMap2
.
get
(
key
);
System
.
out
.
println
(
" "
+
key
+
": \""
+
s
[
0
]
+
"\", \""
+
s
[
1
]
+
"\""
);
}
System
.
out
.
println
(
"\n Sorted map for region and variant subtags. Size="
+
sortedRegionVariantMap
.
size
());
for
(
String
key
:
sortedRegionVariantMap
.
keySet
())
{
System
.
out
.
println
(
" "
+
key
+
": \""
+
sortedRegionVariantMap
.
get
(
key
)
+
"\""
);
}
}
System
.
out
.
println
();
}
private
final
static
String
headerText
=
"final class LocaleEquivalentMaps {\n\n"
+
" static final Map<String, String> singleEquivMap;\n"
+
" static final Map<String, String[]> multiEquivsMap;\n"
+
" static final Map<String, String> regionVariantEquivMap;\n\n"
+
" static {\n"
+
" singleEquivMap = new HashMap<>();\n"
+
" multiEquivsMap = new HashMap<>();\n"
+
" regionVariantEquivMap = new HashMap<>();\n\n"
+
" // This is an auto-generated file and should not be manually edited.\n"
;
private
final
static
String
footerText
=
" }\n\n"
+
"}"
;
private
static
void
generateSourceCode
()
{
System
.
out
.
println
(
headerText
+
" // LSR Revision: "
+
LSRrevisionDate
);
for
(
String
key
:
sortedLanguageMap1
.
keySet
())
{
String
value
=
sortedLanguageMap1
.
get
(
key
);
System
.
out
.
println
(
" singleEquivMap.put(\""
+
key
+
"\", \""
+
value
+
"\");"
);
}
System
.
out
.
println
();
for
(
String
key
:
sortedLanguageMap2
.
keySet
())
{
String
[]
values
=
sortedLanguageMap2
.
get
(
key
);
System
.
out
.
println
(
" multiEquivsMap.put(\""
+
key
+
"\", new String[] {\""
+
values
[
0
]
+
"\", \""
+
values
[
1
]
+
"\"});"
);
}
System
.
out
.
println
();
for
(
String
key
:
sortedRegionVariantMap
.
keySet
())
{
String
value
=
sortedRegionVariantMap
.
get
(
key
);
System
.
out
.
println
(
" regionVariantEquivMap.put(\""
+
key
+
"\", \""
+
value
+
"\");"
);
}
System
.
out
.
println
(
footerText
);
}
}
test/java/util/Locale/tools/language-subtag-registry.txt
0 → 100644
浏览文件 @
ab9e1ef1
此差异已折叠。
点击以展开。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录