-// ================================================================================================\r
-// <summary>\r
-// 翻訳支援処理を実装するための共通クラスソース</summary>\r
-//\r
-// <copyright file="Translator.cs" company="honeplusのメモ帳">\r
-// Copyright (C) 2010 Honeplus. All rights reserved.</copyright>\r
-// <author>\r
-// Honeplus</author>\r
-// ================================================================================================\r
-\r
-namespace Honememo.Wptscs.Logics\r
-{\r
- using System;\r
- using System.IO;\r
- using System.Net;\r
- using System.Net.NetworkInformation;\r
- using System.Reflection;\r
- using Honememo.Utilities;\r
- using Honememo.Wptscs.Models;\r
- using Honememo.Wptscs.Properties;\r
-\r
- /// <summary>\r
- /// 翻訳支援処理を実装するための共通クラスです。\r
- /// </summary>\r
- public abstract class Translator\r
- {\r
- #region private変数\r
-\r
- /// <summary>\r
- /// 改行コード。\r
- /// </summary>\r
- public static readonly string ENTER = "\r\n";\r
-\r
- /// <summary>\r
- /// ログメッセージ。\r
- /// </summary>\r
- private string log;\r
-\r
- /// <summary>\r
- /// 変換後テキスト。\r
- /// </summary>\r
- private string text;\r
-\r
- #endregion\r
- \r
- #region イベント\r
-\r
- /// <summary>\r
- /// ログ更新伝達イベント。\r
- /// </summary>\r
- public event EventHandler LogUpdate;\r
-\r
- #endregion\r
-\r
- #region プロパティ\r
-\r
- /// <summary>\r
- /// 言語間の項目の対訳表。\r
- /// </summary>\r
- public TranslationDictionary ItemTable\r
- {\r
- get;\r
- set;\r
- }\r
-\r
- /// <summary>\r
- /// 言語間の見出しの対訳表。\r
- /// </summary>\r
- public TranslationTable HeadingTable\r
- {\r
- get;\r
- set;\r
- }\r
-\r
- /// <summary>\r
- /// ログメッセージ。\r
- /// </summary>\r
- public string Log\r
- {\r
- // ※ 将来的には、ロジックでログメッセージを出すなんて形を止めて\r
- // データとして保持させてメッセージはビューで・・・としたいが、\r
- // 手間を考えて当面はこの形のまま実装する。\r
- get\r
- {\r
- return this.log;\r
- }\r
-\r
- protected set\r
- {\r
- this.log = (value != null) ? value : String.Empty;\r
- if (this.LogUpdate != null)\r
- {\r
- this.LogUpdate(this, EventArgs.Empty);\r
- }\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// 変換後テキスト。\r
- /// </summary>\r
- public string Text\r
- {\r
- get\r
- {\r
- return this.text;\r
- }\r
-\r
- protected set\r
- {\r
- this.text = StringUtils.DefaultString(value);\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// 処理を途中で終了させるためのフラグ。\r
- /// </summary>\r
- public bool CancellationPending\r
- {\r
- get;\r
- set;\r
- }\r
-\r
- /// <summary>\r
- /// 翻訳元言語のサイト。\r
- /// </summary>\r
- public Website From\r
- {\r
- get;\r
- set;\r
- }\r
-\r
- /// <summary>\r
- /// 翻訳先言語のサイト。\r
- /// </summary>\r
- public Website To\r
- {\r
- get;\r
- set;\r
- }\r
-\r
- #endregion\r
-\r
- #region 静的メソッド\r
-\r
- /// <summary>\r
- /// 翻訳支援処理のインスタンスを作成。\r
- /// </summary>\r
- /// <param name="config">アプリケーション設定。</param>\r
- /// <param name="from">翻訳元言語。</param>\r
- /// <param name="to">翻訳先言語。</param>\r
- /// <returns>生成したインスタンス。</returns>\r
- /// <remarks>\r
- /// 設定は設定クラスより取得、無ければ一部自動生成する。\r
- /// インスタンス生成失敗時は例外を投げる。\r
- /// </remarks>\r
- public static Translator Create(Config config, string from, string to)\r
- {\r
- // 処理対象に応じてTranslatorを継承したオブジェクトを生成\r
- ConstructorInfo constructor = config.Translator.GetConstructor(Type.EmptyTypes);\r
- if (constructor == null)\r
- {\r
- throw new NotImplementedException(config.Translator.FullName + " default constructor is not found");\r
- }\r
-\r
- // 設定に指定されたクラスを、引数無しのコンストラクタを用いて生成する\r
- Translator translator = (Translator)constructor.Invoke(null);\r
-\r
- // Webサイトの設定\r
- translator.From = config.GetWebsite(from);\r
- translator.To = config.GetWebsite(to);\r
-\r
- // 対訳表(項目)の設定\r
- translator.ItemTable = config.GetItemTableNeedCreate(from, to);\r
-\r
- // 対訳表(見出し)の設定、使用する言語は決まっているので組み合わせを設定\r
- translator.HeadingTable = config.HeadingTable;\r
- translator.HeadingTable.From = from;\r
- translator.HeadingTable.To = to;\r
-\r
- return translator;\r
- }\r
-\r
- #endregion\r
-\r
- #region publicメソッド\r
-\r
- /// <summary>\r
- /// 翻訳支援処理実行。\r
- /// </summary>\r
- /// <param name="name">記事名。</param>\r
- /// <returns><c>true</c> 処理成功</returns>\r
- public virtual bool Run(string name)\r
- {\r
- // ※必須な情報が設定されていない場合、InvalidOperationExceptionを返す\r
- if (this.From == null || this.To == null)\r
- {\r
- throw new InvalidOperationException("From or To is null");\r
- }\r
-\r
- // 変数を初期化\r
- this.Initialize();\r
-\r
- // サーバー接続チェック\r
- string host = new Uri(this.From.Location).Host;\r
- if (!String.IsNullOrEmpty(host) && !Settings.Default.IgnoreError)\r
- {\r
- if (!this.Ping(host))\r
- {\r
- return false;\r
- }\r
- }\r
-\r
- // 翻訳支援処理実行部の本体を実行\r
- // ※以降の処理は、継承クラスにて定義\r
- return this.RunBody(name);\r
- }\r
- \r
- #endregion\r
-\r
- #region protectedメソッド\r
-\r
- /// <summary>\r
- /// 翻訳支援処理実行部の本体。\r
- /// </summary>\r
- /// <param name="name">記事名。</param>\r
- /// <returns><c>true</c> 処理成功</returns>\r
- /// <remarks>テンプレートメソッド的な構造になっています。</remarks>\r
- protected abstract bool RunBody(string name);\r
-\r
- /// <summary>\r
- /// ログメッセージを1行追加出力。\r
- /// </summary>\r
- /// <param name="log">ログメッセージ。</param>\r
- protected void LogLine(string log)\r
- {\r
- // 直前のログが改行されていない場合、改行して出力\r
- if (this.Log != String.Empty && this.Log.EndsWith(ENTER) == false)\r
- {\r
- this.Log += ENTER + log + ENTER;\r
- }\r
- else\r
- {\r
- this.Log += log + ENTER;\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// ログメッセージを1行追加出力(入力された文字列を書式化して表示)。\r
- /// </summary>\r
- /// <param name="format">書式項目を含んだログメッセージ。</param>\r
- /// <param name="args">書式設定対象オブジェクト配列。</param>\r
- protected void LogLine(string format, params object[] args)\r
- {\r
- // オーバーロードメソッドをコール\r
- this.LogLine(String.Format(format, args));\r
- }\r
-\r
- /// <summary>\r
- /// ログメッセージを出力しつつページを取得。\r
- /// </summary>\r
- /// <param name="title">ページタイトル。</param>\r
- /// <param name="notFoundMsg">取得できない場合に出力するメッセージ。</param>\r
- /// <returns>取得したページ。ページが存在しない場合は <c>null</c> を返す。</returns>\r
- /// <remarks>通信エラーなど例外が発生した場合は、別途エラーログを出力する。</remarks>\r
- protected Page GetPage(string title, string notFoundMsg)\r
- {\r
- try\r
- {\r
- // 取得できた場合はここで終了\r
- return this.From.GetPage(title);\r
- }\r
- catch (WebException e)\r
- {\r
- // 通信エラー\r
- if (e.Status == WebExceptionStatus.ProtocolError\r
- && (e.Response as HttpWebResponse).StatusCode == HttpStatusCode.NotFound)\r
- {\r
- // 404\r
- this.Log += notFoundMsg;\r
- }\r
- else\r
- {\r
- // それ以外のエラー\r
- this.LogLine(Resources.RightArrow + " " + e.Message);\r
- if (e.Response != null)\r
- {\r
- this.LogLine(Resources.RightArrow + " " + String.Format(Resources.LogMessage_ErrorURL, e.Response.ResponseUri));\r
- }\r
- }\r
- }\r
- catch (FileNotFoundException)\r
- {\r
- // ファイル無し\r
- this.Log += notFoundMsg;\r
- }\r
- catch (Exception e)\r
- {\r
- // その他の想定外のエラー\r
- this.LogLine(Resources.RightArrow + " " + e.Message);\r
- }\r
-\r
- // 取得失敗時いずれの場合もnull\r
- return null;\r
- }\r
-\r
- #endregion\r
-\r
- #region privateメソッド\r
-\r
- /// <summary>\r
- /// 翻訳支援処理実行時の初期化処理。\r
- /// </summary>\r
- private void Initialize()\r
- {\r
- // 変数を初期化\r
- this.log = String.Empty;\r
- this.Text = String.Empty;\r
- this.CancellationPending = false;\r
- }\r
-\r
- /// <summary>\r
- /// サーバー接続チェック。\r
- /// </summary>\r
- /// <param name="server">サーバー名。</param>\r
- /// <returns><c>true</c> 接続成功。</returns>\r
- private bool Ping(string server)\r
- {\r
- // サーバー接続チェック\r
- Ping ping = new Ping();\r
- try\r
- {\r
- PingReply reply = ping.Send(server);\r
- if (reply.Status != IPStatus.Success)\r
- {\r
- this.LogLine(Resources.ErrorMessageConnectionFailed, reply.Status.ToString());\r
- return false;\r
- }\r
- }\r
- catch (Exception e)\r
- {\r
- this.LogLine(Resources.ErrorMessageConnectionFailed, e.InnerException.Message);\r
- return false;\r
- }\r
-\r
- return true;\r
- }\r
-\r
- #endregion\r
- }\r
-}\r
+// ================================================================================================
+// <summary>
+// 翻訳支援処理を実装するための共通クラスソース</summary>
+//
+// <copyright file="Translator.cs" company="honeplusのメモ帳">
+// Copyright (C) 2010 Honeplus. All rights reserved.</copyright>
+// <author>
+// Honeplus</author>
+// ================================================================================================
+
+namespace Honememo.Wptscs.Logics
+{
+ using System;
+ using System.IO;
+ using System.Net;
+ using System.Net.NetworkInformation;
+ using System.Reflection;
+ using Honememo.Utilities;
+ using Honememo.Wptscs.Models;
+ using Honememo.Wptscs.Properties;
+
+ /// <summary>
+ /// 翻訳支援処理を実装するための共通クラスです。
+ /// </summary>
+ public abstract class Translator
+ {
+ #region private変数
+
+ /// <summary>
+ /// 改行コード。
+ /// </summary>
+ public static readonly string ENTER = "\r\n";
+
+ /// <summary>
+ /// ログメッセージ。
+ /// </summary>
+ private string log;
+
+ /// <summary>
+ /// 変換後テキスト。
+ /// </summary>
+ private string text;
+
+ #endregion
+
+ #region イベント
+
+ /// <summary>
+ /// ログ更新伝達イベント。
+ /// </summary>
+ public event EventHandler LogUpdate;
+
+ #endregion
+
+ #region プロパティ
+
+ /// <summary>
+ /// 言語間の項目の対訳表。
+ /// </summary>
+ public TranslationDictionary ItemTable
+ {
+ get;
+ set;
+ }
+
+ /// <summary>
+ /// 言語間の見出しの対訳表。
+ /// </summary>
+ public TranslationTable HeadingTable
+ {
+ get;
+ set;
+ }
+
+ /// <summary>
+ /// ログメッセージ。
+ /// </summary>
+ public string Log
+ {
+ // ※ 将来的には、ロジックでログメッセージを出すなんて形を止めて
+ // データとして保持させてメッセージはビューで・・・としたいが、
+ // 手間を考えて当面はこの形のまま実装する。
+ get
+ {
+ return this.log;
+ }
+
+ protected set
+ {
+ this.log = (value != null) ? value : String.Empty;
+ if (this.LogUpdate != null)
+ {
+ this.LogUpdate(this, EventArgs.Empty);
+ }
+ }
+ }
+
+ /// <summary>
+ /// 変換後テキスト。
+ /// </summary>
+ public string Text
+ {
+ get
+ {
+ return this.text;
+ }
+
+ protected set
+ {
+ this.text = StringUtils.DefaultString(value);
+ }
+ }
+
+ /// <summary>
+ /// 処理を途中で終了させるためのフラグ。
+ /// </summary>
+ public bool CancellationPending
+ {
+ get;
+ set;
+ }
+
+ /// <summary>
+ /// 翻訳元言語のサイト。
+ /// </summary>
+ public Website From
+ {
+ get;
+ set;
+ }
+
+ /// <summary>
+ /// 翻訳先言語のサイト。
+ /// </summary>
+ public Website To
+ {
+ get;
+ set;
+ }
+
+ #endregion
+
+ #region 静的メソッド
+
+ /// <summary>
+ /// 翻訳支援処理のインスタンスを作成。
+ /// </summary>
+ /// <param name="config">アプリケーション設定。</param>
+ /// <param name="from">翻訳元言語。</param>
+ /// <param name="to">翻訳先言語。</param>
+ /// <returns>生成したインスタンス。</returns>
+ /// <remarks>
+ /// 設定は設定クラスより取得、無ければ一部自動生成する。
+ /// インスタンス生成失敗時は例外を投げる。
+ /// </remarks>
+ public static Translator Create(Config config, string from, string to)
+ {
+ // 処理対象に応じてTranslatorを継承したオブジェクトを生成
+ ConstructorInfo constructor = config.Translator.GetConstructor(Type.EmptyTypes);
+ if (constructor == null)
+ {
+ throw new NotImplementedException(config.Translator.FullName + " default constructor is not found");
+ }
+
+ // 設定に指定されたクラスを、引数無しのコンストラクタを用いて生成する
+ Translator translator = (Translator)constructor.Invoke(null);
+
+ // Webサイトの設定
+ translator.From = config.GetWebsite(from);
+ translator.To = config.GetWebsite(to);
+
+ // 対訳表(項目)の設定
+ translator.ItemTable = config.GetItemTableNeedCreate(from, to);
+
+ // 対訳表(見出し)の設定、使用する言語は決まっているので組み合わせを設定
+ translator.HeadingTable = config.HeadingTable;
+ translator.HeadingTable.From = from;
+ translator.HeadingTable.To = to;
+
+ return translator;
+ }
+
+ #endregion
+
+ #region publicメソッド
+
+ /// <summary>
+ /// 翻訳支援処理実行。
+ /// </summary>
+ /// <param name="name">記事名。</param>
+ /// <returns><c>true</c> 処理成功</returns>
+ public virtual bool Run(string name)
+ {
+ // ※必須な情報が設定されていない場合、InvalidOperationExceptionを返す
+ if (this.From == null || this.To == null)
+ {
+ throw new InvalidOperationException("From or To is null");
+ }
+
+ // 変数を初期化
+ this.Initialize();
+
+ // サーバー接続チェック
+ string host = new Uri(this.From.Location).Host;
+ if (!String.IsNullOrEmpty(host) && !Settings.Default.IgnoreError)
+ {
+ if (!this.Ping(host))
+ {
+ return false;
+ }
+ }
+
+ // 翻訳支援処理実行部の本体を実行
+ // ※以降の処理は、継承クラスにて定義
+ return this.RunBody(name);
+ }
+
+ #endregion
+
+ #region protectedメソッド
+
+ /// <summary>
+ /// 翻訳支援処理実行部の本体。
+ /// </summary>
+ /// <param name="name">記事名。</param>
+ /// <returns><c>true</c> 処理成功</returns>
+ /// <remarks>テンプレートメソッド的な構造になっています。</remarks>
+ protected abstract bool RunBody(string name);
+
+ /// <summary>
+ /// ログメッセージを1行追加出力。
+ /// </summary>
+ /// <param name="log">ログメッセージ。</param>
+ protected void LogLine(string log)
+ {
+ // 直前のログが改行されていない場合、改行して出力
+ if (this.Log != String.Empty && this.Log.EndsWith(ENTER) == false)
+ {
+ this.Log += ENTER + log + ENTER;
+ }
+ else
+ {
+ this.Log += log + ENTER;
+ }
+ }
+
+ /// <summary>
+ /// ログメッセージを1行追加出力(入力された文字列を書式化して表示)。
+ /// </summary>
+ /// <param name="format">書式項目を含んだログメッセージ。</param>
+ /// <param name="args">書式設定対象オブジェクト配列。</param>
+ protected void LogLine(string format, params object[] args)
+ {
+ // オーバーロードメソッドをコール
+ this.LogLine(String.Format(format, args));
+ }
+
+ /// <summary>
+ /// ログメッセージを出力しつつページを取得。
+ /// </summary>
+ /// <param name="title">ページタイトル。</param>
+ /// <param name="notFoundMsg">取得できない場合に出力するメッセージ。</param>
+ /// <returns>取得したページ。ページが存在しない場合は <c>null</c> を返す。</returns>
+ /// <remarks>通信エラーなど例外が発生した場合は、別途エラーログを出力する。</remarks>
+ protected Page GetPage(string title, string notFoundMsg)
+ {
+ try
+ {
+ // 取得できた場合はここで終了
+ return this.From.GetPage(title);
+ }
+ catch (WebException e)
+ {
+ // 通信エラー
+ if (e.Status == WebExceptionStatus.ProtocolError
+ && (e.Response as HttpWebResponse).StatusCode == HttpStatusCode.NotFound)
+ {
+ // 404
+ this.Log += notFoundMsg;
+ }
+ else
+ {
+ // それ以外のエラー
+ this.LogLine(Resources.RightArrow + " " + e.Message);
+ if (e.Response != null)
+ {
+ this.LogLine(Resources.RightArrow + " " + String.Format(Resources.LogMessage_ErrorURL, e.Response.ResponseUri));
+ }
+ }
+ }
+ catch (FileNotFoundException)
+ {
+ // ファイル無し
+ this.Log += notFoundMsg;
+ }
+ catch (Exception e)
+ {
+ // その他の想定外のエラー
+ this.LogLine(Resources.RightArrow + " " + e.Message);
+ }
+
+ // 取得失敗時いずれの場合もnull
+ return null;
+ }
+
+ #endregion
+
+ #region privateメソッド
+
+ /// <summary>
+ /// 翻訳支援処理実行時の初期化処理。
+ /// </summary>
+ private void Initialize()
+ {
+ // 変数を初期化
+ this.log = String.Empty;
+ this.Text = String.Empty;
+ this.CancellationPending = false;
+ }
+
+ /// <summary>
+ /// サーバー接続チェック。
+ /// </summary>
+ /// <param name="server">サーバー名。</param>
+ /// <returns><c>true</c> 接続成功。</returns>
+ private bool Ping(string server)
+ {
+ // サーバー接続チェック
+ Ping ping = new Ping();
+ try
+ {
+ PingReply reply = ping.Send(server);
+ if (reply.Status != IPStatus.Success)
+ {
+ this.LogLine(Resources.ErrorMessageConnectionFailed, reply.Status.ToString());
+ return false;
+ }
+ }
+ catch (Exception e)
+ {
+ this.LogLine(Resources.ErrorMessageConnectionFailed, e.InnerException.Message);
+ return false;
+ }
+
+ return true;
+ }
+
+ #endregion
+ }
+}