1 // ================================================================================================
\r
3 // 翻訳支援処理を実装するための共通クラスソース</summary>
\r
5 // <copyright file="Translator.cs" company="honeplusのメモ帳">
\r
6 // Copyright (C) 2010 Honeplus. All rights reserved.</copyright>
\r
9 // ================================================================================================
\r
11 namespace Honememo.Wptscs.Logics
\r
16 using System.Net.NetworkInformation;
\r
17 using System.Reflection;
\r
18 using Honememo.Utilities;
\r
19 using Honememo.Wptscs.Models;
\r
20 using Honememo.Wptscs.Properties;
\r
23 /// 翻訳支援処理を実装するための共通クラスです。
\r
25 public abstract class Translator
\r
32 public static readonly string ENTER = "\r\n";
\r
42 private string text;
\r
51 public event EventHandler LogUpdate;
\r
60 public TranslationDictionary ItemTable
\r
69 public TranslationTable HeadingTable
\r
80 // ※ 将来的には、ロジックでログメッセージを出すなんて形を止めて
\r
81 // データとして保持させてメッセージはビューで・・・としたいが、
\r
82 // 手間を考えて当面はこの形のまま実装する。
\r
90 this.log = (value != null) ? value : String.Empty;
\r
91 if (this.LogUpdate != null)
\r
93 this.LogUpdate(this, EventArgs.Empty);
\r
110 this.text = StringUtils.DefaultString(value);
\r
115 /// 処理を途中で終了させるためのフラグ。
\r
117 public bool CancellationPending
\r
126 public Website From
\r
146 /// 翻訳支援処理のインスタンスを作成。
\r
148 /// <param name="config">アプリケーション設定。</param>
\r
149 /// <param name="from">翻訳元言語。</param>
\r
150 /// <param name="to">翻訳先言語。</param>
\r
151 /// <returns>生成したインスタンス。</returns>
\r
153 /// 設定は設定クラスより取得、無ければ一部自動生成する。
\r
154 /// インスタンス生成失敗時は例外を投げる。
\r
156 public static Translator Create(Config config, string from, string to)
\r
158 // 処理対象に応じてTranslatorを継承したオブジェクトを生成
\r
159 ConstructorInfo constructor = config.Translator.GetConstructor(Type.EmptyTypes);
\r
160 if (constructor == null)
\r
162 throw new NotImplementedException(config.Translator.FullName + " default constructor is not found");
\r
165 // 設定に指定されたクラスを、引数無しのコンストラクタを用いて生成する
\r
166 Translator translator = (Translator)constructor.Invoke(null);
\r
169 translator.From = config.GetWebsite(from);
\r
170 translator.To = config.GetWebsite(to);
\r
173 translator.ItemTable = config.GetItemTableNeedCreate(from, to);
\r
175 // 対訳表(見出し)の設定、使用する言語は決まっているので組み合わせを設定
\r
176 translator.HeadingTable = config.HeadingTable;
\r
177 translator.HeadingTable.From = from;
\r
178 translator.HeadingTable.To = to;
\r
190 /// <param name="name">記事名。</param>
\r
191 /// <returns><c>true</c> 処理成功</returns>
\r
192 public virtual bool Run(string name)
\r
194 // ※必須な情報が設定されていない場合、InvalidOperationExceptionを返す
\r
195 if (this.From == null || this.To == null)
\r
197 throw new InvalidOperationException("From or To is null");
\r
204 string host = new Uri(this.From.Location).Host;
\r
205 if (!String.IsNullOrEmpty(host) && !Settings.Default.IgnoreError)
\r
207 if (!this.Ping(host))
\r
214 // ※以降の処理は、継承クラスにて定義
\r
215 return this.RunBody(name);
\r
220 #region protectedメソッド
\r
225 /// <param name="name">記事名。</param>
\r
226 /// <returns><c>true</c> 処理成功</returns>
\r
227 /// <remarks>テンプレートメソッド的な構造になっています。</remarks>
\r
228 protected abstract bool RunBody(string name);
\r
231 /// ログメッセージを1行追加出力。
\r
233 /// <param name="log">ログメッセージ。</param>
\r
234 protected void LogLine(string log)
\r
236 // 直前のログが改行されていない場合、改行して出力
\r
237 if (this.Log != String.Empty && this.Log.EndsWith(ENTER) == false)
\r
239 this.Log += ENTER + log + ENTER;
\r
243 this.Log += log + ENTER;
\r
248 /// ログメッセージを1行追加出力(入力された文字列を書式化して表示)。
\r
250 /// <param name="format">書式項目を含んだログメッセージ。</param>
\r
251 /// <param name="args">書式設定対象オブジェクト配列。</param>
\r
252 protected void LogLine(string format, params object[] args)
\r
255 this.LogLine(String.Format(format, args));
\r
259 /// ログメッセージを出力しつつページを取得。
\r
261 /// <param name="title">ページタイトル。</param>
\r
262 /// <param name="notFoundMsg">取得できない場合に出力するメッセージ。</param>
\r
263 /// <returns>取得したページ。ページが存在しない場合は <c>null</c> を返す。</returns>
\r
264 /// <remarks>通信エラーなど例外が発生した場合は、別途エラーログを出力する。</remarks>
\r
265 protected Page GetPage(string title, string notFoundMsg)
\r
270 return this.From.GetPage(title);
\r
272 catch (WebException e)
\r
275 if (e.Status == WebExceptionStatus.ProtocolError
\r
276 && (e.Response as HttpWebResponse).StatusCode == HttpStatusCode.NotFound)
\r
279 this.Log += notFoundMsg;
\r
284 this.LogLine(Resources.RightArrow + " " + e.Message);
\r
285 if (e.Response != null)
\r
287 this.LogLine(Resources.RightArrow + " " + String.Format(Resources.LogMessage_ErrorURL, e.Response.ResponseUri));
\r
291 catch (FileNotFoundException)
\r
294 this.Log += notFoundMsg;
\r
296 catch (Exception e)
\r
299 this.LogLine(Resources.RightArrow + " " + e.Message);
\r
302 // 取得失敗時いずれの場合もnull
\r
308 #region privateメソッド
\r
311 /// 翻訳支援処理実行時の初期化処理。
\r
313 private void Initialize()
\r
316 this.log = String.Empty;
\r
317 this.Text = String.Empty;
\r
318 this.CancellationPending = false;
\r
324 /// <param name="server">サーバー名。</param>
\r
325 /// <returns><c>true</c> 接続成功。</returns>
\r
326 private bool Ping(string server)
\r
329 Ping ping = new Ping();
\r
332 PingReply reply = ping.Send(server);
\r
333 if (reply.Status != IPStatus.Success)
\r
335 this.LogLine(Resources.ErrorMessageConnectionFailed, reply.Status.ToString());
\r
339 catch (Exception e)
\r
341 this.LogLine(Resources.ErrorMessageConnectionFailed, e.InnerException.Message);
\r