2 * typical morph information
4 * License : The MIT License
5 * Copyright(c) 2011 MikuToga Partners
8 package jp.sfjp.mikutoga.typical;
10 import java.io.IOException;
11 import java.io.InputStream;
12 import java.util.ArrayList;
13 import java.util.Collections;
14 import java.util.EnumMap;
15 import java.util.List;
17 import javax.xml.parsers.ParserConfigurationException;
18 import jp.sfjp.mikutoga.pmd.MorphType;
19 import org.w3c.dom.Element;
20 import org.w3c.dom.NodeList;
21 import org.xml.sax.SAXException;
26 * <p>各モーフ情報はひとつ以上のプライマリ名(≒日本語名)と
27 * ゼロ個以上のグローバル名(≒英語名)を持つ。
29 * <p>和英対訳はMMD Ver7.39の同梱モデルにほぼ準拠。
31 public final class TypicalMorph extends I18nAlias {
33 private static final Class<?> THISCLASS = TypicalMorph.class;
34 private static final String MORPH_XML = "resources/typicalMorph.xml";
36 private static final String ELEM_MORPHGROUP = "morphGroup";
37 private static final String ELEM_MORPH = "morph";
38 private static final String ATTR_TYPE = "type";
39 private static final String ELEM_PRIMARY = "primary";
40 private static final String ELEM_GLOBAL = "global";
41 private static final String ATTR_NAME = "name";
43 private static final List<TypicalMorph> EMPTY = Collections.emptyList();
45 private static final Map<MorphType, List<TypicalMorph>> TYPED_MAP =
46 new EnumMap<MorphType, List<TypicalMorph>>(MorphType.class);
48 private static final AliasMap<TypicalMorph> MORPH_ALIAS_MAP =
49 new AliasMap<TypicalMorph>();
53 InputStream is = THISCLASS.getResourceAsStream(MORPH_XML);
57 top = I18nAlias.loadXml(is);
58 }catch(ParserConfigurationException e){
59 throw new ExceptionInInitializerError(e);
60 }catch(SAXException e){
61 throw new ExceptionInInitializerError(e);
62 }catch(IOException e){
63 throw new ExceptionInInitializerError(e);
72 private final MorphType type;
78 * 状況に応じて伸長する連結リストが用意される。
80 * @param primaryNum プライマリ名初期数。
81 * @param globalNum グローバル名初期数。
83 private TypicalMorph(MorphType type, int primaryNum, int globalNum){
84 super(primaryNum, globalNum);
88 assert this.getClass() == THISCLASS;
98 private static void parse(Element top) {
99 NodeList groupList = top.getElementsByTagName(ELEM_MORPHGROUP);
100 int groupNo = groupList.getLength();
101 for(int idx = 0; idx < groupNo; idx++){
102 Element groupElem = (Element) groupList.item(idx);
103 parseGroup(groupElem);
106 // 必要に応じモーフ枠に不変空リスト登録
107 for(MorphType morphType : MorphType.values()){
108 if( ! TYPED_MAP.containsKey(morphType) ){
109 TYPED_MAP.put(morphType, EMPTY);
118 * @param groupElem morphGroup要素
120 private static void parseGroup(Element groupElem){
121 String typeAttr = groupElem.getAttribute(ATTR_TYPE);
122 MorphType morphType = MorphType.valueOf(typeAttr);
124 NodeList morphList = groupElem.getElementsByTagName(ELEM_MORPH);
125 int morphNo = morphList.getLength();
126 List<TypicalMorph> groupedList =
127 new ArrayList<TypicalMorph>(morphNo);
129 for(int idx = 0; idx < morphNo; idx++){
130 Element morphElem = (Element) morphList.item(idx);
131 TypicalMorph morph = parseMorph(morphElem, morphType);
132 groupedList.add(morph);
133 MORPH_ALIAS_MAP.addAlias(morph);
136 groupedList = Collections.unmodifiableList(groupedList);
137 TYPED_MAP.put(morphType, groupedList);
144 * @param morphElem morph要素
148 private static TypicalMorph parseMorph(Element morphElem,
150 NodeList primaryNodes = morphElem.getElementsByTagName(ELEM_PRIMARY);
151 NodeList globalNodes = morphElem.getElementsByTagName(ELEM_GLOBAL);
152 int primaryNo = primaryNodes.getLength();
153 int globalNo = globalNodes.getLength();
155 assert primaryNo > 0;
157 TypicalMorph morph = new TypicalMorph(mtype, primaryNo, globalNo);
159 for(int idx = 0; idx < primaryNo; idx++){
160 Element primaryElem = (Element) primaryNodes.item(idx);
161 String primaryName = primaryElem.getAttribute(ATTR_NAME);
162 morph.addPrimaryName(primaryName);
165 for(int idx = 0; idx < globalNo; idx++){
166 Element globalElem = (Element) globalNodes.item(idx);
167 String globalName = globalElem.getAttribute(ATTR_NAME);
168 morph.addGlobalName(globalName);
176 * <p>同一グループ内ではXMLでの定義順が反映される。
178 private static void numbering(){
180 for(MorphType morphType : MorphType.values()){
181 for(TypicalMorph morph : TYPED_MAP.get(morphType)){
182 morph.setOrderNo(order++);
190 * 種別ごとのモーフ情報不変リストを取得する。
191 * @param morphType モーフ種別
194 public static List<TypicalMorph> getTypicalMorphList(
195 MorphType morphType ){
196 List<TypicalMorph> result = TYPED_MAP.get(morphType);
201 * プライマリ名の合致するモーフ情報を返す。
202 * NFKCで正規化されたプライマリ名で検索される。
203 * @param primaryName プライマリ名
204 * @return モーフ情報。見つからなければnull
206 public static TypicalMorph findWithPrimary(String primaryName){
207 TypicalMorph result = MORPH_ALIAS_MAP.getAliasByPrimary(primaryName);
212 * グローバル名の合致するモーフ情報を返す。
213 * NFKCで正規化されたグローバル名で検索される。
214 * @param globalName グローバル名
215 * @return モーフ情報。見つからなければnull
217 public static TypicalMorph findWithGlobal(String globalName){
218 TypicalMorph result = MORPH_ALIAS_MAP.getAliasByGlobal(globalName);
223 * プライマリ名をグローバル名に変換する。
224 * @param primaryName プライマリ名
225 * @return グローバル名。見つからなければnull
227 public static String primary2global(String primaryName){
228 String globalName = MORPH_ALIAS_MAP.primary2global(primaryName);
233 * グローバル名をプライマリ名へ変換する。
234 * @param globalName グローバル名
235 * @return プライマリ名。見つからなければnull
237 public static String global2primary(String globalName){
238 String primaryName = MORPH_ALIAS_MAP.global2primary(globalName);
247 public MorphType getMorphType(){