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;
27 * <p>各モーフ情報はひとつ以上のプライマリ名(≒日本語名)と
28 * ゼロ個以上のグローバル名(≒英語名)を持つ。
32 * <p>和英対訳はMMD Ver7.39の同梱モデルにほぼ準拠。
34 public final class TypicalMorph extends I18nAlias {
36 private static final Class<?> THISCLASS = TypicalMorph.class;
37 private static final String MORPH_XML = "resources/typicalMorph.xml";
39 private static final String ELEM_MORPHGROUP = "morphGroup";
40 private static final String ELEM_MORPH = "morph";
41 private static final String ATTR_TYPE = "type";
42 private static final String ELEM_PRIMARY = "primary";
43 private static final String ELEM_GLOBAL = "global";
44 private static final String ATTR_NAME = "name";
46 private static final List<TypicalMorph> EMPTY = Collections.emptyList();
48 private static final Map<MorphType, List<TypicalMorph>> TYPED_MAP =
49 new EnumMap<>(MorphType.class);
51 private static final AliasMap<TypicalMorph> MORPH_ALIAS_MAP =
56 InputStream is = THISCLASS.getResourceAsStream(MORPH_XML);
60 top = I18nAlias.loadXml(is);
61 }catch(ParserConfigurationException | SAXException | IOException e){
62 throw new ExceptionInInitializerError(e);
71 private final MorphType type;
78 * 状況に応じて伸長する連結リストが用意される。
81 * @param primaryNum プライマリ名初期数。
82 * @param globalNum グローバル名初期数。
84 private TypicalMorph(MorphType type, int primaryNum, int globalNum){
85 super(primaryNum, globalNum);
89 assert this.getClass() == THISCLASS;
99 private static void parse(Element top) {
100 NodeList groupList = top.getElementsByTagName(ELEM_MORPHGROUP);
101 int groupNo = groupList.getLength();
102 for(int idx = 0; idx < groupNo; idx++){
103 Element groupElem = (Element) groupList.item(idx);
104 parseGroup(groupElem);
107 // 必要に応じモーフ枠に不変空リスト登録
108 for(MorphType morphType : MorphType.values()){
109 if( ! TYPED_MAP.containsKey(morphType) ){
110 TYPED_MAP.put(morphType, EMPTY);
119 * @param groupElem morphGroup要素
121 private static void parseGroup(Element groupElem){
122 String typeAttr = groupElem.getAttribute(ATTR_TYPE);
123 MorphType morphType = MorphType.valueOf(typeAttr);
125 NodeList morphList = groupElem.getElementsByTagName(ELEM_MORPH);
126 int morphNo = morphList.getLength();
127 List<TypicalMorph> groupedList =
128 new ArrayList<>(morphNo);
130 for(int idx = 0; idx < morphNo; idx++){
131 Element morphElem = (Element) morphList.item(idx);
132 TypicalMorph morph = parseMorph(morphElem, morphType);
133 groupedList.add(morph);
134 MORPH_ALIAS_MAP.addAlias(morph);
137 groupedList = Collections.unmodifiableList(groupedList);
138 TYPED_MAP.put(morphType, groupedList);
145 * @param morphElem morph要素
149 private static TypicalMorph parseMorph(Element morphElem,
151 NodeList primaryNodes = morphElem.getElementsByTagName(ELEM_PRIMARY);
152 NodeList globalNodes = morphElem.getElementsByTagName(ELEM_GLOBAL);
153 int primaryNo = primaryNodes.getLength();
154 int globalNo = globalNodes.getLength();
156 assert primaryNo > 0;
158 TypicalMorph morph = new TypicalMorph(mtype, primaryNo, globalNo);
160 for(int idx = 0; idx < primaryNo; idx++){
161 Element primaryElem = (Element) primaryNodes.item(idx);
162 String primaryName = primaryElem.getAttribute(ATTR_NAME);
163 morph.addPrimaryName(primaryName);
166 for(int idx = 0; idx < globalNo; idx++){
167 Element globalElem = (Element) globalNodes.item(idx);
168 String globalName = globalElem.getAttribute(ATTR_NAME);
169 morph.addGlobalName(globalName);
178 * <p>同一グループ内ではXMLでの定義順が反映される。
180 private static void numbering(){
182 for(MorphType morphType : MorphType.values()){
183 for(TypicalMorph morph : TYPED_MAP.get(morphType)){
184 morph.setOrderNo(order++);
192 * 種別ごとのモーフ情報不変リストを取得する。
193 * @param morphType モーフ種別
196 public static List<TypicalMorph> getTypicalMorphList(
197 MorphType morphType ){
198 List<TypicalMorph> result = TYPED_MAP.get(morphType);
203 * プライマリ名の合致するモーフ情報を返す。
204 * NFKCで正規化されたプライマリ名で検索される。
205 * @param primaryName プライマリ名
206 * @return モーフ情報。見つからなければnull
208 public static TypicalMorph findWithPrimary(String primaryName){
209 TypicalMorph result = MORPH_ALIAS_MAP.getAliasByPrimary(primaryName);
214 * グローバル名の合致するモーフ情報を返す。
215 * NFKCで正規化されたグローバル名で検索される。
216 * @param globalName グローバル名
217 * @return モーフ情報。見つからなければnull
219 public static TypicalMorph findWithGlobal(String globalName){
220 TypicalMorph result = MORPH_ALIAS_MAP.getAliasByGlobal(globalName);
225 * プライマリ名をグローバル名に変換する。
226 * @param primaryName プライマリ名
227 * @return グローバル名。見つからなければnull
229 public static String primary2global(String primaryName){
230 String globalName = MORPH_ALIAS_MAP.primary2global(primaryName);
235 * グローバル名をプライマリ名へ変換する。
236 * @param globalName グローバル名
237 * @return プライマリ名。見つからなければnull
239 public static String global2primary(String globalName){
240 String primaryName = MORPH_ALIAS_MAP.global2primary(globalName);
249 public MorphType getMorphType(){