Click here to Skip to main content
15,885,956 members
Articles / Web Development / ASP.NET

Using Silverlight in Enterprise: RAD of User Friendly Database Access

Rate me:
Please Sign up or sign in to vote.
4.81/5 (19 votes)
31 Jul 2009CPOL8 min read 58.1K   7K   81  
This article introduces FulcrumWeb RAD Framework - A Silverlight UI Engine to build user friendly database driven applications
/********************************************************************
 *  FulcrumWeb RAD Framework - Fulcrum of your business             *
 *  Copyright (c) 2002-2009 FulcrumWeb, ALL RIGHTS RESERVED         *
 *                                                                  *
 *  THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED      *
 *  FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE        *
 *  COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE       *
 *  AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT  *
 *  AND PERMISSION FROM FULCRUMWEB. CONSULT THE END USER LICENSE    *
 *  AGREEMENT FOR INFORMATION ON ADDITIONAL RESTRICTIONS.           *
 ********************************************************************/

using System.Collections.Generic;

using Framework.Db;
using Framework.Entity;
using Framework.Metadata;
using Framework.Utils;

namespace Framework.Remote
{
  /// <summary>
  /// Class incapsulating edit operations.
  /// </summary>
  public class CxEditController
  {
    private CxEntityUsageMetadata m_EntityUsage;
    //----------------------------------------------------------------------------
    public CxEditController(CxEntityUsageMetadata entityUsage)
    {
      m_EntityUsage = entityUsage;
    }

    /// <summary>
    /// Processes dependent fields of the given entity.
    /// Calculates local expressions, row source filters, read-only and visibility conditions.
    /// </summary>
    /// <param name="exprResult">CxExpressionResult to process</param>
    /// <param name="changedAttr">changed attribute</param>
    /// <param name="changedValue">changed value</param>
    virtual public void ProcessDependentFields(
      CxExpressionResult exprResult,
      CxAttributeMetadata changedAttr,
      object changedValue)
    {
      CxBaseEntity entity = exprResult.ActualEntity;
      if (entity != null && changedAttr != null)
      {
        entity[changedAttr.Id] = changedValue;
        Dictionary<CxAttributeMetadata, bool> processedMap = new Dictionary<CxAttributeMetadata, bool>();
        ProcessDependentFields(exprResult, changedAttr, processedMap);
        // ReplaceFormControls(entity);
      }
    }
    //-------------------------------------------------------------------------
    /// <summary>
    /// Processes dependent fields of the given entity.
    /// Calculates local expressions, row source filters, read-only and visibility conditions.
    /// </summary>
    /// <param name="exprResult">CxExpressionResult to process</param>
    /// <param name="changedAttr">changed attribute</param>
    /// <param name="processedMap">map of the processed attributes</param>
    protected void ProcessDependentFields(
      CxExpressionResult exprResult,
      CxAttributeMetadata changedAttr,
      Dictionary<CxAttributeMetadata, bool> processedMap)
    {
      CxBaseEntity entity = exprResult.ActualEntity;
      IList<CxAttributeMetadata> dependentAttrs = entity.Metadata.GetDependentAttributes(changedAttr);
      if (dependentAttrs != null)
      {
        foreach (CxAttributeMetadata attribute in dependentAttrs)
        {
          if (!processedMap.ContainsKey(attribute))
          {
            processedMap.Add(attribute, true);
            ProcessDependentField(exprResult, attribute, processedMap);
          }
        }
      }

      IList<CxAttributeMetadata> dependentStateAttrs = entity.Metadata.GetDependentStateAttributes(changedAttr);
      if (dependentStateAttrs != null)
      {
        foreach (CxAttributeMetadata attribute in dependentStateAttrs)
        {
          ProcessDependentFieldState(exprResult, attribute);
        }
      }
    }
    //-------------------------------------------------------------------------
    /// <summary>
    /// Processes dependent field of the given entity.
    /// Calculates local expressions, row source filters, read-only and visibility conditions.
    /// </summary>
    /// <param name="exprResult">CxExpressionResult to process</param>
    /// <param name="dependentAttr">dependent attribute</param>
    /// <param name="processedMap">map of the processed attributes</param>
    protected void ProcessDependentField(
      CxExpressionResult exprResult,
      CxAttributeMetadata dependentAttr,
      Dictionary<CxAttributeMetadata, bool> processedMap)
    {
      CxBaseEntity entity = exprResult.ActualEntity;
      object oldValue = entity[dependentAttr.Id];
      object newValue = oldValue;

      // Process local expression
      if (CxUtils.NotEmpty(dependentAttr.LocalExpression))
      {
        using (CxDbConnection connection = CxDbConnections.CreateEntityConnection())
        {
          entity.SetCalculatedValue(connection, dependentAttr, true);
        }
        newValue = entity[dependentAttr.Id];
      }

      // Process row source filter
      if (dependentAttr.RowSource != null && CxUtils.NotEmpty(dependentAttr.RowSourceFilter))
      {
        using (CxDbConnection connection = CxDbConnections.CreateEntityConnection())
        {
         
          RefreshDynamicLookup(exprResult, dependentAttr, true);
         

          string newText;
          dependentAttr.RowSource.GetDefaultValue(
            connection,
            dependentAttr.RowSourceFilter,
            entity,
            GetIsMandatory(dependentAttr, entity),
            dependentAttr.IsMultiValueLookup,
            newValue,
            out newValue,
            out newText);

        

          // If value changed, process further dependencies
          if (CxUtils.ToString(oldValue) != CxUtils.ToString(newValue))
          {
        
            entity[dependentAttr.Id] = newValue;
        
            ProcessDependentFields(exprResult, dependentAttr, processedMap);
          }
        }
      }
    }

    //-------------------------------------------------------------------------
    /// <summary>
    /// Processes dependent state of the field of the given entity.
    /// </summary>
    /// <param name="exprResult">CxExpressionResult to process</param>
    /// <param name="dependentAttr">dependent attribute</param>
    protected void ProcessDependentFieldState(
      CxExpressionResult exprResult,
      CxAttributeMetadata dependentAttr)
    {
      // Process read-only condition and visibility condition for form only.
      // For a grid view these conditions are calculated before show editor.
      //  CxBaseEntity entity = exprResult.ActualEntity;
      //  if (IsForm && m_Form != null)
      //  {
      //       if (CxUtils.NotEmpty(dependentAttr.ReadOnlyCondition) ||
      //         CxUtils.NotEmpty(dependentAttr.VisibilityCondition))
      //     {
      //    m_Form.UpdateControlState(entity.Metadata, dependentAttr);
      //   }
      // }
    }
    
    
    //-------------------------------------------------------------------------
    /// <summary>
    /// Returns true if given attribute should be mandatory in context of the given entity.
    /// </summary>
    /// <param name="attribute">attribute metadata</param>
    /// <param name="entity">entity or null if entity is not present</param>
    public static bool GetIsMandatory(CxAttributeMetadata attribute, CxBaseEntity entity)
    {
      return attribute != null ?
        (entity != null ? entity.IsMandatory(attribute.Id) : !attribute.Nullable) : false;
    }

    //----------------------------------------------------------------------------
    /// <summary>
    /// Refreshes dynamic lookup data source
    /// </summary>
    /// <param name="exprResult">CxExpressionResult to process</param>
    /// <param name="attribute">attribute metadata</param>
    /// <param name="overwrite">true to overwrite existing datasource</param>
    protected void RefreshDynamicLookup(
      CxExpressionResult exprResult,
      CxAttributeMetadata attribute,
      bool overwrite)
    {
      CxRowSourceMetadata rs = attribute.RowSource;
      IList<CxComboItem> items;
      using (CxDbConnection connection = CxDbConnections.CreateEntityConnection())
      {
        items = rs.GetList(
          null,
          connection,
          attribute.GetRowSourceFilter(exprResult.ActualEntity),
          exprResult.ActualEntity,
          !GetIsMandatory(attribute, exprResult.ActualEntity) || false);
      }

      CxClientRowSource rowSource = new CxClientRowSource(items, exprResult.ActualEntity, attribute);
      if (rowSource.IsFilteredRowSource)
      {
        exprResult.FilteredRowSources.Add(rowSource);
      }
      else
      {
        exprResult.UnfilteredRowSources.Add(rowSource.RowSourceId.ToUpper(), rowSource);
      }

    }
    //-------------------------------------------------------------------------
    /// <summary>
    ///  Gets dynamic lookup data source
    /// </summary>
    /// <param name="attribute">attribute metadata</param>
    /// <param name="entity"></param>
    /// <returns></returns>
    public CxClientRowSource GetDynamicRowSource(
      CxAttributeMetadata attribute,
      CxBaseEntity entity)
    {

      CxRowSourceMetadata rs = attribute.RowSource;
      IList<CxComboItem> items;
      CxExpressionResult exprResult = new CxExpressionResult { ActualEntity = entity };
      using (CxDbConnection connection = CxDbConnections.CreateEntityConnection())
      {
        items = rs.GetList(
          null,
          connection,
          attribute.GetRowSourceFilter(exprResult.ActualEntity),
          exprResult.ActualEntity,
          !GetIsMandatory(attribute, exprResult.ActualEntity) || false);
      }
      return new CxClientRowSource(items, exprResult.ActualEntity, attribute);
    }
    //----------------------------------------------------------------------------

    /// <summary>
    /// Returns true if control corresponding to the given attribute should be
    /// visible in context of the given entity.
    /// </summary>
    /// <param name="attribute">attribute metadata</param>
    /// <param name="entity">entity instance</param>
    virtual public bool GetIsVisible(
      CxAttributeMetadata attribute,
      CxBaseEntity entity)
    {
      bool isVisible = m_EntityUsage.GetIsAttributeEditable(attribute);
      if (isVisible)
      {
        if (entity != null && CxUtils.NotEmpty(attribute.VisibilityCondition))
        {
          using (CxDbConnection connection = CxDbConnections.CreateEntityConnection())
          {
            isVisible = entity.CalculateBoolExpression(connection, attribute.VisibilityCondition);
          }
        }
        if (isVisible)
        {
          using (CxDbConnection connection = CxDbConnections.CreateEntityConnection())
          {
            isVisible = attribute.GetIsVisible(m_EntityUsage, connection, entity);
          }
        }
      }
      return isVisible;
    }

    //----------------------------------------------------------------------------
    /// <summary>
    /// Returns true if control corresponding to the given attribute should be
    /// readonly in context of the given entity.
    /// </summary>
    /// <param name="attribute">attribute metadata</param>
    /// <param name="entity">entity instance</param>
    virtual public bool GetIsReadOnly(
      CxAttributeMetadata attribute,
      CxBaseEntity entity)
    {
      bool isReadOnly = (attribute.ReadOnly) ||
                        (m_EntityUsage.ReadOnlyAttributes);

      // Check dynamic read-only state of the column.
      if (!isReadOnly && entity != null && CxUtils.NotEmpty(attribute.ReadOnlyCondition))
      {
        using (CxDbConnection connection = CxDbConnections.CreateEntityConnection())
        {
          isReadOnly = entity.CalculateBoolExpression(connection, attribute.ReadOnlyCondition);
        }
      }
      return isReadOnly;
    }
  }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Ukraine Ukraine
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions