--- /dev/null
+/*
+ * alias map with primary & global
+ *
+ * License : The MIT License
+ * Copyright(c) 2013 MikuToga Partners
+ */
+
+package jp.sfjp.mikutoga.typical;
+
+import java.text.Normalizer;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * プライマリ名 - グローバル名間の対応、
+ * およびUnicode正規化によるゆらぎ表記吸収処理を行う。
+ * @param <T> 別名管理クラス
+ * @see <a href="http://ja.wikipedia.org/wiki/Unicode正規化">
+ * Unicode正規化 </a>
+ * @see <a href="http://unicode.org/reports/tr15/">
+ * UNICODE NORMALIZATION FORMS </a>
+ * @see java.text.Normalizer
+ */
+class AliasMap<T extends I18nAlias> {
+
+ private final Map<String, T> primaryAliasMap;
+ private final Map<String, T> globalAliasMap;
+
+ /**
+ * コンストラクタ。
+ */
+ AliasMap(){
+ super();
+
+ this.primaryAliasMap = new HashMap<String, T>();
+ this.globalAliasMap = new HashMap<String, T>();
+
+ return;
+ }
+
+
+ /**
+ * NFKC正規化されたUnicode文字列を返す。
+ * <p>等価な全半角、濁点、丸付き数字などの表現の正規化を目的とする。
+ * <ul>
+ * <li>「ボーン」は「ボーン」になる
+ * <li>「ホ゛ーン9」は「ボーン9」になる
+ * </ul>
+ * @param name 正規化対象文字列
+ * @return 正規化済み文字列
+ */
+ static String normalize(CharSequence name){
+ String result;
+ result = Normalizer.normalize(name, Normalizer.Form.NFKC);
+ return result;
+ }
+
+
+ /**
+ * 別名管理オブジェクトを登録。
+ * <p>キーとなる名前は、事前にNFKC正規化で
+ * 揺らぎ表記が吸収されたプライマリ名およびグローバル名。
+ * <p>登録キーが衝突した時は後の方が有効となる。
+ * @param alias 別名管理オブジェクト
+ */
+ void addAlias(T alias){
+ addPrimary(alias);
+ addGlobal(alias);
+ return;
+ }
+
+ /**
+ * 別名管理オブジェクトと正規化プライマリ名を対応づける。
+ * <p>事前にNFKC正規化されたプライマリ名が登録キーとなる。
+ * <p>登録キーが衝突した時は後の方が有効となる。
+ * @param alias 別名管理オブジェクト
+ */
+ private void addPrimary(T alias){
+ for(String primaryName : alias.getPrimaryNameList()){
+ String normalized = normalize(primaryName);
+ normalized = normalized.intern();
+ this.primaryAliasMap.put(normalized, alias);
+ }
+ return;
+ }
+
+ /**
+ * 別名管理オブジェクトと正規化グローバル名を対応づける。
+ * <p>事前にNFKC正規化されたグローバル名が登録キーとなる。
+ * <p>登録キーが衝突した時は後の方が有効となる。
+ * @param alias 別名管理オブジェクト
+ */
+ private void addGlobal(T alias){
+ for(String globalName : alias.getGlobalNameList()){
+ String normalized = normalize(globalName);
+ normalized = normalized.intern();
+ this.globalAliasMap.put(normalized, alias);
+ }
+ return;
+ }
+
+ /**
+ * 名前から別名管理オブジェクトを得る。
+ * <p>プライマリ名、グローバル名の順で検索される。
+ * <p>名前は事前にNFKC正規化された後、検索キーとなる。
+ * @param name 名前
+ * @return 別名管理オブジェクト。見つからなければnull
+ */
+ T getAlias(String name){
+ T result;
+ result = getAliasByPrimary(name);
+ if(result == null){
+ result = getAliasByGlobal(name);
+ }
+ return result;
+ }
+
+ /**
+ * プライマリ名から別名管理オブジェクトを得る。
+ * <p>プライマリ名は事前にNFKC正規化された後、検索キーとなる。
+ * @param primaryName プライマリ名
+ * @return 別名管理オブジェクト。見つからなければnull
+ */
+ T getAliasByPrimary(String primaryName){
+ String normalized = normalize(primaryName);
+ T result = this.primaryAliasMap.get(normalized);
+ return result;
+ }
+
+ /**
+ * グローバル名から別名管理オブジェクトを得る。
+ * <p>グローバル名は事前にNFKC正規化された後、検索キーとなる。
+ * @param globalName グローバル名
+ * @return 別名管理オブジェクト。見つからなければnull
+ */
+ T getAliasByGlobal(String globalName){
+ String normalized = normalize(globalName);
+ T result = this.globalAliasMap.get(normalized);
+ return result;
+ }
+
+ /**
+ * プライマリ名から代表グローバル名を得る。
+ * <p>プライマリ名は事前にNFKC正規化された後、検索キーとなる。
+ * @param primaryName プライマリ名
+ * @return 代表グローバル名。見つからなければnull
+ */
+ String primary2global(String primaryName){
+ T alias = getAliasByPrimary(primaryName);
+ if(alias == null) return null;
+ String globalName = alias.getTopGlobalName();
+ return globalName;
+ }
+
+ /**
+ * グローバル名から代表プライマリ名を得る。
+ * <p>グローバル名は事前にNFKC正規化された後、検索キーとなる。
+ * @param globalName グローバル名
+ * @return 代表プライマリ名。見つからなければnull
+ */
+ String global2primary(String globalName){
+ T alias = getAliasByGlobal(globalName);
+ if(alias == null) return null;
+ String primary = alias.getTopPrimaryName();
+ return primary;
+ }
+
+}
* Copyright(c) 2011 MikuToga Partners
*/
-package jp.sourceforge.mikutoga.typical;
+package jp.sfjp.mikutoga.typical;
import java.io.IOException;
import java.io.InputStream;
-import java.text.Normalizer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
/**
* 国際化&別名管理オブジェクトの実装基板。
+ * <p>別名管理オブジェクトは、
+ * 各々のリストの先頭が代表名となる、
+ * プライマリ名の不変リストとグローバル名の不変リストを持つ。
* <p>国産モデルではプライマリ名に日本語名が収められることが多い。
* プライマリ名は必ず一つ以上なければならない。
* <p>国産モデルではグローバル名に英語名が収められることが多いが、
* プライマリ名と同一の日本語名が収められている場合も多い。
+ * <p>別名管理オブジェクトは、
+ * インスタンス間での順序を定義するためのオーダー番号を持つ。
*/
class I18nAlias {
private int orderNo;
- private final List<String> primaryList;
- private final List<String> globalList;
+ private final List<String> primaryNameList;
+ private final List<String> globalNameList;
- private final List<String> umodPrimaryList;
- private final List<String> umodGlobalList;
+ private final List<String> umodPrimaryNameList;
+ private final List<String> umodGlobalNameList;
/**
* コンストラクタ。
* <p>各初期数が0以下の場合は、
* 状況に応じて伸長する連結リストが用意される。
- * @param primaryNo プライマリ名初期数。
- * @param globalNo グローバル名初期数。
+ * @param primaryNum プライマリ名初期数。
+ * @param globalNum グローバル名初期数。
*/
- protected I18nAlias(int primaryNo, int globalNo){
+ protected I18nAlias(int primaryNum, int globalNum){
super();
- if(primaryNo <= 0){
- this.primaryList = new LinkedList<String>();
+ if(primaryNum <= 0){
+ this.primaryNameList = new LinkedList<String>();
}else{
- this.primaryList = new ArrayList<String>(primaryNo);
+ this.primaryNameList = new ArrayList<String>(primaryNum);
}
- if(globalNo <= 0){
- this.globalList = new LinkedList<String>();
+ if(globalNum <= 0){
+ this.globalNameList = new LinkedList<String>();
}else{
- this.globalList = new ArrayList<String>(globalNo);
+ this.globalNameList = new ArrayList<String>(globalNum);
}
- this.umodPrimaryList =
- Collections.unmodifiableList(this.primaryList);
- this.umodGlobalList =
- Collections.unmodifiableList(this.globalList);
+ this.umodPrimaryNameList =
+ Collections.unmodifiableList(this.primaryNameList);
+ this.umodGlobalNameList =
+ Collections.unmodifiableList(this.globalNameList);
return;
}
throws ParserConfigurationException, SAXException, IOException {
DocumentBuilderFactory factory;
factory = DocumentBuilderFactory.newInstance();
- factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(is);
return top;
}
- /**
- * NFKC正規化された文字列を返す。
- * <ul>
- * <li>「ボーン」は「ボーン」になる
- * <li>「ホ゛ーン9」は「ボーン9」になる
- * </ul>
- * @param name 正規化対象文字列
- * @return 正規化済み文字列
- */
- protected static String normalize(CharSequence name){
- String result;
- result = Normalizer.normalize(name, Normalizer.Form.NFKC);
- return result;
- }
-
/**
* オーダー番号を返す。
/**
* プライマリ名の代表をひとつ返す。
+ * <p>必ず存在しなければならない。
* @return 最初のプライマリ名
*/
public String getTopPrimaryName(){
- String result = this.primaryList.get(0);
+ String result = this.primaryNameList.get(0);
return result;
}
* @return 最初のグローバル名。ひとつもなければnull
*/
public String getTopGlobalName(){
- String result;
- if(this.globalList.isEmpty()) result = null;
- else result = this.globalList.get(0);
+ if(this.globalNameList.isEmpty()) return null;
+
+ String result = this.globalNameList.get(0);
+
return result;
}
/**
- * プライマリ名の全エイリアス文字列リストを返す。
- * @return 全プライマリ名リスト。(不可変)
+ * プライマリ名の全別名リストを返す。
+ * @return 全別名リスト。(不可変)
*/
- public List<String> getPrimaryList(){
- return this.umodPrimaryList;
+ public List<String> getPrimaryNameList(){
+ return this.umodPrimaryNameList;
}
/**
* プライマリ名を追加。
- * @param name プライマリ名
+ * @param primaryName プライマリ名
*/
- protected void addPrimaryName(String name){
- this.primaryList.add(name);
+ protected void addPrimaryName(String primaryName){
+ this.primaryNameList.add(primaryName);
return;
}
/**
- * グローバル名の全エイリアス文字列リストを返す。
- * @return 全グローバル名リスト。(不可変)
+ * グローバル名の全別名リストを返す。
+ * @return 全別名リスト。(不可変)
*/
- public List<String> getGlobalList(){
- return this.umodGlobalList;
+ public List<String> getGlobalNameList(){
+ return this.umodGlobalNameList;
}
/**
* グローバル名を追加。
- * @param name グローバル名
+ * @param globalName グローバル名
*/
- protected void addGlobalName(String name){
- this.globalList.add(name);
+ protected void addGlobalName(String globalName){
+ this.globalNameList.add(globalName);
return;
}
* Copyright(c) 2011 MikuToga Partners
*/
-package jp.sourceforge.mikutoga.typical;
+package jp.sfjp.mikutoga.typical;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
-import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
-import java.util.Map;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
private static final Class<?> THISCLASS = TypicalBone.class;
private static final String BONE_XML = "resources/typicalBone.xml";
- private static final List<TypicalBone> TYP_BONE_LIST =
+ private static final String ELEM_BONE = "bone";
+ private static final String ELEM_ROOT = "root";
+ private static final String ELEM_PRIMARY = "primary";
+ private static final String ELEM_GLOBAL = "global";
+ private static final String ATTR_NAME = "name";
+
+ private static final List<TypicalBone> BONE_LIST =
new LinkedList<TypicalBone>();
- private static final Map<String, TypicalBone> PRIMARY_MAP =
- new HashMap<String, TypicalBone>();
- private static final Map<String, TypicalBone> GLOBAL_MAP =
- new HashMap<String, TypicalBone>();
+ private static final AliasMap<TypicalBone> BONE_ALIAS_MAP =
+ new AliasMap<TypicalBone>();
- private static final List<TypicalBone> TYP_BONE_UNMODLIST =
- Collections.unmodifiableList(TYP_BONE_LIST);
+ private static final List<TypicalBone> BONE_UNMODLIST =
+ Collections.unmodifiableList(BONE_LIST);
static{
InputStream is = THISCLASS.getResourceAsStream(BONE_XML);
+
Element top;
try{
top = I18nAlias.loadXml(is);
}
+ private boolean isRoot;
+
+
/**
* コンストラクタ。
* <p>各初期数が0以下の場合は、
* 状況に応じて伸長する連結リストが用意される。
- * @param primaryNo プライマリ名初期数。
- * @param globalNo グローバル名初期数。
+ * @param primaryNum プライマリ名初期数。
+ * @param globalNum グローバル名初期数。
*/
- private TypicalBone(int primaryNo, int globalNo){
- super(primaryNo, globalNo);
+ private TypicalBone(int primaryNum, int globalNum){
+ super(primaryNum, globalNum);
+ assert this.getClass() == THISCLASS;
return;
}
* @param top 最上位要素
*/
private static void parse(Element top) {
- NodeList boneList = top.getElementsByTagName("bone");
+ NodeList boneList = top.getElementsByTagName(ELEM_BONE);
int boneNo = boneList.getLength();
for(int idx = 0; idx < boneNo; idx++){
- Element bone = (Element) boneList.item(idx);
- TypicalBone typBone = parseBone(bone);
- TYP_BONE_LIST.add(typBone);
+ Element boneElem = (Element) boneList.item(idx);
+ TypicalBone typBone = parseBone(boneElem);
+ BONE_LIST.add(typBone);
+ BONE_ALIAS_MAP.addAlias(typBone);
}
return;
/**
* bone要素を解読する。
- * @param bone bone要素
+ * @param boneElem bone要素
* @return ボーン情報
*/
- private static TypicalBone parseBone(Element bone){
- NodeList primaryNodes = bone.getElementsByTagName("primary");
- NodeList globalNodes = bone.getElementsByTagName("global");
+ private static TypicalBone parseBone(Element boneElem){
+ NodeList primaryNodes = boneElem.getElementsByTagName(ELEM_PRIMARY);
+ NodeList globalNodes = boneElem.getElementsByTagName(ELEM_GLOBAL);
int primaryNo = primaryNodes.getLength();
int globalNo = globalNodes.getLength();
- TypicalBone typBone = new TypicalBone(primaryNo, globalNo);
+ assert primaryNo > 0;
+
+ TypicalBone bone = new TypicalBone(primaryNo, globalNo);
for(int idx = 0; idx < primaryNo; idx++){
- Element primary = (Element) primaryNodes.item(idx);
- String name = primary.getAttribute("name");
- typBone.addPrimaryName(name);
+ Element primaryElem = (Element) primaryNodes.item(idx);
+ String name = primaryElem.getAttribute(ATTR_NAME);
+ bone.addPrimaryName(name);
}
for(int idx = 0; idx < globalNo; idx++){
- Element global = (Element) globalNodes.item(idx);
- String name = global.getAttribute("name");
- typBone.addGlobalName(name);
- }
-
- for(String primaryName : typBone.getPrimaryList()){
- String key = normalize(primaryName).intern();
- PRIMARY_MAP.put(key, typBone);
+ Element globalElem = (Element) globalNodes.item(idx);
+ String name = globalElem.getAttribute(ATTR_NAME);
+ bone.addGlobalName(name);
}
- for(String globalName : typBone.getGlobalList()){
- String key = normalize(globalName).intern();
- GLOBAL_MAP.put(key, typBone);
+ NodeList rootNodes = boneElem.getElementsByTagName(ELEM_ROOT);
+ if(rootNodes.getLength() > 0){
+ bone.isRoot = true;
+ }else{
+ bone.isRoot = false;
}
- return typBone;
+ return bone;
}
/**
- * å\85¨ã\83\9cã\83¼ã\83³æ\83\85å ±ã\82\92ä¸\80æ\84\8fã\81«é \86åº\8fä»\98ã\81\91ã\82\8bè¨å®\9aã\82\92è¡\8cã\81\86。
+ * å\85¨ã\83\9cã\83¼ã\83³æ\83\85å ±ã\81«é\80\9aã\81\97ç\95ªå\8f·ã\82\92ä»\98ã\81\91ã\82\8b。
* <p>XMLでの定義順が反映される。
*/
private static void numbering(){
int order = 0;
- for(TypicalBone bone : TYP_BONE_LIST){
+ for(TypicalBone bone : BONE_LIST){
bone.setOrderNo(order++);
}
* 全ボーンの不変リストを返す。
* @return 全ボーンのリスト
*/
- public static List<TypicalBone> getBoneList(){
- return TYP_BONE_UNMODLIST;
+ public static List<TypicalBone> getTypicalBoneList(){
+ return BONE_UNMODLIST;
}
/**
* @return モーフ情報。見つからなければnull
*/
public static TypicalBone findWithPrimary(String primaryName){
- String key = normalize(primaryName);
- TypicalBone result = PRIMARY_MAP.get(key);
+ TypicalBone result = BONE_ALIAS_MAP.getAliasByPrimary(primaryName);
return result;
}
* @return モーフ情報。見つからなければnull
*/
public static TypicalBone findWithGlobal(String globalName){
- String key = normalize(globalName);
- TypicalBone result = GLOBAL_MAP.get(key);
+ TypicalBone result = BONE_ALIAS_MAP.getAliasByGlobal(globalName);
return result;
}
* @return グローバル名。見つからなければnull
*/
public static String primary2global(String primaryName){
- TypicalBone bone = findWithPrimary(primaryName);
- if(bone == null) return null;
- String global = bone.getTopGlobalName();
- return global;
+ String globalName = BONE_ALIAS_MAP.primary2global(primaryName);
+ return globalName;
}
/**
* @return プライマリ名。見つからなければnull
*/
public static String global2primary(String globalName){
- TypicalBone bone = findWithGlobal(globalName);
- if(bone == null) return null;
- String primary = bone.getTopPrimaryName();
- return primary;
+ String primaryName = BONE_ALIAS_MAP.global2primary(globalName);
+ return primaryName;
+ }
+
+
+ /**
+ * このボーンが親を持たないルートボーンとして扱われる慣習なのか
+ * 判定する。
+ * <p>※「全親」ボーンに関する慣習は無視される。
+ * @return 親を持たなければtrue
+ */
+ public boolean isRoot(){
+ return this.isRoot;
}
}
* Copyright(c) 2011 MikuToga Partners
*/
-package jp.sourceforge.mikutoga.typical;
+package jp.sfjp.mikutoga.typical;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumMap;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.ParserConfigurationException;
private static final Class<?> THISCLASS = TypicalMorph.class;
private static final String MORPH_XML = "resources/typicalMorph.xml";
+ private static final String ELEM_MORPHGROUP = "morphGroup";
+ private static final String ELEM_MORPH = "morph";
+ private static final String ATTR_TYPE = "type";
+ private static final String ELEM_PRIMARY = "primary";
+ private static final String ELEM_GLOBAL = "global";
+ private static final String ATTR_NAME = "name";
+
private static final List<TypicalMorph> EMPTY = Collections.emptyList();
private static final Map<MorphType, List<TypicalMorph>> TYPED_MAP =
new EnumMap<MorphType, List<TypicalMorph>>(MorphType.class);
- private static final Map<String, TypicalMorph> PRIMARY_MAP =
- new HashMap<String, TypicalMorph>();
- private static final Map<String, TypicalMorph> GLOBAL_MAP =
- new HashMap<String, TypicalMorph>();
+ private static final AliasMap<TypicalMorph> MORPH_ALIAS_MAP =
+ new AliasMap<TypicalMorph>();
static{
InputStream is = THISCLASS.getResourceAsStream(MORPH_XML);
+
Element top;
try{
top = I18nAlias.loadXml(is);
* <p>各初期数が0以下の場合は、
* 状況に応じて伸長する連結リストが用意される。
* @param type モーフ種別
- * @param primaryNo プライマリ名初期数。
- * @param globalNo グローバル名初期数。
+ * @param primaryNum プライマリ名初期数。
+ * @param globalNum グローバル名初期数。
*/
- private TypicalMorph(MorphType type, int primaryNo, int globalNo){
- super(primaryNo, globalNo);
+ private TypicalMorph(MorphType type, int primaryNum, int globalNum){
+ super(primaryNum, globalNum);
+
this.type = type;
+
+ assert this.getClass() == THISCLASS;
+
return;
}
* @param top 最上位要素
*/
private static void parse(Element top) {
- NodeList groupList = top.getElementsByTagName("morphGroup");
+ NodeList groupList = top.getElementsByTagName(ELEM_MORPHGROUP);
int groupNo = groupList.getLength();
for(int idx = 0; idx < groupNo; idx++){
- Element group = (Element) groupList.item(idx);
- parseGroup(group);
+ Element groupElem = (Element) groupList.item(idx);
+ parseGroup(groupElem);
}
// 必要に応じモーフ枠に不変空リスト登録
/**
* モーフグループ構造を解読する。
- * @param group morphGroup要素
+ * @param groupElem morphGroup要素
*/
- private static void parseGroup(Element group){
- String typeAttr = group.getAttribute("type");
+ private static void parseGroup(Element groupElem){
+ String typeAttr = groupElem.getAttribute(ATTR_TYPE);
MorphType morphType = MorphType.valueOf(typeAttr);
- NodeList morphList = group.getElementsByTagName("morph");
+ NodeList morphList = groupElem.getElementsByTagName(ELEM_MORPH);
int morphNo = morphList.getLength();
List<TypicalMorph> groupedList =
new ArrayList<TypicalMorph>(morphNo);
for(int idx = 0; idx < morphNo; idx++){
- Element morph = (Element) morphList.item(idx);
- TypicalMorph common = parseMorph(morph, morphType);
- groupedList.add(common);
+ Element morphElem = (Element) morphList.item(idx);
+ TypicalMorph morph = parseMorph(morphElem, morphType);
+ groupedList.add(morph);
+ MORPH_ALIAS_MAP.addAlias(morph);
}
groupedList = Collections.unmodifiableList(groupedList);
/**
* morph要素を解読する。
- * @param morph morph要素
+ * @param morphElem morph要素
* @param mtype モーフ種別
* @return モーフ情報
*/
- private static TypicalMorph parseMorph(Element morph, MorphType mtype){
- NodeList primaryNodes = morph.getElementsByTagName("primary");
- NodeList globalNodes = morph.getElementsByTagName("global");
+ private static TypicalMorph parseMorph(Element morphElem,
+ MorphType mtype ){
+ NodeList primaryNodes = morphElem.getElementsByTagName(ELEM_PRIMARY);
+ NodeList globalNodes = morphElem.getElementsByTagName(ELEM_GLOBAL);
int primaryNo = primaryNodes.getLength();
int globalNo = globalNodes.getLength();
- TypicalMorph typMorph = new TypicalMorph(mtype, primaryNo, globalNo);
+ assert primaryNo > 0;
+
+ TypicalMorph morph = new TypicalMorph(mtype, primaryNo, globalNo);
for(int idx = 0; idx < primaryNo; idx++){
- Element primary = (Element) primaryNodes.item(idx);
- String name = primary.getAttribute("name");
- typMorph.addPrimaryName(name);
+ Element primaryElem = (Element) primaryNodes.item(idx);
+ String primaryName = primaryElem.getAttribute(ATTR_NAME);
+ morph.addPrimaryName(primaryName);
}
for(int idx = 0; idx < globalNo; idx++){
- Element global = (Element) globalNodes.item(idx);
- String name = global.getAttribute("name");
- typMorph.addGlobalName(name);
+ Element globalElem = (Element) globalNodes.item(idx);
+ String globalName = globalElem.getAttribute(ATTR_NAME);
+ morph.addGlobalName(globalName);
}
- for(String primaryName : typMorph.getPrimaryList()){
- String key = normalize(primaryName).intern();
- PRIMARY_MAP.put(key, typMorph);
- }
-
- for(String globalName : typMorph.getGlobalList()){
- String key = normalize(globalName).intern();
- GLOBAL_MAP.put(key, typMorph);
- }
-
- return typMorph;
+ return morph;
}
/**
- * å\85¨ã\83¢ã\83¼ã\83\95æ\83\85å ±ã\82\92ä¸\80æ\84\8fã\81«é \86åº\8fä»\98ã\81\91ã\82\8bè¨å®\9aã\82\92è¡\8cã\81\86。
+ * å\85¨ã\83¢ã\83¼ã\83\95æ\83\85å ±ã\81«é\80\9aã\81\97ç\95ªå\8f·ã\82\92ä»\98ã\81\91ã\82\8b。
* <p>同一グループ内ではXMLでの定義順が反映される。
*/
private static void numbering(){
int order = 0;
for(MorphType morphType : MorphType.values()){
- for(TypicalMorph common : TYPED_MAP.get(morphType)){
- common.setOrderNo(order++);
+ for(TypicalMorph morph : TYPED_MAP.get(morphType)){
+ morph.setOrderNo(order++);
}
}
return;
}
-
/**
- * 種別ごとのモーフ情報リストを取得する。
+ * 種別ごとのモーフ情報不変リストを取得する。
* @param morphType モーフ種別
- * @return モーフ情報リスト
+ * @return モーフ情報不変リスト
*/
- public static List<TypicalMorph> getTypedMorphList(MorphType morphType){
+ public static List<TypicalMorph> getTypicalMorphList(
+ MorphType morphType ){
List<TypicalMorph> result = TYPED_MAP.get(morphType);
return result;
}
* @return モーフ情報。見つからなければnull
*/
public static TypicalMorph findWithPrimary(String primaryName){
- String key = normalize(primaryName);
- TypicalMorph result = PRIMARY_MAP.get(key);
+ TypicalMorph result = MORPH_ALIAS_MAP.getAliasByPrimary(primaryName);
return result;
}
* @return モーフ情報。見つからなければnull
*/
public static TypicalMorph findWithGlobal(String globalName){
- String key = normalize(globalName);
- TypicalMorph result = GLOBAL_MAP.get(key);
+ TypicalMorph result = MORPH_ALIAS_MAP.getAliasByGlobal(globalName);
return result;
}
* @return グローバル名。見つからなければnull
*/
public static String primary2global(String primaryName){
- TypicalMorph morph = findWithPrimary(primaryName);
- if(morph == null) return null;
- String global = morph.getTopGlobalName();
- return global;
+ String globalName = MORPH_ALIAS_MAP.primary2global(primaryName);
+ return globalName;
}
/**
* @return プライマリ名。見つからなければnull
*/
public static String global2primary(String globalName){
- TypicalMorph morph = findWithGlobal(globalName);
- if(morph == null) return null;
- String primary = morph.getTopPrimaryName();
- return primary;
+ String primaryName = MORPH_ALIAS_MAP.global2primary(globalName);
+ return primaryName;
}
--- /dev/null
+/*
+ * unique bone information
+ *
+ * License : The MIT License
+ * Copyright(c) 2013 MikuToga Partners
+ */
+
+package jp.sfjp.mikutoga.typical;
+
+/**
+ * 特別扱いされるボーンに関する諸々。
+ */
+public final class UniqBone {
+
+ private static final String HIDARI_LEFT = "\u5de6"; // 「左」
+ private static final String MIGI_RIGHT = "\u53f3"; // 「右」
+ private static final String HIZA_KNEE = "\u3072\u3056"; // 「ひざ」
+
+
+ private static final String KNEE_L_PFX =
+ HIDARI_LEFT + HIZA_KNEE; // 左ひざ
+ private static final String KNEE_R_PFX =
+ MIGI_RIGHT + HIZA_KNEE; // 右ひざ
+
+ static{
+ assert "左ひざ".equals(KNEE_L_PFX);
+ assert "右ひざ".equals(KNEE_R_PFX);
+ }
+
+
+ /**
+ * 隠しコンストラクタ。
+ */
+ private UniqBone(){
+ assert false;
+ throw new AssertionError();
+ }
+
+ /**
+ * IK演算時の回転方向に制限を受ける「ひざボーン」か否か、
+ * ボーン名で判定する。
+ * <p>ボーンのプライマリ名が「左ひざ」もしくは「右ひざ」で始まれば
+ * ひざボーンとする。
+ * <p>ひざボーン名の例
+ * <ul>
+ * <li>「左ひざ」
+ * <li>「左ひざげり」
+ * </ul>
+ * <p>ひざボーン名ではない例
+ * <ul>
+ * <li>「左ひ」
+ * <li>「ひざ」
+ * <li>「前ひざ」
+ * <li>「左ひさ゛」
+ * <li>「左ヒザ」
+ * <li>「左ヒザ」
+ * <li>「左膝」
+ * <li>「Knee_L」
+ * </ul>
+ * @param boneNameJp プライマリボーン名
+ * @return ひざボーンならtrue
+ */
+ public static boolean isPrimaryKneeName(String boneNameJp){
+ if(boneNameJp.startsWith(KNEE_L_PFX)) return true;
+ if(boneNameJp.startsWith(KNEE_R_PFX)) return true;
+
+ return false;
+ }
+
+}
/**
* MMDコミュニティにおける一般的な慣例に関する情報を提供する。
- * <p>例)ボーン名やモーフ名の一般的な名前など
+ * <p>ä¾\8b)ã\83\9cã\83¼ã\83³å\90\8dã\82\84ã\83¢ã\83¼ã\83\95å\90\8dã\81®ä¸\80è\88¬ç\9a\84ã\81ªå\90\8då\89\8dã\80\81対訳ã\81ªã\81©
* <p>MikuMikuDance Ver.7.39同梱のモデルなどが主な情報源。
*/
-package jp.sourceforge.mikutoga.typical;
+package jp.sfjp.mikutoga.typical;
/* EOF */
<!DOCTYPE typicalBone [
<!ELEMENT typicalBone (bone*) >
- <!ELEMENT bone (primary+, global*) >
+ <!ELEMENT bone (root?, primary+, global*) >
+ <!ELEMENT root EMPTY >
<!ELEMENT primary EMPTY >
<!ELEMENT global EMPTY >
<bone>
+ <root />
<primary name="センター" /> <!-- センター -->
<global name="center" />
</bone>
</bone>
<bone>
+ <root />
<primary name="左足IK" /> <!-- 左足IK -->
<global name="leg IK_L" />
</bone>
<bone>
+ <root />
<primary name="右足IK" /> <!-- 右足IK -->
<global name="leg IK_R" />
</bone>
</bone>
<bone>
+ <root />
<primary name="ボーン01" /> <!-- ボーン01 -->
<global name="bone01" />
</bone>
<bone>
+ <root />
<primary name="ボーン02" /> <!-- ボーン02 -->
<global name="bone02" />
</bone>
<bone>
+ <root />
<primary name="ボーン03" /> <!-- ボーン03 -->
<global name="bone03" />
</bone>
<bone>
+ <root />
<primary name="ボーン04" /> <!-- ボーン04 -->
<global name="bone04" />
</bone>
<bone>
+ <root />
<primary name="ボーン05" /> <!-- ボーン05 -->
<global name="bone05" />
</bone>
<bone>
+ <root />
<primary name="ボーン06" /> <!-- ボーン06 -->
<global name="bone06" />
</bone>
<bone>
+ <root />
<primary name="ボーン07" /> <!-- ボーン07 -->
<global name="bone07" />
</bone>
<bone>
+ <root />
<primary name="ボーン08" /> <!-- ボーン08 -->
<global name="bone08" />
</bone>
<bone>
+ <root />
<primary name="ボーン09" /> <!-- ボーン09 -->
<global name="bone09" />
</bone>
<bone>
+ <root />
<primary name="ボーン10" /> <!-- ボーン10 -->
<global name="bone10" />
</bone>
<bone>
+ <root />
<primary name="ボーン11" /> <!-- ボーン11 -->
<global name="bone11" />
</bone>
<bone>
+ <root />
<primary name="ボーン12" /> <!-- ボーン12 -->
<global name="bone12" />
</bone>
<bone>
+ <root />
<primary name="ボーン13" /> <!-- ボーン13 -->
<global name="bone13" />
</bone>
<bone>
+ <root />
<primary name="ボーン14" /> <!-- ボーン14 -->
<global name="bone14" />
</bone>
<bone>
+ <root />
<primary name="ボーン15" /> <!-- ボーン15 -->
<global name="bone15" />
</bone>
--- /dev/null
+/*
+ */
+
+package jp.sfjp.mikutoga.typical;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ */
+public class AliasMapTest {
+
+ public AliasMapTest() {
+ }
+
+ @BeforeClass
+ public static void setUpClass() {
+ }
+
+ @AfterClass
+ public static void tearDownClass() {
+ }
+
+ @Before
+ public void setUp() {
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ static class TestAlias extends I18nAlias{
+ }
+
+ /**
+ * Test of normalize method, of class AliasMap.
+ */
+ @Test
+ public void testNormalize() {
+ System.out.println("normalize");
+
+ assertEquals("", AliasMap.normalize(""));
+
+ assertEquals("azAZ", AliasMap.normalize("azAZ"));
+ assertEquals("azAZ", AliasMap.normalize("azAZ"));
+
+ assertEquals("5678", AliasMap.normalize("5678"));
+ assertEquals("56VII八", AliasMap.normalize("5⑥Ⅶ八"));
+
+ assertEquals("ガ", AliasMap.normalize("ガ"));
+ assertEquals("ガ", AliasMap.normalize("ガ"));
+ assertEquals("ガ", AliasMap.normalize("ガ"));
+ assertEquals("ガ", AliasMap.normalize("カ"+"\u3099"));
+ assertEquals("カ\u0020\u3099", AliasMap.normalize("カ"+"\u309b"));
+
+ assertEquals("パ", AliasMap.normalize("パ"));
+ assertEquals("パ", AliasMap.normalize("パ"));
+ assertEquals("パ", AliasMap.normalize("パ"));
+ assertEquals("パ", AliasMap.normalize("ハ"+"\u309a"));
+ assertEquals("ハ\u0020\u309a", AliasMap.normalize("ハ"+"\u309c"));
+
+ assertEquals("リットル", AliasMap.normalize("㍑"));
+
+ return;
+ }
+
+ /**
+ * Test of addAlias method, of class AliasMap.
+ */
+ @Test
+ public void testAddAlias() {
+ System.out.println("addAlias");
+
+ AliasMap<TestAlias> map;
+ TestAlias alias1;
+
+ alias1 = new TestAlias();
+ alias1.addPrimaryName("p1");
+ alias1.addPrimaryName("p2");
+ alias1.addGlobalName("g1");
+ alias1.addGlobalName("g2");
+
+ map = new AliasMap<TestAlias>();
+ map.addAlias(alias1);
+
+ assertSame(alias1, map.getAlias("p1"));
+ assertSame(alias1, map.getAlias("p2"));
+ assertSame(alias1, map.getAlias("g1"));
+ assertSame(alias1, map.getAlias("g2"));
+
+ assertNull(map.getAlias("ZZZ"));
+
+ assertEquals("g1", map.primary2global("p2"));
+ assertEquals("p1", map.global2primary("g2"));
+
+ assertNull(map.primary2global("ZZZ"));
+ assertNull(map.global2primary("ZZZ"));
+
+
+ TestAlias aliasHand;
+ TestAlias aliasFoot;
+
+ aliasHand = new TestAlias();
+ aliasHand.addPrimaryName("手1");
+ aliasHand.addPrimaryName("おてて2");
+ aliasHand.addPrimaryName("h");
+ aliasHand.addPrimaryName("bone");
+ aliasHand.addPrimaryName("cross1");
+ aliasHand.addGlobalName("hand1");
+ aliasHand.addGlobalName("paw2");
+ aliasHand.addGlobalName("h");
+ aliasHand.addGlobalName("bone");
+ aliasHand.addGlobalName("cross2");
+
+ aliasFoot = new TestAlias();
+ aliasFoot.addPrimaryName("足1");
+ aliasFoot.addPrimaryName("あんよ2");
+ aliasFoot.addPrimaryName("f");
+ aliasFoot.addPrimaryName("bone");
+ aliasFoot.addPrimaryName("cross2");
+ aliasFoot.addGlobalName("foot1");
+ aliasFoot.addGlobalName("hoof2");
+ aliasFoot.addGlobalName("f");
+ aliasFoot.addGlobalName("bone");
+ aliasFoot.addGlobalName("cross1");
+
+ map = new AliasMap<TestAlias>();
+ map.addAlias(aliasHand);
+ map.addAlias(aliasFoot);
+
+ assertSame(aliasHand, map.getAlias("h"));
+ assertSame(aliasFoot, map.getAlias("f"));
+ assertSame(aliasFoot, map.getAlias("bone"));
+ assertSame(aliasHand, map.getAlias("cross1"));
+ assertSame(aliasFoot, map.getAlias("cross2"));
+
+ assertSame(aliasHand, map.getAliasByPrimary("h"));
+ assertSame(aliasFoot, map.getAliasByPrimary("f"));
+ assertSame(aliasFoot, map.getAliasByPrimary("bone"));
+ assertSame(aliasHand, map.getAliasByPrimary("cross1"));
+ assertSame(aliasFoot, map.getAliasByPrimary("cross2"));
+
+ assertSame(aliasHand, map.getAliasByGlobal("h"));
+ assertSame(aliasFoot, map.getAliasByGlobal("f"));
+ assertSame(aliasFoot, map.getAliasByGlobal("bone"));
+ assertSame(aliasFoot, map.getAliasByGlobal("cross1"));
+ assertSame(aliasHand, map.getAliasByGlobal("cross2"));
+
+ return;
+ }
+
+}
--- /dev/null
+/*
+ */
+
+package jp.sfjp.mikutoga.typical;
+
+import java.util.List;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ */
+public class I18nAliasTest {
+
+ public I18nAliasTest() {
+ }
+
+ @BeforeClass
+ public static void setUpClass() {
+ }
+
+ @AfterClass
+ public static void tearDownClass() {
+ }
+
+ @Before
+ public void setUp() {
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ /**
+ * Test of orderNo method, of class I18nAlias.
+ */
+ @Test
+ public void testOrderNo() {
+ System.out.println("OrderNo");
+
+ I18nAlias alias = new I18nAlias();
+
+ assertEquals(0, alias.getOrderNo());
+ alias.setOrderNo(99);
+ assertEquals(99, alias.getOrderNo());
+
+ I18nAlias alias2 = new I18nAlias();
+
+ alias2.setOrderNo(999);
+ assertTrue(0 > I18nAlias.ORDER_COMPARATOR.compare(alias, alias2));
+
+ alias2.setOrderNo(99);
+ assertTrue(0 == I18nAlias.ORDER_COMPARATOR.compare(alias, alias2));
+
+ alias2.setOrderNo(9);
+ assertTrue(0 < I18nAlias.ORDER_COMPARATOR.compare(alias, alias2));
+
+ return;
+ }
+
+ /**
+ * Test of method, of class I18nAlias.
+ */
+ @Test
+ public void testName() {
+ System.out.println("Name");
+
+ I18nAlias alias;
+
+ alias = new I18nAlias();
+
+ alias.addPrimaryName("p1");
+
+ assertEquals("p1", alias.getTopPrimaryName());
+ assertNull(alias.getTopGlobalName());
+
+ List<String> primaryList;
+ List<String> globalList;
+
+ primaryList = alias.getPrimaryNameList();
+ globalList = alias.getGlobalNameList();
+
+ assertEquals(1, primaryList.size());
+ assertEquals(0, globalList.size());
+ assertEquals("p1", primaryList.get(0));
+
+ alias.addGlobalName("g1");
+
+ assertEquals("g1", alias.getTopGlobalName());
+ globalList = alias.getGlobalNameList();
+ assertEquals(1, globalList.size());
+ assertEquals("g1", globalList.get(0));
+
+ return;
+ }
+
+}
/*
*/
-package jp.sourceforge.mikutoga.typical;
+package jp.sfjp.mikutoga.typical;
import java.util.List;
import org.junit.After;
assertEquals("頭", result.getTopPrimaryName());
assertEquals("head", result.getTopGlobalName());
- assertEquals(1, result.getPrimaryList().size());
- assertEquals("頭", result.getPrimaryList().get(0));
- assertEquals(1, result.getGlobalList().size());
- assertEquals("head", result.getGlobalList().get(0));
+ assertEquals(1, result.getPrimaryNameList().size());
+ assertEquals("頭", result.getPrimaryNameList().get(0));
+ assertEquals(1, result.getGlobalNameList().size());
+ assertEquals("head", result.getGlobalNameList().get(0));
return;
}
}
/**
- * Test of getBoneList method, of class TypicalBone.
+ * Test of getTypicalBoneList method, of class TypicalBone.
*/
@Test
public void testGetBoneList() {
List<TypicalBone> boneList;
- boneList = TypicalBone.getBoneList();
+ boneList = TypicalBone.getTypicalBoneList();
assertNotNull(boneList);
assertEquals(77, boneList.size());
return;
}
+ /**
+ * Test of isRoot method, of class TypicalBone.
+ */
+ @Test
+ public void testIsRoot() {
+ System.out.println("isRoot");
+
+ TypicalBone bone;
+
+ bone = TypicalBone.findWithPrimary("センター");
+ assertTrue(bone.isRoot());
+
+ bone = TypicalBone.findWithPrimary("頭");
+ assertFalse(bone.isRoot());
+
+ bone = TypicalBone.findWithPrimary("右足IK");
+ assertTrue(bone.isRoot());
+
+ bone = TypicalBone.findWithPrimary("左足IK");
+ assertTrue(bone.isRoot());
+
+ bone = TypicalBone.findWithPrimary("ボーン01");
+ assertTrue(bone.isRoot());
+
+ return;
+ }
+
}
/*
*/
-package jp.sourceforge.mikutoga.typical;
+package jp.sfjp.mikutoga.typical;
import java.util.List;
import jp.sfjp.mikutoga.pmd.MorphType;
}
/**
- * Test of getTypedMorphList method, of class TypicalMorph.
+ * Test of getTypicalMorphList method, of class TypicalMorph.
*/
@Test
public void testGetTypedMorphList() {
List<TypicalMorph> morphList;
- morphList = TypicalMorph.getTypedMorphList(MorphType.EYEBROW);
+ morphList = TypicalMorph.getTypicalMorphList(MorphType.EYEBROW);
assertEquals(6, morphList.size());
- morphList = TypicalMorph.getTypedMorphList(MorphType.EYE);
+ morphList = TypicalMorph.getTypicalMorphList(MorphType.EYE);
assertEquals(7, morphList.size());
- morphList = TypicalMorph.getTypedMorphList(MorphType.LIP);
+ morphList = TypicalMorph.getTypicalMorphList(MorphType.LIP);
assertEquals(12, morphList.size());
- morphList = TypicalMorph.getTypedMorphList(MorphType.EXTRA);
+ morphList = TypicalMorph.getTypicalMorphList(MorphType.EXTRA);
assertEquals(2, morphList.size());
return;
assertEquals(MorphType.LIP, result.getMorphType());
assertEquals("あ", result.getTopPrimaryName());
assertEquals("a", result.getTopGlobalName());
- assertEquals(1, result.getPrimaryList().size());
- assertEquals("あ", result.getPrimaryList().get(0));
- assertEquals(1, result.getGlobalList().size());
- assertEquals("a", result.getGlobalList().get(0));
+ assertEquals(1, result.getPrimaryNameList().size());
+ assertEquals("あ", result.getPrimaryNameList().get(0));
+ assertEquals(1, result.getGlobalNameList().size());
+ assertEquals("a", result.getGlobalNameList().get(0));
TypicalMorph result1;
TypicalMorph result2;
assertEquals(MorphType.EXTRA, result1.getMorphType());
assertEquals("べー", result1.getTopPrimaryName());
assertEquals("tongue", result1.getTopGlobalName());
- assertEquals(2, result1.getPrimaryList().size());
- assertEquals("べー", result1.getPrimaryList().get(0));
- assertEquals("ぺろっ", result1.getPrimaryList().get(1));
- assertEquals(1, result1.getGlobalList().size());
- assertEquals("tongue", result1.getGlobalList().get(0));
+ assertEquals(2, result1.getPrimaryNameList().size());
+ assertEquals("べー", result1.getPrimaryNameList().get(0));
+ assertEquals("ぺろっ", result1.getPrimaryNameList().get(1));
+ assertEquals(1, result1.getGlobalNameList().size());
+ assertEquals("tongue", result1.getGlobalNameList().get(0));
return;
}
List<TypicalMorph> morphList;
- morphList = TypicalMorph.getTypedMorphList(MorphType.EYEBROW);
+ morphList = TypicalMorph.getTypicalMorphList(MorphType.EYEBROW);
for(TypicalMorph morph : morphList){
MorphType type = morph.getMorphType();
assertEquals(MorphType.EYEBROW, type);
}
- morphList = TypicalMorph.getTypedMorphList(MorphType.EYE);
+ morphList = TypicalMorph.getTypicalMorphList(MorphType.EYE);
for(TypicalMorph morph : morphList){
MorphType type = morph.getMorphType();
assertEquals(MorphType.EYE, type);
}
- morphList = TypicalMorph.getTypedMorphList(MorphType.LIP);
+ morphList = TypicalMorph.getTypicalMorphList(MorphType.LIP);
for(TypicalMorph morph : morphList){
MorphType type = morph.getMorphType();
assertEquals(MorphType.LIP, type);
}
- morphList = TypicalMorph.getTypedMorphList(MorphType.EXTRA);
+ morphList = TypicalMorph.getTypicalMorphList(MorphType.EXTRA);
for(TypicalMorph morph : morphList){
MorphType type = morph.getMorphType();
--- /dev/null
+/*
+ */
+
+package jp.sfjp.mikutoga.typical;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ */
+public class UniqBoneTest {
+
+ public UniqBoneTest() {
+ }
+
+ @BeforeClass
+ public static void setUpClass() {
+ }
+
+ @AfterClass
+ public static void tearDownClass() {
+ }
+
+ @Before
+ public void setUp() {
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ /**
+ * Test of isPrimaryKneeName method, of class UniqBone.
+ */
+ @Test
+ public void testIsPrimaryKneeName() {
+ System.out.println("isPrimaryKneeName");
+
+ assertTrue(UniqBone.isPrimaryKneeName("左ひざ"));
+ assertTrue(UniqBone.isPrimaryKneeName("右ひざ"));
+ assertTrue(UniqBone.isPrimaryKneeName("左ひざ蹴り"));
+
+ assertFalse(UniqBone.isPrimaryKneeName(""));
+ assertFalse(UniqBone.isPrimaryKneeName("左ひ"));
+ assertFalse(UniqBone.isPrimaryKneeName("ひざ"));
+ assertFalse(UniqBone.isPrimaryKneeName("前ひざ"));
+ assertFalse(UniqBone.isPrimaryKneeName("左ひさ゛"));
+ assertFalse(UniqBone.isPrimaryKneeName("左ヒザ"));
+ assertFalse(UniqBone.isPrimaryKneeName("左ヒザ"));
+ assertFalse(UniqBone.isPrimaryKneeName("左膝"));
+ assertFalse(UniqBone.isPrimaryKneeName("Knee_L"));
+
+ return;
+ }
+
+}