Fixes for v.0.7.20401
[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.Net;
47 using System.Reflection;
48 using System.Text;
49 using System.Threading;
50 using System.Threading.Tasks;
51 using System.Windows;
52 using Caliburn.Micro;
53 using Pithos.Client.WPF.Configuration;
54 using Pithos.Client.WPF.Properties;
55 using log4net.Appender;
56 using log4net.Core;
57 using log4net.Repository.Hierarchy;
58
59
60 namespace Pithos.Client.WPF
61 {
62     /// <summary>
63     /// Interaction logic for App.xaml
64     /// </summary>
65     public partial class App : Application
66     {
67         private static readonly log4net.ILog Log = log4net.LogManager.GetLogger( MethodBase.GetCurrentMethod().DeclaringType );
68         
69
70         public App()
71         {
72
73             //var instanceMutex=new Mutex()
74
75             InitializeLogging();
76
77
78             DispatcherUnhandledException += OnDispatcherUnhandledException;
79             AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
80             TaskScheduler.UnobservedTaskException += OnUnobservedException;
81
82
83             //Fix incorrect proxy settings by switching to default proxy, if the proxy server settings is empty
84             if (Settings.Default.UseManualProxy && String.IsNullOrWhiteSpace(Settings.Default.ProxyServer))
85             {
86                 Settings.Default.UseManualProxy = false;
87                 Settings.Default.UseDefaultProxy = true;
88             }
89
90             if (Settings.Default.IgnoreCertificateErrors)
91                 ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true;
92
93
94             InitializeComponent();            
95         }       
96
97
98 /*
99         private void OnUpdateDetected(object sender, UpdateDetectedEventArgs e)
100         {
101             Log.InfoFormat("Update Detected {0}",e.LatestVersion.Version);    
102         }
103 */
104
105         private static void InitializeLogging()
106         {
107             log4net.Config.XmlConfigurator.Configure();
108
109             try
110             {
111                 var pithosDataPath = PithosSettings.PithosDataPath;
112                 if (!Directory.Exists(pithosDataPath))
113                     Directory.CreateDirectory(pithosDataPath);
114
115                 var loggerRepository = (Hierarchy)log4net.LogManager.GetRepository();
116
117                 var appenders = loggerRepository.GetAppenders();
118                 
119
120                 var lossyAppender = appenders.OfType<BufferingForwardingAppender>()
121                     .FirstOrDefault(appender => appender.Name == "LossyFileAppender");
122                 if (lossyAppender!=null)
123                 {
124                     var dumpAppender = lossyAppender.Appenders.OfType<RollingFileAppender>().First();
125                     dumpAppender.File = Path.Combine(pithosDataPath, "errorlog.xml");
126                     dumpAppender.ActivateOptions();
127                 }
128                 
129                 var debugAppender =appenders.OfType<RollingFileAppender>()
130                     .FirstOrDefault(a => a.Name == "DebugFileAppender");
131                 if (debugAppender != null)
132                 {
133                     debugAppender.File = Path.Combine(pithosDataPath, "debuglog.xml");
134                     if (!Settings.Default.DebugLoggingEnabled)
135                         debugAppender.Threshold = Level.Off;
136                     debugAppender.ActivateOptions();
137                 }
138             }
139             catch (Exception exc)
140             {
141                 Log.Error("Dumpl appender initialization failed",exc);                
142             }
143         }
144
145         private Mutex _singleInstanceMutex;
146
147         protected override void OnStartup(StartupEventArgs e)
148         {
149             if (!Settings.Default.StartOnSystemStartup && e.Args.Contains("startup"))
150             {
151                 Shutdown();
152                 return;
153             }
154
155             bool firstInstance;
156             _singleInstanceMutex = new Mutex(false, "PITHOSMUTEX", out firstInstance);
157             if (!firstInstance)
158             {
159                 _singleInstanceMutex.Dispose();
160                 _singleInstanceMutex = null;
161                 Shutdown();
162                 return;
163             }
164
165             //Delay during startup
166             if (e.Args.Contains("startup"))
167             {
168                 if (Settings.Default.StartupDelay>TimeSpan.Zero)
169                     Thread.Sleep(Settings.Default.StartupDelay);
170             }
171
172             var splashScreen = new SplashScreen("images/pithos_logo-title-margin-splash-600-whitebg.png");
173             splashScreen.Show(true);
174             
175             base.OnStartup(e);
176         }
177
178         protected override void OnExit(ExitEventArgs e)
179         {
180             try
181             {
182                 if (_singleInstanceMutex!=null)
183                     _singleInstanceMutex.Dispose();
184                 _singleInstanceMutex = null;
185             }
186             catch { }
187             base.OnExit(e);
188         }
189
190         private void OnUnobservedException(object sender, UnobservedTaskExceptionEventArgs e)
191         {
192             Log.Error("Unobserved Task Exception", e.Exception); 
193             
194             var messages = new List<UserMessage>();
195             e.Exception.Handle(exc=>{
196                 messages.Add(new UserMessage
197                 {
198                     Message = "Unexpected Exception",
199                     Details = exc.ToString(),
200                     Severity = Severity.Error
201                 });
202                 return true;
203             });
204
205
206             var message = String.Format(@"{0}<LineBreak/>{1}<LineBreak/><LineBreak/>{2}", 
207                 WPF.Properties.Resources.Unexpected_Error,
208                 WPF.Properties.Resources.We_Apologize, 
209                 WPF.Properties.Resources.Please_Submit_Error);
210             ShowMessages("Oops!",message, messages);
211             e.SetObserved();            
212         }
213
214         private void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
215         {
216             Log.Error("Unhandled exception", (Exception)e.ExceptionObject);
217
218             var description = e.IsTerminating
219                               ? WPF.Properties.Resources.Unexpected_Error_Terminating
220                               : WPF.Properties.Resources.Unexpected_Error;
221             var message = String.Format(@"{0}<LineBreak/>{1}<LineBreak/><LineBreak/>{2}",
222                 description,
223                 WPF.Properties.Resources.We_Apologize,
224                 WPF.Properties.Resources.Please_Submit_Error);
225
226
227             var exc = ((Exception) e.ExceptionObject);
228             var messages = new[]{
229                                    new UserMessage
230                                        {
231                                            Message = exc.Message,
232                                            Details = exc.ToString(),
233                                            Severity = Severity.Error
234                                        }
235                                };
236
237
238             ShowMessages("Oops!", message,messages);
239         }
240
241         void OnDispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
242         {
243             Log.Error("Unhandled Dispatcher exception", e.Exception);
244             
245             var messages = new[]{
246                                    new UserMessage
247                                        {
248                                            Message = e.Exception.Message, 
249                                            Details = e.Exception.ToString(),
250                                            Severity = Severity.Error
251                                        }
252                                };
253             ShowMessages(WPF.Properties.Resources.Error_Title, 
254                 WPF.Properties.Resources.Unexpected_Error,
255                 messages);
256             e.Handled=true;
257         }
258
259         void ShowMessages(string title,string message,IEnumerable<UserMessage> messages )
260         {
261             var messageList = messages.ToList();
262             LogMessages(messageList);
263             Execute.OnUIThread(()=>{
264                                        var messageView = new MessageView(messageList)
265                                                         {
266                                                             Title = title, 
267                                                             Message = message
268                                                         };
269                                        messageView.ShowDialog();
270             });
271         }
272
273         private void LogMessages(IEnumerable<UserMessage> messages)
274         {
275             var logMessage = CreateMessage(messages);
276
277             Log.Error(logMessage);
278         }
279
280         private static string CreateMessage(IEnumerable<UserMessage> messages)
281         {
282             var messageBuilder = messages.Aggregate(new StringBuilder("Unexpected Error\r\n"),
283                                                     (builder, message) =>
284                                                         {
285                                                             builder.AppendFormat("\r\n[{0}] {1}\r\n{2}\r\n", message.Severity,
286                                                                                  message.Message, message.Details);
287                                                             return builder;
288                                                         });
289             var logMessage = messageBuilder.ToString();
290             return logMessage;
291         }
292     }
293
294 }