OSDN Git Service

4637219e66a0a524573fde7ba822bf5c67cd378c
[wptscs/wpts.git] / Wptscs / Models / TranslationTable.cs
1 // ================================================================================================
2 // <summary>
3 //      言語間の対訳表をあらわすモデルクラスソース</summary>
4 //
5 // <copyright file="TranslationTable.cs" company="honeplusのメモ帳">
6 //      Copyright (C) 2012 Honeplus. All rights reserved.</copyright>
7 // <author>
8 //      Honeplus</author>
9 // ================================================================================================
10
11 namespace Honememo.Wptscs.Models
12 {
13     using System;
14     using System.Collections.Generic;
15     using System.Linq;
16     using System.Xml;
17     using System.Xml.Serialization;
18     using Honememo.Utilities;
19
20     /// <summary>
21     /// 言語間の対訳表をあらわすモデルクラスです。
22     /// </summary>
23     public class TranslationTable : List<IDictionary<string, string[]>>, IXmlSerializable
24     {
25         #region プロパティ
26         
27         /// <summary>
28         /// 翻訳元言語コード。
29         /// </summary>
30         /// <remarks><see cref="GetWord(string)"/>の呼び出しを簡略化するためのプロパティ。</remarks>
31         public string From
32         {
33             get;
34             set;
35         }
36
37         /// <summary>
38         /// 翻訳先言語コード。
39         /// </summary>
40         /// <remarks><see cref="GetWord(string)"/>の呼び出しを簡略化するためのプロパティ。</remarks>
41         public string To
42         {
43             get;
44             set;
45         }
46
47         #endregion
48
49         #region 公開メソッド
50
51         /// <summary>
52         /// 指定された言語の対訳語を取得する。
53         /// </summary>
54         /// <param name="from">翻訳元言語コード。</param>
55         /// <param name="to">翻訳先言語コード。</param>
56         /// <param name="word">翻訳元語句。</param>
57         /// <returns>対訳語句。登録されていない場合 <c>null</c>。</returns>
58         /// <exception cref="ArgumentNullException"><paramref name="from"/>, <paramref name="to"/>, <paramref name="word"/>のいずれかが<c>null</c>の場合。</exception>
59         /// <remarks><paramref name="word"/>の大文字小文字は区別しない。</remarks>
60         public string GetWord(string from, string to, string word)
61         {
62             // nullは不可。以降でエラーになるためここでチェック
63             Validate.NotNull(from, "from");
64             Validate.NotNull(to, "to");
65             string w = Validate.NotNull(word, "word").ToLower();
66
67             // 翻訳元言語の項目を探索
68             foreach (IDictionary<string, string[]> record in this)
69             {
70                 if (record.ContainsKey(from) && CollectionUtils.ContainsIgnoreCase(record[from], w))
71                 {
72                     // 翻訳元を発見した場合、それに対応する翻訳先の語句を返す
73                     string s = null;
74                     if (record.ContainsKey(to))
75                     {
76                         // 代表で先頭の値を取得
77                         s = record[to].First();
78                     }
79
80                     return s;
81                 }
82             }
83
84             return null;
85         }
86
87         /// <summary>
88         /// 指定されている言語の組み合わせで対訳語を取得する。
89         /// </summary>
90         /// <param name="word">翻訳元語。</param>
91         /// <returns>対訳語。登録されていない場合 <c>null</c>。</returns>
92         /// <exception cref="InvalidOperationException"><see cref="From"/>, <see cref="To"/>のいずれかが空の場合。</exception>
93         /// <remarks>大文字小文字は区別しない。</remarks>
94         public string GetWord(string word)
95         {
96             if (string.IsNullOrEmpty(this.From) || string.IsNullOrEmpty(this.To))
97             {
98                 throw new InvalidOperationException("empty from or to");
99             }
100
101             return this.GetWord(this.From, this.To, word);
102         }
103
104         #endregion
105
106         #region XMLシリアライズ用メソッド
107
108         /// <summary>
109         /// シリアライズするXMLのスキーマ定義を返す。
110         /// </summary>
111         /// <returns>XML表現を記述する<see cref="System.Xml.Schema.XmlSchema"/>。</returns>
112         public System.Xml.Schema.XmlSchema GetSchema()
113         {
114             return null;
115         }
116
117         /// <summary>
118         /// XMLからオブジェクトをデシリアライズする。
119         /// </summary>
120         /// <param name="reader">デシリアライズ元の<see cref="XmlReader"/></param>
121         public void ReadXml(XmlReader reader)
122         {
123             XmlDocument xml = new XmlDocument();
124             xml.Load(reader);
125
126             // ※ 以下、基本的に無かったらNGの部分はいちいちチェックしない。例外飛ばす
127             XmlElement tableElement = xml.DocumentElement;
128
129             // 各対訳の読み込み
130             this.Clear();
131             foreach (XmlNode recordNode in tableElement.SelectNodes("Group"))
132             {
133                 IDictionary<string, string[]> record = new Dictionary<string, string[]>();
134                 foreach (XmlNode wordNode in recordNode)
135                 {
136                     // 一つの言語に複数の値が登録可能なため、その場合配列に積む
137                     XmlElement wordElement = wordNode as XmlElement;
138                     string lang = wordElement.GetAttribute("Lang");
139                     string word = wordElement.InnerText;
140                     List<string> list = new List<string>();
141                     string[] words;
142                     if (record.TryGetValue(lang, out words))
143                     {
144                         list.AddRange(words);
145                     }
146
147                     // 既に登録されている場合、代表であれば先頭に、それ以外なら後ろに追加
148                     bool head;
149                     if (bool.TryParse(wordElement.GetAttribute("Head"), out head) && head)
150                     {
151                         list.Insert(0, word);
152                     }
153                     else
154                     {
155                         list.Add(word);
156                     }
157
158                     record[lang] = list.ToArray();
159                 }
160
161                 this.Add(record);
162             }
163         }
164
165         /// <summary>
166         /// オブジェクトをXMLにシリアライズする。
167         /// </summary>
168         /// <param name="writer">シリアライズ先の<see cref="XmlWriter"/></param>
169         public void WriteXml(XmlWriter writer)
170         {
171             // 各対訳の出力
172             foreach (IDictionary<string, string[]> record in this)
173             {
174                 writer.WriteStartElement("Group");
175                 foreach (KeyValuePair<string, string[]> words in record)
176                 {
177                     bool first = true;
178                     foreach (string word in words.Value)
179                     {
180                         writer.WriteStartElement("Word");
181                         writer.WriteAttributeString("Lang", words.Key);
182                         if (first && words.Value.Length > 1)
183                         {
184                             // 先頭項目は変換先として使用されるため、複数ある場合は代表フラグを出力
185                             // ※ 2番目以降は同格のため、先頭以外の並び順は保障しない
186                             writer.WriteAttributeString("Head", bool.TrueString);
187                             first = false;
188                         }
189
190                         writer.WriteValue(word);
191                         writer.WriteEndElement();
192                     }
193                 }
194
195                 writer.WriteEndElement();
196             }
197         }
198
199         #endregion
200     }
201 }