Modified loggers to use their enclosing class
[pithos-ms-client] / trunk / Pithos.Client.WPF / App.xaml.cs
1 #region
2 /* -----------------------------------------------------------------------
3  * <copyright file="App.xaml.cs" company="GRNet">
4  * 
5  * Copyright 2011-2012 GRNET S.A. All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or
8  * without modification, are permitted provided that the following
9  * conditions are met:
10  *
11  *   1. Redistributions of source code must retain the above
12  *      copyright notice, this list of conditions and the following
13  *      disclaimer.
14  *
15  *   2. Redistributions in binary form must reproduce the above
16  *      copyright notice, this list of conditions and the following
17  *      disclaimer in the documentation and/or other materials
18  *      provided with the distribution.
19  *
20  *
21  * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
22  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
25  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
28  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *
34  * The views and conclusions contained in the software and
35  * documentation are those of the authors and should not be
36  * interpreted as representing official policies, either expressed
37  * or implied, of GRNET S.A.
38  * </copyright>
39  * -----------------------------------------------------------------------
40  */
41 #endregion
42 using System;
43 using System.Collections.Generic;
44 using System.IO;
45 using System.Linq;
46 using System.Reflection;
47 using System.Text;
48 using System.Threading;
49 using System.Threading.Tasks;
50 using System.Windows;
51 using Caliburn.Micro;
52 using Pithos.Client.WPF.Properties;
53 using log4net.Appender;
54 using log4net.Repository.Hierarchy;
55
56
57 namespace Pithos.Client.WPF
58 {
59     /// <summary>
60     /// Interaction logic for App.xaml
61     /// </summary>
62     public partial class App : Application
63     {
64         private static readonly log4net.ILog Log = log4net.LogManager.GetLogger( MethodBase.GetCurrentMethod().DeclaringType );
65
66         public App()
67         {
68             InitializeLogging();
69
70
71             DispatcherUnhandledException += OnDispatcherUnhandledException;
72             AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
73             TaskScheduler.UnobservedTaskException += OnUnobservedException;
74
75             //Fix incorrect proxy settings by switching to default proxy, if the proxy server settings is empty
76             if (Settings.Default.UseManualProxy && String.IsNullOrWhiteSpace(Settings.Default.ProxyServer))
77             {
78                 Settings.Default.UseManualProxy = false;
79                 Settings.Default.UseDefaultProxy = true;
80             }
81
82             InitializeComponent();            
83         }
84
85         private static void InitializeLogging()
86         {
87             log4net.Config.XmlConfigurator.Configure();
88
89             try
90             {
91                 var appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
92                 var pithosDataPath= Path.Combine(appDataPath , "GRNET");
93                 if (!Directory.Exists(pithosDataPath))
94                     Directory.CreateDirectory(pithosDataPath);
95
96                 var loggerRepository = (Hierarchy)log4net.LogManager.GetRepository();
97                 
98                 var appenders = loggerRepository.GetAppenders();
99                 var lossyAppender = appenders.OfType<BufferingForwardingAppender>()
100                     .First(appender => appender.Name == "LossyFileAppender");
101                 var dumpAppender = lossyAppender.Appenders.OfType<RollingFileAppender>().First();                
102                 dumpAppender.File = Path.Combine(pithosDataPath, "errorlog.txt");
103                 dumpAppender.ActivateOptions();
104             }
105             catch (Exception exc)
106             {
107                 Log.Error("Dumpl appender initialization failed",exc);                
108             }
109         }
110
111         protected override void OnStartup(StartupEventArgs e)
112         {
113             if (!Settings.Default.StartOnSystemStartup && e.Args.Contains("startup"))
114             {
115                 Shutdown();
116                 return;
117             }
118
119             //Delay during startup
120             if (e.Args.Contains("startup"))
121             {
122                 if (Settings.Default.StartupDelay>TimeSpan.Zero)
123                     Thread.Sleep(Settings.Default.StartupDelay);
124             }
125
126             var splashScreen = new SplashScreen("images/logo.png");
127             splashScreen.Show(true);
128             
129             base.OnStartup(e);
130         }
131
132         private void OnUnobservedException(object sender, UnobservedTaskExceptionEventArgs e)
133         {            
134             var messages=new List<UserMessage>();
135             e.Exception.Handle(exc=>{
136                 messages.Add(new UserMessage
137                 {
138                     Message = "Unexpected Exception",
139                     Details = exc.ToString(),
140                     Severity = Severity.Error
141                 });
142                 return true;
143             });
144
145             Log.Error("Unobserved Task Exception",e.Exception);
146             
147             var message = String.Format(@"{0}\r\n{1}\r\n\r\n{2}", 
148                 WPF.Properties.Resources.Unexpected_Error,
149                 WPF.Properties.Resources.We_Apologize, 
150                 WPF.Properties.Resources.Please_Submit_Error);
151             ShowMessages("Oops!",message, messages);
152             e.SetObserved();
153         }
154
155         private void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
156         {
157             Log.Error("Unhandled exception", (Exception)e.ExceptionObject);
158
159             var description = e.IsTerminating
160                               ? WPF.Properties.Resources.Unexpected_Error_Terminating
161                               : WPF.Properties.Resources.Unexpected_Error;
162             var message = String.Format(@"{0}\r\n{1}\r\n\r\n{2}",
163                 description,
164                 WPF.Properties.Resources.We_Apologize,
165                 WPF.Properties.Resources.Please_Submit_Error);
166
167
168             var exc = ((Exception) e.ExceptionObject);
169             var messages = new[]{
170                                    new UserMessage
171                                        {
172                                            Message = exc.Message,
173                                            Details = exc.ToString(),
174                                            Severity = Severity.Error
175                                        }
176                                };
177
178
179             ShowMessages("Oops!", message,messages);
180         }
181
182         void OnDispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
183         {
184             Log.Error("Unhandled Dispatcher exception", e.Exception);
185             
186             var messages = new[]{
187                                    new UserMessage
188                                        {
189                                            Message = e.Exception.Message, 
190                                            Details = e.Exception.ToString(),
191                                            Severity = Severity.Error
192                                        }
193                                };
194             ShowMessages(WPF.Properties.Resources.Error_Title, 
195                 WPF.Properties.Resources.Unexpected_Error,
196                 messages);
197             e.Handled=true;
198         }
199
200         void ShowMessages(string title,string message,IEnumerable<UserMessage> messages )
201         {
202             var messageList = messages.ToList();
203             LogMessages(messageList);
204             Execute.OnUIThread(()=>{
205                                        var messageView = new MessageView(messageList)
206                                                         {
207                                                             Title = title, 
208                                                             Message = message
209                                                         };
210                                        messageView.ShowDialog();
211             });
212         }
213
214         private void LogMessages(IEnumerable<UserMessage> messages)
215         {
216             var logMessage = CreateMessage(messages);
217
218             Log.Error(logMessage);
219         }
220
221         private static string CreateMessage(IEnumerable<UserMessage> messages)
222         {
223             var messageBuilder = messages.Aggregate(new StringBuilder("Unexpected Error\r\n"),
224                                                     (builder, message) =>
225                                                         {
226                                                             builder.AppendFormat("\r\n[{0}] {1}\r\n{2}\r\n", message.Severity,
227                                                                                  message.Message, message.Details);
228                                                             return builder;
229                                                         });
230             var logMessage = messageBuilder.ToString();
231             return logMessage;
232         }
233     }
234
235 }