Abner-Bilal-SSE554-Project3

=PROJECT 3 SSE-554 OBJECT-ORIENTED DESIGN II toc= = =

Project group : Abnerson Malivert & Ahmad Bilal

Project title : The XML Generator Application

Project Reference :

@http://www.codeproject.com/KB/list/aa_listview.aspx

Wrox Professional C# 2008

Project Overview
The XML Generator is a software tool that takes .ibm and .cbf files, and user-input data to create an .xml file for each .ibm and .cbf file. The idea of the XML Generator came about, when a co-worker complained about having to create multiple xml files by hand when running simulations in the lab. Bilal and I thought it would be a good idea to build an application that would not only meet our project requirement for class but would also have real-life applications.

The example .xml, .ibm, or .cbf files used in this project report are not derived from real data; the simulation data are considered For Official Use Only (FOUO) by the United States Air Force (AF).

The Requirements that were set for the XML Generator are:

1. To allow the user to open one or multiple .ibm or .cbf files at a time.

2. To have a method for the user to choose which .ibm or .cbf files it wants to create an xml file for.

3. To have a way to input the Event Name, Launch Time, CPA time, Range, and sensor type.

4. To include the constant parameters (like the sensor_yaw and pitch value) needed for the xml file.

5. To have a way to clear all the open files off the screen.

Bilal and I wanted to build a tool that would not only work but would also make life easier for the user. We had our requirements set by the end-user and we needed to come up with design ideas that would satisfy their need. This project covers the basic process that we went through to design, and build the XML Generator application.

Project Software Design Pattern
The XML Generator software is designed using the Composite Pattern. The composite pattern allows you to compose objects into tree structures to represent part-whole hierarchies. The composite pattern design would also make it easier for programmers to upgrade the XML generator functions to meet future needs. The Composite pattern would work for our project because of its innate behavior that lets clients treat individual objects and compositions of objects uniformly. The XML Generator requirement is to deal with multiple or single objects. Bellow is the Composite Pattern Schematic for the XML generator:



Composite Pattern
Allows you to compose objects into tree structures to represent part-whole hierarchies. Composite pattern lets clients treat individual objects and compositions of objects uniformly.

Components
The XMLWriterComponents class declares the interface for the objects in the composition; it also declares the interface for the child components. It also implements the behavior for the interface common to all classes. The abstract methods found in the XMLWriterComponents class are: code format="csharp" public abstract class XMLWriterComponents {       public abstract string getEventDir; public abstract string getEventName; public abstract double getLaunchTime; public abstract string getThreatType; public abstract double getCpaTime; public abstract int getRange; public abstract string getSensorType; public abstract string getIbmFileDir; public abstract string getCbfFileDir; public abstract string getBinaryFileDir; public abstract string getSamplePeriod; public abstract void CreateXMLfile; public abstract void AddSelectedItems(XMLWriterComponents XmlFileItem); public abstract void ClearAllList; } code

Composite
The SelectedFilesList class defines the behavior for components having children. The composite is contains the list of files that have been selected by the user. The SelectedFileList class uses the following methods : code format="csharp" public override void AddSelectedItems(XMLWriterComponents XmlFileList) {           FileList.Add(XmlFileList); } code
 * **AddSelectedItems**- Adds xmlwritercomponents to the filelist.

code format="csharp" public override void CreateXMLfile {           IEnumerator iterator = FileList.GetEnumerator;
 * **CreateXMLFile-**uses an enumerator to iterate through the FileList items, than calls the createXMLfile method of the XMLwriter class.

while (iterator.MoveNext) {               XMLWriterComponents XMLWriterComponents = (XMLWriterComponents)iterator.Current; XMLWriterComponents.CreateXMLfile; }

} code

Leaf
represents the leaf objects of the composition and has no children. The XmlWriter class holds the object’s attributes and the constants for sensors; it takes in the parameters such as Launch time, CPA time etc through a constructor as shown below:

code format="csharp" public XMLWriter(string EventFileDir,string Name, string ThreatType, double LaunchTime, double CPATime,           int Range, string CbfFileDir, string IbmFileDir, string BinaryFileDir, string sensorType) {           this._EventFileDir = EventFileDir; this._Name = Name; this._ThreatType = ThreatType; this._LaunchTime = LaunchTime; this._CPATime = CPATime; this._Range = Range; this._CbfFileDir = CbfFileDir; this._IbmFileDir = IbmFileDir; this._BinaryFileDir = BinaryFileDir; this._sensorType = sensorType; } code
 * CreateXMLFile-** The selectedFileList class uses this method to create and enter write the nodes of the XML file.

The _xmldirectory is a string array that holds the split by a dot string of the event file directory and then the array count is subtracted by 1, and then the last index is replaced with .xml. The foreach loop goes through the xml directory and adds the string one after another to create the xml file path appropriately as shown below: code format="csharp" string[] _xmlDirectory = _EventFileDir.Split('.'); int _lastIndex = _xmlDirectory.Count; _xmlDirectory[_lastIndex - 1] = ".xml"; foreach (string _dir in _xmlDirectory) {              _xmlFilePath += _dir; } code The XmlWriter class implements all the methods declared in XMLWriterComponents class except for the AddSelected and ClearAllList methods, and then it also set the settings for the xml file. Event line is found in the file name and is calculated from the file directory by splitting Ibm file or Cbf file directory by the 'M' character, then splitting that by the '.' character, which should leave only the event number as shown below : code format="csharp" //calculating the Event line from the file directory string[] strEventLine = _EventFileDir.Split('M'); int EventLineCount = strEventLine.Count; string strEventLinePart = strEventLine[EventLineCount - 1]; string[] strEventLineA = strEventLinePart.Split('.'); _EventLine = strEventLineA[0]; code The following code set the settings and creates the xml file path as shown below: code format="csharp" // set the settings for the xml file XmlWriterSettings settings = new XmlWriterSettings; settings.Indent = true; settings.NewLineOnAttributes = true; XmlWriter writer = XmlWriter.Create(_xmlFilePath, settings); code The XmlWriter only Writes strings so all integer, double have to be converted to string using the Tostring method.The following code begins with the start element and other elements are then created where Launch time and Cpa time is converted from double to a string as shown below: code format="csharp" writer.WriteStartDocument; //Start creating elements //////////////////////////////////////////////////////////////////////////           //////////////////////////////////////////////////////////////////////////            writer.WriteStartElement("AAR47Scenario"); // Name node writer.WriteElementString("Name", getEventName);

// start Threat node writer.WriteStartElement("Threat"); writer.WriteElementString("ThreatType", ""); writer.WriteElementString("LaunchTime", getLaunchTime.ToString);//convert to string writer.WriteElementString("CPATime", getCpaTime.ToString);// convert to string writer.WriteElementString("EndTime", ""); code Once the elements for threat node are written, writer.WriteEndElement is used to end the threat node. These are the constants declared initially along with other objects in xml writer class: code format="csharp" private const int Sensor1_Yaw = 315; private const int Sensor2_Yaw = 45; private const int Sensor3_Yaw = 225; private const int Sensor4_Yaw = 135; private const int Sensor1_Pitch = 0; private const int Sensor2_Pitch = 0; private const int Sensor3_Pitch = 0; private const int Sensor4_Pitch = 0; code The sensor values and pitch are converted from integer to string and they are written in xml writer as follows: code format="csharp" // write sensor yaw values writer.WriteElementString("Sensor1_Yaw", Sensor1_Yaw.ToString);//convert to string writer.WriteElementString("Sensor2_Yaw", Sensor2_Yaw.ToString);//convert to string writer.WriteElementString("Sensor3_Yaw", Sensor3_Yaw.ToString);//convert to string writer.WriteElementString("Sensor4_Yaw", Sensor4_Yaw.ToString);//convert to string

// write sensor pitch values writer.WriteElementString("Sensor1_Pitch", Sensor1_Pitch.ToString);// convert to string writer.WriteElementString("Sensor2_Pitch", Sensor2_Pitch.ToString);//convert to string writer.WriteElementString("Sensor3_Pitch", Sensor3_Pitch.ToString);// convert to string writer.WriteElementString("Sensor4_Pitch", Sensor4_Pitch.ToString);// convet to string

code The sample period and the file directories which include ibm, cbf, and binary file directory are written as shown below: code format="csharp" // write sample period and ibm, cbf, binary file directory writer.WriteElementString("SamplePeriod",getSamplePeriod); writer.WriteElementString("IBMFile",getIbmFileDir); writer.WriteElementString("CBFFile", getCbfFileDir); writer.WriteElementString("BinaryFile", getBinaryFileDir); writer.WriteElementString("Description",""); writer.WriteElementString("Eventline",_EventLine); code The following code closes the document, clean up the xml writer and shows a message when xml File is successfully created: code format="csharp" // close the xml document writer.WriteEndDocument;

//cleanup XML writter writer.Flush; writer.Close;

//message of successfull creation

MessageBox.Show(_xmlFilePath + " succesfully created");

code

Project GUI Design
To meet the requirement of the XML generator needing the ability to open and correlate user input data to single or multiple files, we decided to use a ListView Control. According to chapter 31 of the Professional C# 2008 book, a ListView control enables you to display items in different ways. A list would be a good way to go with the project since it would allow us to view multiple items at once with each item being its own entity.

In Form1.cs class under the Form_1 load, The Glacial ListView columns and column control type are set. Looking at the picture below, the column directory has a control embedded type of ‘none’. The ‘none’ setting for the embedded control type does not allow the user to make changes to the items in that column. The embedded control type ‘TextBox’, set the column as a changeable Textbox control, the user will be able to change the data in that field. code format="csharp" private void Form1_Load(object sender, EventArgs e)       {

GLColumn column = this.FileDisplayCtrl.Columns.Add("File Directory", 100); column.ActivatedEmbeddedType = GLActivatedEmbeddedTypes.None; column.CheckBoxes = true; GLColumn column1 = this.FileDisplayCtrl.Columns.Add("Event Name", 100); column1.ActivatedEmbeddedType = GLActivatedEmbeddedTypes.TextBox; GLColumn column2 = this.FileDisplayCtrl.Columns.Add("Launch Time(secs)", 100, HorizontalAlignment.Left); column2.ActivatedEmbeddedType = GLActivatedEmbeddedTypes.TextBox; GLColumn column3 = this.FileDisplayCtrl.Columns.Add("CPA Time(secs)", 100); column3.ActivatedEmbeddedType = GLActivatedEmbeddedTypes.TextBox; GLColumn column4 = this.FileDisplayCtrl.Columns.Add("Range(m)", 100, HorizontalAlignment.Left); column4.ActivatedEmbeddedType = GLActivatedEmbeddedTypes.TextBox; GLColumn column5 = this.FileDisplayCtrl.Columns.Add("Sensor Type", 100, HorizontalAlignment.Left); column5.ActivatedEmbeddedType = GLActivatedEmbeddedTypes.TextBox;

} code The ‘clear all’ button control clears all the items of the ListView control. The click method for this control counts all the items on the ListvView control, then removes each item from the conrol. code format="csharp" private void ClearAll_Click(object sender, EventArgs e)       {

int i = FileDisplayCtrl.Items.Count; for (int j = 1; j <= i; j++) {               FileDisplayCtrl.Items[j - 1].Selected = true; FileDisplayCtrl.Items.RemoveAt(j - 1); i = FileDisplayCtrl.Items.Count; }

FileDisplayCtrl.Items.Clear; } code The Generate button control click method creates an enumerator out of all the ListView control items, then uses a while loop and the iterator’s MoveNext method to check which items in the ListView Control is checked. code format="csharp" private void Generate_Click(object sender, EventArgs e)       {

XMLWriterComponents _xmlWriterComponent = new SelectedFileList;

IEnumerator _item = FileDisplayCtrl.Items.GetEnumerator; while (_item.MoveNext) {               if (((GLItem)_item.Current).SubItems[0].Checked) { code If an item is checked, the values for the variables are set inside a try and catch exception handler that catches FormatExceptions from the ListView Control. The selected file is then checked to see if it is an .ibm or .cbf files, or if it is neither. For the ibm and cbf case the ibm,cbf and binary file directory variables are set. For the case where the file is neither, a message display is set to ask the user to only input ibm and cbf files.

After setting all the values, the instance of the xmlwritercomponent is used to add a new XMLwriter to the SelectedFilesList component. code format="csharp" try {                       _EventFileDir = ((GLItem)_item.Current).SubItems[0].Text; _EventName = ((GLItem)_item.Current).SubItems[1].Text; _LaunchTime = Convert.ToDouble(((GLItem)_item.Current).SubItems[2].Text); _CPATime = Convert.ToDouble(((GLItem)_item.Current).SubItems[3].Text); _range = Convert.ToInt32(((GLItem)_item.Current).SubItems[4].Text); _SensorType = ((GLItem)_item.Current).SubItems[5].Text;

string[] filesname = ((GLItem)_item.Current).SubItems[0].Text.Split('.'); int LastItem = filesname.Count; string extension = filesname[LastItem-1]; IEnumerator _FileExtensions = filesname.GetEnumerator; if (extension == "IBM".ToLowerInvariant) {

_IBMFileDir = _EventFileDir; _cbfFileDir = ""; filesname[LastItem - 1] = ".bin"; foreach (string _dir in filesname) {                               _BinaryFileDir += _dir; }                           _xmlWriterComponent.AddSelectedItems(new XMLWriter(_EventFileDir,_EventName, _ThreatType, _LaunchTime,_CPATime, _range, _cbfFileDir, _IBMFileDir, _BinaryFileDir, _SensorType));

}                       else if (extension == "CBF".ToLowerInvariant) {                               _IBMFileDir = ""; _cbfFileDir = _EventFileDir; filesname[LastItem - 1] = ".bin"; foreach (string _dir in filesname) {                                   _BinaryFileDir += _dir; }                               _xmlWriterComponent.AddSelectedItems(new XMLWriter(_EventFileDir,_EventName, _ThreatType, _LaunchTime,_CPATime, _range, _cbfFileDir, _IBMFileDir, _BinaryFileDir, _SensorType)); }                           else {                               MessageBox.Show("IBM AND CBF FILES ONLY"); }

}                   catch (FormatException ex) {                       string ErrorMsg = _EventName + " Invalid fields"; MessageBox.Show(ex.Message, ErrorMsg); }

}

} code After all the new XMLwriter items are added to the xmlwritercomponent, the createXMLfile method is called to create xml files out of each of the XMLwriter items. The clearAll method is called to clear the xmlwritercomponent items. code // create XML files _xmlWriterComponent.CreateXMLfile;

// clear XML files list _xmlWriterComponent.ClearAllList; code

Project reference library
The ListView Control for the XML Generator needed the ability to input column data for each file. We could use the generic .NET ListView Control and code all the capabilities, or we can find an assembly or dynamic link library (.dll) that we can use to meet our requirements.

The open-source dll that we ended up using is the Glacial ListView Control v1.3 written by Allen Anderson. The Glacial ListView Control is a ListView Control that already had all the methods that the XMl Generator needed. It had a method to add a textbox, comboBox, or etc… to column. To use a .dll from an outside source you must:

1. Download the Glacial ListView source file.

2. Located the GlacialList.dll file and copy it to your project directory.

3. Right click on the project name in the solution window, and then click on the “Add Reference” link.

4. Click on the browse tab and locate the GlacialList.dll file, then click okay. Now you have access to all the methods and controls that are in that library.

5. In the program.cs class declare add the directive : using GlacialComponents.Controls;

6. To use the ListView Control from GlacialView.dll file, right click on the general control section of the toolbox, click on the choose items selection, and then click on browse and then locate the dll file. The Glacial ListView control should appear under the general section of the toolbar.

The Glacial ListView Control gives us the ability to drag and drop files unto our program. We decided to use this method instead of using the open file dialogue control to open the files. To enable drag and drop method, go to the control property and set the allow drop property to true.

The XML Generator software utilizes two methods from the allow drop property. The ‘DragEnter’ property flag is raised when the mouse enters the ListView control area and is used to determine the type of data that is being dropped unto the ListView control. For the XML Generator application will only allow files to be dragged unto the ListView control. The DragDropEffects property is set to all to allow copy, past, and etc… code format="csharp" private void FileDisplayCtrl_DragEnter(object sender, DragEventArgs e)       { // make sure they're actually dropping files (not text or anything else) if (e.Data.GetDataPresent(DataFormats.FileDrop, false) == true) // allow them to continue // (without this, the cursor stays a "NO" symbol               e.Effect = DragDropEffects.All;        }

code The next allow drop method used by the XML Generator is the ‘DragDrop’ method. The ‘DragDrop’ method property flag is raised when the drag action starts. This application uses it to add the drop file directory unto the ListView control as a new item. code format="csharp" private void FileDisplayCtrl_DragDrop(object sender, DragEventArgs e)       { // transfer the filenames to a string array string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);

// loop through the string array, adding each filename to the ListBox foreach (string file in files) {                   Filename = Path.GetFileName(file); item = this.FileDisplayCtrl.Items.Add(file); item.Selected = true; }           } code

Test 1
In This test we will test the capability of the XMLGenerator to drag and drop a new item into the ListView control. The image below shows the successful result of this test.

Test 2
In This test we will test the clear button click method and clear all the files of off the GUI. The image below shows a successful test, all the items from test 1 are no longer on the ListView control.

Test 3
This test the ability to add data to each item and the generate button click method using the wrongformat exception. The image below shows input in the each column and an invalid fields exception thrown by the XML Generator because of the Launch time being a string instead of an integer.

Test 4
This test the ability of the XML Generator to reject wrong file format that are not ibm or cbf files. The image bellow shows an error generated by dragging a docx file unto the XML Generator, than clicking on the generate button.

Test 5
To meet the requirement of being able to create a single xml file, this test will create a single xml file. The images below show the successful result of creating an xml file and the data inside the xml file. The info in the xml file matches the info on the GUI and also since it was a cbf file the cbf file directory element string in the xml file are correct. Below are the contents of the XML file : code format="xml"  -  E01 -   5 5  -      </ValidSensor> <Range>50</Range> - <Firingpoint> <X /> <Y /> <Z /> </Firingpoint> - <Clutter> </Clutter> </Threat> -  <Speed_Class /> <GPS /> <SensorType>A(V)2</SensorType> - <Environment> <Temp /> <Visibility /> <Ozone /> <MSL /> <Humidity /> </Environment> <Sensor1_Yaw>315</Sensor1_Yaw> <Sensor2_Yaw>45</Sensor2_Yaw> <Sensor3_Yaw>225</Sensor3_Yaw> <Sensor4_Yaw>135</Sensor4_Yaw> <Sensor1_Pitch>0</Sensor1_Pitch> <Sensor2_Pitch>0</Sensor2_Pitch> <Sensor3_Pitch>0</Sensor3_Pitch> <Sensor4_Pitch>0</Sensor4_Pitch> <SamplePeriod>2500</SamplePeriod> <IBMFile /> <CBFFile>C:\Users\Administrator\Documents\CSharps Programs\2006095_095213_V2SDRG_M7.cbf</CBFFile> <BinaryFile>C:\Users\Administrator\Documents\CSharps Programs\2006095_095213_V2SDRG_M7.bin</BinaryFile> <Description /> <Eventline>7</Eventline> </AAR47Scenario> code

Test 6
This test the capability of the XML Generator to create multiple XML files but only from the checked items. Fig 6.1 and Fig 6.2 shows the message-box that is displayed after the successful creation of the checked item XML files. Fig 6.3 shows the location of the XML files.