| using System;  | 
| using System.Data;  | 
| using System.Configuration;  | 
| using System.Web;  | 
| using System.Web.Security;  | 
| using System.Web.UI;  | 
| using System.Web.UI.HtmlControls;  | 
| using System.Web.UI.WebControls;  | 
| using System.Web.UI.WebControls.WebParts;  | 
| using System.Xml;  | 
| using System.Runtime.CompilerServices;  | 
| using System.Threading;  | 
|   | 
|   | 
| namespace CCSTrace.CCS  | 
| {  | 
|     public class CCSMain  | 
|     {  | 
|         private static CCSMain _instance;  | 
|         public static CCS.Object.CCSCodelist CCSCodelist;  | 
|         public static CCS.Object.EOSCodelist EOSCodelist;  | 
|         public static System.Collections.ArrayList DBConnList = new System.Collections.ArrayList();  | 
|         public static System.Collections.ArrayList ProcessCases = new System.Collections.ArrayList();  | 
|   | 
|         private string LoadFilename = "DBConfig.xml";  | 
|         private string ConnectionString = String.Empty;  | 
|         private string traceConnectionString = String.Empty;  | 
|         private int ConnectionCount = 1;  | 
|         public static System.Data.OracleClient.OracleConnection MainConn = null;  | 
|         static SEventLog _MainLog = null;  | 
|   | 
|         public static System.Collections.Hashtable ProcessFDR = new System.Collections.Hashtable();//Record the processing FDR  | 
|         public static System.Collections.ArrayList WaitingCases = new System.Collections.ArrayList();//Record the case when the case's FDR processed by another  | 
|   | 
|         public CCSMain()  | 
|         {  | 
|             Initial();  | 
|         }  | 
|   | 
|         public static CCSMain Instance()  | 
|         {  | 
|   | 
|             // Uses lazy initialization.  | 
|   | 
|             // Note: this is not thread safe.  | 
|   | 
|             if (_instance == null)  | 
|             {  | 
|                 _instance = new CCSMain();  | 
|   | 
|             }  | 
|             return _instance;  | 
|   | 
|         }  | 
|   | 
|         private void Initial()  | 
|         {  | 
|             _MainLog = new SEventLog();  | 
|   | 
|             try  | 
|             {  | 
|                 ReadXML();  | 
|   | 
|                 if (MainConn == null)  | 
|                     MainConn = CreateConnection();  | 
|                     //MainConn = CreateMainConnection();  | 
|   | 
|                 CCSCodelist = new CCSTrace.CCS.Object.CCSCodelist(MainConn);  | 
|                 EOSCodelist = new CCSTrace.CCS.Object.EOSCodelist(MainConn);  | 
|   | 
|                 for (int i = 0; i < ConnectionCount; i++)  | 
|                     DBConnList.Add(CreateConnection());  | 
|             }  | 
|             catch(Exception e)  | 
|             {  | 
|                 Console.WriteLine(e.Message);  | 
|                 Console.WriteLine(e.StackTrace);  | 
|                 _MainLog.Error(e.Message);  | 
|   | 
|                 if (LocalVariable.ShowError)  | 
|                     _MainLog.Error(e.StackTrace);  | 
|   | 
|                 throw e;  | 
|             }  | 
|             finally  | 
|             {  | 
|                 _MainLog.Close();  | 
|             }  | 
|   | 
|             Object.CCSRecord m_Record = getWaitRecord();  | 
|   | 
|             if (m_Record != null)  | 
|             {  | 
|                 System.Data.OracleClient.OracleConnection _Conn = (System.Data.OracleClient.OracleConnection)DBConnList[0];  | 
|                 DBConnList.Remove(_Conn);  | 
|   | 
|                 ProcessCase(m_Record, _Conn);  | 
|             }  | 
|   | 
|         }  | 
|   | 
|         public void AcceptEvent(Object.CCSRecord _Record)  | 
|         {  | 
|             int i = 0;  | 
|             int ReConnectCount = 1;  | 
|   | 
|   | 
|             while ( i <= ReConnectCount )  | 
|             {  | 
|                 try  | 
|                 {  | 
|                     if (InsertEventRecord(_Record))  | 
|                     {  | 
|                         if (DBConnList.Count > 0)  | 
|                         {  | 
|   | 
|                             //將EVETNQUERY的案件狀態改為開始處理  | 
|                             Object.CCSRecord m_Record = getWaitRecord();  | 
|   | 
|                             if (m_Record != null)  | 
|                             {  | 
|                                 System.Data.OracleClient.OracleConnection _Conn = (System.Data.OracleClient.OracleConnection)DBConnList[0];  | 
|                                 DBConnList.Remove(_Conn);  | 
|   | 
|                                 ProcessCase(m_Record, _Conn);  | 
|                             }  | 
|                         }  | 
|   | 
|                         break;  | 
|                     }  | 
|                 }  | 
|                 catch (Exception ex)  | 
|                 {  | 
|                     if (MainConn.State.ToString().Equals("Closed"))  | 
|                     {  | 
|                         i++;  | 
|                         if (i > ReConnectCount)  | 
|                             throw ex;  | 
|                     }  | 
|                     else  | 
|                         throw ex;  | 
|                 }  | 
|             }  | 
|   | 
|   | 
|         }  | 
|   | 
|         private void ReadXML()  | 
|         {  | 
|             XmlReader reader = null;  | 
|   | 
|             try  | 
|             {  | 
|                 // 建立 XML 讀取器  | 
|                 XmlReaderSettings settings = new XmlReaderSettings();  | 
|                 settings.IgnoreComments = true; // 不處理註解  | 
|                 settings.IgnoreWhitespace = true; // 跳過空白  | 
|                 settings.ValidationType = ValidationType.None; // 不驗證任何資料  | 
|                 reader = XmlTextReader.Create(System.AppDomain.CurrentDomain.BaseDirectory + "\\" + LoadFilename, settings);  | 
|   | 
|                 // 進入讀取主要部分  | 
|                 while (reader.Read())  | 
|                 {  | 
|                     switch (reader.NodeType)  | 
|                     {  | 
|                         case XmlNodeType.Element:  | 
|                             string LocalName = reader.LocalName; // 取得標籤名稱  | 
|   | 
|                             // Step 3: 讀取 FileInfo 標籤的屬性  | 
|                             if (LocalName.Equals("DBSetting"))  | 
|                             {  | 
|                                 ConnectionString = String.Format("Data source={0};User Id={1};Password={2};", reader["DataSource"], reader["UserId"], reader["Password"]) ;  | 
|                                 traceConnectionString = String.Format("{0}/{1}@{2}", reader["UserId"], reader["Password"], reader["DataSource"]);  | 
|                                 ConnectionCount = Int32.Parse(reader["ConnectionCount"]);  | 
|                                 LocalVariable.ShowError = bool.Parse(reader["ShowError"]);  | 
|                             }  | 
|   | 
|                             break;  | 
|                     }  | 
|                 }  | 
|                 reader.Close();  | 
|   | 
|             }  | 
|             catch (System.Xml.XmlException xe)  | 
|             {  | 
|                 Console.WriteLine(xe.StackTrace);  | 
|                 reader.Close();  | 
|             }  | 
|         }  | 
|   | 
|         private System.Data.OracleClient.OracleConnection CreateConnection()  | 
|         {  | 
|             System.Data.OracleClient.OracleConnection DBConn = new System.Data.OracleClient.OracleConnection(ConnectionString);  | 
|               | 
|             DBConn.Open();  | 
|   | 
|             return DBConn;  | 
|         }  | 
|   | 
|         [MethodImpl(MethodImplOptions.Synchronized)]  | 
|         private bool InsertEventRecord(Object.CCSRecord _Record)  | 
|         {  | 
|             Object.EventQuery _EventQuery = null;  | 
|             System.Data.OracleClient.OracleTransaction _Transaction = null;  | 
|   | 
|             try  | 
|             {  | 
|                 _MainLog = new SEventLog();  | 
|   | 
|                 if (MainConn.State.ToString().Equals("Closed"))  | 
|                     MainConn.Open();  | 
|   | 
|                 _Transaction = MainConn.BeginTransaction();  | 
|   | 
|                 if (_Record.InsertDB(MainConn, _Transaction, _MainLog))  | 
|                 {  | 
|                     _EventQuery = new CCSTrace.CCS.Object.EventQuery();  | 
|   | 
|                     _EventQuery.setCCSID(_Record.getCCSID());  | 
|                     _EventQuery.setMeter(_Record.getMeter());  | 
|                     _EventQuery.setCaseStatus(LocalVariable.EventInitial);  | 
|                     _EventQuery.setChangeTime(_Record.getAcceptTime());  | 
|   | 
|                     if (_EventQuery.Insert(_MainLog, MainConn, _Transaction))  | 
|                         _Transaction.Commit();  | 
|                     else  | 
|                     {  | 
|                         if (_Transaction.Connection.State.ToString().Equals("Open"))  | 
|                             _Transaction.Rollback();  | 
|                           | 
|                         throw new Exception("案件未受理成功。");  | 
|                     }  | 
|                 }  | 
|                 else  | 
|                 {  | 
|                     if (_Transaction.Connection.State.ToString().Equals("Open"))  | 
|                         _Transaction.Rollback();  | 
|                       | 
|                     throw new Exception("案件未受理成功。");  | 
|                 }  | 
|   | 
|             }  | 
|             catch (System.Data.OracleClient.OracleException e)  | 
|             {  | 
|                 Console.WriteLine(e.Message);  | 
|                 Console.WriteLine(e.StackTrace);  | 
|                 _MainLog.Error(e.Message);  | 
|   | 
|                 if (LocalVariable.ShowError)  | 
|                     _MainLog.Error(e.StackTrace);  | 
|   | 
|                 if (_Transaction != null && _Transaction.Connection.State.ToString().Equals("Open") )  | 
|                     _Transaction.Rollback();  | 
|   | 
|                 throw e;  | 
|             }  | 
|             catch(Exception ex)  | 
|             {  | 
|                 Console.WriteLine(ex.Message);  | 
|                 Console.WriteLine(ex.StackTrace);  | 
|                 _MainLog.Error(ex.Message);  | 
|   | 
|                 if (LocalVariable.ShowError)  | 
|                     _MainLog.Error(ex.StackTrace);  | 
|   | 
|                 if (_Transaction != null && _Transaction.Connection.State.ToString().Equals("Open") )  | 
|                     _Transaction.Rollback();  | 
|   | 
|                 throw ex;  | 
|             }  | 
|             finally  | 
|             {  | 
|                 _MainLog.Close();  | 
|             }  | 
|   | 
|             return true;  | 
|         }  | 
|   | 
|         delegate void WorkerThreadHandler();  | 
|   | 
|         private void ProcessCase(Object.CCSRecord _Record, System.Data.OracleClient.OracleConnection _Conn)  | 
|         {  | 
|             try  | 
|             {  | 
|                 if (_Conn.State.ToString().Equals("Closed"))  | 
|                     _Conn.Open();  | 
|   | 
|                 ProcessEvent _ProcessEvent = new ProcessEvent(_Record, _Conn, traceConnectionString);  | 
|                 _ProcessEvent.ThreadFinish += new ThreadEndEventHandler(ThreadEndEventProcess);  | 
|   | 
|                 System.Threading.ThreadStart _ThreadStart = new System.Threading.ThreadStart(_ProcessEvent.Run);  | 
|                 System.Threading.Thread _Thread = new System.Threading.Thread(_ThreadStart);  | 
|                 _Thread.Start();  | 
|             }  | 
|             catch  | 
|             {  | 
|                 DBConnList.Add(_Conn);  | 
|             }  | 
|         }  | 
|   | 
|         private void ThreadEndEventProcess(object sender, ThreadEndEvent e)  | 
|         {  | 
|             //將EVETNQUERY的案件狀態改為開始處理  | 
|             Object.CCSRecord m_Record = getWaitRecord();  | 
|   | 
|             try  | 
|             {  | 
|                 if (m_Record != null)  | 
|                     ProcessCase(m_Record, e.getConnection());  | 
|                 else  | 
|                     DBConnList.Add(e.getConnection());  | 
|             }  | 
|             catch  | 
|             {  | 
|                 DBConnList.Add(e.getConnection());  | 
|             }  | 
|         }          | 
|   | 
|         [MethodImpl(MethodImplOptions.Synchronized)]  | 
|         private Object.CCSRecord getWaitRecord()   | 
|         {  | 
|             String ProcessCCSID = "";  | 
|             String CCSID = "";  | 
|             Object.CCSRecord _Record = null;  | 
|   | 
|             foreach (String[] Obj in WaitingCases)  | 
|             {  | 
|                 String _CCSID = Obj[0];  | 
|                 String _FDRID = Obj[1];  | 
|   | 
|                 if (ProcessFDR.ContainsKey(_FDRID)) //該條饋線仍有案件在處理中  | 
|                     ProcessCCSID = ProcessCCSID + "'" + _CCSID + "',";  | 
|                 else  | 
|                 {  | 
|                     CCSID = _CCSID;  | 
|                     WaitingCases.Remove(Obj);  | 
|                     break;  | 
|                 }  | 
|             }  | 
|   | 
|             if (CCSID.Length == 0)  //沒有因同饋線而在等候中的案件  | 
|             {  | 
|                 String SqlStmt = "SELECT Q.CCSID AS CCSID FROM CCS.EVENTQUERY Q,CCS.EVENTRECORD R WHERE Q.CASESTATUS IN (" + LocalVariable.EventInitial + "," + LocalVariable.EventProcess + ")";  | 
|                 System.Collections.IEnumerator Enum = ProcessCases.GetEnumerator();  | 
|   | 
|                 while (Enum.MoveNext())  | 
|                     ProcessCCSID = ProcessCCSID + "'" + Enum.Current.ToString() + "',";  | 
|   | 
|                 if (ProcessCCSID.Length != 0)  | 
|                     SqlStmt = SqlStmt + " AND Q.CCSID NOT IN (" + ProcessCCSID.Substring(0, ProcessCCSID.Length - 1) + ")";  | 
|   | 
|                 SqlStmt = SqlStmt + " AND Q.CCSID = R.CCSID AND ROWNUM < 2 ORDER BY Q.ChangeTime";  | 
|                 System.Data.OracleClient.OracleCommand Command = new System.Data.OracleClient.OracleCommand(SqlStmt, MainConn);  | 
|                 System.Data.OracleClient.OracleDataReader reader = Command.ExecuteReader();  | 
|   | 
|                 try  | 
|                 {  | 
|                     if (reader.Read())  | 
|                         CCSID = reader["CCSID"].ToString();  | 
|                 }  | 
|                 catch (Exception e)  | 
|                 {  | 
|                     Log(e.Message);  | 
|                     _MainLog.Error("無法取得等候處理CCS案件資料。錯誤訊息 = " + e.Message);  | 
|   | 
|                     if (LocalVariable.ShowError)  | 
|                         _MainLog.Error(e.StackTrace);  | 
|                 }  | 
|                 finally  | 
|                 {  | 
|                     reader.Close();  | 
|                     Command.Dispose();  | 
|                 }  | 
|             }  | 
|   | 
|             if (CCSID.Length != 0)  | 
|                 _Record = new Object.CCSRecord(CCSID, MainConn, _MainLog);  | 
|   | 
|             if (_Record != null)  | 
|             {  | 
|                 CCS.Object.EventQuery EventQuery = new CCSTrace.CCS.Object.EventQuery();  | 
|                 //先將EVETNQUERY的案件狀態改為開始處理  | 
|                 EventQuery.setCCSID(_Record.getCCSID());  | 
|                 EventQuery.setCaseStatus(LocalVariable.EventProcess);  | 
|   | 
|                 System.Data.OracleClient.OracleTransaction _Transaction = MainConn.BeginTransaction();  | 
|   | 
|                 try  | 
|                 {  | 
|   | 
|                     if (EventQuery.UpdateCaseStatus(_MainLog, MainConn, _Transaction))  | 
|                     {  | 
|                         _MainLog.Info("更新EVENTQUERY的案件狀態為處理中.(CCSID = " + _Record.getCCSID() + ")");  | 
|                         _Transaction.Commit();  | 
|                         ProcessCases.Add(_Record.getCCSID());  | 
|                     }  | 
|                     else  | 
|                     {  | 
|                         _MainLog.Error("無法更新EVENTQUERY的案件狀態.(CCSID = " + _Record.getCCSID() + ")");  | 
|   | 
|                         if (_Transaction.Connection.State.ToString().Equals("Open"))  | 
|                             _Transaction.Rollback();  | 
|                     }  | 
|                 }  | 
|                 catch (Exception e)  | 
|                 {  | 
|                     if (_Transaction.Connection.State.ToString().Equals("Open"))  | 
|                         _Transaction.Rollback();  | 
|   | 
|                     Log(e.Message);  | 
|                     _Record = null;  | 
|                 }  | 
|             }  | 
|   | 
|             return _Record;  | 
|         }  | 
|   | 
|         private void Log(String message)  | 
|         {  | 
|             RecordLog _PLog = null;  | 
|             try  | 
|             {  | 
|                 _PLog = new RecordLog(CCS.LocalVariable.CCS_ListPath + "MAIN.txt");  | 
|                 _PLog.Error(message);  | 
|             }  | 
|             finally  | 
|             {  | 
|                 if (_PLog != null)  | 
|                 {  | 
|                     _PLog.Close();  | 
|                 }  | 
|             }  | 
|         }  | 
|   | 
|     }  | 
| }  |