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