2 * typical morph information
4 * License : The MIT License
5 * Copyright(c) 2011 MikuToga Partners
8 package jp.sourceforge.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.HashMap;
16 import java.util.List;
18 import javax.xml.parsers.ParserConfigurationException;
19 import jp.sourceforge.mikutoga.pmd.MorphType;
20 import org.w3c.dom.Element;
21 import org.w3c.dom.NodeList;
22 import org.xml.sax.SAXException;
27 * <p>各モーフ情報はひとつ以上のプライマリ名(≒日本語名)と
28 * ゼロ個以上のグローバル名(≒英語名)を持つ。
30 * <p>和英対訳はMMD Ver7.39の同梱モデルにほぼ準拠。
32 public final class TypicalMorph extends I18nAlias {
34 private static final Class<?> THISCLASS = TypicalMorph.class;
35 private static final String MORPH_XML = "resources/typicalMorph.xml";
37 private static final List<TypicalMorph> EMPTY = Collections.emptyList();
39 private static final Map<MorphType, List<TypicalMorph>> TYPED_MAP =
40 new EnumMap<MorphType, List<TypicalMorph>>(MorphType.class);
42 private static final Map<String, TypicalMorph> PRIMARY_MAP =
43 new HashMap<String, TypicalMorph>();
44 private static final Map<String, TypicalMorph> GLOBAL_MAP =
45 new HashMap<String, TypicalMorph>();
49 InputStream is = THISCLASS.getResourceAsStream(MORPH_XML);
52 top = I18nAlias.loadXml(is);
53 }catch(ParserConfigurationException e){
54 throw new ExceptionInInitializerError(e);
55 }catch(SAXException e){
56 throw new ExceptionInInitializerError(e);
57 }catch(IOException e){
58 throw new ExceptionInInitializerError(e);
67 private final MorphType type;
73 * 状況に応じて伸長する連結リストが用意される。
75 * @param primaryNo プライマリ名初期数。
76 * @param globalNo グローバル名初期数。
78 private TypicalMorph(MorphType type, int primaryNo, int globalNo){
79 super(primaryNo, globalNo);
89 private static void parse(Element top) {
90 NodeList groupList = top.getElementsByTagName("morphGroup");
91 int groupNo = groupList.getLength();
92 for(int idx = 0; idx < groupNo; idx++){
93 Element group = (Element) groupList.item(idx);
98 for(MorphType morphType : MorphType.values()){
99 if( ! TYPED_MAP.containsKey(morphType) ){
100 TYPED_MAP.put(morphType, EMPTY);
109 * @param group morphGroup要素
111 private static void parseGroup(Element group){
112 String typeAttr = group.getAttribute("type");
113 MorphType morphType = MorphType.valueOf(typeAttr);
115 NodeList morphList = group.getElementsByTagName("morph");
116 int morphNo = morphList.getLength();
117 List<TypicalMorph> groupedList =
118 new ArrayList<TypicalMorph>(morphNo);
120 for(int idx = 0; idx < morphNo; idx++){
121 Element morph = (Element) morphList.item(idx);
122 TypicalMorph common = parseMorph(morph, morphType);
123 groupedList.add(common);
126 groupedList = Collections.unmodifiableList(groupedList);
127 TYPED_MAP.put(morphType, groupedList);
134 * @param morph morph要素
138 private static TypicalMorph parseMorph(Element morph, MorphType mtype){
139 NodeList primaryNodes = morph.getElementsByTagName("primary");
140 NodeList globalNodes = morph.getElementsByTagName("global");
141 int primaryNo = primaryNodes.getLength();
142 int globalNo = globalNodes.getLength();
144 TypicalMorph typMorph = new TypicalMorph(mtype, primaryNo, globalNo);
146 for(int idx = 0; idx < primaryNo; idx++){
147 Element primary = (Element) primaryNodes.item(idx);
148 String name = primary.getAttribute("name");
149 typMorph.addPrimaryName(name);
152 for(int idx = 0; idx < globalNo; idx++){
153 Element global = (Element) globalNodes.item(idx);
154 String name = global.getAttribute("name");
155 typMorph.addGlobalName(name);
158 for(String primaryName : typMorph.getPrimaryList()){
159 String key = normalize(primaryName).intern();
160 PRIMARY_MAP.put(key, typMorph);
163 for(String globalName : typMorph.getGlobalList()){
164 String key = normalize(globalName).intern();
165 GLOBAL_MAP.put(key, typMorph);
172 * 全モーフ情報を一意に順序付ける設定を行う。
173 * <p>同一グループ内ではXMLでの定義順が反映される。
175 private static void numbering(){
177 for(MorphType morphType : MorphType.values()){
178 for(TypicalMorph common : TYPED_MAP.get(morphType)){
179 common.setOrderNo(order++);
188 * 種別ごとのモーフ情報リストを取得する。
189 * @param morphType モーフ種別
192 public static List<TypicalMorph> getTypedMorphList(MorphType morphType){
193 List<TypicalMorph> result = TYPED_MAP.get(morphType);
198 * プライマリ名の合致するモーフ情報を返す。
199 * NFKCで正規化されたプライマリ名で検索される。
200 * @param primaryName プライマリ名
201 * @return モーフ情報。見つからなければnull
203 public static TypicalMorph findWithPrimary(String primaryName){
204 String key = normalize(primaryName);
205 TypicalMorph result = PRIMARY_MAP.get(key);
210 * グローバル名の合致するモーフ情報を返す。
211 * NFKCで正規化されたグローバル名で検索される。
212 * @param globalName グローバル名
213 * @return モーフ情報。見つからなければnull
215 public static TypicalMorph findWithGlobal(String globalName){
216 String key = normalize(globalName);
217 TypicalMorph result = GLOBAL_MAP.get(key);
222 * プライマリ名をグローバル名に変換する。
223 * @param primaryName プライマリ名
224 * @return グローバル名。見つからなければnull
226 public static String primary2global(String primaryName){
227 TypicalMorph morph = findWithPrimary(primaryName);
228 if(morph == null) return null;
229 String global = morph.getTopGlobalName();
234 * グローバル名をプライマリ名へ変換する。
235 * @param globalName グローバル名
236 * @return プライマリ名。見つからなければnull
238 public static String global2primary(String globalName){
239 TypicalMorph morph = findWithGlobal(globalName);
240 if(morph == null) return null;
241 String primary = morph.getTopPrimaryName();
250 public MorphType getMorphType(){