#region License
/**
* Ingenious MVC : An MVC framework for .NET 2.0
* Copyright (C) 2006, JDP Group
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Authors: - Kent Boogaart (kentcb@internode.on.net)
*/
#endregion
using System;
using Ingenious.Mvc;
using Ingenious.Mvc.Configuration;
using Ingenious.Mvc.Util;
namespace Ingenious.Mvc.Navigators{
/// <include file='NavigatorBase.doc.xml' path='/doc/member[@name="T:NavigatorBase"]/*'/>
[Serializable]
public abstract class NavigatorBase : INavigator
{
private readonly Id<INavigator> _id;
private readonly Task _task;
private readonly Id<IView> _startingViewId;
private readonly IViewManager _viewManager;
private Id<IView> _lastNavigateTo;
/// <include file='NavigatorBase.doc.xml' path='/doc/member[@name="P:Id"]/*'/>
public Id<INavigator> Id
{
get
{
return _id;
}
}
/// <include file='NavigatorBase.doc.xml' path='/doc/member[@name="P:Task"]/*'/>
public Task Task
{
get
{
return _task;
}
}
/// <include file='NavigatorBase.doc.xml' path='/doc/member[@name="P:StartingViewId"]/*'/>
public Id<IView> StartingViewId
{
get
{
return _startingViewId;
}
}
/// <include file='NavigatorBase.doc.xml' path='/doc/member[@name="P:LastNavigateTo"]/*'/>
public Id<IView> LastNavigateTo
{
get
{
return _lastNavigateTo;
}
}
/// <include file='NavigatorBase.doc.xml' path='/doc/member[@name="P:ViewManager"]/*'/>
protected IViewManager ViewManager
{
get
{
return _viewManager;
}
}
/// <include file='NavigatorBase.doc.xml' path='/doc/member[@name="M:.ctor(Ingenious.Mvc.Id`1,Ingenious.Mvc.Task,Ingenious.Mvc.Id`1,Ingenious.Mvc.IViewManager)"]/*'/>
protected NavigatorBase(Id<INavigator> id, Task task, Id<IView> startingViewId, IViewManager viewManager)
{
ArgumentHelper.AssertNotEmpty(id, "id");
ArgumentHelper.AssertNotNull(task, "task");
ArgumentHelper.AssertNotEmpty(startingViewId, "startingViewId");
ArgumentHelper.AssertNotNull(viewManager, "viewManager");
_id = id;
_task = task;
_startingViewId = startingViewId;
_viewManager = viewManager;
}
/// <include file='NavigatorBase.doc.xml' path='/doc/member[@name="M:Initialize()"]/*'/>
public virtual void Initialize()
{
}
/// <include file='NavigatorBase.doc.xml' path='/doc/member[@name="M:CanNavigateTo(Ingenious.Mvc.Id`1)"]/*'/>
public virtual bool CanNavigateTo(Id<IView> viewId)
{
ArgumentHelper.AssertNotEmpty(viewId, "viewId");
return AssertNavigateToValid(ref viewId, false);;
}
/// <include file='NavigatorBase.doc.xml' path='/doc/member[@name="M:NavigateTo(Ingenious.Mvc.Id`1)"]/*'/>
public virtual IView NavigateTo(Id<IView> viewId)
{
return NavigateTo(viewId, null);
}
/// <include file='NavigatorBase.doc.xml' path='/doc/member[@name="M:NavigateTo(Ingenious.Mvc.Id`1,System.Object)"]/*'/>
public virtual IView NavigateTo(Id<IView> viewId, object viewData)
{
ArgumentHelper.AssertNotEmpty(viewId, "viewId");
//ask the base class to assert the navigation attempt
Id<IView> targetViewId = viewId;
AssertNavigateToValid(ref targetViewId, true);
if (targetViewId == Id<IView>.Empty)
{
targetViewId = viewId;
}
//allow subclasses to perform additional processing
BeforeNavigateTo(targetViewId, viewData);
//if we get here, the navigation is valid so do it
return DoNavigateTo(targetViewId, viewData);
}
/// <include file='NavigatorBase.doc.xml' path='/doc/member[@name="M:BeforeNavigateTo(Ingenious.Mvc.Id`1,System.Object)"]/*'/>
protected virtual void BeforeNavigateTo(Id<IView> viewId, object viewData)
{
}
/// <include file='NavigatorBase.doc.xml' path='/doc/member[@name="M:AssertNavigateToValid(Ingenious.Mvc.Id`1&,System.Boolean)"]/*'/>
protected abstract bool AssertNavigateToValid(ref Id<IView> viewId, bool throwOnError);
private IView DoNavigateTo(Id<IView> targetViewId, object viewData)
{
ExceptionHelper.ThrowIf(Task.Manager.ConfigurationInfo == null, "DoNavigateTo.noConfiguration", new object[] {ViewManager.ActiveView, targetViewId}, Id, targetViewId);
ArgumentHelper.AssertNotEmpty(targetViewId, "targetViewId");
ViewInfo viewInfo = Task.Manager.ConfigurationInfo.ViewInfos[targetViewId];
ExceptionHelper.ThrowIf(viewInfo == null, "DoNavigateTo.viewNotFound", new object[] {ViewManager.ActiveView, targetViewId}, Id, targetViewId);
//if we get here then the navigation is legal
IController controller = Task.Manager.GetControllerForTask(Task, viewInfo.ControllerInfo, Task.Manager.ConfigurationInfo.ControllerFactory);
//remember this in case we need to roll back
Id<IView> lastNavigateToCopy = _lastNavigateTo;
IView view = null;
try
{
//store the last navigation before we activate the view because the view might display modally and block us
_lastNavigateTo = targetViewId;
//ask the view manager to activate the view
view = ViewManager.Activate(Task, targetViewId, viewData);
}
catch (Exception)
{
//revert the last navigation because it failed
_lastNavigateTo = lastNavigateToCopy;
throw;
}
//return the view that was navigated to
return view;
}
}
}
|