Software Design Description 2
From TeamF::CGT
Abstract
This document contains the design aspects of the Corporate Governance Toolkit project. It provides both the high-level architectural design of the system as well as the detailed design description.
Introduction
Purpose
The purpose of this document is to provide an easy-to-follow design for the the Corporate Governance Toolkit (CGT). It shall provide the programmers of this system with a guide to the user interface design and its internal functionalities.
This document is also based on the requirements elicited in the Software Requirements Specification (SRS). Hence, the aim is to provide the complete design based on the final version of the SRS.
Also, this document serves as:
- A document in assisting the programmers to understand the system as a whole and to understand the three subsystems: the toolkit, the data layer and the user application;
- A basis to trace each of the requirements in the SRS to the system to verify that all requirements have been designed for and all the behaviours have been accounted for;
- A document to assist the testers to plan testing procedures, drivers, methodologies, to test the correctness and robustness of the system;
- A document for any party wishing to expand, improve or to maintain the system.
This document is assisted by the following complimentary documents:
1. Software Quality Assurance Plan (SQAP)
- The SQAP outlines the procedures the team must follow in achieving maximum quality for the final system produced. This document covers all management and risk related content;
2. Software Requirements Specifications (SRS)
- The SRS specifies all the requirements which is refered to by this document for the design;
3. Software Architecture Design Document (SADD)
- The SADD specifies the methodologies and architecture model that was chosen for the team to follow. The SADD also specifies the different technologies that will be used for the implementation of the system.
Intended Audience
The intended audience of this document includes the following teams:
- Requirements Team: for checking the requirements against the current design;
- Design Team: for the design of the system;
- Coding Team: for the implementation of the system;
- Testing Team: for the blackbox testing of the system;
- Project Manager: for assisting the project planning;
- Risk Manager: for identifying risks in terms of design and implementation compliance issues;
- Supervisor: for reviewing and assessing the SDD as part of the subject 433-440 and also provide any guidance to team members.
Scope
This document incorporates the chosen architectural design method in the SADD and provides a complete overview of the system. It will also show a detailed design of the system along with its major dependencies among the 3 subsystems i.e toolkit, data layer, and user application. Detailed design down to a functional unit level is also provided.
Acronyms and Abbreviations
- SADD - Software Architectural Design Document
- SDD - Software Design Document
- TA - Toolkit Administrator
References
- Tong, Derek et al, "Team F - Software Requirements Specification, revision 3366", 2006; refer to the CSSE, University of Melbourne, Australia
Product Description
The CGT system is a toolkit allowing Risk Wizard to create a customised corporate governance application. The main aim of the system is to allow users to create a customised corporate governance applications by stepping through the toolkit.
Architectural Design
Overview
The proposed system is divided into two applications:
- The User Application
- The Toolkit, which will be used to set up the configuration of the User Application.
The Data Flow Diagram below shows how these two applications will relate to each other. In the Toolkit the TA (Toolkit Administrator) will build the configuration that will be used in the User Application. What this "configuration" refers to is:
- the structure of the database that will be used to store the buisness data
- the types of data it will be storing
- some aspects of the appearance of the User Application (including icons and labels)
- the structure of the Navigation Tree, which is a critical feature of the User Application
To view a formal description of the configuration, see the configuration class diagrams. Upon completion of building the configuration in the toolkit, all of the configuration will be stored as XML. In addition, a SQL script will be generated in order to create the database will which store the buisness data.
The database will need to be manually created onto a server by an administrator by running the SQL script. This could be done either by Risk Wizard, or by the UAA (User Application Administrator) who is an administrator for the buisness/organization that will be using the product. Once this is done the UAA will run the User Application and use it to enter initial records into the database. Once the database has been set up properly it will available for use by the UAUs (User Application Users) who will be the employees/members of the buisness/organization.
When the user application is run it will read in the configuration from the XML file, read in records from the database and provide the customized application to the end user.
To formally clarify the entire process:
- The TA sets up the configuration using the Toolkit
- Toolkit exports an XML file and an SQL script
- The database is set up on a server by running the SQL script
- The UAA runs the User Application to create initial buisness records in the database
- The UAUs (and UAA) uses the User Application (for corporate governance, risk management, or which ever purpose the system is intended to be used for).
The following diagram illustrates this process:
In addition to this the Toolkit will also provide the facility of loading an XML file back into to it to make modifications to a configuration. The current scope of this project does not include modification to an already existing database by the Toolkit, hence if an XML file is re-loaded into the Toolkit for further modification a new database will need to be created for the changed configuration.
Overall System Design
The CGT system has been design to statisfy the requirements of the SRS. The system has been design in an object orient (OO) fashion, and all aspect of the design will reflect this. A Three Tiered (layers) architecture was choosen to define the overall system. The rational behind the decision of the basic architecture of the system is given below.
Design Rationale
A number of various software architctures of desgin patters were researched before the design was made to adopt the Three Tiered Architecture. Listed below are other architecture that could have been chosen instead of Three Tiered.
Model-View-Controller
- Pros: The Model-View-Controller (MVC) archtecture provides three distinct entites. This architecture seperates the logic through the controller away from the view and the data objects (the model).
- Cons: The requirement for the toolkit to create a customisable User Application would result the model and view using the configuration stored in the controller to perform any action.
- Solution: While allowing the view to connect directly to the model, the need for a middle layer containing the configuration for system. As every method transferring information between the model and the view would require a call to the controller, the MVC architecture would effect the performance of the system due to the return of the configuration to both the model and the view.
Client Server
- Pros: The Client Server architecture is a well tested network architecture. The client renders the information provided by the server and usually performs little or no calculation. The server provides the webservices and the database functionallities required by the system.
- Cons: While Cleint Server provides a simple definition of layers, the business logic of the system will need to be included in the server layer.
- Solution: The Three Tier architecture is similiar to the client server, however, it provides a third layer to remove the logic from the frontend of the system.
Dependencies between Layers
Dependencies between Data Layer and Toolkit
The Toolkit interacts with these classes in the Data Layer:
- Configuration Library (in namespace RiskWizard.Cgt.Config)
- GlobalConfiguration
- Tree
- Table
- Attribute
- Operation
- ConfigurationReader
- ConfigurationWriter
- Database Library (in namespace RiskWizard.Cgt.Data)
- DatabaseSystemRegistry
- IDatabaseSystem
- DataType
- SqlScriptWriter
Refer to Configuration Library Module.
Dependencies between Data Layer and User Application
The User Application interacts with these classes in the Data Layer:
- Configuration Library (in namespace RiskWizard.Cgt.Config)
- GlobalConfiguration
- Tree
- Table
- Attribute
- Operation
- ConfigurationReader
- Database Library (in namespace RiskWizard.Cgt.Data)
- DatabaseSystemRegistry
- UserAppLogic
Refer to Database Library Module.
Modular Decomposition
Data Layer Decomposition
Overview of Data Layer
Data Layer is the bottom layer in our three-tier architecture. It is distinct from other layers in a sense as it serves both the Toolkit and the User Application.
The Purpose and Functions of the Data Layer: Data Layer provides all the functionalities necessary to store and retrieve data for both the Toolkit and the User Application. In particular, there are two types of data, classified on the basis of nature of their storage:
- Persistent Data
- Temporary Data
Persistent Data: The persistent data relates to the configuration that describes the structure of the User Application such as the database schema and relationship between information. They will be stored in a xml configuration file. Other persistent data relates to the business data that the User Application needs to store. This will be stored in a database.
Temporary Data: Temporary data refers to data retrieved from a file or database and stored in the memory for either the Toolkit or the User Application to manipulate. They must be in memory for faster access. The Data Layer provides the means for the Toolkit and the User Application to access and save them either in a database or in a file.
The high level functionalities of the data layer is shown below:
Data Layer is decomposed into number of inter-related entities that provide distinct functionalities to achieve a particular purpose as shown in the following figure:
Module Description
Identification: RiskWizard.Cgt.Config.GlobalConfiguration
- Type: Module
- Function: This module returns the location of the database for the User Application to store and retrieve business data. It also returns the schema of all the tables that exist in the database to the Logic in the User Application.
Identification: RiskWizard.Cgt.Config.Table
- Type: Module
- Function: This module holds and returns the name of the table, all the child tables of the given table as well as the attributes of the table.
Identification: RiskWizard.Cgt.Config.Attribute
- Type: Module
- Function: This module holds all the information needed to describe an attribute in a table. It stores and returns the following properties of an attribute.
Identification: RiskWizard.Cgt.Config.Operation
- Type: Module
- Function: It describes the mathematical operation and contains the list of attributes on which this operation needs to be performed.
Identification: RiskWizard.Cgt.Config.DataType
- Type: Module
- Function: This module provides all the permitted data types for an attribute in a table.
Identification: RiskWizard.Cgt.Config.ConfigWriter
- Type: Module
- Function: This module is responsible for saving the objects that contain the configuration of the User Application, specially GlobalConfiguration, Table and Attribute into a file by transforming into an XML DOM and then saving as a file.
Identification: RiskWizard.Cgt.Config.ConfigReader
- Type: Module
- Function: This module reads the ConfigFile and converts them into an XMLDOM and then process the XMLDOM and creates the objects, GlobalConfiguration, Table, Attribute and Operation so that both the User Application and Toolkit can use this information.
Identification: RiskWizard.Cgt.Config.XmlDOM
- Type: Data Store
- Function: This module is responsible for maintaining the information in XML format and provides a quick way of reading and writing the information stored in the XML format.
Identification: RiskWizard.Cgt.Config.XmlDOMReader
- Type: Module
- Function: This module is responsible for reading the ConfigFile and parsing information stored in XML format and storing them in XML DOM format.
Identification: RiskWizard.Cgt.Config.XmlDomWriter
- Type: Module
- Function: This module is responsible for traversing through the XML DOM and converting them into XML format and writing the information in a file, ConfigFile
Identification: RiskWizard.Cgt.Config.ConfigFile
- Type: Data Store
- Function: This data store holds all the necessary information to define the User Application. The information in ConfigFile is stored in XML format.
Identification: RiskWizard.Cgt.Config.DatabaseHandler
- Type: Module.
- Function: This module is responsible for both retrieving the data for the User Application and saving the data to the database. This module receives requests from the User Application for data and runs the appropriate queries and returns a record to the User Application. It also receives data from the User Application and writes them to the specified table in the database.
Identification: Database
- Type: Data Store
- Function: The database provides all functionalities needed to read and write information as well ensure the integrity of data and concurrency control.
Modular Dependencies
The following diagram shows the interactions between the modules of the data layer for high level functions:
Load DB Schema:
Read Data from Database:
Toolkit Decomposition
Overview of Toolkit
The Toolkit is the application which the TA (toolkit administrator) will use to set up the configuration for the User Application. The Toolkit will be a windows application in the form of a wizard, where the TA will be asked to customize various features of the User Application.
These customizable features are as follows:
- Database schema (tables, attributes)
- Tree constraints
The Toolkit Form will contain the following components
- Toolkit Form
- File Handling
- Setup Database
- Table Property Form
- Attribute Property Form
- DataType Property Form
- Linked Attribute Property Form
- Calculated Attribute Property Form
- Tree Constraints Property Form
Toolkit Form
Toolkit Form is the main WinForm the TA will be using. It contains the other classes and creates each of them based on TA’s operation.
The TA will be able to use Toolkit Form to initiate a template, open/read a template, create configuration templates and save the template.
File Handling
File Handling will be the first option displayed for TA, which includes the following feature:
- Choose a existing template from APPLICATION_FOLDER/templates/ , with file name “rttmp” (increment 2)
- Choose a blank template.
- Open an existing xml configuration file.
- Close/Exit the File Handling window
Setup Database
Setup Database component is called every time the user creates a new configuration without definition of the database type and connection string. In this component user is able to:
- Choose a Database type, once defined in the configuration, it cannot be changed.
- Enter a generated connection string
Table Property Definition
Table Property Definition is used to define the table for Global Configuration. For each table the TA will need to specify the:
- Table Name
- Table Icon (increment 2)
- Table Display Name
- Table Permission (increment 2)
Attribute Property Definition
Attributes Property Definition is used to define the attribute for each table created by Table Property Definition. For each attribute the TA will need to specify the:
- Attribute Name
- Attribute Icon (increment 2)
- Attribute Display Name
- Attribute as Display Attribute
- Attribute Type - The attribute can be either normal, linked or calculated.
- Attribute DataType – DataType Definition based on Attribute Type.
- Additional flags (increment 2) - Visibility, Logged, Reported
DataType Property Form
Once an attribute is defined as normal attribute, TA will need to specify the data type based on the database selection made earlier. The following option will be enabled for TA:
- Data type supported by the target database
- Data type parameter supported by the chosen data type.
- User modified data type string which may/may not include the data type parameter.
Linked Attribute Property Form
Once an attribute is defined as linked attribute, TA will need to specify:
- Table of destination non-linked attribute
- Destination non-linked attribute
Tree Constraints Property Form
Increment 1: The TA will devise the structure of the tree in the User Application. The tree in the User Application is a tree of all records from all tables in the database so the tree constraints simply define which tables the child nodes are allowed to come from, for any given node.
Increment 2: The TA will be able to create multiple tree constraints for the configuration. Each tree constraints will allow the User Application to add different tree views into the database
Calculated Attribute Property Form
The TA will specify the details of all the CALCULATED attributes which were defined in Attributes Property Definition. A calculated attribute of a table will not be an actual attribute within the database - rather it is operation performed on other attributes, possibly from other tables. The TA will need to define all the attributes and tree constrains before add in the Calculated Attribute, and specify the Attribute’s operation.
There are 2 types of operations the TA can choose for:
- Row Operation - This will be an operation which takes only other fields from the same record as arguments for the operation. So for example in a Risk table we might have attributes Impact and Probability. So the TA may want to define a calculated attribute for that table called Exposure, which is the record's Impact X Probability.
- Column Operation - This will be an operation over every record in a particular table on some attribute. For example in the Risk table we may want to display the average age of its affected employees. In this case we will define a column operation of the Age attribute from the Employee table.
Components decomposition diagram
Components Description
Identification: ToolkitForm
- Type: WinForm
- Purpose: The windows form for central control of the components
Identification: SetupDatabase
- Type: WinForm
- Purpose: The windows form for the database setup of the toolkit
Identification: FileHandling
- Type: WinForm
- Purpose: The windows form for creating blank configurations, open templates and saved configuration files.
Identification: TablePropertyForm
- Type: WinForm
- Purpose: The windows form for the define tables
Identification: AttributePropertyForm
- Type: WinForm
- Purpose: The windows form for the define Attribute
Identification: DataTypePropertyForm
- Type: WinForm
- Purpose: The windows form for the define Attribute
Identification: LinkedAttributePropertyForm
- Type: WinForm
- Purpose: The windows form for the editing Linked Attribute
Identification: CalculatedAttribute
- Type: WinForm
- Purpose: The windows form for the define calculated attributes
Identification: TreeConstraints
- Type: WinForm
- Purpose: The windows form for the define tree constraints
User Application
Overview
The User Application is used by Risk Wizards's clients. It is used to record, monitor and control various types of business related information (e.g. risks, workgroups and etc).
It essentially provides an organization with a centralized database that holds information from all the different divisions and the filtering ability to examine certain specific information.
Detailed Design
Data Layer Design
Configuration Library Module
Functionalities
Class Dependencies
ReadFromXmlDocument(XmlDocument document):
WriteToXmlDocument(GlobalConfiguration config):
Detailed Class Design
ConfigurationReader: Refer to online documentation for class details.
ConfiguartionWriter: Refer to online documentation for class details.
GlobalConfiguration: Refer to online documentation for class details.
Tree: Refer to online documentation for class details.
Table: Refer to online documentation for class details.
Attribute: Refer to online documentation for class details.
Operation: Refer to online documentation for class details.
Configuration File Format
The details of the configuration file are to be kept internal to the Data Layer. The Data Layer needs to provide access service to both the Toolkit and the User Application, for reading from and writing to configuration files.
Diagrams:
Schema File:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="CgtConfig">
<xs:complexType>
<xs:sequence>
<xs:element name="Connection">
<xs:complexType>
<xs:attribute name="TargetDbSystemName" type="xs:string" use="required"/>
<xs:attribute name="ConnectionString" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="Schema">
<xs:complexType>
<xs:sequence>
<xs:element name="Table" type="TableType" minOccurs="0" maxOccurs="unbounded">
<xs:key name="AttributeNameIsKey">
<xs:selector xpath="Attribute"/>
<xs:field xpath="@Id"/>
</xs:key>
</xs:element>
<xs:element name="Tree" type="TreeType" minOccurs="0" maxOccurs="unbounded">
<xs:annotation>
<xs:documentation>This defines multiple trees.</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:key name="TableNameIsKey">
<xs:selector xpath="Table"/>
<xs:field xpath="@Id"/>
</xs:key>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="TableType">
<xs:sequence>
<xs:element name="Attribute" type="AttributeType" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="Id" type="xs:string" use="required"/>
<xs:attribute name="Name" type="xs:string" use="required"/>
<xs:attribute name="DisplayName" type="xs:string" use="required"/>
<xs:attribute name="IsRoot" type="xs:boolean" use="required"/>
</xs:complexType>
<xs:complexType name="AttributeType">
<xs:sequence>
<xs:element name="Link" minOccurs="0">
<xs:annotation>
<xs:documentation>This implements the concept of linked attributes.</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:attribute name="TableId" type="xs:string" use="required"/>
<xs:attribute name="AttributeId" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="Operation" type="OperationType" minOccurs="0">
<xs:annotation>
<xs:documentation>This implements the virtual concept of derived attributes.</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
<xs:attribute name="Id" type="xs:string" use="required"/>
<xs:attribute name="Name" type="xs:string" use="required"/>
<xs:attribute name="DisplayName" type="xs:string" use="required"/>
<xs:attribute name="DataType" type="xs:string" use="required"/>
<xs:attribute name="IsUnique" type="xs:boolean" use="required"/>
<xs:attribute name="IsNullable" type="xs:boolean" use="required"/>
</xs:complexType>
<xs:complexType name="OperationType">
<xs:sequence>
<xs:element name="Method">
<xs:complexType>
<xs:attribute name="Id" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="ParamTable">
<xs:complexType>
<xs:sequence>
<xs:element name="ParamAttribute" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="Id" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="Id" type="xs:string" use="required"/>
</xs:complexType>
<xs:key name="ParamAttributeNameIsKey">
<xs:selector xpath="ParamAttribute"/>
<xs:field xpath="@Id"/>
</xs:key>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="TreeType">
<xs:sequence>
<xs:element name="Constraint" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="ParentTableId" use="required"/>
<xs:attribute name="ChildTableId" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="Id" type="xs:string" use="required"/>
<xs:attribute name="Name" type="xs:string" use="required"/>
</xs:complexType>
</xs:schema>
|
Database Library Module
Functionalities
The Database System is responsible for retrieving data from and saving data in the database. It needs to serve both the Toolkit and User Application. It needs to translate the methods calls from the Toolkit and User Application into appropriate SQL queries and perform the actions on the database.
Typically the following steps occur:
- Method calls are received from Toolkit or User Application.
- Translate them into appropriate SQL query based on the type of database system used (for example, MSSQL-Server or Oracle).
- Make a connection to the database.
- Retrieve data from the database and return information to the User Application or Toolkit or save data in the database and notify the User Application or Toolkit.
The detailed methods are shown in below:
Class Dependencies
The following diagram shows dependency between the different classes:
The following diagrams show how various classes interact together. The interactions are shown for all the detailed methods to be implemented.
GetChildNodes():
InsertChildNode():
GetSingleNode():
UpdateSingleNode():
DeleteSingleNode():
CreateTables():
GetDataTypes():
Detailed Class Design
SqlScriptWriter: Refer to online documentation for class details.
UserAppLogic: Refer to online documentation for class details.
DatabaseSystemRegistry: Refer to online documentation for class details.
DataType: Refer to online documentation for class details.
IDatabaseSystem: Refer to online documentation for class details.
MsqlDatabaseSystem:
CommandExecuter:
Detailed Documentation File
Detailed Documentation in Help file format
Toolkit Design
Toolkit System Class Diagram
ToolkitMain Class Diagram
ToolkitForm Class Diagram
ErrorCheck Class Diagram
FileProperty Class Diagram
SetupDatabase Class Diagram
TableProperty Class Diagram
AttributeProperty Class Diagram
DataTypeProperty Class Diagram
LinkedAttributeProperty Class Diagram
CalculatedAttributeProperty Class Diagram
TreeConstraintsProperty Class Diagram
Toolkit System GUI diagrams
ToolkitForm GUI Diagram
IconLibrary GUI Diagram
FileProperty GUI Diagram
SetupDatabase GUI Diagram
TableProperty GUI Diagram
AttributeProperty GUI Diagram
DataTypeProperty GUI Diagram
LinkedAttributeProperty GUI Diagram
CalculatedAttributeProperty GUI Diagram
Calculated Attribute: Column Operation
Calculated Attribute: Row Operation
TreeList GUI Diagram
TreeConstraintsProperty GUI Diagram
Toolkit System Event Flow Charts
Startup:
New Configuration Event:
Open File Event:
Save File Event:
Close Configuration Event:
Toolkit System Detailed Documentation
Detailed Documentation in Help file format
User Application Design
Login Webpage
Overview
All the account management issues involved in the End-system are handled by the login class.
Fields and Methods
- protected void Page_Load(object sender, EventArgs e)
- Description: Method for a page load.
- Input
- object sender, EventArgs e
- Output
- None
- Included in increment 1.
- protected void Login_Authenticate(object sender, AuthenticateEventArgs e)
- Description: Authenticate a user.
- Input
- object sender, AuthenticateEventArgs e
- Output
- None
- Included in increment 1.
- private bool UserAuthentication(string userName, string password)
- Description: Authenticate a user by username and password.
- Input
- string userName, string password
- Output
- bool
- Included in increment 1.
Database background
login table
A login table will be predefined in the Toolkit Application and included in the End-system database.
This table contains four attributes, namely, "username", "password", "accountType", "status".
login table attribute "accountType"
The attribute "accountType" specifies whether this is an administrator account or a normal user account.
accountType=1 => administrator account ; accountType=0 => normal user account
An administrator account will be created by default at the beginning by the Toolkit Application to manage all the account related issues. Also, the last administrator account in the database can not be deleted.
login table attribute "status"
The attribute "status" specifies whether this account is active or has been deleted.
status=1 => active ; status=0 => disabled
The reason for having this "status" attribute is, the client does not want any data to be deleted in the End-system. Hence all delete method will actually disable the targeted data instead of permanently deleting.
The reason "int" is used as the attribute type for both "accountType" and "status" instead of "bool", is to provide the room for possible future development, as there may be more account access levels as well as more account status.
Reasons for both administrator accounts and user accounts are recorded in the same database table
All usernames have to be unique. If this two types of accounts were recorded in different database table, whenever account information are required, in the most cases, two SQL queries will be required to perform the task instead of one SQL. Plus the result of this two SQL queries may also need to be concatenated. (i.e. During login process, two SQL will be required to search for the given username if the accounts are recorded separately.). By removing this extra validation, the implementation can be simplified.
User Application Configuration
Overview
During the initial(not postback) load of the UserApp the configuration created from the CGT toolkit will be read in. The location and file name of the configuration file will be stored in the web.config, so that the configuration file can be changed by just changing the value through a simple text editor. The value will be stored in the appSettings section, under a the CGTConfiguration key. The value will be a relative path to base of the website.
Properties and Methods
- ReadUserAppGlobalConfig
- Description: Reads in the configuration for the User Application. Reads the file given the web.config. Also will set the initial tree as the first tree from the configuration file.
- Input: None
- Output: None
- Included in increment 1.
UserApp Webpage
Overview
UserApp webpage contains two main parts which are the "Navigation Tree" and "Display Content".
In terms of the navigation tree, there is the basic tree and the filtered tree. The following classes form the code-behind:
- TreeBuilder class
- Builds the tree given a datarow and recursively works its way down the tree and get the datarows of the children
For the display content, the following classes form the code-behind:
- ControlCreator class
- Creates the controls for the user application
- ControlDecorator class
- Makes the controls pretty
- InputValidator class
- Validates the inputs given and gives a warning if input is incorrectly entered
User Application Page Lifecycle
Life cycle of the user application is as follows:
To view information from a node
- Postback
- Pageload (To view node, controls must be built)
- Click-handler run
- Node is selected
- Click-handler sets:
- Context.Item variables regarding needed controls
- Flag indicating that menu handler has run
- Click-handler run
- Postback
- Pageload
- Context.Item variables moved to ViewState
- Click-handler run
- Flag indicating menu handler is set therefore does nothing
To add a node
- Postback
- Pageload (To view node, controls must be built)
- Click-handler run
- Menu-handler sets :
- Context.Item variables regarding what controls is needed
- Flag indicating meny handler has run
- Menu-handler sets :
- Click-handler run
- Postback
- Pageload (Controls are built from Context.Item variables
- Context.Item variables moved to ViewState
- Click-handler run
- Flag indicating menu handler is set therefore does nothing
To save a node
- Postback
- Pageload (the add button is dynamic and has to be rebuilt including the add button)
- ViewState is set and builds controls
- Controls have unique id which is saved to ViewState
- Add button event handler is set
- Add button is run
- Values are saved
- Record added to database
- Record added to tree
- Context.Item variables set to view node
- Postback
- Pageload
- Context Item variables moved to ViewState
- Click-handler run
- Flag indicating menu handler is set therefore does nothing
To edit a node
- Postback
- Pageload (the add button is dynamic and has to be rebuilt including the edit button)
- ViewState is set and builds controls
- Controls have unique id which is saved to ViewState
- Edit button event handler is set
- Edit button is run
- Values are saved
- Record added to database
- Record added to tree
- Context.Item variables set to view node
- Postback
- Pageload
- Context Item variables moved to ViewState
- Click-handler run
- Flag indicating menu handler is set therefore does nothing
userapp.aspx.cs
When displaying the information from the database, different information will be displayed different. The information can be one of the following:
- Normal attributes
- Linked attributes
- Calculated attributes
When displaying normal attributes in the add and edit form, the UserApp.aspx.cs runs the methods createAddForm and createEditForm, the methods will run a foreach loop which goes through each normal attribute and render it as textbox. Otherwise, when viewing the content, normal attributes is rendered directly to HTML.
When displaying linked attributes, when the UserApp.aspx.cs runs the methods createAddForm and createEditForm, and finds a linked attribute it will be display a linked drop down list populated with all relevant records to choose from. When populating the drop down box, the linked value is recursively taken by getting a dataset via the parent table of the linked attribute. Then, the attribute is checked whether it is null or not. If it is not null, then the linked attribute will be added as a control. If the linked attribute is also a calculated attribute, the linked attribute will be calculated recursively first before adding it as a control. The text entry in the drop down box will display the display attribute so that it is readable.
In terms of rendering calculated attributes, the toolkit has column operations (sum, product, average, max, count, and min) and row operations (add, subtract, multiply, divide and concatenate). The user application, when running through the methods createViewForm and finds a calculated attribute (if attribute.Operation is not null), the user app will call the calculator and perform the operation on the row or the column.
If a row operation is being done, Calculator.PerformRowOperation will calculate the right value based on the attr.Operation.ParamAttributeList before displaying the attribute.
If a column operation is being done, the dataset of all the records will be received before the Calculator.PerformColumnOperation and perform it on the right column in the set before displaying the attribute.
Fields and Methods
- private static GlobalConfiguration userAppConfig
- Description: Global object for configuration
- Initialization: userAppConfig = UserAppGlobalConfiguration.Configuration
- Included in increment 1.
- private static Guid currentTreeID
- Description: Current Tree that is loaded
- Included in increment 1.
- override protected void OnInit(EventArgs e)
- Description: Raise the System.Web.UI.Control.Init event to initialize the page.
- Input:
- EventArgs e
- Output:
- None
- Included in increment 1.
- private void Initialize()
- Description: Initializes all necessities of user application.
- Input:
- None
- Output:
- None
- Included in increment 1.
- protected void Page_Load(object sender, EventArgs e)
- Description: Method for page load.
- Input:
- object sender, EventArgs e
- Output:
- None
- Included in increment 1.
- private void ReadUserAppGlobalConfig()
- Description: Reads and Loads the GlobalConfiguration for the User Application.
- Input:
- None
- Output:
- None
- Included in increment 1.
- private void LoadTableAttributeList()
- Description: Loads the combo box with the list of tables
- Input:
- None
- Output:
- None
- Included in increment 2.
- private void RefreshAddMenu()
- Description: Builds the add menu dynamically
- Input:
- None
- Output:
- None
- Included in increment 2
- private void createEditForm(string title, string currentTableName, string recordId, string parentTableName, string parentRecordId)
- Description: Creates a form to edit a record with Save and Cancel button.
- Input:
- string title: The display attribute of the current record
- string currentTableName: The table name of the current record being edited
- string recordId: The ID of the current record
- string parentTableName: The parent table of the current record
- string parentRecordId: The Id of the parent record
- Output:
- None
- Included in increment 2
- private void createViewForm(string title, string currentTableName, string recordId, string parentTableName, string parentRecordId)
- Description: Creates a form to view a record with an Edit and Delete button.
- Input:
- string title: The display attribute of the current record
- string currentTableName: The table name of the current record being edited
- string recordId: The ID of the current record
- string parentTableName: The parent table of the current record
- string parentRecordId: The Id of the parent record
- Output:
- None
- Included in increment 2
- private void createAddForm( string currentTableName, string parentTableName, string parentRecordId )
- Description: Creates a form to add a record
- Input:
- string currentTableName: The table name of the current record being added
- string parentTableName: The parent table of the current record
- string parentRecordId: the Id of the parent record
- Output:
- None
- Included in increment 2
- private DataSet GetPossibleParents(Tree tree, Table table, string recordID)
- Description: Gets a DataSet with all possible parents for a given table type.
- Input:
- Tree tree: The tree to look through
- Table table: The table that the parents is needed
- string recordID: The record to get the parent for
- Output:
- Dataset: with all the possible parents
- Included in increment 2
- private void DeleteChildren(string tableName, string recordId)
- Description: Recursively deletes children from the current tree.
- Input:
- string tableName: table to delete children from
- string recordID: record to look for
- Output:
- None
- Included in increment 2
- private void LoadOperatorList()
- Description: Loads list of operators based on the attribute data type
- Input:
- None
- Output:
- None
- Included in increment 2
- internal bool IsTextDataType(string dataType)
- Description: Checks whether the supplied datatype string refers to a text type.
- Input:
- string dataType: The datatype to be examined
- Output:
- None
- Included in increment 2
- private void SetFilterControlsVisible(bool state)
- Description: Sets the filter controls to visible or not
- Input:
- bool state: the state of the controls
- Output:
- None
- Included in increment 2
- private void SetFilterControls(bool state)
- Description: Enables and disables the filter controls
- Input:
- bool state: to allow the controls to be changed
- Output:
- None
- Included in increment 2
- protected void CurrentTreeView_SelectedNodeChanged(object sender, RadTreeNodeEventArgs e)
- Description: Method to pass the selected node in tree view to the main page.
- Input:
- object sender: sender of the event
- RadTreeNodeEventArgs e: event derived from
- Output:
- None
- Included in increment 2
- protected void CurrentTreeView_ContextCLicked(object sender, RadTreeNodeEventArgs e)
- Description: Method for context menu events
- Input:
- object sender: sender of the event
- RadTreeNodeEventArgs e: event derived from
- Output:
- None
- Included in increment 2
- protected void TreeListDropDown_SelectedIndexChanged(object o, RadComboBoxSelectedIndexChangedEventArgs e)
- Description: Method to change the selected tree
- Input:
- object o: sender of the event
- RadComboBoxSelectedIndexChangedEventArgs e: event derived from
- Output:
- None
- Included in increment 2
- protected void TableAttributeComboBox_SelectedIndexChanged(object o, RadComboBoxSelectedIndexChangedEventArgs e)
- Description: Method for the ComboBox
- Input:
- object o: sender of the event
- RadComboBoxSelectedIndexChangedEventArgs e: event derived from
- Output:
- None
- Included in increment 2
- private void Menu_OnClicking(object sender, RadMenuEventArgs e)
- Description: Method that handles the OnClicking event of the Menu control
- Input:
- object o: sender of the event
- RadMenuEventArgs e: event derived from
- Output:
- None
- Included in increment 2
- private void RemoveAddVariablesFromContext()
- Description: Removes the add variables from the context
- Input:
- None
- Output:
- None
- Included in increment 2
- protected void AddFilterButton_Click(object sender, EventArgs e)
- Description: Event for when the add menu is clicked
- Input:
- object sender: sender of the event
- EventArgs e: event derived from
- Output:
- None
- Included in increment 2
- protected void CancelFilterButton_Click(object sender, EventArgs e)
- Description: Event for when the cancel button is clicked
- Input:
- object sender: sender of the event
- EventArgs e: event derived from
- Output:
- None
- Included in increment 2
- protected void SaveFilterButton_Click(object sender, EventArgs e)
- Description: Event for when the save button is clicked
- Input:
- object sender: sender of the event
- EventArgs e: event derived from
- Output:
- None
- Included in increment 2
- protected void ApplyFilterButton_Click(object sender, EventArgs e)
- Description: Event for when the apply button is clicked
- Input:
- object sender: sender of the event
- EventArgs e: event derived from
- Output:
- None
- Included in increment 2
- protected void ClearFilterButton_Click(object sender, EventArgs e)
- Description: Event for when the clear button is clicked
- Input:
- object sender: sender of the event
- EventArgs e: event derived from
- Output:
- None
- Included in increment 2
- protected void RemoveFilterButton_Click(object sender, EventArgs e)
- Description: Event for when the remove button is clicked
- Input:
- object sender: sender of the event
- EventArgs e: event derived from
- Output:
- None
- Included in increment 2
ControlCreator
The ControlCreator class is creates the controls for the user application.
- private static Boolean isTextBoxType(Attribute attr)
- Description: Returns true when an attribute should be rendered as a textbox
- Input:
- Attribute attr: the attribute
- Output:
- Boolean: True if attribute is textbox, false otherwise
- Included in increment 2
- public static void SetUpConfig(GlobalConfiguration config)
- Description: Sets the global configuration object
- Input:
- GlobalConfiguration config: The configuration set
- Output:
- None
- Included in increment 2
- public static WebControl GenerateViewableWebControl(Tree currentTree, Attribute attr, DataRow record)
- Description: Creates a viewable control for a given Attribute based on the attribute type.
- Input:
- Tree currentTree: the current tree
- Attribute attr: the attribute to be viewed
- DataRow record: the datarow of the record
- Output:
- WebControl: the webcontrol that is generated
- Included in increment 2
- public static WebControl GenerateViewableWebControl(Tree tree, DataRow record)
- Description: Creates a viewable control for a given Attribute based on the attribute type.
- Input:
- Tree tree: the current tree
- DataRow record: the datarow of the record
- Output:
- WebControl: the webcontrol that is generated
- Included in increment 2
- public static WebControl GenerateEditableWebControl(Tree currentTree, Attribute attr, string value)
- Description: Creates an editable control for a given Attribute based on the attribute type.
- Input:
- Tree currentTree: the current tree
- Attribute attr: the attribute to be viewed
- string value: The initial value. Null if empty
- Output:
- WebControl: the webcontrol that is generated
- Included in increment 2
- public static WebControl GenerateParentRecordSelector(Tree tree, DataSet ds, Table table, string parentTableName, string parentRecordID)
- Description: Generates an editable control for selecting a parent record in a given tree from given DataSet (most likely a drop down)
- Input:
- Tree tree: The current tree that is being considered
- DataSet ds: The dataset that is to be displayed
- Table table: The current table that is to be added to
- string parentTableName: The parent of the table
- string parentRecordID: the parent of the record
- Output:
- WebControl: the webcontrol that is generated
- Included in increment 2
- public static List<string> ProcessWebControl(RadGrid radGrid, string controlID)
- Description: Takes the content panel (radGrid) searches for a given control, then extracts the relevant information from it.
- Input:
- RadGrid radGrid: the radgrid controls
- string controlID: the control that we are looking for
- Output:
- List<string>: a list of values in the control. normally one, but maybe more will be necessary.
- Included in increment 2
- private static string GetValue(WebControl control)
- Description: Gets a value from a given WebControl object.
- Input:
- WebControl control: the control that used
- Output:
- string: the value needed
- Included in increment 2
- private static string CalculateRecursively(DataRow record, Attribute attr, Tree currentTree)
- Description: Recursively gets a calculated attribute value.
- Input:
- DataRow record: the record that is being looked for
- Attribute attr: the attribute that we are looking for
- Tree currentTree: the current tree
- Output:
- string: the calculated attribute value
- Included in increment 2
- private static string GetLinkedValue(DataRow record, Attribute attr, Tree currentTree)
- Description: Recursively returns the linked value of an attribute.
- Input:
- DataRow record: the record of the linked value
- Attribute attr: the attribute
- Tree currentTree: the current tree
- Output:
- string: the linked value
- Included in increment 2
- private static Boolean IsChild(Tree currentTree, Table parentTable, string parentRecord, string wantedChild)
- Description: Returns true if a given record is a child (or descendant) of a parent record in the current tree.
- Input:
- Tree currentTree: the current tree that is to be looked at
- Table parentTree: the parent table
- string ParentRecord: the parent record
- string wantedChild: the wanted child
- Output:
- Boolean: True if a given record is a child of the parent record, false otherwise
- Included in increment 2
- private static void FilterSet(DataSet set, Tree tree)
- Description: Filters a given data set to only contain records found in the current tree.
- Input:
- DataSet set: The dataset to be filtered
- Tree tree: the current tree
- Output:
- None
- Included in increment 2.
ControlDecorator
The ControlDecorator class decorates the controls
- public static void DecorateControls(string skinText, RadDockingManager radDockManager, RadMenu radMenu, RadGrid radGrid, RadComboBox radComboBox, RadTreeView radTree, RadTreeView radFilterTree)
- Description: Decorates the controls
- Input:
- string skinText: the name of the skin
- RadDockingManager radDockManager: the docking manager used
- RadMenu radMenu: the menu used
- RadGrid radGrid: the grid used
- RadComboBox radComboBox: the combo boxes used
- RadTreeView radTree: the tree used
- RadTreeView radFilterTree: the filtered tree used
- Output:
- None
- Included in increment 2.
InputValidator
The InputValidator class validates inputs entered into the User Application.
- private static bool IsNumeric(string numberString)
- Description: Checks the string
- Input:
- string numberString: to be compared
- Output:
- Bool: true if is numeric, false otherwise
- Included in increment 2
- private static bool IsDecimalPlace(char character)
- Description: checks if the current character is the only decimical place in a number
- Input:
- char character: to be checked
- Output:
- Bool: true if there is only one decimal point, false otherwise
- Included in increment 2
- private static void ShowErrorMessage(Label errorLabel, string errorMessage, bool visible)
- Description: Sets or clears the error message label
- Input:
- Label errorLabel: the label to display the error message on
- string errorMessage: the error message to be displayed
- bool visible: whether the label is visible
- Output:
- None
- Included in increment 2
- public static bool EvaluateInput(string input, Attribute inputAttribute, Label errorLabel)
- Description: Evaluates whether the input is valid, if valid sets error label else clears it
- Input:
- string input: to be validated
- Attribute inputAttribute: the input attribute
- Label errorLabel: Label to set error on
- Output:
- Bool: checks whether the input is valid
- public static InputDataType GetInputDataType(string dataType)
- Description: check the data type of an attribute input type
- Input:
- string dataType: string of the data type
- Output:
- InputDataType: the datatype of the given inputs
Navigation Tree
The main page of the User Application will contain a tree in the top left corner of the page. This will allow users to navigate through the records and select the desired record to be displayed. The tree will be of type RadTreeView consisting of RadTreeNodes. The following methods will be used to construct the tree.
This tree is able to handle multiple trees. In the UserApp.aspx.cs, there are three methods, createViewForm, createEditForm and createAddForm. When viewing the tree, it displays the parent records (via the display attribute) so that different trees can be shown under the same tree. When editing and adding, these records are drop-down boxes which is populated with possible parent records for the current record that is selected.
- loadTree()
- Description
- This method loads up an empty tree. It fetches the child nodes of the root table for the Database Library through the getChildNodes. These items are placed in the tree as the root nodes. Once a root element is found, TreeBuilder.BuildTree is call on that datarow to load up that branch of the tree.
- Input:
- None
- Output:
- None
- Included in increment 1.
- Description
- private void getTreeList()
- Description: Loads the list of trees into a ComboBox to allow the user to select a tree that they wish to display
- Input:
- None
- Output:
- None
- Included in increment 1.
- private void LoadFilterTree()
- Description: Loads the filtered tree
- Input:
- None
- Output:
- None
- Included in increment 2.
- private void RefreshTree()
- Description: Refreshes the tree
- Input:
- None
- Output:
- None
- Included in increment 2.
- private void RefreshFilterTree()
- Description: Refreshes the filtered tree
- Input:
- None
- Output:
- None
- Included in increment 2.
TreeBuilder
The TreeBuilder class is a static class that will build a given branch of the tree. The Class will perform two operations. Firstly it will build a RadTreeNode from the given datarow and secondly it will recursively work its way down the tree and get the datarows of the children of the current node.
- public static void SetUpTree(GlobalConfiguration configuration)
- Description: Setups up the filter list. And adds a filter for each table without a condition
- Input:
- GlobalConfiguration configuration: the configuration from the User Application
- Output:
- None
- Included in increment 2.
- public static void BuildTree(RadTreeView filterTree, Guid currentTreeID)
- Description: Builds the filtered tree
- Input:
- RadTreeView filterTree: Tree to add filters to
- Guid currentTreeID: The current tree that is being viewed
- Output:
- None
- Included in increment 2.
- private static RadTreeNode Load(DataRow currentRow, LoadType loadType, Guid currentTreeID)
- Description: Loads a node for a datarow to display in the tree
- Input:
- DataRow currentRow: Record to be displayed
- LoadType loadType: Normal or partial load
- Guid currentTreeID: Tree that the node is to be displayed
- Output:
- RadTreeNode: returns the displayed node if there is one, null otherwise
- Included in increment 2
- public static DataSet GetChildrenDataSet(Guid treeID, Table table, DataRow parentRow)
- Description: Gets children nodes of current row
- Input:
- Guid treeID: Selected tree
- Table table: Table of the current row
- DataRow parentRow: Parent row to get the children from
- Output:
- DataSet: Containing all children
- Included in increment 2
- public static RadTreeNode GetNode(DataRow currentRow, LoadType loadType, Guid treeID)
- Description: Creates a node for the current datarow if it needs to be displayed
- Input:
- DataRow currentRow: Record to be displayed
- LoadType loadType: Normal or partial load
- Guid currentTreeID: Tree that the node is to be displayed
- Output:
- RadTreeNode: returns the displayed node if there is one, null otherwise
- Included in increment 2
- private static RadTreeNode CreateNode(DataRow dataRow)
- Description: creates a RadTreeNode from a given DataRow
- Input:
- DataRow dataRow: The row to be added as a node
- Output:
- RadTreeNode: Containing the branch of the tree
- Included in increment 2
- private static RadTreeNode CreateNode(DataRow dataRow, GlobalConfiguration userAppConfiguration)
- Description: creates a RadTreeNode from a given DataRow
- Input:
- DataRow dataRow: The row to be added as a node
- GlobalConfiguration userAppConfiguration: Configuration of the User App
- Output:
- RadTreeNode: Containing the branch of the tree
- Included in increment 2
- public static void BuildFilterTree(RadTreeView filterTree)
- Description: Builds the filtered tree
- Input:
- RadTreeView filterTree: Tree to add the filters to
- Output:
- None
- Included in increment 2
- internal static List<Filter> findTableFilters(List<Filter> filters, Table currentTable)
- Description: Finds the filters to apply to the current data row
- Input:
- List<Filter> filters: Complete list of filters
- Table currentTable: Current table for the filter
- Output:
- List<Filter>: List of filters
- Included in increment 2
- internal static Filter GetFilterForTable(string tableName)
- Description: Get the filter for a given table name
- Input:
- string tableName: the table name for the filter
- Output:
- Filter: for the table
- Included in increment 2
- public static void AddCondition(string tableName, Condition newCondition, string prevConditionID)
- Description: Adds new condition to the filter
- Input:
- string tableName: Name of the table for added condition
- Condition newCondition: the new added condition
- string prevConditionID: the previous condition id
- Output:
- None
- Included in increment 2
- public static void ClearFilters()
- Description: Clears all the filters from the tree
- Input:
- None
- Output:
- None
- Included in increment 2
- public static void ClearFiltersTable(string tableName)
- Description: Clears all conditions in a table
- Input:
- string tableName: Table to remove all conditions
- Output:
- None
- Included in increment 2
- public static void RemoveFilter(string tableName, string conditionID)
- Description: Remove a condition from a table
- Input:
- string tableName: Table of the condition to be removed
- string conditionID: Condition ID
- Output:
- None
- Included in increment 2
Condition
The Condition class is a static class that allows the user application to be able to set conditions for the filter.
- public Condition(Attribute attribute, ConditionOperators.Ops conditionOperator, Object value)
- Description: The constructor for the Condition
- Input:
- Attribute attribute: Attribute this condition will evaluate on
- ConditionOperators.Ops conditionOperator: Operator for the condition
- Object value: Value to compare attribute to during evaluation
- Output:
- None:
- Included in increment 2
- internal void Add(Condition newCondition, Connector connectorOperator)
- Description: Attaches another condition with another
- Input:
- Condition newCondition: The new condition to attach
- Connector connectorOperator: Attached it with an AN or OR
- Output:
- None
- Included in increment 2
- internal bool Evaluate(DataRow row)
- Description: Evaluates whether a datarow satisfies this condition
- Input:
- DataRow row: Datarow to evaluate
- Output:
- Bool: True if satisfies, false otherwise
- Included in increment 2
ConditionOperators
The ConditionOperators class is a static class that form the condition operators for the user application.
- public static string ConvertToString(Ops operatorType)
- Description: Converts a conditionOperator to a string to be displayed in the drop down box for the user
- Input:
- Ops operatorType: Condition operator to convert
- Output:
- string: of the operator
- Included in increment 2
- static public int getTypeIndex(string dataType)
- Description: Get the enum starting value of the datatype
- Input:
- string dataType: the name of the datatype
- Output:
- int: the starting index of the enum
- Included in increment 2
- static public Ops getOperator(int index, string dataType)
- Description: Gets the operator given an index and datatype
- Input:
- int index: the index
- string dataType: the name of the datatype
- Output:
- Ops: the operator given an index and datatype
- Included in increment 2
- static public List<string> getOperatorStringList(string dataType)
- Description: Gets a list of operators
- Input:
- string dataType: the name of the datatype
- Output:
- List<string>: list of operators
- Included in increment 2
- public static bool validOperator(string dataType, Ops operatorType)
- Description: Tests wehther a condition operator can be applied to a certain datatype
- Input:
- string dataType: the name of the datatype
- Ops operatorType: the operator given an index and datatype
- Output:
- bool: true where the operator is valid for the datatype
- Included in increment 2
- public static bool evaluate(Ops operatorType, object valueA, object valueB)
- Description: Checks if two values satisfy a particular criteria
- Input:
- Ops operatorType: The Condition operator
- object valueA: The first value
- object valueB: The second value
- Output:
- bool: True if satisfies, false otherwise
- Included in increment 2
- static private bool evaluateNumeric<T>(Ops operatorType, T a, T b) where T : System.IComparable
- Description: Evaluates all numeric types
- Input:
- Ops operatorType: the condition operator
- T a: the first value
- T b: the second value
- Output:
- bool: True if satisfies, false otherwise
- Included in increment 2
Filter
The Filter class is a internal class that serves a filter.
- internal bool HasCondition()
- Description: Checks to see if the filter has a condition
- Input:
- None
- Output:
- bool: true if filter has a condition, false otherwise
- Included in increment 2
- internal void AddCondition(Condition newCondition, string prevConditionID)
- Description: Adds a condition to the current filter
- Input:
- Condition newCondition: new condition that is to be added
- string prevConditionID: previous condition to be added
- Output:
- None
- Included in increment 2
- internal void Remove(string conditionID)
- Description: Removes a condition from the filter
- Input:
- string conditionID: ID of the condition that is to be removed
- Output:
- None
- Included in increment 2
Filter
Overview
The filter will be used to apply conditions to the records that will be displayed in the tree. The user will be able to apply any number of conditions to any number of tables in the application. To explain precisely how the filter will operate on the tree, the following example is used:
Let's say the user chooses to apply a filter onto only table T with condition Cs:
- The filter is only applied to records of table T. The records from other tables are displayed as normal.
- In the tree we will display all root records of all tables which are not from table T, and all root records from tables T, as long as they match conditions Cs.
- However with the records that are from T that do NOT match conditions Cs, we may still want to display these records in the tree. Let's say we have a root record R which is from table T, and does not match conditions Cs - then we will want to display this record if there are any descendants of R that are from table T and DO match condition Cs. This ensures that all records from table T that match conditions Cs will be displayed in the tree, so the user does not miss out on any records.
- In this case we will display record R as "greyed". If a record is greyed it means that it did not match the filter conditions, but we still need to display it because there is a record in one of its descendants that does match the filter conditions.
- Because R is greyed, we only display it's children nodes that we need in order to display those records of R's descendants that do match the filter conditions Cs. In other words, only display the children of R that are ancestors of those records that need to be displayed (because they are from table T and match conditions Cs) or are those records themselves.
The final result is that we get a tree that shows ALL records from table T that match the conditions Cs, and only shows records from table T that don't match conditions Cs if we need them in order to show any descendants of those records that are from table T and do match conditions Cs. The algorithm for this process can be found here.
Classes
The following class diagram shows the classes that will be used for the functioning of the filter:
Filter
A filter is a set of conditions applied to a particular table within the database. In the CGT user application, the user will be able apply a filter to any number of tables. The reason why there is only a single condition within the filter class is because the set of conditions is stored as a linked list.
Condition
A condition takes an attribute from the table it belongs to and will apply a comparison operator to a constant value. The comparison operator will obviously depend on the datatype of the attribute. If the attribute is an int then the available comparison operators will be >, <, =>, <=, =. The datatype of Value must be the same as the datatype of the attribute.
As stated above, multiple conditions are stored for tables through a linked list. The reason for this is that it allows for a very simple algorithm to evaluate a complex set of conditions connected with either AND's or OR's. The connector member specifies whether to connect this condition to the rest of the list with an AND or an OR. So for example the following three connected conditions with the connectors:
- A OR -> B AND -> C FINAL
is evaluated as
- A OR (B AND C)
If the connector is FINAL then no further nested conditions are allowed.
- evaluate
- Description
- Checks whether a datarow satisfies this condition.
- Input
- Datarow to be evaluated.
- Output
- Boolean. Whether the row satisfied the condition.
- Constraints
- The datarow must be from the same table as the condition's Filter object.
- Algorithm
- To evaluate the datarow, it is first evaluated on the linked condition. The result is then either ANDed or ORed with the result of comparing the value of the Attribute field with the Value. This is done by calling evaluate() in the Operators class.
- Description
Operators
This class is used to store the comparison operators that the conditions will use to evaluate records. The reason why a separate class is used to store these operators is for extendibility. To add another comparison operator that the user can use for filtering only this class needs to be modified.
The set of operators will be stored as enums, one enum for each datatype that will be used. As can be seen in the diagram the NumberOperators enum contains all the standard integral comparison operators. The evaluate() method will execute the comparison and check whether two values satisfy the condition.
- evaluate
- Description
- Checks whether two values satisfy a comparison condition
- Input
- An int which refers to the enum value of the operator to be used for the comparison, the two values which will be evaluated to see if they satisfy the condition
- Output
- A boolean saying whether the two values satisfy the comparison condition.
- Constraints
- The two values must be of the same datatype and there must be at least one comparison operator defined for that datatype (i.e. an enum). Since the two values passed to this method can be of various datatypes this method will be overloaded. Hence to enable this method to work for new datatypes we can simply overload this method with the two values being of the new type. The current version will allow for evaluate(int, int, int), evaluate(int, float, float), evaluate(int, string, string). Which ever one is used, the method must be able to perform a comparison for each value listed in the corresponding enumeration. (e.g. if there are 5 values in the NumberOperators enum then evaluate(int, int, int) method must have cases for all 5 values)
- Description
Tree building algorithm
The following diagram illustrates the algorithm for building the tree, given that there may be filters. The Load() method is takes a datarow and will appropriately load all of the datarow's children, recursively.
GUI controls
The following diagram shows the user interface for the filter:
treeViewFilter
- Purpose
- This tree view will display all of the conditions that are currently in the filter. The first level nodes represent the tables in schema that can be part of currently selected Tree, the second level nodes represent the conditions that the user has chosen to apply to records of that table.
- Method
- When the user selects a table in this tree view, they will be able to add conditions to the table by clicking on buttonAddCondition. If a condition node is selected the user will able to add a nested condition to the currently selected condition, as long as the selected condition has been created with a condition connector (AND or OR).
buttonApply
- Purpose
- Applies the filter to the tree
- Method
- Upon click it simply refreshes the user application tree
buttonAddCondition
- Purpose
- Loads the newConditionDialogue so the user can add a condition to the currently selected table in the treeViewFilter.
- Method
- Upon click the newConditionDialogue will appear, as long as a node within the treeViewFilter is selected.
buttonRemoveCondition
- Purpose
- Removes the currently selected condition in the treeViewFilter.
- Method
- Upon click if there is a condition selected in the treeViewFilter it along with the associated condition object will be removed. If the condition is a link within a chain of conditions it's parent will be linked to it's child.
buttonClear
- Purpose
- Clears all conditions from the treeViewFilter.
- Method
- Upon click remove all conditions.
newConditionDialogue
- Purpose
- Allows the user to create a condition
- Method
- The comboBoxAttribute will be populated with attributes from the currently selected table within the treeViewFilter. The comboBoxOperator will be populated with the operators associated with the datatype of the attribute selected in the comboBoxAttribute.
buttonNewConditionDone
- Purpose
- Saves the new condition that the user has defined
- Method
- Upon click there will be error checking to make sure all fields have been selected, and that the value entered is of the same type as the attribute selected in the comboBoxAttribute. If all is well the condition object will be created and a new node will be added to the treeViewFilter.
Telerik Controls
Overview
Telerik Treeview control is used for data navigation.
Telerik Menu control is used to provide functionalities such as add/modify/delete and etc.
Telerik Dock control is used to adjust the position of different controls in the User App.




































































