// ******************************************************************************
// ******************************************************************************
// ASP.NET DaST Rendering Engine
// Copyright (C) 2011 Roman Gubarenko
// Project Home: http://aspnetdast.sourceforge.net/
// ******************************************************************************
// ******************************************************************************
//
// 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
//
// ******************************************************************************
// Primary Contact: rgubarenko@gmail.com
// Learn More: http://aspnetdast.sourceforge.net/
// Project Repository: http://sourceforge.net/projects/aspnetdast/
// ******************************************************************************
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AspNetDaST.Web.Private;
namespace AspNetDaST.Web
{
public class ScopeFacade
{
private ScopeTreeModel _scopeTree;
private PathExact _renderPath;
private ScopeDataBag _scopeData;
internal ScopeFacade(ScopeTreeModel scopeTree, PathExact renderPath, ScopeDataBag scopeData)
{
_scopeTree = scopeTree;
_renderPath = renderPath;
_scopeData = scopeData;
// populate scope dast:... attributes
Attributes = new Dictionary<string, string>();
var scopeNode = scopeTree.GetNode(renderPath);
foreach (string attrName in scopeNode.TagAttributes.Keys)
{
if (!string.Equals(attrName, "dast:scope", StringComparison.OrdinalIgnoreCase) &&
attrName.StartsWith("dast:", StringComparison.OrdinalIgnoreCase))
{
Attributes[attrName] = scopeNode.TagAttributes[attrName];
}
}
// set rest of properties
InterimParams = new ParamsFacade(_scopeData.InterimParams);
Params = new ParamsFacade(_scopeData.StoredParams);
Binder = new BinderFacade(_scopeData.DataBinding);
}
#region Client Interface
public string ScopeClientID { get { return _scopeData.ScopeClientID; } }
public ScopeRenderType RenderType { get { return _scopeData.RenderType; } set { _scopeData.RenderType = value; } }
public Dictionary<string, string> Attributes { get; private set; }
public ParamsFacade InterimParams { get; private set; }
public ParamsFacade Params { get; private set; }
public BinderFacade Binder { get; private set; }
public void Refresh()
{
// make sure we're inside action handler function
if (_scopeTree.State != ScopeTreeModel.RenderState.HandlingActions)
throw new DaSTException("Operation not available in the current context");
// clear scope datas on the subtree of refreshed scope NOT including the scope itself
foreach (var path in _scopeTree.ScopeDataMap.Keys.Where(p => _renderPath.IsStrictSubpathOf(p)).ToArray())
{
_scopeTree.ScopeDataMap.Remove(path);
}
// save path to refreshed scope in special collection
if (!_scopeTree.RefreshScopePaths.Exists(path => path.IsSubpathOf(_renderPath)))
{
_scopeTree.RefreshScopePaths.RemoveAll(path => _renderPath.IsSubpathOf(path));
_scopeTree.RefreshScopePaths.Add(_renderPath);
}
// refreshing automatically resets rendering to normal (by design)
_scopeData.RenderType = ScopeRenderType.Normal;
}
public void RaiseAction(string actionName, object actionArg)
{
// make sure we're inside action handler function
if (_scopeTree.State != ScopeTreeModel.RenderState.HandlingActions)
throw new DaSTException("Operation not available in the current context");
// get current pointed node
var currNode = _scopeTree.GetNode(_renderPath);
// make sure current node is a controller root
if (!currNode.IsControllerRoot) throw new DaSTException("Cannot invoke scope action on '{0}', because this is not a controller scope", _renderPath);
// make sure parent scope exists
if (currNode.ParentNode == null) throw new DaSTException("Cannot raise actions from root controller");
// invoke action handler
_scopeTree.InvokeScopeActionHandler(
currNode.ParentNode.Controller.TreeNode,
_renderPath,
currNode.NodePath,
actionName,
actionArg);
}
public void InvokeAction(string actionName, object actionArg)
{
// make sure we're inside action handler function
if (_scopeTree.State != ScopeTreeModel.RenderState.HandlingActions)
throw new DaSTException("Operation not available in the current context");
// get current pointed node
var currNode = _scopeTree.GetNode(_renderPath);
// make sure current node is a controller root
if (!currNode.IsControllerRoot) throw new DaSTException("Cannot invoke scope action on '{0}', because this is not a controller scope", _renderPath);
// since on client action the scope tree is only partially restored to the
// target scope, manual action invokation may occur on the controller with
// unfinished model so we must check the model and build it on demand
if (currNode.Nodes.Count == 0)
{
_scopeTree.RebuildControllerModel(currNode.Controller, _renderPath);
}
// invoke action handler
_scopeTree.InvokeScopeActionHandler(
currNode,
_renderPath,
currNode.NodePath,
actionName,
actionArg);
}
#endregion
public class ParamsFacade
{
internal ScopeParams _params;
internal ParamsFacade(ScopeParams scopeParams)
{
_params = scopeParams;
}
public bool Has(string name)
{
return _params.ContainsKey(name);
}
public void Init(string name, object value)
{
if (!Has(name)) Set(name, value);
}
public void Set(string name, object value)
{
_params.Set(name, value);
}
public void Set(object obj, string propertyName, string paramName)
{
_params.Set(obj, propertyName, paramName);
}
public void Set(object obj, string[] propertyNames, string[] paramNames)
{
_params.SetRange(obj, propertyNames, paramNames);
}
public T Get<T>(string name)
{
return _params.Get<T>(name);
}
public T Get<T>(string name, T defaultValue)
{
if (Has(name)) return Get<T>(name);
else return defaultValue;
}
public void Clear()
{
_params.Clear();
}
public void Clear(string name)
{
_params.Remove(name);
}
}
public class BinderFacade
{
internal ScopeBinding _binding;
internal BinderFacade(ScopeBinding binding)
{
_binding = binding;
}
public void Repeat()
{
_binding.NewAxisBinding();
}
public void RestartRepeater()
{
_binding.ClearAxisBindings();
}
public void Replace(string placeholder, object replacement)
{
_binding.AddAxisRenderer(new HtmlContentRenderer_SingleReplacement(placeholder, replacement));
}
public void Replace(string placeholder, object obj, string propertyName)
{
_binding.AddAxisRenderer(new HtmlContentRenderer_SingleReplacement(placeholder, obj, propertyName, val => val));
}
public void Replace(string placeholder, object obj, string propertyName, Func<object, object> transformValue)
{
_binding.AddAxisRenderer(new HtmlContentRenderer_SingleReplacement(placeholder, obj, propertyName, transformValue));
}
//public void Replace(string[] paramNames, string placeholderFormat)
//{
// Replace(this, paramNames, placeholderFormat);
//}
public void Replace(ParamsFacade pf, string[] paramNames, string placeholderFormat)
{
_binding.AddAxisRenderer(new HtmlContentRenderer_ParamsReplacement(pf, paramNames, placeholderFormat));
}
public void Replace(object obj, string[] propertyNames, string placeholderFormat)
{
_binding.AddAxisRenderer(new HtmlContentRenderer_ObjectReplacement(obj, propertyNames, placeholderFormat));
}
public void ApplyAreaConditional(string area, bool flag)
{
_binding.AddAxisRenderer(new HtmlContentRenderer_ShowFragmentArea(area, flag));
}
public void ApplyAreaRepeater(string area)
{
throw new NotImplementedException();
}
}
}
}