Converted NetSparkle project to .NET 4 Client Profile
[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
67
68         public App()
69         {
70
71             InitializeLogging();
72
73
74             DispatcherUnhandledException += OnDispatcherUnhandledException;
75             AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
76             TaskScheduler.UnobservedTaskException += OnUnobservedException;
77
78
79             //Fix incorrect proxy settings by switching to default proxy, if the proxy server settings is empty
80             if (Settings.Default.UseManualProxy && String.IsNullOrWhiteSpace(Settings.Default.ProxyServer))
81             {
82                 Settings.Default.UseManualProxy = false;
83                 Settings.Default.UseDefaultProxy = true;
84             }
85
86             InitializeComponent();            
87         }
88
89 /*
90         private void OnUpdateDetected(object sender, UpdateDetectedEventArgs e)
91         {
92             Log.InfoFormat("Update Detected {0}",e.LatestVersion.Version);    
93         }
94 */
95
96         private static void InitializeLogging()
97         {
98             log4net.Config.XmlConfigurator.Configure();
99
100             try
101             {
102                 var appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
103                 var pithosDataPath= Path.Combine(appDataPath , "GRNET");
104                 if (!Directory.Exists(pithosDataPath))
105                     Directory.CreateDirectory(pithosDataPath);
106
107                 var loggerRepository = (Hierarchy)log4net.LogManager.GetRepository();
108                 
109                 var appenders = loggerRepository.GetAppenders();
110                 var lossyAppender = appenders.OfType<BufferingForwardingAppender>()
111                     .First(appender => appender.Name == "LossyFileAppender");
112                 var dumpAppender = lossyAppender.Appenders.OfType<RollingFileAppender>().First();                
113                 dumpAppender.File = Path.Combine(pithosDataPath, "errorlog.txt");
114                 dumpAppender.ActivateOptions();
115             }
116             catch (Exception exc)
117             {
118                 Log.Error("Dumpl appender initialization failed",exc);                
119             }
120         }
121
122         protected override void OnStartup(StartupEventArgs e)
123         {
124             if (!Settings.Default.StartOnSystemStartup && e.Args.Contains("startup"))
125             {
126                 Shutdown();
127                 return;
128             }
129
130             //Delay during startup
131             if (e.Args.Contains("startup"))
132             {
133                 if (Settings.Default.StartupDelay>TimeSpan.Zero)
134                     Thread.Sleep(Settings.Default.StartupDelay);
135             }
136
137             var splashScreen = new SplashScreen("images/logo.png");
138             splashScreen.Show(true);
139             
140             base.OnStartup(e);
141         }
142
143         private void OnUnobservedException(object sender, UnobservedTaskExceptionEventArgs e)
144         {            
145             var messages=new List<UserMessage>();
146             e.Exception.Handle(exc=>{
147                 messages.Add(new UserMessage
148                 {
149                     Message = "Unexpected Exception",
150                     Details = exc.ToString(),
151                     Severity = Severity.Error
152                 });
153                 return true;
154             });
155
156             Log.Error("Unobserved Task Exception",e.Exception);
157             
158             var message = String.Format(@"{0}\r\n{1}\r\n\r\n{2}", 
159                 WPF.Properties.Resources.Unexpected_Error,
160                 WPF.Properties.Resources.We_Apologize, 
161                 WPF.Properties.Resources.Please_Submit_Error);
162             ShowMessages("Oops!",message, messages);
163             e.SetObserved();
164         }
165
166         private void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
167         {
168             Log.Error("Unhandled exception", (Exception)e.ExceptionObject);
169
170             var description = e.IsTerminating
171                               ? WPF.Properties.Resources.Unexpected_Error_Terminating
172                               : WPF.Properties.Resources.Unexpected_Error;
173             var message = String.Format(@"{0}\r\n{1}\r\n\r\n{2}",
174                 description,
175                 WPF.Properties.Resources.We_Apologize,
176                 WPF.Properties.Resources.Please_Submit_Error);
177
178
179             var exc = ((Exception) e.ExceptionObject);
180             var messages = new[]{
181                                    new UserMessage
182                                        {
183                                            Message = exc.Message,
184                                            Details = exc.ToString(),
185                                            Severity = Severity.Error
186                                        }
187                                };
188
189
190             ShowMessages("Oops!", message,messages);
191         }
192
193         void OnDispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
194         {
195             Log.Error("Unhandled Dispatcher exception", e.Exception);
196             
197             var messages = new[]{
198                                    new UserMessage
199                                        {
200                                            Message = e.Exception.Message, 
201                                            Details = e.Exception.ToString(),
202                                            Severity = Severity.Error
203                                        }
204                                };
205             ShowMessages(WPF.Properties.Resources.Error_Title, 
206                 WPF.Properties.Resources.Unexpected_Error,
207                 messages);
208             e.Handled=true;
209         }
210
211         void ShowMessages(string title,string message,IEnumerable<UserMessage> messages )
212         {
213             var messageList = messages.ToList();
214             LogMessages(messageList);
215             Execute.OnUIThread(()=>{
216                                        var messageView = new MessageView(messageList)
217                                                         {
218                                                             Title = title, 
219                                                             Message = message
220                                                         };
221                                        messageView.ShowDialog();
222             });
223         }
224
225         private void LogMessages(IEnumerable<UserMessage> messages)
226         {
227             var logMessage = CreateMessage(messages);
228
229             Log.Error(logMessage);
230         }
231
232         private static string CreateMessage(IEnumerable<UserMessage> messages)
233         {
234             var messageBuilder = messages.Aggregate(new StringBuilder("Unexpected Error\r\n"),
235                                                     (builder, message) =>
236                                                         {
237                                                             builder.AppendFormat("\r\n[{0}] {1}\r\n{2}\r\n", message.Severity,
238                                                                                  message.Message, message.Details);
239                                                             return builder;
240                                                         });
241             var logMessage = messageBuilder.ToString();
242             return logMessage;
243         }
244     }
245
246 }