From: Olyutorskii Date: Tue, 23 Aug 2011 16:01:41 +0000 (+0900) Subject: typicalパッケージ導入 X-Git-Tag: fromMercurial~51 X-Git-Url: http://git.osdn.net/view?p=mikutoga%2FTogaGem.git;a=commitdiff_plain;h=a6539fa0c60f353b5110cb57ac9173bcad327eff typicalパッケージ導入 --- diff --git a/src/main/java/jp/sourceforge/mikutoga/typical/TypicalBone.java b/src/main/java/jp/sourceforge/mikutoga/typical/TypicalBone.java new file mode 100644 index 0000000..1be886a --- /dev/null +++ b/src/main/java/jp/sourceforge/mikutoga/typical/TypicalBone.java @@ -0,0 +1,181 @@ +/* + * typical bone information + * + * License : The MIT License + * Copyright(c) 2011 MikuToga Partners + */ + +package jp.sourceforge.mikutoga.typical; + +import java.io.IOException; +import java.io.InputStream; +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; +import org.xml.sax.SAXException; + +/** + * 一般的な標準ボーン構成に関する情報。 + *

各ボーン情報はひとつ以上のプライマリ名(≒日本語名)と + * ゼロ個以上のグローバル名(≒英語名)を持つ。 + *

選択基準は独断。 + *

和英対訳はMMD Ver7.39の同梱モデルにほぼ準拠。 + */ +public final class TypicalBone extends TypicalObject { + + private static final Class THISCLASS = TypicalBone.class; + private static final String BONE_XML = "resources/typicalBone.xml"; + + private static final List TYP_BONE_LIST = + new LinkedList(); + private static final Map PRIMARY_MAP = + new HashMap(); + private static final Map GLOBAL_MAP = + new HashMap(); + + + static{ + InputStream is = THISCLASS.getResourceAsStream(BONE_XML); + Element top; + try{ + top = TypicalObject.loadXml(is); + }catch(ParserConfigurationException e){ + throw new ExceptionInInitializerError(e); + }catch(SAXException e){ + throw new ExceptionInInitializerError(e); + }catch(IOException e){ + throw new ExceptionInInitializerError(e); + } + + parse(top); + + numbering(); + } + + + /** + * コンストラクタ。 + *

各初期数が0以下の場合は、状況に応じて伸長する連結リストが用意される。 + * @param primaryNo プライマリ名初期数。 + * @param globalNo グローバル名初期数。 + */ + private TypicalBone(int primaryNo, int globalNo){ + super(primaryNo, globalNo); + return; + } + + + /** + * XML文書の最上位構造を解読する。 + * @param top 最上位要素 + */ + private static void parse(Element top) { + NodeList boneList = top.getElementsByTagName("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); + } + + return; + } + + /** + * bone要素を解読する。 + * @param bone bone要素 + * @return ボーン情報 + */ + private static TypicalBone parseBone(Element bone){ + NodeList primaryNodes = bone.getElementsByTagName("primary"); + NodeList globalNodes = bone.getElementsByTagName("global"); + int primaryNo = primaryNodes.getLength(); + int globalNo = globalNodes.getLength(); + + TypicalBone typBone = new TypicalBone(primaryNo, globalNo); + + for(int idx = 0; idx < primaryNo; idx++){ + Element primary = (Element) primaryNodes.item(idx); + String name = primary.getAttribute("name"); + typBone.primaryList.add(name); + } + + for(int idx = 0; idx < globalNo; idx++){ + Element global = (Element) globalNodes.item(idx); + String name = global.getAttribute("name"); + typBone.globalList.add(name); + } + + for(String primaryName : typBone.primaryList){ + PRIMARY_MAP.put(primaryName, typBone); + } + + for(String globalName : typBone.globalList){ + GLOBAL_MAP.put(globalName, typBone); + } + + return typBone; + } + + /** + * 全ボーン情報を一意に順序付ける設定を行う。 + *

XMLでの定義順が反映される。 + */ + private static void numbering(){ + int order = 0; + for(TypicalBone bone : TYP_BONE_LIST){ + bone.orderNo = order++; + } + + return; + } + + /** + * プライマリ名の合致するボーン情報を返す。 + * @param primaryName プライマリ名 + * @return モーフ情報。見つからなければnull + */ + public static TypicalBone findWithPrimary(String primaryName){ + TypicalBone result = PRIMARY_MAP.get(primaryName); + return result; + } + + /** + * グローバル名の合致するボーン情報を返す。 + * @param globalName グローバル名 + * @return モーフ情報。見つからなければnull + */ + public static TypicalBone findWithGlobal(String globalName){ + TypicalBone result = GLOBAL_MAP.get(globalName); + return result; + } + + /** + * プライマリ名をグローバル名に変換する。 + * @param primaryName プライマリ名 + * @return グローバル名。見つからなければnull + */ + public static String primary2global(String primaryName){ + TypicalBone bone = findWithPrimary(primaryName); + if(bone == null) return null; + String global = bone.getTopGlobalName(); + return global; + } + + /** + * グローバル名をプライマリ名へ変換する。 + * @param globalName グローバル名 + * @return プライマリ名。見つからなければnull + */ + public static String global2primary(String globalName){ + TypicalBone bone = findWithGlobal(globalName); + if(bone == null) return null; + String primary = bone.getTopPrimaryName(); + return primary; + } + +} diff --git a/src/main/java/jp/sourceforge/mikutoga/typical/TypicalMorph.java b/src/main/java/jp/sourceforge/mikutoga/typical/TypicalMorph.java new file mode 100644 index 0000000..12c37d8 --- /dev/null +++ b/src/main/java/jp/sourceforge/mikutoga/typical/TypicalMorph.java @@ -0,0 +1,244 @@ +/* + * typical morph information + * + * License : The MIT License + * Copyright(c) 2011 MikuToga Partners + */ + +package jp.sourceforge.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; +import jp.sourceforge.mikutoga.pmd.MorphType; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + + +/** + * 一般的な標準モーフに関する情報。 + *

各モーフ情報はひとつ以上のプライマリ名(≒日本語名)と + * ゼロ個以上のグローバル名(≒英語名)を持つ。 + *

選択基準は独断。 + *

和英対訳はMMD Ver7.39の同梱モデルにほぼ準拠。 + */ +public final class TypicalMorph extends TypicalObject { + + private static final Class THISCLASS = TypicalMorph.class; + private static final String MORPH_XML = "resources/typicalMorph.xml"; + + private static final List EMPTY = Collections.emptyList(); + + private static final Map> TYPED_MAP = + new EnumMap>(MorphType.class); + + private static final Map PRIMARY_MAP = + new HashMap(); + private static final Map GLOBAL_MAP = + new HashMap(); + + + static{ + InputStream is = THISCLASS.getResourceAsStream(MORPH_XML); + Element top; + try{ + top = TypicalObject.loadXml(is); + }catch(ParserConfigurationException e){ + throw new ExceptionInInitializerError(e); + }catch(SAXException e){ + throw new ExceptionInInitializerError(e); + }catch(IOException e){ + throw new ExceptionInInitializerError(e); + } + + parse(top); + + numbering(); + } + + + private final MorphType type; + + + /** + * コンストラクタ。 + *

各初期数が0以下の場合は、状況に応じて伸長する連結リストが用意される。 + * @param type モーフ種別 + * @param primaryNo プライマリ名初期数。 + * @param globalNo グローバル名初期数。 + */ + private TypicalMorph(MorphType type, int primaryNo, int globalNo){ + super(primaryNo, globalNo); + this.type = type; + return; + } + + + /** + * XML文書の最上位構造を解読する。 + * @param top 最上位要素 + */ + private static void parse(Element top) { + NodeList groupList = top.getElementsByTagName("morphGroup"); + int groupNo = groupList.getLength(); + for(int idx = 0; idx < groupNo; idx++){ + Element group = (Element) groupList.item(idx); + parseGroup(group); + } + + // 空リスト登録 + for(MorphType morphType : MorphType.values()){ + if( ! TYPED_MAP.containsKey(morphType) ){ + TYPED_MAP.put(morphType, EMPTY); + } + } + + return; + } + + /** + * モーフグループ構造を解読する。 + * @param group morphGroup要素 + */ + private static void parseGroup(Element group){ + String typeAttr = group.getAttribute("type"); + MorphType morphType = MorphType.valueOf(typeAttr); + + NodeList morphList = group.getElementsByTagName("morph"); + int morphNo = morphList.getLength(); + List groupedList = new ArrayList(morphNo); + + for(int idx = 0; idx < morphNo; idx++){ + Element morph = (Element) morphList.item(idx); + TypicalMorph common = parseMorph(morph, morphType); + groupedList.add(common); + } + + TYPED_MAP.put(morphType, Collections.unmodifiableList(groupedList)); + + return; + } + + /** + * morph要素を解読する。 + * @param morph morph要素 + * @param mtype モーフ種別 + * @return モーフ情報 + */ + private static TypicalMorph parseMorph(Element morph, MorphType mtype){ + NodeList primaryNodes = morph.getElementsByTagName("primary"); + NodeList globalNodes = morph.getElementsByTagName("global"); + int primaryNo = primaryNodes.getLength(); + int globalNo = globalNodes.getLength(); + + TypicalMorph typMorph = new TypicalMorph(mtype, primaryNo, globalNo); + + for(int idx = 0; idx < primaryNo; idx++){ + Element primary = (Element) primaryNodes.item(idx); + String name = primary.getAttribute("name"); + typMorph.primaryList.add(name); + } + + for(int idx = 0; idx < globalNo; idx++){ + Element global = (Element) globalNodes.item(idx); + String name = global.getAttribute("name"); + typMorph.globalList.add(name); + } + + for(String primaryName : typMorph.primaryList){ + PRIMARY_MAP.put(primaryName, typMorph); + } + + for(String globalName : typMorph.globalList){ + GLOBAL_MAP.put(globalName, typMorph); + } + + return typMorph; + } + + /** + * 全モーフ情報を一意に順序付ける設定を行う。 + *

同一グループ内ではXMLでの定義順が反映される。 + */ + private static void numbering(){ + int order = 0; + for(MorphType morphType : MorphType.values()){ + for(TypicalMorph common : TYPED_MAP.get(morphType)){ + common.orderNo = order++; + } + } + + return; + } + + + /** + * 種別ごとのモーフ情報リストを取得する。 + * @param morphType モーフ種別 + * @return モーフ情報リスト + */ + public static List getTypedMorphList(MorphType morphType){ + List result = TYPED_MAP.get(morphType); + return result; + } + + /** + * プライマリ名の合致するモーフ情報を返す。 + * @param primaryName プライマリ名 + * @return モーフ情報。見つからなければnull + */ + public static TypicalMorph findWithPrimary(String primaryName){ + TypicalMorph result = PRIMARY_MAP.get(primaryName); + return result; + } + + /** + * グローバル名の合致するモーフ情報を返す。 + * @param globalName グローバル名 + * @return モーフ情報。見つからなければnull + */ + public static TypicalMorph findWithGlobal(String globalName){ + TypicalMorph result = GLOBAL_MAP.get(globalName); + return result; + } + + /** + * プライマリ名をグローバル名に変換する。 + * @param primaryName プライマリ名 + * @return グローバル名。見つからなければnull + */ + public static String primary2global(String primaryName){ + TypicalMorph morph = findWithPrimary(primaryName); + if(morph == null) return null; + String global = morph.getTopGlobalName(); + return global; + } + + /** + * グローバル名をプライマリ名へ変換する。 + * @param globalName グローバル名 + * @return プライマリ名。見つからなければnull + */ + public static String global2primary(String globalName){ + TypicalMorph morph = findWithGlobal(globalName); + if(morph == null) return null; + String primary = morph.getTopPrimaryName(); + return primary; + } + + /** + * モーフ種別を返す。 + * @return モーフ種別 + */ + public MorphType getMorphType(){ + return this.type; + } + +} diff --git a/src/main/java/jp/sourceforge/mikutoga/typical/TypicalObject.java b/src/main/java/jp/sourceforge/mikutoga/typical/TypicalObject.java new file mode 100644 index 0000000..f1a4bd8 --- /dev/null +++ b/src/main/java/jp/sourceforge/mikutoga/typical/TypicalObject.java @@ -0,0 +1,172 @@ +/* + * typical object information + * + * License : The MIT License + * Copyright(c) 2011 MikuToga Partners + */ + +package jp.sourceforge.mikutoga.typical; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.LinkedList; +import java.util.List; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.xml.sax.SAXException; + +/** + * 各種標準オブジェクトの実装基板。 + *

国産モデルではプライマリ名に日本語名が収められることが多い。 + * プライマリ名は必ず一つ以上なければならない。 + *

国産モデルではグローバル名に英語名が収められることが多いが、 + * プライマリ名と同一の日本語名が収められている場合も多い。 + */ +class TypicalObject { + + /** オーダ番号によるコンパレータ。 */ + public static final Comparator ORDER_COMPARATOR = + new OrderComparator(); + + protected final List primaryList; + protected final List globalList; + + protected final List umodPrimaryList; + protected final List umodGlobalList; + + protected int orderNo; + + + /** + * コンストラクタ。 + *

各初期数が0以下の場合は、状況に応じて伸長する連結リストが用意される。 + * @param primaryNo プライマリ名初期数。 + * @param globalNo グローバル名初期数。 + */ + protected TypicalObject(int primaryNo, int globalNo){ + super(); + + if(primaryNo <= 0){ + this.primaryList = new LinkedList(); + }else{ + this.primaryList = new ArrayList(primaryNo); + } + + if(globalNo <= 0){ + this.globalList = new LinkedList(); + }else{ + this.globalList = new ArrayList(globalNo); + } + + this.umodPrimaryList = + Collections.unmodifiableList(this.primaryList); + this.umodGlobalList = + Collections.unmodifiableList(this.globalList); + + return; + } + + /** + * コンストラクタ。 + *

プライマリ名、グローバル名共、状況に応じて伸長する連結リストが用意される。 + */ + protected TypicalObject(){ + this(0, 0); + return; + } + + + /** + * XMLドキュメントをロードする。 + * @param is 入力 + * @return 最上位要素 + * @throws ParserConfigurationException XMLの構成が変 + * @throws SAXException XMLの内容が変 + * @throws IOException 入力エラー + */ + protected static Element loadXml(InputStream is) + throws ParserConfigurationException, SAXException, IOException { + DocumentBuilderFactory factory; + factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); + + DocumentBuilder builder = factory.newDocumentBuilder(); + Document doc = builder.parse(is); + + Element top = doc.getDocumentElement(); + + return top; + } + + + /** + * プライマリ名をひとつ返す。 + * @return 最初のプライマリ名 + */ + public String getTopPrimaryName(){ + String result = this.primaryList.get(0); + return result; + } + + /** + * グローバル名をひとつ返す。 + * @return 最初のグローバル名。ひとつもなければnull + */ + public String getTopGlobalName(){ + String result; + if(this.globalList.isEmpty()) result = null; + else result = this.globalList.get(0); + return result; + } + + /** + * 全プライマリ名を返す。 + * @return 全プライマリ名リスト。(不可変) + */ + public List getPrimaryList(){ + return this.umodPrimaryList; + } + + /** + * 全グローバル名を返す。 + * @return 全グローバル名リスト。(不可変) + */ + public List getGlobalList(){ + return this.umodGlobalList; + } + + /** + * オーダ番号によるコンパレータ。 + */ + private static class OrderComparator + implements Comparator { + + /** + * コンストラクタ。 + */ + private OrderComparator(){ + super(); + return; + } + + /** + * オーダ番号を順序づける。 + * @param o1 {@inheritDoc} + * @param o2 {@inheritDoc} + * @return {@inheritDoc} + */ + @Override + public int compare(TypicalObject o1, TypicalObject o2){ + int result = o1.orderNo - o2.orderNo; + return result; + } + + } + +} diff --git a/src/main/java/jp/sourceforge/mikutoga/typical/package-info.java b/src/main/java/jp/sourceforge/mikutoga/typical/package-info.java new file mode 100644 index 0000000..93e1b33 --- /dev/null +++ b/src/main/java/jp/sourceforge/mikutoga/typical/package-info.java @@ -0,0 +1,16 @@ +/* + * typical information + * + * License : The MIT License + * Copyright(c) 2011 MikuToga Partners + */ + +/** + * MMDコミュニティにおける一般的な慣例に関する情報を提供する。 + *

例)ボーン名やモーフ名の一般的な名前など + *

MikuMikuDance Ver.7.39同梱のモデルなどが主な情報源。 + */ + +package jp.sourceforge.mikutoga.typical; + +/* EOF */ diff --git a/src/main/resources/jp/sourceforge/mikutoga/typical/resources/typicalBone.xml b/src/main/resources/jp/sourceforge/mikutoga/typical/resources/typicalBone.xml new file mode 100644 index 0000000..dbd26fb --- /dev/null +++ b/src/main/resources/jp/sourceforge/mikutoga/typical/resources/typicalBone.xml @@ -0,0 +1,413 @@ + + + + + + + + + + + + + +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/jp/sourceforge/mikutoga/typical/resources/typicalMorph.xml b/src/main/resources/jp/sourceforge/mikutoga/typical/resources/typicalMorph.xml new file mode 100644 index 0000000..ebbae48 --- /dev/null +++ b/src/main/resources/jp/sourceforge/mikutoga/typical/resources/typicalMorph.xml @@ -0,0 +1,184 @@ + + + + + + + + + + + + + + + +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +