All containers and first level folders are automatically added to Selective Sync...
[pithos-ms-client] / trunk / Pithos.Client.WPF / App.xaml.cs
index 96e82b8..b399db6 100644 (file)
@@ -1,19 +1,62 @@
-using System;
+#region
+/* -----------------------------------------------------------------------
+ * <copyright file="App.xaml.cs" company="GRNet">
+ * 
+ * Copyright 2011-2012 GRNET S.A. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above
+ *      copyright notice, this list of conditions and the following
+ *      disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above
+ *      copyright notice, this list of conditions and the following
+ *      disclaimer in the documentation and/or other materials
+ *      provided with the distribution.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and
+ * documentation are those of the authors and should not be
+ * interpreted as representing official policies, either expressed
+ * or implied, of GRNET S.A.
+ * </copyright>
+ * -----------------------------------------------------------------------
+ */
+#endregion
+using System;
 using System.Collections.Generic;
-using System.Configuration;
-using System.Data;
-using System.Diagnostics;
+using System.IO;
 using System.Linq;
 using System.Net;
-using System.Net.Mail;
 using System.Reflection;
 using System.Text;
+using System.Threading;
 using System.Threading.Tasks;
 using System.Windows;
 using Caliburn.Micro;
-using Microsoft.Win32;
-using Caliburn.Micro.Logging;
+using Pithos.Client.WPF.Configuration;
 using Pithos.Client.WPF.Properties;
+using Pithos.Interfaces;
+using log4net.Appender;
+using log4net.Core;
+using log4net.Repository.Hierarchy;
+using System.Runtime.InteropServices;
 
 
 namespace Pithos.Client.WPF
@@ -23,16 +66,27 @@ namespace Pithos.Client.WPF
     /// </summary>
     public partial class App : Application
     {
-        private readonly log4net.ILog _log = log4net.LogManager.GetLogger(typeof (App));
-
+        private static readonly log4net.ILog Log = log4net.LogManager.GetLogger( MethodBase.GetCurrentMethod().DeclaringType );
+        
+            ///DLL Import to add restart manager support
+            [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
+            static extern uint RegisterApplicationRestart(string pwzCommandLine, RestartFlags dwFlags);
+               
         public App()
         {
-            log4net.Config.XmlConfigurator.Configure();            
-            
-            this.DispatcherUnhandledException += OnUnhandledException;
+
+            //var instanceMutex=new Mutex()
+            InitializeLogging();
+
+            ///Register Application in the Restartmanager service
+            RegisterApplicationRestart("Upgrade", RestartFlags.NONE);
+
+
+            DispatcherUnhandledException += OnDispatcherUnhandledException;
             AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
             TaskScheduler.UnobservedTaskException += OnUnobservedException;
 
+
             //Fix incorrect proxy settings by switching to default proxy, if the proxy server settings is empty
             if (Settings.Default.UseManualProxy && String.IsNullOrWhiteSpace(Settings.Default.ProxyServer))
             {
@@ -40,26 +94,111 @@ namespace Pithos.Client.WPF
                 Settings.Default.UseDefaultProxy = true;
             }
 
+            if (Settings.Default.IgnoreCertificateErrors)
+                ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true;
+
+
             InitializeComponent();            
+        }       
+
+
+/*
+        private void OnUpdateDetected(object sender, UpdateDetectedEventArgs e)
+        {
+            Log.InfoFormat("Update Detected {0}",e.LatestVersion.Version);    
+        }
+*/
+
+        private static void InitializeLogging()
+        {
+            log4net.Config.XmlConfigurator.Configure();
+
+            try
+            {
+                var pithosDataPath = PithosSettings.PithosDataPath;
+                if (!Directory.Exists(pithosDataPath))
+                    Directory.CreateDirectory(pithosDataPath);
+
+                var loggerRepository = (Hierarchy)log4net.LogManager.GetRepository();
+
+                var appenders = loggerRepository.GetAppenders();
+                
+
+                var lossyAppender = appenders.OfType<BufferingForwardingAppender>()
+                    .FirstOrDefault(appender => appender.Name == "LossyFileAppender");
+                if (lossyAppender!=null)
+                {
+                    var dumpAppender = lossyAppender.Appenders.OfType<RollingFileAppender>().First();
+                    dumpAppender.File = Path.Combine(pithosDataPath, "errorlog.xml");
+                    dumpAppender.ActivateOptions();
+                }
+                
+                var debugAppender =appenders.OfType<RollingFileAppender>()
+                    .FirstOrDefault(a => a.Name == "DebugFileAppender");
+                if (debugAppender != null)
+                {
+                    debugAppender.File = Path.Combine(pithosDataPath, "debuglog.xml");
+                    if (!Settings.Default.DebugLoggingEnabled)
+                        debugAppender.Threshold = Level.Off;
+                    debugAppender.ActivateOptions();
+                }
+            }
+            catch (Exception exc)
+            {
+                Log.Error("Dumpl appender initialization failed",exc);                
+            }
         }
 
+        private Mutex _singleInstanceMutex;
+
         protected override void OnStartup(StartupEventArgs e)
         {
             if (!Settings.Default.StartOnSystemStartup && e.Args.Contains("startup"))
             {
-                this.Shutdown();
+                Shutdown();
                 return;
             }
-            
-            var splashScreen = new SplashScreen("images/logo.png");
+
+            bool firstInstance;
+            _singleInstanceMutex = new Mutex(false, "PITHOSMUTEX", out firstInstance);
+            if (!firstInstance)
+            {
+                _singleInstanceMutex.Dispose();
+                _singleInstanceMutex = null;
+                Shutdown();
+                return;
+            }
+
+            //Delay during startup
+            if (e.Args.Contains("startup"))
+            {
+                if (Settings.Default.StartupDelay>TimeSpan.Zero)
+                    Thread.Sleep(Settings.Default.StartupDelay);
+            }
+
+            var splashScreen = new SplashScreen("images/pithos_logo-title-margin-splash-600-whitebg.png");
             splashScreen.Show(true);
             
             base.OnStartup(e);
         }
 
+        protected override void OnExit(ExitEventArgs e)
+        {
+            try
+            {
+                if (_singleInstanceMutex!=null)
+                    _singleInstanceMutex.Dispose();
+                _singleInstanceMutex = null;
+            }
+            catch { }
+            base.OnExit(e);
+        }
+
         private void OnUnobservedException(object sender, UnobservedTaskExceptionEventArgs e)
-        {            
-            var messages=new List<UserMessage>();
+        {
+            Log.Error("Unobserved Task Exception", e.Exception); 
+            
+            var messages = new List<UserMessage>();
             e.Exception.Handle(exc=>{
                 messages.Add(new UserMessage
                 {
@@ -70,31 +209,88 @@ namespace Pithos.Client.WPF
                 return true;
             });
 
-            ShowMessages("Oops!","Where did that come from? \r\nErm, an exception occured.\r\nWe apologize for the inconvenience", messages);
-            e.SetObserved();
+
+            //Do not display any messages if this is a 304 code
+            var ignoreExceptions = from exc in e.Exception.InnerExceptions.OfType<WebException>()
+                                   where IsAllowedException(exc)
+                                   select exc;
+
+            if (ignoreExceptions.Any())
+            {
+                e.SetObserved();
+                return;
+            }
+
+
+           /* var message = String.Format(@"{0}" + Environment.NewLine + "{1}" + Environment.NewLine + "{2}", 
+                WPF.Properties.Resources.Unexpected_Error,
+                WPF.Properties.Resources.We_Apologize, 
+                WPF.Properties.Resources.Please_Submit_Error);
+            ShowMessages("Oops!",message, messages);*/
+            e.SetObserved();            
+        }
+
+        private bool IsAllowedException(Exception exc)
+        {
+            var we = exc as WebException;
+            if (we==null)
+            {
+                return false;
+            }
+            var response = we.Response as HttpWebResponse;
+            return (response != null && response.StatusCode == HttpStatusCode.NotModified);
         }
 
         private void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
         {
-            var message = e.IsTerminating
-                              ? "Unexpected Exception. The application must terminate"
-                              : "Unexpected Exception";
 
+            //Do not display any messages if this is a 304 code
+            if (IsAllowedException(e.ExceptionObject as Exception))
+            {
+                return;
+            }
 
+            Log.Error("Unhandled exception", (Exception)e.ExceptionObject);
+
+            if (!e.IsTerminating)
+                //Do not display a message unless the application is terminating
+                return;
+
+            var description = e.IsTerminating
+                              ? WPF.Properties.Resources.Unexpected_Error_Terminating
+                              : WPF.Properties.Resources.Unexpected_Error;
+            var message = String.Format(@"{0}<LineBreak/>{1}<LineBreak/><LineBreak/>{2}",
+                description,
+                WPF.Properties.Resources.We_Apologize,
+                WPF.Properties.Resources.Please_Submit_Error);
+
+            var exc = ((Exception) e.ExceptionObject);
             var messages = new[]{
                                    new UserMessage
                                        {
-                                           Message = (e.ExceptionObject as Exception).Message,
-                                           Details = e.ExceptionObject.ToString(),
+                                           Message = exc.Message,
+                                           Details = exc.ToString(),
                                            Severity = Severity.Error
                                        }
                                };
+
+
             ShowMessages("Oops!", message,messages);
         }
 
-        void OnUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
-        {                        
-            var messages = new[]{
+
+
+        void OnDispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
+        {
+            //Do not display any messages if this is a 304 code
+            if (IsAllowedException(e.Exception))
+            {
+                return;
+            }
+
+            Log.Error("Unhandled Dispatcher exception", e.Exception);
+            
+           /* var messages = new[]{
                                    new UserMessage
                                        {
                                            Message = e.Exception.Message, 
@@ -102,18 +298,23 @@ namespace Pithos.Client.WPF
                                            Severity = Severity.Error
                                        }
                                };
-            ShowMessages("Oops!", "Unexcpected Exception", messages);
+            ShowMessages(WPF.Properties.Resources.Error_Title, 
+                WPF.Properties.Resources.Unexpected_Error,
+                messages);*/
             e.Handled=true;
         }
 
         void ShowMessages(string title,string message,IEnumerable<UserMessage> messages )
         {
-            LogMessages(messages);
+            var messageList = messages.ToList();
+            LogMessages(messageList);
             Execute.OnUIThread(()=>{
-                var messageView = new MessageView(messages);
-                messageView.Title = title;
-                messageView.Message = message;
-                messageView.ShowDialog();
+                                       var messageView = new MessageView(messageList)
+                                                        {
+                                                            Title = title, 
+                                                            Message = message
+                                                        };
+                                       messageView.ShowDialog();
             });
         }
 
@@ -121,7 +322,7 @@ namespace Pithos.Client.WPF
         {
             var logMessage = CreateMessage(messages);
 
-            _log.Error(logMessage);
+            Log.Error(logMessage);
         }
 
         private static string CreateMessage(IEnumerable<UserMessage> messages)
@@ -139,3 +340,15 @@ namespace Pithos.Client.WPF
     }
 
 }
+
+    enum RestartFlags
+    {
+        NONE = 0,
+        RESTART_CYCLICAL = 1,
+        RESTART_NOTIFY_SOLUTION = 2,
+        RESTART_NOTIFY_FAULT = 4,
+        RESTART_NO_CRASH = 8,
+        RESTART_NO_HANG = 16,
+        RESTART_NO_PATCH = 32,
+        RESTART_NO_REBOOT = 64
+    }
\ No newline at end of file