private async Task <bool> SyncedCloseAsync(IProject project)
        {
            Argument.IsNotNull(() => project);

            Log.Debug("Closing project '{0}'", project);

            _projectStateSetter.SetProjectClosing(project.Location, true);

            var cancelEventArgs = new ProjectCancelEventArgs(project);
            await ProjectClosingAsync.SafeInvokeAsync(this, cancelEventArgs, false).ConfigureAwait(false);

            if (cancelEventArgs.Cancel)
            {
                _projectStateSetter.SetProjectClosing(project.Location, false);

                Log.Debug("Canceled closing project '{0}'", project);
                await ProjectClosingCanceledAsync.SafeInvokeAsync(this, new ProjectEventArgs(project)).ConfigureAwait(false);

                return(false);
            }

            if (Equals(ActiveProject, project))
            {
                await SetActiveProjectAsync(null).ConfigureAwait(false);
            }

            UnregisterProject(project);

            _projectStateSetter.SetProjectClosing(project.Location, false);
            await ProjectClosedAsync.SafeInvokeAsync(this, new ProjectEventArgs(project)).ConfigureAwait(false);

            Log.Info("Closed project '{0}'", project);

            return(true);
        }
Beispiel #2
0
        private Task OnProjectManagerSavingAsync(object sender, ProjectCancelEventArgs e)
        {
            IsSuspended = true;

            return(TaskHelper.Completed);
        }
 protected virtual Task OnRefreshingAsync(ProjectCancelEventArgs e)
 {
     return TaskHelper.Completed;
 }
        protected virtual Task OnRefreshingInternalAsync(ProjectCancelEventArgs e)
        {
            IsRefreshing = true;

            return OnRefreshingAsync(e);
        }
        private Task OnClosingInternalAsync(ProjectCancelEventArgs e)
        {
            IsClosing = true;

            return OnClosingAsync(e);
        }
Beispiel #6
0
 protected virtual Task OnRefreshingAsync(ProjectCancelEventArgs e)
 {
     return(TaskHelper.Completed);
 }
Beispiel #7
0
        protected virtual Task OnRefreshingInternalAsync(ProjectCancelEventArgs e)
        {
            IsRefreshing = true;

            return(OnRefreshingAsync(e));
        }
Beispiel #8
0
        private Task OnClosingInternalAsync(ProjectCancelEventArgs e)
        {
            IsClosing = true;

            return(OnClosingAsync(e));
        }
        private Task OnLoadingAsync(ProjectCancelEventArgs e)
        {
            UpdateState(e.Location, state => state.IsLoading = true);

            return TaskHelper.Completed;
        }
        protected virtual Task OnRefreshingAsync(ProjectCancelEventArgs e)
        {
            if (e.Location.EqualsIgnoreCase(_lastActiveProject))
            {
                IsRefreshingActiveProject = true;
            }

            UpdateState(e.Location, state => state.IsRefreshing = true);

            return TaskHelper.Completed;
        }
        private Task OnSavingAsync(ProjectCancelEventArgs e)
        {
            // TODO: Support SaveAs where we store the new location, but we need to make sure that we also remove 
            // the old one (and revert on failure & cancel). For now this is sufficient (we will just get a new instance)
            UpdateState(e.Location, state => state.IsSaving = true);

            return TaskHelper.Completed;
        }
        private async Task <bool> SyncedSaveAsync(IProject project, string location)
        {
            Argument.IsNotNull(() => project);

            if (string.IsNullOrWhiteSpace(location))
            {
                location = project.Location;
            }

            using (new DisposableToken(null, token => _savingProjects.Add(location), token => _savingProjects.Remove(location)))
            {
                Log.Debug("Saving project '{0}' to '{1}'", project, location);

                // TODO: Support SaveAs where we store the new location, but we need to make sure that we also remove
                // the old one (and revert on failure & cancel). For now this is sufficient (we will just get a new instance)
                _projectStateSetter.SetProjectSaving(location, true);

                var cancelEventArgs = new ProjectCancelEventArgs(project);
                await ProjectSavingAsync.SafeInvokeAsync(this, cancelEventArgs, false).ConfigureAwait(false);

                if (cancelEventArgs.Cancel)
                {
                    _projectStateSetter.SetProjectSaving(location, false);

                    Log.Debug("Canceled saving of project to '{0}'", location);
                    await ProjectSavingCanceledAsync.SafeInvokeAsync(this, new ProjectEventArgs(project)).ConfigureAwait(false);

                    return(false);
                }

                Exception error   = null;
                var       success = true;
                try
                {
                    success = await WriteProjectAsync(project, location);
                }
                catch (Exception ex)
                {
                    error = ex;
                }

                if (error != null)
                {
                    _projectStateSetter.SetProjectSaving(location, false);

                    Log.Error(error, "Failed to save project '{0}' to '{1}'", project, location);
                    await ProjectSavingFailedAsync.SafeInvokeAsync(this, new ProjectErrorEventArgs(project, error)).ConfigureAwait(false);

                    return(false);
                }

                if (!success)
                {
                    Log.Error("Not saved project '{0}' to '{1}'", project, location);
                    return(false);
                }

                _projectStateSetter.SetProjectSaving(location, false);

                await ProjectSavedAsync.SafeInvokeAsync(this, new ProjectEventArgs(project)).ConfigureAwait(false);

                var projectString = project.ToString();
                Log.Info("Saved project '{0}' to '{1}'", projectString, location);
            }

            return(true);
        }
        private async Task <IProject> SyncedLoadProjectAsync(string location)
        {
            Argument.IsNotNullOrWhitespace("location", location);

            var project = Projects.FirstOrDefault(x => location.EqualsIgnoreCase(x.Location));

            if (project != null)
            {
                return(project);
            }

            var projectLocation = location;

            using (new DisposableToken(null, token => _loadingProjects.Add(projectLocation), token => _loadingProjects.Remove(projectLocation)))
            {
                Log.Debug($"Going to load project from '{location}', checking if an upgrade is required");

                if (await _projectUpgrader.RequiresUpgradeAsync(location))
                {
                    Log.Debug($"Upgrade is required for '{location}', upgrading...");

                    location = await _projectUpgrader.UpgradeAsync(location);

                    Log.Debug($"Upgraded project, final location is '{location}'");
                }

                Log.Debug($"Loading project from '{location}'");

                _projectStateSetter.SetProjectLoading(location, true);

                var cancelEventArgs = new ProjectCancelEventArgs(location);

                await ProjectLoadingAsync.SafeInvokeAsync(this, cancelEventArgs, false).ConfigureAwait(false);

                if (cancelEventArgs.Cancel)
                {
                    Log.Debug("Canceled loading of project from '{0}'", location);

                    _projectStateSetter.SetProjectLoading(location, false);

                    await ProjectLoadingCanceledAsync.SafeInvokeAsync(this, new ProjectEventArgs(location)).ConfigureAwait(false);

                    return(null);
                }

                Exception error = null;

                IValidationContext validationContext = null;

                try
                {
                    if (_projects.Count > 0 && ProjectManagementType == ProjectManagementType.SingleDocument)
                    {
                        throw Log.ErrorAndCreateException <SdiProjectManagementException>("Cannot load project '{0}', currently in SDI mode", location);
                    }

                    if (!await _projectValidator.CanStartLoadingProjectAsync(location))
                    {
                        validationContext = new ValidationContext();
                        validationContext.Add(BusinessRuleValidationResult.CreateError("Project validator informed that project could not be loaded"));

                        throw new ProjectException(location, $"Cannot load project from '{location}'");
                    }

                    validationContext = await _projectValidator.ValidateProjectBeforeLoadingAsync(location);

                    if (validationContext.HasErrors)
                    {
                        throw Log.ErrorAndCreateException <InvalidOperationException>($"Project could not be loaded from '{location}', validator returned errors");
                    }

                    project = await QuietlyLoadProjectAsync(location, true).ConfigureAwait(false);

                    validationContext = await _projectValidator.ValidateProjectAsync(project);

                    if (validationContext.HasErrors)
                    {
                        throw Log.ErrorAndCreateException <InvalidOperationException>($"Project data was loaded from '{location}', but the validator returned errors");
                    }

                    RegisterProject(project);
                }
                catch (Exception ex)
                {
                    error = ex;
                    Log.Error(ex, "Failed to load project from '{0}'", location);
                }

                if (error != null)
                {
                    _projectStateSetter.SetProjectLoading(location, false);

                    await ProjectLoadingFailedAsync.SafeInvokeAsync(this, new ProjectErrorEventArgs(location, error, validationContext)).ConfigureAwait(false);

                    return(null);
                }

                _projectStateSetter.SetProjectLoading(project?.Location, false);

                await ProjectLoadedAsync.SafeInvokeAsync(this, new ProjectEventArgs(project)).ConfigureAwait(false);

                Log.Info("Loaded project from '{0}'", location);
            }

            return(project);
        }
        private async Task <bool> SyncedRefreshAsync(IProject project)
        {
            var projectLocation = project.Location;

            var activeProjectLocation = this.GetActiveProjectLocation();

            Log.Debug("Refreshing project from '{0}'", projectLocation);

            var isRefreshingActiveProject = activeProjectLocation.EndsWithIgnoreCase(projectLocation);

            _projectStateSetter.SetProjectRefreshing(projectLocation, true, isRefreshingActiveProject);

            var cancelEventArgs = new ProjectCancelEventArgs(project);
            await ProjectRefreshingAsync.SafeInvokeAsync(this, cancelEventArgs, false).ConfigureAwait(false);

            Exception          error             = null;
            IValidationContext validationContext = null;

            try
            {
                if (cancelEventArgs.Cancel)
                {
                    _projectStateSetter.SetProjectRefreshing(projectLocation, false, true);

                    await ProjectRefreshingCanceledAsync.SafeInvokeAsync(this, new ProjectErrorEventArgs(project)).ConfigureAwait(false);

                    return(false);
                }

                UnregisterProject(project);

                if (isRefreshingActiveProject)
                {
                    await SetActiveProjectAsync(null).ConfigureAwait(false);
                }

                validationContext = await _projectValidator.ValidateProjectBeforeLoadingAsync(projectLocation);

                if (validationContext.HasErrors)
                {
                    throw Log.ErrorAndCreateException <InvalidOperationException>($"Project could not be loaded from '{projectLocation}', the validator returned errors");
                }

                var loadedProject = await QuietlyLoadProjectAsync(projectLocation, false).ConfigureAwait(false);

                validationContext = await _projectValidator.ValidateProjectAsync(loadedProject);

                if (validationContext.HasErrors)
                {
                    throw Log.ErrorAndCreateException <InvalidOperationException>($"Project data was loaded from '{projectLocation}', but the validator returned errors");
                }

                RegisterProject(loadedProject);

                // Note: we disable IsRefreshingActiveProject at Activated event, that is why isActiveProject == false
                _projectStateSetter.SetProjectRefreshing(projectLocation, true, false);

                await ProjectRefreshedAsync.SafeInvokeAsync(this, new ProjectEventArgs(loadedProject)).ConfigureAwait(false);

                if (isRefreshingActiveProject)
                {
                    await SetActiveProjectAsync(loadedProject).ConfigureAwait(false);
                }

                Log.Info("Refreshed project from '{0}'", projectLocation);
            }
            catch (Exception exception)
            {
                error = exception;
            }

            if (error == null)
            {
                return(true);
            }

            _projectStateSetter.SetProjectRefreshing(projectLocation, false, true);

            var eventArgs = new ProjectErrorEventArgs(project,
                                                      new ProjectException(project, $"Failed to load project from location '{projectLocation}' while refreshing.", error),
                                                      validationContext);

            await ProjectRefreshingFailedAsync.SafeInvokeAsync(this, eventArgs).ConfigureAwait(false);

            return(false);
        }